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</center></h2>
26 *
27 * Redistribution and use in source and binary forms, with or without modification,
28 * are permitted provided that the following conditions are met:
29 * 1. Redistributions of source code must retain the above copyright notice,
30 * this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright notice,
32 * this list of conditions and the following disclaimer in the documentation
33 * and/or other materials provided with the distribution.
34 * 3. Neither the name of STMicroelectronics nor the names of its contributors
35 * may be used to endorse or promote products derived from this software
36 * without specific prior written permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
39 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
44 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
45 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 ******************************************************************************
50 */
51
52 /** @addtogroup CMSIS
53 * @{
54 */
55
56 /** @addtogroup stm32l0xx_system
57 * @{
58 */
59
60 /** @addtogroup STM32L0xx_System_Private_Includes
61 * @{
62 */
63
64 #include "stm32l0xx.h"
65
66 #if !defined (HSE_VALUE)
67 #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
68 #endif /* HSE_VALUE */
69
70 #if !defined (MSI_VALUE)
71 #define MSI_VALUE ((uint32_t)2000000U) /*!< Value of the Internal oscillator in Hz*/
72 #endif /* MSI_VALUE */
73
74 #if !defined (HSI_VALUE)
75 #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
76 #endif /* HSI_VALUE */
77
78
79 /**
80 * @}
81 */
82
83 /** @addtogroup STM32L0xx_System_Private_TypesDefinitions
84 * @{
85 */
86
87 /**
88 * @}
89 */
90
91 /** @addtogroup STM32L0xx_System_Private_Defines
92 * @{
93 */
94 /************************* Miscellaneous Configuration ************************/
95
96 /*!< Uncomment the following line if you need to relocate your vector Table in
97 Internal SRAM. */
98 /* #define VECT_TAB_SRAM */
99 #define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field.
100 This value must be a multiple of 0x200. */
101 /******************************************************************************/
102 /**
103 * @}
104 */
105
106 /** @addtogroup STM32L0xx_System_Private_Macros
107 * @{
108 */
109
110 /**
111 * @}
112 */
113
114 /** @addtogroup STM32L0xx_System_Private_Variables
115 * @{
116 */
117 /* This variable is updated in three ways:
118 1) by calling CMSIS function SystemCoreClockUpdate()
119 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
120 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
121 Note: If you use this function to configure the system clock; then there
122 is no need to call the 2 first functions listed above, since SystemCoreClock
123 variable is updated automatically.
124 */
125 uint32_t SystemCoreClock = 2000000U;
126 const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
127 const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
128 const uint8_t PLLMulTable[9] = {3U, 4U, 6U, 8U, 12U, 16U, 24U, 32U, 48U};
129
130 /**
131 * @}
132 */
133
134 /** @addtogroup STM32L0xx_System_Private_FunctionPrototypes
135 * @{
136 */
137
138 /**
139 * @}
140 */
141
142 /** @addtogroup STM32L0xx_System_Private_Functions
143 * @{
144 */
145
146 /**
147 * @brief Setup the microcontroller system.
148 * @param None
149 * @retval None
150 */
SystemInit(void)151 void SystemInit (void)
152 {
153 /*!< Set MSION bit */
154 RCC->CR |= (uint32_t)0x00000100U;
155
156 /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */
157 RCC->CFGR &= (uint32_t) 0x88FF400CU;
158
159 /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */
160 RCC->CR &= (uint32_t)0xFEF6FFF6U;
161
162 /*!< Reset HSI48ON bit */
163 RCC->CRRCR &= (uint32_t)0xFFFFFFFEU;
164
165 /*!< Reset HSEBYP bit */
166 RCC->CR &= (uint32_t)0xFFFBFFFFU;
167
168 /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */
169 RCC->CFGR &= (uint32_t)0xFF02FFFFU;
170
171 /*!< Disable all interrupts */
172 RCC->CIER = 0x00000000U;
173
174 /* Configure the Vector Table location add offset address ------------------*/
175 #ifdef VECT_TAB_SRAM
176 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
177 #else
178 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
179 #endif
180 }
181
182 /**
183 * @brief Update SystemCoreClock according to Clock Register Values
184 * The SystemCoreClock variable contains the core clock (HCLK), it can
185 * be used by the user application to setup the SysTick timer or configure
186 * other parameters.
187 *
188 * @note Each time the core clock (HCLK) changes, this function must be called
189 * to update SystemCoreClock variable value. Otherwise, any configuration
190 * based on this variable will be incorrect.
191 *
192 * @note - The system frequency computed by this function is not the real
193 * frequency in the chip. It is calculated based on the predefined
194 * constant and the selected clock source:
195 *
196 * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI
197 * value as defined by the MSI range.
198 *
199 * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
200 *
201 * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
202 *
203 * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
204 * or HSI_VALUE(*) multiplied/divided by the PLL factors.
205 *
206 * (*) HSI_VALUE is a constant defined in stm32l0xx_hal.h file (default value
207 * 16 MHz) but the real value may vary depending on the variations
208 * in voltage and temperature.
209 *
210 * (**) HSE_VALUE is a constant defined in stm32l0xx_hal.h file (default value
211 * 8 MHz), user has to ensure that HSE_VALUE is same as the real
212 * frequency of the crystal used. Otherwise, this function may
213 * have wrong result.
214 *
215 * - The result of this function could be not correct when using fractional
216 * value for HSE crystal.
217 * @param None
218 * @retval None
219 */
SystemCoreClockUpdate(void)220 void SystemCoreClockUpdate (void)
221 {
222 uint32_t tmp = 0U, pllmul = 0U, plldiv = 0U, pllsource = 0U, msirange = 0U;
223
224 /* Get SYSCLK source -------------------------------------------------------*/
225 tmp = RCC->CFGR & RCC_CFGR_SWS;
226
227 switch (tmp)
228 {
229 case 0x00U: /* MSI used as system clock */
230 msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13U;
231 SystemCoreClock = (32768U * (1U << (msirange + 1U)));
232 break;
233 case 0x04U: /* HSI used as system clock */
234 SystemCoreClock = HSI_VALUE;
235 break;
236 case 0x08U: /* HSE used as system clock */
237 SystemCoreClock = HSE_VALUE;
238 break;
239 case 0x0CU: /* PLL used as system clock */
240 /* Get PLL clock source and multiplication factor ----------------------*/
241 pllmul = RCC->CFGR & RCC_CFGR_PLLMUL;
242 plldiv = RCC->CFGR & RCC_CFGR_PLLDIV;
243 pllmul = PLLMulTable[(pllmul >> 18U)];
244 plldiv = (plldiv >> 22U) + 1U;
245
246 pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
247
248 if (pllsource == 0x00U)
249 {
250 /* HSI oscillator clock selected as PLL clock entry */
251 SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv);
252 }
253 else
254 {
255 /* HSE selected as PLL clock entry */
256 SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv);
257 }
258 break;
259 default: /* MSI used as system clock */
260 msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13U;
261 SystemCoreClock = (32768U * (1U << (msirange + 1U)));
262 break;
263 }
264 /* Compute HCLK clock frequency --------------------------------------------*/
265 /* Get HCLK prescaler */
266 tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
267 /* HCLK clock frequency */
268 SystemCoreClock >>= tmp;
269 }
270
271
272
273 /**
274 * @}
275 */
276
277 /**
278 * @}
279 */
280
281 /**
282 * @}
283 */
284
285 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
286