diff options
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/devices/LPC844/drivers/fsl_clock.c')
-rw-r--r-- | lib/chibios-contrib/ext/mcux-sdk/devices/LPC844/drivers/fsl_clock.c | 691 |
1 files changed, 691 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/LPC844/drivers/fsl_clock.c b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC844/drivers/fsl_clock.c new file mode 100644 index 000000000..1ef429740 --- /dev/null +++ b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC844/drivers/fsl_clock.c | |||
@@ -0,0 +1,691 @@ | |||
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 | ******************************************************************************/ | ||
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 | |||
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 | |||
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 | */ | ||
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 | */ | ||
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 | */ | ||
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 | */ | ||
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 | */ | ||
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 | */ | ||
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 | */ | ||
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 | */ | ||
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 | */ | ||
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 | */ | ||
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 | */ | ||
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 | */ | ||
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 | */ | ||
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 | */ | ||
469 | uint32_t CLOCK_GetSystemPLLInClockRate(void) | ||
470 | { | ||
471 | uint32_t freq = 0U; | ||
472 | |||
473 | switch ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK)) | ||
474 | { | ||
475 | case 0x03U: | ||
476 | freq = CLOCK_GetFroFreq() >> 1U; | ||
477 | break; | ||
478 | case 0x00U: | ||
479 | freq = CLOCK_GetFroFreq(); | ||
480 | break; | ||
481 | case 0x01U: | ||
482 | freq = CLOCK_GetExtClkFreq(); | ||
483 | break; | ||
484 | case 0x02U: | ||
485 | freq = CLOCK_GetWdtOscFreq(); | ||
486 | break; | ||
487 | |||
488 | default: | ||
489 | freq = 0U; | ||
490 | break; | ||
491 | } | ||
492 | |||
493 | return freq; | ||
494 | } | ||
495 | |||
496 | static uint32_t findSyestemPllPsel(uint32_t outFreq) | ||
497 | { | ||
498 | uint32_t pSel = 0U; | ||
499 | |||
500 | if (outFreq > (SYSPLL_MIN_FCCO_FREQ_HZ >> 1U)) | ||
501 | { | ||
502 | pSel = 0U; | ||
503 | } | ||
504 | else if (outFreq > (SYSPLL_MIN_FCCO_FREQ_HZ >> 2U)) | ||
505 | { | ||
506 | pSel = 1U; | ||
507 | } | ||
508 | else if (outFreq > (SYSPLL_MIN_FCCO_FREQ_HZ >> 3U)) | ||
509 | { | ||
510 | pSel = 2U; | ||
511 | } | ||
512 | else | ||
513 | { | ||
514 | pSel = 3U; | ||
515 | } | ||
516 | |||
517 | return pSel; | ||
518 | } | ||
519 | |||
520 | /*! brief System PLL initialize. | ||
521 | * param config System PLL configurations. | ||
522 | */ | ||
523 | void CLOCK_InitSystemPll(const clock_sys_pll_t *config) | ||
524 | { | ||
525 | assert(config->targetFreq <= SYSPLL_MAX_OUTPUT_FREQ_HZ); | ||
526 | |||
527 | uint32_t mSel = 0U, pSel = 0U, inputFreq = 0U; | ||
528 | uint32_t syspllclkseltmp; | ||
529 | /* Power off PLL during setup changes */ | ||
530 | SYSCON->PDRUNCFG |= SYSCON_PDRUNCFG_SYSPLL_PD_MASK; | ||
531 | |||
532 | /*set system pll clock source select register */ | ||
533 | syspllclkseltmp = (SYSCON->SYSPLLCLKSEL & (~SYSCON_SYSPLLCLKSEL_SEL_MASK)) | (uint32_t)config->src; | ||
534 | SYSCON->SYSPLLCLKSEL |= syspllclkseltmp; | ||
535 | /* system pll clock source update */ | ||
536 | CLOCK_UpdateClkSrc((volatile uint32_t *)(&(SYSCON->SYSPLLCLKUEN)), SYSCON_SYSPLLCLKSEL_SEL_MASK); | ||
537 | |||
538 | inputFreq = CLOCK_GetSystemPLLInClockRate(); | ||
539 | assert(inputFreq != 0U); | ||
540 | |||
541 | /* calucate the feedback divider value and post divider value*/ | ||
542 | mSel = config->targetFreq / inputFreq; | ||
543 | pSel = findSyestemPllPsel(config->targetFreq); | ||
544 | |||
545 | /* configure PSEL and MSEL */ | ||
546 | SYSCON->SYSPLLCTRL = (SYSCON->SYSPLLCTRL & (~(SYSCON_SYSPLLCTRL_MSEL_MASK | SYSCON_SYSPLLCTRL_PSEL_MASK))) | | ||
547 | SYSCON_SYSPLLCTRL_MSEL(mSel == 0U ? 0U : (mSel - 1U)) | SYSCON_SYSPLLCTRL_PSEL(pSel); | ||
548 | |||
549 | /* Power up PLL after setup changes */ | ||
550 | SYSCON->PDRUNCFG &= ~SYSCON_PDRUNCFG_SYSPLL_PD_MASK; | ||
551 | |||
552 | /* wait pll lock */ | ||
553 | while ((SYSCON->SYSPLLSTAT & SYSCON_SYSPLLSTAT_LOCK_MASK) == 0U) | ||
554 | { | ||
555 | } | ||
556 | } | ||
557 | |||
558 | /*! brief Init external CLK IN, select the CLKIN as the external clock source. | ||
559 | * param clkInFreq external clock in frequency. | ||
560 | */ | ||
561 | void CLOCK_InitExtClkin(uint32_t clkInFreq) | ||
562 | { | ||
563 | /* remove the pull up and pull down resistors in the IOCON */ | ||
564 | IOCON->PIO[IOCON_INDEX_PIO0_1] &= ~IOCON_PIO_MODE_MASK; | ||
565 | /* enable the 1 bit functions for CLKIN */ | ||
566 | SWM0->PINENABLE0 &= ~SWM_PINENABLE0_CLKIN_MASK; | ||
567 | /* enable the external clk in */ | ||
568 | SYSCON->EXTCLKSEL |= SYSCON_EXTCLKSEL_SEL_MASK; | ||
569 | /* record the external clock rate */ | ||
570 | g_Ext_Clk_Freq = clkInFreq; | ||
571 | } | ||
572 | |||
573 | /*! brief XTALIN init function | ||
574 | * system oscillator is bypassed, sys_osc_clk is fed driectly from the XTALIN. | ||
575 | * param xtalInFreq XTALIN frequency value | ||
576 | * return Frequency of PLL | ||
577 | */ | ||
578 | void CLOCK_InitXtalin(uint32_t xtalInFreq) | ||
579 | { | ||
580 | /* remove the pull up and pull down resistors in the IOCON */ | ||
581 | IOCON->PIO[IOCON_INDEX_PIO0_8] &= ~IOCON_PIO_MODE_MASK; | ||
582 | /* enable the 1 bit functions for XTALIN and XTALOUT */ | ||
583 | SWM0->PINENABLE0 &= ~SWM_PINENABLE0_XTALIN_MASK; | ||
584 | |||
585 | /* system osc configure */ | ||
586 | SYSCON->SYSOSCCTRL |= SYSCON_SYSOSCCTRL_BYPASS_MASK; | ||
587 | /* external clock select */ | ||
588 | SYSCON->EXTCLKSEL &= ~SYSCON_EXTCLKSEL_SEL_MASK; | ||
589 | /* enable system osc power first */ | ||
590 | SYSCON->PDRUNCFG &= ~SYSCON_PDRUNCFG_SYSOSC_PD_MASK; | ||
591 | |||
592 | /* software delay 500USs */ | ||
593 | SDK_DelayAtLeastUs(500U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); | ||
594 | |||
595 | /* record the external clock rate */ | ||
596 | g_Ext_Clk_Freq = xtalInFreq; | ||
597 | } | ||
598 | |||
599 | /*! brief Init SYS OSC | ||
600 | * param oscFreq oscillator frequency value. | ||
601 | */ | ||
602 | void CLOCK_InitSysOsc(uint32_t oscFreq) | ||
603 | { | ||
604 | uint32_t sysoscctrltmp; | ||
605 | /* remove the pull up and pull down resistors in the IOCON */ | ||
606 | IOCON->PIO[IOCON_INDEX_PIO0_9] &= ~IOCON_PIO_MODE_MASK; | ||
607 | IOCON->PIO[IOCON_INDEX_PIO0_8] &= ~IOCON_PIO_MODE_MASK; | ||
608 | /* enable the 1 bit functions for XTALIN and XTALOUT */ | ||
609 | SWM0->PINENABLE0 &= ~(SWM_PINENABLE0_XTALIN_MASK | SWM_PINENABLE0_XTALOUT_MASK); | ||
610 | |||
611 | /* system osc configure */ | ||
612 | sysoscctrltmp = (SYSCON->SYSOSCCTRL & (~(SYSCON_SYSOSCCTRL_BYPASS_MASK | SYSCON_SYSOSCCTRL_FREQRANGE_MASK))) | | ||
613 | (oscFreq > SYSOSC_BOUNDARY_FREQ_HZ ? SYSCON_SYSOSCCTRL_FREQRANGE_MASK : 0U); | ||
614 | SYSCON->SYSOSCCTRL |= sysoscctrltmp; | ||
615 | /* external clock select */ | ||
616 | SYSCON->EXTCLKSEL &= ~SYSCON_EXTCLKSEL_SEL_MASK; | ||
617 | |||
618 | /* enable system osc power first */ | ||
619 | SYSCON->PDRUNCFG &= ~SYSCON_PDRUNCFG_SYSOSC_PD_MASK; | ||
620 | |||
621 | /* software delay 500USs */ | ||
622 | SDK_DelayAtLeastUs(500U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); | ||
623 | |||
624 | /* record the external clock rate */ | ||
625 | g_Ext_Clk_Freq = oscFreq; | ||
626 | } | ||
627 | |||
628 | /*! brief Init watch dog OSC | ||
629 | * Any setting of the FREQSEL bits will yield a Fclkana value within 40% of the | ||
630 | * listed frequency value. The watchdog oscillator is the clock source with the lowest power | ||
631 | * consumption. If accurate timing is required, use the FRO or system oscillator. | ||
632 | * The frequency of the watchdog oscillator is undefined after reset. The watchdog | ||
633 | * oscillator frequency must be programmed by writing to the WDTOSCCTRL register before | ||
634 | * using the watchdog oscillator. | ||
635 | * Watchdog osc output frequency = wdtOscFreq / wdtOscDiv, should in range 9.3KHZ to 2.3MHZ. | ||
636 | * param wdtOscFreq watch dog analog part output frequency, reference _wdt_analog_output_freq. | ||
637 | * param wdtOscDiv watch dog analog part output frequency divider, shoule be a value >= 2U and multiple of 2 | ||
638 | */ | ||
639 | void CLOCK_InitWdtOsc(clock_wdt_analog_freq_t wdtOscFreq, uint32_t wdtOscDiv) | ||
640 | { | ||
641 | assert(wdtOscDiv >= 2U); | ||
642 | |||
643 | uint32_t wdtOscCtrl = SYSCON->WDTOSCCTRL; | ||
644 | |||
645 | wdtOscCtrl &= ~(SYSCON_WDTOSCCTRL_DIVSEL_MASK | SYSCON_WDTOSCCTRL_FREQSEL_MASK); | ||
646 | |||
647 | wdtOscCtrl |= | ||
648 | SYSCON_WDTOSCCTRL_DIVSEL((wdtOscDiv >> 1U) - 1U) | SYSCON_WDTOSCCTRL_FREQSEL(CLK_WDT_OSC_GET_REG(wdtOscFreq)); | ||
649 | |||
650 | SYSCON->WDTOSCCTRL = wdtOscCtrl; | ||
651 | |||
652 | /* power up watchdog oscillator */ | ||
653 | SYSCON->PDRUNCFG &= ~SYSCON_PDRUNCFG_WDTOSC_PD_MASK; | ||
654 | /* update watch dog oscillator value */ | ||
655 | g_Wdt_Osc_Freq = CLK_WDT_OSC_GET_FREQ(wdtOscFreq) / wdtOscDiv; | ||
656 | } | ||
657 | |||
658 | /*! brief Set main clock reference source. | ||
659 | * param src, reference clock_main_clk_src_t to set the main clock source. | ||
660 | */ | ||
661 | void CLOCK_SetMainClkSrc(clock_main_clk_src_t src) | ||
662 | { | ||
663 | uint32_t mainMux = CLK_MAIN_CLK_MUX_GET_MUX(src), mainPreMux = CLK_MAIN_CLK_MUX_GET_PRE_MUX(src); | ||
664 | |||
665 | if (((SYSCON->MAINCLKSEL & SYSCON_MAINCLKSEL_SEL_MASK) != mainPreMux) && (mainMux == 0U)) | ||
666 | { | ||
667 | SYSCON->MAINCLKSEL = (SYSCON->MAINCLKSEL & (~SYSCON_MAINCLKSEL_SEL_MASK)) | SYSCON_MAINCLKSEL_SEL(mainPreMux); | ||
668 | CLOCK_UpdateClkSrc((volatile uint32_t *)(&(SYSCON->MAINCLKUEN)), SYSCON_MAINCLKUEN_ENA_MASK); | ||
669 | } | ||
670 | |||
671 | if ((SYSCON->MAINCLKPLLSEL & SYSCON_MAINCLKPLLSEL_SEL_MASK) != mainMux) | ||
672 | { | ||
673 | SYSCON->MAINCLKPLLSEL = | ||
674 | (SYSCON->MAINCLKPLLSEL & (~SYSCON_MAINCLKPLLSEL_SEL_MASK)) | SYSCON_MAINCLKPLLSEL_SEL(mainMux); | ||
675 | CLOCK_UpdateClkSrc((volatile uint32_t *)(&(SYSCON->MAINCLKPLLUEN)), SYSCON_MAINCLKPLLUEN_ENA_MASK); | ||
676 | } | ||
677 | } | ||
678 | |||
679 | /*! brief Set FRO clock source | ||
680 | * param src, please reference _clock_fro_src definition. | ||
681 | * | ||
682 | */ | ||
683 | void CLOCK_SetFroOutClkSrc(clock_fro_src_t src) | ||
684 | { | ||
685 | if ((uint32_t)src != (SYSCON->FROOSCCTRL & SYSCON_FROOSCCTRL_FRO_DIRECT_MASK)) | ||
686 | { | ||
687 | SYSCON->FROOSCCTRL = (SYSCON->FROOSCCTRL & (~SYSCON_FROOSCCTRL_FRO_DIRECT_MASK)) | (uint32_t)src; | ||
688 | /* Update clock source */ | ||
689 | CLOCK_UpdateClkSrc((volatile uint32_t *)(&(SYSCON->FRODIRECTCLKUEN)), SYSCON_FRODIRECTCLKUEN_ENA_MASK); | ||
690 | } | ||
691 | } | ||