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
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 ******************************************************************************
25 * <h2><center>© 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 ******************************************************************************
56 /** @addtogroup stm32h7xx_system
60 /** @addtogroup STM32H7xx_System_Private_Includes
64 #include "stm32h7xx.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 */
90 /** @addtogroup STM32H7xx_System_Private_TypesDefinitions
98 /** @addtogroup STM32H7xx_System_Private_Defines
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
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 /******************************************************************************/
123 /** @addtogroup STM32H7xx_System_Private_Macros
131 /** @addtogroup STM32H7xx_System_Private_Variables
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};
150 /** @addtogroup STM32H7xx_System_Private_FunctionPrototypes
153 #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
154 static void SystemInit_ExtMemCtl(void);
155 #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
161 /** @addtogroup STM32H7xx_System_Private_Functions
165 static void Error_Handler(void)
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
{
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
= {
217 .vos
= PWR_REGULATOR_VOLTAGE_SCALE1
221 pllConfig_t pll1ConfigRevV
= {
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};
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 */
253 #ifdef USE_H7_LEGACY_CPU_REVISION_SPEED
254 pllConfig_t
*pll1Config
= &pll1ConfigRevY
;
256 pllConfig_t
*pll1Config
= (HAL_GetREVID() == REV_ID_V
) ? &pll1ConfigRevV
: &pll1ConfigRevY
;
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
)) {
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
);
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.
314 if (status
!= HAL_OK
) {
315 /* Initialization Error */
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 */
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 */
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
)) {
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();
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
);
438 // Configure UART peripheral clock sources
441 // D2PCLK1 (pclk1 for APB1 = USART234578)
442 // D2PCLK2 (pclk2 for APB2 = USART16)
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:
461 // Possible sources for SPI45:
462 // D2PCLK1 (rcc_pclk2 = APB1) 100MHz
468 // Possible sources for SPI6:
469 // D3PCLK1 (rcc_pclk4 = APB4) 100MHz
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
);
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)
546 void HAL_RCCEx_CRS_SyncWarnCallback(void)
551 void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
556 void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error
)
561 void CRS_IRQHandler(void)
563 HAL_RCCEx_CRS_IRQHandler();
567 #include "build/debug.h"
569 void systemCheckResetReason(void);
571 #include "drivers/memprot.h"
573 void SystemInit (void)
577 initialiseMemorySections();
580 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
581 SCB
->CPACR
|= ((3UL << 10*2)|(3UL << 11*2)); // Set CP10 and CP11 Full Access
584 // Reset the RCC clock configuration to the default reset state
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.
652 SCB
->VTOR
= FLASH_BANK1_BASE
| VECT_TAB_OFFSET
; /* Vector Table Relocation in Internal FLASH */
655 #ifdef USE_HAL_DRIVER
659 SystemClock_Config();
660 SystemCoreClockUpdate();
664 memProtConfigure(mpuRegions
, mpuRegionCount
);
666 // Enable CPU L1-Cache
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
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
703 * - The result of this function could be not correct when using fractional
704 * value for HSE crystal.
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).
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
805 WriteRecoveryTime = 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;
834 for (index
= 0; index
<1000; index
++);
837 FMC_Bank5_6
->SDCMR
= 0x0000000A;
839 while((tmpreg
!= 0) && (timeout
-- > 0))
841 tmpreg
= FMC_Bank5_6
->SDSR
& 0x00000020;
844 FMC_Bank5_6
->SDCMR
= 0x000000EB;
846 while((tmpreg
!= 0) && (timeout
-- > 0))
848 tmpreg
= FMC_Bank5_6
->SDSR
& 0x00000020;
851 FMC_Bank5_6
->SDCMR
= 0x0004400C;
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 */
952 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/