1 /*
2 * Copyright 2017-2019 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_clock.h"
9 /*******************************************************************************
10 * Definitions
11 ******************************************************************************/
12 /* Component ID definition, used by tools. */
13 #ifndef FSL_COMPONENT_ID
14 #define FSL_COMPONENT_ID "platform.drivers.clock"
15 #endif
16 #define SYSPLL_MIN_INPUT_FREQ_HZ (10000000U) /*!< Minimum PLL input rate */
17 #define SYSPLL_MAX_INPUT_FREQ_HZ (25000000U) /*!< Maximum PLL input rate */
18 #define SYSPLL_MAX_OUTPUT_FREQ_HZ (100000000U) /*!< Maximum PLL output rate */
19 #define SYSPLL_MIN_FCCO_FREQ_HZ (156000000U) /*!< Maximum FCCO output rate */
20 #define SYSPLL_MAX_FCCO_FREQ_HZ (320000000U) /*!< Maximum FCCO output rate */
21 #define SYSOSC_BOUNDARY_FREQ_HZ (15000000U) /*!< boundary frequency value */
22
23 /* External clock rate.
24 * Either external clk in rate or system oscillator frequency.
25 */
26 volatile uint32_t g_Ext_Clk_Freq = 0U;
27 /** watch dog oscillator rate in Hz.*/
28 volatile uint32_t g_Wdt_Osc_Freq = 0U;
29
30 /*******************************************************************************
31 * Variables
32 ******************************************************************************/
33
34 /*******************************************************************************
35 * Prototypes
36 ******************************************************************************/
37 /*
38 * @brief select post divider for system pll according to the target frequency.
39 * @param outFreq: Value to be output
40 * @return post divider
41 */
42 static uint32_t findSyestemPllPsel(uint32_t outFreq);
43
44 /*
45 * @brief Get FRG input clock frequency.
46 * @param fractional clock register base address.
47 * @return input clock frequency.
48 */
49 static uint32_t CLOCK_GetFRGInputClkFreq(uint32_t *base);
50
51 /*
52 * @brief Update clock source.
53 * @param base clock register base address.
54 * @param mask clock source update enable bit mask value.
55 */
56 static void CLOCK_UpdateClkSrc(volatile uint32_t *base, uint32_t mask);
57
58 /*******************************************************************************
59 * Code
60 ******************************************************************************/
CLOCK_GetFRGInputClkFreq(uint32_t * base)61 static uint32_t CLOCK_GetFRGInputClkFreq(uint32_t *base)
62 {
63 uint32_t sel = CLK_FRG_SEL_REG_MAP(base) & SYSCON_FRG_FRGCLKSEL_SEL_MASK;
64
65 if (sel == 0U)
66 {
67 return CLOCK_GetFroFreq();
68 }
69 else if (sel == 1U)
70 {
71 return CLOCK_GetMainClkFreq();
72 }
73 else
74 {
75 return CLOCK_GetSystemPLLFreq();
76 }
77 }
78
CLOCK_SetFRGClkFreq(uint32_t * base,uint32_t freq)79 static bool CLOCK_SetFRGClkFreq(uint32_t *base, uint32_t freq)
80 {
81 assert(freq);
82
83 uint32_t input = CLOCK_GetFRGInputClkFreq(base);
84 uint32_t mul;
85
86 if ((freq > input) || (input / freq >= 2U))
87 {
88 return false;
89 }
90
91 mul = (uint32_t)(((uint64_t)((uint64_t)input - freq) << 8U) / ((uint64_t)freq));
92
93 CLK_FRG_DIV_REG_MAP(base) = SYSCON_FRG_FRGDIV_DIV_MASK;
94 CLK_FRG_MUL_REG_MAP(base) = SYSCON_FRG_FRGMULT_MULT(mul);
95
96 return true;
97 }
98
CLOCK_UpdateClkSrc(volatile uint32_t * base,uint32_t mask)99 static void CLOCK_UpdateClkSrc(volatile uint32_t *base, uint32_t mask)
100 {
101 assert(base);
102
103 *base &= ~mask;
104 *base |= mask;
105 while ((*base & mask) == 0U)
106 {
107 }
108 }
109
110 /*! brief Set FRG0 output frequency.
111 * param freq, target output frequency,freq < input and (input / freq) < 2 should be satisfy.
112 * retval true - successfully, false - input argument is invalid.
113 *
114 */
CLOCK_SetFRG0ClkFreq(uint32_t freq)115 bool CLOCK_SetFRG0ClkFreq(uint32_t freq)
116 {
117 return CLOCK_SetFRGClkFreq(((uint32_t *)(uint32_t)(&SYSCON->FRG[0U])), freq);
118 }
119
120 /*! brief Set FRG1 output frequency.
121 * param freq, target output frequency,freq < input and (input / freq) < 2 should be satisfy.
122 * retval true - successfully, false - input argument is invalid.
123 *
124 */
CLOCK_SetFRG1ClkFreq(uint32_t freq)125 bool CLOCK_SetFRG1ClkFreq(uint32_t freq)
126 {
127 return CLOCK_SetFRGClkFreq(((uint32_t *)(uint32_t)(&SYSCON->FRG[1U])), freq);
128 }
129
130 /*! brief Return Frequency of FRG0 Clock.
131 * return Frequency of FRG0 Clock.
132 */
CLOCK_GetFRG0ClkFreq(void)133 uint32_t CLOCK_GetFRG0ClkFreq(void)
134 {
135 uint32_t temp;
136
137 temp = CLOCK_GetFRGInputClkFreq((uint32_t *)(uint32_t)(&SYSCON->FRG[0U])) << 8U;
138 return (uint32_t)((uint64_t)(temp) / (((uint64_t)SYSCON->FRG[0U].FRGMULT & SYSCON_FRG_FRGMULT_MULT_MASK) + 256ULL));
139 }
140
141 /*! brief Return Frequency of FRG1 Clock.
142 * return Frequency of FRG1 Clock.
143 */
CLOCK_GetFRG1ClkFreq(void)144 uint32_t CLOCK_GetFRG1ClkFreq(void)
145 {
146 uint32_t temp;
147
148 temp = (CLOCK_GetFRGInputClkFreq((uint32_t *)(uint32_t)(&SYSCON->FRG[1U])) << 8U);
149 return (uint32_t)(((uint64_t)temp) / (((uint64_t)SYSCON->FRG[1U].FRGMULT & SYSCON_FRG_FRGMULT_MULT_MASK) + 256ULL));
150 }
151
152 /*! brief Return Frequency of Main Clock.
153 * return Frequency of Main Clock.
154 */
CLOCK_GetMainClkFreq(void)155 uint32_t CLOCK_GetMainClkFreq(void)
156 {
157 uint32_t freq = 0U;
158
159 if ((SYSCON->MAINCLKPLLSEL & SYSCON_MAINCLKPLLSEL_SEL_MASK) == 1U)
160 {
161 return CLOCK_GetSystemPLLFreq();
162 }
163
164 switch (SYSCON->MAINCLKSEL)
165 {
166 case 0U:
167 freq = CLOCK_GetFroFreq();
168 break;
169
170 case 1U:
171 freq = CLOCK_GetExtClkFreq();
172 break;
173
174 case 2U:
175 freq = CLOCK_GetWdtOscFreq();
176 break;
177
178 case 3U:
179 freq = CLOCK_GetFroFreq() >> 1U;
180 break;
181 default:
182 freq = 0U;
183 break;
184 }
185
186 return freq;
187 }
188
189 /*! brief Return Frequency of FRO.
190 * return Frequency of FRO.
191 */
CLOCK_GetFroFreq(void)192 uint32_t CLOCK_GetFroFreq(void)
193 {
194 uint32_t froOscSel = SYSCON->FROOSCCTRL & 3U;
195 uint32_t froOscFreq = 0U;
196
197 if (froOscSel == 0U)
198 {
199 froOscFreq = 18000000U;
200 }
201 else if (froOscSel == 1U)
202 {
203 froOscFreq = 24000000U;
204 }
205 else
206 {
207 froOscFreq = 30000000U;
208 }
209
210 if (((SYSCON->FROOSCCTRL & SYSCON_FROOSCCTRL_FRO_DIRECT_MASK) >> SYSCON_FROOSCCTRL_FRO_DIRECT_SHIFT) == 0U)
211 {
212 /* need to check the FAIM low power boot value */
213 froOscFreq /= ((*((volatile uint32_t *)(CLOCK_FAIM_BASE)) & 0x2U) != 0UL) ? 16U : 2U;
214 }
215
216 return froOscFreq;
217 }
218
219 /*! brief Return Frequency of ClockOut
220 * return Frequency of ClockOut
221 */
CLOCK_GetClockOutClkFreq(void)222 uint32_t CLOCK_GetClockOutClkFreq(void)
223 {
224 uint32_t divider = SYSCON->CLKOUTDIV & 0xffU, freq = 0U;
225
226 switch (SYSCON->CLKOUTSEL)
227 {
228 case 0U:
229 freq = CLOCK_GetFroFreq();
230 break;
231
232 case 1U:
233 freq = CLOCK_GetMainClkFreq();
234 break;
235
236 case 2U:
237 freq = CLOCK_GetSystemPLLFreq();
238 break;
239
240 case 3U:
241 freq = CLOCK_GetExtClkFreq();
242 break;
243
244 case 4U:
245 freq = CLOCK_GetWdtOscFreq();
246 break;
247
248 default:
249 freq = 0U;
250 break;
251 }
252
253 return divider == 0U ? 0U : (freq / divider);
254 }
255
256 /*! brief Return Frequency of UART0
257 * return Frequency of UART0
258 */
CLOCK_GetUart0ClkFreq(void)259 uint32_t CLOCK_GetUart0ClkFreq(void)
260 {
261 uint32_t freq = 0U;
262
263 switch (SYSCON->FCLKSEL[0])
264 {
265 case 0U:
266 freq = CLOCK_GetFroFreq();
267 break;
268 case 1U:
269 freq = CLOCK_GetMainClkFreq();
270 break;
271 case 2U:
272 freq = CLOCK_GetFRG0ClkFreq();
273 break;
274 case 3U:
275 freq = CLOCK_GetFRG1ClkFreq();
276 break;
277 case 4U:
278 freq = CLOCK_GetFroFreq() >> 1U;
279 break;
280
281 default:
282 freq = 0U;
283 break;
284 }
285
286 return freq;
287 }
288
289 /*! brief Return Frequency of UART1
290 * return Frequency of UART1
291 */
CLOCK_GetUart1ClkFreq(void)292 uint32_t CLOCK_GetUart1ClkFreq(void)
293 {
294 uint32_t freq = 0U;
295
296 switch (SYSCON->FCLKSEL[1])
297 {
298 case 0U:
299 freq = CLOCK_GetFroFreq();
300 break;
301 case 1U:
302 freq = CLOCK_GetMainClkFreq();
303 break;
304 case 2U:
305 freq = CLOCK_GetFRG0ClkFreq();
306 break;
307 case 3U:
308 freq = CLOCK_GetFRG1ClkFreq();
309 break;
310 case 4U:
311 freq = CLOCK_GetFroFreq() >> 1U;
312 break;
313
314 default:
315 freq = 0U;
316 break;
317 }
318
319 return freq;
320 }
321
322 /*! brief Return Frequency of UART2
323 * return Frequency of UART2
324 */
CLOCK_GetUart2ClkFreq(void)325 uint32_t CLOCK_GetUart2ClkFreq(void)
326 {
327 uint32_t freq = 0U;
328
329 switch (SYSCON->FCLKSEL[2])
330 {
331 case 0U:
332 freq = CLOCK_GetFroFreq();
333 break;
334 case 1U:
335 freq = CLOCK_GetMainClkFreq();
336 break;
337 case 2U:
338 freq = CLOCK_GetFRG0ClkFreq();
339 break;
340 case 3U:
341 freq = CLOCK_GetFRG1ClkFreq();
342 break;
343 case 4U:
344 freq = CLOCK_GetFroFreq() >> 1U;
345 break;
346
347 default:
348 freq = 0U;
349 break;
350 }
351
352 return freq;
353 }
354
355 /*! brief Return Frequency of UART3
356 * return Frequency of UART3
357 */
CLOCK_GetUart3ClkFreq(void)358 uint32_t CLOCK_GetUart3ClkFreq(void)
359 {
360 uint32_t freq = 0U;
361
362 switch (SYSCON->FCLKSEL[3])
363 {
364 case 0U:
365 freq = CLOCK_GetFroFreq();
366 break;
367 case 1U:
368 freq = CLOCK_GetMainClkFreq();
369 break;
370 case 2U:
371 freq = CLOCK_GetFRG0ClkFreq();
372 break;
373 case 3U:
374 freq = CLOCK_GetFRG1ClkFreq();
375 break;
376 case 4U:
377 freq = CLOCK_GetFroFreq() >> 1U;
378 break;
379
380 default:
381 freq = 0U;
382 break;
383 }
384
385 return freq;
386 }
387
388 /*! brief Return Frequency of UART4
389 * return Frequency of UART4
390 */
CLOCK_GetUart4ClkFreq(void)391 uint32_t CLOCK_GetUart4ClkFreq(void)
392 {
393 uint32_t freq = 0U;
394
395 switch (SYSCON->FCLKSEL[4])
396 {
397 case 0U:
398 freq = CLOCK_GetFroFreq();
399 break;
400 case 1U:
401 freq = CLOCK_GetMainClkFreq();
402 break;
403 case 2U:
404 freq = CLOCK_GetFRG0ClkFreq();
405 break;
406 case 3U:
407 freq = CLOCK_GetFRG1ClkFreq();
408 break;
409 case 4U:
410 freq = CLOCK_GetFroFreq() >> 1U;
411 break;
412
413 default:
414 freq = 0U;
415 break;
416 }
417
418 return freq;
419 }
420
421 /*! brief Return Frequency of selected clock
422 * return Frequency of selected clock
423 */
CLOCK_GetFreq(clock_name_t clockName)424 uint32_t CLOCK_GetFreq(clock_name_t clockName)
425 {
426 uint32_t freq;
427
428 switch (clockName)
429 {
430 case kCLOCK_CoreSysClk:
431 freq = CLOCK_GetCoreSysClkFreq();
432 break;
433 case kCLOCK_MainClk:
434 freq = CLOCK_GetMainClkFreq();
435 break;
436 case kCLOCK_Fro:
437 freq = CLOCK_GetFroFreq();
438 break;
439 case kCLOCK_FroDiv:
440 freq = CLOCK_GetFroFreq() >> 1U;
441 break;
442 case kCLOCK_ExtClk:
443 freq = CLOCK_GetExtClkFreq();
444 break;
445 case kCLOCK_WdtOsc:
446 freq = CLOCK_GetWdtOscFreq();
447 break;
448 case kCLOCK_PllOut:
449 freq = CLOCK_GetSystemPLLFreq();
450 break;
451 case kCLOCK_Frg0:
452 freq = CLOCK_GetFRG0ClkFreq();
453 break;
454 case kCLOCK_Frg1:
455 freq = CLOCK_GetFRG1ClkFreq();
456 break;
457
458 default:
459 freq = 0U;
460 break;
461 }
462
463 return freq;
464 }
465
466 /*! brief Return System PLL input clock rate
467 * return System PLL input clock rate
468 */
CLOCK_GetSystemPLLInClockRate(void)469 uint32_t CLOCK_GetSystemPLLInClockRate(void)
470 {
471 uint32_t freq = 0U;
472
473 switch ((SYSCON->SYSPLLCLKSEL))
474 {
475 /* source from fro div clock */
476 case 0x03U:
477 freq = CLOCK_GetFroFreq() >> 1U;
478 break;
479 /* source from the fro clock */
480 case 0x00U:
481 freq = CLOCK_GetFroFreq();
482 break;
483 /* source from external clock in */
484 case 0x01U:
485 freq = CLOCK_GetExtClkFreq();
486 break;
487 /* source from watchdog oscillator */
488 case 0x02U:
489 freq = CLOCK_GetWdtOscFreq();
490 break;
491
492 default:
493 freq = 0U;
494 break;
495 }
496
497 return freq;
498 }
499
findSyestemPllPsel(uint32_t outFreq)500 static uint32_t findSyestemPllPsel(uint32_t outFreq)
501 {
502 uint32_t pSel = 0U;
503
504 if (outFreq > (SYSPLL_MIN_FCCO_FREQ_HZ >> 1U))
505 {
506 pSel = 0U;
507 }
508 else if (outFreq > (SYSPLL_MIN_FCCO_FREQ_HZ >> 2U))
509 {
510 pSel = 1U;
511 }
512 else if (outFreq > (SYSPLL_MIN_FCCO_FREQ_HZ >> 3U))
513 {
514 pSel = 2U;
515 }
516 else
517 {
518 pSel = 3U;
519 }
520
521 return pSel;
522 }
523
524 /*! brief System PLL initialize.
525 * param config System PLL configurations.
526 */
CLOCK_InitSystemPll(const clock_sys_pll_t * config)527 void CLOCK_InitSystemPll(const clock_sys_pll_t *config)
528 {
529 assert(config->targetFreq <= SYSPLL_MAX_OUTPUT_FREQ_HZ);
530
531 uint32_t mSel = 0U, pSel = 0U, inputFreq = 0U;
532 uint32_t syspllclkseltmp;
533 /* Power off PLL during setup changes */
534 SYSCON->PDRUNCFG |= SYSCON_PDRUNCFG_SYSPLL_PD_MASK;
535
536 /*set system pll clock source select register */
537 syspllclkseltmp = (SYSCON->SYSPLLCLKSEL & (~SYSCON_SYSPLLCLKSEL_SEL_MASK)) | (uint32_t)(config->src);
538 SYSCON->SYSPLLCLKSEL |= syspllclkseltmp;
539 /* system pll clock source update */
540 CLOCK_UpdateClkSrc((volatile uint32_t *)(&(SYSCON->SYSPLLCLKUEN)), SYSCON_SYSPLLCLKSEL_SEL_MASK);
541
542 inputFreq = CLOCK_GetSystemPLLInClockRate();
543 assert(inputFreq != 0U);
544
545 /* calucate the feedback divider value and post divider value*/
546 mSel = config->targetFreq / inputFreq;
547 pSel = findSyestemPllPsel(config->targetFreq);
548
549 /* configure PSEL and MSEL */
550 SYSCON->SYSPLLCTRL = (SYSCON->SYSPLLCTRL & (~(SYSCON_SYSPLLCTRL_MSEL_MASK | SYSCON_SYSPLLCTRL_PSEL_MASK))) |
551 SYSCON_SYSPLLCTRL_MSEL(mSel == 0U ? 0U : (mSel - 1U)) | SYSCON_SYSPLLCTRL_PSEL(pSel);
552
553 /* Power up PLL after setup changes */
554 SYSCON->PDRUNCFG &= ~SYSCON_PDRUNCFG_SYSPLL_PD_MASK;
555
556 /* wait pll lock */
557 while ((SYSCON->SYSPLLSTAT & SYSCON_SYSPLLSTAT_LOCK_MASK) == 0U)
558 {
559 }
560 }
561
562 /*! brief Init external CLK IN, select the CLKIN as the external clock source.
563 * param clkInFreq external clock in frequency.
564 */
CLOCK_InitExtClkin(uint32_t clkInFreq)565 void CLOCK_InitExtClkin(uint32_t clkInFreq)
566 {
567 /* remove the pull up and pull down resistors in the IOCON */
568 IOCON->PIO[IOCON_INDEX_PIO0_1] &= ~IOCON_PIO_MODE_MASK;
569 /* enable the 1 bit functions for CLKIN */
570 SWM0->PINENABLE0 &= ~SWM_PINENABLE0_CLKIN_MASK;
571 /* enable the external clk in */
572 SYSCON->EXTCLKSEL |= SYSCON_EXTCLKSEL_SEL_MASK;
573 /* record the external clock rate */
574 g_Ext_Clk_Freq = clkInFreq;
575 }
576
577 /*! brief XTALIN init function
578 * system oscillator is bypassed, sys_osc_clk is fed driectly from the XTALIN.
579 * param xtalInFreq XTALIN frequency value
580 * return Frequency of PLL
581 */
CLOCK_InitXtalin(uint32_t xtalInFreq)582 void CLOCK_InitXtalin(uint32_t xtalInFreq)
583 {
584 /* remove the pull up and pull down resistors in the IOCON */
585 IOCON->PIO[IOCON_INDEX_PIO0_8] &= ~IOCON_PIO_MODE_MASK;
586 /* enable the 1 bit functions for XTALIN and XTALOUT */
587 SWM0->PINENABLE0 &= ~SWM_PINENABLE0_XTALIN_MASK;
588
589 /* system osc configure */
590 SYSCON->SYSOSCCTRL |= SYSCON_SYSOSCCTRL_BYPASS_MASK;
591 /* external clock select */
592 SYSCON->EXTCLKSEL &= ~SYSCON_EXTCLKSEL_SEL_MASK;
593 /* enable system osc power first */
594 SYSCON->PDRUNCFG &= ~SYSCON_PDRUNCFG_SYSOSC_PD_MASK;
595
596 /* software delay 500USs */
597 SDK_DelayAtLeastUs(500U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
598
599 /* record the external clock rate */
600 g_Ext_Clk_Freq = xtalInFreq;
601 }
602
603 /*! brief Init SYS OSC
604 * param oscFreq oscillator frequency value.
605 */
CLOCK_InitSysOsc(uint32_t oscFreq)606 void CLOCK_InitSysOsc(uint32_t oscFreq)
607 {
608 uint32_t sysoscctrltmp;
609 /* remove the pull up and pull down resistors in the IOCON */
610 IOCON->PIO[IOCON_INDEX_PIO0_9] &= ~IOCON_PIO_MODE_MASK;
611 IOCON->PIO[IOCON_INDEX_PIO0_8] &= ~IOCON_PIO_MODE_MASK;
612 /* enable the 1 bit functions for XTALIN and XTALOUT */
613 SWM0->PINENABLE0 &= ~(SWM_PINENABLE0_XTALIN_MASK | SWM_PINENABLE0_XTALOUT_MASK);
614
615 /* system osc configure */
616 sysoscctrltmp = (SYSCON->SYSOSCCTRL & (~(SYSCON_SYSOSCCTRL_BYPASS_MASK | SYSCON_SYSOSCCTRL_FREQRANGE_MASK))) |
617 (oscFreq > SYSOSC_BOUNDARY_FREQ_HZ ? SYSCON_SYSOSCCTRL_FREQRANGE_MASK : 0U);
618 SYSCON->SYSOSCCTRL |= sysoscctrltmp;
619 /* external clock select */
620 SYSCON->EXTCLKSEL &= ~SYSCON_EXTCLKSEL_SEL_MASK;
621
622 /* enable system osc power first */
623 SYSCON->PDRUNCFG &= ~SYSCON_PDRUNCFG_SYSOSC_PD_MASK;
624
625 /* software delay 500USs */
626 SDK_DelayAtLeastUs(500U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
627
628 /* record the external clock rate */
629 g_Ext_Clk_Freq = oscFreq;
630 }
631
632 /*! brief Init watch dog OSC
633 * Any setting of the FREQSEL bits will yield a Fclkana value within 40% of the
634 * listed frequency value. The watchdog oscillator is the clock source with the lowest power
635 * consumption. If accurate timing is required, use the FRO or system oscillator.
636 * The frequency of the watchdog oscillator is undefined after reset. The watchdog
637 * oscillator frequency must be programmed by writing to the WDTOSCCTRL register before
638 * using the watchdog oscillator.
639 * Watchdog osc output frequency = wdtOscFreq / wdtOscDiv, should in range 9.3KHZ to 2.3MHZ.
640 * param wdtOscFreq watch dog analog part output frequency, reference _wdt_analog_output_freq.
641 * param wdtOscDiv watch dog analog part output frequency divider, shoule be a value >= 2U and multiple of 2
642 */
CLOCK_InitWdtOsc(clock_wdt_analog_freq_t wdtOscFreq,uint32_t wdtOscDiv)643 void CLOCK_InitWdtOsc(clock_wdt_analog_freq_t wdtOscFreq, uint32_t wdtOscDiv)
644 {
645 assert(wdtOscDiv >= 2U);
646
647 uint32_t wdtOscCtrl = SYSCON->WDTOSCCTRL;
648
649 wdtOscCtrl &= ~(SYSCON_WDTOSCCTRL_DIVSEL_MASK | SYSCON_WDTOSCCTRL_FREQSEL_MASK);
650
651 wdtOscCtrl |= SYSCON_WDTOSCCTRL_DIVSEL((wdtOscDiv >> 1U) - 1U) |
652 SYSCON_WDTOSCCTRL_FREQSEL(CLK_WDT_OSC_GET_REG((uint32_t)wdtOscFreq));
653
654 SYSCON->WDTOSCCTRL = wdtOscCtrl;
655
656 /* power up watchdog oscillator */
657 SYSCON->PDRUNCFG &= ~SYSCON_PDRUNCFG_WDTOSC_PD_MASK;
658 /* update watch dog oscillator value */
659 g_Wdt_Osc_Freq = CLK_WDT_OSC_GET_FREQ(wdtOscFreq) / wdtOscDiv;
660 }
661
662 /*! brief Set main clock reference source.
663 * param src, reference clock_main_clk_src_t to set the main clock source.
664 */
CLOCK_SetMainClkSrc(clock_main_clk_src_t src)665 void CLOCK_SetMainClkSrc(clock_main_clk_src_t src)
666 {
667 uint32_t mainMux = CLK_MAIN_CLK_MUX_GET_MUX(src), mainPreMux = CLK_MAIN_CLK_MUX_GET_PRE_MUX(src);
668
669 if (((SYSCON->MAINCLKSEL & SYSCON_MAINCLKSEL_SEL_MASK) != mainPreMux) && (mainMux == 0U))
670 {
671 SYSCON->MAINCLKSEL = (SYSCON->MAINCLKSEL & (~SYSCON_MAINCLKSEL_SEL_MASK)) | SYSCON_MAINCLKSEL_SEL(mainPreMux);
672 CLOCK_UpdateClkSrc((volatile uint32_t *)(&(SYSCON->MAINCLKUEN)), SYSCON_MAINCLKUEN_ENA_MASK);
673 }
674
675 if ((SYSCON->MAINCLKPLLSEL & SYSCON_MAINCLKPLLSEL_SEL_MASK) != mainMux)
676 {
677 SYSCON->MAINCLKPLLSEL =
678 (SYSCON->MAINCLKPLLSEL & (~SYSCON_MAINCLKPLLSEL_SEL_MASK)) | SYSCON_MAINCLKPLLSEL_SEL(mainMux);
679 CLOCK_UpdateClkSrc((volatile uint32_t *)(&(SYSCON->MAINCLKPLLUEN)), SYSCON_MAINCLKPLLUEN_ENA_MASK);
680 }
681 }
682
683 /*! brief Set FRO clock source
684 * param src, please reference _clock_fro_src definition.
685 *
686 */
CLOCK_SetFroOutClkSrc(clock_fro_src_t src)687 void CLOCK_SetFroOutClkSrc(clock_fro_src_t src)
688 {
689 if ((uint32_t)src != (SYSCON->FROOSCCTRL & SYSCON_FROOSCCTRL_FRO_DIRECT_MASK))
690 {
691 SYSCON->FROOSCCTRL = (SYSCON->FROOSCCTRL & (~SYSCON_FROOSCCTRL_FRO_DIRECT_MASK)) | (uint32_t)src;
692 /* Update clock source */
693 CLOCK_UpdateClkSrc((volatile uint32_t *)(&(SYSCON->FRODIRECTCLKUEN)), SYSCON_FRODIRECTCLKUEN_ENA_MASK);
694 }
695 }
696
697 /*! brief Set the flash wait states for the input freuqency.
698 * param iFreq : Input frequency
699 */
CLOCK_SetFLASHAccessCyclesForFreq(uint32_t iFreq)700 void CLOCK_SetFLASHAccessCyclesForFreq(uint32_t iFreq)
701 {
702 uint32_t num_wait_states;
703 if (iFreq <= 24000000UL)
704 {
705 /* [0 - 24 MHz] */
706 num_wait_states = 0UL;
707 }
708 else
709 {
710 /* Above 24 MHz */
711 num_wait_states = 1UL;
712 }
713
714 FLASH_CTRL->FLASHCFG =
715 ((FLASH_CTRL->FLASHCFG & ~FLASH_CTRL_FLASHCFG_FLASHTIM_MASK) | FLASH_CTRL_FLASHCFG_FLASHTIM(num_wait_states));
716 }
717