2 ******************************************************************************
\r
3 * @file system_stm32h7xx.c
\r
4 * @author MCD Application Team
\r
5 * @brief CMSIS Cortex-Mx Device Peripheral Access Layer System Source File.
\r
7 * This file provides two functions and one global variable to be called from
\r
9 * - SystemInit(): This function is called at startup just after reset and
\r
10 * before branch to main program. This call is made inside
\r
11 * the "startup_stm32h7xx.s" file.
\r
13 * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
\r
14 * by the user application to setup the SysTick
\r
15 * timer or configure other parameters.
\r
17 * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
\r
18 * be called whenever the core clock is changed
\r
19 * during program execution.
\r
22 ******************************************************************************
\r
25 * <h2><center>© Copyright (c) 2019 STMicroelectronics.
\r
26 * All rights reserved.</center></h2>
\r
28 * This software component is licensed by ST under BSD 3-Clause license,
\r
29 * the "License"; You may not use this file except in compliance with the
\r
30 * License. You may obtain a copy of the License at:
\r
31 * opensource.org/licenses/BSD-3-Clause
\r
33 ******************************************************************************
\r
36 /** @addtogroup CMSIS
\r
40 /** @addtogroup stm32h7xx_system
\r
44 /** @addtogroup STM32H7xx_System_Private_Includes
\r
48 #include "stm32h7xx.h"
\r
51 #if !defined (HSE_VALUE)
\r
52 #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
\r
53 #endif /* HSE_VALUE */
\r
55 #if !defined (CSI_VALUE)
\r
56 #define CSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/
\r
57 #endif /* CSI_VALUE */
\r
59 #if !defined (HSI_VALUE)
\r
60 #define HSI_VALUE ((uint32_t)64000000) /*!< Value of the Internal oscillator in Hz*/
\r
61 #endif /* HSI_VALUE */
\r
67 /** @addtogroup STM32H7xx_System_Private_TypesDefinitions
\r
75 /** @addtogroup STM32H7xx_System_Private_Defines
\r
79 /************************* Miscellaneous Configuration ************************/
\r
80 /*!< Uncomment the following line if you need to use external SDRAM mounted
\r
81 on DISCO board as data memory */
\r
82 /*#define DATA_IN_ExtSDRAM*/
\r
84 /*!< Uncomment the following line if you need to relocate your vector Table in
\r
86 /* #define VECT_TAB_SRAM */
\r
87 #define VECT_TAB_OFFSET 0x00000000UL /*!< Vector Table base offset field.
\r
88 This value must be a multiple of 0x200. */
\r
89 /******************************************************************************/
\r
95 /** @addtogroup STM32H7xx_System_Private_Macros
\r
103 /** @addtogroup STM32H7xx_System_Private_Variables
\r
106 /* This variable is updated in three ways:
\r
107 1) by calling CMSIS function SystemCoreClockUpdate()
\r
108 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
\r
109 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
\r
110 Note: If you use this function to configure the system clock; then there
\r
111 is no need to call the 2 first functions listed above, since SystemCoreClock
\r
112 variable is updated automatically.
\r
114 uint32_t SystemCoreClock = 64000000;
\r
115 uint32_t SystemD2Clock = 64000000;
\r
116 const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
\r
122 /** @addtogroup STM32H7xx_System_Private_FunctionPrototypes
\r
125 #if defined (DATA_IN_ExtSDRAM)
\r
126 static void SystemInit_ExtMemCtl(void);
\r
127 #endif /* DATA_IN_ExtSDRAM */
\r
133 /** @addtogroup STM32H7xx_System_Private_Functions
\r
138 * @brief Setup the microcontroller system
\r
139 * Initialize the FPU setting, vector table location and External memory
\r
144 void SystemInit (void)
\r
146 /* FPU settings ------------------------------------------------------------*/
\r
147 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
\r
148 SCB->CPACR |= ((3UL << (10*2))|(3UL << (11*2))); /* set CP10 and CP11 Full Access */
\r
151 /*SEVONPEND enabled so that an interrupt coming from the CPU(n) interrupt signal is
\r
152 detectable by the CPU after a WFI/WFE instruction.*/
\r
153 SCB->SCR |= SCB_SCR_SEVONPEND_Pos;
\r
156 /* Reset the RCC clock configuration to the default reset state ------------*/
\r
157 /* Set HSION bit */
\r
158 RCC->CR |= RCC_CR_HSION;
\r
160 /* Reset CFGR register */
\r
161 RCC->CFGR = 0x00000000;
\r
163 /* Reset HSEON, CSSON , CSION,RC48ON, CSIKERON PLL1ON, PLL2ON and PLL3ON bits */
\r
164 RCC->CR &= 0xEAF6ED7FU;
\r
166 /* Reset D1CFGR register */
\r
167 RCC->D1CFGR = 0x00000000;
\r
169 /* Reset D2CFGR register */
\r
170 RCC->D2CFGR = 0x00000000;
\r
172 /* Reset D3CFGR register */
\r
173 RCC->D3CFGR = 0x00000000;
\r
175 /* Reset PLLCKSELR register */
\r
176 RCC->PLLCKSELR = 0x00000000;
\r
178 /* Reset PLLCFGR register */
\r
179 RCC->PLLCFGR = 0x00000000;
\r
180 /* Reset PLL1DIVR register */
\r
181 RCC->PLL1DIVR = 0x00000000;
\r
182 /* Reset PLL1FRACR register */
\r
183 RCC->PLL1FRACR = 0x00000000;
\r
185 /* Reset PLL2DIVR register */
\r
186 RCC->PLL2DIVR = 0x00000000;
\r
188 /* Reset PLL2FRACR register */
\r
190 RCC->PLL2FRACR = 0x00000000;
\r
191 /* Reset PLL3DIVR register */
\r
192 RCC->PLL3DIVR = 0x00000000;
\r
194 /* Reset PLL3FRACR register */
\r
195 RCC->PLL3FRACR = 0x00000000;
\r
197 /* Reset HSEBYP bit */
\r
198 RCC->CR &= 0xFFFBFFFFU;
\r
200 /* Disable all interrupts */
\r
201 RCC->CIER = 0x00000000;
\r
203 /* Enable CortexM7 HSEM EXTI line (line 78)*/
\r
204 EXTI_D2->EMR3 |= 0x4000UL;
\r
206 /* Change the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */
\r
207 if((DBGMCU->IDCODE & 0xFFFF0000U) < 0x20000000U)
\r
209 /* if stm32h7 revY*/
\r
210 /* Change the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */
\r
211 *((__IO uint32_t*)0x51008108) = 0x00000001U;
\r
214 #if defined (DATA_IN_ExtSDRAM)
\r
215 SystemInit_ExtMemCtl();
\r
216 #endif /* DATA_IN_ExtSDRAM */
\r
218 #endif /* CORE_CM7*/
\r
222 /* Configure the Vector Table location add offset address ------------------*/
\r
223 #ifdef VECT_TAB_SRAM
\r
224 SCB->VTOR = D2_AHBSRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
\r
226 SCB->VTOR = FLASH_BANK2_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
\r
232 /* Configure the Vector Table location add offset address ------------------*/
\r
233 #ifdef VECT_TAB_SRAM
\r
234 SCB->VTOR = D1_AXISRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
\r
236 SCB->VTOR = FLASH_BANK1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
\r
240 #error Please #define CORE_CM4 or CORE_CM7
\r
247 * @brief Update SystemCoreClock variable according to Clock Register Values.
\r
248 * The SystemCoreClock variable contains the core clock , it can
\r
249 * be used by the user application to setup the SysTick timer or configure
\r
250 * other parameters.
\r
252 * @note Each time the core clock changes, this function must be called
\r
253 * to update SystemCoreClock variable value. Otherwise, any configuration
\r
254 * based on this variable will be incorrect.
\r
256 * @note - The system frequency computed by this function is not the real
\r
257 * frequency in the chip. It is calculated based on the predefined
\r
258 * constant and the selected clock source:
\r
260 * - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*)
\r
261 * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
\r
262 * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
\r
263 * - If SYSCLK source is PLL, SystemCoreClock will contain the CSI_VALUE(*),
\r
264 * HSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
\r
266 * (*) CSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value
\r
267 * 4 MHz) but the real value may vary depending on the variations
\r
268 * in voltage and temperature.
\r
269 * (**) HSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value
\r
270 * 64 MHz) but the real value may vary depending on the variations
\r
271 * in voltage and temperature.
\r
273 * (***)HSE_VALUE is a constant defined in stm32h7xx_hal.h file (default value
\r
274 * 25 MHz), user has to ensure that HSE_VALUE is same as the real
\r
275 * frequency of the crystal used. Otherwise, this function may
\r
276 * have wrong result.
\r
278 * - The result of this function could be not correct when using fractional
\r
279 * value for HSE crystal.
\r
283 void SystemCoreClockUpdate (void)
\r
285 uint32_t pllp, pllsource, pllm, pllfracen, hsivalue, tmp;
\r
286 float_t fracn1, pllvco;
\r
288 /* Get SYSCLK source -------------------------------------------------------*/
\r
290 switch (RCC->CFGR & RCC_CFGR_SWS)
\r
292 case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */
\r
293 SystemCoreClock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3));
\r
297 case RCC_CFGR_SWS_CSI: /* CSI used as system clock source */
\r
298 SystemCoreClock = CSI_VALUE;
\r
301 case RCC_CFGR_SWS_HSE: /* HSE used as system clock source */
\r
302 SystemCoreClock = HSE_VALUE;
\r
305 case RCC_CFGR_SWS_PLL1: /* PLL1 used as system clock source */
\r
307 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
\r
308 SYSCLK = PLL_VCO / PLLR
\r
310 pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
\r
311 pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1)>> 4) ;
\r
312 pllfracen = ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN)>>RCC_PLLCFGR_PLL1FRACEN_Pos);
\r
313 fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN1)>> 3));
\r
319 case RCC_PLLCKSELR_PLLSRC_HSI: /* HSI used as PLL clock source */
\r
321 hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ;
\r
322 pllvco = ( (float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
\r
326 case RCC_PLLCKSELR_PLLSRC_CSI: /* CSI used as PLL clock source */
\r
327 pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
\r
330 case RCC_PLLCKSELR_PLLSRC_HSE: /* HSE used as PLL clock source */
\r
331 pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
\r
335 pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
\r
338 pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_P1) >>9) + 1U ) ;
\r
339 SystemCoreClock = (uint32_t)(float_t)(pllvco/(float_t)pllp);
\r
343 SystemCoreClock = 0U;
\r
348 SystemCoreClock = CSI_VALUE;
\r
352 /* Compute SystemClock frequency --------------------------------------------------*/
\r
353 tmp = D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_D1CPRE)>> RCC_D1CFGR_D1CPRE_Pos];
\r
355 /* SystemCoreClock frequency : CM7 CPU frequency */
\r
356 SystemCoreClock >>= tmp;
\r
358 /* SystemD2Clock frequency : CM4 CPU, AXI and AHBs Clock frequency */
\r
359 SystemD2Clock = (SystemCoreClock >> ((D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_HPRE)>> RCC_D1CFGR_HPRE_Pos]) & 0x1FU));
\r
361 #if defined (DATA_IN_ExtSDRAM)
\r
363 * @brief Setup the external memory controller.
\r
364 * Called in startup_stm32h7xx.s before jump to main.
\r
365 * This function configures the external memories SDRAM
\r
366 * This SDRAM will be used as program data memory (including heap and stack).
\r
370 void SystemInit_ExtMemCtl(void)
\r
372 __IO uint32_t tmp = 0;
\r
373 register uint32_t tmpreg = 0, timeout = 0xFFFF;
\r
374 register __IO uint32_t index;
\r
376 /* Enable GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface
\r
378 RCC->AHB4ENR |= 0x000001F8;
\r
380 /* Delay after an RCC peripheral clock enabling */
\r
381 tmp = READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOEEN);
\r
383 /* Connect PDx pins to FMC Alternate function */
\r
384 GPIOD->AFR[0] = 0x000000CC;
\r
385 GPIOD->AFR[1] = 0xCC000CCC;
\r
386 /* Configure PDx pins in Alternate function mode */
\r
387 GPIOD->MODER = 0xAFEAFFFA;
\r
388 /* Configure PDx pins speed to 100 MHz */
\r
389 GPIOD->OSPEEDR = 0xF03F000F;
\r
390 /* Configure PDx pins Output type to push-pull */
\r
391 GPIOD->OTYPER = 0x00000000;
\r
392 /* Configure PDx pins in Pull-up */
\r
393 GPIOD->PUPDR = 0x50150005;
\r
395 /* Connect PEx pins to FMC Alternate function */
\r
396 GPIOE->AFR[0] = 0xC00000CC;
\r
397 GPIOE->AFR[1] = 0xCCCCCCCC;
\r
398 /* Configure PEx pins in Alternate function mode */
\r
399 GPIOE->MODER = 0xAAAABFFA;
\r
400 /* Configure PEx pins speed to 100 MHz */
\r
401 GPIOE->OSPEEDR = 0xFFFFC00F;
\r
402 /* Configure PEx pins Output type to push-pull */
\r
403 GPIOE->OTYPER = 0x00000000;
\r
404 /* Configure PEx pins in Pull-up */
\r
405 GPIOE->PUPDR = 0x55554005;
\r
407 /* Connect PFx pins to FMC Alternate function */
\r
408 GPIOF->AFR[0] = 0x00CCCCCC;
\r
409 GPIOF->AFR[1] = 0xCCCCC000;
\r
410 /* Configure PFx pins in Alternate function mode */
\r
411 GPIOF->MODER = 0xAABFFAAA;
\r
412 /* Configure PFx pins speed to 100 MHz */
\r
413 GPIOF->OSPEEDR = 0xFFC00FFF;
\r
414 /* Configure PFx pins Output type to push-pull */
\r
415 GPIOF->OTYPER = 0x00000000;
\r
416 /* Configure PFx pins in Pull-up */
\r
417 GPIOF->PUPDR = 0x55400555;
\r
419 /* Connect PGx pins to FMC Alternate function */
\r
420 GPIOG->AFR[0] = 0x00CC00CC;
\r
421 GPIOG->AFR[1] = 0xC000000C;
\r
422 /* Configure PGx pins in Alternate function mode */
\r
423 GPIOG->MODER = 0xBFFEFAFA;
\r
424 /* Configure PGx pins speed to 100 MHz */
\r
425 GPIOG->OSPEEDR = 0xC0030F0F;
\r
426 /* Configure PGx pins Output type to push-pull */
\r
427 GPIOG->OTYPER = 0x00000000;
\r
428 /* Configure PGx pins in Pull-up */
\r
429 GPIOG->PUPDR = 0x40010505;
\r
431 /* Connect PHx pins to FMC Alternate function */
\r
432 GPIOH->AFR[0] = 0xCCC00000;
\r
433 GPIOH->AFR[1] = 0xCCCCCCCC;
\r
434 /* Configure PHx pins in Alternate function mode */
\r
435 GPIOH->MODER = 0xAAAAABFF;
\r
436 /* Configure PHx pins speed to 100 MHz */
\r
437 GPIOH->OSPEEDR = 0xFFFFFC00;
\r
438 /* Configure PHx pins Output type to push-pull */
\r
439 GPIOH->OTYPER = 0x00000000;
\r
440 /* Configure PHx pins in Pull-up */
\r
441 GPIOH->PUPDR = 0x55555400;
\r
443 /*-- FMC Configuration ------------------------------------------------------*/
\r
444 /* Enable the FMC interface clock */
\r
445 (RCC->AHB3ENR |= (RCC_AHB3ENR_FMCEN));
\r
446 /*SDRAM Timing and access interface configuration*/
\r
447 /*LoadToActiveDelay = 2
\r
448 ExitSelfRefreshDelay = 6
\r
449 SelfRefreshTime = 4
\r
451 WriteRecoveryTime = 2
\r
454 SDBank = FMC_SDRAM_BANK2
\r
455 ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8
\r
456 RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12
\r
457 MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16
\r
458 InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4
\r
459 CASLatency = FMC_SDRAM_CAS_LATENCY_2
\r
460 WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE
\r
461 SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2
\r
462 ReadBurst = FMC_SDRAM_RBURST_ENABLE
\r
463 ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0*/
\r
465 FMC_Bank5_6_R->SDCR[0] = 0x00001800;
\r
466 FMC_Bank5_6_R->SDCR[1] = 0x00000154;
\r
467 FMC_Bank5_6_R->SDTR[0] = 0x00105000;
\r
468 FMC_Bank5_6_R->SDTR[1] = 0x01010351;
\r
470 /* SDRAM initialization sequence */
\r
471 /* Clock enable command */
\r
472 FMC_Bank5_6_R->SDCMR = 0x00000009;
\r
473 tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020;
\r
474 while((tmpreg != 0) && (timeout-- > 0))
\r
476 tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020;
\r
480 for (index = 0; index<1000; index++);
\r
482 /* PALL command */
\r
483 FMC_Bank5_6_R->SDCMR = 0x0000000A;
\r
485 while((tmpreg != 0) && (timeout-- > 0))
\r
487 tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020;
\r
490 FMC_Bank5_6_R->SDCMR = 0x000000EB;
\r
492 while((tmpreg != 0) && (timeout-- > 0))
\r
494 tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020;
\r
497 FMC_Bank5_6_R->SDCMR = 0x0004400C;
\r
499 while((tmpreg != 0) && (timeout-- > 0))
\r
501 tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020;
\r
503 /* Set refresh count */
\r
504 tmpreg = FMC_Bank5_6_R->SDRTR;
\r
505 FMC_Bank5_6_R->SDRTR = (tmpreg | (0x00000603<<1));
\r
507 /* Disable write protection */
\r
508 tmpreg = FMC_Bank5_6_R->SDCR[1];
\r
509 FMC_Bank5_6_R->SDCR[1] = (tmpreg & 0xFFFFFDFF);
\r
511 /*FMC controller Enable*/
\r
512 FMC_Bank1_R->BTCR[0] |= 0x80000000;
\r
516 #endif /* DATA_IN_ExtSDRAM */
\r
530 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r