system_stm32h5xx.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  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. /** @addtogroup CMSIS
  100. * @{
  101. */
  102. /** @addtogroup STM32H5xx_system
  103. * @{
  104. */
  105. /** @addtogroup STM32H5xx_System_Private_Includes
  106. * @{
  107. */
  108. #include "stm32h5xx.h"
  109. /**
  110. * @}
  111. */
  112. /** @addtogroup STM32H5xx_System_Private_TypesDefinitions
  113. * @{
  114. */
  115. /**
  116. * @}
  117. */
  118. /** @addtogroup STM32H5xx_System_Private_Defines
  119. * @{
  120. */
  121. #if !defined (HSE_VALUE)
  122. #define HSE_VALUE (25000000UL) /*!< Value of the External oscillator in Hz */
  123. #endif /* HSE_VALUE */
  124. #if !defined (CSI_VALUE)
  125. #define CSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/
  126. #endif /* CSI_VALUE */
  127. #if !defined (HSI_VALUE)
  128. #define HSI_VALUE (64000000UL) /*!< Value of the Internal oscillator in Hz */
  129. #endif /* HSI_VALUE */
  130. /************************* Miscellaneous Configuration ************************/
  131. /*!< Uncomment the following line if you need to relocate your vector Table in
  132. Internal SRAM. */
  133. /* #define VECT_TAB_SRAM */
  134. #define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field.
  135. This value must be a multiple of 0x200. */
  136. /******************************************************************************/
  137. /**
  138. * @}
  139. */
  140. /** @addtogroup STM32H5xx_System_Private_Macros
  141. * @{
  142. */
  143. /**
  144. * @}
  145. */
  146. /** @addtogroup STM32H5xx_System_Private_Variables
  147. * @{
  148. */
  149. /* The SystemCoreClock variable is updated in three ways:
  150. 1) by calling CMSIS function SystemCoreClockUpdate()
  151. 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
  152. 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
  153. Note: If you use this function to configure the system clock; then there
  154. is no need to call the 2 first functions listed above, since SystemCoreClock
  155. variable is updated automatically.
  156. */
  157. uint32_t SystemCoreClock = 64000000U;
  158. const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
  159. const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
  160. /**
  161. * @}
  162. */
  163. /** @addtogroup STM32H5xx_System_Private_FunctionPrototypes
  164. * @{
  165. */
  166. /**
  167. * @}
  168. */
  169. /** @addtogroup STM32H5xx_System_Private_Functions
  170. * @{
  171. */
  172. /**
  173. * @brief Setup the microcontroller system.
  174. * @param None
  175. * @retval None
  176. */
  177. void SystemInit(void)
  178. {
  179. uint32_t reg_opsr;
  180. /* FPU settings ------------------------------------------------------------*/
  181. #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  182. SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */
  183. #endif
  184. /* Reset the RCC clock configuration to the default reset state ------------*/
  185. /* Set HSION bit */
  186. RCC->CR = RCC_CR_HSION;
  187. /* Reset CFGR register */
  188. RCC->CFGR1 = 0U;
  189. RCC->CFGR2 = 0U;
  190. /* Reset HSEON, HSECSSON, HSEBYP, HSEEXT, HSIDIV, HSIKERON, CSION, CSIKERON, HSI48 and PLLxON bits */
  191. #if defined(RCC_CR_PLL3ON)
  192. RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_HSECSSON | RCC_CR_HSEBYP | RCC_CR_HSEEXT | RCC_CR_HSIDIV | RCC_CR_HSIKERON | \
  193. RCC_CR_CSION | RCC_CR_CSIKERON |RCC_CR_HSI48ON | RCC_CR_PLL1ON | RCC_CR_PLL2ON | RCC_CR_PLL3ON);
  194. #else
  195. RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_HSECSSON | RCC_CR_HSEBYP | RCC_CR_HSEEXT | RCC_CR_HSIDIV | RCC_CR_HSIKERON | \
  196. RCC_CR_CSION | RCC_CR_CSIKERON |RCC_CR_HSI48ON | RCC_CR_PLL1ON | RCC_CR_PLL2ON);
  197. #endif
  198. /* Reset PLLxCFGR register */
  199. RCC->PLL1CFGR = 0U;
  200. RCC->PLL2CFGR = 0U;
  201. #if defined(RCC_CR_PLL3ON)
  202. RCC->PLL3CFGR = 0U;
  203. #endif /* RCC_CR_PLL3ON */
  204. /* Reset PLL1DIVR register */
  205. RCC->PLL1DIVR = 0x01010280U;
  206. /* Reset PLL1FRACR register */
  207. RCC->PLL1FRACR = 0x00000000U;
  208. /* Reset PLL2DIVR register */
  209. RCC->PLL2DIVR = 0x01010280U;
  210. /* Reset PLL2FRACR register */
  211. RCC->PLL2FRACR = 0x00000000U;
  212. #if defined(RCC_CR_PLL3ON)
  213. /* Reset PLL3DIVR register */
  214. RCC->PLL3DIVR = 0x01010280U;
  215. /* Reset PLL3FRACR register */
  216. RCC->PLL3FRACR = 0x00000000U;
  217. #endif /* RCC_CR_PLL3ON */
  218. /* Reset HSEBYP bit */
  219. RCC->CR &= ~(RCC_CR_HSEBYP);
  220. /* Disable all interrupts */
  221. RCC->CIER = 0U;
  222. /* Configure the Vector Table location add offset address ------------------*/
  223. #ifdef VECT_TAB_SRAM
  224. SCB->VTOR = SRAM1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
  225. #else
  226. SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
  227. #endif /* VECT_TAB_SRAM */
  228. /* Check OPSR register to verify if there is an ongoing swap or option bytes update interrupted by a reset */
  229. reg_opsr = FLASH->OPSR & FLASH_OPSR_CODE_OP;
  230. if ((reg_opsr == FLASH_OPSR_CODE_OP) || (reg_opsr == (FLASH_OPSR_CODE_OP_2 | FLASH_OPSR_CODE_OP_1)))
  231. {
  232. /* Check FLASH Option Control Register access */
  233. if ((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != 0U)
  234. {
  235. /* Authorizes the Option Byte registers programming */
  236. FLASH->OPTKEYR = 0x08192A3BU;
  237. FLASH->OPTKEYR = 0x4C5D6E7FU;
  238. }
  239. /* Launch the option bytes change operation */
  240. FLASH->OPTCR |= FLASH_OPTCR_OPTSTART;
  241. /* Lock the FLASH Option Control Register access */
  242. FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK;
  243. }
  244. }
  245. /**
  246. * @brief Update SystemCoreClock variable according to Clock Register Values.
  247. * The SystemCoreClock variable contains the core clock (HCLK), it can
  248. * be used by the user application to setup the SysTick timer or configure
  249. * other parameters.
  250. *
  251. * @note Each time the core clock (HCLK) changes, this function must be called
  252. * to update SystemCoreClock variable value. Otherwise, any configuration
  253. * based on this variable will be incorrect.
  254. *
  255. * @note - The system frequency computed by this function is not the real
  256. * frequency in the chip. It is calculated based on the predefined
  257. * constant and the selected clock source:
  258. *
  259. * - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*)
  260. *
  261. * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
  262. *
  263. * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
  264. *
  265. * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
  266. * or HSI_VALUE(**) or CSI_VALUE(*) multiplied/divided by the PLL factors.
  267. *
  268. * (*) CSI_VALUE is a constant defined in stm32h5xx_hal.h file (default value
  269. * 4 MHz) but the real value may vary depending on the variations
  270. * in voltage and temperature.
  271. *
  272. * (**) HSI_VALUE is a constant defined in stm32h5xx_hal.h file (default value
  273. * 64 MHz) but the real value may vary depending on the variations
  274. * in voltage and temperature.
  275. *
  276. * (***) HSE_VALUE is a constant defined in stm32h5xx_hal.h file (default value
  277. * 25 MHz), user has to ensure that HSE_VALUE is same as the real
  278. * frequency of the crystal used. Otherwise, this function may
  279. * have wrong result.
  280. *
  281. * - The result of this function could be not correct when using fractional
  282. * value for HSE crystal.
  283. *
  284. * @param None
  285. * @retval None
  286. */
  287. void SystemCoreClockUpdate(void)
  288. {
  289. uint32_t pllp, pllsource, pllm, pllfracen, hsivalue, tmp;
  290. float_t fracn1, pllvco;
  291. /* Get SYSCLK source -------------------------------------------------------*/
  292. switch (RCC->CFGR1 & RCC_CFGR1_SWS)
  293. {
  294. case 0x00UL: /* HSI used as system clock source */
  295. SystemCoreClock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3));
  296. break;
  297. case 0x08UL: /* CSI used as system clock source */
  298. SystemCoreClock = CSI_VALUE;
  299. break;
  300. case 0x10UL: /* HSE used as system clock source */
  301. SystemCoreClock = HSE_VALUE;
  302. break;
  303. case 0x18UL: /* PLL1 used as system clock source */
  304. /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
  305. SYSCLK = PLL_VCO / PLLR
  306. */
  307. pllsource = (RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC);
  308. pllm = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1M)>> RCC_PLL1CFGR_PLL1M_Pos);
  309. pllfracen = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1FRACEN)>>RCC_PLL1CFGR_PLL1FRACEN_Pos);
  310. fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN)>> RCC_PLL1FRACR_PLL1FRACN_Pos));
  311. switch (pllsource)
  312. {
  313. case 0x01UL: /* HSI used as PLL clock source */
  314. hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ;
  315. pllvco = ((float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
  316. (fracn1/(float_t)0x2000) +(float_t)1 );
  317. break;
  318. case 0x02UL: /* CSI used as PLL clock source */
  319. pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
  320. (fracn1/(float_t)0x2000) +(float_t)1 );
  321. break;
  322. case 0x03UL: /* HSE used as PLL clock source */
  323. pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
  324. (fracn1/(float_t)0x2000) +(float_t)1 );
  325. break;
  326. default: /* No clock sent to PLL*/
  327. pllvco = (float_t) 0U;
  328. break;
  329. }
  330. pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1P) >>RCC_PLL1DIVR_PLL1P_Pos) + 1U ) ;
  331. SystemCoreClock = (uint32_t)(float_t)(pllvco/(float_t)pllp);
  332. break;
  333. default:
  334. SystemCoreClock = HSI_VALUE;
  335. break;
  336. }
  337. /* Compute HCLK clock frequency --------------------------------------------*/
  338. /* Get HCLK prescaler */
  339. tmp = AHBPrescTable[((RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos)];
  340. /* HCLK clock frequency */
  341. SystemCoreClock >>= tmp;
  342. }
  343. /**
  344. * @}
  345. */
  346. /**
  347. * @}
  348. */
  349. /**
  350. * @}
  351. */