1 /**
2 ******************************************************************************
3 * @file system_stm32h5xx.c
4 * @author MCD Application Team
5 * @brief CMSIS Cortex-M33 Device Peripheral Access Layer System Source File
6 *
7 ******************************************************************************
8 * @attention
9 *
10 * Copyright (c) 2023 STMicroelectronics.
11 * All rights reserved.
12 *
13 * This software is licensed under terms that can be found in the LICENSE file
14 * in the root directory of this software component.
15 * If no LICENSE file comes with this software, it is provided AS-IS.
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_stm32h5xx.s" file.
23 *
24 * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
25 * by the user application to setup the SysTick
26 * 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_stm32h5xx.s" file, to
34 * configure the system clock before to branch to main program.
35 *
36 * This file configures the system clock as follows:
37 *=============================================================================
38 *-----------------------------------------------------------------------------
39 * System Clock source | HSI
40 *-----------------------------------------------------------------------------
41 * SYSCLK(Hz) | 64000000
42 *-----------------------------------------------------------------------------
43 * HCLK(Hz) | 64000000
44 *-----------------------------------------------------------------------------
45 * AHB Prescaler | 1
46 *-----------------------------------------------------------------------------
47 * APB1 Prescaler | 1
48 *-----------------------------------------------------------------------------
49 * APB2 Prescaler | 1
50 *-----------------------------------------------------------------------------
51 * APB3 Prescaler | 1
52 *-----------------------------------------------------------------------------
53 * HSI Division factor | 1
54 *-----------------------------------------------------------------------------
55 * PLL1_SRC | No clock
56 *-----------------------------------------------------------------------------
57 * PLL1_M | Prescaler disabled
58 *-----------------------------------------------------------------------------
59 * PLL1_N | 129
60 *-----------------------------------------------------------------------------
61 * PLL1_P | 2
62 *-----------------------------------------------------------------------------
63 * PLL1_Q | 2
64 *-----------------------------------------------------------------------------
65 * PLL1_R | 2
66 *-----------------------------------------------------------------------------
67 * PLL1_FRACN | 0
68 *-----------------------------------------------------------------------------
69 * PLL2_SRC | No clock
70 *-----------------------------------------------------------------------------
71 * PLL2_M | Prescaler disabled
72 *-----------------------------------------------------------------------------
73 * PLL2_N | 129
74 *-----------------------------------------------------------------------------
75 * PLL2_P | 2
76 *-----------------------------------------------------------------------------
77 * PLL2_Q | 2
78 *-----------------------------------------------------------------------------
79 * PLL2_R | 2
80 *-----------------------------------------------------------------------------
81 * PLL2_FRACN | 0
82 *-----------------------------------------------------------------------------
83 * PLL3_SRC | No clock
84 *-----------------------------------------------------------------------------
85 * PLL3_M | Prescaler disabled
86 *-----------------------------------------------------------------------------
87 * PLL3_N | 129
88 *-----------------------------------------------------------------------------
89 * PLL3_P | 2
90 *-----------------------------------------------------------------------------
91 * PLL3_Q | 2
92 *-----------------------------------------------------------------------------
93 * PLL3_R | 2
94 *-----------------------------------------------------------------------------
95 * PLL3_FRACN | 0
96 *-----------------------------------------------------------------------------
97 *=============================================================================
98 */
99
100 /** @addtogroup CMSIS
101 * @{
102 */
103
104 /** @addtogroup STM32H5xx_system
105 * @{
106 */
107
108 /** @addtogroup STM32H5xx_System_Private_Includes
109 * @{
110 */
111
112 #include "stm32h5xx.h"
113
114 /**
115 * @}
116 */
117
118 /** @addtogroup STM32H5xx_System_Private_TypesDefinitions
119 * @{
120 */
121
122 /**
123 * @}
124 */
125
126 /** @addtogroup STM32H5xx_System_Private_Defines
127 * @{
128 */
129
130 #if !defined (HSE_VALUE)
131 #define HSE_VALUE (25000000UL) /*!< Value of the External oscillator in Hz */
132 #endif /* HSE_VALUE */
133
134 #if !defined (CSI_VALUE)
135 #define CSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/
136 #endif /* CSI_VALUE */
137
138 #if !defined (HSI_VALUE)
139 #define HSI_VALUE (64000000UL) /*!< Value of the Internal oscillator in Hz */
140 #endif /* HSI_VALUE */
141
142 /************************* Miscellaneous Configuration ************************/
143 /*!< Uncomment the following line if you need to relocate your vector Table in
144 Internal SRAM. */
145 /* #define VECT_TAB_SRAM */
146 #define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field.
147 This value must be a multiple of 0x200. */
148 /******************************************************************************/
149
150 /**
151 * @}
152 */
153
154 /** @addtogroup STM32H5xx_System_Private_Macros
155 * @{
156 */
157
158 /**
159 * @}
160 */
161
162 /** @addtogroup STM32H5xx_System_Private_Variables
163 * @{
164 */
165 /* The SystemCoreClock variable is updated in three ways:
166 1) by calling CMSIS function SystemCoreClockUpdate()
167 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
168 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
169 Note: If you use this function to configure the system clock; then there
170 is no need to call the 2 first functions listed above, since SystemCoreClock
171 variable is updated automatically.
172 */
173 uint32_t SystemCoreClock = 64000000U;
174
175 const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
176 const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
177 /**
178 * @}
179 */
180
181 /** @addtogroup STM32H5xx_System_Private_FunctionPrototypes
182 * @{
183 */
184
185 /**
186 * @}
187 */
188
189 /** @addtogroup STM32H5xx_System_Private_Functions
190 * @{
191 */
192
193 /**
194 * @brief Setup the microcontroller system.
195 * @param None
196 * @retval None
197 */
198
SystemInit(void)199 void SystemInit(void)
200 {
201 uint32_t reg_opsr;
202
203 /* FPU settings ------------------------------------------------------------*/
204 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
205 SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */
206 #endif
207
208 /* Reset the RCC clock configuration to the default reset state ------------*/
209 /* Set HSION bit */
210 RCC->CR = RCC_CR_HSION;
211
212 /* Reset CFGR register */
213 RCC->CFGR1 = 0U;
214 RCC->CFGR2 = 0U;
215
216 /* Reset HSEON, HSECSSON, HSEBYP, HSEEXT, HSIDIV, HSIKERON, CSION, CSIKERON, HSI48 and PLLxON bits */
217 #if defined(RCC_CR_PLL3ON)
218 RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_HSECSSON | RCC_CR_HSEBYP | RCC_CR_HSEEXT | RCC_CR_HSIDIV | RCC_CR_HSIKERON | \
219 RCC_CR_CSION | RCC_CR_CSIKERON |RCC_CR_HSI48ON | RCC_CR_PLL1ON | RCC_CR_PLL2ON | RCC_CR_PLL3ON);
220 #else
221 RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_HSECSSON | RCC_CR_HSEBYP | RCC_CR_HSEEXT | RCC_CR_HSIDIV | RCC_CR_HSIKERON | \
222 RCC_CR_CSION | RCC_CR_CSIKERON |RCC_CR_HSI48ON | RCC_CR_PLL1ON | RCC_CR_PLL2ON);
223 #endif
224
225 /* Reset PLLxCFGR register */
226 RCC->PLL1CFGR = 0U;
227 RCC->PLL2CFGR = 0U;
228 #if defined(RCC_CR_PLL3ON)
229 RCC->PLL3CFGR = 0U;
230 #endif /* RCC_CR_PLL3ON */
231
232 /* Reset PLL1DIVR register */
233 RCC->PLL1DIVR = 0x01010280U;
234 /* Reset PLL1FRACR register */
235 RCC->PLL1FRACR = 0x00000000U;
236 /* Reset PLL2DIVR register */
237 RCC->PLL2DIVR = 0x01010280U;
238 /* Reset PLL2FRACR register */
239 RCC->PLL2FRACR = 0x00000000U;
240 #if defined(RCC_CR_PLL3ON)
241 /* Reset PLL3DIVR register */
242 RCC->PLL3DIVR = 0x01010280U;
243 /* Reset PLL3FRACR register */
244 RCC->PLL3FRACR = 0x00000000U;
245 #endif /* RCC_CR_PLL3ON */
246
247 /* Reset HSEBYP bit */
248 RCC->CR &= ~(RCC_CR_HSEBYP);
249
250 /* Disable all interrupts */
251 RCC->CIER = 0U;
252
253 /* Configure the Vector Table location add offset address ------------------*/
254 #ifdef VECT_TAB_SRAM
255 SCB->VTOR = SRAM1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
256 #else
257 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
258 #endif /* VECT_TAB_SRAM */
259
260 /* Check OPSR register to verify if there is an ongoing swap or option bytes update interrupted by a reset */
261 reg_opsr = FLASH->OPSR & FLASH_OPSR_CODE_OP;
262 if ((reg_opsr == FLASH_OPSR_CODE_OP) || (reg_opsr == (FLASH_OPSR_CODE_OP_2 | FLASH_OPSR_CODE_OP_1)))
263 {
264 /* Check FLASH Option Control Register access */
265 if ((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != 0U)
266 {
267 /* Authorizes the Option Byte registers programming */
268 FLASH->OPTKEYR = 0x08192A3BU;
269 FLASH->OPTKEYR = 0x4C5D6E7FU;
270 }
271 /* Launch the option bytes change operation */
272 FLASH->OPTCR |= FLASH_OPTCR_OPTSTART;
273
274 /* Lock the FLASH Option Control Register access */
275 FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK;
276 }
277 }
278
279 /**
280 * @brief Update SystemCoreClock variable according to Clock Register Values.
281 * The SystemCoreClock variable contains the core clock (HCLK), it can
282 * be used by the user application to setup the SysTick timer or configure
283 * other parameters.
284 *
285 * @note Each time the core clock (HCLK) changes, this function must be called
286 * to update SystemCoreClock variable value. Otherwise, any configuration
287 * based on this variable will be incorrect.
288 *
289 * @note - The system frequency computed by this function is not the real
290 * frequency in the chip. It is calculated based on the predefined
291 * constant and the selected clock source:
292 *
293 * - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*)
294 *
295 * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
296 *
297 * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
298 *
299 * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
300 * or HSI_VALUE(**) or CSI_VALUE(*) multiplied/divided by the PLL factors.
301 *
302 * (*) CSI_VALUE is a constant defined in stm32h5xx_hal.h file (default value
303 * 4 MHz) but the real value may vary depending on the variations
304 * in voltage and temperature.
305 *
306 * (**) HSI_VALUE is a constant defined in stm32h5xx_hal.h file (default value
307 * 64 MHz) but the real value may vary depending on the variations
308 * in voltage and temperature.
309 *
310 * (***) HSE_VALUE is a constant defined in stm32h5xx_hal.h file (default value
311 * 25 MHz), user has to ensure that HSE_VALUE is same as the real
312 * frequency of the crystal used. Otherwise, this function may
313 * have wrong result.
314 *
315 * - The result of this function could be not correct when using fractional
316 * value for HSE crystal.
317 *
318 * @param None
319 * @retval None
320 */
SystemCoreClockUpdate(void)321 void SystemCoreClockUpdate(void)
322 {
323 uint32_t pllp, pllsource, pllm, pllfracen, hsivalue, tmp;
324 float_t fracn1, pllvco;
325
326 /* Get SYSCLK source -------------------------------------------------------*/
327 switch (RCC->CFGR1 & RCC_CFGR1_SWS)
328 {
329 case 0x00UL: /* HSI used as system clock source */
330 SystemCoreClock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3));
331 break;
332
333 case 0x08UL: /* CSI used as system clock source */
334 SystemCoreClock = CSI_VALUE;
335 break;
336
337 case 0x10UL: /* HSE used as system clock source */
338 SystemCoreClock = HSE_VALUE;
339 break;
340
341 case 0x18UL: /* PLL1 used as system clock source */
342 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
343 SYSCLK = PLL_VCO / PLLR
344 */
345 pllsource = (RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC);
346 pllm = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1M)>> RCC_PLL1CFGR_PLL1M_Pos);
347 pllfracen = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1FRACEN)>>RCC_PLL1CFGR_PLL1FRACEN_Pos);
348 fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN)>> RCC_PLL1FRACR_PLL1FRACN_Pos));
349
350 switch (pllsource)
351 {
352 case 0x01UL: /* HSI used as PLL clock source */
353 hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ;
354 pllvco = ((float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
355 (fracn1/(float_t)0x2000) +(float_t)1 );
356 break;
357
358 case 0x02UL: /* CSI used as PLL clock source */
359 pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
360 (fracn1/(float_t)0x2000) +(float_t)1 );
361 break;
362
363 case 0x03UL: /* HSE used as PLL clock source */
364 pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
365 (fracn1/(float_t)0x2000) +(float_t)1 );
366 break;
367
368 default: /* No clock sent to PLL*/
369 pllvco = (float_t) 0U;
370 break;
371 }
372
373 pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1P) >>RCC_PLL1DIVR_PLL1P_Pos) + 1U ) ;
374 SystemCoreClock = (uint32_t)(float_t)(pllvco/(float_t)pllp);
375
376 break;
377
378 default:
379 SystemCoreClock = HSI_VALUE;
380 break;
381 }
382 /* Compute HCLK clock frequency --------------------------------------------*/
383 /* Get HCLK prescaler */
384 tmp = AHBPrescTable[((RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos)];
385 /* HCLK clock frequency */
386 SystemCoreClock >>= tmp;
387 }
388
389
390 /**
391 * @}
392 */
393
394 /**
395 * @}
396 */
397
398 /**
399 * @}
400 */
401