aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios/os/hal/ports/STM32/STM32H7xx/hal_lld.c
diff options
context:
space:
mode:
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.c432
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 */
39uint32_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 */
54static 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 */
94static 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 */
136void 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 */
212void 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/** @} */