1 /*********************COPYRIGHT(C) 2019 WCH. A11 rights reserved***********************
2 * File Name : ch32f10x_system.c
3 * Author : WCH
4 * Version : V1.0.0
5 * Date : 2019/10/15
6 * Description : CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
7 ****************************************************************************************/
8 #include "ch32f10x.h"
9
10 /*
11 * Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after
12 * reset the HSI is used as SYSCLK source).
13 * If none of the define below is enabled, the HSI is used as System clock source.
14 */
15 // #define SYSCLK_FREQ_HSE HSE_VALUE
16 /* #define SYSCLK_FREQ_24MHz 24000000 */
17 // #define SYSCLK_FREQ_48MHz 48000000
18 /* #define SYSCLK_FREQ_56MHz 56000000 */
19 #define SYSCLK_FREQ_72MHz 72000000
20
21
22 /* Uncomment the following line if you need to relocate your vector Table in Internal SRAM */
23 /* #define VECT_TAB_SRAM */
24
25 /* Vector Table base offset field This value must be a multiple of 0x200 */
26 #define VECT_TAB_OFFSET 0x0
27
28
29 /* Clock Definitions */
30 #ifdef SYSCLK_FREQ_HSE
31 uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /*!< System Clock Frequency (Core Clock) */
32 #elif defined SYSCLK_FREQ_24MHz
33 uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /*!< System Clock Frequency (Core Clock) */
34 #elif defined SYSCLK_FREQ_48MHz
35 uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /*!< System Clock Frequency (Core Clock) */
36 #elif defined SYSCLK_FREQ_56MHz
37 uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /*!< System Clock Frequency (Core Clock) */
38 #elif defined SYSCLK_FREQ_72MHz
39 uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */
40 #else /*!< HSI Selected as System Clock source */
41 uint32_t SystemCoreClock = HSI_VALUE; /*!< System Clock Frequency (Core Clock) */
42 #endif
43
44 __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
45
46
47 /* ch32f10x_system_private_functionprototypes */
48 static void SetSysClock(void);
49
50 #ifdef SYSCLK_FREQ_HSE
51 static void SetSysClockToHSE(void);
52 #elif defined SYSCLK_FREQ_24MHz
53 static void SetSysClockTo24(void);
54 #elif defined SYSCLK_FREQ_48MHz
55 static void SetSysClockTo48(void);
56 #elif defined SYSCLK_FREQ_56MHz
57 static void SetSysClockTo56(void);
58 #elif defined SYSCLK_FREQ_72MHz
59 static void SetSysClockTo72(void);
60 #endif
61
62 #ifdef DATA_IN_ExtSRAM
63 static void SystemInit_ExtMemCtl(void);
64 #endif /* DATA_IN_ExtSRAM */
65
66
67 /******************************************************************************************
68 * Function Name : SystemInit
69 * Description : Setup the microcontroller system Initialize the Embedded Flash Interface,
70 * the PLL and update the SystemCoreClock variable.
71 * Input : None
72 * Return : None
73 *******************************************************************************************/
SystemInit(void)74 void SystemInit (void)
75 {
76 RCC->CTLR |= (uint32_t)0x00000001;
77 RCC->CFGR0 &= (uint32_t)0xF8FF0000;
78 RCC->CTLR &= (uint32_t)0xFEF6FFFF;
79 RCC->CTLR &= (uint32_t)0xFFFBFFFF;
80 RCC->CFGR0 &= (uint32_t)0xFF80FFFF;
81 RCC->INTR = 0x009F0000;
82 SetSysClock();
83
84 #ifdef VECT_TAB_SRAM
85 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
86 #else
87 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
88 #endif
89 }
90
91
92 /******************************************************************************************
93 * Function Name : SystemCoreClockUpdate
94 * Description : Update SystemCoreClock variable according to Clock Register Values.
95 * Input : None
96 * Return : None
97 *******************************************************************************************/
SystemCoreClockUpdate(void)98 void SystemCoreClockUpdate (void)
99 {
100 uint32_t tmp = 0, pllmull = 0, pllsource = 0;
101
102 tmp = RCC->CFGR0 & RCC_SWS;
103
104 switch (tmp)
105 {
106 case 0x00:
107 SystemCoreClock = HSI_VALUE;
108 break;
109 case 0x04:
110 SystemCoreClock = HSE_VALUE;
111 break;
112 case 0x08:
113 pllmull = RCC->CFGR0 & RCC_PLLMULL;
114 pllsource = RCC->CFGR0 & RCC_PLLSRC;
115 pllmull = ( pllmull >> 18) + 2;
116 if (pllsource == 0x00)
117 {
118 SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
119 }
120 else
121 {
122 if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET)
123 {
124 SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
125 }
126 else
127 {
128 SystemCoreClock = HSE_VALUE * pllmull;
129 }
130 }
131 break;
132 default:
133 SystemCoreClock = HSI_VALUE;
134 break;
135 }
136
137 tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)];
138 SystemCoreClock >>= tmp;
139 }
140
141
142 /******************************************************************************************
143 * Function Name : SetSysClock
144 * Description : Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
145 * Input : None
146 * Return : None
147 *******************************************************************************************/
SetSysClock(void)148 static void SetSysClock(void)
149 {
150 #ifdef SYSCLK_FREQ_HSE
151 SetSysClockToHSE();
152 #elif defined SYSCLK_FREQ_24MHz
153 SetSysClockTo24();
154 #elif defined SYSCLK_FREQ_48MHz
155 SetSysClockTo48();
156 #elif defined SYSCLK_FREQ_56MHz
157 SetSysClockTo56();
158 #elif defined SYSCLK_FREQ_72MHz
159 SetSysClockTo72();
160 #endif
161
162 /* If none of the define above is enabled, the HSI is used as System clock
163 * source (default after reset)
164 */
165 }
166
167
168 #ifdef DATA_IN_ExtSRAM
169
170 /******************************************************************************************
171 * Function Name : SystemInit_ExtMemCtl
172 * Description : Setup the external memory controller.
173 * Input : None
174 * Return : None
175 *******************************************************************************************/
SystemInit_ExtMemCtl(void)176 void SystemInit_ExtMemCtl(void)
177 {
178 RCC->AHBENR = 0x00000114;
179 RCC->APB2ENR = 0x000001E0;
180
181 GPIOD->CRL = 0x44BB44BB;
182 GPIOD->CRH = 0xBBBBBBBB;
183
184 GPIOE->CRL = 0xB44444BB;
185 GPIOE->CRH = 0xBBBBBBBB;
186
187 GPIOF->CRL = 0x44BBBBBB;
188 GPIOF->CRH = 0xBBBB4444;
189
190 GPIOG->CRL = 0x44BBBBBB;
191 GPIOG->CRH = 0x44444B44;
192
193 FSMC_Bank1->BTCR[4] = 0x00001011;
194 FSMC_Bank1->BTCR[5] = 0x00000200;
195 }
196 #endif /* DATA_IN_ExtSRAM */
197
198
199 #ifdef SYSCLK_FREQ_HSE
200
201 /******************************************************************************************
202 * Function Name : SetSysClockToHSE
203 * Description : elects HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers.
204 * Input : None
205 * Return : None
206 *******************************************************************************************/
SetSysClockToHSE(void)207 static void SetSysClockToHSE(void)
208 {
209 __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
210
211
212 RCC->CTLR |= ((uint32_t)RCC_HSEON);
213
214 /* Wait till HSE is ready and if Time out is reached exit */
215 do
216 {
217 HSEStatus = RCC->CTLR & RCC_HSERDY;
218 StartUpCounter++;
219 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
220
221 if ((RCC->CTLR & RCC_HSERDY) != RESET)
222 {
223 HSEStatus = (uint32_t)0x01;
224 }
225 else
226 {
227 HSEStatus = (uint32_t)0x00;
228 }
229
230 if (HSEStatus == (uint32_t)0x01)
231 {
232 FLASH->ACTLR |= FLASH_ACTLR_PRFTBE;
233 /* Flash 0 wait state */
234 FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY);
235 FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_0;
236
237 /* HCLK = SYSCLK */
238 RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
239 /* PCLK2 = HCLK */
240 RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
241 /* PCLK1 = HCLK */
242 RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
243
244 /* Select HSE as system clock source */
245 RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
246 RCC->CFGR0 |= (uint32_t)RCC_SW_HSE;
247
248 /* Wait till HSE is used as system clock source */
249 while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04)
250 {
251 }
252 }
253 else
254 {
255 /* If HSE fails to start-up, the application will have wrong clock
256 * configuration. User can add here some code to deal with this error
257 */
258 }
259 }
260
261 #elif defined SYSCLK_FREQ_24MHz
262
263 /******************************************************************************************
264 * Function Name : SetSysClockTo24
265 * Description : Sets System clock frequency to 24MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
266 * Input : None
267 * Return : None
268 *******************************************************************************************/
SetSysClockTo24(void)269 static void SetSysClockTo24(void)
270 {
271 __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
272
273 RCC->CTLR |= ((uint32_t)RCC_HSEON);
274
275 /* Wait till HSE is ready and if Time out is reached exit */
276 do
277 {
278 HSEStatus = RCC->CTLR & RCC_HSERDY;
279 StartUpCounter++;
280 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
281
282 if ((RCC->CTLR & RCC_HSERDY) != RESET)
283 {
284 HSEStatus = (uint32_t)0x01;
285 }
286 else
287 {
288 HSEStatus = (uint32_t)0x00;
289 }
290 if (HSEStatus == (uint32_t)0x01)
291 {
292 /* Enable Prefetch Buffer */
293 FLASH->ACTLR |= FLASH_ACTLR_PRFTBE;
294
295 /* Flash 0 wait state */
296 FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY);
297 FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_0;
298
299 /* HCLK = SYSCLK */
300 RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
301 /* PCLK2 = HCLK */
302 RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
303 /* PCLK1 = HCLK */
304 RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
305
306 RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
307 RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL3);
308 /* Enable PLL */
309 RCC->CTLR |= RCC_PLLON;
310
311 /* Wait till PLL is ready */
312 while((RCC->CTLR & RCC_PLLRDY) == 0)
313 {
314 }
315 /* Select PLL as system clock source */
316 RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
317 RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
318 /* Wait till PLL is used as system clock source */
319 while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
320 {
321 }
322 }
323 else
324 {
325 /* If HSE fails to start-up, the application will have wrong clock
326 * configuration. User can add here some code to deal with this error
327 */
328 }
329 }
330
331
332 #elif defined SYSCLK_FREQ_48MHz
333
334 /******************************************************************************************
335 * Function Name : SetSysClockTo48
336 * Description : Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
337 * Input : None
338 * Return : None
339 *******************************************************************************************/
SetSysClockTo48(void)340 static void SetSysClockTo48(void)
341 {
342 __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
343
344
345 RCC->CTLR |= ((uint32_t)RCC_HSEON);
346 /* Wait till HSE is ready and if Time out is reached exit */
347 do
348 {
349 HSEStatus = RCC->CTLR & RCC_HSERDY;
350 StartUpCounter++;
351 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
352
353 if ((RCC->CTLR & RCC_HSERDY) != RESET)
354 {
355 HSEStatus = (uint32_t)0x01;
356 }
357 else
358 {
359 HSEStatus = (uint32_t)0x00;
360 }
361
362 if (HSEStatus == (uint32_t)0x01)
363 {
364 /* Enable Prefetch Buffer */
365 FLASH->ACTLR |= FLASH_ACTLR_PRFTBE;
366
367 /* Flash 1 wait state */
368 FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY);
369 FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1;
370
371 /* HCLK = SYSCLK */
372 RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
373 /* PCLK2 = HCLK */
374 RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
375 /* PCLK1 = HCLK */
376 RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
377
378 /* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */
379 RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
380 RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL6);
381
382 /* Enable PLL */
383 RCC->CTLR |= RCC_PLLON;
384 /* Wait till PLL is ready */
385 while((RCC->CTLR & RCC_PLLRDY) == 0)
386 {
387 }
388 /* Select PLL as system clock source */
389 RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
390 RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
391 /* Wait till PLL is used as system clock source */
392 while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
393 {
394 }
395 }
396 else
397 {
398 /*
399 * If HSE fails to start-up, the application will have wrong clock
400 * configuration. User can add here some code to deal with this error
401 */
402 }
403 }
404
405 #elif defined SYSCLK_FREQ_56MHz
406
407 /******************************************************************************************
408 * Function Name : SetSysClockTo56
409 * Description : Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
410 * Input : None
411 * Return : None
412 *******************************************************************************************/
SetSysClockTo56(void)413 static void SetSysClockTo56(void)
414 {
415 __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
416
417 RCC->CTLR |= ((uint32_t)RCC_HSEON);
418
419 /* Wait till HSE is ready and if Time out is reached exit */
420 do
421 {
422 HSEStatus = RCC->CTLR & RCC_HSERDY;
423 StartUpCounter++;
424 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
425
426 if ((RCC->CTLR & RCC_HSERDY) != RESET)
427 {
428 HSEStatus = (uint32_t)0x01;
429 }
430 else
431 {
432 HSEStatus = (uint32_t)0x00;
433 }
434
435 if (HSEStatus == (uint32_t)0x01)
436 {
437 /* Enable Prefetch Buffer */
438 FLASH->ACTLR |= FLASH_ACTLR_PRFTBE;
439
440 /* Flash 2 wait state */
441 FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY);
442 FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_2;
443
444 /* HCLK = SYSCLK */
445 RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
446 /* PCLK2 = HCLK */
447 RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
448 /* PCLK1 = HCLK */
449 RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
450
451 /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */
452 RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
453 RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL7);
454 /* Enable PLL */
455 RCC->CTLR |= RCC_PLLON;
456 /* Wait till PLL is ready */
457 while((RCC->CTLR & RCC_PLLRDY) == 0)
458 {
459 }
460
461 /* Select PLL as system clock source */
462 RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
463 RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
464 /* Wait till PLL is used as system clock source */
465 while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
466 {
467 }
468 }
469 else
470 {
471 /*
472 * If HSE fails to start-up, the application will have wrong clock
473 * configuration. User can add here some code to deal with this error
474 */
475 }
476 }
477
478 #elif defined SYSCLK_FREQ_72MHz
479
480 /******************************************************************************************
481 * Function Name : SetSysClockTo72
482 * Description : Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
483 * Input : None
484 * Return : None
485 *******************************************************************************************/
SetSysClockTo72(void)486 static void SetSysClockTo72(void)
487 {
488 __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
489
490 RCC->CTLR |= ((uint32_t)RCC_HSEON);
491
492 /* Wait till HSE is ready and if Time out is reached exit */
493 do
494 {
495 HSEStatus = RCC->CTLR & RCC_HSERDY;
496 StartUpCounter++;
497 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
498
499 if ((RCC->CTLR & RCC_HSERDY) != RESET)
500 {
501 HSEStatus = (uint32_t)0x01;
502 }
503 else
504 {
505 HSEStatus = (uint32_t)0x00;
506 }
507
508 if (HSEStatus == (uint32_t)0x01)
509 {
510 /* Enable Prefetch Buffer */
511 FLASH->ACTLR |= FLASH_ACTLR_PRFTBE;
512
513 /* Flash 2 wait state */
514 FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY);
515 FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_2;
516
517 /* HCLK = SYSCLK */
518 RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
519 /* PCLK2 = HCLK */
520 RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
521 /* PCLK1 = HCLK */
522 RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
523
524 /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
525 RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
526 RCC_PLLMULL));
527 RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL9);
528 /* Enable PLL */
529 RCC->CTLR |= RCC_PLLON;
530 /* Wait till PLL is ready */
531 while((RCC->CTLR & RCC_PLLRDY) == 0)
532 {
533 }
534 /* Select PLL as system clock source */
535 RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
536 RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
537 /* Wait till PLL is used as system clock source */
538 while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
539 {
540 }
541 }
542 else
543 {
544 /*
545 * If HSE fails to start-up, the application will have wrong clock
546 * configuration. User can add here some code to deal with this error
547 */
548 }
549 }
550 #endif
551
552
553
554
555