1 /**
2 ******************************************************************************
3 * @file system_stm32u5xx_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 TrustZone-M security.
8 *
9 * This file provides two functions and one global variable to be called from
10 * user application:
11 * - SystemInit(): This function is called at secure startup just after reset
12 * and before branch to secure main program.
13 * This call is made inside the "startup_stm32u5xx.s" file.
14 *
15 * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
16 * by the user application to setup the SysTick
17 * timer or configure other parameters.
18 *
19 * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
20 * be called whenever the core clock is changed
21 * during program execution.
22 *
23 * - SECURE_SystemCoreClockUpdate(): Non-secure callable function to update
24 * the variable SystemCoreClock and return
25 * its value to the non-secure calling
26 * application. It must be called whenever
27 * the core clock is changed during program
28 * execution.
29 *
30 * After each device reset the MSI (4 MHz) is used as system clock source.
31 * Then SystemInit() function is called, in "startup_stm32u5xx.s" file, to
32 * configure the system clock before to branch to main program.
33 *
34 * This file configures the system clock as follows:
35 *=============================================================================
36 *-----------------------------------------------------------------------------
37 * System Clock source | MSI
38 *-----------------------------------------------------------------------------
39 * SYSCLK(Hz) | 4000000
40 *-----------------------------------------------------------------------------
41 * HCLK(Hz) | 4000000
42 *-----------------------------------------------------------------------------
43 * AHB Prescaler | 1
44 *-----------------------------------------------------------------------------
45 * APB1 Prescaler | 1
46 *-----------------------------------------------------------------------------
47 * APB2 Prescaler | 1
48 *-----------------------------------------------------------------------------
49 * APB3 Prescaler | 1
50 *-----------------------------------------------------------------------------
51 * PLL1_SRC | No clock
52 *-----------------------------------------------------------------------------
53 * PLL1_M | 1
54 *-----------------------------------------------------------------------------
55 * PLL1_N | 8
56 *-----------------------------------------------------------------------------
57 * PLL1_P | 7
58 *-----------------------------------------------------------------------------
59 * PLL1_Q | 2
60 *-----------------------------------------------------------------------------
61 * PLL1_R | 2
62 *-----------------------------------------------------------------------------
63 * PLL2_SRC | NA
64 *-----------------------------------------------------------------------------
65 * PLL2_M | NA
66 *-----------------------------------------------------------------------------
67 * PLL2_N | NA
68 *-----------------------------------------------------------------------------
69 * PLL2_P | NA
70 *-----------------------------------------------------------------------------
71 * PLL2_Q | NA
72 *-----------------------------------------------------------------------------
73 * PLL2_R | NA
74 *-----------------------------------------------------------------------------
75 * PLL3_SRC | NA
76 *-----------------------------------------------------------------------------
77 * PLL3_M | NA
78 *-----------------------------------------------------------------------------
79 * PLL3_N | NA
80 *-----------------------------------------------------------------------------
81 * PLL3_P | NA
82 *-----------------------------------------------------------------------------
83 * Require 48MHz for USB FS, | Disabled
84 * SDIO and RNG clock |
85 *-----------------------------------------------------------------------------
86 *=============================================================================
87 ******************************************************************************
88 * @attention
89 *
90 * Copyright (c) 2021 STMicroelectronics.
91 * All rights reserved.
92 *
93 * This software is licensed under terms that can be found in the LICENSE file
94 * in the root directory of this software component.
95 * If no LICENSE file comes with this software, it is provided AS-IS.
96 *
97 ******************************************************************************
98 */
99
100 /** @addtogroup CMSIS
101 * @{
102 */
103
104 /** @addtogroup STM32U5xx_system
105 * @{
106 */
107
108 /** @addtogroup STM32U5xx_System_Private_Includes
109 * @{
110 */
111
112 #include "stm32u5xx.h"
113 #include "partition_stm32u5xx.h" /* Trustzone-M core secure attributes */
114 #include <math.h>
115
116 /**
117 * @}
118 */
119
120 /** @addtogroup STM32U5xx_System_Private_TypesDefinitions
121 * @{
122 */
123
124 #if defined ( __ICCARM__ )
125 # define CMSE_NS_ENTRY __cmse_nonsecure_entry
126 #else
127 # define CMSE_NS_ENTRY __attribute((cmse_nonsecure_entry))
128 #endif
129 /**
130 * @}
131 */
132
133 /** @addtogroup STM32U5xx_System_Private_Defines
134 * @{
135 */
136 #if !defined (HSE_VALUE)
137 #define HSE_VALUE 16000000U /*!< Value of the External oscillator in Hz */
138 #endif /* HSE_VALUE */
139
140 #if !defined (MSI_VALUE)
141 #define MSI_VALUE 4000000U /*!< Value of the Internal oscillator in Hz*/
142 #endif /* MSI_VALUE */
143
144 #if !defined (HSI_VALUE)
145 #define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/
146 #endif /* HSI_VALUE */
147
148 /************************* Miscellaneous Configuration ************************/
149 /*!< Uncomment the following line if you need to relocate your vector Table in
150 Internal SRAM. */
151 /* #define VECT_TAB_SRAM */
152 #define VECT_TAB_OFFSET 0x00000000UL /*!< Vector Table base offset field.
153 This value must be a multiple of 0x200. */
154 /******************************************************************************/
155 /**
156 * @}
157 */
158
159 /** @addtogroup STM32U5xx_System_Private_Macros
160 * @{
161 */
162
163 /**
164 * @}
165 */
166
167 /** @addtogroup STM32U5xx_System_Private_Variables
168 * @{
169 */
170 /* The SystemCoreClock variable is updated in three ways:
171 1) by calling CMSIS function SystemCoreClockUpdate()
172 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
173 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
174 Note: If you use this function to configure the system clock; then there
175 is no need to call the 2 first functions listed above, since SystemCoreClock
176 variable is updated automatically.
177 */
178 uint32_t SystemCoreClock = 4000000U;
179
180 const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
181 const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
182 const uint32_t MSIRangeTable[16] = {48000000U,24000000U,16000000U,12000000U, 4000000U, 2000000U, 1330000U,\
183 1000000U, 3072000U, 1536000U,1024000U, 768000U, 400000U, 200000U, 133000U, 100000U};
184 /**
185 * @}
186 */
187
188 /** @addtogroup STM32U5xx_System_Private_FunctionPrototypes
189 * @{
190 */
191
192 /**
193 * @}
194 */
195
196 /** @addtogroup STM32U5xx_System_Private_Functions
197 * @{
198 */
199
200 /**
201 * @brief Setup the microcontroller system.
202 * @param None
203 * @retval None
204 */
205
SystemInit(void)206 void SystemInit(void)
207 {
208 /* SAU/IDAU, FPU and Interrupts secure/non-secure allocation settings */
209 TZ_SAU_Setup();
210
211 /* FPU settings ------------------------------------------------------------*/
212 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
213 SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */
214
215 SCB_NS->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */
216 #endif
217
218 /* Reset the RCC clock configuration to the default reset state ------------*/
219 /* Set MSION bit */
220 RCC->CR = RCC_CR_MSISON;
221
222 /* Reset CFGR register */
223 RCC->CFGR1 = 0U;
224 RCC->CFGR2 = 0U;
225 RCC->CFGR3 = 0U;
226
227 /* Reset HSEON, CSSON , HSION, PLLxON bits */
228 RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLL1ON | RCC_CR_PLL2ON | RCC_CR_PLL3ON);
229
230 /* Reset PLLCFGR register */
231 RCC->PLL1CFGR = 0U;
232
233 /* Reset HSEBYP bit */
234 RCC->CR &= ~(RCC_CR_HSEBYP);
235
236 /* Disable all interrupts */
237 RCC->CIER = 0U;
238
239 /* Configure the Vector Table location add offset address ------------------*/
240 #ifdef VECT_TAB_SRAM
241 SCB->VTOR = SRAM1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
242 #else
243 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
244 #endif
245 }
246
247 /**
248 * @brief Update SystemCoreClock variable according to Clock Register Values.
249 * The SystemCoreClock variable contains the core clock (HCLK), it can
250 * be used by the user application to setup the SysTick timer or configure
251 * other parameters.
252 *
253 * @note Depending on secure or non-secure compilation, the adequate RCC peripheral
254 * memory are is accessed thanks to RCC alias defined in stm32u5xxxx.h device file
255 * so either from RCC_S peripheral register mapped memory in secure or from
256 * RCC_NS peripheral register mapped memory in non-secure.
257 *
258 * @note Each time the core clock (HCLK) changes, this function must be called
259 * to update SystemCoreClock variable value. Otherwise, any configuration
260 * based on this variable will be incorrect.
261 *
262 * @note - The system frequency computed by this function is not the real
263 * frequency in the chip. It is calculated based on the predefined
264 * constant and the selected clock source:
265 *
266 * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*)
267 *
268 * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
269 *
270 * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
271 *
272 * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
273 * or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors.
274 *
275 * (*) MSI_VALUE is a constant defined in stm32u5xx_hal.h file (default value
276 * 4 MHz) but the real value may vary depending on the variations
277 * in voltage and temperature.
278 *
279 * (**) HSI_VALUE is a constant defined in stm32u5xx_hal.h file (default value
280 * 16 MHz) but the real value may vary depending on the variations
281 * in voltage and temperature.
282 *
283 * (***) HSE_VALUE is a constant defined in stm32u5xx_hal.h file (default value
284 * 8 MHz), user has to ensure that HSE_VALUE is same as the real
285 * frequency of the crystal used. Otherwise, this function may
286 * have wrong result.
287 *
288 * - The result of this function could be not correct when using fractional
289 * value for HSE crystal.
290 *
291 * @param None
292 * @retval None
293 */
SystemCoreClockUpdate(void)294 void SystemCoreClockUpdate(void)
295 {
296 uint32_t pllr, pllsource, pllm , tmp, pllfracen, msirange;
297 float_t fracn1, pllvco;
298
299 /* Get MSI Range frequency--------------------------------------------------*/
300 if(READ_BIT(RCC->ICSCR1, RCC_ICSCR1_MSIRGSEL) == 0U)
301 {
302 /* MSISRANGE from RCC_CSR applies */
303 msirange = (RCC->CSR & RCC_CSR_MSISSRANGE) >> RCC_CSR_MSISSRANGE_Pos;
304 }
305 else
306 {
307 /* MSIRANGE from RCC_CR applies */
308 msirange = (RCC->ICSCR1 & RCC_ICSCR1_MSISRANGE) >> RCC_ICSCR1_MSISRANGE_Pos;
309 }
310
311 /*MSI frequency range in HZ*/
312 msirange = MSIRangeTable[msirange];
313
314 /* Get SYSCLK source -------------------------------------------------------*/
315 switch (RCC->CFGR1 & RCC_CFGR1_SWS)
316 {
317 case 0x00: /* MSI used as system clock source */
318 SystemCoreClock = msirange;
319 break;
320
321 case 0x04: /* HSI used as system clock source */
322 SystemCoreClock = HSI_VALUE;
323 break;
324
325 case 0x08: /* HSE used as system clock source */
326 SystemCoreClock = HSE_VALUE;
327 break;
328
329 case 0x0C: /* PLL used as system clock source */
330 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
331 SYSCLK = PLL_VCO / PLLR
332 */
333 pllsource = (RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC);
334 pllm = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1M)>> RCC_PLL1CFGR_PLL1M_Pos) + 1U;
335 pllfracen = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1FRACEN)>>RCC_PLL1CFGR_PLL1FRACEN_Pos);
336 fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN)>> RCC_PLL1FRACR_PLL1FRACN_Pos));
337
338 switch (pllsource)
339 {
340 case 0x00: /* No clock sent to PLL*/
341 pllvco = (float_t)0U;
342 break;
343
344 case 0x02: /* HSI used as PLL clock source */
345 pllvco = ((float_t)HSI_VALUE / (float_t)pllm);
346 break;
347
348 case 0x03: /* HSE used as PLL clock source */
349 pllvco = ((float_t)HSE_VALUE / (float_t)pllm);
350 break;
351
352 default: /* MSI used as PLL clock source */
353 pllvco = ((float_t)msirange / (float_t)pllm);
354 break;
355 }
356
357 pllvco = pllvco * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + (fracn1/(float_t)0x2000) + (float_t)1U);
358 pllr = (((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1R) >> RCC_PLL1DIVR_PLL1R_Pos) + 1U );
359 SystemCoreClock = (uint32_t)((uint32_t)pllvco/pllr);
360 break;
361
362 default:
363 SystemCoreClock = msirange;
364 break;
365 }
366 /* Compute HCLK clock frequency --------------------------------------------*/
367 /* Get HCLK prescaler */
368 tmp = AHBPrescTable[((RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos)];
369 /* HCLK clock frequency */
370 SystemCoreClock >>= tmp;
371 }
372
373 /**
374 * @brief Secure Non-Secure-Callable function to return the current
375 * SystemCoreClock value after SystemCoreClock update.
376 * The SystemCoreClock variable contains the core clock (HCLK), it can
377 * be used by the user application to setup the SysTick timer or configure
378 * other parameters.
379 * @retval SystemCoreClock value (HCLK)
380 */
SECURE_SystemCoreClockUpdate(void)381 CMSE_NS_ENTRY uint32_t SECURE_SystemCoreClockUpdate(void)
382 {
383 SystemCoreClockUpdate();
384
385 return SystemCoreClock;
386 }
387
388 /**
389 * @}
390 */
391
392 /**
393 * @}
394 */
395
396 /**
397 * @}
398 */
399
400