You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

366 lines
12 KiB

  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 (HCLK), 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>&copy; 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. /** @addtogroup CMSIS
  36. * @{
  37. */
  38. /** @addtogroup stm32h7xx_system
  39. * @{
  40. */
  41. /** @addtogroup STM32H7xx_System_Private_Includes
  42. * @{
  43. */
  44. #include "stm32h7xx.h"
  45. #include <math.h>
  46. #if !defined (HSE_VALUE)
  47. #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
  48. #endif /* HSE_VALUE */
  49. #if !defined (CSI_VALUE)
  50. #define CSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/
  51. #endif /* CSI_VALUE */
  52. #if !defined (HSI_VALUE)
  53. #define HSI_VALUE ((uint32_t)64000000) /*!< Value of the Internal oscillator in Hz*/
  54. #endif /* HSI_VALUE */
  55. /**
  56. * @}
  57. */
  58. /** @addtogroup STM32H7xx_System_Private_TypesDefinitions
  59. * @{
  60. */
  61. /**
  62. * @}
  63. */
  64. /** @addtogroup STM32H7xx_System_Private_Defines
  65. * @{
  66. */
  67. /************************* Miscellaneous Configuration ************************/
  68. /*!< Uncomment the following line if you need to use initialized data in D2 domain SRAM (AHB SRAM) */
  69. /* #define DATA_IN_D2_SRAM */
  70. /*!< Uncomment the following line if you need to relocate your vector Table in
  71. Internal SRAM. */
  72. /* #define VECT_TAB_SRAM */
  73. #define VECT_TAB_OFFSET 0x00000000UL /*!< Vector Table base offset field.
  74. This value must be a multiple of 0x200. */
  75. /******************************************************************************/
  76. /**
  77. * @}
  78. */
  79. /** @addtogroup STM32H7xx_System_Private_Macros
  80. * @{
  81. */
  82. /**
  83. * @}
  84. */
  85. /** @addtogroup STM32H7xx_System_Private_Variables
  86. * @{
  87. */
  88. /* This variable is updated in three ways:
  89. 1) by calling CMSIS function SystemCoreClockUpdate()
  90. 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
  91. 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
  92. Note: If you use this function to configure the system clock; then there
  93. is no need to call the 2 first functions listed above, since SystemCoreClock
  94. variable is updated automatically.
  95. */
  96. uint32_t SystemCoreClock = 64000000;
  97. uint32_t SystemD2Clock = 64000000;
  98. const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
  99. /**
  100. * @}
  101. */
  102. /** @addtogroup STM32H7xx_System_Private_FunctionPrototypes
  103. * @{
  104. */
  105. /**
  106. * @}
  107. */
  108. /** @addtogroup STM32H7xx_System_Private_Functions
  109. * @{
  110. */
  111. /**
  112. * @brief Setup the microcontroller system
  113. * Initialize the FPU setting and vector table location
  114. * configuration.
  115. * @param None
  116. * @retval None
  117. */
  118. void SystemInit (void)
  119. {
  120. #if defined (DATA_IN_D2_SRAM)
  121. __IO uint32_t tmpreg;
  122. #endif /* DATA_IN_D2_SRAM */
  123. /* FPU settings ------------------------------------------------------------*/
  124. #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  125. SCB->CPACR |= ((3UL << (10*2))|(3UL << (11*2))); /* set CP10 and CP11 Full Access */
  126. #endif
  127. /* Reset the RCC clock configuration to the default reset state ------------*/
  128. /* Set HSION bit */
  129. RCC->CR |= RCC_CR_HSION;
  130. /* Reset CFGR register */
  131. RCC->CFGR = 0x00000000;
  132. /* Reset HSEON, CSSON , CSION,RC48ON, CSIKERON PLL1ON, PLL2ON and PLL3ON bits */
  133. RCC->CR &= 0xEAF6ED7FU;
  134. /* Reset D1CFGR register */
  135. RCC->D1CFGR = 0x00000000;
  136. /* Reset D2CFGR register */
  137. RCC->D2CFGR = 0x00000000;
  138. /* Reset D3CFGR register */
  139. RCC->D3CFGR = 0x00000000;
  140. /* Reset PLLCKSELR register */
  141. RCC->PLLCKSELR = 0x00000000;
  142. /* Reset PLLCFGR register */
  143. RCC->PLLCFGR = 0x00000000;
  144. /* Reset PLL1DIVR register */
  145. RCC->PLL1DIVR = 0x00000000;
  146. /* Reset PLL1FRACR register */
  147. RCC->PLL1FRACR = 0x00000000;
  148. /* Reset PLL2DIVR register */
  149. RCC->PLL2DIVR = 0x00000000;
  150. /* Reset PLL2FRACR register */
  151. RCC->PLL2FRACR = 0x00000000;
  152. /* Reset PLL3DIVR register */
  153. RCC->PLL3DIVR = 0x00000000;
  154. /* Reset PLL3FRACR register */
  155. RCC->PLL3FRACR = 0x00000000;
  156. /* Reset HSEBYP bit */
  157. RCC->CR &= 0xFFFBFFFFU;
  158. /* Disable all interrupts */
  159. RCC->CIER = 0x00000000;
  160. #if defined (DATA_IN_D2_SRAM)
  161. /* in case of initialized data in D2 SRAM (AHB SRAM) , enable the D2 SRAM clock ((AHB SRAM clock) */
  162. #if defined(RCC_AHB2ENR_D2SRAM1EN)
  163. RCC->AHB2ENR |= (RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN | RCC_AHB2ENR_D2SRAM3EN);
  164. #else
  165. RCC->AHB2ENR |= (RCC_AHB2ENR_AHBSRAM1EN | RCC_AHB2ENR_AHBSRAM2EN);
  166. #endif /* RCC_AHB2ENR_D2SRAM1EN */
  167. tmpreg = RCC->AHB2ENR;
  168. (void) tmpreg;
  169. #endif /* DATA_IN_D2_SRAM */
  170. #if defined(DUAL_CORE) && defined(CORE_CM4)
  171. /* Configure the Vector Table location add offset address for cortex-M4 ------------------*/
  172. #ifdef VECT_TAB_SRAM
  173. SCB->VTOR = D2_AHBSRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
  174. #else
  175. SCB->VTOR = FLASH_BANK2_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
  176. #endif /* VECT_TAB_SRAM */
  177. #else
  178. /* dual core CM7 or single core line */
  179. if((DBGMCU->IDCODE & 0xFFFF0000U) < 0x20000000U)
  180. {
  181. /* if stm32h7 revY*/
  182. /* Change the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */
  183. *((__IO uint32_t*)0x51008108) = 0x000000001U;
  184. }
  185. /* Configure the Vector Table location add offset address for cortex-M7 ------------------*/
  186. #ifdef VECT_TAB_SRAM
  187. SCB->VTOR = D1_AXISRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal D1 AXI-RAM */
  188. #else
  189. SCB->VTOR = FLASH_BANK1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
  190. #endif
  191. #endif /*DUAL_CORE && CORE_CM4*/
  192. }
  193. /**
  194. * @brief Update SystemCoreClock variable according to Clock Register Values.
  195. * The SystemCoreClock variable contains the core clock , it can
  196. * be used by the user application to setup the SysTick timer or configure
  197. * other parameters.
  198. *
  199. * @note Each time the core clock changes, this function must be called
  200. * to update SystemCoreClock variable value. Otherwise, any configuration
  201. * based on this variable will be incorrect.
  202. *
  203. * @note - The system frequency computed by this function is not the real
  204. * frequency in the chip. It is calculated based on the predefined
  205. * constant and the selected clock source:
  206. *
  207. * - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*)
  208. * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
  209. * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
  210. * - If SYSCLK source is PLL, SystemCoreClock will contain the CSI_VALUE(*),
  211. * HSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
  212. *
  213. * (*) CSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value
  214. * 4 MHz) but the real value may vary depending on the variations
  215. * in voltage and temperature.
  216. * (**) HSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value
  217. * 64 MHz) but the real value may vary depending on the variations
  218. * in voltage and temperature.
  219. *
  220. * (***)HSE_VALUE is a constant defined in stm32h7xx_hal.h file (default value
  221. * 25 MHz), user has to ensure that HSE_VALUE is same as the real
  222. * frequency of the crystal used. Otherwise, this function may
  223. * have wrong result.
  224. *
  225. * - The result of this function could be not correct when using fractional
  226. * value for HSE crystal.
  227. * @param None
  228. * @retval None
  229. */
  230. void SystemCoreClockUpdate (void)
  231. {
  232. uint32_t pllp, pllsource, pllm, pllfracen, hsivalue, tmp;
  233. float_t fracn1, pllvco;
  234. /* Get SYSCLK source -------------------------------------------------------*/
  235. switch (RCC->CFGR & RCC_CFGR_SWS)
  236. {
  237. case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */
  238. SystemCoreClock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3));
  239. break;
  240. case RCC_CFGR_SWS_CSI: /* CSI used as system clock source */
  241. SystemCoreClock = CSI_VALUE;
  242. break;
  243. case RCC_CFGR_SWS_HSE: /* HSE used as system clock source */
  244. SystemCoreClock = HSE_VALUE;
  245. break;
  246. case RCC_CFGR_SWS_PLL1: /* PLL1 used as system clock source */
  247. /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
  248. SYSCLK = PLL_VCO / PLLR
  249. */
  250. pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
  251. pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1)>> 4) ;
  252. pllfracen = ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN)>>RCC_PLLCFGR_PLL1FRACEN_Pos);
  253. fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN1)>> 3));
  254. if (pllm != 0U)
  255. {
  256. switch (pllsource)
  257. {
  258. case RCC_PLLCKSELR_PLLSRC_HSI: /* HSI used as PLL clock source */
  259. hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ;
  260. pllvco = ( (float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
  261. break;
  262. case RCC_PLLCKSELR_PLLSRC_CSI: /* CSI used as PLL clock source */
  263. pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
  264. break;
  265. case RCC_PLLCKSELR_PLLSRC_HSE: /* HSE used as PLL clock source */
  266. pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
  267. break;
  268. default:
  269. pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
  270. break;
  271. }
  272. pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_P1) >>9) + 1U ) ;
  273. SystemCoreClock = (uint32_t)(float_t)(pllvco/(float_t)pllp);
  274. }
  275. else
  276. {
  277. SystemCoreClock = 0U;
  278. }
  279. break;
  280. default:
  281. SystemCoreClock = CSI_VALUE;
  282. break;
  283. }
  284. /* Compute SystemClock frequency --------------------------------------------------*/
  285. tmp = D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_D1CPRE)>> RCC_D1CFGR_D1CPRE_Pos];
  286. /* SystemCoreClock frequency : CM7 CPU frequency */
  287. SystemCoreClock >>= tmp;
  288. /* SystemD2Clock frequency : CM4 CPU, AXI and AHBs Clock frequency */
  289. SystemD2Clock = (SystemCoreClock >> ((D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_HPRE)>> RCC_D1CFGR_HPRE_Pos]) & 0x1FU));
  290. }
  291. /**
  292. * @}
  293. */
  294. /**
  295. * @}
  296. */
  297. /**
  298. * @}
  299. */
  300. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/