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