1 /**
2 ******************************************************************************
3 * @file system_stm32h7xx.c
4 * @author MCD Application Team
5 * @brief CMSIS Cortex-Mx Device Peripheral Access Layer System Source File.
6 *
7 * This file provides two functions and one global variable to be called from
8 * user application:
9 * - SystemInit(): This function is called at startup just after reset and
10 * before branch to main program. This call is made inside
11 * the "startup_stm32h7xx.s" file.
12 *
13 * - SystemCoreClock variable: Contains the core clock, it can be used
14 * by the user application to setup the SysTick
15 * timer or configure other parameters.
16 *
17 * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
18 * be called whenever the core clock is changed
19 * during program execution.
20 *
21 *
22 ******************************************************************************
23 * @attention
24 *
25 * <h2><center>© Copyright (c) 2017 STMicroelectronics.
26 * All rights reserved.</center></h2>
27 *
28 * This software component is licensed by ST under BSD 3-Clause license,
29 * the "License"; You may not use this file except in compliance with the
30 * License. You may obtain a copy of the License at:
31 * opensource.org/licenses/BSD-3-Clause
32 *
33 ******************************************************************************
34 */
35
36 /** @addtogroup CMSIS
37 * @{
38 */
39
40 /** @addtogroup stm32h7xx_system
41 * @{
42 */
43
44 /** @addtogroup STM32H7xx_System_Private_Includes
45 * @{
46 */
47
48 #include "stm32h7xx.h"
49 #include <math.h>
50 #if !defined (HSE_VALUE)
51 #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
52 #endif /* HSE_VALUE */
53
54 #if !defined (CSI_VALUE)
55 #define CSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/
56 #endif /* CSI_VALUE */
57
58 #if !defined (HSI_VALUE)
59 #define HSI_VALUE ((uint32_t)64000000) /*!< Value of the Internal oscillator in Hz*/
60 #endif /* HSI_VALUE */
61
62
63 /**
64 * @}
65 */
66
67 /** @addtogroup STM32H7xx_System_Private_TypesDefinitions
68 * @{
69 */
70
71 /**
72 * @}
73 */
74
75 /** @addtogroup STM32H7xx_System_Private_Defines
76 * @{
77 */
78
79 /************************* Miscellaneous Configuration ************************/
80 /*!< Uncomment the following line if you need to use initialized data in D2 domain SRAM (AHB SRAM) */
81 /* #define DATA_IN_D2_SRAM */
82
83 /*!< Uncomment the following line if you need to relocate your vector Table in
84 Internal SRAM. */
85 /* #define VECT_TAB_SRAM */
86 #define VECT_TAB_OFFSET 0x00000000UL /*!< Vector Table base offset field.
87 This value must be a multiple of 0x200. */
88 /******************************************************************************/
89
90 /**
91 * @}
92 */
93
94 /** @addtogroup STM32H7xx_System_Private_Macros
95 * @{
96 */
97
98 /**
99 * @}
100 */
101
102 /** @addtogroup STM32H7xx_System_Private_Variables
103 * @{
104 */
105 /* This variable is updated in three ways:
106 1) by calling CMSIS function SystemCoreClockUpdate()
107 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
108 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
109 Note: If you use this function to configure the system clock; then there
110 is no need to call the 2 first functions listed above, since SystemCoreClock
111 variable is updated automatically.
112 */
113 uint32_t SystemCoreClock = 64000000;
114 uint32_t SystemD2Clock = 64000000;
115 const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
116
117 /**
118 * @}
119 */
120
121 /** @addtogroup STM32H7xx_System_Private_FunctionPrototypes
122 * @{
123 */
124
125 /**
126 * @}
127 */
128
129 /** @addtogroup STM32H7xx_System_Private_Functions
130 * @{
131 */
132
133 /**
134 * @brief Setup the microcontroller system
135 * Initialize the FPU setting and vector table location
136 * configuration.
137 * @param None
138 * @retval None
139 */
SystemInit(void)140 void SystemInit (void)
141 {
142 #if defined (DATA_IN_D2_SRAM)
143 __IO uint32_t tmpreg;
144 #endif /* DATA_IN_D2_SRAM */
145
146 /* FPU settings ------------------------------------------------------------*/
147 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
148 SCB->CPACR |= ((3UL << (10*2))|(3UL << (11*2))); /* set CP10 and CP11 Full Access */
149 #endif
150 /* Reset the RCC clock configuration to the default reset state ------------*/
151
152 /* Increasing the CPU frequency */
153 if(FLASH_LATENCY_DEFAULT > (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY)))
154 {
155 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
156 MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, (uint32_t)(FLASH_LATENCY_DEFAULT));
157 }
158
159 /* Set HSION bit */
160 RCC->CR |= RCC_CR_HSION;
161
162 /* Reset CFGR register */
163 RCC->CFGR = 0x00000000;
164
165 /* Reset HSEON, HSECSSON, CSION, HSI48ON, CSIKERON, PLL1ON, PLL2ON and PLL3ON bits */
166 RCC->CR &= 0xEAF6ED7FU;
167
168 /* Decreasing the number of wait states because of lower CPU frequency */
169 if(FLASH_LATENCY_DEFAULT < (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY)))
170 {
171 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
172 MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, (uint32_t)(FLASH_LATENCY_DEFAULT));
173 }
174
175 #if defined(D3_SRAM_BASE)
176 /* Reset D1CFGR register */
177 RCC->D1CFGR = 0x00000000;
178
179 /* Reset D2CFGR register */
180 RCC->D2CFGR = 0x00000000;
181
182 /* Reset D3CFGR register */
183 RCC->D3CFGR = 0x00000000;
184 #else
185 /* Reset CDCFGR1 register */
186 RCC->CDCFGR1 = 0x00000000;
187
188 /* Reset CDCFGR2 register */
189 RCC->CDCFGR2 = 0x00000000;
190
191 /* Reset SRDCFGR register */
192 RCC->SRDCFGR = 0x00000000;
193 #endif
194 /* Reset PLLCKSELR register */
195 RCC->PLLCKSELR = 0x02020200;
196
197 /* Reset PLLCFGR register */
198 RCC->PLLCFGR = 0x01FF0000;
199 /* Reset PLL1DIVR register */
200 RCC->PLL1DIVR = 0x01010280;
201 /* Reset PLL1FRACR register */
202 RCC->PLL1FRACR = 0x00000000;
203
204 /* Reset PLL2DIVR register */
205 RCC->PLL2DIVR = 0x01010280;
206
207 /* Reset PLL2FRACR register */
208
209 RCC->PLL2FRACR = 0x00000000;
210 /* Reset PLL3DIVR register */
211 RCC->PLL3DIVR = 0x01010280;
212
213 /* Reset PLL3FRACR register */
214 RCC->PLL3FRACR = 0x00000000;
215
216 /* Reset HSEBYP bit */
217 RCC->CR &= 0xFFFBFFFFU;
218
219 /* Disable all interrupts */
220 RCC->CIER = 0x00000000;
221
222 #if (STM32H7_DEV_ID == 0x450UL)
223 /* dual core CM7 or single core line */
224 if((DBGMCU->IDCODE & 0xFFFF0000U) < 0x20000000U)
225 {
226 /* if stm32h7 revY*/
227 /* Change the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */
228 *((__IO uint32_t*)0x51008108) = 0x000000001U;
229 }
230 #endif
231
232 #if defined (DATA_IN_D2_SRAM)
233 /* in case of initialized data in D2 SRAM (AHB SRAM) , enable the D2 SRAM clock (AHB SRAM clock) */
234 #if defined(RCC_AHB2ENR_D2SRAM3EN)
235 RCC->AHB2ENR |= (RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN | RCC_AHB2ENR_D2SRAM3EN);
236 #elif defined(RCC_AHB2ENR_D2SRAM2EN)
237 RCC->AHB2ENR |= (RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN);
238 #else
239 RCC->AHB2ENR |= (RCC_AHB2ENR_AHBSRAM1EN | RCC_AHB2ENR_AHBSRAM2EN);
240 #endif /* RCC_AHB2ENR_D2SRAM3EN */
241
242 tmpreg = RCC->AHB2ENR;
243 (void) tmpreg;
244 #endif /* DATA_IN_D2_SRAM */
245
246 #if defined(DUAL_CORE) && defined(CORE_CM4)
247 /* Configure the Vector Table location add offset address for cortex-M4 ------------------*/
248 #ifdef VECT_TAB_SRAM
249 SCB->VTOR = D2_AXISRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
250 #else
251 SCB->VTOR = FLASH_BANK2_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
252 #endif /* VECT_TAB_SRAM */
253
254 #else
255
256 /*
257 * Disable the FMC bank1 (enabled after reset).
258 * This, prevents CPU speculation access on this bank which blocks the use of FMC during
259 * 24us. During this time the others FMC master (such as LTDC) cannot use it!
260 */
261 FMC_Bank1_R->BTCR[0] = 0x000030D2;
262
263 /* Configure the Vector Table location add offset address for cortex-M7 ------------------*/
264 #ifdef VECT_TAB_SRAM
265 SCB->VTOR = D1_AXISRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal AXI-RAM */
266 #else
267 SCB->VTOR = FLASH_BANK1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
268 #endif
269
270 #endif /*DUAL_CORE && CORE_CM4*/
271
272 }
273
274 /**
275 * @brief Update SystemCoreClock variable according to Clock Register Values.
276 * The SystemCoreClock variable contains the core clock , it can
277 * be used by the user application to setup the SysTick timer or configure
278 * other parameters.
279 *
280 * @note Each time the core clock changes, this function must be called
281 * to update SystemCoreClock variable value. Otherwise, any configuration
282 * based on this variable will be incorrect.
283 *
284 * @note - The system frequency computed by this function is not the real
285 * frequency in the chip. It is calculated based on the predefined
286 * constant and the selected clock source:
287 *
288 * - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*)
289 * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
290 * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
291 * - If SYSCLK source is PLL, SystemCoreClock will contain the CSI_VALUE(*),
292 * HSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
293 *
294 * (*) CSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value
295 * 4 MHz) but the real value may vary depending on the variations
296 * in voltage and temperature.
297 * (**) HSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value
298 * 64 MHz) but the real value may vary depending on the variations
299 * in voltage and temperature.
300 *
301 * (***)HSE_VALUE is a constant defined in stm32h7xx_hal.h file (default value
302 * 25 MHz), user has to ensure that HSE_VALUE is same as the real
303 * frequency of the crystal used. Otherwise, this function may
304 * have wrong result.
305 *
306 * - The result of this function could be not correct when using fractional
307 * value for HSE crystal.
308 * @param None
309 * @retval None
310 */
SystemCoreClockUpdate(void)311 void SystemCoreClockUpdate (void)
312 {
313 uint32_t pllp, pllsource, pllm, pllfracen, hsivalue, tmp;
314 uint32_t common_system_clock;
315 float_t fracn1, pllvco;
316
317
318 /* Get SYSCLK source -------------------------------------------------------*/
319
320 switch (RCC->CFGR & RCC_CFGR_SWS)
321 {
322 case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */
323 common_system_clock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3));
324 break;
325
326 case RCC_CFGR_SWS_CSI: /* CSI used as system clock source */
327 common_system_clock = CSI_VALUE;
328 break;
329
330 case RCC_CFGR_SWS_HSE: /* HSE used as system clock source */
331 common_system_clock = HSE_VALUE;
332 break;
333
334 case RCC_CFGR_SWS_PLL1: /* PLL1 used as system clock source */
335
336 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
337 SYSCLK = PLL_VCO / PLLR
338 */
339 pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
340 pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1)>> 4) ;
341 pllfracen = ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN)>>RCC_PLLCFGR_PLL1FRACEN_Pos);
342 fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN1)>> 3));
343
344 if (pllm != 0U)
345 {
346 switch (pllsource)
347 {
348 case RCC_PLLCKSELR_PLLSRC_HSI: /* HSI used as PLL clock source */
349
350 hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ;
351 pllvco = ( (float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
352
353 break;
354
355 case RCC_PLLCKSELR_PLLSRC_CSI: /* CSI used as PLL clock source */
356 pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
357 break;
358
359 case RCC_PLLCKSELR_PLLSRC_HSE: /* HSE used as PLL clock source */
360 pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
361 break;
362
363 default:
364 pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
365 break;
366 }
367 pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_P1) >>9) + 1U ) ;
368 common_system_clock = (uint32_t)(float_t)(pllvco/(float_t)pllp);
369 }
370 else
371 {
372 common_system_clock = 0U;
373 }
374 break;
375
376 default:
377 common_system_clock = CSI_VALUE;
378 break;
379 }
380
381 /* Compute SystemClock frequency --------------------------------------------------*/
382 #if defined (RCC_D1CFGR_D1CPRE)
383 tmp = D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_D1CPRE)>> RCC_D1CFGR_D1CPRE_Pos];
384
385 /* common_system_clock frequency : CM7 CPU frequency */
386 common_system_clock >>= tmp;
387
388 /* SystemD2Clock frequency : CM4 CPU, AXI and AHBs Clock frequency */
389 SystemD2Clock = (common_system_clock >> ((D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_HPRE)>> RCC_D1CFGR_HPRE_Pos]) & 0x1FU));
390
391 #else
392 tmp = D1CorePrescTable[(RCC->CDCFGR1 & RCC_CDCFGR1_CDCPRE)>> RCC_CDCFGR1_CDCPRE_Pos];
393
394 /* common_system_clock frequency : CM7 CPU frequency */
395 common_system_clock >>= tmp;
396
397 /* SystemD2Clock frequency : AXI and AHBs Clock frequency */
398 SystemD2Clock = (common_system_clock >> ((D1CorePrescTable[(RCC->CDCFGR1 & RCC_CDCFGR1_HPRE)>> RCC_CDCFGR1_HPRE_Pos]) & 0x1FU));
399
400 #endif
401
402 #if defined(DUAL_CORE) && defined(CORE_CM4)
403 SystemCoreClock = SystemD2Clock;
404 #else
405 SystemCoreClock = common_system_clock;
406 #endif /* DUAL_CORE && CORE_CM4 */
407 }
408
409
410 /**
411 * @}
412 */
413
414 /**
415 * @}
416 */
417
418 /**
419 * @}
420 */
421 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
422