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