1 /**
2 ******************************************************************************
3 * @file system_hk32f0xx.c
4 * @version V1.0.1
5 * @date 2019-08-15
6 * @brief CMSIS Cortex-M0 Device Peripheral Access Layer System Source File.
7 * This file contains the system clock configuration for HK32F0xx devices,
8 * and is generated by the clock configuration tool
9 * HK32F0xx_Clock_Configuration_V1.0.1.xls
10 *
11 * 1. This file provides two functions and one global variable to be called from
12 * user application:
13 * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
14 * and Divider factors, AHB/APBx prescalers and Flash settings),
15 * depending on the configuration made in the clock xls tool.
16 * This function is called at startup just after reset and
17 * before branch to main program. This call is made inside
18 * the "startup_hk32f0xx.s" file.
19 *
20 * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
21 * by the user application to setup the SysTick
22 * timer or configure other parameters.
23 *
24 * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
25 * be called whenever the core clock is changed
26 * during program execution.
27 *
28 * 2. After each device reset the HSI (8 MHz Range) is used as system clock source.
29 * Then SystemInit() function is called, in "startup_hk32f0xx.s" file, to
30 * configure the system clock before to branch to main program.
31 *
32 * 3. If the system clock source selected by user fails to startup, the SystemInit()
33 * function will do nothing and HSI still used as system clock source. User can
34 * add some code to deal with this issue inside the SetSysClock() function.
35 *
36 * 4. The default value of HSE crystal is set to 8MHz, refer to "HSE_VALUE" define
37 * in "hk32f0xx.h" file. When HSE is used as system clock source, directly or
38 * through PLL, and you are using different crystal you have to adapt the HSE
39 * value to your own configuration.
40 *
41 * 5. This file configures the system clock as follows:
42 *=============================================================================
43 *=============================================================================
44 * System Clock source | PLL(HSE)
45 *-----------------------------------------------------------------------------
46 * SYSCLK(Hz) | 48000000
47 *-----------------------------------------------------------------------------
48 * HCLK(Hz) | 48000000
49 *-----------------------------------------------------------------------------
50 * AHB Prescaler | 1
51 *-----------------------------------------------------------------------------
52 * APB Prescaler | 1
53 *-----------------------------------------------------------------------------
54 * HSE Frequency(Hz) | 8000000
55 *----------------------------------------------------------------------------
56 * PLLMUL | 6
57 *-----------------------------------------------------------------------------
58 * PREDIV | 1
59 *-----------------------------------------------------------------------------
60 * Flash Latency(WS) | 1
61 *-----------------------------------------------------------------------------
62 * Prefetch Buffer | ON
63 *-----------------------------------------------------------------------------
64 ******************************************************************************
65 */
66
67 /** @addtogroup CMSIS
68 * @{
69 */
70
71 /** @addtogroup HK32f0xx_system
72 * @{
73 */
74
75 /** @addtogroup HK32F0xx_System_Private_Includes
76 * @{
77 */
78
79 #include "hk32f0xx.h"
80
81 /**
82 * @}
83 */
84
85 /** @addtogroup HK32F0xx_System_Private_TypesDefinitions
86 * @{
87 */
88
89 /**
90 * @}
91 */
92
93 /** @addtogroup HK32F0xx_System_Private_Defines
94 * @{
95 */
96 /**
97 * @}
98 */
99
100 /** @addtogroup HK32F0xx_System_Private_Macros
101 * @{
102 */
103
104 /**
105 * @}
106 */
107
108 /** @addtogroup HK32F0xx_System_Private_Variables
109 * @{
110 */
111 uint32_t SystemCoreClock = 48000000;
112 __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
113
114 /**
115 * @}
116 */
117
118 /** @addtogroup HK32F0xx_System_Private_FunctionPrototypes
119 * @{
120 */
121
122 static void SetSysClock(void);
123
124 /**
125 * @}
126 */
127
128 /** @addtogroup HK32F0xx_System_Private_Functions
129 * @{
130 */
131
132 /**
133 * @brief Setup the microcontroller system.
134 * Initialize the Embedded Flash Interface, the PLL and update the
135 * SystemCoreClock variable.
136 * @param None
137 * @retval None
138 */
SystemInit(void)139 void SystemInit (void)
140 {
141 /* Set HSION bit */
142 RCC->CR |= (uint32_t)0x00000001;
143
144 /* Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE and MCOSEL[2:0] bits */
145 RCC->CFGR &= (uint32_t)0xF8FFB80C;
146
147 /* Reset HSEON, CSSON and PLLON bits */
148 RCC->CR &= (uint32_t)0xFEF6FFFF;
149
150 /* Reset HSEBYP bit */
151 RCC->CR &= (uint32_t)0xFFFBFFFF;
152
153 /* Reset PLLSRC, PLLXTPRE and PLLMUL[3:0] bits */
154 RCC->CFGR &= (uint32_t)0xFFC0FFFF;
155
156 /* Reset PREDIV1[3:0] bits */
157 RCC->CFGR2 &= (uint32_t)0xFFFFFFF0;
158
159 /* Reset USARTSW[1:0], I2CSW, CECSW and ADCSW bits */
160 RCC->CFGR3 &= (uint32_t)0xFFFFFEAC;
161
162 /* Reset HSI14 bit */
163 RCC->CR2 &= (uint32_t)0xFFFFFFFE;
164
165 /* Disable all interrupts */
166 RCC->CIR = 0x00000000;
167
168 /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */
169 SetSysClock();
170 }
171
172 /**
173 * @brief Update SystemCoreClock according to Clock Register Values
174 * The SystemCoreClock variable contains the core clock (HCLK), it can
175 * be used by the user application to setup the SysTick timer or configure
176 * other parameters.
177 *
178 * @note Each time the core clock (HCLK) changes, this function must be called
179 * to update SystemCoreClock variable value. Otherwise, any configuration
180 * based on this variable will be incorrect.
181 *
182 * @note - The system frequency computed by this function is not the real
183 * frequency in the chip. It is calculated based on the predefined
184 * constant and the selected clock source:
185 *
186 * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
187 *
188 * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
189 *
190 * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
191 * or HSI_VALUE(*) multiplied/divided by the PLL factors.
192 *
193 * (*) HSI_VALUE is a constant defined in HK32f0xx.h file (default value
194 * 8 MHz) but the real value may vary depending on the variations
195 * in voltage and temperature.
196 *
197 * (**) HSE_VALUE is a constant defined in HK32f0xx.h file (default value
198 * 8 MHz), user has to ensure that HSE_VALUE is same as the real
199 * frequency of the crystal used. Otherwise, this function may
200 * have wrong result.
201 *
202 * - The result of this function could be not correct when using fractional
203 * value for HSE crystal.
204 * @param None
205 * @retval None
206 */
SystemCoreClockUpdate(void)207 void SystemCoreClockUpdate (void)
208 {
209 uint32_t tmp = 0, pllmull = 0, pllsource = 0, prediv1factor = 0;
210
211 /* Get SYSCLK source -------------------------------------------------------*/
212 tmp = RCC->CFGR & RCC_CFGR_SWS;
213
214 switch (tmp)
215 {
216 case 0x00: /* HSI used as system clock */
217 SystemCoreClock = HSI_VALUE;
218 break;
219 case 0x04: /* HSE used as system clock */
220 SystemCoreClock = HSE_VALUE;
221 break;
222 case 0x08: /* PLL used as system clock */
223 /* Get PLL clock source and multiplication factor ----------------------*/
224 pllmull = RCC->CFGR & RCC_CFGR_PLLMUL;
225 pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
226 pllmull = ( pllmull >> 18) + 2;
227
228 if (pllsource == 0x00)
229 {
230 /* HSI oscillator clock divided by 2 selected as PLL clock entry */
231 SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
232 }
233 else
234 {
235 prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV_1) + 1;
236 /* HSE oscillator clock selected as PREDIV1 clock entry */
237 SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
238 }
239 break;
240 default: /* HSI used as system clock */
241 SystemCoreClock = HSI_VALUE;
242 break;
243 }
244 /* Compute HCLK clock frequency ----------------*/
245 /* Get HCLK prescaler */
246 tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
247 /* HCLK clock frequency */
248 SystemCoreClock >>= tmp;
249 }
250
251 /**
252 * @brief Configures the System clock frequency, AHB/APBx prescalers and Flash
253 * settings.
254 * @note This function should be called only once the RCC clock configuration
255 * is reset to the default reset state (done in SystemInit() function).
256 * @param None
257 * @retval None
258 */
SetSysClock(void)259 static void SetSysClock(void)
260 {
261 __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
262
263 /******************************************************************************/
264 /* PLL (clocked by HSE) used as System clock source */
265 /******************************************************************************/
266
267 /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/
268 *(uint32_t *)0x400210e0 |= 0x00060000;
269
270 /* Enable HSE */
271 RCC->CR |= ((uint32_t)RCC_CR_HSEON);
272
273 /* Wait till HSE is ready and if Time out is reached exit */
274 do
275 {
276 HSEStatus = RCC->CR & RCC_CR_HSERDY;
277 StartUpCounter++;
278 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
279
280 if ((RCC->CR & RCC_CR_HSERDY) != RESET)
281 {
282 HSEStatus = (uint32_t)0x01;
283 }
284 else
285 {
286 HSEStatus = (uint32_t)0x00;
287 }
288
289 if (HSEStatus == (uint32_t)0x01)
290 {
291 /* Enable Prefetch Buffer and set Flash Latency */
292 FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
293
294 /* HCLK = SYSCLK */
295 RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
296
297 /* PCLK = HCLK */
298 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1;
299
300 /* PLL configuration */
301 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL));
302 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE_PREDIV | RCC_CFGR_PLLXTPRE_HSE_PREDIV_DIV1 | RCC_CFGR_PLLMUL6 );
303
304 /* Enable PLL */
305 RCC->CR |= RCC_CR_PLLON;
306
307 /* Wait till PLL is ready */
308 while((RCC->CR & RCC_CR_PLLRDY) == 0)
309 {
310 }
311
312 /* Select PLL as system clock source */
313 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
314 RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
315
316 /* Wait till PLL is used as system clock source */
317 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)
318 {
319 }
320 }
321 else
322 { /* If HSE fails to start-up, the application will have wrong clock
323 configuration. User can add here some code to deal with this error */
324 }
325 }
326
327
328