1 /**
2   ******************************************************************************
3   * @file    system_stm32g0xx.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_stm32g0xx.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   *   After each device reset the HSI (8 MHz then 16 MHz) is used as system clock source.
22   *   Then SystemInit() function is called, in "startup_stm32g0xx.s" file, to
23   *   configure the system clock before to branch to main program.
24   *
25   *   This file configures the system clock as follows:
26   *=============================================================================
27   *-----------------------------------------------------------------------------
28   *        System Clock source                    | HSI
29   *-----------------------------------------------------------------------------
30   *        SYSCLK(Hz)                             | 16000000
31   *-----------------------------------------------------------------------------
32   *        HCLK(Hz)                               | 16000000
33   *-----------------------------------------------------------------------------
34   *        AHB Prescaler                          | 1
35   *-----------------------------------------------------------------------------
36   *        APB Prescaler                          | 1
37   *-----------------------------------------------------------------------------
38   *        HSI Division factor                    | 1
39   *-----------------------------------------------------------------------------
40   *        PLL_M                                  | 1
41   *-----------------------------------------------------------------------------
42   *        PLL_N                                  | 8
43   *-----------------------------------------------------------------------------
44   *        PLL_P                                  | 7
45   *-----------------------------------------------------------------------------
46   *        PLL_Q                                  | 2
47   *-----------------------------------------------------------------------------
48   *        PLL_R                                  | 2
49   *-----------------------------------------------------------------------------
50   *        Require 48MHz for RNG                  | Disabled
51   *-----------------------------------------------------------------------------
52   *=============================================================================
53   ******************************************************************************
54   * @attention
55   *
56   * Copyright (c) 2018-2021 STMicroelectronics.
57   * All rights reserved.
58   *
59   * This software is licensed under terms that can be found in the LICENSE file
60   * in the root directory of this software component.
61   * If no LICENSE file comes with this software, it is provided AS-IS.
62   *
63   ******************************************************************************
64   */
65 /** @addtogroup CMSIS
66   * @{
67   */
68 
69 /** @addtogroup stm32g0xx_system
70   * @{
71   */
72 
73 /** @addtogroup STM32G0xx_System_Private_Includes
74   * @{
75   */
76 
77 #include "stm32g0xx.h"
78 
79 #if !defined  (HSE_VALUE)
80 #define HSE_VALUE    (8000000UL)    /*!< Value of the External oscillator in Hz */
81 #endif /* HSE_VALUE */
82 
83 #if !defined  (HSI_VALUE)
84   #define HSI_VALUE  (16000000UL)   /*!< Value of the Internal oscillator in Hz*/
85 #endif /* HSI_VALUE */
86 
87 #if !defined  (LSI_VALUE)
88  #define LSI_VALUE   (32000UL)     /*!< Value of LSI in Hz*/
89 #endif /* LSI_VALUE */
90 
91 #if !defined  (LSE_VALUE)
92   #define LSE_VALUE  (32768UL)      /*!< Value of LSE in Hz*/
93 #endif /* LSE_VALUE */
94 
95 /**
96   * @}
97   */
98 
99 /** @addtogroup STM32G0xx_System_Private_TypesDefinitions
100   * @{
101   */
102 
103 /**
104   * @}
105   */
106 
107 /** @addtogroup STM32G0xx_System_Private_Defines
108   * @{
109   */
110 
111 /************************* Miscellaneous Configuration ************************/
112 /* Note: Following vector table addresses must be defined in line with linker
113          configuration. */
114 /*!< Uncomment the following line if you need to relocate the vector table
115      anywhere in Flash or Sram, else the vector table is kept at the automatic
116      remap of boot address selected */
117 /* #define USER_VECT_TAB_ADDRESS */
118 
119 #if defined(USER_VECT_TAB_ADDRESS)
120 /*!< Uncomment the following line if you need to relocate your vector Table
121      in Sram else user remap will be done in Flash. */
122 /* #define VECT_TAB_SRAM */
123 #if defined(VECT_TAB_SRAM)
124 #define VECT_TAB_BASE_ADDRESS   SRAM_BASE       /*!< Vector Table base address field.
125                                                      This value must be a multiple of 0x200. */
126 #define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table base offset field.
127                                                      This value must be a multiple of 0x200. */
128 #else
129 #define VECT_TAB_BASE_ADDRESS   FLASH_BASE      /*!< Vector Table base address field.
130                                                      This value must be a multiple of 0x200. */
131 #define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table base offset field.
132                                                      This value must be a multiple of 0x200. */
133 #endif /* VECT_TAB_SRAM */
134 #endif /* USER_VECT_TAB_ADDRESS */
135 /******************************************************************************/
136 /**
137   * @}
138   */
139 
140 /** @addtogroup STM32G0xx_System_Private_Macros
141   * @{
142   */
143 
144 /**
145   * @}
146   */
147 
148 /** @addtogroup STM32G0xx_System_Private_Variables
149   * @{
150   */
151   /* The SystemCoreClock variable is updated in three ways:
152       1) by calling CMSIS function SystemCoreClockUpdate()
153       2) by calling HAL API function HAL_RCC_GetHCLKFreq()
154       3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
155          Note: If you use this function to configure the system clock; then there
156                is no need to call the 2 first functions listed above, since SystemCoreClock
157                variable is updated automatically.
158   */
159   uint32_t SystemCoreClock = 16000000UL;
160 
161   const uint32_t AHBPrescTable[16UL] = {0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL, 6UL, 7UL, 8UL, 9UL};
162   const uint32_t APBPrescTable[8UL] =  {0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL};
163 
164 /**
165   * @}
166   */
167 
168 /** @addtogroup STM32G0xx_System_Private_FunctionPrototypes
169   * @{
170   */
171 
172 /**
173   * @}
174   */
175 
176 /** @addtogroup STM32G0xx_System_Private_Functions
177   * @{
178   */
179 
180 /**
181   * @brief  Setup the microcontroller system.
182   * @param  None
183   * @retval None
184   */
SystemInit(void)185 void SystemInit(void)
186 {
187   /* Configure the Vector Table location -------------------------------------*/
188 #if defined(USER_VECT_TAB_ADDRESS)
189   SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation */
190 #endif /* USER_VECT_TAB_ADDRESS */
191 }
192 
193 /**
194   * @brief  Update SystemCoreClock variable according to Clock Register Values.
195   *         The SystemCoreClock variable contains the core clock (HCLK), it can
196   *         be used by the user application to setup the SysTick timer or configure
197   *         other parameters.
198   *
199   * @note   Each time the core clock (HCLK) changes, this function must be called
200   *         to update SystemCoreClock variable value. Otherwise, any configuration
201   *         based on this variable will be incorrect.
202   *
203   * @note   - The system frequency computed by this function is not the real
204   *           frequency in the chip. It is calculated based on the predefined
205   *           constant and the selected clock source:
206   *
207   *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) / HSI division factor
208   *
209   *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
210   *
211   *           - If SYSCLK source is LSI, SystemCoreClock will contain the LSI_VALUE
212   *
213   *           - If SYSCLK source is LSE, SystemCoreClock will contain the LSE_VALUE
214   *
215   *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
216   *             or HSI_VALUE(*) multiplied/divided by the PLL factors.
217   *
218   *         (**) HSI_VALUE is a constant defined in stm32g0xx_hal_conf.h file (default value
219   *              16 MHz) but the real value may vary depending on the variations
220   *              in voltage and temperature.
221   *
222   *         (***) HSE_VALUE is a constant defined in stm32g0xx_hal_conf.h file (default value
223   *              8 MHz), user has to ensure that HSE_VALUE is same as the real
224   *              frequency of the crystal used. Otherwise, this function may
225   *              have wrong result.
226   *
227   *         - The result of this function could be not correct when using fractional
228   *           value for HSE crystal.
229   *
230   * @param  None
231   * @retval None
232   */
SystemCoreClockUpdate(void)233 void SystemCoreClockUpdate(void)
234 {
235   uint32_t tmp;
236   uint32_t pllvco;
237   uint32_t pllr;
238   uint32_t pllsource;
239   uint32_t pllm;
240   uint32_t hsidiv;
241 
242   /* Get SYSCLK source -------------------------------------------------------*/
243   switch (RCC->CFGR & RCC_CFGR_SWS)
244   {
245     case RCC_CFGR_SWS_0:                /* HSE used as system clock */
246       SystemCoreClock = HSE_VALUE;
247       break;
248 
249     case (RCC_CFGR_SWS_1 | RCC_CFGR_SWS_0):  /* LSI used as system clock */
250       SystemCoreClock = LSI_VALUE;
251       break;
252 
253     case RCC_CFGR_SWS_2:                /* LSE used as system clock */
254       SystemCoreClock = LSE_VALUE;
255       break;
256 
257     case RCC_CFGR_SWS_1:  /* PLL used as system clock */
258       /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
259          SYSCLK = PLL_VCO / PLLR
260          */
261       pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
262       pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1UL;
263 
264       if(pllsource == 0x03UL)           /* HSE used as PLL clock source */
265       {
266         pllvco = (HSE_VALUE / pllm);
267       }
268       else                              /* HSI used as PLL clock source */
269       {
270           pllvco = (HSI_VALUE / pllm);
271       }
272       pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
273       pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1UL);
274 
275       SystemCoreClock = pllvco/pllr;
276       break;
277 
278     case 0x00000000U:                   /* HSI used as system clock */
279     default:                            /* HSI used as system clock */
280       hsidiv = (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV))>> RCC_CR_HSIDIV_Pos));
281       SystemCoreClock = (HSI_VALUE/hsidiv);
282       break;
283   }
284   /* Compute HCLK clock frequency --------------------------------------------*/
285   /* Get HCLK prescaler */
286   tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
287   /* HCLK clock frequency */
288   SystemCoreClock >>= tmp;
289 }
290 
291 
292 /**
293   * @}
294   */
295 
296 /**
297   * @}
298   */
299 
300 /**
301   * @}
302   */
303