2 ******************************************************************************
\r
3 * @file system_stm32l1xx.c
\r
4 * @author MCD Application Team
\r
7 * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
\r
8 * This file contains the system clock configuration for STM32L1xx Ultra
\r
9 * Low Medium-density devices, and is generated by the clock configuration
\r
10 * tool "STM32L1xx_Clock_Configuration_V1.0.0.xls".
\r
12 * 1. This file provides two functions and one global variable to be called from
\r
14 * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
\r
15 * and Divider factors, AHB/APBx prescalers and Flash settings),
\r
16 * depending on the configuration made in the clock xls tool.
\r
17 * This function is called at startup just after reset and
\r
18 * before branch to main program. This call is made inside
\r
19 * the "startup_stm32l1xx_md.s" file.
\r
21 * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
\r
22 * by the user application to setup the SysTick
\r
23 * timer or configure other parameters.
\r
25 * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
\r
26 * be called whenever the core clock is changed
\r
27 * during program execution.
\r
29 * 2. After each device reset the MSI (2.1 MHz Range) is used as system clock source.
\r
30 * Then SystemInit() function is called, in "startup_stm32l1xx_md.s" file, to
\r
31 * configure the system clock before to branch to main program.
\r
33 * 3. If the system clock source selected by user fails to startup, the SystemInit()
\r
34 * function will do nothing and MSI still used as system clock source. User can
\r
35 * add some code to deal with this issue inside the SetSysClock() function.
\r
37 * 4. The default value of HSE crystal is set to 8MHz, refer to "HSE_VALUE" define
\r
38 * in "stm32l1xx.h" file. When HSE is used as system clock source, directly or
\r
39 * through PLL, and you are using different crystal you have to adapt the HSE
\r
40 * value to your own configuration.
\r
42 * 5. This file configures the system clock as follows:
\r
43 *=============================================================================
\r
44 * System Clock Configuration
\r
45 *=============================================================================
\r
46 * System clock source | HSI
\r
47 *-----------------------------------------------------------------------------
\r
48 * SYSCLK | 16000000 Hz
\r
49 *-----------------------------------------------------------------------------
\r
50 * HCLK | 16000000 Hz
\r
51 *-----------------------------------------------------------------------------
\r
53 *-----------------------------------------------------------------------------
\r
54 * APB1 Prescaler | 1
\r
55 *-----------------------------------------------------------------------------
\r
56 * APB2 Prescaler | 1
\r
57 *-----------------------------------------------------------------------------
\r
58 * HSE Frequency | 8000000 Hz
\r
59 *-----------------------------------------------------------------------------
\r
60 * PLL DIV | Not Used
\r
61 *-----------------------------------------------------------------------------
\r
62 * PLL MUL | Not Used
\r
63 *-----------------------------------------------------------------------------
\r
65 *-----------------------------------------------------------------------------
\r
66 * Vcore | 1.8 V (Range 1)
\r
67 *-----------------------------------------------------------------------------
\r
68 * Flash Latency | 0 WS
\r
69 *-----------------------------------------------------------------------------
\r
70 * Require 48MHz for USB clock | Disabled
\r
71 *-----------------------------------------------------------------------------
\r
72 *=============================================================================
\r
73 ******************************************************************************
\r
76 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
\r
77 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
\r
78 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
\r
79 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
\r
80 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
\r
81 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
\r
83 * <h2><center>© COPYRIGHT 2010 STMicroelectronics</center></h2>
\r
84 ******************************************************************************
\r
87 /** @addtogroup CMSIS
\r
91 /** @addtogroup stm32l1xx_system
\r
95 /** @addtogroup STM32L1xx_System_Private_Includes
\r
99 #include "stm32l1xx.h"
\r
105 /** @addtogroup STM32L1xx_System_Private_TypesDefinitions
\r
113 /** @addtogroup STM32L1xx_System_Private_Defines
\r
116 /*!< Uncomment the following line if you need to relocate your vector Table in
\r
118 /* #define VECT_TAB_SRAM */
\r
119 #define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field.
\r
120 This value must be a multiple of 0x200. */
\r
125 /** @addtogroup STM32L1xx_System_Private_Macros
\r
133 /** @addtogroup STM32L1xx_System_Private_Variables
\r
136 uint32_t SystemCoreClock = 16000000;
\r
137 __I uint8_t PLLMulTable[9] = {3, 4, 6, 8, 12, 16, 24, 32, 48};
\r
138 __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
\r
144 /** @addtogroup STM32L1xx_System_Private_FunctionPrototypes
\r
148 void SetSysClock(void);
\r
154 /** @addtogroup STM32L1xx_System_Private_Functions
\r
159 * @brief Setup the microcontroller system.
\r
160 * Initialize the Embedded Flash Interface, the PLL and update the
\r
161 * SystemCoreClock variable.
\r
165 void SystemInit (void)
\r
167 /*!< Set MSION bit */
\r
168 RCC->CR |= (uint32_t)0x00000100;
\r
170 /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */
\r
171 RCC->CFGR &= (uint32_t)0x88FFC00C;
\r
173 /*!< Reset HSION, HSEON, CSSON and PLLON bits */
\r
174 RCC->CR &= (uint32_t)0xEEFEFFFE;
\r
176 /*!< Reset HSEBYP bit */
\r
177 RCC->CR &= (uint32_t)0xFFFBFFFF;
\r
179 /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */
\r
180 RCC->CFGR &= (uint32_t)0xFF02FFFF;
\r
182 /*!< Disable all interrupts */
\r
183 RCC->CIR = 0x00000000;
\r
185 /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */
\r
188 #ifdef VECT_TAB_SRAM
\r
189 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
\r
191 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
\r
196 * @brief Update SystemCoreClock according to Clock Register Values
\r
197 * @note - The system frequency computed by this function is not the real
\r
198 * frequency in the chip. It is calculated based on the predefined
\r
199 * constant and the selected clock source:
\r
201 * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI
\r
202 * value as defined by the MSI range.
\r
204 * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
\r
206 * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
\r
208 * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
\r
209 * or HSI_VALUE(*) multiplied/divided by the PLL factors.
\r
211 * (*) HSI_VALUE is a constant defined in stm32l1xx.h file (default value
\r
212 * 16 MHz) but the real value may vary depending on the variations
\r
213 * in voltage and temperature.
\r
215 * (**) HSE_VALUE is a constant defined in stm32l1xx.h file (default value
\r
216 * 8 MHz), user has to ensure that HSE_VALUE is same as the real
\r
217 * frequency of the crystal used. Otherwise, this function may
\r
218 * have wrong result.
\r
220 * - The result of this function could be not correct when using fractional
\r
221 * value for HSE crystal.
\r
225 void SystemCoreClockUpdate (void)
\r
227 uint32_t tmp = 0, pllmul = 0, plldiv = 0, pllsource = 0, msirange = 0;
\r
229 /* Get SYSCLK source -------------------------------------------------------*/
\r
230 tmp = RCC->CFGR & RCC_CFGR_SWS;
\r
234 case 0x00: /* MSI used as system clock */
\r
235 msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13;
\r
236 SystemCoreClock = (32768 * (1 << (msirange + 1)));
\r
238 case 0x04: /* HSI used as system clock */
\r
239 SystemCoreClock = HSI_VALUE;
\r
241 case 0x08: /* HSE used as system clock */
\r
242 SystemCoreClock = HSE_VALUE;
\r
244 case 0x0C: /* PLL used as system clock */
\r
245 /* Get PLL clock source and multiplication factor ----------------------*/
\r
246 pllmul = RCC->CFGR & RCC_CFGR_PLLMUL;
\r
247 plldiv = RCC->CFGR & RCC_CFGR_PLLDIV;
\r
248 pllmul = PLLMulTable[(pllmul >> 18)];
\r
249 plldiv = (plldiv >> 22) + 1;
\r
251 pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
\r
253 if (pllsource == 0x00)
\r
255 /* HSI oscillator clock selected as PLL clock entry */
\r
256 SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv);
\r
260 /* HSE selected as PLL clock entry */
\r
261 SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv);
\r
264 default: /* MSI used as system clock */
\r
265 msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13;
\r
266 SystemCoreClock = (32768 * (1 << (msirange + 1)));
\r
269 /* Compute HCLK clock frequency --------------------------------------------*/
\r
270 /* Get HCLK prescaler */
\r
271 tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
\r
272 /* HCLK clock frequency */
\r
273 SystemCoreClock >>= tmp;
\r
277 * @brief Configures the System clock frequency, AHB/APBx prescalers and Flash
\r
279 * @note This function should be called only once the RCC clock configuration
\r
280 * is reset to the default reset state (done in SystemInit() function).
\r
284 void SetSysClock(void)
\r
286 __IO uint32_t StartUpCounter = 0, HSIStatus = 0;
\r
288 /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
\r
290 RCC->CR |= ((uint32_t)RCC_CR_HSION);
\r
292 /* Wait till HSI is ready and if Time out is reached exit */
\r
295 HSIStatus = RCC->CR & RCC_CR_HSIRDY;
\r
296 } while((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT));
\r
298 if ((RCC->CR & RCC_CR_HSIRDY) != RESET)
\r
300 HSIStatus = (uint32_t)0x01;
\r
304 HSIStatus = (uint32_t)0x00;
\r
307 if (HSIStatus == (uint32_t)0x01)
\r
309 /* Flash 0 wait state */
\r
310 FLASH->ACR &= ~FLASH_ACR_LATENCY;
\r
312 /* Disable Prefetch Buffer */
\r
313 FLASH->ACR &= ~FLASH_ACR_PRFTEN;
\r
315 /* Disable 64-bit access */
\r
316 FLASH->ACR &= ~FLASH_ACR_ACC64;
\r
320 RCC->APB1ENR |= RCC_APB1ENR_PWREN;
\r
322 /* Select the Voltage Range 1 (1.8 V) */
\r
323 PWR->CR = PWR_CR_VOS_0;
\r
326 /* Wait Until the Voltage Regulator is ready */
\r
327 while((PWR->CSR & PWR_CSR_VOSF) != RESET)
\r
331 /* HCLK = SYSCLK /1*/
\r
332 RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
\r
333 /* PCLK2 = HCLK /1*/
\r
334 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
\r
336 /* PCLK1 = HCLK /1*/
\r
337 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
\r
339 /* Select HSI as system clock source */
\r
340 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
\r
341 RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSI;
\r
343 /* Wait till HSI is used as system clock source */
\r
344 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_HSI)
\r
350 /* If HSI fails to start-up, the application will have wrong clock
\r
351 configuration. User can add here some code to deal with this error */
\r
367 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
\r