1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016 - 2020, NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_clock.h"
10 #include "fsl_common.h"
11 /*******************************************************************************
12 * Definitions
13 ******************************************************************************/
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "platform.drivers.clock"
17 #endif
18
19 #define OTP_INIT_API ((void (*)(uint32_t src_clk_freq))FSL_ROM_OTP_INIT_ADDR)
20 #define OTP_DEINIT_API ((void (*)(void))FSL_ROM_OTP_DEINIT_ADDR)
21 #define OTP_FUSE_READ_API ((void (*)(uint32_t addr, uint32_t * data)) FSL_ROM_OTP_FUSE_READ_ADDR)
22 /* OTP fuse index. */
23 #define FFRO_STABLE_TIME 12
24 #define SFRO_STABLE_TIME 13
25 #define FIRC_48MHZ_TRIM_TEMPCO 48
26 #define FIRC_48MHZ_TRIM_COARSE 49
27 #define FIRC_48MHZ_TRIM_FINE 50
28 #define FIRC_60MHZ_TRIM_TEMPCO 51
29 #define FIRC_60MHZ_TRIM_COARSE 52
30 #define FIRC_60MHZ_TRIM_FINE 53
31 /*******************************************************************************
32 * Variables
33 ******************************************************************************/
34
35 /* External XTAL (OSC) clock frequency. */
36 volatile uint32_t g_xtalFreq = 0U;
37 /* External CLK_IN pin clock frequency. */
38 volatile uint32_t g_clkinFreq = 0U;
39 /* External MCLK in (mclk_in) clock frequency. If not used,
40 set this to 0. Otherwise, set it to the exact rate in Hz this pin is
41 being driven at.*/
42 volatile uint32_t g_mclkFreq = 0U;
43
44 /*******************************************************************************
45 * Code
46 ******************************************************************************/
47 /* Clock Selection for IP */
48 /**
49 * brief Configure the clock selection muxes.
50 * param connection : Clock to be configured.
51 * return Nothing
52 */
CLOCK_AttachClk(clock_attach_id_t connection)53 void CLOCK_AttachClk(clock_attach_id_t connection)
54 {
55 bool final_descriptor = false;
56 uint32_t i;
57 volatile uint32_t *pClkSel;
58
59 for (i = 0U; (i < 2U) && (!final_descriptor); i++)
60 {
61 connection =
62 (clock_attach_id_t)(uint32_t)(((uint32_t)connection) >> (i * 16U)); /*!< pick up next descriptor */
63
64 if (((((uint32_t)connection) & 0x80000000U) | ((((uint32_t)connection) & 0x8000U))) != 0UL)
65 {
66 pClkSel = CLKCTL_TUPLE_REG(CLKCTL1, connection);
67 }
68 else
69 {
70 pClkSel = CLKCTL_TUPLE_REG(CLKCTL0, connection);
71 }
72
73 if ((((uint32_t)connection) & 0xfffU) != 0UL)
74 {
75 *pClkSel = CLKCTL_TUPLE_SEL(connection);
76 }
77 else
78 {
79 final_descriptor = true;
80 }
81 }
82 }
83 /* Set IP Clock divider */
84 /**
85 * brief Setup peripheral clock dividers.
86 * param div_name : Clock divider name
87 * param divider : Value to be divided. Divided clock frequency = Undivided clock frequency / divider.
88 * return Nothing
89 */
CLOCK_SetClkDiv(clock_div_name_t div_name,uint32_t divider)90 void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divider)
91 {
92 volatile uint32_t *pClkDiv;
93
94 if ((((uint32_t)div_name) & 0x80000000U) != 0UL)
95 {
96 pClkDiv = CLKCTL_TUPLE_REG(CLKCTL1, div_name);
97 }
98 else
99 {
100 pClkDiv = CLKCTL_TUPLE_REG(CLKCTL0, div_name);
101 }
102 /* Reset the divider counter */
103 *pClkDiv |= 1UL << 29U;
104
105 if (divider == 0U) /*!< halt */
106 {
107 *pClkDiv |= 1UL << 30U;
108 }
109 else
110 {
111 *pClkDiv = divider - 1U;
112
113 while (((*pClkDiv) & 0x80000000U) != 0UL)
114 {
115 }
116 }
117 }
118 /*! @brief Return Frequency of High-Freq output of FRO
119 * @return Frequency of High-Freq output of FRO
120 */
CLOCK_GetFFroFreq(void)121 uint32_t CLOCK_GetFFroFreq(void)
122 {
123 uint32_t freq = 0U;
124 /* FFROCTL0 should not be touched by application */
125 switch ((CLKCTL0->FFROCTL0) & CLKCTL0_FFROCTL0_TRIM_RANGE_MASK)
126 {
127 case CLKCTL0_FFROCTL0_TRIM_RANGE(0):
128 freq = CLK_FRO_48MHZ;
129 break;
130 case CLKCTL0_FFROCTL0_TRIM_RANGE(3):
131 freq = CLK_FRO_60MHZ;
132 break;
133 default:
134 freq = 0U;
135 break;
136 }
137 return freq;
138 }
139 /* Get SYSTEM PLL Clk */
140 /*! brief Return Frequency of SYSPLL
141 * return Frequency of SYSPLL
142 */
CLOCK_GetSysPllFreq(void)143 uint32_t CLOCK_GetSysPllFreq(void)
144 {
145 uint32_t freq = 0U;
146 uint64_t freqTmp;
147
148 switch ((CLKCTL0->SYSPLL0CLKSEL) & CLKCTL0_SYSPLL0CLKSEL_SEL_MASK)
149 {
150 case CLKCTL0_SYSPLL0CLKSEL_SEL(0):
151 freq = CLOCK_GetSFroFreq();
152 break;
153 case CLKCTL0_SYSPLL0CLKSEL_SEL(1):
154 freq = CLOCK_GetXtalInClkFreq();
155 break;
156 case CLKCTL0_SYSPLL0CLKSEL_SEL(2):
157 freq = CLOCK_GetFFroFreq() / 2U;
158 break;
159 default:
160 /* Added comments to prevent the violation of MISRA C-2012 rule. */
161 break;
162 }
163
164 if (((CLKCTL0->SYSPLL0CTL0) & CLKCTL0_SYSPLL0CTL0_BYPASS_MASK) == 0U)
165 {
166 /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */
167 freqTmp = ((uint64_t)freq * ((uint64_t)(CLKCTL0->SYSPLL0NUM))) / ((uint64_t)(CLKCTL0->SYSPLL0DENOM));
168 freq *= ((CLKCTL0->SYSPLL0CTL0) & CLKCTL0_SYSPLL0CTL0_MULT_MASK) >> CLKCTL0_SYSPLL0CTL0_MULT_SHIFT;
169 freq += (uint32_t)freqTmp;
170 }
171 return freq;
172 }
173 /* Get SYSTEM PLL PFDn Clk */
174 /*! brief Get current output frequency of specific System PLL PFD.
175 * param pfd : pfd name to get frequency.
176 * return Frequency of SYSPLL PFD.
177 */
CLOCK_GetSysPfdFreq(clock_pfd_t pfd)178 uint32_t CLOCK_GetSysPfdFreq(clock_pfd_t pfd)
179 {
180 uint32_t freq = CLOCK_GetSysPllFreq();
181
182 if (((CLKCTL0->SYSPLL0CTL0) & CLKCTL0_SYSPLL0CTL0_BYPASS_MASK) == 0U)
183 {
184 switch (pfd)
185 {
186 case kCLOCK_Pfd0:
187 freq =
188 (uint32_t)((uint64_t)freq * 18ULL /
189 ((CLKCTL0->SYSPLL0PFD & CLKCTL0_SYSPLL0PFD_PFD0_MASK) >> CLKCTL0_SYSPLL0PFD_PFD0_SHIFT));
190 break;
191
192 case kCLOCK_Pfd1:
193 freq =
194 (uint32_t)((uint64_t)freq * 18ULL /
195 ((CLKCTL0->SYSPLL0PFD & CLKCTL0_SYSPLL0PFD_PFD1_MASK) >> CLKCTL0_SYSPLL0PFD_PFD1_SHIFT));
196 break;
197
198 case kCLOCK_Pfd2:
199 freq =
200 (uint32_t)((uint64_t)freq * 18ULL /
201 ((CLKCTL0->SYSPLL0PFD & CLKCTL0_SYSPLL0PFD_PFD2_MASK) >> CLKCTL0_SYSPLL0PFD_PFD2_SHIFT));
202 break;
203
204 case kCLOCK_Pfd3:
205 freq =
206 (uint32_t)((uint64_t)freq * 18ULL /
207 ((CLKCTL0->SYSPLL0PFD & CLKCTL0_SYSPLL0PFD_PFD3_MASK) >> CLKCTL0_SYSPLL0PFD_PFD3_SHIFT));
208 break;
209
210 default:
211 freq = 0U;
212 break;
213 }
214 }
215
216 return freq;
217 }
CLOCK_GetMainPllClkFreq(void)218 static uint32_t CLOCK_GetMainPllClkFreq(void)
219 {
220 return CLOCK_GetSysPfdFreq(kCLOCK_Pfd0) / ((CLKCTL0->MAINPLLCLKDIV & CLKCTL0_MAINPLLCLKDIV_DIV_MASK) + 1U);
221 }
CLOCK_GetDspPllClkFreq(void)222 static uint32_t CLOCK_GetDspPllClkFreq(void)
223 {
224 return CLOCK_GetSysPfdFreq(kCLOCK_Pfd1) / ((CLKCTL0->DSPPLLCLKDIV & CLKCTL0_DSPPLLCLKDIV_DIV_MASK) + 1U);
225 }
CLOCK_GetAux0PllClkFreq(void)226 static uint32_t CLOCK_GetAux0PllClkFreq(void)
227 {
228 return CLOCK_GetSysPfdFreq(kCLOCK_Pfd2) / ((CLKCTL0->AUX0PLLCLKDIV & CLKCTL0_AUX0PLLCLKDIV_DIV_MASK) + 1U);
229 }
CLOCK_GetAux1PllClkFreq(void)230 static uint32_t CLOCK_GetAux1PllClkFreq(void)
231 {
232 return CLOCK_GetSysPfdFreq(kCLOCK_Pfd3) / ((CLKCTL0->AUX1PLLCLKDIV & CLKCTL0_AUX1PLLCLKDIV_DIV_MASK) + 1U);
233 }
234 /* Get AUDIO PLL Clk */
235 /*! brief Return Frequency of AUDIO PLL
236 * return Frequency of AUDIO PLL
237 */
CLOCK_GetAudioPllFreq(void)238 uint32_t CLOCK_GetAudioPllFreq(void)
239 {
240 uint32_t freq = 0U;
241 uint64_t freqTmp;
242
243 switch ((CLKCTL1->AUDIOPLL0CLKSEL) & CLKCTL1_AUDIOPLL0CLKSEL_SEL_MASK)
244 {
245 case CLKCTL1_AUDIOPLL0CLKSEL_SEL(0):
246 freq = CLOCK_GetSFroFreq();
247 break;
248 case CLKCTL1_AUDIOPLL0CLKSEL_SEL(1):
249 freq = CLOCK_GetXtalInClkFreq();
250 break;
251 case CLKCTL1_AUDIOPLL0CLKSEL_SEL(2):
252 freq = CLOCK_GetFFroFreq() / 2U;
253 break;
254 default:
255 freq = 0U;
256 break;
257 }
258
259 if (((CLKCTL1->AUDIOPLL0CTL0) & CLKCTL1_AUDIOPLL0CTL0_BYPASS_MASK) == 0UL)
260 {
261 /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */
262 freqTmp = ((uint64_t)freq * ((uint64_t)(CLKCTL1->AUDIOPLL0NUM))) / ((uint64_t)(CLKCTL1->AUDIOPLL0DENOM));
263 freq *= ((CLKCTL1->AUDIOPLL0CTL0) & CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) >> CLKCTL1_AUDIOPLL0CTL0_MULT_SHIFT;
264 freq += (uint32_t)freqTmp;
265 }
266 return freq;
267 }
268 /* Get AUDIO PLL PFDn Clk */
269 /*! brief Get current output frequency of specific Audio PLL PFD.
270 * param pfd : pfd name to get frequency.
271 * return Frequency of AUDIO PLL PFD.
272 */
CLOCK_GetAudioPfdFreq(clock_pfd_t pfd)273 uint32_t CLOCK_GetAudioPfdFreq(clock_pfd_t pfd)
274 {
275 uint32_t freq = CLOCK_GetAudioPllFreq();
276
277 if (((CLKCTL1->AUDIOPLL0CTL0) & CLKCTL1_AUDIOPLL0CTL0_BYPASS_MASK) == 0UL)
278 {
279 switch (pfd)
280 {
281 case kCLOCK_Pfd0:
282 freq = (uint32_t)(
283 (uint64_t)freq * 18ULL /
284 ((CLKCTL1->AUDIOPLL0PFD & CLKCTL1_AUDIOPLL0PFD_PFD0_MASK) >> CLKCTL1_AUDIOPLL0PFD_PFD0_SHIFT));
285 break;
286
287 case kCLOCK_Pfd1:
288 freq = (uint32_t)(
289 (uint64_t)freq * 18ULL /
290 ((CLKCTL1->AUDIOPLL0PFD & CLKCTL1_AUDIOPLL0PFD_PFD1_MASK) >> CLKCTL1_AUDIOPLL0PFD_PFD1_SHIFT));
291 break;
292
293 case kCLOCK_Pfd2:
294 freq = (uint32_t)(
295 (uint64_t)freq * 18ULL /
296 ((CLKCTL1->AUDIOPLL0PFD & CLKCTL1_AUDIOPLL0PFD_PFD2_MASK) >> CLKCTL1_AUDIOPLL0PFD_PFD2_SHIFT));
297 break;
298
299 case kCLOCK_Pfd3:
300 freq = (uint32_t)(
301 (uint64_t)freq * 18ULL /
302 ((CLKCTL1->AUDIOPLL0PFD & CLKCTL1_AUDIOPLL0PFD_PFD3_MASK) >> CLKCTL1_AUDIOPLL0PFD_PFD3_SHIFT));
303 break;
304
305 default:
306 freq = 0U;
307 break;
308 }
309 }
310
311 return freq;
312 }
CLOCK_GetAudioPllClkFreq(void)313 static uint32_t CLOCK_GetAudioPllClkFreq(void)
314 {
315 return CLOCK_GetAudioPfdFreq(kCLOCK_Pfd0) / ((CLKCTL1->AUDIOPLLCLKDIV & CLKCTL1_AUDIOPLLCLKDIV_DIV_MASK) + 1U);
316 }
317 /* Get MAIN Clk */
318 /*! brief Return Frequency of main clk
319 * return Frequency of main clk
320 */
CLOCK_GetMainClkFreq(void)321 uint32_t CLOCK_GetMainClkFreq(void)
322 {
323 uint32_t freq = 0U;
324
325 switch ((CLKCTL0->MAINCLKSELB) & CLKCTL0_MAINCLKSELB_SEL_MASK)
326 {
327 case CLKCTL0_MAINCLKSELB_SEL(0):
328 switch ((CLKCTL0->MAINCLKSELA) & CLKCTL0_MAINCLKSELA_SEL_MASK)
329 {
330 case CLKCTL0_MAINCLKSELA_SEL(0):
331 freq = CLOCK_GetFFroFreq() / 4U;
332 break;
333 case CLKCTL0_MAINCLKSELA_SEL(1):
334 freq = CLOCK_GetXtalInClkFreq();
335 break;
336 case CLKCTL0_MAINCLKSELA_SEL(2):
337 freq = CLOCK_GetLpOscFreq();
338 break;
339 case CLKCTL0_MAINCLKSELA_SEL(3):
340 freq = CLOCK_GetFFroFreq();
341 break;
342 default:
343 freq = 0U;
344 break;
345 }
346 break;
347
348 case CLKCTL0_MAINCLKSELB_SEL(1):
349 freq = CLOCK_GetSFroFreq();
350 break;
351
352 case CLKCTL0_MAINCLKSELB_SEL(2):
353 freq = CLOCK_GetMainPllClkFreq();
354 break;
355
356 case CLKCTL0_MAINCLKSELB_SEL(3):
357 freq = CLOCK_GetOsc32KFreq();
358 break;
359
360 default:
361 freq = 0U;
362 break;
363 }
364
365 return freq;
366 }
367 /* Get DSP MAIN Clk */
368 /*! brief Return Frequency of DSP main clk
369 * return Frequency of DSP main clk
370 */
CLOCK_GetDspMainClkFreq(void)371 uint32_t CLOCK_GetDspMainClkFreq(void)
372 {
373 uint32_t freq = 0U;
374
375 switch ((CLKCTL1->DSPCPUCLKSELB) & CLKCTL1_DSPCPUCLKSELB_SEL_MASK)
376 {
377 case CLKCTL1_DSPCPUCLKSELB_SEL(0):
378 switch ((CLKCTL1->DSPCPUCLKSELA) & CLKCTL1_DSPCPUCLKSELA_SEL_MASK)
379 {
380 case CLKCTL1_DSPCPUCLKSELA_SEL(0):
381 freq = CLOCK_GetFFroFreq();
382 break;
383 case CLKCTL1_DSPCPUCLKSELA_SEL(1):
384 freq = CLOCK_GetXtalInClkFreq();
385 break;
386 case CLKCTL1_DSPCPUCLKSELA_SEL(2):
387 freq = CLOCK_GetLpOscFreq();
388 break;
389 case CLKCTL1_DSPCPUCLKSELA_SEL(3):
390 freq = CLOCK_GetSFroFreq();
391 break;
392 default:
393 freq = 0U;
394 break;
395 }
396 break;
397
398 case CLKCTL1_DSPCPUCLKSELB_SEL(1):
399 freq = CLOCK_GetMainPllClkFreq();
400 break;
401
402 case CLKCTL1_DSPCPUCLKSELB_SEL(2):
403 freq = CLOCK_GetDspPllClkFreq();
404 break;
405
406 case CLKCTL1_DSPCPUCLKSELB_SEL(3):
407 freq = CLOCK_GetOsc32KFreq();
408 break;
409
410 default:
411 freq = 0U;
412 break;
413 }
414
415 return freq;
416 }
417 /* Get ADC Clk */
418 /*! brief Return Frequency of Adc Clock
419 * return Frequency of Adc Clock.
420 */
CLOCK_GetAdcClkFreq(void)421 uint32_t CLOCK_GetAdcClkFreq(void)
422 {
423 uint32_t freq = 0U;
424
425 switch ((CLKCTL0->ADC0FCLKSEL1) & CLKCTL0_ADC0FCLKSEL1_SEL_MASK)
426 {
427 case CLKCTL0_ADC0FCLKSEL1_SEL(0):
428 switch ((CLKCTL0->ADC0FCLKSEL0) & CLKCTL0_ADC0FCLKSEL0_SEL_MASK)
429 {
430 case CLKCTL0_ADC0FCLKSEL0_SEL(0):
431 freq = CLOCK_GetSFroFreq();
432 break;
433 case CLKCTL0_ADC0FCLKSEL0_SEL(1):
434 freq = CLOCK_GetXtalInClkFreq();
435 break;
436 case CLKCTL0_ADC0FCLKSEL0_SEL(2):
437 freq = CLOCK_GetLpOscFreq();
438 break;
439 case CLKCTL0_ADC0FCLKSEL0_SEL(3):
440 freq = CLOCK_GetFFroFreq();
441 break;
442 default:
443 freq = 0U;
444 break;
445 }
446 break;
447
448 case CLKCTL0_ADC0FCLKSEL1_SEL(1):
449 freq = CLOCK_GetMainPllClkFreq();
450 break;
451
452 case CLKCTL0_ADC0FCLKSEL1_SEL(3):
453 freq = CLOCK_GetAux0PllClkFreq();
454 break;
455
456 case CLKCTL0_ADC0FCLKSEL1_SEL(5):
457 freq = CLOCK_GetAux1PllClkFreq();
458 break;
459
460 default:
461 freq = 0U;
462 break;
463 }
464
465 return freq / ((CLKCTL0->ADC0FCLKDIV & CLKCTL0_ADC0FCLKDIV_DIV_MASK) + 1U);
466 }
467 /* Get CLOCK OUT Clk */
468 /*! brief Return Frequency of ClockOut
469 * return Frequency of ClockOut
470 */
CLOCK_GetClockOutClkFreq(void)471 uint32_t CLOCK_GetClockOutClkFreq(void)
472 {
473 uint32_t freq = 0U;
474
475 switch ((CLKCTL1->CLKOUTSEL1) & CLKCTL1_CLKOUTSEL1_SEL_MASK)
476 {
477 case CLKCTL1_CLKOUTSEL1_SEL(0):
478 switch ((CLKCTL1->CLKOUTSEL0) & CLKCTL1_CLKOUTSEL0_SEL_MASK)
479 {
480 case CLKCTL1_CLKOUTSEL0_SEL(0):
481 freq = CLOCK_GetSFroFreq();
482 break;
483 case CLKCTL1_CLKOUTSEL0_SEL(1):
484 freq = CLOCK_GetXtalInClkFreq();
485 break;
486 case CLKCTL1_CLKOUTSEL0_SEL(2):
487 freq = CLOCK_GetLpOscFreq();
488 break;
489 case CLKCTL1_CLKOUTSEL0_SEL(3):
490 freq = CLOCK_GetFFroFreq();
491 break;
492 case CLKCTL1_CLKOUTSEL0_SEL(4):
493 freq = CLOCK_GetMainClkFreq();
494 break;
495 case CLKCTL1_CLKOUTSEL0_SEL(6):
496 freq = CLOCK_GetDspMainClkFreq();
497 break;
498 default:
499 freq = 0U;
500 break;
501 }
502 break;
503
504 case CLKCTL1_CLKOUTSEL1_SEL(1):
505 freq = CLOCK_GetMainPllClkFreq();
506 break;
507
508 case CLKCTL1_CLKOUTSEL1_SEL(2):
509 freq = CLOCK_GetAux0PllClkFreq();
510 break;
511
512 case CLKCTL1_CLKOUTSEL1_SEL(3):
513 freq = CLOCK_GetDspPllClkFreq();
514 break;
515
516 case CLKCTL1_CLKOUTSEL1_SEL(4):
517 freq = CLOCK_GetAux1PllClkFreq();
518 break;
519
520 case CLKCTL1_CLKOUTSEL1_SEL(5):
521 freq = CLOCK_GetAudioPllClkFreq();
522 break;
523
524 case CLKCTL1_CLKOUTSEL1_SEL(6):
525 freq = CLOCK_GetOsc32KFreq();
526 break;
527
528 default:
529 freq = 0U;
530 break;
531 }
532
533 return freq / ((CLKCTL1->CLKOUTDIV & CLKCTL1_CLKOUTDIV_DIV_MASK) + 1U);
534 }
535 /* Get FRG Clk */
536 /*! brief Return Input frequency for the Fractional baud rate generator
537 * return Input Frequency for FRG
538 */
CLOCK_GetFRGClock(uint32_t id)539 uint32_t CLOCK_GetFRGClock(uint32_t id)
540 {
541 uint32_t freq = 0U;
542 uint32_t frgPllDiv = 1U;
543 uint32_t clkSel = 0U;
544 uint32_t frgDiv = 0U;
545 uint32_t frgMul = 0U;
546
547 if (id <= 7UL)
548 {
549 clkSel = CLKCTL1->FLEXCOMM[id].FRGCLKSEL & CLKCTL1_FRGCLKSEL_SEL_MASK;
550 frgMul = ((CLKCTL1->FLEXCOMM[id].FRGCTL) & CLKCTL1_FRGCTL_MULT_MASK) >> CLKCTL1_FRGCTL_MULT_SHIFT;
551 frgDiv = ((CLKCTL1->FLEXCOMM[id].FRGCTL) & CLKCTL1_FRGCTL_DIV_MASK) >> CLKCTL1_FRGCTL_DIV_SHIFT;
552 }
553 else if (id == 14UL)
554 {
555 clkSel = CLKCTL1->FRG14CLKSEL & CLKCTL1_FRG14CLKSEL_SEL_MASK;
556 frgMul = ((CLKCTL1->FRG14CTL) & CLKCTL1_FRGCTL_MULT_MASK) >> CLKCTL1_FRGCTL_MULT_SHIFT;
557 frgDiv = ((CLKCTL1->FRG14CTL) & CLKCTL1_FRGCTL_DIV_MASK) >> CLKCTL1_FRGCTL_DIV_SHIFT;
558 }
559 else if (id == 15UL)
560 {
561 clkSel = CLKCTL1->FRG15CLKSEL & CLKCTL1_FRG14CLKSEL_SEL_MASK;
562 frgMul = ((CLKCTL1->FRG15CTL) & CLKCTL1_FRGCTL_MULT_MASK) >> CLKCTL1_FRGCTL_MULT_SHIFT;
563 frgDiv = ((CLKCTL1->FRG15CTL) & CLKCTL1_FRGCTL_DIV_MASK) >> CLKCTL1_FRGCTL_DIV_SHIFT;
564 }
565 else
566 {
567 assert(false);
568 }
569
570 switch (clkSel)
571 {
572 case CLKCTL1_FRGCLKSEL_SEL(0):
573 freq = CLOCK_GetMainClkFreq();
574 break;
575
576 case CLKCTL1_FRGCLKSEL_SEL(1):
577 frgPllDiv = (CLKCTL1->FRGPLLCLKDIV & CLKCTL1_FRGPLLCLKDIV_DIV_MASK) + 1U;
578 freq = CLOCK_GetMainPllClkFreq() / frgPllDiv;
579 break;
580
581 case CLKCTL1_FRGCLKSEL_SEL(2):
582 freq = CLOCK_GetSFroFreq();
583 break;
584
585 case CLKCTL1_FRGCLKSEL_SEL(3):
586 freq = CLOCK_GetFFroFreq();
587 break;
588
589 default:
590 freq = 0U;
591 break;
592 }
593
594 return (uint32_t)(((uint64_t)freq * ((uint64_t)frgDiv + 1ULL)) / (frgMul + frgDiv + 1UL));
595 }
596 /* Get FLEXCOMM Clk */
597 /*! brief Return Frequency of Flexcomm functional Clock
598 * param id : flexcomm index to get frequency.
599 * return Frequency of Flexcomm functional Clock
600 */
CLOCK_GetFlexCommClkFreq(uint32_t id)601 uint32_t CLOCK_GetFlexCommClkFreq(uint32_t id)
602 {
603 uint32_t freq = 0U;
604 uint32_t clkSel = 0U;
605
606 if (id <= 7UL)
607 {
608 clkSel = CLKCTL1->FLEXCOMM[id].FCFCLKSEL;
609 }
610 else if (id == 14UL)
611 {
612 clkSel = CLKCTL1->FC14FCLKSEL;
613 }
614 else if (id == 15UL)
615 {
616 clkSel = CLKCTL1->FC15FCLKSEL;
617 }
618 else
619 {
620 assert(false);
621 }
622
623 switch (clkSel)
624 {
625 case CLKCTL1_FCFCLKSEL_SEL(0):
626 freq = CLOCK_GetSFroFreq();
627 break;
628
629 case CLKCTL1_FCFCLKSEL_SEL(1):
630 freq = CLOCK_GetFFroFreq();
631 break;
632
633 case CLKCTL1_FCFCLKSEL_SEL(2):
634 freq = CLOCK_GetAudioPllClkFreq();
635 break;
636
637 case CLKCTL1_FCFCLKSEL_SEL(3):
638 freq = CLOCK_GetMclkInClkFreq();
639 break;
640
641 case CLKCTL1_FCFCLKSEL_SEL(4):
642 freq = CLOCK_GetFRGClock(id);
643 break;
644
645 default:
646 freq = 0U;
647 break;
648 }
649
650 return freq;
651 }
652 /* Get CTIMER Clk */
653 /*! brief Return Frequency of Ctimer Clock
654 * param id : ctimer index to get frequency.
655 * return Frequency of Ctimer Clock
656 */
CLOCK_GetCTimerClkFreq(uint32_t id)657 uint32_t CLOCK_GetCTimerClkFreq(uint32_t id)
658 {
659 uint32_t freq = 0U;
660
661 switch ((CLKCTL1->CT32BITFCLKSEL[id]) & CLKCTL1_CT32BITFCLKSEL_SEL_MASK)
662 {
663 case CLKCTL1_CT32BITFCLKSEL_SEL(0):
664 freq = CLOCK_GetMainClkFreq();
665 break;
666
667 case CLKCTL1_CT32BITFCLKSEL_SEL(1):
668 freq = CLOCK_GetSFroFreq();
669 break;
670
671 case CLKCTL1_CT32BITFCLKSEL_SEL(2):
672 freq = CLOCK_GetFFroFreq();
673 break;
674
675 case CLKCTL1_CT32BITFCLKSEL_SEL(3):
676 freq = CLOCK_GetAudioPllClkFreq();
677 break;
678
679 case CLKCTL1_CT32BITFCLKSEL_SEL(4):
680 freq = CLOCK_GetMclkInClkFreq();
681 break;
682
683 case CLKCTL1_CT32BITFCLKSEL_SEL(5):
684 freq = CLOCK_GetLpOscFreq();
685 break;
686
687 default:
688 freq = 0U;
689 break;
690 }
691
692 return freq;
693 }
694 /* Get FLEXSPI Clk */
695 /*! brief Return Frequency of FLEXSPI Clock
696 * return Frequency of FLEXSPI.
697 */
CLOCK_GetFlexspiClkFreq(void)698 uint32_t CLOCK_GetFlexspiClkFreq(void)
699 {
700 uint32_t freq = 0U;
701
702 switch ((CLKCTL0->FLEXSPIFCLKSEL) & CLKCTL0_FLEXSPIFCLKSEL_SEL_MASK)
703 {
704 case CLKCTL0_FLEXSPIFCLKSEL_SEL(0):
705 freq = CLOCK_GetMainClkFreq();
706 break;
707
708 case CLKCTL0_FLEXSPIFCLKSEL_SEL(1):
709 freq = CLOCK_GetMainPllClkFreq();
710 break;
711
712 case CLKCTL0_FLEXSPIFCLKSEL_SEL(2):
713 freq = CLOCK_GetAux0PllClkFreq();
714 break;
715
716 case CLKCTL0_FLEXSPIFCLKSEL_SEL(3):
717 freq = CLOCK_GetFFroFreq();
718 break;
719
720 case CLKCTL0_FLEXSPIFCLKSEL_SEL(4):
721 freq = CLOCK_GetAux1PllClkFreq();
722 break;
723
724 default:
725 freq = 0U;
726 break;
727 }
728
729 return freq / ((CLKCTL0->FLEXSPIFCLKDIV & CLKCTL0_FLEXSPIFCLKDIV_DIV_MASK) + 1U);
730 }
731
732 /* Get SCT Clk */
733 /*! brief Return Frequency of sct
734 * return Frequency of sct clk
735 */
CLOCK_GetSctClkFreq(void)736 uint32_t CLOCK_GetSctClkFreq(void)
737 {
738 uint32_t freq = 0U;
739
740 switch ((CLKCTL0->SCTFCLKSEL) & CLKCTL0_SCTFCLKSEL_SEL_MASK)
741 {
742 case CLKCTL0_SCTFCLKSEL_SEL(0):
743 freq = CLOCK_GetMainClkFreq();
744 break;
745
746 case CLKCTL0_SCTFCLKSEL_SEL(1):
747 freq = CLOCK_GetMainPllClkFreq();
748 break;
749
750 case CLKCTL0_SCTFCLKSEL_SEL(2):
751 freq = CLOCK_GetAux0PllClkFreq();
752 break;
753
754 case CLKCTL0_SCTFCLKSEL_SEL(3):
755 freq = CLOCK_GetFFroFreq();
756 break;
757
758 case CLKCTL0_SCTFCLKSEL_SEL(4):
759 freq = CLOCK_GetAux1PllClkFreq();
760 break;
761
762 case CLKCTL0_SCTFCLKSEL_SEL(5):
763 freq = CLOCK_GetAudioPllClkFreq();
764 break;
765
766 default:
767 freq = 0U;
768 break;
769 }
770
771 return freq / ((CLKCTL0->SCTFCLKDIV & CLKCTL0_SCTFCLKDIV_DIV_MASK) + 1U);
772 }
773
774 /*! brief Return Frequency of mclk Out
775 * return Frequency of mclk Out clk
776 */
CLOCK_GetMclkClkFreq(void)777 uint32_t CLOCK_GetMclkClkFreq(void)
778 {
779 uint32_t freq = 0U;
780
781 if (CLKCTL1->AUDIOMCLKSEL == 0U)
782 {
783 freq = CLOCK_GetFFroFreq();
784 }
785 else if (CLKCTL1->AUDIOMCLKSEL == 1U)
786 {
787 freq = CLOCK_GetAudioPllClkFreq();
788 }
789 else
790 {
791 /* Added comments to prevent the violation of MISRA C-2012 rule 15.7. */
792 }
793
794 return freq / ((CLKCTL1->AUDIOMCLKDIV & CLKCTL1_AUDIOMCLKDIV_DIV_MASK) + 1U);
795 }
796
797 /*! @brief Return Frequency of WDT clk
798 * @param id : WDT index to get frequency.
799 * @return Frequency of WDT clk
800 */
CLOCK_GetWdtClkFreq(uint32_t id)801 uint32_t CLOCK_GetWdtClkFreq(uint32_t id)
802 {
803 uint32_t freq = 0U;
804
805 assert(id <= 1UL);
806
807 if (id == 0UL)
808 {
809 if ((CLKCTL0->WDT0FCLKSEL & CLKCTL0_WDT0FCLKSEL_SEL_MASK) == CLKCTL0_WDT0FCLKSEL_SEL(0))
810 {
811 freq = CLOCK_GetLpOscFreq();
812 }
813 else
814 {
815 freq = CLOCK_GetMainClkFreq();
816 }
817 }
818 else
819 {
820 if ((CLKCTL1->WDT1FCLKSEL & CLKCTL1_WDT1FCLKSEL_SEL_MASK) == CLKCTL1_WDT1FCLKSEL_SEL(0))
821 {
822 freq = CLOCK_GetLpOscFreq();
823 }
824 else
825 {
826 freq = CLOCK_GetMainClkFreq();
827 }
828 }
829
830 return freq;
831 }
832
833 /*! brief Return Frequency of systick clk
834 * return Frequency of systick clk
835 */
CLOCK_GetSystickClkFreq(void)836 uint32_t CLOCK_GetSystickClkFreq(void)
837 {
838 uint32_t freq = 0U;
839
840 switch (CLKCTL0->SYSTICKFCLKSEL)
841 {
842 case CLKCTL0_SYSTICKFCLKSEL_SEL(0):
843 freq = CLOCK_GetMainClkFreq() / ((CLKCTL0->SYSTICKFCLKDIV & CLKCTL0_SYSTICKFCLKDIV_DIV_MASK) + 1U);
844 break;
845
846 case CLKCTL0_SYSTICKFCLKSEL_SEL(1):
847 freq = CLOCK_GetLpOscFreq();
848 break;
849
850 case CLKCTL0_SYSTICKFCLKSEL_SEL(2):
851 freq = CLOCK_GetOsc32KFreq();
852 break;
853
854 case CLKCTL0_SYSTICKFCLKSEL_SEL(3):
855 freq = CLOCK_GetSFroFreq();
856 break;
857
858 default:
859 freq = 0U;
860 break;
861 }
862
863 return freq;
864 }
865
866 /*! brief Return Frequency of SDIO clk
867 * param id : SDIO index to get frequency.
868 * return Frequency of SDIO clk
869 */
CLOCK_GetSdioClkFreq(uint32_t id)870 uint32_t CLOCK_GetSdioClkFreq(uint32_t id)
871 {
872 uint32_t freq = 0U;
873 volatile uint32_t *pClkSel;
874 volatile uint32_t *pClkDiv;
875
876 assert(id <= 1U);
877
878 if (id == 0UL)
879 {
880 pClkSel = &CLKCTL0->SDIO0FCLKSEL;
881 pClkDiv = &CLKCTL0->SDIO0FCLKDIV;
882 }
883 else
884 {
885 pClkSel = &CLKCTL0->SDIO1FCLKSEL;
886 pClkDiv = &CLKCTL0->SDIO1FCLKDIV;
887 }
888
889 switch ((*pClkSel) & CLKCTL0_SDIO0FCLKSEL_SEL_MASK)
890 {
891 case CLKCTL0_SDIO0FCLKSEL_SEL(0):
892 freq = CLOCK_GetMainClkFreq();
893 break;
894
895 case CLKCTL0_SDIO0FCLKSEL_SEL(1):
896 freq = CLOCK_GetMainPllClkFreq();
897 break;
898
899 case CLKCTL0_SDIO0FCLKSEL_SEL(2):
900 freq = CLOCK_GetAux0PllClkFreq();
901 break;
902
903 case CLKCTL0_SDIO0FCLKSEL_SEL(3):
904 freq = CLOCK_GetFFroFreq();
905 break;
906
907 case CLKCTL0_SDIO0FCLKSEL_SEL(4):
908 freq = CLOCK_GetAux1PllClkFreq();
909 break;
910
911 default:
912 freq = 0U;
913 break;
914 }
915
916 return freq / (((*pClkDiv) & CLKCTL0_SDIO0FCLKDIV_DIV_MASK) + 1U);
917 }
918
919 /*! @brief Return Frequency of I3C clk
920 * @return Frequency of I3C clk
921 */
CLOCK_GetI3cClkFreq(void)922 uint32_t CLOCK_GetI3cClkFreq(void)
923 {
924 uint32_t freq = 0U;
925
926 switch ((CLKCTL1->I3C0FCLKSEL) & CLKCTL1_I3C0FCLKSEL_SEL_MASK)
927 {
928 case CLKCTL1_I3C0FCLKSEL_SEL(0):
929 freq = CLOCK_GetMainClkFreq();
930 break;
931
932 case CLKCTL1_I3C0FCLKSEL_SEL(1):
933 freq = CLOCK_GetFFroFreq();
934 break;
935
936 default:
937 freq = 0U;
938 break;
939 }
940
941 return freq / ((CLKCTL1->I3C0FCLKDIV & CLKCTL1_I3C0FCLKDIV_DIV_MASK) + 1U);
942 }
943
944 /*! brief Return Frequency of USB clk
945 * return Frequency of USB clk
946 */
CLOCK_GetUsbClkFreq(void)947 uint32_t CLOCK_GetUsbClkFreq(void)
948 {
949 uint32_t freq = 0U;
950
951 if (CLKCTL0->USBHSFCLKSEL == 0U)
952 {
953 freq = CLOCK_GetXtalInClkFreq();
954 }
955 else if (CLKCTL0->USBHSFCLKSEL == 1U)
956 {
957 freq = CLOCK_GetMainClkFreq();
958 }
959 else
960 {
961 /* Add comments to prevent the violation of MISRA C-2012 rule 15.7 */
962 }
963
964 return freq / ((CLKCTL0->USBHSFCLKDIV & 0xffU) + 1U);
965 }
966
967 /*! brief Return Frequency of DMIC clk
968 * return Frequency of DMIC clk
969 */
CLOCK_GetDmicClkFreq(void)970 uint32_t CLOCK_GetDmicClkFreq(void)
971 {
972 uint32_t freq = 0U;
973
974 switch ((CLKCTL1->DMIC0FCLKSEL) & CLKCTL1_DMIC0FCLKSEL_SEL_MASK)
975 {
976 case CLKCTL1_DMIC0FCLKSEL_SEL(0):
977 freq = CLOCK_GetSFroFreq();
978 break;
979
980 case CLKCTL1_DMIC0FCLKSEL_SEL(1):
981 freq = CLOCK_GetFFroFreq();
982 break;
983
984 case CLKCTL1_DMIC0FCLKSEL_SEL(2):
985 freq = CLOCK_GetAudioPllClkFreq();
986 break;
987
988 case CLKCTL1_DMIC0FCLKSEL_SEL(3):
989 freq = CLOCK_GetMclkInClkFreq();
990 break;
991
992 case CLKCTL1_DMIC0FCLKSEL_SEL(4):
993 freq = CLOCK_GetLpOscFreq();
994 break;
995
996 case CLKCTL1_DMIC0FCLKSEL_SEL(5):
997 freq = CLOCK_GetWakeClk32KFreq();
998 break;
999
1000 default:
1001 freq = 0U;
1002 break;
1003 }
1004
1005 return freq / ((CLKCTL1->DMIC0FCLKDIV & 0xffU) + 1U);
1006 }
1007
1008 /*! brief Return Frequency of ACMP clk
1009 * return Frequency of ACMP clk
1010 */
CLOCK_GetAcmpClkFreq(void)1011 uint32_t CLOCK_GetAcmpClkFreq(void)
1012 {
1013 uint32_t freq = 0U;
1014
1015 switch ((CLKCTL1->ACMP0FCLKSEL) & CLKCTL1_ACMP0FCLKSEL_SEL_MASK)
1016 {
1017 case CLKCTL1_ACMP0FCLKSEL_SEL(0):
1018 freq = CLOCK_GetMainClkFreq();
1019 break;
1020
1021 case CLKCTL1_ACMP0FCLKSEL_SEL(1):
1022 freq = CLOCK_GetSFroFreq();
1023 break;
1024
1025 case CLKCTL1_ACMP0FCLKSEL_SEL(2):
1026 freq = CLOCK_GetFFroFreq();
1027 break;
1028
1029 case CLKCTL1_ACMP0FCLKSEL_SEL(3):
1030 freq = CLOCK_GetAux0PllClkFreq();
1031 break;
1032
1033 case CLKCTL1_ACMP0FCLKSEL_SEL(4):
1034 freq = CLOCK_GetAux1PllClkFreq();
1035 break;
1036
1037 default:
1038 freq = 0U;
1039 break;
1040 }
1041
1042 return freq / ((CLKCTL1->ACMP0FCLKDIV & CLKCTL1_ACMP0FCLKDIV_DIV_MASK) + 1U);
1043 }
1044
1045 /* Get IP Clk */
1046 /*! brief Return Frequency of selected clock
1047 * return Frequency of selected clock
1048 */
CLOCK_GetFreq(clock_name_t clockName)1049 uint32_t CLOCK_GetFreq(clock_name_t clockName)
1050 {
1051 uint32_t freq = 0U;
1052
1053 switch (clockName)
1054 {
1055 case kCLOCK_CoreSysClk:
1056 case kCLOCK_BusClk:
1057 freq = CLOCK_GetMainClkFreq() / ((CLKCTL0->SYSCPUAHBCLKDIV & CLKCTL0_SYSCPUAHBCLKDIV_DIV_MASK) + 1U);
1058 break;
1059 case kCLOCK_MclkClk:
1060 freq = CLOCK_GetMclkClkFreq();
1061 break;
1062 case kCLOCK_ClockOutClk:
1063 freq = CLOCK_GetClockOutClkFreq();
1064 break;
1065 case kCLOCK_AdcClk:
1066 freq = CLOCK_GetAdcClkFreq();
1067 break;
1068 case kCLOCK_FlexspiClk:
1069 freq = CLOCK_GetFlexspiClkFreq();
1070 break;
1071 case kCLOCK_SctClk:
1072 freq = CLOCK_GetSctClkFreq();
1073 break;
1074 case kCLOCK_Wdt0Clk:
1075 freq = CLOCK_GetWdtClkFreq(0U);
1076 break;
1077 case kCLOCK_Wdt1Clk:
1078 freq = CLOCK_GetWdtClkFreq(1U);
1079 break;
1080 case kCLOCK_SystickClk:
1081 freq = CLOCK_GetSystickClkFreq();
1082 break;
1083 case kCLOCK_Sdio0Clk:
1084 freq = CLOCK_GetSdioClkFreq(0U);
1085 break;
1086 case kCLOCK_Sdio1Clk:
1087 freq = CLOCK_GetSdioClkFreq(1U);
1088 break;
1089 case kCLOCK_I3cClk:
1090 freq = CLOCK_GetI3cClkFreq();
1091 break;
1092 case kCLOCK_UsbClk:
1093 freq = CLOCK_GetUsbClkFreq();
1094 break;
1095 case kCLOCK_DmicClk:
1096 freq = CLOCK_GetDmicClkFreq();
1097 break;
1098 case kCLOCK_DspCpuClk:
1099 freq = CLOCK_GetDspMainClkFreq() / ((CLKCTL1->DSPCPUCLKDIV & CLKCTL1_DSPCPUCLKDIV_DIV_MASK) + 1U);
1100 break;
1101 case kCLOCK_AcmpClk:
1102 freq = CLOCK_GetAcmpClkFreq();
1103 break;
1104 case kCLOCK_Flexcomm0Clk:
1105 freq = CLOCK_GetFlexCommClkFreq(0U);
1106 break;
1107 case kCLOCK_Flexcomm1Clk:
1108 freq = CLOCK_GetFlexCommClkFreq(1U);
1109 break;
1110 case kCLOCK_Flexcomm2Clk:
1111 freq = CLOCK_GetFlexCommClkFreq(2U);
1112 break;
1113 case kCLOCK_Flexcomm3Clk:
1114 freq = CLOCK_GetFlexCommClkFreq(3U);
1115 break;
1116 case kCLOCK_Flexcomm4Clk:
1117 freq = CLOCK_GetFlexCommClkFreq(4U);
1118 break;
1119 case kCLOCK_Flexcomm5Clk:
1120 freq = CLOCK_GetFlexCommClkFreq(5U);
1121 break;
1122 case kCLOCK_Flexcomm6Clk:
1123 freq = CLOCK_GetFlexCommClkFreq(6U);
1124 break;
1125 case kCLOCK_Flexcomm7Clk:
1126 freq = CLOCK_GetFlexCommClkFreq(7U);
1127 break;
1128 case kCLOCK_Flexcomm14Clk:
1129 freq = CLOCK_GetFlexCommClkFreq(14U);
1130 break;
1131 case kCLOCK_Flexcomm15Clk:
1132 freq = CLOCK_GetFlexCommClkFreq(15U);
1133 break;
1134 default:
1135 freq = 0U;
1136 break;
1137 }
1138
1139 return freq;
1140 }
1141
1142 /* Set FRG Clk */
1143 /*! brief Set output of the Fractional baud rate generator
1144 * param config : Configuration to set to FRGn clock.
1145 */
CLOCK_SetFRGClock(const clock_frg_clk_config_t * config)1146 void CLOCK_SetFRGClock(const clock_frg_clk_config_t *config)
1147 {
1148 uint32_t i = config->num;
1149
1150 assert(i <= 15U);
1151 assert(config->divider == 255U); /* Always set to 0xFF to use with the fractional baudrate generator.*/
1152
1153 if (i <= 7UL)
1154 {
1155 CLKCTL1->FLEXCOMM[i].FRGCLKSEL = (uint32_t)config->sfg_clock_src;
1156 CLKCTL1->FLEXCOMM[i].FRGCTL = (CLKCTL1_FRGCTL_MULT(config->mult) | CLKCTL1_FRGCTL_DIV(config->divider));
1157 }
1158 else if (i == 14UL)
1159 {
1160 CLKCTL1->FRG14CLKSEL = (uint32_t)config->sfg_clock_src;
1161 CLKCTL1->FRG14CTL = (CLKCTL1_FRGCTL_MULT(config->mult) | CLKCTL1_FRGCTL_DIV(config->divider));
1162 }
1163 else if (i == 15UL)
1164 {
1165 CLKCTL1->FRG15CLKSEL = (uint32_t)config->sfg_clock_src;
1166 CLKCTL1->FRG15CTL = (CLKCTL1_FRGCTL_MULT(config->mult) | CLKCTL1_FRGCTL_DIV(config->divider));
1167 }
1168 else
1169 {
1170 assert(false);
1171 }
1172 }
1173
1174 #ifndef __XCC__
1175 /**
1176 * brief Enable FFRO 48M/60M clock.
1177 * Note Need to make sure FFRO and ROM has power(PDRUNCFG0[16] and PDRUNCFG1[28] = 0U) before calling this API
1178 *
1179 * param ffroFreq : target fro frequency.
1180 * return Nothing
1181 */
CLOCK_EnableFfroClk(clock_ffro_freq_t ffroFreq)1182 void CLOCK_EnableFfroClk(clock_ffro_freq_t ffroFreq)
1183 {
1184 uint32_t tempco = 0U;
1185 uint32_t coarse = 0U;
1186 uint32_t fine = 0U;
1187 uint32_t ffro_delay = 0U;
1188
1189 assert(((SYSCTL0->PDRUNCFG0 & SYSCTL0_PDRUNCFG0_FFRO_PD_MASK) == 0UL) &&
1190 ((SYSCTL0->PDRUNCFG1 & SYSCTL0_PDRUNCFG1_ROM_PD_MASK) == 0UL));
1191
1192 /* FFROCTL0, FFROCTL1 and the otp trim value should not be touched by application */
1193 CLKCTL0->FFROCTL1 |= CLKCTL0_FFROCTL1_UPDATE_MASK;
1194 OTP_INIT_API(CLOCK_GetMainClkFreq() / ((CLKCTL0->SYSCPUAHBCLKDIV & CLKCTL0_SYSCPUAHBCLKDIV_DIV_MASK) + 1U));
1195 if (ffroFreq == kCLOCK_Ffro48M)
1196 {
1197 /* Read 48M FFRO clock Trim settings from fuse. */
1198 OTP_FUSE_READ_API(FIRC_48MHZ_TRIM_TEMPCO, &tempco);
1199 OTP_FUSE_READ_API(FIRC_48MHZ_TRIM_COARSE, &coarse);
1200 OTP_FUSE_READ_API(FIRC_48MHZ_TRIM_FINE, &fine);
1201 }
1202 else
1203 {
1204 /* Read 60M FFRO clock Trim settings from fuse. */
1205 OTP_FUSE_READ_API(FIRC_60MHZ_TRIM_TEMPCO, &tempco);
1206 OTP_FUSE_READ_API(FIRC_60MHZ_TRIM_COARSE, &coarse);
1207 OTP_FUSE_READ_API(FIRC_60MHZ_TRIM_FINE, &fine);
1208 }
1209 /* Read FFRO stable time from fuse. */
1210 OTP_FUSE_READ_API(FFRO_STABLE_TIME, &ffro_delay);
1211 OTP_DEINIT_API();
1212 CLKCTL0->FFROCTL0 = CLKCTL0_FFROCTL0_TRIM_TEMPCO(tempco) | CLKCTL0_FFROCTL0_TRIM_COARSE(coarse) |
1213 CLKCTL0_FFROCTL0_TRIM_FINE(fine) |
1214 CLKCTL0_FFROCTL0_TRIM_RANGE((ffroFreq == kCLOCK_Ffro48M) ? 0 : 3);
1215 CLKCTL0->FFROCTL1 &= ~CLKCTL0_FFROCTL1_UPDATE_MASK;
1216 /* No FFRO enable/disable control in CLKCTL. Just wait FFRO stable in case FFRO just get powered on. */
1217 SDK_DelayAtLeastUs(ffro_delay, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1218 }
1219 /**
1220 * brief Enable SFRO clock.
1221 * Note Need to make sure SFRO and ROM has power(PDRUNCFG0[15] and PDRUNCFG1[28] = 0U) before calling this API
1222 *
1223 * param Nothing
1224 * return Nothing
1225 */
1226
CLOCK_EnableSfroClk(void)1227 void CLOCK_EnableSfroClk(void)
1228 {
1229 uint32_t sfro_delay = 0U;
1230
1231 assert(((SYSCTL0->PDRUNCFG0 & SYSCTL0_PDRUNCFG0_SFRO_PD_MASK) == 0UL) &&
1232 ((SYSCTL0->PDRUNCFG1 & SYSCTL0_PDRUNCFG1_ROM_PD_MASK) == 0UL));
1233 /* The otp trim value should not be touched by application */
1234 OTP_INIT_API(CLOCK_GetMainClkFreq() / ((CLKCTL0->SYSCPUAHBCLKDIV & CLKCTL0_SYSCPUAHBCLKDIV_DIV_MASK) + 1U));
1235 /* Read SFRO stable time from fuse. */
1236 OTP_FUSE_READ_API(SFRO_STABLE_TIME, &sfro_delay);
1237 OTP_DEINIT_API();
1238 /* No SFRO enable/disable control in CLKCTL. Just wait SFRO stable in case SFRO just get powered on. */
1239 SDK_DelayAtLeastUs(sfro_delay, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1240 }
1241 #endif /* __XCC__ */
1242
1243 /* Initialize the SYSTEM PLL Clk */
1244 /*! brief Initialize the System PLL.
1245 * param config : Configuration to set to PLL.
1246 */
CLOCK_InitSysPll(const clock_sys_pll_config_t * config)1247 void CLOCK_InitSysPll(const clock_sys_pll_config_t *config)
1248 {
1249 /* Power down SYSPLL before change fractional settings */
1250 SYSCTL0->PDRUNCFG0_SET = SYSCTL0_PDRUNCFG0_SYSPLLLDO_PD_MASK | SYSCTL0_PDRUNCFG0_SYSPLLANA_PD_MASK;
1251
1252 CLKCTL0->SYSPLL0CLKSEL = (uint32_t)config->sys_pll_src;
1253 CLKCTL0->SYSPLL0NUM = config->numerator;
1254 CLKCTL0->SYSPLL0DENOM = config->denominator;
1255 switch (config->sys_pll_mult)
1256 {
1257 case kCLOCK_SysPllMult16:
1258 CLKCTL0->SYSPLL0CTL0 =
1259 (CLKCTL0->SYSPLL0CTL0 & ~CLKCTL0_SYSPLL0CTL0_MULT_MASK) | CLKCTL0_SYSPLL0CTL0_MULT(16);
1260 break;
1261 case kCLOCK_SysPllMult17:
1262 CLKCTL0->SYSPLL0CTL0 =
1263 (CLKCTL0->SYSPLL0CTL0 & ~CLKCTL0_SYSPLL0CTL0_MULT_MASK) | CLKCTL0_SYSPLL0CTL0_MULT(17);
1264 break;
1265 case kCLOCK_SysPllMult18:
1266 CLKCTL0->SYSPLL0CTL0 =
1267 (CLKCTL0->SYSPLL0CTL0 & ~CLKCTL0_SYSPLL0CTL0_MULT_MASK) | CLKCTL0_SYSPLL0CTL0_MULT(18);
1268 break;
1269 case kCLOCK_SysPllMult19:
1270 CLKCTL0->SYSPLL0CTL0 =
1271 (CLKCTL0->SYSPLL0CTL0 & ~CLKCTL0_SYSPLL0CTL0_MULT_MASK) | CLKCTL0_SYSPLL0CTL0_MULT(19);
1272 break;
1273 case kCLOCK_SysPllMult20:
1274 CLKCTL0->SYSPLL0CTL0 =
1275 (CLKCTL0->SYSPLL0CTL0 & ~CLKCTL0_SYSPLL0CTL0_MULT_MASK) | CLKCTL0_SYSPLL0CTL0_MULT(20);
1276 break;
1277 case kCLOCK_SysPllMult21:
1278 CLKCTL0->SYSPLL0CTL0 =
1279 (CLKCTL0->SYSPLL0CTL0 & ~CLKCTL0_SYSPLL0CTL0_MULT_MASK) | CLKCTL0_SYSPLL0CTL0_MULT(21);
1280 break;
1281 case kCLOCK_SysPllMult22:
1282 CLKCTL0->SYSPLL0CTL0 =
1283 (CLKCTL0->SYSPLL0CTL0 & ~CLKCTL0_SYSPLL0CTL0_MULT_MASK) | CLKCTL0_SYSPLL0CTL0_MULT(22);
1284 break;
1285 default:
1286 /* Added comments to prevent the violation of MISRA rule. */
1287 break;
1288 }
1289 /* Clear System PLL reset*/
1290 CLKCTL0->SYSPLL0CTL0 &= ~CLKCTL0_SYSPLL0CTL0_RESET_MASK;
1291 /* Power up SYSPLL*/
1292 SYSCTL0->PDRUNCFG0_CLR = SYSCTL0_PDRUNCFG0_SYSPLLLDO_PD_MASK | SYSCTL0_PDRUNCFG0_SYSPLLANA_PD_MASK;
1293 SDK_DelayAtLeastUs((CLKCTL0->SYSPLL0LOCKTIMEDIV2 & CLKCTL0_SYSPLL0LOCKTIMEDIV2_LOCKTIMEDIV2_MASK) / 2UL,
1294 SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1295 /* Set System PLL HOLDRINGOFF_ENA */
1296 CLKCTL0->SYSPLL0CTL0 |= CLKCTL0_SYSPLL0CTL0_HOLDRINGOFF_ENA_MASK;
1297 SDK_DelayAtLeastUs((CLKCTL0->SYSPLL0LOCKTIMEDIV2 & CLKCTL0_SYSPLL0LOCKTIMEDIV2_LOCKTIMEDIV2_MASK) / 6UL,
1298 SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1299 /* Clear System PLL HOLDRINGOFF_ENA*/
1300 CLKCTL0->SYSPLL0CTL0 &= ~CLKCTL0_SYSPLL0CTL0_HOLDRINGOFF_ENA_MASK;
1301 SDK_DelayAtLeastUs((CLKCTL0->SYSPLL0LOCKTIMEDIV2 & CLKCTL0_SYSPLL0LOCKTIMEDIV2_LOCKTIMEDIV2_MASK) / 3UL,
1302 SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1303 }
1304 /* Initialize the System PLL PFD */
1305 /*! brief Initialize the System PLL PFD.
1306 * param pfd : Which PFD clock to enable.
1307 * param divider : The PFD divider value.
1308 * note It is recommended that PFD settings are kept between 12-35.
1309 */
CLOCK_InitSysPfd(clock_pfd_t pfd,uint8_t divider)1310 void CLOCK_InitSysPfd(clock_pfd_t pfd, uint8_t divider)
1311 {
1312 uint32_t pfdIndex = (uint32_t)pfd;
1313 uint32_t syspfd;
1314
1315 syspfd = CLKCTL0->SYSPLL0PFD &
1316 ~(((uint32_t)CLKCTL0_SYSPLL0PFD_PFD0_CLKGATE_MASK | (uint32_t)CLKCTL0_SYSPLL0PFD_PFD0_MASK)
1317 << (8UL * pfdIndex));
1318
1319 /* Disable the clock output first. */
1320 CLKCTL0->SYSPLL0PFD = syspfd | ((uint32_t)CLKCTL0_SYSPLL0PFD_PFD0_CLKGATE_MASK << (8UL * pfdIndex));
1321
1322 /* Set the new value and enable output. */
1323 CLKCTL0->SYSPLL0PFD = syspfd | (CLKCTL0_SYSPLL0PFD_PFD0(divider) << (8UL * pfdIndex));
1324 /* Wait for output becomes stable. */
1325 while ((CLKCTL0->SYSPLL0PFD & ((uint32_t)CLKCTL0_SYSPLL0PFD_PFD0_CLKRDY_MASK << (8UL * pfdIndex))) == 0UL)
1326 {
1327 }
1328 /* Clear ready status flag. */
1329 CLKCTL0->SYSPLL0PFD |= ((uint32_t)CLKCTL0_SYSPLL0PFD_PFD0_CLKRDY_MASK << (8UL * pfdIndex));
1330 }
1331 /* Initialize the Audio PLL Clk */
1332 /*! brief Initialize the audio PLL.
1333 * param config : Configuration to set to PLL.
1334 */
CLOCK_InitAudioPll(const clock_audio_pll_config_t * config)1335 void CLOCK_InitAudioPll(const clock_audio_pll_config_t *config)
1336 {
1337 /* Power down Audio PLL before change fractional settings */
1338 SYSCTL0->PDRUNCFG0_SET = SYSCTL0_PDRUNCFG0_AUDPLLLDO_PD_MASK | SYSCTL0_PDRUNCFG0_AUDPLLANA_PD_MASK;
1339
1340 CLKCTL1->AUDIOPLL0CLKSEL = (uint32_t)(config->audio_pll_src);
1341 CLKCTL1->AUDIOPLL0NUM = config->numerator;
1342 CLKCTL1->AUDIOPLL0DENOM = config->denominator;
1343 switch (config->audio_pll_mult)
1344 {
1345 case kCLOCK_AudioPllMult16:
1346 CLKCTL1->AUDIOPLL0CTL0 =
1347 (CLKCTL1->AUDIOPLL0CTL0 & ~CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) | CLKCTL1_AUDIOPLL0CTL0_MULT(16);
1348 break;
1349 case kCLOCK_AudioPllMult17:
1350 CLKCTL1->AUDIOPLL0CTL0 =
1351 (CLKCTL1->AUDIOPLL0CTL0 & ~CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) | CLKCTL1_AUDIOPLL0CTL0_MULT(17);
1352 break;
1353 case kCLOCK_AudioPllMult18:
1354 CLKCTL1->AUDIOPLL0CTL0 =
1355 (CLKCTL1->AUDIOPLL0CTL0 & ~CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) | CLKCTL1_AUDIOPLL0CTL0_MULT(18);
1356 break;
1357 case kCLOCK_AudioPllMult19:
1358 CLKCTL1->AUDIOPLL0CTL0 =
1359 (CLKCTL1->AUDIOPLL0CTL0 & ~CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) | CLKCTL1_AUDIOPLL0CTL0_MULT(19);
1360 break;
1361 case kCLOCK_AudioPllMult20:
1362 CLKCTL1->AUDIOPLL0CTL0 =
1363 (CLKCTL1->AUDIOPLL0CTL0 & ~CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) | CLKCTL1_AUDIOPLL0CTL0_MULT(20);
1364 break;
1365 case kCLOCK_AudioPllMult21:
1366 CLKCTL1->AUDIOPLL0CTL0 =
1367 (CLKCTL1->AUDIOPLL0CTL0 & ~CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) | CLKCTL1_AUDIOPLL0CTL0_MULT(21);
1368 break;
1369 case kCLOCK_AudioPllMult22:
1370 CLKCTL1->AUDIOPLL0CTL0 =
1371 (CLKCTL1->AUDIOPLL0CTL0 & ~CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) | CLKCTL1_AUDIOPLL0CTL0_MULT(22);
1372 break;
1373 default:
1374 /* Added comments to prevent the violation of MISRA C-2012 rule */
1375 break;
1376 }
1377
1378 /* Clear Audio PLL reset*/
1379 CLKCTL1->AUDIOPLL0CTL0 &= ~CLKCTL1_AUDIOPLL0CTL0_RESET_MASK;
1380 /* Power up Audio PLL*/
1381 SYSCTL0->PDRUNCFG0_CLR = SYSCTL0_PDRUNCFG0_AUDPLLLDO_PD_MASK | SYSCTL0_PDRUNCFG0_AUDPLLANA_PD_MASK;
1382 SDK_DelayAtLeastUs((CLKCTL1->AUDIOPLL0LOCKTIMEDIV2 & CLKCTL1_AUDIOPLL0LOCKTIMEDIV2_LOCKTIMEDIV2_MASK) / 2UL,
1383 SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1384 /* Set Audio PLL HOLDRINGOFF_ENA */
1385 CLKCTL1->AUDIOPLL0CTL0 |= CLKCTL1_AUDIOPLL0CTL0_HOLDRINGOFF_ENA_MASK;
1386 SDK_DelayAtLeastUs((CLKCTL1->AUDIOPLL0LOCKTIMEDIV2 & CLKCTL1_AUDIOPLL0LOCKTIMEDIV2_LOCKTIMEDIV2_MASK) / 6UL,
1387 SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1388 /* Clear Audio PLL HOLDRINGOFF_ENA*/
1389 CLKCTL1->AUDIOPLL0CTL0 &= ~CLKCTL1_AUDIOPLL0CTL0_HOLDRINGOFF_ENA_MASK;
1390 SDK_DelayAtLeastUs((CLKCTL1->AUDIOPLL0LOCKTIMEDIV2 & CLKCTL1_AUDIOPLL0LOCKTIMEDIV2_LOCKTIMEDIV2_MASK) / 3UL,
1391 SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1392 }
1393 /* Initialize the Audio PLL PFD */
1394 /*! brief Initialize the audio PLL PFD.
1395 * param pfd : Which PFD clock to enable.
1396 * param divider : The PFD divider value.
1397 * note It is recommended that PFD settings are kept between 12-35.
1398 */
CLOCK_InitAudioPfd(clock_pfd_t pfd,uint8_t divider)1399 void CLOCK_InitAudioPfd(clock_pfd_t pfd, uint8_t divider)
1400 {
1401 uint32_t pfdIndex = (uint32_t)pfd;
1402 uint32_t syspfd;
1403
1404 syspfd = CLKCTL1->AUDIOPLL0PFD &
1405 ~(((uint32_t)CLKCTL1_AUDIOPLL0PFD_PFD0_CLKGATE_MASK | (uint32_t)CLKCTL1_AUDIOPLL0PFD_PFD0_MASK)
1406 << (8UL * pfdIndex));
1407
1408 /* Disable the clock output first. */
1409 CLKCTL1->AUDIOPLL0PFD = syspfd | ((uint32_t)CLKCTL1_AUDIOPLL0PFD_PFD0_CLKGATE_MASK << (8UL * pfdIndex));
1410
1411 /* Set the new value and enable output. */
1412 CLKCTL1->AUDIOPLL0PFD = syspfd | (CLKCTL1_AUDIOPLL0PFD_PFD0(divider) << (8UL * pfdIndex));
1413 /* Wait for output becomes stable. */
1414 while ((CLKCTL1->AUDIOPLL0PFD & ((uint32_t)CLKCTL1_AUDIOPLL0PFD_PFD0_CLKRDY_MASK << (8UL * pfdIndex))) == 0UL)
1415 {
1416 }
1417 /* Clear ready status flag. */
1418 CLKCTL1->AUDIOPLL0PFD |= ((uint32_t)CLKCTL1_AUDIOPLL0PFD_PFD0_CLKRDY_MASK << (8UL * pfdIndex));
1419 }
1420 /*! @brief Enable/Disable sys osc clock from external crystal clock.
1421 * @param enable : true to enable system osc clock, false to bypass system osc.
1422 * @param enableLowPower : true to enable low power mode, false to enable high gain mode.
1423 * @param delay_us : Delay time after OSC power up.
1424 */
CLOCK_EnableSysOscClk(bool enable,bool enableLowPower,uint32_t delay_us)1425 void CLOCK_EnableSysOscClk(bool enable, bool enableLowPower, uint32_t delay_us)
1426 {
1427 uint32_t ctrl = enableLowPower ? CLKCTL0_SYSOSCCTL0_LP_ENABLE_MASK : 0U;
1428
1429 if (enable)
1430 {
1431 CLKCTL0->SYSOSCCTL0 = ctrl;
1432 CLKCTL0->SYSOSCBYPASS = 0;
1433 SDK_DelayAtLeastUs(delay_us, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1434 }
1435 else
1436 {
1437 CLKCTL0->SYSOSCCTL0 = ctrl | CLKCTL0_SYSOSCCTL0_BYPASS_ENABLE_MASK;
1438 }
1439 }
1440 /*! @brief Enable USB HS device clock.
1441 *
1442 * This function enables USB HS device clock.
1443 */
CLOCK_EnableUsbhsDeviceClock(void)1444 void CLOCK_EnableUsbhsDeviceClock(void)
1445 {
1446 CLOCK_EnableClock(kCLOCK_UsbhsPhy);
1447 /* Enable usbhs device and ram clock */
1448 CLOCK_EnableClock(kCLOCK_UsbhsDevice);
1449 CLOCK_EnableClock(kCLOCK_UsbhsSram);
1450 }
1451
1452 /*! @brief Enable USB HS host clock.
1453 *
1454 * This function enables USB HS host clock.
1455 */
CLOCK_EnableUsbhsHostClock(void)1456 void CLOCK_EnableUsbhsHostClock(void)
1457 {
1458 CLOCK_EnableClock(kCLOCK_UsbhsPhy);
1459 /* Enable usbhs host and ram clock */
1460 CLOCK_EnableClock(kCLOCK_UsbhsHost);
1461 CLOCK_EnableClock(kCLOCK_UsbhsSram);
1462 }
1463
1464 /*! brief Enable USB hs0PhyPll clock.
1465 *
1466 * param src USB HS clock source.
1467 * param freq The frequency specified by src.
1468 * retval true The clock is set successfully.
1469 * retval false The clock source is invalid to get proper USB HS clock.
1470 */
CLOCK_EnableUsbHs0PhyPllClock(clock_attach_id_t src,uint32_t freq)1471 bool CLOCK_EnableUsbHs0PhyPllClock(clock_attach_id_t src, uint32_t freq)
1472 {
1473 uint32_t phyPllDiv = 0U;
1474 uint32_t multiplier = 0U;
1475 bool retVal = true;
1476
1477 USBPHY->CTRL_CLR = USBPHY_CTRL_SFTRST_MASK;
1478
1479 uint32_t delay = 100000;
1480 while ((delay--) != 0UL)
1481 {
1482 __NOP();
1483 }
1484
1485 multiplier = 480000000UL / freq;
1486
1487 switch (multiplier)
1488 {
1489 case 13:
1490 {
1491 phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(0U);
1492 break;
1493 }
1494 case 15:
1495 {
1496 phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(1U);
1497 break;
1498 }
1499 case 16:
1500 {
1501 phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(2U);
1502 break;
1503 }
1504 case 20:
1505 {
1506 phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(3U);
1507 break;
1508 }
1509 case 22:
1510 {
1511 phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(4U);
1512 break;
1513 }
1514 case 25:
1515 {
1516 phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(5U);
1517 break;
1518 }
1519 case 30:
1520 {
1521 phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(6U);
1522 break;
1523 }
1524 case 240:
1525 {
1526 phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(7U);
1527 break;
1528 }
1529 default:
1530 {
1531 retVal = false;
1532 break;
1533 }
1534 }
1535
1536 if (retVal)
1537 {
1538 USBPHY->PLL_SIC_SET = (USBPHY_PLL_SIC_PLL_POWER(1) | USBPHY_PLL_SIC_PLL_REG_ENABLE_MASK);
1539 USBPHY->PLL_SIC = (USBPHY->PLL_SIC & ~(USBPHY_PLL_SIC_PLL_DIV_SEL_MASK)) | phyPllDiv;
1540 USBPHY->PLL_SIC_CLR = USBPHY_PLL_SIC_PLL_BYPASS_MASK;
1541 USBPHY->PLL_SIC_SET = (USBPHY_PLL_SIC_PLL_EN_USB_CLKS_MASK);
1542
1543 USBPHY->CTRL_CLR = USBPHY_CTRL_CLR_CLKGATE_MASK;
1544 USBPHY->PWD_SET = 0x0;
1545
1546 while (0UL == (USBPHY->PLL_SIC & USBPHY_PLL_SIC_PLL_LOCK_MASK))
1547 {
1548 }
1549 }
1550
1551 return retVal;
1552 }
1553