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