add SPL06 in Matek targets
[inav/snaewe.git] / src / main / target / system_stm32h7xx.c
blobce16a546ffad95a00ec904970b945fcc0e23e75f
1 /**
2 ******************************************************************************
3 * @file system_stm32h7xx.c
4 * @author MCD Application Team
5 * @brief CMSIS Cortex-Mx Device Peripheral Access Layer System Source File.
7 * This file provides two functions and one global variable to be called from
8 * user application:
9 * - SystemInit(): This function is called at startup just after reset and
10 * before branch to main program. This call is made inside
11 * the "startup_stm32h7xx.s" file.
13 * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
14 * by the user application to setup the SysTick
15 * timer or configure other parameters.
17 * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
18 * be called whenever the core clock is changed
19 * during program execution.
22 ******************************************************************************
23 * @attention
25 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
27 * Redistribution and use in source and binary forms, with or without modification,
28 * are permitted provided that the following conditions are met:
29 * 1. Redistributions of source code must retain the above copyright notice,
30 * this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright notice,
32 * this list of conditions and the following disclaimer in the documentation
33 * and/or other materials provided with the distribution.
34 * 3. Neither the name of STMicroelectronics nor the names of its contributors
35 * may be used to endorse or promote products derived from this software
36 * without specific prior written permission.
38 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
39 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
44 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
45 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49 ******************************************************************************
52 /** @addtogroup CMSIS
53 * @{
56 /** @addtogroup stm32h7xx_system
57 * @{
60 /** @addtogroup STM32H7xx_System_Private_Includes
61 * @{
64 #include "stm32h7xx.h"
65 #include "platform.h"
66 #include "string.h"
67 #include "common/utils.h"
68 #include "drivers/system.h"
69 #include "build/debug.h"
71 void forcedSystemResetWithoutDisablingCaches(void);
73 #if !defined (HSE_VALUE)
74 #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
75 #endif /* HSE_VALUE */
77 #if !defined (CSI_VALUE)
78 #define CSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/
79 #endif /* CSI_VALUE */
81 #if !defined (HSI_VALUE)
82 #define HSI_VALUE ((uint32_t)64000000) /*!< Value of the Internal oscillator in Hz*/
83 #endif /* HSI_VALUE */
86 /**
87 * @}
90 /** @addtogroup STM32H7xx_System_Private_TypesDefinitions
91 * @{
94 /**
95 * @}
98 /** @addtogroup STM32H7xx_System_Private_Defines
99 * @{
102 /************************* Miscellaneous Configuration ************************/
103 /*!< Uncomment the following line if you need to use external SRAM or SDRAM mounted
104 on EVAL board as data memory */
105 /*#define DATA_IN_ExtSRAM */
106 /*#define DATA_IN_ExtSDRAM*/
108 #if defined(DATA_IN_ExtSRAM) && defined(DATA_IN_ExtSDRAM)
109 #error "Please select DATA_IN_ExtSRAM or DATA_IN_ExtSDRAM "
110 #endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */
112 /*!< Uncomment the following line if you need to relocate your vector Table in
113 Internal SRAM. */
114 /* #define VECT_TAB_SRAM */
115 #define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
116 This value must be a multiple of 0x200. */
117 /******************************************************************************/
120 * @}
123 /** @addtogroup STM32H7xx_System_Private_Macros
124 * @{
128 * @}
131 /** @addtogroup STM32H7xx_System_Private_Variables
132 * @{
134 /* This variable is updated in three ways:
135 1) by calling CMSIS function SystemCoreClockUpdate()
136 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
137 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
138 Note: If you use this function to configure the system clock; then there
139 is no need to call the 2 first functions listed above, since SystemCoreClock
140 variable is updated automatically.
142 uint32_t SystemCoreClock = 64000000;
143 uint32_t SystemD2Clock = 64000000;
144 const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
147 * @}
150 /** @addtogroup STM32H7xx_System_Private_FunctionPrototypes
151 * @{
153 #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
154 static void SystemInit_ExtMemCtl(void);
155 #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
158 * @}
161 /** @addtogroup STM32H7xx_System_Private_Functions
162 * @{
165 static void Error_Handler(void)
167 while (1);
170 void HandleStuckSysTick(void)
172 uint32_t tickStart = HAL_GetTick();
173 uint32_t tickEnd = 0;
175 int attemptsRemaining = 80 * 1000;
176 while (((tickEnd = HAL_GetTick()) == tickStart) && --attemptsRemaining) {
177 // H7 at 400Mhz - attemptsRemaining was reduced by debug build: 5,550, release build: 33,245
180 if (tickStart == tickEnd) {
181 forcedSystemResetWithoutDisablingCaches();
185 typedef struct pllConfig_s {
186 uint16_t clockMhz;
187 uint8_t m;
188 uint16_t n;
189 uint8_t p;
190 uint8_t q;
191 uint8_t r;
192 uint32_t vos;
193 } pllConfig_t;
196 PLL1 configuration for different silicon revisions.
198 Note for future overclocking support.
200 - Rev.Y (and Rev.X), nominal max at 400MHz, runs stably overclocked to 480MHz.
201 - Rev.V, nominal max at 480MHz, runs stably at 540MHz, but not to 600MHz (VCO probably out of operating range)
203 - A possible frequency table would look something like this, and a revision
204 check logic would place a cap for Rev.Y and V.
206 400 420 440 460 (Rev.Y & V ends here) 480 500 520 540
209 // 400MHz for Rev.Y (and Rev.X)
210 pllConfig_t pll1ConfigRevY = {
211 .clockMhz = 400,
212 .m = 4,
213 .n = 400,
214 .p = 2,
215 .q = 8,
216 .r = 5,
217 .vos = PWR_REGULATOR_VOLTAGE_SCALE1
220 // 480MHz for Rev.V
221 pllConfig_t pll1ConfigRevV = {
222 .clockMhz = 480,
223 .m = 4,
224 .n = 480,
225 .p = 2,
226 .q = 8,
227 .r = 5,
228 .vos = PWR_REGULATOR_VOLTAGE_SCALE0
231 // HSE clock configuration, originally taken from
232 // STM32Cube_FW_H7_V1.3.0/Projects/STM32H743ZI-Nucleo/Examples/RCC/RCC_ClockConfig/Src/main.c
234 static void SystemClockHSE_Config(void)
236 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
237 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
239 #ifdef notdef
240 // CSI has been disabled at SystemInit().
241 // HAL_RCC_ClockConfig() will fail because CSIRDY is off.
243 /* -1- Select CSI as system clock source to allow modification of the PLL configuration */
245 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
246 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_CSI;
247 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) {
248 /* Initialization Error */
249 Error_Handler();
251 #endif
253 #ifdef USE_H7_LEGACY_CPU_REVISION_SPEED
254 pllConfig_t *pll1Config = &pll1ConfigRevY;
255 #else
256 pllConfig_t *pll1Config = (HAL_GetREVID() == REV_ID_V) ? &pll1ConfigRevV : &pll1ConfigRevY;
257 #endif
259 // Configure voltage scale.
260 // It has been pre-configured at PWR_REGULATOR_VOLTAGE_SCALE1,
261 // and it may stay or overridden by PWR_REGULATOR_VOLTAGE_SCALE0 depending on the clock config.
263 __HAL_PWR_VOLTAGESCALING_CONFIG(pll1Config->vos);
265 while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {
266 // Empty
269 /* -2- Enable HSE Oscillator, select it as PLL source and finally activate the PLL */
271 #define USE_H7_HSERDY_SLOW_WORKAROUND
272 #ifdef USE_H7_HSERDY_SLOW_WORKAROUND
274 // With reference to 2.3.22 in the ES0250 Errata for the L476.
275 // Applying the same workaround here in the vain hopes that it improves startup times.
276 // Randomly the HSERDY bit takes AGES, over 10 seconds, to be set.
278 __HAL_RCC_GPIOH_CLK_ENABLE();
280 HAL_GPIO_WritePin(GPIOH, GPIO_PIN_0 | GPIO_PIN_1, GPIO_PIN_RESET);
282 GPIO_InitTypeDef gpio_initstruct;
283 gpio_initstruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
284 gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP;
285 gpio_initstruct.Pull = GPIO_NOPULL;
286 gpio_initstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
288 HAL_GPIO_Init(GPIOH, &gpio_initstruct);
289 #endif
291 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
292 RCC_OscInitStruct.HSEState = RCC_HSE_ON; // Even Nucleo-H473 work without RCC_HSE_BYPASS
294 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
295 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
296 RCC_OscInitStruct.PLL.PLLM = pll1Config->m;
297 RCC_OscInitStruct.PLL.PLLN = pll1Config->n;
298 RCC_OscInitStruct.PLL.PLLP = pll1Config->p;
299 RCC_OscInitStruct.PLL.PLLQ = pll1Config->q;
300 RCC_OscInitStruct.PLL.PLLR = pll1Config->r;
302 RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
303 RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
305 HAL_StatusTypeDef status = HAL_RCC_OscConfig(&RCC_OscInitStruct);
307 #define USE_H7_HSE_TIMEOUT_WORKAROUND
308 #ifdef USE_H7_HSE_TIMEOUT_WORKAROUND
309 if (status == HAL_TIMEOUT) {
310 forcedSystemResetWithoutDisablingCaches(); // DC - sometimes HSERDY gets stuck, waiting longer doesn't help.
312 #endif
314 if (status != HAL_OK) {
315 /* Initialization Error */
316 Error_Handler();
319 // Configure PLL2 and PLL3
320 // Use of PLL2 and PLL3 are not determined yet.
321 // A review of total system wide clock requirements is necessary.
324 // Configure SCGU (System Clock Generation Unit)
325 // Select PLL as system clock source and configure bus clock dividers.
327 // Clock type and divider member names do not have direct visual correspondence.
328 // Here is how these correspond:
329 // RCC_CLOCKTYPE_SYSCLK sys_ck
330 // RCC_CLOCKTYPE_HCLK AHBx (rcc_hclk1,rcc_hclk2,rcc_hclk3,rcc_hclk4)
331 // RCC_CLOCKTYPE_D1PCLK1 APB3 (rcc_pclk3)
332 // RCC_CLOCKTYPE_PCLK1 APB1 (rcc_pclk1)
333 // RCC_CLOCKTYPE_PCLK2 APB2 (rcc_pclk2)
334 // RCC_CLOCKTYPE_D3PCLK1 APB4 (rcc_pclk4)
336 RCC_ClkInitStruct.ClockType = ( \
337 RCC_CLOCKTYPE_SYSCLK | \
338 RCC_CLOCKTYPE_HCLK | \
339 RCC_CLOCKTYPE_D1PCLK1 | \
340 RCC_CLOCKTYPE_PCLK1 | \
341 RCC_CLOCKTYPE_PCLK2 | \
342 RCC_CLOCKTYPE_D3PCLK1);
343 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // = PLL1P = 400
344 RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; // = PLL1P(400) / 1 = 400
345 RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; // = SYSCLK(400) / 2 = 200
346 RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; // = HCLK(200) / 2 = 100
347 RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; // = HCLK(200) / 2 = 100
348 RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; // = HCLK(200) / 2 = 100
349 RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; // = HCLK(200) / 2 = 100
351 // For HCLK=200MHz with VOS1 range, ST recommended flash latency is 2WS.
352 // RM0433 (Rev.5) Table 12. FLASH recommended number of wait states and programming delay
354 // For higher HCLK frequency, VOS0 is available on RevV silicons, with FLASH wait states 4WS
355 // AN5312 (Rev.1) Section 1.2.1 Voltage scaling Table.1
357 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
358 /* Initialization Error */
359 Error_Handler();
362 /* -4- Optional: Disable CSI Oscillator (if the HSI is no more needed by the application)*/
363 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_CSI;
364 RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
365 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
366 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
367 /* Initialization Error */
368 Error_Handler();
372 void SystemClock_Config(void)
374 // Configure power supply
376 HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
378 // Pre-configure voltage scale to PWR_REGULATOR_VOLTAGE_SCALE1.
379 // SystemClockHSE_Config may configure PWR_REGULATOR_VOLTAGE_SCALE0.
381 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
383 while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {
384 // Empty
387 SystemClockHSE_Config();
389 /*activate CSI clock mondatory for I/O Compensation Cell*/
391 __HAL_RCC_CSI_ENABLE() ;
393 /* Enable SYSCFG clock mondatory for I/O Compensation Cell */
395 __HAL_RCC_SYSCFG_CLK_ENABLE() ;
397 /* Enables the I/O Compensation Cell */
399 HAL_EnableCompensationCell();
401 HandleStuckSysTick();
403 HAL_Delay(10);
405 // Configure peripheral clocks
407 RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
409 // Configure HSI48 as peripheral clock for USB
411 RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
412 RCC_PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
413 HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
415 // Configure CRS for dynamic calibration of HSI48
416 // While ES0392 Rev 5 "STM32H742xI/G and STM32H743xI/G device limitations" states CRS not working for REV.Y,
417 // it is always turned on as it seems that it has no negative effect on clock accuracy.
419 RCC_CRSInitTypeDef crsInit = {
420 .Prescaler = RCC_CRS_SYNC_DIV1,
421 .Source = RCC_CRS_SYNC_SOURCE_USB2,
422 .Polarity = RCC_CRS_SYNC_POLARITY_RISING,
423 .ReloadValue = RCC_CRS_RELOADVALUE_DEFAULT,
424 .ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT,
425 .HSI48CalibrationValue = RCC_CRS_HSI48CALIBRATION_DEFAULT,
428 __HAL_RCC_CRS_CLK_ENABLE();
429 HAL_RCCEx_CRSConfig(&crsInit);
431 #ifdef USE_CRS_INTERRUPTS
432 // Turn on USE_CRS_INTERRUPTS to see CRS in action
433 HAL_NVIC_SetPriority(CRS_IRQn, 6, 0);
434 HAL_NVIC_EnableIRQ(CRS_IRQn);
435 __HAL_RCC_CRS_ENABLE_IT(RCC_CRS_IT_SYNCOK|RCC_CRS_IT_SYNCWARN|RCC_CRS_IT_ESYNC|RCC_CRS_IT_ERR);
436 #endif
438 // Configure UART peripheral clock sources
440 // Possible sources:
441 // D2PCLK1 (pclk1 for APB1 = USART234578)
442 // D2PCLK2 (pclk2 for APB2 = USART16)
443 // PLL2 (pll2_q_ck)
444 // PLL3 (pll3_q_ck),
445 // HSI (hsi_ck),
446 // CSI (csi_ck),LSE(lse_ck);
448 RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART16|RCC_PERIPHCLK_USART234578;
449 RCC_PeriphClkInit.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;
450 RCC_PeriphClkInit.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1;
451 HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
453 // Configure SPI peripheral clock sources
455 // Possible sources for SPI123:
456 // PLL (pll1_q_ck)
457 // PLL2 (pll2_p_ck)
458 // PLL3 (pll3_p_ck)
459 // PIN (I2S_CKIN)
460 // CLKP (per_ck)
461 // Possible sources for SPI45:
462 // D2PCLK1 (rcc_pclk2 = APB1) 100MHz
463 // PLL2 (pll2_q_ck)
464 // PLL3 (pll3_q_ck)
465 // HSI (hsi_ker_ck)
466 // CSI (csi_ker_ck)
467 // HSE (hse_ck)
468 // Possible sources for SPI6:
469 // D3PCLK1 (rcc_pclk4 = APB4) 100MHz
470 // PLL2 (pll2_q_ck)
471 // PLL3 (pll3_q_ck)
472 // HSI (hsi_ker_ck)
473 // CSI (csi_ker_ck)
474 // HSE (hse_ck)
476 // For the first cut, we use 100MHz from various sources
477 RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI123|RCC_PERIPHCLK_SPI45|RCC_PERIPHCLK_SPI6;
478 RCC_PeriphClkInit.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
479 RCC_PeriphClkInit.Spi45ClockSelection = RCC_SPI45CLKSOURCE_D2PCLK1;
480 RCC_PeriphClkInit.Spi6ClockSelection = RCC_SPI6CLKSOURCE_D3PCLK1;
481 HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
483 // Configure I2C peripheral clock sources
485 // Current source for I2C123:
486 // D2PCLK1 (rcc_pclk1 = APB1 peripheral clock)
488 // Current source for I2C4:
489 // D3PCLK1 (rcc_pclk4 = APB4 peripheral clock)
491 // Note that peripheral clock determination in bus_i2c_hal_init.c must be modified when the sources are modified.
493 RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C123|RCC_PERIPHCLK_I2C4;
494 RCC_PeriphClkInit.I2c123ClockSelection = RCC_I2C123CLKSOURCE_D2PCLK1;
495 RCC_PeriphClkInit.I2c4ClockSelection = RCC_I2C4CLKSOURCE_D3PCLK1;
496 HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
498 #ifdef USE_SDCARD_SDIO
499 RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SDMMC;
500 RCC_PeriphClkInit.PLL2.PLL2M = 5;
501 RCC_PeriphClkInit.PLL2.PLL2N = 500;
502 RCC_PeriphClkInit.PLL2.PLL2P = 2; // 500Mhz
503 RCC_PeriphClkInit.PLL2.PLL2Q = 3; // 266Mhz - 133Mhz can be derived from this for for QSPI if flash chip supports the speed.
504 RCC_PeriphClkInit.PLL2.PLL2R = 4; // 200Mhz HAL LIBS REQUIRE 200MHZ SDMMC CLOCK, see HAL_SD_ConfigWideBusOperation, SDMMC_HSpeed_CLK_DIV, SDMMC_NSpeed_CLK_DIV
505 RCC_PeriphClkInit.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_0;
506 RCC_PeriphClkInit.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
507 RCC_PeriphClkInit.PLL2.PLL2FRACN = 0;
508 RCC_PeriphClkInit.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL2;
509 HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
510 #endif
512 // Configure MCO clocks for clock test/verification
514 // Possible sources for MCO1:
515 // RCC_MCO1SOURCE_HSI (hsi_ck)
516 // RCC_MCO1SOURCE_LSE (?)
517 // RCC_MCO1SOURCE_HSE (hse_ck)
518 // RCC_MCO1SOURCE_PLL1QCLK (pll1_q_ck)
519 // RCC_MCO1SOURCE_HSI48 (hsi48_ck)
521 // HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1); // HSE(8M) / 1 = 1M
522 HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI48, RCC_MCODIV_4); // HSI48(48M) / 4 = 12M
524 // Possible sources for MCO2:
525 // RCC_MCO2SOURCE_SYSCLK (sys_ck)
526 // RCC_MCO2SOURCE_PLL2PCLK (pll2_p_ck)
527 // RCC_MCO2SOURCE_HSE (hse_ck)
528 // RCC_MCO2SOURCE_PLLCLK (pll1_p_ck)
529 // RCC_MCO2SOURCE_CSICLK (csi_ck)
530 // RCC_MCO2SOURCE_LSICLK (lsi_ck)
532 HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO2SOURCE_PLLCLK, RCC_MCODIV_15); // PLL1P(400M) / 15 = 26.67M
535 #ifdef USE_CRS_INTERRUPTS
536 static uint32_t crs_syncok = 0;
537 static uint32_t crs_syncwarn = 0;
538 static uint32_t crs_expectedsync = 0;
539 static uint32_t crs_error = 0;
541 void HAL_RCCEx_CRS_SyncOkCallback(void)
543 ++crs_syncok;
546 void HAL_RCCEx_CRS_SyncWarnCallback(void)
548 ++crs_syncwarn;
551 void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
553 ++crs_expectedsync;
556 void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
558 ++crs_error;
561 void CRS_IRQHandler(void)
563 HAL_RCCEx_CRS_IRQHandler();
565 #endif
567 #include "build/debug.h"
569 void systemCheckResetReason(void);
571 #include "drivers/memprot.h"
573 void SystemInit (void)
575 memProtReset();
577 initialiseMemorySections();
579 // FPU settings
580 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
581 SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); // Set CP10 and CP11 Full Access
582 #endif
584 // Reset the RCC clock configuration to the default reset state
585 // Set HSION bit
586 RCC->CR = RCC_CR_HSION;
588 // Reset CFGR register
589 RCC->CFGR = 0x00000000;
591 // Reset HSEON, CSSON , CSION,RC48ON, CSIKERON PLL1ON, PLL2ON and PLL3ON bits
593 // XXX Don't do this until we are established with clock handling
594 // RCC->CR &= (uint32_t)0xEAF6ED7F;
596 // Instead, we explicitly turn those on
597 RCC->CR |= RCC_CR_CSION;
598 RCC->CR |= RCC_CR_HSION;
599 RCC->CR |= RCC_CR_HSEON;
600 RCC->CR |= RCC_CR_HSI48ON;
602 /* Reset D1CFGR register */
603 RCC->D1CFGR = 0x00000000;
605 /* Reset D2CFGR register */
606 RCC->D2CFGR = 0x00000000;
608 /* Reset D3CFGR register */
609 RCC->D3CFGR = 0x00000000;
611 /* Reset PLLCKSELR register */
612 RCC->PLLCKSELR = 0x00000000;
614 /* Reset PLLCFGR register */
615 RCC->PLLCFGR = 0x00000000;
616 /* Reset PLL1DIVR register */
617 RCC->PLL1DIVR = 0x00000000;
618 /* Reset PLL1FRACR register */
619 RCC->PLL1FRACR = 0x00000000;
621 /* Reset PLL2DIVR register */
622 RCC->PLL2DIVR = 0x00000000;
624 /* Reset PLL2FRACR register */
626 RCC->PLL2FRACR = 0x00000000;
627 /* Reset PLL3DIVR register */
628 RCC->PLL3DIVR = 0x00000000;
630 /* Reset PLL3FRACR register */
631 RCC->PLL3FRACR = 0x00000000;
633 /* Reset HSEBYP bit */
634 RCC->CR &= (uint32_t)0xFFFBFFFF;
636 /* Disable all interrupts */
637 RCC->CIER = 0x00000000;
639 /* Change the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */
640 *((__IO uint32_t*)0x51008108) = 0x00000001;
642 #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
643 SystemInit_ExtMemCtl();
644 #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
646 /* Configure the Vector Table location add offset address ------------------*/
647 #if defined(VECT_TAB_SRAM)
648 SCB->VTOR = D1_AXISRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal ITCMSRAM */
649 #elif defined(USE_EXST)
650 // Don't touch the vector table, the bootloader will have already set it.
651 #else
652 SCB->VTOR = FLASH_BANK1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
653 #endif
655 #ifdef USE_HAL_DRIVER
656 HAL_Init();
657 #endif
659 SystemClock_Config();
660 SystemCoreClockUpdate();
662 // Configure MPU
664 memProtConfigure(mpuRegions, mpuRegionCount);
666 // Enable CPU L1-Cache
667 SCB_EnableICache();
668 SCB_EnableDCache();
672 * @brief Update SystemCoreClock variable according to Clock Register Values.
673 * The SystemCoreClock variable contains the core clock , it can
674 * be used by the user application to setup the SysTick timer or configure
675 * other parameters.
677 * @note Each time the core clock changes, this function must be called
678 * to update SystemCoreClock variable value. Otherwise, any configuration
679 * based on this variable will be incorrect.
681 * @note - The system frequency computed by this function is not the real
682 * frequency in the chip. It is calculated based on the predefined
683 * constant and the selected clock source:
685 * - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*)
686 * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
687 * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
688 * - If SYSCLK source is PLL, SystemCoreClock will contain the CSI_VALUE(*),
689 * HSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
691 * (*) CSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value
692 * 4 MHz) but the real value may vary depending on the variations
693 * in voltage and temperature.
694 * (**) HSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value
695 * 64 MHz) but the real value may vary depending on the variations
696 * in voltage and temperature.
698 * (***)HSE_VALUE is a constant defined in stm32h7xx_hal.h file (default value
699 * 25 MHz), user has to ensure that HSE_VALUE is same as the real
700 * frequency of the crystal used. Otherwise, this function may
701 * have wrong result.
703 * - The result of this function could be not correct when using fractional
704 * value for HSE crystal.
705 * @param None
706 * @retval None
709 void SystemCoreClockUpdate (void)
711 SystemCoreClock = HAL_RCC_GetSysClockFreq();
714 #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
716 * @brief Setup the external memory controller.
717 * Called in startup_stm32h7xx.s before jump to main.
718 * This function configures the external memories (SRAM/SDRAM)
719 * This SRAM/SDRAM will be used as program data memory (including heap and stack).
720 * @param None
721 * @retval None
723 void SystemInit_ExtMemCtl(void)
725 #if defined (DATA_IN_ExtSDRAM)
726 register uint32_t tmpreg = 0, timeout = 0xFFFF;
727 register __IO uint32_t index;
729 /* Enable GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */
730 RCC->AHB4ENR |= 0x000001F8;
731 /* Connect PDx pins to FMC Alternate function */
732 GPIOD->AFR[0] = 0x000000CC;
733 GPIOD->AFR[1] = 0xCC000CCC;
734 /* Configure PDx pins in Alternate function mode */
735 GPIOD->MODER = 0xAFEAFFFA;
736 /* Configure PDx pins speed to 50 MHz */
737 GPIOD->OSPEEDR = 0xA02A000A;
738 /* Configure PDx pins Output type to push-pull */
739 GPIOD->OTYPER = 0x00000000;
740 /* No pull-up, pull-down for PDx pins */
741 GPIOD->PUPDR = 0x55555505;
742 /* Connect PEx pins to FMC Alternate function */
743 GPIOE->AFR[0] = 0xC00000CC;
744 GPIOE->AFR[1] = 0xCCCCCCCC;
745 /* Configure PEx pins in Alternate function mode */
746 GPIOE->MODER = 0xAAAABFFA;
747 /* Configure PEx pins speed to 50 MHz */
748 GPIOE->OSPEEDR = 0xAAAA800A;
749 /* Configure PEx pins Output type to push-pull */
750 GPIOE->OTYPER = 0x00000000;
751 /* No pull-up, pull-down for PEx pins */
752 GPIOE->PUPDR = 0x55554005;
753 /* Connect PFx pins to FMC Alternate function */
754 GPIOF->AFR[0] = 0x00CCCCCC;
755 GPIOF->AFR[1] = 0xCCCCC000;
756 /* Configure PFx pins in Alternate function mode */
757 GPIOF->MODER = 0xAABFFAAA;
758 /* Configure PFx pins speed to 50 MHz */
759 GPIOF->OSPEEDR = 0xAA800AAA;
760 /* Configure PFx pins Output type to push-pull */
761 GPIOF->OTYPER = 0x00000000;
762 /* No pull-up, pull-down for PFx pins */
763 GPIOF->PUPDR = 0x55400555;
764 /* Connect PGx pins to FMC Alternate function */
765 GPIOG->AFR[0] = 0x00CCCCCC;
766 GPIOG->AFR[1] = 0xC000000C;
767 /* Configure PGx pins in Alternate function mode */
768 GPIOG->MODER = 0xBFFEFAAA;
769 /* Configure PGx pins speed to 50 MHz */
770 GPIOG->OSPEEDR = 0x80020AAA;
771 /* Configure PGx pins Output type to push-pull */
772 GPIOG->OTYPER = 0x00000000;
773 /* No pull-up, pull-down for PGx pins */
774 GPIOG->PUPDR = 0x40010515;
775 /* Connect PHx pins to FMC Alternate function */
776 GPIOH->AFR[0] = 0xCCC00000;
777 GPIOH->AFR[1] = 0xCCCCCCCC;
778 /* Configure PHx pins in Alternate function mode */
779 GPIOH->MODER = 0xAAAAABFF;
780 /* Configure PHx pins speed to 50 MHz */
781 GPIOH->OSPEEDR = 0xAAAAA800;
782 /* Configure PHx pins Output type to push-pull */
783 GPIOH->OTYPER = 0x00000000;
784 /* No pull-up, pull-down for PHx pins */
785 GPIOH->PUPDR = 0x55555400;
786 /* Connect PIx pins to FMC Alternate function */
787 GPIOI->AFR[0] = 0xCCCCCCCC;
788 GPIOI->AFR[1] = 0x00000CC0;
789 /* Configure PIx pins in Alternate function mode */
790 GPIOI->MODER = 0xFFEBAAAA;
791 /* Configure PIx pins speed to 50 MHz */
792 GPIOI->OSPEEDR = 0x0028AAAA;
793 /* Configure PIx pins Output type to push-pull */
794 GPIOI->OTYPER = 0x00000000;
795 /* No pull-up, pull-down for PIx pins */
796 GPIOI->PUPDR = 0x00145555;
797 /*-- FMC Configuration ------------------------------------------------------*/
798 /* Enable the FMC interface clock */
799 (RCC->AHB3ENR |= (RCC_AHB3ENR_FMCEN));
800 /*SDRAM Timing and access interface configuration*/
801 /*LoadToActiveDelay = 2
802 ExitSelfRefreshDelay = 6
803 SelfRefreshTime = 4
804 RowCycleDelay = 6
805 WriteRecoveryTime = 2
806 RPDelay = 2
807 RCDDelay = 2
808 SDBank = FMC_SDRAM_BANK2
809 ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9
810 RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12
811 MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32
812 InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4
813 CASLatency = FMC_SDRAM_CAS_LATENCY_2
814 WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE
815 SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2
816 ReadBurst = FMC_SDRAM_RBURST_ENABLE
817 ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0*/
819 FMC_Bank5_6->SDCR[0] = 0x00001800;
820 FMC_Bank5_6->SDCR[1] = 0x00000165;
821 FMC_Bank5_6->SDTR[0] = 0x00105000;
822 FMC_Bank5_6->SDTR[1] = 0x01010351;
824 /* SDRAM initialization sequence */
825 /* Clock enable command */
826 FMC_Bank5_6->SDCMR = 0x00000009;
827 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
828 while((tmpreg != 0) && (timeout-- > 0))
830 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
833 /* Delay */
834 for (index = 0; index<1000; index++);
836 /* PALL command */
837 FMC_Bank5_6->SDCMR = 0x0000000A;
838 timeout = 0xFFFF;
839 while((tmpreg != 0) && (timeout-- > 0))
841 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
844 FMC_Bank5_6->SDCMR = 0x000000EB;
845 timeout = 0xFFFF;
846 while((tmpreg != 0) && (timeout-- > 0))
848 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
851 FMC_Bank5_6->SDCMR = 0x0004400C;
852 timeout = 0xFFFF;
853 while((tmpreg != 0) && (timeout-- > 0))
855 tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
857 /* Set refresh count */
858 tmpreg = FMC_Bank5_6->SDRTR;
859 FMC_Bank5_6->SDRTR = (tmpreg | (0x00000603<<1));
861 /* Disable write protection */
862 tmpreg = FMC_Bank5_6->SDCR[1];
863 FMC_Bank5_6->SDCR[1] = (tmpreg & 0xFFFFFDFF);
865 /*FMC controller Enable*/
866 FMC_Bank1->BTCR[0] |= 0x80000000;
869 #endif /* DATA_IN_ExtSDRAM */
871 #if defined(DATA_IN_ExtSRAM)
872 /*-- GPIOs Configuration -----------------------------------------------------*/
873 /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
874 RCC->AHB4ENR |= 0x00000078;
876 /* Connect PDx pins to FMC Alternate function */
877 GPIOD->AFR[0] = 0x00CCC0CC;
878 GPIOD->AFR[1] = 0xCCCCCCCC;
879 /* Configure PDx pins in Alternate function mode */
880 GPIOD->MODER = 0xAAAA0A8A;
881 /* Configure PDx pins speed to 100 MHz */
882 GPIOD->OSPEEDR = 0xFFFF0FCF;
883 /* Configure PDx pins Output type to push-pull */
884 GPIOD->OTYPER = 0x00000000;
885 /* No pull-up, pull-down for PDx pins */
886 GPIOD->PUPDR = 0x55550545;
888 /* Connect PEx pins to FMC Alternate function */
889 GPIOE->AFR[0] = 0xC00CC0CC;
890 GPIOE->AFR[1] = 0xCCCCCCCC;
891 /* Configure PEx pins in Alternate function mode */
892 GPIOE->MODER = 0xAAAA828A;
893 /* Configure PEx pins speed to 100 MHz */
894 GPIOE->OSPEEDR = 0xFFFFC3CF;
895 /* Configure PEx pins Output type to push-pull */
896 GPIOE->OTYPER = 0x00000000;
897 /* No pull-up, pull-down for PEx pins */
898 GPIOE->PUPDR = 0x55554145;
900 /* Connect PFx pins to FMC Alternate function */
901 GPIOF->AFR[0] = 0x00CCCCCC;
902 GPIOF->AFR[1] = 0xCCCC0000;
903 /* Configure PFx pins in Alternate function mode */
904 GPIOF->MODER = 0xAA000AAA;
905 /* Configure PFx pins speed to 100 MHz */
906 GPIOF->OSPEEDR = 0xFF000FFF;
907 /* Configure PFx pins Output type to push-pull */
908 GPIOF->OTYPER = 0x00000000;
909 /* No pull-up, pull-down for PFx pins */
910 GPIOF->PUPDR = 0x55000555;
912 /* Connect PGx pins to FMC Alternate function */
913 GPIOG->AFR[0] = 0x00CCCCCC;
914 GPIOG->AFR[1] = 0x000000C0;
915 /* Configure PGx pins in Alternate function mode */
916 GPIOG->MODER = 0x00200AAA;
917 /* Configure PGx pins speed to 100 MHz */
918 GPIOG->OSPEEDR = 0x00300FFF;
919 /* Configure PGx pins Output type to push-pull */
920 GPIOG->OTYPER = 0x00000000;
921 /* No pull-up, pull-down for PGx pins */
922 GPIOG->PUPDR = 0x00100555;
924 /*-- FMC/FSMC Configuration --------------------------------------------------*/
925 /* Enable the FMC/FSMC interface clock */
926 (RCC->AHB3ENR |= (RCC_AHB3ENR_FMCEN));
928 /* Configure and enable Bank1_SRAM2 */
929 FMC_Bank1->BTCR[4] = 0x00001091;
930 FMC_Bank1->BTCR[5] = 0x00110212;
931 FMC_Bank1E->BWTR[4] = 0x0FFFFFFF;
933 /*FMC controller Enable*/
934 FMC_Bank1->BTCR[0] |= 0x80000000;
936 #endif /* DATA_IN_ExtSRAM */
938 #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
942 * @}
946 * @}
950 * @}
952 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/