1 /**
2   ******************************************************************************
3   * @file    system_stm32h7rsxx.c
4   * @author  MCD Application Team
5   * @brief   CMSIS Cortex-M7 Device Peripheral Access Layer System Source File
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2022 STMicroelectronics.
10   * All rights reserved.
11   *
12   * This software is licensed under terms that can be found in the LICENSE file
13   * in the root directory of this software component.
14   * If no LICENSE file comes with this software, it is provided AS-IS.
15   *
16   ******************************************************************************
17   *
18   *   This file provides two functions and one global variable to be called from
19   *   user application:
20   *      - SystemInit(): This function is called at startup just after reset and
21   *                      before branch to main program. This call is made inside
22   *                      the "startup_stm32h7rsxx.s" file.
23   *
24   *      - SystemCoreClock variable: Contains the core clock (sys_cpu_ck), it can
25   *                                  be used by the user application to setup the
26   *                                  SysTick timer or configure other parameters.
27   *
28   *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
29   *                                 be called whenever the core clock is changed
30   *                                 during program execution.
31   *
32   *   After each device reset the HSI (64 MHz) is used as system clock source.
33   *   Then SystemInit() function is called, in "startup_stm32h7rsxx.s" file, to
34   *   optionally configure the system clock before to branch to main program.
35   *
36   *=============================================================================
37   */
38 
39 /** @addtogroup CMSIS
40   * @{
41   */
42 
43 /** @addtogroup STM32H7RSxx_System
44   * @{
45   */
46 
47 /** @addtogroup STM32H7RSxx_System_Private_Includes
48   * @{
49   */
50 
51 #include "stm32h7rsxx.h"
52 #include <math.h>
53 
54 /**
55   * @}
56   */
57 
58 /** @addtogroup STM32H7RSxx_System_Private_TypesDefinitions
59   * @{
60   */
61 
62 /**
63   * @}
64   */
65 
66 /** @addtogroup STM32H7RSxx_System_Private_Defines
67   * @{
68   */
69 #if !defined  (HSE_VALUE)
70   #define HSE_VALUE    24000000UL /*!< Value of the High-Speed External oscillator in Hz */
71 #endif /* HSE_VALUE */
72 
73 #if !defined  (HSI_VALUE)
74   #define HSI_VALUE    64000000UL /*!< Value of the High-Speed Internal oscillator in Hz */
75 #endif /* HSI_VALUE */
76 
77 #if !defined  (CSI_VALUE)
78   #define CSI_VALUE    4000000UL  /*!< Value of the Low-power Internal oscillator in Hz */
79 #endif /* CSI_VALUE */
80 
81 /*!< The VTOR location information is based on information from the linker with a dependency
82      on the IDE, the cortex register is updated using the INTVECT_START.
83 */
84 #if defined(__ICCARM__)
85 extern uint32_t __vector_table;
86 #define INTVECT_START ((uint32_t)& __vector_table)
87 #elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
88 extern void * __Vectors;
89 #define INTVECT_START ((uint32_t) & __Vectors)
90 #elif defined(__GNUC__)
91 extern void * g_pfnVectors;
92 #define INTVECT_START ((uint32_t)& g_pfnVectors)
93 #endif /* __ICCARM__*/
94 
95 
96 
97 /******************************************************************************/
98 /**
99   * @}
100   */
101 
102 /** @addtogroup STM32H7RSxx_System_Private_Macros
103   * @{
104   */
105 
106 /**
107   * @}
108   */
109 
110 /** @addtogroup STM32H7RSxx_System_Private_Variables
111   * @{
112   */
113   /* The SystemCoreClock variable is updated in two ways:
114       1) by calling CMSIS function SystemCoreClockUpdate()
115       2) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
116          Note: If you use this function to configure the system clock; then there
117                is no need to call the first function listed above, since SystemCoreClock
118                variable is updated automatically.
119   */
120 uint32_t SystemCoreClock = HSI_VALUE;
121 
122 /**
123   * @}
124   */
125 
126 /** @addtogroup STM32H7RSxx_System_Private_FunctionPrototypes
127   * @{
128   */
129 
130 /**
131   * @}
132   */
133 
134 /** @addtogroup STM32H7RSxx_System_Private_Functions
135   * @{
136   */
137 
138 /**
139   * @brief  Setup the microcontroller system.
140   * @retval None
141   */
142 
SystemInit(void)143 void SystemInit(void)
144 {
145   /* Configure the Vector Table location -------------------------------------*/
146   SCB->VTOR = INTVECT_START;
147 
148   /* FPU settings ------------------------------------------------------------*/
149 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
150   SCB->CPACR |= ((3UL << 20U)|(3UL << 22U));  /* set CP10 and CP11 Full Access */
151 #endif
152 }
153 
154 /**
155   * @brief  Update SystemCoreClock variable according to RCC registers values.
156   *         The SystemCoreClock variable contains the core clock (sys_cpu_ck), it can
157   *         be used by the user application to setup the SysTick timer or configure
158   *         other parameters.
159   *
160   * @note   Each time the core clock changes, this function must be called
161   *         to update SystemCoreClock variable value. Otherwise, any configuration
162   *         based on this variable will be incorrect.
163   *
164   * @note   - The system frequency computed by this function is not the real
165   *           frequency in the chip. It is calculated based on the predefined
166   *           constant and the selected clock source:
167   *
168   *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
169   *
170   *           - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(**)
171   *
172   *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
173   *
174   *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSI_VALUE(*)
175   *             or CSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
176   *
177   *         (*) HSI_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value
178   *              64 MHz) but the real value may vary depending on the variations
179   *              in voltage and temperature.
180   *
181   *         (**) CSI_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value
182   *             4 MHz) but the real value may vary depending on the variations
183   *             in voltage and temperature.
184   *
185   *         (***) HSE_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value
186   *              24 MHz), user has to ensure that HSE_VALUE is same as the real
187   *              frequency of the crystal used. Otherwise, this function may
188   *              have wrong result.
189   *
190   *         - The result of this function could be not correct when using fractional
191   *           value for HSE crystal.
192   *
193   * @retval None
194   */
SystemCoreClockUpdate(void)195 void SystemCoreClockUpdate(void)
196 {
197   uint32_t sysclk, hsivalue, pllsource, pllm, pllp, core_presc;
198   float_t pllfracn, pllvco;
199 
200   /* Get SYSCLK source -------------------------------------------------------*/
201   switch (RCC->CFGR & RCC_CFGR_SWS)
202   {
203   case 0x00:  /* HSI used as system clock source (default after reset) */
204     sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos));
205     break;
206 
207   case 0x08:  /* CSI used as system clock source */
208     sysclk = CSI_VALUE;
209     break;
210 
211   case 0x10:  /* HSE used as system clock source */
212     sysclk = HSE_VALUE;
213     break;
214 
215   case 0x18:  /* PLL1 used as system clock  source */
216     /* PLL1_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
217        SYSCLK = PLL1_VCO / PLL1R
218        */
219     pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
220     pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos)  ;
221     if ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN) != 0U)
222     {
223       pllfracn = (float_t)(uint32_t)(((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN)>> RCC_PLL1FRACR_FRACN_Pos));
224     }
225     else
226     {
227       pllfracn = (float_t)0U;
228     }
229 
230     if (pllm != 0U)
231     {
232       switch (pllsource)
233       {
234       case 0x02:  /* HSE used as PLL1 clock source */
235         pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 );
236         break;
237 
238       case 0x01:  /* CSI used as PLL1 clock source */
239         pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 );
240         break;
241 
242       case 0x00:  /* HSI used as PLL1 clock source */
243       default:
244         hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos));
245         pllvco = ( (float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 );
246         break;
247       }
248       pllp = (((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVP) >> RCC_PLL1DIVR1_DIVP_Pos) + 1U ) ;
249       sysclk =  (uint32_t)(float_t)(pllvco/(float_t)pllp);
250     }
251     else
252     {
253       sysclk = 0U;
254     }
255     break;
256 
257   default:  /* Unexpected, default to HSI used as system clock source (default after reset) */
258     sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos));
259     break;
260   }
261 
262   /* system clock frequency : CM7 CPU frequency  */
263   core_presc = (RCC->CDCFGR & RCC_CDCFGR_CPRE);
264   if (core_presc >= 8U)
265   {
266     SystemCoreClock = (sysclk >> (core_presc - RCC_CDCFGR_CPRE_3 + 1U));
267   }
268   else
269   {
270     SystemCoreClock = sysclk;
271   }
272 }
273 
274 
275 /**
276   * @}
277   */
278 
279 /**
280   * @}
281   */
282 
283 /**
284   * @}
285   */
286