diff options
Diffstat (limited to 'lib/chibios/os/hal/ports/STM32/STM32F7xx/hal_lld.c')
-rw-r--r-- | lib/chibios/os/hal/ports/STM32/STM32F7xx/hal_lld.c | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/lib/chibios/os/hal/ports/STM32/STM32F7xx/hal_lld.c b/lib/chibios/os/hal/ports/STM32/STM32F7xx/hal_lld.c new file mode 100644 index 000000000..1b4ee1329 --- /dev/null +++ b/lib/chibios/os/hal/ports/STM32/STM32F7xx/hal_lld.c | |||
@@ -0,0 +1,311 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * @file STM32F7xx/hal_lld.c | ||
19 | * @brief STM32F7xx HAL subsystem low level driver source. | ||
20 | * | ||
21 | * @addtogroup HAL | ||
22 | * @{ | ||
23 | */ | ||
24 | |||
25 | #include "hal.h" | ||
26 | |||
27 | /*===========================================================================*/ | ||
28 | /* Driver local definitions. */ | ||
29 | /*===========================================================================*/ | ||
30 | |||
31 | /*===========================================================================*/ | ||
32 | /* Driver exported variables. */ | ||
33 | /*===========================================================================*/ | ||
34 | |||
35 | /** | ||
36 | * @brief CMSIS system core clock variable. | ||
37 | * @note It is declared in system_stm32f7xx.h. | ||
38 | */ | ||
39 | uint32_t SystemCoreClock = STM32_HCLK; | ||
40 | |||
41 | /*===========================================================================*/ | ||
42 | /* Driver local variables and types. */ | ||
43 | /*===========================================================================*/ | ||
44 | |||
45 | /*===========================================================================*/ | ||
46 | /* Driver local functions. */ | ||
47 | /*===========================================================================*/ | ||
48 | |||
49 | /** | ||
50 | * @brief Initializes the backup domain. | ||
51 | * @note WARNING! Changing clock source impossible without resetting | ||
52 | * of the whole BKP domain. | ||
53 | */ | ||
54 | static void hal_lld_backup_domain_init(void) { | ||
55 | |||
56 | /* Backup domain access enabled and left open.*/ | ||
57 | PWR->CR1 |= PWR_CR1_DBP; | ||
58 | |||
59 | /* Reset BKP domain if different clock source selected.*/ | ||
60 | if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { | ||
61 | /* Backup domain reset.*/ | ||
62 | RCC->BDCR = RCC_BDCR_BDRST; | ||
63 | RCC->BDCR = 0; | ||
64 | } | ||
65 | |||
66 | #if STM32_LSE_ENABLED | ||
67 | #if defined(STM32_LSE_BYPASS) | ||
68 | /* LSE Bypass.*/ | ||
69 | RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; | ||
70 | #else | ||
71 | /* No LSE Bypass.*/ | ||
72 | RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; | ||
73 | #endif | ||
74 | while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) | ||
75 | ; /* Waits until LSE is stable. */ | ||
76 | #endif | ||
77 | |||
78 | #if HAL_USE_RTC | ||
79 | /* If the backup domain hasn't been initialized yet then proceed with | ||
80 | initialization.*/ | ||
81 | if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { | ||
82 | /* Selects clock source.*/ | ||
83 | RCC->BDCR |= STM32_RTCSEL; | ||
84 | |||
85 | /* RTC clock enabled.*/ | ||
86 | RCC->BDCR |= RCC_BDCR_RTCEN; | ||
87 | } | ||
88 | #endif /* HAL_USE_RTC */ | ||
89 | |||
90 | #if STM32_BKPRAM_ENABLE | ||
91 | rccEnableBKPSRAM(true); | ||
92 | |||
93 | PWR->CSR1 |= PWR_CSR1_BRE; | ||
94 | while ((PWR->CSR1 & PWR_CSR1_BRR) == 0) | ||
95 | ; /* Waits until the regulator is stable */ | ||
96 | #else | ||
97 | PWR->CSR1 &= ~PWR_CSR1_BRE; | ||
98 | #endif /* STM32_BKPRAM_ENABLE */ | ||
99 | } | ||
100 | |||
101 | /*===========================================================================*/ | ||
102 | /* Driver interrupt handlers. */ | ||
103 | /*===========================================================================*/ | ||
104 | |||
105 | /*===========================================================================*/ | ||
106 | /* Driver exported functions. */ | ||
107 | /*===========================================================================*/ | ||
108 | |||
109 | /** | ||
110 | * @brief Low level HAL driver initialization. | ||
111 | * | ||
112 | * @notapi | ||
113 | */ | ||
114 | void hal_lld_init(void) { | ||
115 | |||
116 | /* Reset of all peripherals. AHB3 is not reseted because it could have | ||
117 | been initialized in the board initialization file (board.c). | ||
118 | Note, GPIOs are not reset because initialized before this point in | ||
119 | board files.*/ | ||
120 | rccResetAHB1(~STM32_GPIO_EN_MASK); | ||
121 | rccResetAHB2(~0); | ||
122 | rccResetAPB1(~RCC_APB1RSTR_PWRRST); | ||
123 | rccResetAPB2(~0); | ||
124 | |||
125 | /* Initializes the backup domain.*/ | ||
126 | hal_lld_backup_domain_init(); | ||
127 | |||
128 | /* DMA subsystems initialization.*/ | ||
129 | #if defined(STM32_DMA_REQUIRED) | ||
130 | dmaInit(); | ||
131 | #endif | ||
132 | |||
133 | /* IRQ subsystem initialization.*/ | ||
134 | irqInit(); | ||
135 | |||
136 | #if STM32_SRAM2_NOCACHE | ||
137 | /* The SRAM2 bank can optionally made a non cache-able area for use by | ||
138 | DMA engines.*/ | ||
139 | mpuConfigureRegion(MPU_REGION_7, | ||
140 | SRAM2_BASE, | ||
141 | MPU_RASR_ATTR_AP_RW_RW | | ||
142 | MPU_RASR_ATTR_NON_CACHEABLE | | ||
143 | MPU_RASR_SIZE_16K | | ||
144 | MPU_RASR_ENABLE); | ||
145 | mpuEnable(MPU_CTRL_PRIVDEFENA); | ||
146 | |||
147 | /* Invalidating data cache to make sure that the MPU settings are taken | ||
148 | immediately.*/ | ||
149 | SCB_CleanInvalidateDCache(); | ||
150 | #endif | ||
151 | |||
152 | /* Programmable voltage detector enable.*/ | ||
153 | #if STM32_PVD_ENABLE | ||
154 | PWR->CR1 |= PWR_CR1_PVDE | (STM32_PLS & STM32_PLS_MASK); | ||
155 | #endif /* STM32_PVD_ENABLE */ | ||
156 | } | ||
157 | |||
158 | /** | ||
159 | * @brief STM32F2xx clocks and PLL initialization. | ||
160 | * @note All the involved constants come from the file @p board.h. | ||
161 | * @note This function should be invoked just after the system reset. | ||
162 | * | ||
163 | * @special | ||
164 | */ | ||
165 | void stm32_clock_init(void) { | ||
166 | |||
167 | #if !STM32_NO_INIT | ||
168 | /* PWR clock enabled.*/ | ||
169 | #if defined(HAL_USE_RTC) && defined(RCC_APB1ENR_RTCEN) | ||
170 | RCC->APB1ENR = RCC_APB1ENR_PWREN | RCC_APB1ENR_RTCEN; | ||
171 | #else | ||
172 | RCC->APB1ENR = RCC_APB1ENR_PWREN; | ||
173 | #endif | ||
174 | |||
175 | /* PWR initialization.*/ | ||
176 | PWR->CR1 = STM32_VOS; | ||
177 | |||
178 | /* HSI setup, it enforces the reset situation in order to handle possible | ||
179 | problems with JTAG probes and re-initializations.*/ | ||
180 | RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ | ||
181 | while (!(RCC->CR & RCC_CR_HSIRDY)) | ||
182 | ; /* Wait until HSI is stable. */ | ||
183 | |||
184 | /* HSI is selected as new source without touching the other fields in | ||
185 | CFGR. Clearing the register has to be postponed after HSI is the | ||
186 | new source.*/ | ||
187 | RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */ | ||
188 | while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) | ||
189 | ; /* Wait until HSI is selected. */ | ||
190 | |||
191 | /* Registers finally cleared to reset values.*/ | ||
192 | RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ | ||
193 | RCC->CFGR = 0; /* CFGR reset value. */ | ||
194 | |||
195 | #if STM32_HSE_ENABLED | ||
196 | /* HSE activation.*/ | ||
197 | #if defined(STM32_HSE_BYPASS) | ||
198 | /* HSE Bypass.*/ | ||
199 | RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; | ||
200 | #else | ||
201 | /* No HSE Bypass.*/ | ||
202 | RCC->CR |= RCC_CR_HSEON; | ||
203 | #endif | ||
204 | while ((RCC->CR & RCC_CR_HSERDY) == 0) | ||
205 | ; /* Waits until HSE is stable. */ | ||
206 | #endif | ||
207 | |||
208 | #if STM32_LSI_ENABLED | ||
209 | /* LSI activation.*/ | ||
210 | RCC->CSR |= RCC_CSR_LSION; | ||
211 | while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) | ||
212 | ; /* Waits until LSI is stable. */ | ||
213 | #endif | ||
214 | |||
215 | #if STM32_ACTIVATE_PLL | ||
216 | /* PLL activation.*/ | ||
217 | RCC->PLLCFGR = STM32_PLLQ | STM32_PLLSRC | STM32_PLLP | STM32_PLLN | | ||
218 | STM32_PLLM; | ||
219 | RCC->CR |= RCC_CR_PLLON; | ||
220 | |||
221 | /* Synchronization with voltage regulator stabilization.*/ | ||
222 | while ((PWR->CSR1 & PWR_CSR1_VOSRDY) == 0) | ||
223 | ; /* Waits until power regulator is stable. */ | ||
224 | |||
225 | #if STM32_OVERDRIVE_REQUIRED | ||
226 | /* Overdrive activation performed after activating the PLL in order to save | ||
227 | time as recommended in RM in "Entering Over-drive mode" paragraph.*/ | ||
228 | PWR->CR1 |= PWR_CR1_ODEN; | ||
229 | while (!(PWR->CSR1 & PWR_CSR1_ODRDY)) | ||
230 | ; | ||
231 | PWR->CR1 |= PWR_CR1_ODSWEN; | ||
232 | while (!(PWR->CSR1 & PWR_CSR1_ODSWRDY)) | ||
233 | ; | ||
234 | #endif /* STM32_OVERDRIVE_REQUIRED */ | ||
235 | |||
236 | /* Waiting for PLL lock.*/ | ||
237 | while (!(RCC->CR & RCC_CR_PLLRDY)) | ||
238 | ; | ||
239 | #endif /* STM32_OVERDRIVE_REQUIRED */ | ||
240 | |||
241 | #if STM32_ACTIVATE_PLLI2S | ||
242 | /* PLLI2S activation.*/ | ||
243 | RCC->PLLI2SCFGR = STM32_PLLI2SR | STM32_PLLI2SQ | STM32_PLLI2SP | | ||
244 | STM32_PLLI2SN; | ||
245 | RCC->CR |= RCC_CR_PLLI2SON; | ||
246 | |||
247 | /* Waiting for PLL lock.*/ | ||
248 | while (!(RCC->CR & RCC_CR_PLLI2SRDY)) | ||
249 | ; | ||
250 | #endif | ||
251 | |||
252 | #if STM32_ACTIVATE_PLLSAI | ||
253 | /* PLLSAI activation.*/ | ||
254 | RCC->PLLSAICFGR = STM32_PLLSAIR | STM32_PLLSAIQ | STM32_PLLSAIP | | ||
255 | STM32_PLLSAIN; | ||
256 | RCC->CR |= RCC_CR_PLLSAION; | ||
257 | |||
258 | /* Waiting for PLL lock.*/ | ||
259 | while (!(RCC->CR & RCC_CR_PLLSAIRDY)) | ||
260 | ; | ||
261 | #endif | ||
262 | |||
263 | /* Other clock-related settings (dividers, MCO etc).*/ | ||
264 | RCC->CFGR = STM32_MCO2SEL | STM32_MCO2PRE | STM32_MCO1PRE | STM32_I2SSRC | | ||
265 | STM32_MCO1SEL | STM32_RTCPRE | STM32_PPRE2 | STM32_PPRE1 | | ||
266 | STM32_HPRE; | ||
267 | |||
268 | /* DCKCFGR1 register initialization, note, must take care of the _OFF | ||
269 | pseudo settings.*/ | ||
270 | { | ||
271 | uint32_t dckcfgr1 = STM32_PLLI2SDIVQ | STM32_PLLSAIDIVQ | STM32_PLLSAIDIVR; | ||
272 | #if STM32_SAI2SEL != STM32_SAI2SEL_OFF | ||
273 | dckcfgr1 |= STM32_SAI2SEL; | ||
274 | #endif | ||
275 | #if STM32_SAI1SEL != STM32_SAI1SEL_OFF | ||
276 | dckcfgr1 |= STM32_SAI1SEL; | ||
277 | #endif | ||
278 | #if STM32_TIMPRE_ENABLE == TRUE | ||
279 | dckcfgr1 |= RCC_DCKCFGR1_TIMPRE; | ||
280 | #endif | ||
281 | RCC->DCKCFGR1 = dckcfgr1; | ||
282 | } | ||
283 | |||
284 | /* Peripheral clock sources.*/ | ||
285 | RCC->DCKCFGR2 = STM32_SDMMC2SEL | STM32_SDMMC1SEL | STM32_CK48MSEL | | ||
286 | STM32_CECSEL | STM32_LPTIM1SEL | STM32_I2C4SEL | | ||
287 | STM32_I2C3SEL | STM32_I2C2SEL | STM32_I2C1SEL | | ||
288 | STM32_UART8SEL | STM32_UART7SEL | STM32_USART6SEL | | ||
289 | STM32_UART5SEL | STM32_UART4SEL | STM32_USART3SEL | | ||
290 | STM32_USART2SEL | STM32_USART1SEL; | ||
291 | |||
292 | /* Flash setup.*/ | ||
293 | FLASH->ACR = FLASH_ACR_ARTEN | FLASH_ACR_PRFTEN | STM32_FLASHBITS; | ||
294 | while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != | ||
295 | (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { | ||
296 | } | ||
297 | |||
298 | /* Switching to the configured clock source if it is different from HSI.*/ | ||
299 | #if (STM32_SW != STM32_SW_HSI) | ||
300 | RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ | ||
301 | while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) | ||
302 | ; | ||
303 | #endif | ||
304 | #endif /* STM32_NO_INIT */ | ||
305 | |||
306 | /* SYSCFG clock enabled here because it is a multi-functional unit shared | ||
307 | among multiple drivers.*/ | ||
308 | rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); | ||
309 | } | ||
310 | |||
311 | /** @} */ | ||