diff options
Diffstat (limited to 'lib/chibios/os/hal/ports/STM32/STM32H7xx/hal_lld.c')
-rw-r--r-- | lib/chibios/os/hal/ports/STM32/STM32H7xx/hal_lld.c | 432 |
1 files changed, 432 insertions, 0 deletions
diff --git a/lib/chibios/os/hal/ports/STM32/STM32H7xx/hal_lld.c b/lib/chibios/os/hal/ports/STM32/STM32H7xx/hal_lld.c new file mode 100644 index 000000000..0d64df9c9 --- /dev/null +++ b/lib/chibios/os/hal/ports/STM32/STM32H7xx/hal_lld.c | |||
@@ -0,0 +1,432 @@ | |||
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 STM32H7xx/hal_lld.c | ||
19 | * @brief STM32H7xx 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_CORE_CK; | ||
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 inline void init_bkp_domain(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 | |||
91 | /** | ||
92 | * @brief Initializes the PWR unit. | ||
93 | */ | ||
94 | static inline void init_pwr(void) { | ||
95 | #if 0 | ||
96 | PWR_TypeDef *pwr = PWR; /* For inspection.*/ | ||
97 | (void)pwr; | ||
98 | #endif | ||
99 | |||
100 | /* Lower C3 byte, it must be programmed at very first, then waiting for | ||
101 | power supply to stabilize.*/ | ||
102 | PWR->CR3 = STM32_PWR_CR3 & 0x000000FFU; | ||
103 | while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0) | ||
104 | ; /* CHTODO timeout handling.*/ | ||
105 | |||
106 | PWR->CR1 = STM32_PWR_CR1 | 0xF0000000U; | ||
107 | PWR->CR2 = STM32_PWR_CR2; | ||
108 | PWR->CR3 = STM32_PWR_CR3; /* Other bits, lower byte is not changed. */ | ||
109 | PWR->CPUCR = STM32_PWR_CPUCR; | ||
110 | PWR->D3CR = STM32_VOS; | ||
111 | #if !defined(STM32_ENFORCE_H7_REV_XY) | ||
112 | SYSCFG->PWRCR = STM32_ODEN; | ||
113 | #endif | ||
114 | while ((PWR->D3CR & PWR_D3CR_VOSRDY) == 0) | ||
115 | ; /* CHTODO timeout handling.*/ | ||
116 | #if STM32_PWR_CR2 & PWR_CR2_BREN | ||
117 | // while ((PWR->CR2 & PWR_CR2_BRRDY) == 0) | ||
118 | // ; | ||
119 | // rccEnableBKPRAM(true); | ||
120 | #endif | ||
121 | } | ||
122 | |||
123 | /*===========================================================================*/ | ||
124 | /* Driver interrupt handlers. */ | ||
125 | /*===========================================================================*/ | ||
126 | |||
127 | /*===========================================================================*/ | ||
128 | /* Driver exported functions. */ | ||
129 | /*===========================================================================*/ | ||
130 | |||
131 | /** | ||
132 | * @brief Low level HAL driver initialization. | ||
133 | * | ||
134 | * @notapi | ||
135 | */ | ||
136 | void hal_lld_init(void) { | ||
137 | |||
138 | #if STM32_NO_INIT == FALSE | ||
139 | /* Reset of all peripherals. AHB3 is not reset entirely because FMC could | ||
140 | have been initialized in the board initialization file (board.c). | ||
141 | Note, GPIOs are not reset because initialized before this point in | ||
142 | board files.*/ | ||
143 | rccResetAHB1(~0); | ||
144 | rccResetAHB2(~0); | ||
145 | rccResetAHB3(~(RCC_AHB3RSTR_FMCRST | | ||
146 | 0x80000000U)); /* Was RCC_AHB3RSTR_CPURST in Rev-V.*/ | ||
147 | rccResetAHB4(~(RCC_APB4RSTR_SYSCFGRST | STM32_GPIO_EN_MASK)); | ||
148 | rccResetAPB1L(~0); | ||
149 | rccResetAPB1H(~0); | ||
150 | rccResetAPB2(~0); | ||
151 | rccResetAPB3(~0); | ||
152 | rccResetAPB4(~0); | ||
153 | #endif /* STM32_NO_INIT == FALSE */ | ||
154 | |||
155 | /* DMA subsystems initialization.*/ | ||
156 | #if defined(STM32_BDMA_REQUIRED) | ||
157 | bdmaInit(); | ||
158 | #endif | ||
159 | #if defined(STM32_DMA_REQUIRED) | ||
160 | dmaInit(); | ||
161 | #endif | ||
162 | #if defined(STM32_MDMA_REQUIRED) | ||
163 | mdmaInit(); | ||
164 | #endif | ||
165 | |||
166 | /* IRQ subsystem initialization.*/ | ||
167 | irqInit(); | ||
168 | |||
169 | /* MPU initialization.*/ | ||
170 | #if (STM32_NOCACHE_SRAM1_SRAM2 == TRUE) || (STM32_NOCACHE_SRAM3 == TRUE) | ||
171 | { | ||
172 | uint32_t base, size; | ||
173 | |||
174 | #if (STM32_NOCACHE_SRAM1_SRAM2 == TRUE) && (STM32_NOCACHE_SRAM3 == TRUE) | ||
175 | base = 0x30000000U; | ||
176 | size = MPU_RASR_SIZE_512K; | ||
177 | #elif (STM32_NOCACHE_SRAM1_SRAM2 == TRUE) && (STM32_NOCACHE_SRAM3 == FALSE) | ||
178 | base = 0x30000000U; | ||
179 | size = MPU_RASR_SIZE_256K; | ||
180 | #elif (STM32_NOCACHE_SRAM1_SRAM2 == FALSE) && (STM32_NOCACHE_SRAM3 == TRUE) | ||
181 | base = 0x30040000U; | ||
182 | size = MPU_RASR_SIZE_16K; | ||
183 | #else | ||
184 | #error "invalid constants used in mcuconf.h" | ||
185 | #endif | ||
186 | |||
187 | /* The SRAM2 bank can optionally made a non cache-able area for use by | ||
188 | DMA engines.*/ | ||
189 | mpuConfigureRegion(STM32_NOCACHE_MPU_REGION, | ||
190 | base, | ||
191 | MPU_RASR_ATTR_AP_RW_RW | | ||
192 | MPU_RASR_ATTR_NON_CACHEABLE | | ||
193 | MPU_RASR_ATTR_S | | ||
194 | size | | ||
195 | MPU_RASR_ENABLE); | ||
196 | mpuEnable(MPU_CTRL_PRIVDEFENA); | ||
197 | |||
198 | /* Invalidating data cache to make sure that the MPU settings are taken | ||
199 | immediately.*/ | ||
200 | SCB_CleanInvalidateDCache(); | ||
201 | } | ||
202 | #endif | ||
203 | } | ||
204 | |||
205 | /** | ||
206 | * @brief STM32H7xx clocks and PLL initialization. | ||
207 | * @note All the involved constants come from the file @p board.h. | ||
208 | * @note This function should be invoked just after the system reset. | ||
209 | * | ||
210 | * @special | ||
211 | */ | ||
212 | void stm32_clock_init(void) { | ||
213 | #if STM32_NO_INIT == FALSE | ||
214 | uint32_t cfgr; | ||
215 | |||
216 | #if 0 | ||
217 | RCC_TypeDef *rcc = RCC; /* For inspection.*/ | ||
218 | (void)rcc; | ||
219 | #endif | ||
220 | |||
221 | #if defined(STM32_ENFORCE_H7_REV_XY) | ||
222 | /* Fix for errata 2.2.15: Reading from AXI SRAM might lead to data | ||
223 | read corruption. | ||
224 | AXI->TARG7_FN_MOD.*/ | ||
225 | *((volatile uint32_t *)(0x51000000 + 0x1108 + 0x7000)) = 0x00000001U; | ||
226 | #endif | ||
227 | |||
228 | /* SYSCFG clock enabled here because it is a multi-functional unit shared | ||
229 | among multiple drivers.*/ | ||
230 | rccEnableAPB4(RCC_APB4ENR_SYSCFGEN, true); | ||
231 | |||
232 | /* PWR initialization.*/ | ||
233 | init_pwr(); | ||
234 | |||
235 | /* Backup domain initialization.*/ | ||
236 | init_bkp_domain(); | ||
237 | |||
238 | /* HSI setup, it enforces the reset situation in order to handle possible | ||
239 | problems with JTAG probes and re-initializations.*/ | ||
240 | RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ | ||
241 | while (!(RCC->CR & RCC_CR_HSIRDY)) | ||
242 | ; /* Wait until HSI is stable. */ | ||
243 | |||
244 | /* HSI is selected as new source without touching the other fields in | ||
245 | CFGR. This is only required when using a debugger than can cause | ||
246 | restarts.*/ | ||
247 | RCC->CFGR = 0x00000000U; /* Reset SW to HSI. */ | ||
248 | while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) | ||
249 | ; /* Wait until HSI is selected. */ | ||
250 | |||
251 | /* Registers cleared to reset values.*/ | ||
252 | RCC->CR = RCC_CR_HSION; /* CR Reset value. */ | ||
253 | RCC->HSICFGR = 0x40000000U; /* HSICFGR Reset value. */ | ||
254 | #if !defined(STM32_ENFORCE_H7_REV_XY) | ||
255 | RCC->CSICFGR = 0x20000000U; /* CSICFGR Reset value. */ | ||
256 | #endif | ||
257 | RCC->CSR = 0x00000000U; /* CSR reset value. */ | ||
258 | RCC->PLLCFGR = 0x01FF0000U; /* PLLCFGR reset value. */ | ||
259 | |||
260 | /* Other clock-related settings, done before other things because | ||
261 | recommended in the RM.*/ | ||
262 | cfgr = STM32_MCO2SEL | RCC_CFGR_MCO2PRE_VALUE(STM32_MCO2PRE_VALUE) | | ||
263 | STM32_MCO1SEL | RCC_CFGR_MCO1PRE_VALUE(STM32_MCO1PRE_VALUE) | | ||
264 | RCC_CFGR_RTCPRE_VALUE(STM32_RTCPRE_VALUE) | | ||
265 | STM32_HRTIMSEL | STM32_STOPKERWUCK | STM32_STOPWUCK; | ||
266 | #if STM32_TIMPRE_ENABLE == TRUE | ||
267 | cfgr |= RCC_CFGR_TIMPRE; | ||
268 | #endif | ||
269 | RCC->CFGR = cfgr; | ||
270 | |||
271 | /* HSE activation with optional bypass.*/ | ||
272 | #if STM32_HSE_ENABLED == TRUE | ||
273 | #if defined(STM32_HSE_BYPASS) | ||
274 | RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; | ||
275 | #else | ||
276 | RCC->CR |= RCC_CR_HSEON; | ||
277 | #endif | ||
278 | while ((RCC->CR & RCC_CR_HSERDY) == 0) | ||
279 | ; /* Waits until HSE is stable. */ | ||
280 | #endif /* STM32_HSE_ENABLED == TRUE */ | ||
281 | |||
282 | /* HSI48 activation.*/ | ||
283 | #if STM32_HSI48_ENABLED == TRUE | ||
284 | RCC->CR |= RCC_CR_HSI48ON; | ||
285 | while ((RCC->CR & RCC_CR_HSI48RDY) == 0) | ||
286 | ; /* Waits until HSI48 is stable. */ | ||
287 | |||
288 | #endif /* STM32_HSI48_ENABLED == TRUE */ | ||
289 | |||
290 | /* CSI activation.*/ | ||
291 | #if STM32_CSI_ENABLED == TRUE | ||
292 | RCC->CR |= RCC_CR_CSION; | ||
293 | while ((RCC->CR & RCC_CR_CSIRDY) == 0) | ||
294 | ; /* Waits until CSI is stable. */ | ||
295 | #endif /* STM32_CSI_ENABLED == TRUE */ | ||
296 | |||
297 | /* LSI activation.*/ | ||
298 | #if STM32_LSI_ENABLED == TRUE | ||
299 | RCC->CSR |= RCC_CSR_LSION; | ||
300 | while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) | ||
301 | ; /* Waits until LSI is stable. */ | ||
302 | #endif /* STM32_LSI_ENABLED == TRUE */ | ||
303 | |||
304 | /* PLLs activation, it happens in parallel in order to | ||
305 | reduce boot time.*/ | ||
306 | #if (STM32_PLL1_ENABLED == TRUE) || \ | ||
307 | (STM32_PLL2_ENABLED == TRUE) || \ | ||
308 | (STM32_PLL3_ENABLED == TRUE) | ||
309 | { | ||
310 | uint32_t onmask = 0; | ||
311 | uint32_t rdymask = 0; | ||
312 | uint32_t cfgmask = 0; | ||
313 | |||
314 | RCC->PLLCKSELR = RCC_PLLCKSELR_DIVM3_VALUE(STM32_PLL3_DIVM_VALUE) | | ||
315 | RCC_PLLCKSELR_DIVM2_VALUE(STM32_PLL2_DIVM_VALUE) | | ||
316 | RCC_PLLCKSELR_DIVM1_VALUE(STM32_PLL1_DIVM_VALUE) | | ||
317 | RCC_PLLCKSELR_PLLSRC_VALUE(STM32_PLLSRC); | ||
318 | |||
319 | cfgmask = STM32_PLLCFGR_PLL3RGE | STM32_PLLCFGR_PLL3VCOSEL | RCC_PLLCFGR_PLL3FRACEN | | ||
320 | STM32_PLLCFGR_PLL2RGE | STM32_PLLCFGR_PLL2VCOSEL | RCC_PLLCFGR_PLL2FRACEN | | ||
321 | STM32_PLLCFGR_PLL1RGE | STM32_PLLCFGR_PLL1VCOSEL | RCC_PLLCFGR_PLL1FRACEN; | ||
322 | |||
323 | #if STM32_PLL1_ENABLED == TRUE | ||
324 | RCC->PLL1FRACR = STM32_PLL1_FRACN; | ||
325 | RCC->PLL1DIVR = STM32_PLL1_DIVR | STM32_PLL1_DIVQ | | ||
326 | STM32_PLL1_DIVP | STM32_PLL1_DIVN; | ||
327 | onmask |= RCC_CR_PLL1ON; | ||
328 | rdymask |= RCC_CR_PLL1RDY; | ||
329 | #if STM32_PLL1_P_ENABLED == TRUE | ||
330 | cfgmask |= RCC_PLLCFGR_DIVP1EN; | ||
331 | #endif | ||
332 | #if STM32_PLL1_Q_ENABLED == TRUE | ||
333 | cfgmask |= RCC_PLLCFGR_DIVQ1EN; | ||
334 | #endif | ||
335 | #if STM32_PLL1_R_ENABLED == TRUE | ||
336 | cfgmask |= RCC_PLLCFGR_DIVR1EN; | ||
337 | #endif | ||
338 | #endif /* STM32_PLL1_ENABLED == TRUE */ | ||
339 | |||
340 | #if STM32_PLL2_ENABLED == TRUE | ||
341 | RCC->PLL2FRACR = STM32_PLL2_FRACN; | ||
342 | RCC->PLL2DIVR = STM32_PLL2_DIVR | STM32_PLL2_DIVQ | | ||
343 | STM32_PLL2_DIVP | STM32_PLL2_DIVN; | ||
344 | onmask |= RCC_CR_PLL2ON; | ||
345 | rdymask |= RCC_CR_PLL2RDY; | ||
346 | #if STM32_PLL2_P_ENABLED == TRUE | ||
347 | cfgmask |= RCC_PLLCFGR_DIVP2EN; | ||
348 | #endif | ||
349 | #if STM32_PLL2_Q_ENABLED == TRUE | ||
350 | cfgmask |= RCC_PLLCFGR_DIVQ2EN; | ||
351 | #endif | ||
352 | #if STM32_PLL2_R_ENABLED == TRUE | ||
353 | cfgmask |= RCC_PLLCFGR_DIVR2EN; | ||
354 | #endif | ||
355 | #endif /* STM32_PLL2_ENABLED == TRUE */ | ||
356 | |||
357 | #if STM32_PLL3_ENABLED == TRUE | ||
358 | RCC->PLL3FRACR = STM32_PLL3_FRACN; | ||
359 | RCC->PLL3DIVR = STM32_PLL3_DIVR | STM32_PLL3_DIVQ | | ||
360 | STM32_PLL3_DIVP | STM32_PLL3_DIVN; | ||
361 | onmask |= RCC_CR_PLL3ON; | ||
362 | rdymask |= RCC_CR_PLL3RDY; | ||
363 | #if STM32_PLL3_P_ENABLED == TRUE | ||
364 | cfgmask |= RCC_PLLCFGR_DIVP3EN; | ||
365 | #endif | ||
366 | #if STM32_PLL3_Q_ENABLED == TRUE | ||
367 | cfgmask |= RCC_PLLCFGR_DIVQ3EN; | ||
368 | #endif | ||
369 | #if STM32_PLL3_R_ENABLED == TRUE | ||
370 | cfgmask |= RCC_PLLCFGR_DIVR3EN; | ||
371 | #endif | ||
372 | #endif /* STM32_PLL3_ENABLED == TRUE */ | ||
373 | |||
374 | /* Activating enabled PLLs and waiting for all of them to become ready.*/ | ||
375 | RCC->PLLCFGR = cfgmask & STM32_PLLCFGR_MASK; | ||
376 | RCC->CR |= onmask; | ||
377 | while ((RCC->CR & rdymask) != rdymask) | ||
378 | ; | ||
379 | } | ||
380 | #endif /* STM32_PLL1_ENABLED || STM32_PLL2_ENABLED || STM32_PLL3_ENABLED */ | ||
381 | |||
382 | /* AHB and APB dividers.*/ | ||
383 | RCC->D1CFGR = STM32_D1CPRE | STM32_D1PPRE3 | STM32_D1HPRE; | ||
384 | RCC->D2CFGR = STM32_D2PPRE2 | STM32_D2PPRE1; | ||
385 | RCC->D3CFGR = STM32_D3PPRE4; | ||
386 | |||
387 | /* Peripherals clocks.*/ | ||
388 | RCC->D1CCIPR = STM32_CKPERSEL | STM32_SDMMCSEL | STM32_QSPISEL | | ||
389 | STM32_FMCSEL; | ||
390 | RCC->D2CCIP1R = STM32_SWPSEL | STM32_FDCANSEL | STM32_DFSDM1SEL | | ||
391 | STM32_SPDIFSEL | STM32_SPDIFSEL | STM32_SPI45SEL | | ||
392 | STM32_SPI123SEL | STM32_SAI23SEL | STM32_SAI1SEL; | ||
393 | RCC->D2CCIP2R = STM32_LPTIM1SEL | STM32_CECSEL | STM32_USBSEL | | ||
394 | STM32_I2C123SEL | STM32_RNGSEL | STM32_USART16SEL | | ||
395 | STM32_USART234578SEL; | ||
396 | RCC->D3CCIPR = STM32_SPI6SEL | STM32_SAI4BSEL | STM32_SAI4ASEL | | ||
397 | STM32_ADCSEL | STM32_LPTIM345SEL | STM32_LPTIM2SEL | | ||
398 | STM32_I2C4SEL | STM32_LPUART1SEL; | ||
399 | |||
400 | /* Flash setup.*/ | ||
401 | FLASH->ACR = FLASH_ACR_WRHIGHFREQ_1 | FLASH_ACR_WRHIGHFREQ_0 | | ||
402 | STM32_FLASHBITS; | ||
403 | while ((FLASH->ACR & FLASH_ACR_LATENCY) != | ||
404 | (STM32_FLASHBITS & FLASH_ACR_LATENCY)) { | ||
405 | } | ||
406 | |||
407 | /* Switching to the configured clock source if it is different | ||
408 | from HSI.*/ | ||
409 | #if STM32_SW != STM32_SW_HSI_CK | ||
410 | RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ | ||
411 | while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 3U)) | ||
412 | ; | ||
413 | #endif | ||
414 | |||
415 | #if 0 | ||
416 | /* Peripheral clock sources.*/ | ||
417 | RCC->DCKCFGR2 = STM32_SDMMCSEL | STM32_CK48MSEL | STM32_CECSEL | | ||
418 | STM32_LPTIM1SEL | STM32_I2C4SEL | STM32_I2C3SEL | | ||
419 | STM32_I2C2SEL | STM32_I2C1SEL | STM32_UART8SEL | | ||
420 | STM32_UART7SEL | STM32_USART6SEL | STM32_UART5SEL | | ||
421 | STM32_UART4SEL | STM32_USART3SEL | STM32_USART2SEL | | ||
422 | STM32_USART1SEL; | ||
423 | #endif | ||
424 | |||
425 | /* RAM1 2 and 3 clocks enabled.*/ | ||
426 | rccEnableSRAM1(true); | ||
427 | rccEnableSRAM2(true); | ||
428 | rccEnableSRAM3(true); | ||
429 | #endif /* STM32_NO_INIT */ | ||
430 | } | ||
431 | |||
432 | /** @} */ | ||