1 /*!
2 * @file system_apm32e10x.c
3 *
4 * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File
5 *
6 * @version V1.0.2
7 *
8 * @date 2022-12-31
9 *
10 * @attention
11 *
12 * Copyright (C) 2021-2023 Geehy Semiconductor
13 *
14 * You may not use this file except in compliance with the
15 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16 *
17 * The program is only for reference, which is distributed in the hope
18 * that it will be useful and instructional for customers to develop
19 * their software. Unless required by applicable law or agreed to in
20 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23 * and limitations under the License.
24 */
25
26 #include "apm32e10x.h"
27
28 /** @addtogroup CMSIS
29 @{
30 */
31
32 /** @addtogroup APM32E10x_System
33 * @brief APM32E10x system configuration
34 @{
35 */
36
37 /** @defgroup System_Macros
38 @{
39 */
40
41
42 //#define SYSTEM_CLOCK_HSE HSE_VALUE
43 //#define SYSTEM_CLOCK_24MHz (24000000)
44 //#define SYSTEM_CLOCK_36MHz (36000000)
45 //#define SYSTEM_CLOCK_48MHz (48000000)
46 //#define SYSTEM_CLOCK_56MHz (56000000)
47 #define SYSTEM_CLOCK_72MHz (72000000)
48 //#define SYSTEM_CLOCK_96MHz (96000000)
49 //#define SYSTEM_CLOCK_120MHz (120000000)
50
51 /* #define VECT_TAB_SRAM */
52 #define VECT_TAB_OFFSET 0x00
53
54 /**@} end of group System_Macros */
55
56 /** @defgroup System_Variables
57 @{
58 */
59
60 #ifdef SYSTEM_CLOCK_HSE
61 uint32_t SystemCoreClock = SYSTEM_CLOCK_HSE;
62 #elif defined SYSTEM_CLOCK_24MHz
63 uint32_t SystemCoreClock = SYSTEM_CLOCK_24MHz;
64 #elif defined SYSTEM_CLOCK_36MHz
65 uint32_t SystemCoreClock = SYSTEM_CLOCK_36MHz;
66 #elif defined SYSTEM_CLOCK_48MHz
67 uint32_t SystemCoreClock = SYSTEM_CLOCK_48MHz;
68 #elif defined SYSTEM_CLOCK_56MHz
69 uint32_t SystemCoreClock = SYSTEM_CLOCK_56MHz;
70 #elif defined SYSTEM_CLOCK_72MHz
71 uint32_t SystemCoreClock = SYSTEM_CLOCK_72MHz;
72 #elif defined SYSTEM_CLOCK_96MHz
73 uint32_t SystemCoreClock = SYSTEM_CLOCK_96MHz;
74 #else
75 uint32_t SystemCoreClock = SYSTEM_CLOCK_120MHz;
76 #endif
77
78 /**@} end of group System_Variables */
79
80 /** @defgroup System_Functions
81 @{
82 */
83
84 static void SystemClockConfig(void);
85
86 #ifdef SYSTEM_CLOCK_HSE
87 static void SystemClockHSE(void);
88 #elif defined SYSTEM_CLOCK_24MHz
89 static void SystemClock24M(void);
90 #elif defined SYSTEM_CLOCK_36MHz
91 static void SystemClock36M(void);
92 #elif defined SYSTEM_CLOCK_48MHz
93 static void SystemClock48M(void);
94 #elif defined SYSTEM_CLOCK_56MHz
95 static void SystemClock56M(void);
96 #elif defined SYSTEM_CLOCK_72MHz
97 static void SystemClock72M(void);
98 #elif defined SYSTEM_CLOCK_96MHz
99 static void SystemClock96M(void);
100 #elif defined SYSTEM_CLOCK_120MHz
101 static void SystemClock120M(void);
102 #endif
103
104 /*!
105 * @brief Setup the microcontroller system
106 *
107 * @param None
108 *
109 * @retval None
110 *
111 * @note
112 */
SystemInit(void)113 void SystemInit (void)
114 {
115 /** Set HSIEN bit */
116 RCM->CTRL_B.HSIEN = BIT_SET;
117 /** Reset SCLKSW, AHBPSC, APB1PSC, APB2PSC, ADCPSC and MCOSEL bits */
118 RCM->CFG &= (uint32_t)0xF8FF0000;
119 /** Reset HSEEN, CSSEN and PLLEN bits */
120 RCM->CTRL &= (uint32_t)0xFEF6FFFF;
121 /** Reset HSEBCFG bit */
122 RCM->CTRL_B.HSEBCFG = BIT_RESET;
123 /** Reset PLLSRCSEL, PLLHSEPSC, PLLMULCFG and USBDIV bits */
124 RCM->CFG &= (uint32_t)0xFF80FFFF;
125 /** Disable all interrupts and clear pending bits */
126 RCM->INT = 0x009F0000;
127
128 SystemClockConfig();
129
130 #ifdef VECT_TAB_SRAM
131 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;
132 #else
133 SCB->VTOR = FMC_BASE | VECT_TAB_OFFSET;
134 #endif
135 }
136
137 /*!
138 * @brief Update SystemCoreClock variable according to Clock Register Values
139 * The SystemCoreClock variable contains the core clock (HCLK)
140 *
141 * @param None
142 *
143 * @retval None
144 *
145 * @note
146 */
SystemCoreClockUpdate(void)147 void SystemCoreClockUpdate (void)
148 {
149 uint32_t sysClock, pllMull, pllSource, Prescaler;
150 uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
151
152 sysClock = RCM->CFG_B.SCLKSWSTS;
153
154 switch(sysClock)
155 {
156 /** sys clock is HSI */
157 case 0:
158 SystemCoreClock = HSI_VALUE;
159 break;
160
161 /** sys clock is HSE */
162 case 1:
163 SystemCoreClock = HSE_VALUE;
164 break;
165
166 /** sys clock is PLL */
167 case 2:
168 pllMull = RCM->CFG_B.PLLMULCFG + 2;
169 pllSource = RCM->CFG_B.PLLSRCSEL;
170
171 /** PLL entry clock source is HSE */
172 if(pllSource == BIT_SET)
173 {
174 SystemCoreClock = HSE_VALUE * pllMull;
175
176 /** HSE clock divided by 2 */
177 if(pllSource == RCM->CFG_B.PLLHSEPSC)
178 {
179 SystemCoreClock >>= 1;
180 }
181 }
182 /** PLL entry clock source is HSI/2 */
183 else
184 {
185 SystemCoreClock = (HSI_VALUE >> 1) * pllMull;
186 }
187 break;
188
189 default:
190 SystemCoreClock = HSI_VALUE;
191 break;
192 }
193
194 Prescaler = AHBPrescTable[RCM->CFG_B.AHBPSC];
195 SystemCoreClock >>= Prescaler;
196 }
197
198 /*!
199 * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers
200 *
201 * @param None
202 *
203 * @retval None
204 *
205 * @note
206 */
SystemClockConfig(void)207 static void SystemClockConfig(void)
208 {
209 #ifdef SYSTEM_CLOCK_HSE
210 SystemClockHSE();
211 #elif defined SYSTEM_CLOCK_24MHz
212 SystemClock24M();
213 #elif defined SYSTEM_CLOCK_36MHz
214 SystemClock36M();
215 #elif defined SYSTEM_CLOCK_48MHz
216 SystemClock48M();
217 #elif defined SYSTEM_CLOCK_56MHz
218 SystemClock56M();
219 #elif defined SYSTEM_CLOCK_72MHz
220 SystemClock72M();
221 #elif defined SYSTEM_CLOCK_96MHz
222 SystemClock96M();
223 #elif defined SYSTEM_CLOCK_120MHz
224 SystemClock120M();
225 #endif
226 }
227
228 #if defined SYSTEM_CLOCK_HSE
229 /*!
230 * @brief Selects HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers
231 *
232 * @param None
233 *
234 * @retval None
235 *
236 * @note
237 */
SystemClockHSE(void)238 static void SystemClockHSE(void)
239 {
240 __IO uint32_t i;
241
242 RCM->CTRL_B.HSEEN= BIT_SET;
243
244 for(i = 0; i < HSE_STARTUP_TIMEOUT; i++)
245 {
246 if(RCM->CTRL_B.HSERDYFLG)
247 {
248 break;
249 }
250 }
251
252 if(RCM->CTRL_B.HSERDYFLG)
253 {
254 /* Enable Prefetch Buffer */
255 FMC->CTRL1_B.PBEN = BIT_SET;
256 /* Flash 0 wait state */
257 FMC->CTRL1_B.WS = 0;
258
259 /* HCLK = SYSCLK */
260 RCM->CFG_B.AHBPSC= 0X00;
261 /* PCLK2 = HCLK */
262 RCM->CFG_B.APB2PSC= 0;
263 /* PCLK1 = HCLK */
264 RCM->CFG_B.APB1PSC = 0;
265
266 /* Select HSE as system clock source */
267 RCM->CFG_B.SCLKSW = 1;
268
269 /** Wait till HSE is used as system clock source */
270 while(RCM->CFG_B.SCLKSWSTS!= 0x01);
271 }
272 }
273
274
275 #elif defined SYSTEM_CLOCK_24MHz
276 /*!
277 * @brief Sets System clock frequency to 24MHz and configure HCLK, PCLK2 and PCLK1 prescalers
278 *
279 * @param None
280 *
281 * @retval None
282 *
283 * @note
284 */
SystemClock24M(void)285 static void SystemClock24M(void)
286 {
287 __IO uint32_t i;
288
289 RCM->CTRL_B.HSEEN= BIT_SET;
290
291 for(i = 0; i < HSE_STARTUP_TIMEOUT; i++)
292 {
293 if(RCM->CTRL_B.HSERDYFLG)
294 {
295 break;
296 }
297 }
298
299 if(RCM->CTRL_B.HSERDYFLG)
300 {
301 /* Enable Prefetch Buffer */
302 FMC->CTRL1_B.PBEN = BIT_SET;
303 /* Flash 0 wait state */
304 FMC->CTRL1_B.WS = 0;
305
306 /* HCLK = SYSCLK */
307 RCM->CFG_B.AHBPSC= 0X00;
308 /* PCLK2 = HCLK */
309 RCM->CFG_B.APB2PSC= 0;
310 /* PCLK1 = HCLK */
311 RCM->CFG_B.APB1PSC = 0;
312
313 /** PLL: (HSE / 2) * 6 */
314 RCM->CFG_B.PLLSRCSEL = 1;
315 RCM->CFG_B.PLLHSEPSC = 1;
316 RCM->CFG_B.PLLMULCFG = 4;
317
318 /** Enable PLL */
319 RCM->CTRL_B.PLLEN = 1;
320 /** Wait PLL Ready */
321 while(RCM->CTRL_B.PLLRDYFLG == BIT_RESET);
322
323 /* Select PLL as system clock source */
324 RCM->CFG_B.SCLKSW = 2;
325 /* Wait till PLL is used as system clock source */
326 while(RCM->CFG_B.SCLKSWSTS!= 0x02);
327 }
328 }
329
330 #elif defined SYSTEM_CLOCK_36MHz
331 /*!
332 * @brief Sets System clock frequency to 36MHz and configure HCLK, PCLK2 and PCLK1 prescalers
333 *
334 * @param None
335 *
336 * @retval None
337 *
338 * @note
339 */
SystemClock36M(void)340 static void SystemClock36M(void)
341 {
342 __IO uint32_t i;
343
344 RCM->CTRL_B.HSEEN= BIT_SET;
345
346 for(i = 0; i < HSE_STARTUP_TIMEOUT; i++)
347 {
348 if(RCM->CTRL_B.HSERDYFLG)
349 {
350 break;
351 }
352 }
353
354 if(RCM->CTRL_B.HSERDYFLG)
355 {
356 /* Enable Prefetch Buffer */
357 FMC->CTRL1_B.PBEN = BIT_SET;
358 /* Flash 1 wait state */
359 FMC->CTRL1_B.WS = 1;
360
361 /* HCLK = SYSCLK */
362 RCM->CFG_B.AHBPSC= 0X00;
363 /* PCLK2 = HCLK */
364 RCM->CFG_B.APB2PSC= 0;
365 /* PCLK1 = HCLK */
366 RCM->CFG_B.APB1PSC = 0;
367
368 /** PLL: (HSE / 2) * 9 */
369 RCM->CFG_B.PLLSRCSEL = 1;
370 RCM->CFG_B.PLLHSEPSC = 1;
371 RCM->CFG_B.PLLMULCFG = 7;
372
373 /** Enable PLL */
374 RCM->CTRL_B.PLLEN = 1;
375 /** Wait PLL Ready */
376 while(RCM->CTRL_B.PLLRDYFLG == BIT_RESET);
377
378 /* Select PLL as system clock source */
379 RCM->CFG_B.SCLKSW = 2;
380 /* Wait till PLL is used as system clock source */
381 while(RCM->CFG_B.SCLKSWSTS != 0x02);
382 }
383 }
384
385 #elif defined SYSTEM_CLOCK_48MHz
386 /*!
387 * @brief Sets System clock frequency to 46MHz and configure HCLK, PCLK2 and PCLK1 prescalers
388 *
389 * @param None
390 *
391 * @retval None
392 *
393 * @note
394 */
SystemClock48M(void)395 static void SystemClock48M(void)
396 {
397 __IO uint32_t i;
398
399 RCM->CTRL_B.HSEEN= BIT_SET;
400
401 for(i = 0; i < HSE_STARTUP_TIMEOUT; i++)
402 {
403 if(RCM->CTRL_B.HSERDYFLG)
404 {
405 break;
406 }
407 }
408
409 if(RCM->CTRL_B.HSERDYFLG)
410 {
411 /* Enable Prefetch Buffer */
412 FMC->CTRL1_B.PBEN = BIT_SET;
413 /* Flash 1 wait state */
414 FMC->CTRL1_B.WS = 1;
415
416 /* HCLK = SYSCLK */
417 RCM->CFG_B.AHBPSC= 0X00;
418 /* PCLK2 = HCLK */
419 RCM->CFG_B.APB2PSC= 0;
420 /* PCLK1 = HCLK / 2 */
421 RCM->CFG_B.APB1PSC = 4;
422
423 /** PLL: HSE * 6 */
424 RCM->CFG_B.PLLSRCSEL = 1;
425 RCM->CFG_B.PLLMULCFG = 4;
426
427 /** Enable PLL */
428 RCM->CTRL_B.PLLEN = 1;
429 /** Wait PLL Ready */
430 while(RCM->CTRL_B.PLLRDYFLG == BIT_RESET);
431
432 /* Select PLL as system clock source */
433 RCM->CFG_B.SCLKSW = 2;
434 /* Wait till PLL is used as system clock source */
435 while(RCM->CFG_B.SCLKSWSTS!= 0x02);
436 }
437 }
438
439 #elif defined SYSTEM_CLOCK_56MHz
440 /*!
441 * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers
442 *
443 * @param None
444 *
445 * @retval None
446 *
447 * @note
448 */
SystemClock56M(void)449 static void SystemClock56M(void)
450 {
451 __IO uint32_t i;
452
453 RCM->CTRL_B.HSEEN= BIT_SET;
454
455 for(i = 0; i < HSE_STARTUP_TIMEOUT; i++)
456 {
457 if(RCM->CTRL_B.HSERDYFLG)
458 {
459 break;
460 }
461 }
462
463 if(RCM->CTRL_B.HSERDYFLG)
464 {
465 /* Enable Prefetch Buffer */
466 FMC->CTRL1_B.PBEN = BIT_SET;
467 /* Flash 2 wait state */
468 FMC->CTRL1_B.WS = 2;
469
470 /* HCLK = SYSCLK */
471 RCM->CFG_B.AHBPSC= 0X00;
472 /* PCLK2 = HCLK */
473 RCM->CFG_B.APB2PSC= 0;
474 /* PCLK1 = HCLK / 2 */
475 RCM->CFG_B.APB1PSC = 4;
476
477 /** PLL: HSE * 7 */
478 RCM->CFG_B.PLLSRCSEL = 1;
479 RCM->CFG_B.PLLMULCFG = 5;
480
481 /** Enable PLL */
482 RCM->CTRL_B.PLLEN = 1;
483 /** Wait PLL Ready */
484 while(RCM->CTRL_B.PLLRDYFLG == BIT_RESET);
485
486 /* Select PLL as system clock source */
487 RCM->CFG_B.SCLKSW = 2;
488 /* Wait till PLL is used as system clock source */
489 while(RCM->CFG_B.SCLKSWSTS!= 0x02);
490 }
491 }
492
493 #elif defined SYSTEM_CLOCK_72MHz
494 /*!
495 * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers
496 *
497 * @param None
498 *
499 * @retval None
500 *
501 * @note
502 */
SystemClock72M(void)503 static void SystemClock72M(void)
504 {
505 __IO uint32_t i;
506
507 RCM->CTRL_B.HSEEN= BIT_SET;
508
509 for(i = 0; i < HSE_STARTUP_TIMEOUT; i++)
510 {
511 if(RCM->CTRL_B.HSERDYFLG)
512 {
513 break;
514 }
515 }
516
517 if(RCM->CTRL_B.HSERDYFLG)
518 {
519 /* Enable Prefetch Buffer */
520 FMC->CTRL1_B.PBEN = BIT_SET;
521 /* Flash 2 wait state */
522 FMC->CTRL1_B.WS = 2;
523
524 /* HCLK = SYSCLK */
525 RCM->CFG_B.AHBPSC= 0X00;
526 /* PCLK2 = HCLK */
527 RCM->CFG_B.APB2PSC= 0;
528 /* PCLK1 = HCLK / 2 */
529 RCM->CFG_B.APB1PSC = 4;
530
531 /** PLL: HSE * 9 */
532 RCM->CFG_B.PLLSRCSEL = 1;
533 RCM->CFG_B.PLLMULCFG = 7;
534
535 /** Enable PLL */
536 RCM->CTRL_B.PLLEN = 1;
537 /** Wait PLL Ready */
538 while(RCM->CTRL_B.PLLRDYFLG == BIT_RESET);
539
540 /* Select PLL as system clock source */
541 RCM->CFG_B.SCLKSW = 2;
542 /* Wait till PLL is used as system clock source */
543 while(RCM->CFG_B.SCLKSWSTS!= 0x02);
544 }
545
546 }
547
548 #elif defined SYSTEM_CLOCK_96MHz
549 /*!
550 * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers
551 *
552 * @param None
553 *
554 * @retval None
555 *
556 * @note
557 */
SystemClock96M(void)558 static void SystemClock96M(void)
559 {
560 __IO uint32_t i;
561
562 RCM->CTRL_B.HSEEN= BIT_SET;
563
564 for(i = 0; i < HSE_STARTUP_TIMEOUT; i++)
565 {
566 if(RCM->CTRL_B.HSERDYFLG)
567 {
568 break;
569 }
570 }
571
572 if(RCM->CTRL_B.HSERDYFLG)
573 {
574 /* Enable Prefetch Buffer */
575 FMC->CTRL1_B.PBEN = BIT_SET;
576 /* Flash 3 wait state */
577 FMC->CTRL1_B.WS = 3;
578
579 /* HCLK = SYSCLK */
580 RCM->CFG_B.AHBPSC= 0X00;
581 /* PCLK2 = HCLK */
582 RCM->CFG_B.APB2PSC= 0;
583 /* PCLK1 = HCLK / 2 */
584 RCM->CFG_B.APB1PSC = 4;
585
586 /** PLL: HSE * 12 */
587 RCM->CFG_B.PLLSRCSEL = 1;
588 RCM->CFG_B.PLLMULCFG = 10;
589
590 /** Enable PLL */
591 RCM->CTRL_B.PLLEN = 1;
592 /** Wait PLL Ready */
593 while(RCM->CTRL_B.PLLRDYFLG == BIT_RESET);
594
595 /* Select PLL as system clock source */
596 RCM->CFG_B.SCLKSW = 2;
597 /* Wait till PLL is used as system clock source */
598 while(RCM->CFG_B.SCLKSWSTS!= 0x02);
599 }
600 }
601
602 #elif defined SYSTEM_CLOCK_120MHz
603 /*!
604 * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers
605 *
606 * @param None
607 *
608 * @retval None
609 *
610 * @note
611 */
SystemClock120M(void)612 static void SystemClock120M(void)
613 {
614 __IO uint32_t i;
615
616 RCM->CTRL_B.HSEEN= BIT_SET;
617
618 for(i = 0; i < HSE_STARTUP_TIMEOUT; i++)
619 {
620 if(RCM->CTRL_B.HSERDYFLG)
621 {
622 break;
623 }
624 }
625
626 if(RCM->CTRL_B.HSERDYFLG)
627 {
628 /* Enable Prefetch Buffer */
629 FMC->CTRL1_B.PBEN = BIT_SET;
630 /* Flash 3 wait state */
631 FMC->CTRL1_B.WS = 3;
632
633 /* HCLK = SYSCLK */
634 RCM->CFG_B.AHBPSC= 0X00;
635 /* PCLK2 = HCLK */
636 RCM->CFG_B.APB2PSC= 0;
637 /* PCLK1 = HCLK / 2 */
638 RCM->CFG_B.APB1PSC = 4;
639
640 /** PLL: HSE * 15 */
641 RCM->CFG_B.PLLSRCSEL = 1;
642 RCM->CFG_B.PLLMULCFG = 13;
643
644 /** Enable PLL */
645 RCM->CTRL_B.PLLEN = 1;
646 /** Wait PLL Ready */
647 while(RCM->CTRL_B.PLLRDYFLG == BIT_RESET);
648
649 /* Select PLL as system clock source */
650 RCM->CFG_B.SCLKSW = 2;
651 /* Wait till PLL is used as system clock source */
652 while(RCM->CFG_B.SCLKSWSTS!= 0x02);
653 }
654 }
655 #endif
656
657 /**@} end of group System_Functions */
658 /**@} end of group APM32E10x_System */
659 /**@} end of group CMSIS */
660