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.
 
 
 

280 lines
8.6 KiB

  1. /**
  2. ******************************************************************************
  3. * @file system_stm32l0xx.c
  4. * @author MCD Application Team
  5. * @brief CMSIS Cortex-M0+ 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_stm32l0xx.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) 2016 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 stm32l0xx_system
  39. * @{
  40. */
  41. /** @addtogroup STM32L0xx_System_Private_Includes
  42. * @{
  43. */
  44. #include "stm32l0xx.h"
  45. #if !defined (HSE_VALUE)
  46. #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
  47. #endif /* HSE_VALUE */
  48. #if !defined (MSI_VALUE)
  49. #define MSI_VALUE ((uint32_t)2097152U) /*!< Value of the Internal oscillator in Hz*/
  50. #endif /* MSI_VALUE */
  51. #if !defined (HSI_VALUE)
  52. #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
  53. #endif /* HSI_VALUE */
  54. /**
  55. * @}
  56. */
  57. /** @addtogroup STM32L0xx_System_Private_TypesDefinitions
  58. * @{
  59. */
  60. /**
  61. * @}
  62. */
  63. /** @addtogroup STM32L0xx_System_Private_Defines
  64. * @{
  65. */
  66. /************************* Miscellaneous Configuration ************************/
  67. /*!< Uncomment the following line if you need to relocate your vector Table in
  68. Internal SRAM. */
  69. /* #define VECT_TAB_SRAM */
  70. #define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field.
  71. This value must be a multiple of 0x100. */
  72. /******************************************************************************/
  73. /**
  74. * @}
  75. */
  76. /** @addtogroup STM32L0xx_System_Private_Macros
  77. * @{
  78. */
  79. /**
  80. * @}
  81. */
  82. /** @addtogroup STM32L0xx_System_Private_Variables
  83. * @{
  84. */
  85. /* This variable is updated in three ways:
  86. 1) by calling CMSIS function SystemCoreClockUpdate()
  87. 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
  88. 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
  89. Note: If you use this function to configure the system clock; then there
  90. is no need to call the 2 first functions listed above, since SystemCoreClock
  91. variable is updated automatically.
  92. */
  93. uint32_t SystemCoreClock = 2097152U; /* 32.768 kHz * 2^6 */
  94. const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
  95. const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
  96. const uint8_t PLLMulTable[9] = {3U, 4U, 6U, 8U, 12U, 16U, 24U, 32U, 48U};
  97. /**
  98. * @}
  99. */
  100. /** @addtogroup STM32L0xx_System_Private_FunctionPrototypes
  101. * @{
  102. */
  103. /**
  104. * @}
  105. */
  106. /** @addtogroup STM32L0xx_System_Private_Functions
  107. * @{
  108. */
  109. /**
  110. * @brief Setup the microcontroller system.
  111. * @param None
  112. * @retval None
  113. */
  114. void SystemInit (void)
  115. {
  116. /*!< Set MSION bit */
  117. RCC->CR |= (uint32_t)0x00000100U;
  118. /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */
  119. RCC->CFGR &= (uint32_t) 0x88FF400CU;
  120. /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */
  121. RCC->CR &= (uint32_t)0xFEF6FFF6U;
  122. /*!< Reset HSI48ON bit */
  123. RCC->CRRCR &= (uint32_t)0xFFFFFFFEU;
  124. /*!< Reset HSEBYP bit */
  125. RCC->CR &= (uint32_t)0xFFFBFFFFU;
  126. /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */
  127. RCC->CFGR &= (uint32_t)0xFF02FFFFU;
  128. /*!< Disable all interrupts */
  129. RCC->CIER = 0x00000000U;
  130. /* Configure the Vector Table location add offset address ------------------*/
  131. #ifdef VECT_TAB_SRAM
  132. SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
  133. #else
  134. SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
  135. #endif
  136. }
  137. /**
  138. * @brief Update SystemCoreClock according to Clock Register Values
  139. * The SystemCoreClock variable contains the core clock (HCLK), it can
  140. * be used by the user application to setup the SysTick timer or configure
  141. * other parameters.
  142. *
  143. * @note Each time the core clock (HCLK) changes, this function must be called
  144. * to update SystemCoreClock variable value. Otherwise, any configuration
  145. * based on this variable will be incorrect.
  146. *
  147. * @note - The system frequency computed by this function is not the real
  148. * frequency in the chip. It is calculated based on the predefined
  149. * constant and the selected clock source:
  150. *
  151. * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI
  152. * value as defined by the MSI range.
  153. *
  154. * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
  155. *
  156. * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
  157. *
  158. * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
  159. * or HSI_VALUE(*) multiplied/divided by the PLL factors.
  160. *
  161. * (*) HSI_VALUE is a constant defined in stm32l0xx_hal.h file (default value
  162. * 16 MHz) but the real value may vary depending on the variations
  163. * in voltage and temperature.
  164. *
  165. * (**) HSE_VALUE is a constant defined in stm32l0xx_hal.h file (default value
  166. * 8 MHz), user has to ensure that HSE_VALUE is same as the real
  167. * frequency of the crystal used. Otherwise, this function may
  168. * have wrong result.
  169. *
  170. * - The result of this function could be not correct when using fractional
  171. * value for HSE crystal.
  172. * @param None
  173. * @retval None
  174. */
  175. void SystemCoreClockUpdate (void)
  176. {
  177. uint32_t tmp = 0U, pllmul = 0U, plldiv = 0U, pllsource = 0U, msirange = 0U;
  178. /* Get SYSCLK source -------------------------------------------------------*/
  179. tmp = RCC->CFGR & RCC_CFGR_SWS;
  180. switch (tmp)
  181. {
  182. case 0x00U: /* MSI used as system clock */
  183. msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> RCC_ICSCR_MSIRANGE_Pos;
  184. SystemCoreClock = (32768U * (1U << (msirange + 1U)));
  185. break;
  186. case 0x04U: /* HSI used as system clock */
  187. if ((RCC->CR & RCC_CR_HSIDIVF) != 0U)
  188. {
  189. SystemCoreClock = HSI_VALUE / 4U;
  190. }
  191. else
  192. {
  193. SystemCoreClock = HSI_VALUE;
  194. }
  195. break;
  196. case 0x08U: /* HSE used as system clock */
  197. SystemCoreClock = HSE_VALUE;
  198. break;
  199. default: /* PLL used as system clock */
  200. /* Get PLL clock source and multiplication factor ----------------------*/
  201. pllmul = RCC->CFGR & RCC_CFGR_PLLMUL;
  202. plldiv = RCC->CFGR & RCC_CFGR_PLLDIV;
  203. pllmul = PLLMulTable[(pllmul >> RCC_CFGR_PLLMUL_Pos)];
  204. plldiv = (plldiv >> RCC_CFGR_PLLDIV_Pos) + 1U;
  205. pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
  206. if (pllsource == 0x00U)
  207. {
  208. /* HSI oscillator clock selected as PLL clock entry */
  209. if ((RCC->CR & RCC_CR_HSIDIVF) != 0U)
  210. {
  211. SystemCoreClock = (((HSI_VALUE / 4U) * pllmul) / plldiv);
  212. }
  213. else
  214. {
  215. SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv);
  216. }
  217. }
  218. else
  219. {
  220. /* HSE selected as PLL clock entry */
  221. SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv);
  222. }
  223. break;
  224. }
  225. /* Compute HCLK clock frequency --------------------------------------------*/
  226. /* Get HCLK prescaler */
  227. tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
  228. /* HCLK clock frequency */
  229. SystemCoreClock >>= tmp;
  230. }
  231. /**
  232. * @}
  233. */
  234. /**
  235. * @}
  236. */
  237. /**
  238. * @}
  239. */
  240. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/