1 /**
2   ******************************************************************************
3   * @file    system_stm32f0xx.c
4   * @author  MCD Application Team
5   * @brief   CMSIS Cortex-M0 Device Peripheral Access Layer System Source File.
6   *
7   * 1. 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_stm32f0xx.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   * Copyright (c) 2016 STMicroelectronics.
26   * All rights reserved.
27   *
28   * This software is licensed under terms that can be found in the LICENSE file
29   * in the root directory of this software component.
30   * If no LICENSE file comes with this software, it is provided AS-IS.
31   *
32   ******************************************************************************
33   */
34 /** @addtogroup CMSIS
35   * @{
36   */
37 
38 /** @addtogroup stm32f0xx_system
39   * @{
40   */
41 
42 /** @addtogroup STM32F0xx_System_Private_Includes
43   * @{
44   */
45 
46 #include "stm32f0xx.h"
47 
48 /**
49   * @}
50   */
51 
52 /** @addtogroup STM32F0xx_System_Private_TypesDefinitions
53   * @{
54   */
55 
56 /**
57   * @}
58   */
59 
60 /** @addtogroup STM32F0xx_System_Private_Defines
61   * @{
62   */
63 #if !defined  (HSE_VALUE)
64   #define HSE_VALUE    ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz.
65                                                 This value can be provided and adapted by the user application. */
66 #endif /* HSE_VALUE */
67 
68 #if !defined  (HSI_VALUE)
69   #define HSI_VALUE    ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz.
70                                                 This value can be provided and adapted by the user application. */
71 #endif /* HSI_VALUE */
72 
73 #if !defined (HSI48_VALUE)
74 #define HSI48_VALUE    ((uint32_t)48000000) /*!< Default value of the HSI48 Internal oscillator in Hz.
75                                                  This value can be provided and adapted by the user application. */
76 #endif /* HSI48_VALUE */
77 /**
78   * @}
79   */
80 
81 /** @addtogroup STM32F0xx_System_Private_Macros
82   * @{
83   */
84 
85 /**
86   * @}
87   */
88 
89 /** @addtogroup STM32F0xx_System_Private_Variables
90   * @{
91   */
92   /* This variable is updated in three ways:
93       1) by calling CMSIS function SystemCoreClockUpdate()
94       2) by calling HAL API function HAL_RCC_GetHCLKFreq()
95       3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
96          Note: If you use this function to configure the system clock; then there
97                is no need to call the 2 first functions listed above, since SystemCoreClock
98                variable is updated automatically.
99   */
100 uint32_t SystemCoreClock = 8000000;
101 
102 const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
103 const uint8_t APBPrescTable[8]  = {0, 0, 0, 0, 1, 2, 3, 4};
104 
105 /**
106   * @}
107   */
108 
109 /** @addtogroup STM32F0xx_System_Private_FunctionPrototypes
110   * @{
111   */
112 
113 /**
114   * @}
115   */
116 
117 /** @addtogroup STM32F0xx_System_Private_Functions
118   * @{
119   */
120 
121 /**
122   * @brief  Setup the microcontroller system
123   * @param  None
124   * @retval None
125   */
SystemInit(void)126 void SystemInit(void)
127 {
128   /* NOTE :SystemInit(): This function is called at startup just after reset and
129                          before branch to main program. This call is made inside
130                          the "startup_stm32f0xx.s" file.
131                          User can setups the default system clock (System clock source, PLL Multiplier
132                          and Divider factors, AHB/APBx prescalers and Flash settings).
133    */
134 }
135 
136 /**
137    * @brief  Update SystemCoreClock variable according to Clock Register Values.
138   *         The SystemCoreClock variable contains the core clock (HCLK), it can
139   *         be used by the user application to setup the SysTick timer or configure
140   *         other parameters.
141   *
142   * @note   Each time the core clock (HCLK) changes, this function must be called
143   *         to update SystemCoreClock variable value. Otherwise, any configuration
144   *         based on this variable will be incorrect.
145   *
146   * @note   - The system frequency computed by this function is not the real
147   *           frequency in the chip. It is calculated based on the predefined
148   *           constant and the selected clock source:
149   *
150   *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
151   *
152   *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
153   *
154   *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
155   *             or HSI_VALUE(*) multiplied/divided by the PLL factors.
156   *
157   *           - If SYSCLK source is HSI48, SystemCoreClock will contain the HSI48_VALUE(***)
158   *
159   *         (*) HSI_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default value
160   *             8 MHz) but the real value may vary depending on the variations
161   *             in voltage and temperature.
162   *
163   *         (**) HSE_VALUE is a constant defined in stm32f0xx_hal_conf.h file (its value
164   *              depends on the application requirements), user has to ensure that HSE_VALUE
165   *              is same as the real frequency of the crystal used. Otherwise, this function
166   *              may have wrong result.
167   *
168   *         (***) HSI48_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default value
169   *             48 MHz) but the real value may vary depending on the variations
170   *             in voltage and temperature.
171   *
172   *         - The result of this function could be not correct when using fractional
173   *           value for HSE crystal.
174   *
175   * @param  None
176   * @retval None
177   */
SystemCoreClockUpdate(void)178 void SystemCoreClockUpdate (void)
179 {
180   uint32_t tmp = 0, pllmull = 0, pllsource = 0, predivfactor = 0;
181 
182   /* Get SYSCLK source -------------------------------------------------------*/
183   tmp = RCC->CFGR & RCC_CFGR_SWS;
184 
185   switch (tmp)
186   {
187     case RCC_CFGR_SWS_HSI:  /* HSI used as system clock */
188       SystemCoreClock = HSI_VALUE;
189       break;
190     case RCC_CFGR_SWS_HSE:  /* HSE used as system clock */
191       SystemCoreClock = HSE_VALUE;
192       break;
193     case RCC_CFGR_SWS_PLL:  /* PLL used as system clock */
194       /* Get PLL clock source and multiplication factor ----------------------*/
195       pllmull = RCC->CFGR & RCC_CFGR_PLLMUL;
196       pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
197       pllmull = ( pllmull >> 18) + 2;
198       predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1;
199 
200       if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV)
201       {
202         /* HSE used as PLL clock source : SystemCoreClock = HSE/PREDIV * PLLMUL */
203         SystemCoreClock = (HSE_VALUE/predivfactor) * pllmull;
204       }
205 #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx)
206       else if (pllsource == RCC_CFGR_PLLSRC_HSI48_PREDIV)
207       {
208         /* HSI48 used as PLL clock source : SystemCoreClock = HSI48/PREDIV * PLLMUL */
209         SystemCoreClock = (HSI48_VALUE/predivfactor) * pllmull;
210       }
211 #endif /* STM32F042x6 || STM32F048xx || STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx */
212       else
213       {
214 #if defined(STM32F042x6) || defined(STM32F048xx)  || defined(STM32F070x6) \
215  || defined(STM32F078xx) || defined(STM32F071xB)  || defined(STM32F072xB) \
216  || defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx)  || defined(STM32F030xC)
217         /* HSI used as PLL clock source : SystemCoreClock = HSI/PREDIV * PLLMUL */
218         SystemCoreClock = (HSI_VALUE/predivfactor) * pllmull;
219 #else
220         /* HSI used as PLL clock source : SystemCoreClock = HSI/2 * PLLMUL */
221         SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
222 #endif /* STM32F042x6 || STM32F048xx || STM32F070x6 ||
223           STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB ||
224           STM32F091xC || STM32F098xx || STM32F030xC */
225 	  }
226       break;
227     default: /* HSI used as system clock */
228       SystemCoreClock = HSI_VALUE;
229       break;
230   }
231   /* Compute HCLK clock frequency ----------------*/
232   /* Get HCLK prescaler */
233   tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
234   /* HCLK clock frequency */
235   SystemCoreClock >>= tmp;
236 }
237 
238 /**
239   * @}
240   */
241 
242 /**
243   * @}
244   */
245 
246 /**
247   * @}
248   */
249 
250