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, 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   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
0026   * All rights reserved.</center></h2>
0027   *
0028   * This software component is licensed by ST under BSD 3-Clause license,
0029   * the "License"; You may not use this file except in compliance with the
0030   * License. You may obtain a copy of the License at:
0031   *                        opensource.org/licenses/BSD-3-Clause
0032   *
0033   ******************************************************************************
0034   */
0035 
0036 /** @addtogroup CMSIS
0037   * @{
0038   */
0039 
0040 /** @addtogroup stm32h7xx_system
0041   * @{
0042   */
0043 
0044 /** @addtogroup STM32H7xx_System_Private_Includes
0045   * @{
0046   */
0047 
0048 #include "stm32h7xx.h"
0049 #include <math.h>
0050 #ifdef __rtems__
0051 #include <bsp/linker-symbols.h>
0052 #include <bspopts.h>
0053 
0054 #define HSE_VALUE STM32H7_HSE_FREQUENCY
0055 
0056 #endif /* __rtems__ */
0057 #if !defined  (HSE_VALUE)
0058 #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
0059 #endif /* HSE_VALUE */
0060 
0061 #if !defined  (CSI_VALUE)
0062   #define CSI_VALUE    ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/
0063 #endif /* CSI_VALUE */
0064 
0065 #if !defined  (HSI_VALUE)
0066   #define HSI_VALUE    ((uint32_t)64000000) /*!< Value of the Internal oscillator in Hz*/
0067 #endif /* HSI_VALUE */
0068 
0069 
0070 /**
0071   * @}
0072   */
0073 
0074 /** @addtogroup STM32H7xx_System_Private_TypesDefinitions
0075   * @{
0076   */
0077 
0078 /**
0079   * @}
0080   */
0081 
0082 /** @addtogroup STM32H7xx_System_Private_Defines
0083   * @{
0084   */
0085 
0086 /************************* Miscellaneous Configuration ************************/
0087 /*!< Uncomment the following line if you need to use initialized data in D2 domain SRAM (AHB SRAM) */
0088 /* #define DATA_IN_D2_SRAM */
0089 
0090 /*!< Uncomment the following line if you need to relocate your vector Table in
0091      Internal SRAM. */
0092 /* #define VECT_TAB_SRAM */
0093 #define VECT_TAB_OFFSET  0x00000000UL /*!< Vector Table base offset field.
0094                                       This value must be a multiple of 0x200. */
0095 /******************************************************************************/
0096 
0097 /**
0098   * @}
0099   */
0100 
0101 /** @addtogroup STM32H7xx_System_Private_Macros
0102   * @{
0103   */
0104 
0105 /**
0106   * @}
0107   */
0108 
0109 /** @addtogroup STM32H7xx_System_Private_Variables
0110   * @{
0111   */
0112   /* This variable is updated in three ways:
0113       1) by calling CMSIS function SystemCoreClockUpdate()
0114       2) by calling HAL API function HAL_RCC_GetHCLKFreq()
0115       3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
0116          Note: If you use this function to configure the system clock; then there
0117                is no need to call the 2 first functions listed above, since SystemCoreClock
0118                variable is updated automatically.
0119   */
0120 #ifndef __rtems__
0121   uint32_t SystemCoreClock = 64000000;
0122   uint32_t SystemD2Clock = 64000000;
0123 #else /* __rtems__ */
0124   RTEMS_SECTION(".rtemsstack") uint32_t SystemCoreClock;
0125   RTEMS_SECTION(".rtemsstack") uint32_t SystemD2Clock;
0126 #endif /* __rtems__ */
0127   const  uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
0128 
0129 /**
0130   * @}
0131   */
0132 
0133 /** @addtogroup STM32H7xx_System_Private_FunctionPrototypes
0134   * @{
0135   */
0136 
0137 /**
0138   * @}
0139   */
0140 
0141 /** @addtogroup STM32H7xx_System_Private_Functions
0142   * @{
0143   */
0144 
0145 /**
0146   * @brief  Setup the microcontroller system
0147   *         Initialize the FPU setting and  vector table location
0148   *         configuration.
0149   * @param  None
0150   * @retval None
0151   */
0152 void SystemInit (void)
0153 {
0154 #if defined (DATA_IN_D2_SRAM)
0155  __IO uint32_t tmpreg;
0156 #endif /* DATA_IN_D2_SRAM */
0157 
0158   /* FPU settings ------------------------------------------------------------*/
0159   #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
0160     SCB->CPACR |= ((3UL << (10*2))|(3UL << (11*2)));  /* set CP10 and CP11 Full Access */
0161   #endif
0162   /* Reset the RCC clock configuration to the default reset state ------------*/
0163   /* Set HSION bit */
0164   RCC->CR |= RCC_CR_HSION;
0165 
0166   /* Reset CFGR register */
0167   RCC->CFGR = 0x00000000;
0168 
0169   /* Reset HSEON, CSSON , CSION,RC48ON, CSIKERON PLL1ON, PLL2ON and PLL3ON bits */
0170   RCC->CR &= 0xEAF6ED7FU;
0171 
0172 #if defined(D3_SRAM_BASE)
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 #else
0182   /* Reset CDCFGR1 register */
0183   RCC->CDCFGR1 = 0x00000000;
0184 
0185   /* Reset CDCFGR2 register */
0186   RCC->CDCFGR2 = 0x00000000;
0187 
0188   /* Reset SRDCFGR register */
0189   RCC->SRDCFGR = 0x00000000;
0190 #endif
0191   /* Reset PLLCKSELR register */
0192   RCC->PLLCKSELR = 0x00000000;
0193 
0194   /* Reset PLLCFGR register */
0195   RCC->PLLCFGR = 0x00000000;
0196   /* Reset PLL1DIVR register */
0197   RCC->PLL1DIVR = 0x00000000;
0198   /* Reset PLL1FRACR register */
0199   RCC->PLL1FRACR = 0x00000000;
0200 
0201   /* Reset PLL2DIVR register */
0202   RCC->PLL2DIVR = 0x00000000;
0203 
0204   /* Reset PLL2FRACR register */
0205 
0206   RCC->PLL2FRACR = 0x00000000;
0207   /* Reset PLL3DIVR register */
0208   RCC->PLL3DIVR = 0x00000000;
0209 
0210   /* Reset PLL3FRACR register */
0211   RCC->PLL3FRACR = 0x00000000;
0212 
0213   /* Reset HSEBYP bit */
0214   RCC->CR &= 0xFFFBFFFFU;
0215 
0216   /* Disable all interrupts */
0217   RCC->CIER = 0x00000000;
0218 
0219 #if (STM32H7_DEV_ID == 0x450UL)
0220   /* dual core CM7 or single core line */
0221   if((DBGMCU->IDCODE & 0xFFFF0000U) < 0x20000000U)
0222   {
0223     /* if stm32h7 revY*/
0224     /* Change  the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */
0225     *((__IO uint32_t*)0x51008108) = 0x000000001U;
0226   }
0227 #endif
0228 
0229 #ifndef __rtems__
0230 #if defined (DATA_IN_D2_SRAM)
0231   /* in case of initialized data in D2 SRAM (AHB SRAM) , enable the D2 SRAM clock (AHB SRAM clock) */
0232 #if defined(RCC_AHB2ENR_D2SRAM3EN)
0233   RCC->AHB2ENR |= (RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN | RCC_AHB2ENR_D2SRAM3EN);
0234 #elif defined(RCC_AHB2ENR_D2SRAM2EN)
0235   RCC->AHB2ENR |= (RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN);
0236 #else
0237   RCC->AHB2ENR |= (RCC_AHB2ENR_AHBSRAM1EN | RCC_AHB2ENR_AHBSRAM2EN);
0238 #endif /* RCC_AHB2ENR_D2SRAM3EN */
0239 
0240   tmpreg = RCC->AHB2ENR;
0241   (void) tmpreg;
0242 #endif /* DATA_IN_D2_SRAM */
0243 #else /* __rtems__ */
0244   RCC->AHB2ENR |= (RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN | RCC_AHB2ENR_D2SRAM3EN);
0245   RCC->AHB2ENR;
0246 #endif /* __rtems__ */
0247 
0248 #ifndef __rtems__
0249 #if defined(DUAL_CORE) && defined(CORE_CM4)
0250   /* Configure the Vector Table location add offset address for cortex-M4 ------------------*/
0251 #ifdef VECT_TAB_SRAM
0252   SCB->VTOR = D2_AHBSRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
0253 #else
0254   SCB->VTOR = FLASH_BANK2_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
0255 #endif /* VECT_TAB_SRAM */
0256 
0257 #else
0258 
0259   /* Configure the Vector Table location add offset address for cortex-M7 ------------------*/
0260 #ifdef VECT_TAB_SRAM
0261   SCB->VTOR = D1_AXISRAM_BASE  | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal AXI-RAM */
0262 #else
0263   SCB->VTOR = FLASH_BANK1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
0264 #endif
0265 
0266 #endif /*DUAL_CORE && CORE_CM4*/
0267 #else /* __rtems__ */
0268   SCB->VTOR = (uint32_t) bsp_start_vector_table_begin;
0269 #endif /* __rtems__ */
0270 
0271 }
0272 
0273 /**
0274    * @brief  Update SystemCoreClock variable according to Clock Register Values.
0275   *         The SystemCoreClock variable contains the core clock , it can
0276   *         be used by the user application to setup the SysTick timer or configure
0277   *         other parameters.
0278   *
0279   * @note   Each time the core clock changes, this function must be called
0280   *         to update SystemCoreClock variable value. Otherwise, any configuration
0281   *         based on this variable will be incorrect.
0282   *
0283   * @note   - The system frequency computed by this function is not the real
0284   *           frequency in the chip. It is calculated based on the predefined
0285   *           constant and the selected clock source:
0286   *
0287   *           - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*)
0288   *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
0289   *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
0290   *           - If SYSCLK source is PLL, SystemCoreClock will contain the CSI_VALUE(*),
0291   *             HSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
0292   *
0293   *         (*) CSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value
0294   *             4 MHz) but the real value may vary depending on the variations
0295   *             in voltage and temperature.
0296   *         (**) HSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value
0297   *             64 MHz) but the real value may vary depending on the variations
0298   *             in voltage and temperature.
0299   *
0300   *         (***)HSE_VALUE is a constant defined in stm32h7xx_hal.h file (default value
0301   *              25 MHz), user has to ensure that HSE_VALUE is same as the real
0302   *              frequency of the crystal used. Otherwise, this function may
0303   *              have wrong result.
0304   *
0305   *         - The result of this function could be not correct when using fractional
0306   *           value for HSE crystal.
0307   * @param  None
0308   * @retval None
0309   */
0310 void SystemCoreClockUpdate (void)
0311 {
0312   uint32_t pllp, pllsource, pllm, pllfracen, hsivalue, tmp;
0313   uint32_t common_system_clock;
0314   float_t fracn1, pllvco;
0315 
0316 
0317   /* Get SYSCLK source -------------------------------------------------------*/
0318 
0319   switch (RCC->CFGR & RCC_CFGR_SWS)
0320   {
0321   case RCC_CFGR_SWS_HSI:  /* HSI used as system clock source */
0322     common_system_clock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3));
0323     break;
0324 
0325   case RCC_CFGR_SWS_CSI:  /* CSI used as system clock  source */
0326     common_system_clock = CSI_VALUE;
0327     break;
0328 
0329   case RCC_CFGR_SWS_HSE:  /* HSE used as system clock  source */
0330     common_system_clock = HSE_VALUE;
0331     break;
0332 
0333   case RCC_CFGR_SWS_PLL1:  /* PLL1 used as system clock  source */
0334 
0335     /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
0336     SYSCLK = PLL_VCO / PLLR
0337     */
0338     pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
0339     pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1)>> 4)  ;
0340     pllfracen = ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN)>>RCC_PLLCFGR_PLL1FRACEN_Pos);
0341     fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN1)>> 3));
0342 
0343     if (pllm != 0U)
0344     {
0345       switch (pllsource)
0346       {
0347         case RCC_PLLCKSELR_PLLSRC_HSI:  /* HSI used as PLL clock source */
0348 
0349         hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ;
0350         pllvco = ( (float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
0351 
0352         break;
0353 
0354         case RCC_PLLCKSELR_PLLSRC_CSI:  /* CSI used as PLL clock source */
0355           pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
0356         break;
0357 
0358         case RCC_PLLCKSELR_PLLSRC_HSE:  /* HSE used as PLL clock source */
0359           pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
0360         break;
0361 
0362       default:
0363           pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
0364         break;
0365       }
0366       pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_P1) >>9) + 1U ) ;
0367       common_system_clock =  (uint32_t)(float_t)(pllvco/(float_t)pllp);
0368     }
0369     else
0370     {
0371       common_system_clock = 0U;
0372     }
0373     break;
0374 
0375   default:
0376     common_system_clock = CSI_VALUE;
0377     break;
0378   }
0379 
0380   /* Compute SystemClock frequency --------------------------------------------------*/
0381 #if defined (RCC_D1CFGR_D1CPRE)
0382   tmp = D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_D1CPRE)>> RCC_D1CFGR_D1CPRE_Pos];
0383 
0384   /* common_system_clock frequency : CM7 CPU frequency  */
0385   common_system_clock >>= tmp;
0386 
0387   /* SystemD2Clock frequency : CM4 CPU, AXI and AHBs Clock frequency  */
0388   SystemD2Clock = (common_system_clock >> ((D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_HPRE)>> RCC_D1CFGR_HPRE_Pos]) & 0x1FU));
0389 
0390 #else
0391   tmp = D1CorePrescTable[(RCC->CDCFGR1 & RCC_CDCFGR1_CDCPRE)>> RCC_CDCFGR1_CDCPRE_Pos];
0392 
0393   /* common_system_clock frequency : CM7 CPU frequency  */
0394   common_system_clock >>= tmp;
0395 
0396   /* SystemD2Clock frequency : AXI and AHBs Clock frequency  */
0397   SystemD2Clock = (common_system_clock >> ((D1CorePrescTable[(RCC->CDCFGR1 & RCC_CDCFGR1_HPRE)>> RCC_CDCFGR1_HPRE_Pos]) & 0x1FU));
0398 
0399 #endif
0400 
0401 #if defined(DUAL_CORE) && defined(CORE_CM4)
0402   SystemCoreClock = SystemD2Clock;
0403 #else
0404   SystemCoreClock = common_system_clock;
0405 #endif /* DUAL_CORE && CORE_CM4 */
0406 }
0407 
0408 
0409 /**
0410   * @}
0411   */
0412 
0413 /**
0414   * @}
0415   */
0416 
0417 /**
0418   * @}
0419   */
0420 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/