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.
 
 
 

355 lines
13 KiB

  1. /**
  2. ******************************************************************************
  3. * @file system_stm32l4xx.c
  4. * @author MCD Application Team
  5. * @version V1.3.2
  6. * @date 16-June-2017
  7. * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File
  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 startup just after reset and
  12. * before branch to main program. This call is made inside
  13. * the "startup_stm32l4xx.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. * After each device reset the MSI (4 MHz) is used as system clock source.
  24. * Then SystemInit() function is called, in "startup_stm32l4xx.s" file, to
  25. * configure the system clock before to branch to main program.
  26. *
  27. * This file configures the system clock as follows:
  28. *=============================================================================
  29. *-----------------------------------------------------------------------------
  30. * System Clock source | MSI
  31. *-----------------------------------------------------------------------------
  32. * SYSCLK(Hz) | 4000000
  33. *-----------------------------------------------------------------------------
  34. * HCLK(Hz) | 4000000
  35. *-----------------------------------------------------------------------------
  36. * AHB Prescaler | 1
  37. *-----------------------------------------------------------------------------
  38. * APB1 Prescaler | 1
  39. *-----------------------------------------------------------------------------
  40. * APB2 Prescaler | 1
  41. *-----------------------------------------------------------------------------
  42. * PLL_M | 1
  43. *-----------------------------------------------------------------------------
  44. * PLL_N | 8
  45. *-----------------------------------------------------------------------------
  46. * PLL_P | 7
  47. *-----------------------------------------------------------------------------
  48. * PLL_Q | 2
  49. *-----------------------------------------------------------------------------
  50. * PLL_R | 2
  51. *-----------------------------------------------------------------------------
  52. * PLLSAI1_P | NA
  53. *-----------------------------------------------------------------------------
  54. * PLLSAI1_Q | NA
  55. *-----------------------------------------------------------------------------
  56. * PLLSAI1_R | NA
  57. *-----------------------------------------------------------------------------
  58. * PLLSAI2_P | NA
  59. *-----------------------------------------------------------------------------
  60. * PLLSAI2_Q | NA
  61. *-----------------------------------------------------------------------------
  62. * PLLSAI2_R | NA
  63. *-----------------------------------------------------------------------------
  64. * Require 48MHz for USB OTG FS, | Disabled
  65. * SDIO and RNG clock |
  66. *-----------------------------------------------------------------------------
  67. *=============================================================================
  68. ******************************************************************************
  69. * @attention
  70. *
  71. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  72. *
  73. * Redistribution and use in source and binary forms, with or without modification,
  74. * are permitted provided that the following conditions are met:
  75. * 1. Redistributions of source code must retain the above copyright notice,
  76. * this list of conditions and the following disclaimer.
  77. * 2. Redistributions in binary form must reproduce the above copyright notice,
  78. * this list of conditions and the following disclaimer in the documentation
  79. * and/or other materials provided with the distribution.
  80. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  81. * may be used to endorse or promote products derived from this software
  82. * without specific prior written permission.
  83. *
  84. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  85. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  86. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  87. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  88. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  89. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  90. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  91. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  92. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  93. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  94. *
  95. ******************************************************************************
  96. */
  97. /** @addtogroup CMSIS
  98. * @{
  99. */
  100. /** @addtogroup stm32l4xx_system
  101. * @{
  102. */
  103. /** @addtogroup STM32L4xx_System_Private_Includes
  104. * @{
  105. */
  106. #include "stm32l4xx.h"
  107. #if !defined (HSE_VALUE)
  108. #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
  109. #endif /* HSE_VALUE */
  110. #if !defined (MSI_VALUE)
  111. #define MSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/
  112. #endif /* MSI_VALUE */
  113. #if !defined (HSI_VALUE)
  114. #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
  115. #endif /* HSI_VALUE */
  116. /**
  117. * @}
  118. */
  119. /** @addtogroup STM32L4xx_System_Private_TypesDefinitions
  120. * @{
  121. */
  122. /**
  123. * @}
  124. */
  125. /** @addtogroup STM32L4xx_System_Private_Defines
  126. * @{
  127. */
  128. /************************* Miscellaneous Configuration ************************/
  129. /*!< Uncomment the following line if you need to relocate your vector Table in
  130. Internal SRAM. */
  131. /* #define VECT_TAB_SRAM */
  132. #define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
  133. This value must be a multiple of 0x200. */
  134. /******************************************************************************/
  135. /**
  136. * @}
  137. */
  138. /** @addtogroup STM32L4xx_System_Private_Macros
  139. * @{
  140. */
  141. /**
  142. * @}
  143. */
  144. /** @addtogroup STM32L4xx_System_Private_Variables
  145. * @{
  146. */
  147. /* The SystemCoreClock variable is updated in three ways:
  148. 1) by calling CMSIS function SystemCoreClockUpdate()
  149. 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
  150. 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
  151. Note: If you use this function to configure the system clock; then there
  152. is no need to call the 2 first functions listed above, since SystemCoreClock
  153. variable is updated automatically.
  154. */
  155. uint32_t SystemCoreClock = 4000000;
  156. const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
  157. const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
  158. const uint32_t MSIRangeTable[12] = {100000, 200000, 400000, 800000, 1000000, 2000000, \
  159. 4000000, 8000000, 16000000, 24000000, 32000000, 48000000};
  160. /**
  161. * @}
  162. */
  163. /** @addtogroup STM32L4xx_System_Private_FunctionPrototypes
  164. * @{
  165. */
  166. /**
  167. * @}
  168. */
  169. /** @addtogroup STM32L4xx_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. /* FPU settings ------------------------------------------------------------*/
  180. #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  181. SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
  182. #endif
  183. /* Reset the RCC clock configuration to the default reset state ------------*/
  184. /* Set MSION bit */
  185. RCC->CR |= RCC_CR_MSION;
  186. /* Reset CFGR register */
  187. RCC->CFGR = 0x00000000;
  188. /* Reset HSEON, CSSON , HSION, and PLLON bits */
  189. RCC->CR &= (uint32_t)0xEAF6FFFF;
  190. /* Reset PLLCFGR register */
  191. RCC->PLLCFGR = 0x00001000;
  192. /* Reset HSEBYP bit */
  193. RCC->CR &= (uint32_t)0xFFFBFFFF;
  194. /* Disable all interrupts */
  195. RCC->CIER = 0x00000000;
  196. /* Configure the Vector Table location add offset address ------------------*/
  197. #ifdef VECT_TAB_SRAM
  198. SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
  199. #else
  200. SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
  201. #endif
  202. }
  203. /**
  204. * @brief Update SystemCoreClock variable according to Clock Register Values.
  205. * The SystemCoreClock variable contains the core clock (HCLK), it can
  206. * be used by the user application to setup the SysTick timer or configure
  207. * other parameters.
  208. *
  209. * @note Each time the core clock (HCLK) changes, this function must be called
  210. * to update SystemCoreClock variable value. Otherwise, any configuration
  211. * based on this variable will be incorrect.
  212. *
  213. * @note - The system frequency computed by this function is not the real
  214. * frequency in the chip. It is calculated based on the predefined
  215. * constant and the selected clock source:
  216. *
  217. * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*)
  218. *
  219. * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
  220. *
  221. * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
  222. *
  223. * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
  224. * or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors.
  225. *
  226. * (*) MSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value
  227. * 4 MHz) but the real value may vary depending on the variations
  228. * in voltage and temperature.
  229. *
  230. * (**) HSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value
  231. * 16 MHz) but the real value may vary depending on the variations
  232. * in voltage and temperature.
  233. *
  234. * (***) HSE_VALUE is a constant defined in stm32l4xx_hal.h file (default value
  235. * 8 MHz), user has to ensure that HSE_VALUE is same as the real
  236. * frequency of the crystal used. Otherwise, this function may
  237. * have wrong result.
  238. *
  239. * - The result of this function could be not correct when using fractional
  240. * value for HSE crystal.
  241. *
  242. * @param None
  243. * @retval None
  244. */
  245. void SystemCoreClockUpdate(void)
  246. {
  247. uint32_t tmp = 0, msirange = 0, pllvco = 0, pllr = 2, pllsource = 0, pllm = 2;
  248. /* Get MSI Range frequency--------------------------------------------------*/
  249. if((RCC->CR & RCC_CR_MSIRGSEL) == RESET)
  250. { /* MSISRANGE from RCC_CSR applies */
  251. msirange = (RCC->CSR & RCC_CSR_MSISRANGE) >> 8;
  252. }
  253. else
  254. { /* MSIRANGE from RCC_CR applies */
  255. msirange = (RCC->CR & RCC_CR_MSIRANGE) >> 4;
  256. }
  257. /*MSI frequency range in HZ*/
  258. msirange = MSIRangeTable[msirange];
  259. /* Get SYSCLK source -------------------------------------------------------*/
  260. switch (RCC->CFGR & RCC_CFGR_SWS)
  261. {
  262. case 0x00: /* MSI used as system clock source */
  263. SystemCoreClock = msirange;
  264. break;
  265. case 0x04: /* HSI used as system clock source */
  266. SystemCoreClock = HSI_VALUE;
  267. break;
  268. case 0x08: /* HSE used as system clock source */
  269. SystemCoreClock = HSE_VALUE;
  270. break;
  271. case 0x0C: /* PLL used as system clock source */
  272. /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
  273. SYSCLK = PLL_VCO / PLLR
  274. */
  275. pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
  276. pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4) + 1 ;
  277. switch (pllsource)
  278. {
  279. case 0x02: /* HSI used as PLL clock source */
  280. pllvco = (HSI_VALUE / pllm);
  281. break;
  282. case 0x03: /* HSE used as PLL clock source */
  283. pllvco = (HSE_VALUE / pllm);
  284. break;
  285. default: /* MSI used as PLL clock source */
  286. pllvco = (msirange / pllm);
  287. break;
  288. }
  289. pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8);
  290. pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25) + 1) * 2;
  291. SystemCoreClock = pllvco/pllr;
  292. break;
  293. default:
  294. SystemCoreClock = msirange;
  295. break;
  296. }
  297. /* Compute HCLK clock frequency --------------------------------------------*/
  298. /* Get HCLK prescaler */
  299. tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
  300. /* HCLK clock frequency */
  301. SystemCoreClock >>= tmp;
  302. }
  303. /**
  304. * @}
  305. */
  306. /**
  307. * @}
  308. */
  309. /**
  310. * @}
  311. */
  312. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/