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