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