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