Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:06

0001 /**
0002   ******************************************************************************
0003   * @file    system_stm32h7xx.c
0004   * @author  MCD Application Team
0005   * @brief   CMSIS Cortex-Mx Device Peripheral Access Layer System Source File.
0006   *
0007   *   This file provides two functions and one global variable to be called from
0008   *   user application:
0009   *      - SystemInit(): This function is called at startup just after reset and
0010   *                      before branch to main program. This call is made inside
0011   *                      the "startup_stm32h7xx.s" file.
0012   *
0013   *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
0014   *                                  by the user application to setup the SysTick
0015   *                                  timer or configure other parameters.
0016   *
0017   *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
0018   *                                 be called whenever the core clock is changed
0019   *                                 during program execution.
0020   *
0021   *
0022   ******************************************************************************
0023   * @attention
0024   *
0025   * Copyright (c) 2019 STMicroelectronics.
0026   * All rights reserved.
0027   *
0028   * This software is licensed under terms that can be found in the LICENSE file
0029   * in the root directory of this software component.
0030   * If no LICENSE file comes with this software, it is provided AS-IS.
0031   *
0032   ******************************************************************************
0033   */
0034 
0035 /** @addtogroup CMSIS
0036   * @{
0037   */
0038 
0039 /** @addtogroup stm32h7xx_system
0040   * @{
0041   */
0042 
0043 /** @addtogroup STM32H7xx_System_Private_Includes
0044   * @{
0045   */
0046 
0047 #include "stm32h7xx.h"
0048 #include <math.h>
0049 
0050 #if !defined  (HSE_VALUE)
0051 #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
0052 #endif /* HSE_VALUE */
0053 
0054 #if !defined  (CSI_VALUE)
0055   #define CSI_VALUE    ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/
0056 #endif /* CSI_VALUE */
0057 
0058 #if !defined  (HSI_VALUE)
0059   #define HSI_VALUE    ((uint32_t)64000000) /*!< Value of the Internal oscillator in Hz*/
0060 #endif /* HSI_VALUE */
0061 
0062 /**
0063   * @}
0064   */
0065 
0066 /** @addtogroup STM32H7xx_System_Private_TypesDefinitions
0067   * @{
0068   */
0069 
0070 /**
0071   * @}
0072   */
0073 
0074 /** @addtogroup STM32H7xx_System_Private_Defines
0075   * @{
0076   */
0077 
0078 /************************* Miscellaneous Configuration ************************/
0079 /*!< Uncomment the following line if you need to use external SDRAM mounted
0080      on DISCO board as data memory  */
0081 /*#define DATA_IN_ExtSDRAM*/
0082 #ifdef __rtems__
0083 #define DATA_IN_ExtSDRAM
0084 #endif /* __rtems__ */
0085 
0086 /*!< Uncomment the following line if you need to use initialized data in D2 domain SRAM  */
0087 /* #define DATA_IN_D2_SRAM */
0088 
0089 /*!< Uncomment the following line if you need to relocate your vector Table in
0090      Internal SRAM. */
0091 /* #define VECT_TAB_SRAM */
0092 #define VECT_TAB_OFFSET  0x00000000UL       /*!< Vector Table base offset field.
0093                                       This value must be a multiple of 0x200. */
0094 /******************************************************************************/
0095 
0096 /**
0097   * @}
0098   */
0099 
0100 /** @addtogroup STM32H7xx_System_Private_Macros
0101   * @{
0102   */
0103 
0104 /**
0105   * @}
0106   */
0107 
0108 /** @addtogroup STM32H7xx_System_Private_Variables
0109   * @{
0110   */
0111   /* This variable is updated in three ways:
0112       1) by calling CMSIS function SystemCoreClockUpdate()
0113       2) by calling HAL API function HAL_RCC_GetHCLKFreq()
0114       3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
0115          Note: If you use this function to configure the system clock; then there
0116                is no need to call the 2 first functions listed above, since SystemCoreClock
0117                variable is updated automatically.
0118   */
0119   uint32_t SystemCoreClock = 64000000;
0120   uint32_t SystemD2Clock = 64000000;
0121   const  uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
0122 
0123 /**
0124   * @}
0125   */
0126 
0127 /** @addtogroup STM32H7xx_System_Private_FunctionPrototypes
0128   * @{
0129   */
0130 #ifndef __rtems__
0131 #if defined (DATA_IN_ExtSDRAM)
0132   static void SystemInit_ExtMemCtl(void);
0133 #endif /* DATA_IN_ExtSDRAM */
0134 #else
0135 #include <bsp.h>
0136 #endif
0137 
0138 /**
0139   * @}
0140   */
0141 
0142 /** @addtogroup STM32H7xx_System_Private_Functions
0143   * @{
0144   */
0145 
0146 /**
0147   * @brief  Setup the microcontroller system
0148   *         Initialize the FPU setting, vector table location and External memory
0149   *         configuration.
0150   * @param  None
0151   * @retval None
0152   */
0153 void SystemInit (void)
0154 {
0155 #if defined (DATA_IN_D2_SRAM)
0156  __IO uint32_t tmpreg;
0157 #endif /* DATA_IN_D2_SRAM */
0158 
0159   /* FPU settings ------------------------------------------------------------*/
0160   #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
0161     SCB->CPACR |= ((3UL << (10*2))|(3UL << (11*2)));  /* set CP10 and CP11 Full Access */
0162   #endif
0163   /* Reset the RCC clock configuration to the default reset state ------------*/
0164   /* Set HSION bit */
0165   RCC->CR |= RCC_CR_HSION;
0166 
0167   /* Reset CFGR register */
0168   RCC->CFGR = 0x00000000;
0169 
0170   /* Reset HSEON, CSSON , CSION,RC48ON, CSIKERON PLL1ON, PLL2ON and PLL3ON bits */
0171   RCC->CR &= 0xEAF6ED7FU;
0172 
0173   /* Reset D1CFGR register */
0174   RCC->D1CFGR = 0x00000000;
0175 
0176   /* Reset D2CFGR register */
0177   RCC->D2CFGR = 0x00000000;
0178 
0179   /* Reset D3CFGR register */
0180   RCC->D3CFGR = 0x00000000;
0181 
0182   /* Reset PLLCKSELR register */
0183   RCC->PLLCKSELR = 0x00000000;
0184 
0185   /* Reset PLLCFGR register */
0186   RCC->PLLCFGR = 0x00000000;
0187   /* Reset PLL1DIVR register */
0188   RCC->PLL1DIVR = 0x00000000;
0189   /* Reset PLL1FRACR register */
0190   RCC->PLL1FRACR = 0x00000000;
0191 
0192   /* Reset PLL2DIVR register */
0193   RCC->PLL2DIVR = 0x00000000;
0194 
0195   /* Reset PLL2FRACR register */
0196 
0197   RCC->PLL2FRACR = 0x00000000;
0198   /* Reset PLL3DIVR register */
0199   RCC->PLL3DIVR = 0x00000000;
0200 
0201   /* Reset PLL3FRACR register */
0202   RCC->PLL3FRACR = 0x00000000;
0203 
0204   /* Reset HSEBYP bit */
0205   RCC->CR &= 0xFFFBFFFFU;
0206 
0207   /* Disable all interrupts */
0208   RCC->CIER = 0x00000000;
0209 
0210   /* Change  the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */
0211   if((DBGMCU->IDCODE & 0xFFFF0000U) < 0x20000000U)
0212   {
0213     /* if stm32h7 revY*/
0214     /* Change  the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */
0215     *((__IO uint32_t*)0x51008108) = 0x00000001U;
0216   }
0217 
0218 #if defined (DATA_IN_D2_SRAM)
0219   /* in case of initialized data in D2 SRAM , enable the D2 SRAM clock */
0220   RCC->AHB2ENR |= (RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN | RCC_AHB2ENR_D2SRAM3EN);
0221   tmpreg = RCC->AHB2ENR;
0222   (void) tmpreg;
0223 #endif /* DATA_IN_D2_SRAM */
0224 
0225 
0226 /*
0227    * Disable the FMC bank1 (enabled after reset).
0228    * This, prevents CPU speculation access on this bank which blocks the use of FMC during
0229    * 24us. During this time the others FMC master (such as LTDC) cannot use it!
0230    */
0231   FMC_Bank1_R->BTCR[0] = 0x000030D2;
0232 
0233 #if defined (DATA_IN_ExtSDRAM)
0234   SystemInit_ExtMemCtl();
0235 #endif /* DATA_IN_ExtSDRAM */
0236 
0237   /* Configure the Vector Table location add offset address ------------------*/
0238 #ifdef VECT_TAB_SRAM
0239   SCB->VTOR = D1_AXISRAM_BASE  | VECT_TAB_OFFSET;       /* Vector Table Relocation in Internal SRAM */
0240 #else
0241   SCB->VTOR = FLASH_BANK1_BASE | VECT_TAB_OFFSET;       /* Vector Table Relocation in Internal FLASH */
0242 #endif
0243 
0244 
0245 }
0246 
0247 /**
0248    * @brief  Update SystemCoreClock variable according to Clock Register Values.
0249   *         The SystemCoreClock variable contains the core clock , it can
0250   *         be used by the user application to setup the SysTick timer or configure
0251   *         other parameters.
0252   *
0253   * @note   Each time the core clock changes, this function must be called
0254   *         to update SystemCoreClock variable value. Otherwise, any configuration
0255   *         based on this variable will be incorrect.
0256   *
0257   * @note   - The system frequency computed by this function is not the real
0258   *           frequency in the chip. It is calculated based on the predefined
0259   *           constant and the selected clock source:
0260   *
0261   *           - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*)
0262   *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
0263   *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
0264   *           - If SYSCLK source is PLL, SystemCoreClock will contain the CSI_VALUE(*),
0265   *             HSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
0266   *
0267   *         (*) CSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value
0268   *             4 MHz) but the real value may vary depending on the variations
0269   *             in voltage and temperature.
0270   *         (**) HSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value
0271   *             64 MHz) but the real value may vary depending on the variations
0272   *             in voltage and temperature.
0273   *
0274   *         (***)HSE_VALUE is a constant defined in stm32h7xx_hal.h file (default value
0275   *              25 MHz), user has to ensure that HSE_VALUE is same as the real
0276   *              frequency of the crystal used. Otherwise, this function may
0277   *              have wrong result.
0278   *
0279   *         - The result of this function could be not correct when using fractional
0280   *           value for HSE crystal.
0281   * @param  None
0282   * @retval None
0283   */
0284 void SystemCoreClockUpdate (void)
0285 {
0286   uint32_t pllp, pllsource, pllm, pllfracen, hsivalue, tmp;
0287   float_t fracn1, pllvco;
0288 
0289   /* Get SYSCLK source -------------------------------------------------------*/
0290 
0291   switch (RCC->CFGR & RCC_CFGR_SWS)
0292   {
0293   case RCC_CFGR_SWS_HSI:  /* HSI used as system clock source */
0294    SystemCoreClock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3));
0295 
0296     break;
0297 
0298   case RCC_CFGR_SWS_CSI:  /* CSI used as system clock  source */
0299     SystemCoreClock = CSI_VALUE;
0300     break;
0301 
0302   case RCC_CFGR_SWS_HSE:  /* HSE used as system clock  source */
0303     SystemCoreClock = HSE_VALUE;
0304     break;
0305 
0306   case RCC_CFGR_SWS_PLL1:  /* PLL1 used as system clock  source */
0307 
0308     /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
0309     SYSCLK = PLL_VCO / PLLR
0310     */
0311     pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
0312     pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1)>> 4)  ;
0313     pllfracen = ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN)>>RCC_PLLCFGR_PLL1FRACEN_Pos);
0314     fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN1)>> 3));
0315 
0316     if (pllm != 0U)
0317     {
0318       switch (pllsource)
0319       {
0320         case RCC_PLLCKSELR_PLLSRC_HSI:  /* HSI used as PLL clock source */
0321 
0322         hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ;
0323         pllvco = ( (float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
0324 
0325         break;
0326 
0327         case RCC_PLLCKSELR_PLLSRC_CSI:  /* CSI used as PLL clock source */
0328           pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
0329         break;
0330 
0331         case RCC_PLLCKSELR_PLLSRC_HSE:  /* HSE used as PLL clock source */
0332           pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
0333         break;
0334 
0335       default:
0336           pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
0337         break;
0338       }
0339       pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_P1) >>9) + 1U ) ;
0340       SystemCoreClock =  (uint32_t)(float_t)(pllvco/(float_t)pllp);
0341     }
0342     else
0343     {
0344       SystemCoreClock = 0U;
0345     }
0346     break;
0347 
0348   default:
0349     SystemCoreClock = CSI_VALUE;
0350     break;
0351   }
0352 
0353   /* Compute SystemClock frequency --------------------------------------------------*/
0354 
0355   tmp = D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_D1CPRE)>> RCC_D1CFGR_D1CPRE_Pos];
0356   /* SystemCoreClock frequency : CM7 CPU frequency  */
0357   SystemCoreClock >>= tmp;
0358 
0359   /* SystemD2Clock frequency : AXI and AHBs Clock frequency  */
0360   SystemD2Clock = (SystemCoreClock >> ((D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_HPRE)>> RCC_D1CFGR_HPRE_Pos]) & 0x1FU));
0361 }
0362 #if defined (DATA_IN_ExtSDRAM)
0363 /**
0364   * @brief  Setup the external memory controller.
0365   *         Called in startup_stm32h7xx.s before jump to main.
0366   *         This function configures the external memories SDRAM
0367   *         This SDRAM will be used as program data memory (including heap and stack).
0368   * @param  None
0369   * @retval None
0370   */
0371 void SystemInit_ExtMemCtl(void)
0372 {
0373   __IO uint32_t tmp = 0;
0374   register uint32_t tmpreg = 0, timeout = 0xFFFF;
0375   register __IO uint32_t index;
0376 
0377   /* Enable GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface
0378       clock */
0379   RCC->AHB4ENR |= 0x000001F8;
0380 
0381   /* Delay after an RCC peripheral clock enabling */
0382   tmp = READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOEEN);
0383 
0384   /* Connect PDx pins to FMC Alternate function */
0385   GPIOD->AFR[0]  = 0x000000CC;
0386   GPIOD->AFR[1]  = 0xCC000CCC;
0387   /* Configure PDx pins in Alternate function mode */
0388   GPIOD->MODER   = 0xAFEAFFFA;
0389   /* Configure PDx pins speed to 100 MHz */
0390   GPIOD->OSPEEDR = 0xF03F000F;
0391   /* Configure PDx pins Output type to push-pull */
0392   GPIOD->OTYPER  = 0x00000000;
0393   /* Configure PDx pins in Pull-up */
0394   GPIOD->PUPDR   = 0x50150005;
0395 
0396   /* Connect PEx pins to FMC Alternate function */
0397   GPIOE->AFR[0]  = 0xC00000CC;
0398   GPIOE->AFR[1]  = 0xCCCCCCCC;
0399   /* Configure PEx pins in Alternate function mode */
0400   GPIOE->MODER   = 0xAAAABFFA;
0401   /* Configure PEx pins speed to 100 MHz */
0402   GPIOE->OSPEEDR = 0xFFFFC00F;
0403   /* Configure PEx pins Output type to push-pull */
0404   GPIOE->OTYPER  = 0x00000000;
0405   /* Configure PEx pins in Pull-up */
0406   GPIOE->PUPDR   = 0x55554005;
0407 
0408   /* Connect PFx pins to FMC Alternate function */
0409   GPIOF->AFR[0]  = 0x00CCCCCC;
0410   GPIOF->AFR[1]  = 0xCCCCC000;
0411   /* Configure PFx pins in Alternate function mode */
0412   GPIOF->MODER   = 0xAABFFAAA;
0413   /* Configure PFx pins speed to 100 MHz */
0414   GPIOF->OSPEEDR = 0xFFC00FFF;
0415   /* Configure PFx pins Output type to push-pull */
0416   GPIOF->OTYPER  = 0x00000000;
0417   /* Configure PFx pins in Pull-up */
0418   GPIOF->PUPDR   = 0x55400555;
0419 
0420   /* Connect PGx pins to FMC Alternate function */
0421   GPIOG->AFR[0]  = 0x00CC00CC;
0422   GPIOG->AFR[1]  = 0xC000000C;
0423   /* Configure PGx pins in Alternate function mode */
0424   GPIOG->MODER   = 0xBFFEFAFA;
0425  /* Configure PGx pins speed to 100 MHz */
0426   GPIOG->OSPEEDR = 0xC0030F0F;
0427   /* Configure PGx pins Output type to push-pull */
0428   GPIOG->OTYPER  = 0x00000000;
0429   /* Configure PGx pins in Pull-up */
0430   GPIOG->PUPDR   = 0x40010505;
0431 
0432   /* Connect PHx pins to FMC Alternate function */
0433   GPIOH->AFR[0]  = 0xCCC00000;
0434   GPIOH->AFR[1]  = 0xCCCCCCCC;
0435   /* Configure PHx pins in Alternate function mode */
0436   GPIOH->MODER   = 0xAAAAABFF;
0437   /* Configure PHx pins speed to 100 MHz */
0438   GPIOH->OSPEEDR = 0xFFFFFC00;
0439   /* Configure PHx pins Output type to push-pull */
0440   GPIOH->OTYPER  = 0x00000000;
0441   /* Configure PHx pins in Pull-up */
0442   GPIOH->PUPDR   = 0x55555400;
0443 
0444 /*-- FMC Configuration ------------------------------------------------------*/
0445   /* Enable the FMC interface clock */
0446   (RCC->AHB3ENR |= (RCC_AHB3ENR_FMCEN));
0447   /*SDRAM Timing and access interface configuration*/
0448   /*LoadToActiveDelay  = 2
0449     ExitSelfRefreshDelay = 6
0450     SelfRefreshTime      = 4
0451     RowCycleDelay        = 6
0452     WriteRecoveryTime    = 2
0453     RPDelay              = 2
0454     RCDDelay             = 2
0455     SDBank             = FMC_SDRAM_BANK2
0456     ColumnBitsNumber   = FMC_SDRAM_COLUMN_BITS_NUM_8
0457     RowBitsNumber      = FMC_SDRAM_ROW_BITS_NUM_12
0458     MemoryDataWidth    = FMC_SDRAM_MEM_BUS_WIDTH_16
0459     InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4
0460     CASLatency         = FMC_SDRAM_CAS_LATENCY_2
0461     WriteProtection    = FMC_SDRAM_WRITE_PROTECTION_DISABLE
0462     SDClockPeriod      = FMC_SDRAM_CLOCK_PERIOD_2
0463     ReadBurst          = FMC_SDRAM_RBURST_ENABLE
0464     ReadPipeDelay      = FMC_SDRAM_RPIPE_DELAY_0*/
0465 
0466   FMC_Bank5_6_R->SDCR[0] = 0x00001800;
0467   FMC_Bank5_6_R->SDCR[1] = 0x00000154;
0468   FMC_Bank5_6_R->SDTR[0] = 0x00105000;
0469   FMC_Bank5_6_R->SDTR[1] = 0x01010351;
0470 
0471   /* SDRAM initialization sequence */
0472   /* Clock enable command */
0473   FMC_Bank5_6_R->SDCMR = 0x00000009;
0474   tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020;
0475   while((tmpreg != 0) && (timeout-- > 0))
0476   {
0477     tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020;
0478   }
0479 
0480   /* Delay */
0481   for (index = 0; index<1000; index++);
0482 
0483   /* PALL command */
0484     FMC_Bank5_6_R->SDCMR = 0x0000000A;
0485   timeout = 0xFFFF;
0486   while((tmpreg != 0) && (timeout-- > 0))
0487   {
0488     tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020;
0489   }
0490 
0491   FMC_Bank5_6_R->SDCMR = 0x000000EB;
0492   timeout = 0xFFFF;
0493   while((tmpreg != 0) && (timeout-- > 0))
0494   {
0495     tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020;
0496   }
0497 
0498   FMC_Bank5_6_R->SDCMR = 0x0004400C;
0499   timeout = 0xFFFF;
0500   while((tmpreg != 0) && (timeout-- > 0))
0501   {
0502     tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020;
0503   }
0504   /* Set refresh count */
0505   tmpreg = FMC_Bank5_6_R->SDRTR;
0506   FMC_Bank5_6_R->SDRTR = (tmpreg | (0x00000603<<1));
0507 
0508   /* Disable write protection */
0509   tmpreg = FMC_Bank5_6_R->SDCR[1];
0510   FMC_Bank5_6_R->SDCR[1] = (tmpreg & 0xFFFFFDFF);
0511 
0512    /*FMC controller Enable*/
0513   FMC_Bank1_R->BTCR[0]  |= 0x80000000;
0514 
0515   (void)(tmp);
0516 }
0517 #endif /* DATA_IN_ExtSDRAM */
0518 
0519 
0520 /**
0521   * @}
0522   */
0523 
0524 /**
0525   * @}
0526   */
0527 
0528 /**
0529   * @}
0530   */