blob: 5a7e29ee50a1a622058b996aed63dd2ea3209177 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
#include "rcc.h"
#include "flash.h"
#include "../syscfg/syscfg.h"
void rcc_init() {
// Initialize flash.
flash_init();
#if defined(STM32F1) || defined(STM32F3)
// Enable HSE.
RCC->CR |= 0x10000;
while(!(RCC->CR & 0x20000));
// Configure and enable PLL.
RCC->CFGR = 0x1d0000;
RCC->CR |= 0x1000000;
while(!(RCC->CR & 0x2000000));
// Switch to PLL.
RCC->CFGR |= 0x2;
while(!(RCC->CFGR & 0x8));
// Set APB1 prescaler to /2.
RCC->CFGR |= 0x400;
// Set ADCCLK prescaler to /6.
RCC->CFGR |= 0x8000;
#elif defined(STM32F4)
// Enable HSE.
RCC->CR |= 0x10000;
while(!(RCC->CR & 0x20000));
// Configure and enable PLL.
RCC->PLLCFGR = 0x20400000 | (7 << 24) | (2 * 168 << 6) | 8;
RCC->CR |= 0x1000000;
while(!(RCC->CR & 0x2000000));
// Switch to PLL.
RCC->CFGR |= 0x2;
while(!(RCC->CFGR & 0x8));
// Set APB1 prescaler to /4.
RCC->CFGR |= 5 << 10;
// Set APB2 prescaler to /2.
RCC->CFGR |= 4 << 13;
#elif defined(STM32F0)
// Enable HSI48.
RCC->CR2 |= 1 << 16; // HSI48ON
while(!(RCC->CR2 & (1 << 17))); // HSI48RDY
// Switch to HSI48.
RCC->CFGR |= 3 << 0; // SW = HSI48
while((RCC->CFGR & (3 << 2)) != (3 << 2)); // SWS = HSI48
#elif defined(STM32L0)
// Enable HSI16.
RCC->CR |= 1 << 0; // HSI16ON
while(!(RCC->CR & (1 << 2))); // HSI16RDYF
// Configure PLL.
RCC->CFGR |= (1 << 22) | (1 << 18) | (0 << 16); // PLLDIV = /2, PLLMUL = 4x, PLLSRC = HSI16
// Enable PLL.
RCC->CR |= 1 << 24; // PLLON
while(!(RCC->CR & (1 << 25))); // PLLRDY
// Switch to PLL.
RCC->CFGR |= 3 << 0; // SW = PLL
while((RCC->CFGR & (3 << 2)) != (3 << 2)); // SWS = PLL
// Enable VREFINT for HSI48.
RCC->enable(RCC->SYSCFG);
SYSCFG.CFGR3 |= (1 << 13) | (1 << 0); // ENREF_HSI48, EN_VREFINT
while(!(SYSCFG.CFGR3 & (1 << 26))); // REF_HSI48_RDYF
// Enable HSI48.
RCC->CRRCR |= 1 << 0; // HSI48ON
while(!(RCC->CRRCR & (1 << 1))); // HSI48RDY
// Select HSI48 for USB.
RCC->CCIPR |= 1 << 26;
#endif
}
#if defined(STM32F4)
void rcc_init(uint32_t osc_mhz, uint32_t sysclk_mhz) {
// Initialize flash.
flash_init();
uint32_t pll_mhz = sysclk_mhz > 192 / 2 ? sysclk_mhz * 2 : sysclk_mhz * 4;
uint32_t pllp = sysclk_mhz > 192 / 2 ? 0 : 1;
// Enable HSE.
RCC->CR |= 0x10000;
while(!(RCC->CR & 0x20000));
// Configure and enable PLL.
RCC->PLLCFGR = 0x20400000 | ((pll_mhz / 48) << 24) | (pllp << 16) | (pll_mhz << 6) | osc_mhz;
RCC->CR |= 0x1000000;
while(!(RCC->CR & 0x2000000));
// Switch to PLL.
RCC->CFGR |= 0x2;
while(!(RCC->CFGR & 0x8));
if(sysclk_mhz > 84) {
// Set APB1 prescaler to /4.
RCC->CFGR |= 5 << 10; // PPRE1
// Set APB2 prescaler to /2.
RCC->CFGR |= 4 << 13; // PPRE2
} else {
// Set APB1 prescaler to /2.
RCC->CFGR |= 4 << 10; // PPRE1
// Set APB2 prescaler to /1.
RCC->CFGR |= 0 << 13; // PPRE2
}
}
#endif
|