1 /**
2 ******************************************************************************
3 * @file system_stm32c0xx.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_stm32c0xx.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 * @attention
23 *
24 * Copyright (c) 2022 STMicroelectronics.
25 * All rights reserved.
26 *
27 * This software is licensed under terms that can be found in the LICENSE file
28 * in the root directory of this software component.
29 * If no LICENSE file comes with this software, it is provided AS-IS.
30 *
31 ******************************************************************************
32 */
33
34 /** @addtogroup CMSIS
35 * @{
36 */
37
38 /** @addtogroup stm32c0xx_system
39 * @{
40 */
41
42 /** @addtogroup STM32C0xx_System_Private_Includes
43 * @{
44 */
45
46 #include "stm32c0xx.h"
47
48 #if !defined (HSE_VALUE)
49 #define HSE_VALUE (48000000UL) /*!< Value of the External oscillator in Hz */
50 #endif /* HSE_VALUE */
51
52 #if !defined (HSI_VALUE)
53 #define HSI_VALUE (48000000UL) /*!< Value of the Internal oscillator in Hz*/
54 #endif /* HSI_VALUE */
55
56 #if !defined (LSI_VALUE)
57 #define LSI_VALUE (32000UL) /*!< Value of LSI in Hz*/
58 #endif /* LSI_VALUE */
59
60 #if !defined (LSE_VALUE)
61 #define LSE_VALUE (32768UL) /*!< Value of LSE in Hz*/
62 #endif /* LSE_VALUE */
63
64 #if defined(RCC_HSI48_SUPPORT)
65 #if !defined (HSI48_VALUE)
66 #define HSI48_VALUE 48000000U /*!< Value of the HSI48 oscillator in Hz */
67 #endif /* HSI48_VALUE */
68 #endif /* RCC_HSI48_SUPPORT */
69
70 /**
71 * @}
72 */
73
74 /** @addtogroup STM32C0xx_System_Private_TypesDefinitions
75 * @{
76 */
77
78 /**
79 * @}
80 */
81
82 /** @addtogroup STM32C0xx_System_Private_Defines
83 * @{
84 */
85
86 /************************* Miscellaneous Configuration ************************/
87 /*!< Uncomment the following line if you need to relocate your vector Table in
88 Internal SRAM. */
89 //#define VECT_TAB_SRAM
90 #define VECT_TAB_OFFSET 0x0U /*!< Vector Table base offset field.
91 This value must be a multiple of 0x100. */
92 /******************************************************************************/
93 /**
94 * @}
95 */
96
97 /** @addtogroup STM32C0xx_System_Private_Macros
98 * @{
99 */
100
101 /**
102 * @}
103 */
104
105 /** @addtogroup STM32C0xx_System_Private_Variables
106 * @{
107 */
108 /* The SystemCoreClock variable is updated in three ways:
109 1) by calling CMSIS function SystemCoreClockUpdate()
110 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
111 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
112 Note: If you use this function to configure the system clock; then there
113 is no need to call the 2 first functions listed above, since SystemCoreClock
114 variable is updated automatically.
115 */
116 uint32_t SystemCoreClock = 12000000UL;
117
118 const uint32_t AHBPrescTable[16UL] = {0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL, 6UL, 7UL, 8UL, 9UL};
119 const uint32_t APBPrescTable[8UL] = {0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL};
120
121 /**
122 * @}
123 */
124
125 /** @addtogroup STM32C0xx_System_Private_FunctionPrototypes
126 * @{
127 */
128
129 /**
130 * @}
131 */
132
133 /** @addtogroup STM32C0xx_System_Private_Functions
134 * @{
135 */
136
137 /**
138 * @brief Setup the microcontroller system.
139 * @param None
140 * @retval None
141 */
SystemInit(void)142 void SystemInit(void)
143 {
144
145 /* Configure the Vector Table location add offset address ------------------*/
146 #ifdef VECT_TAB_SRAM
147 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
148 #else
149 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
150 #endif
151 }
152
153 /**
154 * @brief Update SystemCoreClock variable according to Clock Register Values.
155 * The SystemCoreClock variable contains the core clock (HCLK), it can
156 * be used by the user application to setup the SysTick timer or configure
157 * other parameters.
158 *
159 * @note Each time the core clock (HCLK) changes, this function must be called
160 * to update SystemCoreClock variable value. Otherwise, any configuration
161 * based on this variable will be incorrect.
162 *
163 * @note - The system frequency computed by this function is not the real
164 * frequency in the chip. It is calculated based on the predefined
165 * constant and the selected clock source:
166 *
167 * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) / HSI division factor
168 *
169 * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
170 *
171 * - If SYSCLK source is LSI, SystemCoreClock will contain the LSI_VALUE
172 *
173 * - If SYSCLK source is LSE, SystemCoreClock will contain the LSE_VALUE
174 *
175 * (**) HSI_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value
176 * 48 MHz) but the real value may vary depending on the variations
177 * in voltage and temperature.
178 *
179 * (***) HSE_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value
180 * 48 MHz), user has to ensure that HSE_VALUE is same as the real
181 * frequency of the crystal used. Otherwise, this function may
182 * have wrong result.
183 *
184 * - The result of this function could be not correct when using fractional
185 * value for HSE crystal.
186 *
187 * @param None
188 * @retval None
189 */
SystemCoreClockUpdate(void)190 void SystemCoreClockUpdate(void)
191 {
192 uint32_t tmp;
193 uint32_t hsidiv;
194 uint32_t sysdiv;
195 #if defined(RCC_CR_SYSDIV)
196 sysdiv = (uint32_t)(((RCC->CR & RCC_CR_SYSDIV) >> RCC_CR_SYSDIV_Pos) + 1U);
197 #else
198 sysdiv = 1U;
199 #endif /* RCC_CR_SYSDIV */
200
201 /* Get SYSCLK source -------------------------------------------------------*/
202 switch (RCC->CFGR & RCC_CFGR_SWS)
203 {
204 case RCC_CFGR_SWS_0: /* HSE used as system clock */
205 SystemCoreClock = (HSE_VALUE / sysdiv);
206 break;
207
208 #if defined(RCC_HSI48_SUPPORT)
209 case RCC_CFGR_SW_1: /* HSI48 used as system clock */
210 SystemCoreClock = (HSI48_VALUE / sysdiv);
211 break;
212 #endif /* RCC_HSI48_SUPPORT */
213
214 case (RCC_CFGR_SWS_1 | RCC_CFGR_SWS_0): /* LSI used as system clock */
215 SystemCoreClock = (LSI_VALUE / sysdiv);
216 break;
217
218 case RCC_CFGR_SWS_2: /* LSE used as system clock */
219 SystemCoreClock = (LSE_VALUE / sysdiv);
220 break;
221
222 case 0x00000000U: /* HSI used as system clock */
223 default: /* HSI used as system clock */
224 hsidiv = (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV))>> RCC_CR_HSIDIV_Pos));
225 SystemCoreClock = ((HSI_VALUE / sysdiv) / hsidiv);
226 break;
227 }
228 /* Compute HCLK clock frequency --------------------------------------------*/
229 /* Get HCLK prescaler */
230 tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
231 /* HCLK clock frequency */
232 SystemCoreClock >>= tmp;
233 }
234
235
236 /**
237 * @}
238 */
239
240 /**
241 * @}
242 */
243
244 /**
245 * @}
246 */
247