2 ******************************************************************************
3 * @file system_stm32f1xx.c
4 * @author MCD Application Team
6 * @date 16-December-2014
7 * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
9 * 1. This file provides two functions and one global variable to be called from
11 * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
12 * factors, AHB/APBx prescalers and Flash settings).
13 * This function is called at startup just after reset and
14 * before branch to main program. This call is made inside
15 * the "startup_stm32f1xx_xx.s" file.
17 * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
18 * by the user application to setup the SysTick
19 * timer or configure other parameters.
21 * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
22 * be called whenever the core clock is changed
23 * during program execution.
25 * 2. After each device reset the HSI (8 MHz) is used as system clock source.
26 * Then SystemInit() function is called, in "startup_stm32f1xx_xx.s" file, to
27 * configure the system clock before to branch to main program.
29 * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on
30 * the product used), refer to "HSE_VALUE".
31 * When HSE is used as system clock source, directly or through PLL, and you
32 * are using different crystal you have to adapt the HSE value to your own
35 * This file configures the system clock as follows:
36 *-----------------------------------------------------------------------------
37 * System clock source | 1- PLL_HSE_EXTC | 3- PLL_HSI
38 * | (external 8 MHz clock) | (internal 8 MHz)
40 * | (external 8 MHz xtal) |
41 *-----------------------------------------------------------------------------
42 * SYSCLK(MHz) | 72 | 64
43 *-----------------------------------------------------------------------------
44 * AHBCLK (MHz) | 72 | 64
45 *-----------------------------------------------------------------------------
46 * APB1CLK (MHz) | 36 | 32
47 *-----------------------------------------------------------------------------
48 * APB2CLK (MHz) | 72 | 64
49 *-----------------------------------------------------------------------------
50 * USB capable (48 MHz precise clock) | NO | NO
51 *-----------------------------------------------------------------------------
52 ******************************************************************************
55 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
57 * Redistribution and use in source and binary forms, with or without modification,
58 * are permitted provided that the following conditions are met:
59 * 1. Redistributions of source code must retain the above copyright notice,
60 * this list of conditions and the following disclaimer.
61 * 2. Redistributions in binary form must reproduce the above copyright notice,
62 * this list of conditions and the following disclaimer in the documentation
63 * and/or other materials provided with the distribution.
64 * 3. Neither the name of STMicroelectronics nor the names of its contributors
65 * may be used to endorse or promote products derived from this software
66 * without specific prior written permission.
68 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
69 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
70 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
71 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
72 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
73 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
74 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
75 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
76 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
77 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79 ******************************************************************************
86 /** @addtogroup stm32f1xx_system
90 /** @addtogroup STM32F1xx_System_Private_Includes
94 #include "stm32f1xx.h"
101 /** @addtogroup STM32F1xx_System_Private_TypesDefinitions
109 /** @addtogroup STM32F1xx_System_Private_Defines
113 #if !defined (HSE_VALUE)
114 #define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz.
115 This value can be provided and adapted by the user application. */
116 #endif /* HSE_VALUE */
118 #if !defined (HSI_VALUE)
119 #define HSI_VALUE ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz.
120 This value can be provided and adapted by the user application. */
121 #endif /* HSI_VALUE */
123 /*!< Uncomment the following line if you need to use external SRAM */
124 #if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
125 /* #define DATA_IN_ExtSRAM */
126 #endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
128 /*!< Uncomment the following line if you need to relocate your vector Table in
130 /* #define VECT_TAB_SRAM */
131 #define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field.
132 This value must be a multiple of 0x200. */
139 /** @addtogroup STM32F1xx_System_Private_Macros
143 /* Select the clock sources (other than HSI) to start with (0=OFF, 1=ON) */
144 #define USE_PLL_HSE_EXTC (1) /* Use external clock */
145 #define USE_PLL_HSE_XTAL (1) /* Use external xtal */
151 /** @addtogroup STM32F1xx_System_Private_Variables
155 /*******************************************************************************
157 *******************************************************************************/
158 #if defined(STM32F100xB) ||defined(STM32F100xE)
159 uint32_t SystemCoreClock = 24000000; /*!< System Clock Frequency (Core Clock) */
160 #else /*!< HSI Selected as System Clock source */
161 uint32_t SystemCoreClock = 72000000; /*!< System Clock Frequency (Core Clock) */
164 const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
169 /** @addtogroup STM32F1xx_System_Private_FunctionPrototypes
173 #if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
174 #ifdef DATA_IN_ExtSRAM
175 static void SystemInit_ExtMemCtl(void);
176 #endif /* DATA_IN_ExtSRAM */
177 #endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
179 #if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0)
180 uint8_t SetSysClock_PLL_HSE(uint8_t bypass);
183 uint8_t SetSysClock_PLL_HSI(void);
189 /** @addtogroup STM32F1xx_System_Private_Functions
194 * @brief Setup the microcontroller system
195 * Initialize the Embedded Flash Interface, the PLL and update the
196 * SystemCoreClock variable.
197 * @note This function should be used only after reset.
201 void SystemInit (void)
203 /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
205 RCC->CR |= (uint32_t)0x00000001;
207 /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
208 #if !defined(STM32F105xC) && !defined(STM32F107xC)
209 RCC->CFGR &= (uint32_t)0xF8FF0000;
211 RCC->CFGR &= (uint32_t)0xF0FF0000;
212 #endif /* STM32F105xC */
214 /* Reset HSEON, CSSON and PLLON bits */
215 RCC->CR &= (uint32_t)0xFEF6FFFF;
217 /* Reset HSEBYP bit */
218 RCC->CR &= (uint32_t)0xFFFBFFFF;
220 /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
221 RCC->CFGR &= (uint32_t)0xFF80FFFF;
223 #if defined(STM32F105xC) || defined(STM32F107xC)
224 /* Reset PLL2ON and PLL3ON bits */
225 RCC->CR &= (uint32_t)0xEBFFFFFF;
227 /* Disable all interrupts and clear pending bits */
228 RCC->CIR = 0x00FF0000;
230 /* Reset CFGR2 register */
231 RCC->CFGR2 = 0x00000000;
232 #elif defined(STM32F100xB) || defined(STM32F100xE)
233 /* Disable all interrupts and clear pending bits */
234 RCC->CIR = 0x009F0000;
236 /* Reset CFGR2 register */
237 RCC->CFGR2 = 0x00000000;
239 /* Disable all interrupts and clear pending bits */
240 RCC->CIR = 0x009F0000;
241 #endif /* STM32F105xC */
243 #if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
244 #ifdef DATA_IN_ExtSRAM
245 SystemInit_ExtMemCtl();
246 #endif /* DATA_IN_ExtSRAM */
250 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
252 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
255 /* Configure the Cube driver */
256 SystemCoreClock = 8000000; // At this stage the HSI is used as system clock
259 /* Configure the System clock source, PLL Multiplier and Divider factors,
260 AHB/APBx prescalers and Flash settings */
263 /* Reset the timer to avoid issues after the RAM initialization */
269 * @brief Update SystemCoreClock variable according to Clock Register Values.
270 * The SystemCoreClock variable contains the core clock (HCLK), it can
271 * be used by the user application to setup the SysTick timer or configure
274 * @note Each time the core clock (HCLK) changes, this function must be called
275 * to update SystemCoreClock variable value. Otherwise, any configuration
276 * based on this variable will be incorrect.
278 * @note - The system frequency computed by this function is not the real
279 * frequency in the chip. It is calculated based on the predefined
280 * constant and the selected clock source:
282 * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
284 * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
286 * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
287 * or HSI_VALUE(*) multiplied by the PLL factors.
289 * (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
290 * 8 MHz) but the real value may vary depending on the variations
291 * in voltage and temperature.
293 * (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
294 * 8 MHz or 25 MHz, depending on the product used), user has to ensure
295 * that HSE_VALUE is same as the real frequency of the crystal used.
296 * Otherwise, this function may have wrong result.
298 * - The result of this function could be not correct when using fractional
299 * value for HSE crystal.
303 void SystemCoreClockUpdate (void)
305 uint32_t tmp = 0, pllmull = 0, pllsource = 0;
307 #if defined(STM32F105xC) || defined(STM32F107xC)
308 uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
309 #endif /* STM32F105xC */
311 #if defined(STM32F100xB) || defined(STM32F100xE)
312 uint32_t prediv1factor = 0;
313 #endif /* STM32F100xB or STM32F100xE */
315 /* Get SYSCLK source -------------------------------------------------------*/
316 tmp = RCC->CFGR & RCC_CFGR_SWS;
320 case 0x00: /* HSI used as system clock */
321 SystemCoreClock = HSI_VALUE;
323 case 0x04: /* HSE used as system clock */
324 SystemCoreClock = HSE_VALUE;
326 case 0x08: /* PLL used as system clock */
328 /* Get PLL clock source and multiplication factor ----------------------*/
329 pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
330 pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
332 #if !defined(STM32F105xC) && !defined(STM32F107xC)
333 pllmull = ( pllmull >> 18) + 2;
335 if (pllsource == 0x00)
337 /* HSI oscillator clock divided by 2 selected as PLL clock entry */
338 SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
342 #if defined(STM32F100xB) || defined(STM32F100xE)
343 prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
344 /* HSE oscillator clock selected as PREDIV1 clock entry */
345 SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
347 /* HSE selected as PLL clock entry */
348 if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
349 {/* HSE oscillator clock divided by 2 */
350 SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
354 SystemCoreClock = HSE_VALUE * pllmull;
359 pllmull = pllmull >> 18;
366 { /* PLL multiplication factor = PLL input clock * 6.5 */
370 if (pllsource == 0x00)
372 /* HSI oscillator clock divided by 2 selected as PLL clock entry */
373 SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
376 {/* PREDIV1 selected as PLL clock entry */
378 /* Get PREDIV1 clock source and division factor */
379 prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
380 prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
382 if (prediv1source == 0)
384 /* HSE oscillator clock selected as PREDIV1 clock entry */
385 SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
388 {/* PLL2 clock selected as PREDIV1 clock entry */
390 /* Get PREDIV2 division factor and PLL2 multiplication factor */
391 prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1;
392 pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2;
393 SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
396 #endif /* STM32F105xC */
400 SystemCoreClock = HSI_VALUE;
404 /* Compute HCLK clock frequency ----------------*/
405 /* Get HCLK prescaler */
406 tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
407 /* HCLK clock frequency */
408 SystemCoreClock >>= tmp;
411 #if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
413 * @brief Setup the external memory controller. Called in startup_stm32f1xx.s
414 * before jump to __main
418 #ifdef DATA_IN_ExtSRAM
420 * @brief Setup the external memory controller.
421 * Called in startup_stm32f1xx_xx.s/.c before jump to main.
422 * This function configures the external SRAM mounted on STM3210E-EVAL
423 * board (STM32 High density devices). This SRAM will be used as program
424 * data memory (including heap and stack).
428 void SystemInit_ExtMemCtl(void)
430 __IO uint32_t tmpreg;
431 /*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
432 required, then adjust the Register Addresses */
434 /* Enable FSMC clock */
435 RCC->AHBENR = 0x00000114;
437 /* Delay after an RCC peripheral clock enabling */
438 tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
440 /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
441 RCC->APB2ENR = 0x000001E0;
443 /* Delay after an RCC peripheral clock enabling */
444 tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
448 /* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
449 /*---------------- SRAM Address lines configuration -------------------------*/
450 /*---------------- NOE and NWE configuration --------------------------------*/
451 /*---------------- NE3 configuration ----------------------------------------*/
452 /*---------------- NBL0, NBL1 configuration ---------------------------------*/
454 GPIOD->CRL = 0x44BB44BB;
455 GPIOD->CRH = 0xBBBBBBBB;
457 GPIOE->CRL = 0xB44444BB;
458 GPIOE->CRH = 0xBBBBBBBB;
460 GPIOF->CRL = 0x44BBBBBB;
461 GPIOF->CRH = 0xBBBB4444;
463 GPIOG->CRL = 0x44BBBBBB;
464 GPIOG->CRH = 0x444B4B44;
466 /*---------------- FSMC Configuration ---------------------------------------*/
467 /*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
469 FSMC_Bank1->BTCR[4] = 0x00001091;
470 FSMC_Bank1->BTCR[5] = 0x00110212;
472 #endif /* DATA_IN_ExtSRAM */
473 #endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
476 * @brief Configures the System clock source, PLL Multiplier and Divider factors,
477 * AHB/APBx prescalers and Flash settings
478 * @note This function should be called only once the RCC clock configuration
479 * is reset to the default reset state (done in SystemInit() function).
483 void SetSysClock(void)
485 /* 1- Try to start with HSE and external clock */
486 #if USE_PLL_HSE_EXTC != 0
487 if (SetSysClock_PLL_HSE(1) == 0)
490 /* 2- If fail try to start with HSE and external xtal */
491 #if USE_PLL_HSE_XTAL != 0
492 if (SetSysClock_PLL_HSE(0) == 0)
495 /* 3- If fail start with HSI clock */
496 if (SetSysClock_PLL_HSI() == 0)
500 // [TODO] Put something here to tell the user that a problem occured...
506 /* Output clock on MCO1 pin(PA8) for debugging purpose */
507 //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); // 72 MHz or 64 MHz
510 #if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0)
511 /******************************************************************************/
512 /* PLL (clocked by HSE) used as System clock source */
513 /******************************************************************************/
514 uint8_t SetSysClock_PLL_HSE(uint8_t bypass)
516 RCC_ClkInitTypeDef RCC_ClkInitStruct;
517 RCC_OscInitTypeDef RCC_OscInitStruct;
519 /* Enable HSE oscillator and activate PLL with HSE as source */
520 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
523 RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */
527 RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */
529 RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
530 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
531 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
532 RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; // 72 MHz (8 MHz * 9)
533 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
538 /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
539 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
540 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 72 MHz
541 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 72 MHz
542 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; // 36 MHz
543 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 72 MHz
544 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
549 /* Output clock on MCO1 pin(PA8) for debugging purpose */
550 //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1); // 8 MHz
556 /******************************************************************************/
557 /* PLL (clocked by HSI) used as System clock source */
558 /******************************************************************************/
559 uint8_t SetSysClock_PLL_HSI(void)
561 RCC_ClkInitTypeDef RCC_ClkInitStruct;
562 RCC_OscInitTypeDef RCC_OscInitStruct;
564 /* Enable HSI oscillator and activate PLL with HSI as source */
565 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE;
566 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
567 RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
568 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
569 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
570 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
571 RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16; // 64 MHz (8 MHz/2 * 16)
572 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
577 /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
578 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
579 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 64 MHz
580 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 64 MHz
581 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; // 32 MHz
582 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 64 MHz
583 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
588 /* Output clock on MCO1 pin(PA8) for debugging purpose */
589 //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_1); // 8 MHz
605 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/