1 /*!
2 \file system_gd32vf103.c
3 \brief RISC-V Device Peripheral Access Layer Source File for
4 GD32VF103 Device Series
5
6 \version 2019-06-05, V1.0.0, firmware for GD32VF103
7 \version 2020-08-04, V1.1.0, firmware for GD32VF103
8 */
9
10 /*
11 Copyright (c) 2020, GigaDevice Semiconductor Inc.
12
13 Redistribution and use in source and binary forms, with or without modification,
14 are permitted provided that the following conditions are met:
15
16 1. Redistributions of source code must retain the above copyright notice, this
17 list of conditions and the following disclaimer.
18 2. Redistributions in binary form must reproduce the above copyright notice,
19 this list of conditions and the following disclaimer in the documentation
20 and/or other materials provided with the distribution.
21 3. Neither the name of the copyright holder nor the names of its contributors
22 may be used to endorse or promote products derived from this software without
23 specific prior written permission.
24
25 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
34 OF SUCH DAMAGE.
35 */
36
37 /* This file refers the RISC-V standard, some adjustments are made according to GigaDevice chips */
38
39 #include "gd32vf103.h"
40
41 /* system frequency define */
42 #define __IRC8M (IRC8M_VALUE) /* internal 8 MHz RC oscillator frequency */
43 #define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */
44 #define __SYS_OSC_CLK (__IRC8M) /* main oscillator frequency */
45
46 /* select a system clock by uncommenting the following line */
47 /* use IRC8M */
48 //#define __SYSTEM_CLOCK_48M_PLL_IRC8M (uint32_t)(48000000)
49 //#define __SYSTEM_CLOCK_72M_PLL_IRC8M (uint32_t)(72000000)
50 //#define __SYSTEM_CLOCK_108M_PLL_IRC8M (uint32_t)(108000000)
51
52 /********************************************************************/
53 //#define __SYSTEM_CLOCK_HXTAL (HXTAL_VALUE)
54 //#define __SYSTEM_CLOCK_24M_PLL_HXTAL (uint32_t)(24000000)
55 /********************************************************************/
56
57 //#define __SYSTEM_CLOCK_36M_PLL_HXTAL (uint32_t)(36000000)
58 //#define __SYSTEM_CLOCK_48M_PLL_HXTAL (uint32_t)(48000000)
59 //#define __SYSTEM_CLOCK_56M_PLL_HXTAL (uint32_t)(56000000)
60 //#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000)
61 //#define __SYSTEM_CLOCK_96M_PLL_HXTAL (uint32_t)(96000000)
62 #define __SYSTEM_CLOCK_108M_PLL_HXTAL (uint32_t)(108000000)
63
64 #define SEL_IRC8M 0x00U
65 #define SEL_HXTAL 0x01U
66 #define SEL_PLL 0x02U
67
68 /* set the system clock frequency and declare the system clock configuration function */
69 #ifdef __SYSTEM_CLOCK_48M_PLL_IRC8M
70 uint32_t SystemCoreClock = __SYSTEM_CLOCK_48M_PLL_IRC8M;
71 static void system_clock_48m_irc8m(void);
72 #elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M)
73 uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_IRC8M;
74 static void system_clock_72m_irc8m(void);
75 #elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M)
76 uint32_t SystemCoreClock = __SYSTEM_CLOCK_108M_PLL_IRC8M;
77 static void system_clock_108m_irc8m(void);
78
79 #elif defined (__SYSTEM_CLOCK_HXTAL)
80 uint32_t SystemCoreClock = __SYSTEM_CLOCK_HXTAL;
81 static void system_clock_hxtal(void);
82 #elif defined (__SYSTEM_CLOCK_24M_PLL_HXTAL)
83 uint32_t SystemCoreClock = __SYSTEM_CLOCK_24M_PLL_HXTAL;
84 static void system_clock_24m_hxtal(void);
85 #elif defined (__SYSTEM_CLOCK_36M_PLL_HXTAL)
86 uint32_t SystemCoreClock = __SYSTEM_CLOCK_36M_PLL_HXTAL;
87 static void system_clock_36m_hxtal(void);
88 #elif defined (__SYSTEM_CLOCK_48M_PLL_HXTAL)
89 uint32_t SystemCoreClock = __SYSTEM_CLOCK_48M_PLL_HXTAL;
90 static void system_clock_48m_hxtal(void);
91 #elif defined (__SYSTEM_CLOCK_56M_PLL_HXTAL)
92 uint32_t SystemCoreClock = __SYSTEM_CLOCK_56M_PLL_HXTAL;
93 static void system_clock_56m_hxtal(void);
94 #elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
95 uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_HXTAL;
96 static void system_clock_72m_hxtal(void);
97 #elif defined (__SYSTEM_CLOCK_96M_PLL_HXTAL)
98 uint32_t SystemCoreClock = __SYSTEM_CLOCK_96M_PLL_HXTAL;
99 static void system_clock_96m_hxtal(void);
100 #elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL)
101 uint32_t SystemCoreClock = __SYSTEM_CLOCK_108M_PLL_HXTAL;
102 static void system_clock_108m_hxtal(void);
103 #else
104 uint32_t SystemCoreClock = IRC8M_VALUE;
105 #endif /* __SYSTEM_CLOCK_48M_PLL_IRC8M */
106
107 /* configure the system clock */
108 static void system_clock_config(void);
109
110 /*!
111 \brief configure the system clock
112 \param[in] none
113 \param[out] none
114 \retval none
115 */
system_clock_config(void)116 static void system_clock_config(void)
117 {
118 #ifdef __SYSTEM_CLOCK_HXTAL
119 system_clock_hxtal();
120 #elif defined (__SYSTEM_CLOCK_24M_PLL_HXTAL)
121 system_clock_24m_hxtal();
122 #elif defined (__SYSTEM_CLOCK_36M_PLL_HXTAL)
123 system_clock_36m_hxtal();
124 #elif defined (__SYSTEM_CLOCK_48M_PLL_HXTAL)
125 system_clock_48m_hxtal();
126 #elif defined (__SYSTEM_CLOCK_56M_PLL_HXTAL)
127 system_clock_56m_hxtal();
128 #elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
129 system_clock_72m_hxtal();
130 #elif defined (__SYSTEM_CLOCK_96M_PLL_HXTAL)
131 system_clock_96m_hxtal();
132 #elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL)
133 system_clock_108m_hxtal();
134
135 #elif defined (__SYSTEM_CLOCK_48M_PLL_IRC8M)
136 system_clock_48m_irc8m();
137 #elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M)
138 system_clock_72m_irc8m();
139 #elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M)
140 system_clock_108m_irc8m();
141 #endif /* __SYSTEM_CLOCK_HXTAL */
142 }
143
144 /*!
145 \brief setup the microcontroller system, initialize the system
146 \param[in] none
147 \param[out] none
148 \retval none
149 */
SystemInit(void)150 void SystemInit(void)
151 {
152 /* reset the RCC clock configuration to the default reset state */
153 /* enable IRC8M */
154 RCU_CTL |= RCU_CTL_IRC8MEN;
155
156 /* reset SCS, AHBPSC, APB1PSC, APB2PSC, ADCPSC, CKOUT0SEL bits */
157 RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |
158 RCU_CFG0_ADCPSC | RCU_CFG0_ADCPSC_2 | RCU_CFG0_CKOUT0SEL);
159
160 /* reset HXTALEN, CKMEN, PLLEN bits */
161 RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN);
162
163 /* Reset HXTALBPS bit */
164 RCU_CTL &= ~(RCU_CTL_HXTALBPS);
165
166 /* reset PLLSEL, PREDV0_LSB, PLLMF, USBFSPSC bits */
167
168 RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0_LSB | RCU_CFG0_PLLMF |
169 RCU_CFG0_USBFSPSC | RCU_CFG0_PLLMF_4);
170 RCU_CFG1 = 0x00000000U;
171
172 /* Reset HXTALEN, CKMEN, PLLEN, PLL1EN and PLL2EN bits */
173 RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_PLL1EN | RCU_CTL_PLL2EN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN);
174 /* disable all interrupts */
175 RCU_INT = 0x00FF0000U;
176
177 /* Configure the System clock source, PLL Multiplier, AHB/APBx prescalers and Flash settings */
178 system_clock_config();
179 }
180
181 /*!
182 \brief update the SystemCoreClock with current core clock retrieved from cpu registers
183 \param[in] none
184 \param[out] none
185 \retval none
186 */
SystemCoreClockUpdate(void)187 void SystemCoreClockUpdate(void)
188 {
189 uint32_t scss;
190 uint32_t pllsel, predv0sel, pllmf, ck_src;
191 uint32_t predv0, predv1, pll1mf;
192
193 scss = GET_BITS(RCU_CFG0, 2, 3);
194
195 switch (scss)
196 {
197 /* IRC8M is selected as CK_SYS */
198 case SEL_IRC8M:
199 SystemCoreClock = IRC8M_VALUE;
200 break;
201
202 /* HXTAL is selected as CK_SYS */
203 case SEL_HXTAL:
204 SystemCoreClock = HXTAL_VALUE;
205 break;
206
207 /* PLL is selected as CK_SYS */
208 case SEL_PLL:
209 /* PLL clock source selection, HXTAL or IRC8M/2 */
210 pllsel = (RCU_CFG0 & RCU_CFG0_PLLSEL);
211
212
213 if(RCU_PLLSRC_IRC8M_DIV2 == pllsel){
214 /* PLL clock source is IRC8M/2 */
215 ck_src = IRC8M_VALUE / 2U;
216 }else{
217 /* PLL clock source is HXTAL */
218 ck_src = HXTAL_VALUE;
219
220 predv0sel = (RCU_CFG1 & RCU_CFG1_PREDV0SEL);
221
222 /* source clock use PLL1 */
223 if(RCU_PREDV0SRC_CKPLL1 == predv0sel){
224 predv1 = ((RCU_CFG1 & RCU_CFG1_PREDV1) >> 4) + 1U;
225 pll1mf = ((RCU_CFG1 & RCU_CFG1_PLL1MF) >> 8) + 2U;
226 if(17U == pll1mf){
227 pll1mf = 20U;
228 }
229 ck_src = (ck_src / predv1) * pll1mf;
230 }
231 predv0 = (RCU_CFG1 & RCU_CFG1_PREDV0) + 1U;
232 ck_src /= predv0;
233 }
234
235 /* PLL multiplication factor */
236 pllmf = GET_BITS(RCU_CFG0, 18, 21);
237
238 if((RCU_CFG0 & RCU_CFG0_PLLMF_4)){
239 pllmf |= 0x10U;
240 }
241
242 if(pllmf >= 15U){
243 pllmf += 1U;
244 }else{
245 pllmf += 2U;
246 }
247
248 SystemCoreClock = ck_src * pllmf;
249
250 if(15U == pllmf){
251 /* PLL source clock multiply by 6.5 */
252 SystemCoreClock = ck_src * 6U + ck_src / 2U;
253 }
254
255 break;
256
257 /* IRC8M is selected as CK_SYS */
258 default:
259 SystemCoreClock = IRC8M_VALUE;
260 break;
261 }
262 }
263
264 #ifdef __SYSTEM_CLOCK_HXTAL
265 /*!
266 \brief configure the system clock to HXTAL
267 \param[in] none
268 \param[out] none
269 \retval none
270 */
system_clock_hxtal(void)271 static void system_clock_hxtal(void)
272 {
273 uint32_t timeout = 0U;
274 uint32_t stab_flag = 0U;
275
276 /* enable HXTAL */
277 RCU_CTL |= RCU_CTL_HXTALEN;
278
279 /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
280 do{
281 timeout++;
282 stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
283 }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
284
285 /* if fail */
286 if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
287 while(1){
288 }
289 }
290
291 /* AHB = SYSCLK */
292 RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
293 /* APB2 = AHB/1 */
294 RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
295 /* APB1 = AHB/2 */
296 RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
297
298 /* select HXTAL as system clock */
299 RCU_CFG0 &= ~RCU_CFG0_SCS;
300 RCU_CFG0 |= RCU_CKSYSSRC_HXTAL;
301
302 /* wait until HXTAL is selected as system clock */
303 while(0 == (RCU_CFG0 & RCU_SCSS_HXTAL)){
304 }
305 }
306
307 #elif defined (__SYSTEM_CLOCK_24M_PLL_HXTAL)
308 /*!
309 \brief configure the system clock to 24M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source
310 \param[in] none
311 \param[out] none
312 \retval none
313 */
system_clock_24m_hxtal(void)314 static void system_clock_24m_hxtal(void)
315 {
316 uint32_t timeout = 0U;
317 uint32_t stab_flag = 0U;
318
319 /* enable HXTAL */
320 RCU_CTL |= RCU_CTL_HXTALEN;
321
322 /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
323 do{
324 timeout++;
325 stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
326 }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
327
328 /* if fail */
329 if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
330 while(1){
331 }
332 }
333
334 /* HXTAL is stable */
335 /* AHB = SYSCLK */
336 RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
337 /* APB2 = AHB/1 */
338 RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
339 /* APB1 = AHB/2 */
340 RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
341
342 /* CK_PLL = (CK_PREDIV0) * 6 = 24 MHz */
343 RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
344 RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL6);
345
346 if(HXTAL_VALUE==25000000){
347 /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
348 RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
349 RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
350
351 /* enable PLL1 */
352 RCU_CTL |= RCU_CTL_PLL1EN;
353 /* wait till PLL1 is ready */
354 while((RCU_CTL & RCU_CTL_PLL1STB) == 0){
355 }
356
357 }else if(HXTAL_VALUE==8000000){
358 RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0);
359 RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 );
360 }
361
362 /* enable PLL */
363 RCU_CTL |= RCU_CTL_PLLEN;
364
365 /* wait until PLL is stable */
366 while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
367 }
368
369 /* select PLL as system clock */
370 RCU_CFG0 &= ~RCU_CFG0_SCS;
371 RCU_CFG0 |= RCU_CKSYSSRC_PLL;
372
373 /* wait until PLL is selected as system clock */
374 while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
375 }
376 }
377
378 #elif defined (__SYSTEM_CLOCK_36M_PLL_HXTAL)
379 /*!
380 \brief configure the system clock to 36M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source
381 \param[in] none
382 \param[out] none
383 \retval none
384 */
system_clock_36m_hxtal(void)385 static void system_clock_36m_hxtal(void)
386 {
387 uint32_t timeout = 0U;
388 uint32_t stab_flag = 0U;
389
390 /* enable HXTAL */
391 RCU_CTL |= RCU_CTL_HXTALEN;
392
393 /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
394 do{
395 timeout++;
396 stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
397 }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
398
399 /* if fail */
400 if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
401 while(1){
402 }
403 }
404
405 /* HXTAL is stable */
406 /* AHB = SYSCLK */
407 RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
408 /* APB2 = AHB/1 */
409 RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
410 /* APB1 = AHB/2 */
411 RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
412
413 /* CK_PLL = (CK_PREDIV0) * 9 = 36 MHz */
414 RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
415 RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL9);
416
417 if(HXTAL_VALUE==25000000){
418 /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
419 RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
420 RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
421
422 /* enable PLL1 */
423 RCU_CTL |= RCU_CTL_PLL1EN;
424 /* wait till PLL1 is ready */
425 while((RCU_CTL & RCU_CTL_PLL1STB) == 0){
426 }
427
428 }else if(HXTAL_VALUE==8000000){
429 RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0);
430 RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 );
431 }
432
433 /* enable PLL */
434 RCU_CTL |= RCU_CTL_PLLEN;
435
436 /* wait until PLL is stable */
437 while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
438 }
439
440 /* select PLL as system clock */
441 RCU_CFG0 &= ~RCU_CFG0_SCS;
442 RCU_CFG0 |= RCU_CKSYSSRC_PLL;
443
444 /* wait until PLL is selected as system clock */
445 while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
446 }
447 }
448
449 #elif defined (__SYSTEM_CLOCK_48M_PLL_HXTAL)
450 /*!
451 \brief configure the system clock to 48M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source
452 \param[in] none
453 \param[out] none
454 \retval none
455 */
system_clock_48m_hxtal(void)456 static void system_clock_48m_hxtal(void)
457 {
458 uint32_t timeout = 0U;
459 uint32_t stab_flag = 0U;
460
461 /* enable HXTAL */
462 RCU_CTL |= RCU_CTL_HXTALEN;
463
464 /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
465 do{
466 timeout++;
467 stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
468 }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
469
470 /* if fail */
471 if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
472 while(1){
473 }
474 }
475
476 /* HXTAL is stable */
477 /* AHB = SYSCLK */
478 RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
479 /* APB2 = AHB/1 */
480 RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
481 /* APB1 = AHB/2 */
482 RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
483
484 /* CK_PLL = (CK_PREDIV0) * 12 = 48 MHz */
485 RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
486 RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL12);
487
488 if(HXTAL_VALUE==25000000){
489
490 /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
491 RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
492 RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
493
494 /* enable PLL1 */
495 RCU_CTL |= RCU_CTL_PLL1EN;
496 /* wait till PLL1 is ready */
497 while((RCU_CTL & RCU_CTL_PLL1STB) == 0){
498 }
499
500 }else if(HXTAL_VALUE==8000000){
501 RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0);
502 RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 );
503 }
504
505
506
507 /* enable PLL */
508 RCU_CTL |= RCU_CTL_PLLEN;
509
510 /* wait until PLL is stable */
511 while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
512 }
513
514 /* select PLL as system clock */
515 RCU_CFG0 &= ~RCU_CFG0_SCS;
516 RCU_CFG0 |= RCU_CKSYSSRC_PLL;
517
518 /* wait until PLL is selected as system clock */
519 while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
520 }
521 }
522
523 #elif defined (__SYSTEM_CLOCK_56M_PLL_HXTAL)
524 /*!
525 \brief configure the system clock to 56M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source
526 \param[in] none
527 \param[out] none
528 \retval none
529 */
system_clock_56m_hxtal(void)530 static void system_clock_56m_hxtal(void)
531 {
532 uint32_t timeout = 0U;
533 uint32_t stab_flag = 0U;
534
535 /* enable HXTAL */
536 RCU_CTL |= RCU_CTL_HXTALEN;
537
538 /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
539 do{
540 timeout++;
541 stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
542 }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
543
544 /* if fail */
545 if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
546 while(1){
547 }
548 }
549
550 /* HXTAL is stable */
551 /* AHB = SYSCLK */
552 RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
553 /* APB2 = AHB/1 */
554 RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
555 /* APB1 = AHB/2 */
556 RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
557
558 /* CK_PLL = (CK_PREDIV0) * 14 = 56 MHz */
559 RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
560 RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL14);
561
562 if(HXTAL_VALUE==25000000){
563
564 /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
565 RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
566 RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
567
568 /* enable PLL1 */
569 RCU_CTL |= RCU_CTL_PLL1EN;
570 /* wait till PLL1 is ready */
571 while((RCU_CTL & RCU_CTL_PLL1STB) == 0){
572 }
573
574 }else if(HXTAL_VALUE==8000000){
575 RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0);
576 RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 );
577 }
578
579 /* enable PLL */
580 RCU_CTL |= RCU_CTL_PLLEN;
581
582 /* wait until PLL is stable */
583 while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
584 }
585
586 /* select PLL as system clock */
587 RCU_CFG0 &= ~RCU_CFG0_SCS;
588 RCU_CFG0 |= RCU_CKSYSSRC_PLL;
589
590 /* wait until PLL is selected as system clock */
591 while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
592 }
593 }
594
595 #elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
596 /*!
597 \brief configure the system clock to 72M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source
598 \param[in] none
599 \param[out] none
600 \retval none
601 */
system_clock_72m_hxtal(void)602 static void system_clock_72m_hxtal(void)
603 {
604 uint32_t timeout = 0U;
605 uint32_t stab_flag = 0U;
606
607 /* enable HXTAL */
608 RCU_CTL |= RCU_CTL_HXTALEN;
609
610 /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
611 do{
612 timeout++;
613 stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
614 }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
615
616 /* if fail */
617 if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
618 while(1){
619 }
620 }
621
622 /* HXTAL is stable */
623 /* AHB = SYSCLK */
624 RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
625 /* APB2 = AHB/1 */
626 RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
627 /* APB1 = AHB/2 */
628 RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
629
630 /* CK_PLL = (CK_PREDIV0) * 18 = 72 MHz */
631 RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
632 RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL18);
633
634
635 if(HXTAL_VALUE==25000000){
636
637 /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
638 RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
639 RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
640
641 /* enable PLL1 */
642 RCU_CTL |= RCU_CTL_PLL1EN;
643 /* wait till PLL1 is ready */
644 while((RCU_CTL & RCU_CTL_PLL1STB) == 0){
645 }
646
647 }else if(HXTAL_VALUE==8000000){
648 RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0);
649 RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 );
650 }
651
652 /* enable PLL */
653 RCU_CTL |= RCU_CTL_PLLEN;
654
655 /* wait until PLL is stable */
656 while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
657 }
658
659 /* select PLL as system clock */
660 RCU_CFG0 &= ~RCU_CFG0_SCS;
661 RCU_CFG0 |= RCU_CKSYSSRC_PLL;
662
663 /* wait until PLL is selected as system clock */
664 while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
665 }
666 }
667
668 #elif defined (__SYSTEM_CLOCK_96M_PLL_HXTAL)
669 /*!
670 \brief configure the system clock to 96M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source
671 \param[in] none
672 \param[out] none
673 \retval none
674 */
system_clock_96m_hxtal(void)675 static void system_clock_96m_hxtal(void)
676 {
677 uint32_t timeout = 0U;
678 uint32_t stab_flag = 0U;
679
680 /* enable HXTAL */
681 RCU_CTL |= RCU_CTL_HXTALEN;
682
683 /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
684 do{
685 timeout++;
686 stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
687 }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
688
689 /* if fail */
690 if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
691 while(1){
692 }
693 }
694
695 /* HXTAL is stable */
696 /* AHB = SYSCLK */
697 RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
698 /* APB2 = AHB/1 */
699 RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
700 /* APB1 = AHB/2 */
701 RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
702
703 if(HXTAL_VALUE==25000000){
704
705 /* CK_PLL = (CK_PREDIV0) * 24 = 96 MHz */
706 RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
707 RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL24);
708
709 /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
710 RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
711 RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
712 /* enable PLL1 */
713 RCU_CTL |= RCU_CTL_PLL1EN;
714 /* wait till PLL1 is ready */
715 while((RCU_CTL & RCU_CTL_PLL1STB) == 0){
716 }
717
718 }else if(HXTAL_VALUE==8000000){
719 /* CK_PLL = (CK_PREDIV0) * 24 = 96 MHz */
720 RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
721 RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL24);
722
723 RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0);
724 RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 );
725 }
726
727 /* enable PLL */
728 RCU_CTL |= RCU_CTL_PLLEN;
729
730 /* wait until PLL is stable */
731 while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
732 }
733
734 /* select PLL as system clock */
735 RCU_CFG0 &= ~RCU_CFG0_SCS;
736 RCU_CFG0 |= RCU_CKSYSSRC_PLL;
737
738 /* wait until PLL is selected as system clock */
739 while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
740 }
741 }
742
743 #elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL)
744 /*!
745 \brief configure the system clock to 108M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source
746 \param[in] none
747 \param[out] none
748 \retval none
749 */
750
system_clock_108m_hxtal(void)751 static void system_clock_108m_hxtal(void)
752 {
753 uint32_t timeout = 0U;
754 uint32_t stab_flag = 0U;
755
756 /* enable HXTAL */
757 RCU_CTL |= RCU_CTL_HXTALEN;
758
759 /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
760 do{
761 timeout++;
762 stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
763 }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
764
765 /* if fail */
766 if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
767 while(1){
768 }
769 }
770
771 /* HXTAL is stable */
772 /* AHB = SYSCLK */
773 RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
774 /* APB2 = AHB/1 */
775 RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
776 /* APB1 = AHB/2 */
777 RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
778
779 /* CK_PLL = (CK_PREDIV0) * 27 = 108 MHz */
780 RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
781 RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL27);
782
783 if(HXTAL_VALUE==25000000){
784 /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
785 RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0);
786 RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PREDV1_DIV5 | RCU_PLL1_MUL8 | RCU_PREDV0_DIV10);
787
788 /* enable PLL1 */
789 RCU_CTL |= RCU_CTL_PLL1EN;
790 /* wait till PLL1 is ready */
791 while(0U == (RCU_CTL & RCU_CTL_PLL1STB)){
792 }
793
794 /* enable PLL1 */
795 RCU_CTL |= RCU_CTL_PLL2EN;
796 /* wait till PLL1 is ready */
797 while(0U == (RCU_CTL & RCU_CTL_PLL2STB)){
798 }
799 }else if(HXTAL_VALUE==8000000){
800 RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0);
801 RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 | RCU_PREDV1_DIV2 | RCU_PLL1_MUL20 | RCU_PLL2_MUL20);
802
803 /* enable PLL1 */
804 RCU_CTL |= RCU_CTL_PLL1EN;
805 /* wait till PLL1 is ready */
806 while(0U == (RCU_CTL & RCU_CTL_PLL1STB)){
807 }
808
809 /* enable PLL2 */
810 RCU_CTL |= RCU_CTL_PLL2EN;
811 /* wait till PLL1 is ready */
812 while(0U == (RCU_CTL & RCU_CTL_PLL2STB)){
813 }
814
815 }
816 /* enable PLL */
817 RCU_CTL |= RCU_CTL_PLLEN;
818
819 /* wait until PLL is stable */
820 while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
821 }
822
823 /* select PLL as system clock */
824 RCU_CFG0 &= ~RCU_CFG0_SCS;
825 RCU_CFG0 |= RCU_CKSYSSRC_PLL;
826
827 /* wait until PLL is selected as system clock */
828 while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
829 }
830 }
831
832 #elif defined (__SYSTEM_CLOCK_48M_PLL_IRC8M)
833 /*!
834 \brief configure the system clock to 48M by PLL which selects IRC8M as its clock source
835 \param[in] none
836 \param[out] none
837 \retval none
838 */
system_clock_48m_irc8m(void)839 static void system_clock_48m_irc8m(void)
840 {
841 uint32_t timeout = 0U;
842 uint32_t stab_flag = 0U;
843
844 /* enable IRC8M */
845 RCU_CTL |= RCU_CTL_IRC8MEN;
846
847 /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
848 do{
849 timeout++;
850 stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
851 }
852 while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
853
854 /* if fail */
855 if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){
856 while(1){
857 }
858 }
859
860 /* IRC8M is stable */
861 /* AHB = SYSCLK */
862 RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
863 /* APB2 = AHB/1 */
864 RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
865 /* APB1 = AHB/2 */
866 RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
867
868 /* CK_PLL = (CK_IRC8M/2) * 12 = 48 MHz */
869 RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
870 RCU_CFG0 |= RCU_PLL_MUL12;
871
872 /* enable PLL */
873 RCU_CTL |= RCU_CTL_PLLEN;
874
875 /* wait until PLL is stable */
876 while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
877 }
878
879 /* select PLL as system clock */
880 RCU_CFG0 &= ~RCU_CFG0_SCS;
881 RCU_CFG0 |= RCU_CKSYSSRC_PLL;
882
883 /* wait until PLL is selected as system clock */
884 while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
885 }
886 }
887
888 #elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M)
889 /*!
890 \brief configure the system clock to 72M by PLL which selects IRC8M as its clock source
891 \param[in] none
892 \param[out] none
893 \retval none
894 */
system_clock_72m_irc8m(void)895 static void system_clock_72m_irc8m(void)
896 {
897 uint32_t timeout = 0U;
898 uint32_t stab_flag = 0U;
899
900 /* enable IRC8M */
901 RCU_CTL |= RCU_CTL_IRC8MEN;
902
903 /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
904 do{
905 timeout++;
906 stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
907 }
908 while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
909
910 /* if fail */
911 if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){
912 while(1){
913 }
914 }
915
916 /* IRC8M is stable */
917 /* AHB = SYSCLK */
918 RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
919 /* APB2 = AHB/1 */
920 RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
921 /* APB1 = AHB/2 */
922 RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
923
924 /* CK_PLL = (CK_IRC8M/2) * 18 = 72 MHz */
925 RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
926 RCU_CFG0 |= RCU_PLL_MUL18;
927
928 /* enable PLL */
929 RCU_CTL |= RCU_CTL_PLLEN;
930
931 /* wait until PLL is stable */
932 while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
933 }
934
935 /* select PLL as system clock */
936 RCU_CFG0 &= ~RCU_CFG0_SCS;
937 RCU_CFG0 |= RCU_CKSYSSRC_PLL;
938
939 /* wait until PLL is selected as system clock */
940 while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
941 }
942 }
943
944 #elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M)
945 /*!
946 \brief configure the system clock to 108M by PLL which selects IRC8M as its clock source
947 \param[in] none
948 \param[out] none
949 \retval none
950 */
system_clock_108m_irc8m(void)951 static void system_clock_108m_irc8m(void)
952 {
953 uint32_t timeout = 0U;
954 uint32_t stab_flag = 0U;
955
956 /* enable IRC8M */
957 RCU_CTL |= RCU_CTL_IRC8MEN;
958
959 /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
960 do{
961 timeout++;
962 stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
963 }
964 while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
965
966 /* if fail */
967 if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){
968 while(1){
969 }
970 }
971
972 /* IRC8M is stable */
973 /* AHB = SYSCLK */
974 RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
975 /* APB2 = AHB/1 */
976 RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
977 /* APB1 = AHB/2 */
978 RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
979
980 /* CK_PLL = (CK_IRC8M/2) * 27 = 108 MHz */
981 RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
982 RCU_CFG0 |= RCU_PLL_MUL27;
983
984 /* enable PLL */
985 RCU_CTL |= RCU_CTL_PLLEN;
986
987 /* wait until PLL is stable */
988 while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
989 }
990
991 /* select PLL as system clock */
992 RCU_CFG0 &= ~RCU_CFG0_SCS;
993 RCU_CFG0 |= RCU_CKSYSSRC_PLL;
994
995 /* wait until PLL is selected as system clock */
996 while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
997 }
998 }
999
1000 #endif
1001