1 /*
2 * Copyright 2017 - 2021 , NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_clock.h"
9 #include "fsl_power.h"
10 /*******************************************************************************
11 * Definitions
12 ******************************************************************************/
13 /* Component ID definition, used by tools. */
14 #ifndef FSL_COMPONENT_ID
15 #define FSL_COMPONENT_ID "platform.drivers.clock"
16 #endif
17 #define NVALMAX (0x100U)
18 #define PVALMAX (0x20U)
19 #define MVALMAX (0x10000U)
20
21 #define PLL_MAX_N_DIV 0x100U
22
23 /*--------------------------------------------------------------------------
24 !!! If required these #defines can be moved to chip library file
25 ----------------------------------------------------------------------------*/
26
27 #define PLL_SSCG1_MDEC_VAL_P (10U) /* MDEC is in bits 25 downto 10 */
28 #define PLL_SSCG1_MDEC_VAL_M (0xFFFFULL << PLL_SSCG1_MDEC_VAL_P)
29 #define PLL_NDEC_VAL_P (0U) /* NDEC is in bits 9:0 */
30 #define PLL_NDEC_VAL_M (0xFFUL << PLL_NDEC_VAL_P)
31 #define PLL_PDEC_VAL_P (0U) /*!< PDEC is in bits 6:0 */
32 #define PLL_PDEC_VAL_M (0x1FUL << PLL_PDEC_VAL_P)
33
34 #define PLL_MIN_CCO_FREQ_MHZ (275000000U)
35 #define PLL_MAX_CCO_FREQ_MHZ (550000000U)
36 #define PLL_LOWER_IN_LIMIT (2000U) /*!< Minimum PLL input rate */
37 #define PLL_HIGHER_IN_LIMIT (150000000U) /*!< Maximum PLL input rate */
38 #define PLL_MIN_IN_SSMODE (3000000U)
39 #define PLL_MAX_IN_SSMODE \
40 (100000000U) /*!< Not find the value in UM, Just use the maximum frequency which device support */
41
42 /* PLL NDEC reg */
43 #define PLL_NDEC_VAL_SET(value) (((unsigned long)(value) << PLL_NDEC_VAL_P) & PLL_NDEC_VAL_M)
44 /* PLL PDEC reg */
45 #define PLL_PDEC_VAL_SET(value) (((unsigned long)(value) << PLL_PDEC_VAL_P) & PLL_PDEC_VAL_M)
46 /* SSCG control1 */
47 #define PLL_SSCG1_MDEC_VAL_SET(value) (((uint64_t)(value) << PLL_SSCG1_MDEC_VAL_P) & PLL_SSCG1_MDEC_VAL_M)
48
49 /* PLL0 SSCG control1 */
50 #define PLL0_SSCG_MD_FRACT_P 0U
51 #define PLL0_SSCG_MD_INT_P 25U
52 #define PLL0_SSCG_MD_FRACT_M (0x1FFFFFFUL << PLL0_SSCG_MD_FRACT_P)
53 #define PLL0_SSCG_MD_INT_M ((uint64_t)0xFFUL << PLL0_SSCG_MD_INT_P)
54
55 #define PLL0_SSCG_MD_FRACT_SET(value) (((uint64_t)(value) << PLL0_SSCG_MD_FRACT_P) & PLL0_SSCG_MD_FRACT_M)
56 #define PLL0_SSCG_MD_INT_SET(value) (((uint64_t)(value) << PLL0_SSCG_MD_INT_P) & PLL0_SSCG_MD_INT_M)
57
58 /* Saved value of PLL output rate, computed whenever needed to save run-time
59 computation on each call to retrive the PLL rate. */
60 static uint32_t s_Pll0_Freq;
61 static uint32_t s_Pll1_Freq;
62
63 /** External clock rate on the CLKIN pin in Hz. If not used,
64 set this to 0. Otherwise, set it to the exact rate in Hz this pin is
65 being driven at. */
66 static uint32_t s_Ext_Clk_Freq = 16000000U;
67 static uint32_t s_I2S_Mclk_Freq = 0U;
68 static uint32_t s_PLU_ClkIn_Freq = 0U;
69
70 /*******************************************************************************
71 * Variables
72 ******************************************************************************/
73
74 /*******************************************************************************
75 * Prototypes
76 ******************************************************************************/
77 /* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */
78 static void pllFindSel(uint32_t M, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR);
79 /* Get predivider (N) from PLL0 NDEC setting */
80 static uint32_t findPll0PreDiv(void);
81 /* Get predivider (N) from PLL1 NDEC setting */
82 static uint32_t findPll1PreDiv(void);
83 /* Get postdivider (P) from PLL0 PDEC setting */
84 static uint32_t findPll0PostDiv(void);
85 /* Get postdivider (P) from PLL1 PDEC setting. */
86 static uint32_t findPll1PostDiv(void);
87 /* Get multiplier (M) from PLL0 MDEC and SSCG settings */
88 static float findPll0MMult(void);
89 /* Get multiplier (M) from PLL1 MDEC. */
90 static uint32_t findPll1MMult(void);
91 /* Get the greatest common divisor */
92 static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n);
93 /* Set PLL output based on desired output rate */
94 static pll_error_t CLOCK_GetPll0Config(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useSS);
95 /* Update local PLL rate variable */
96 static void CLOCK_GetPLL0OutFromSetupUpdate(pll_setup_t *pSetup);
97 /* Update local PLL1 rate variable */
98 static void CLOCK_GetPLL1OutFromSetupUpdate(pll_setup_t *pSetup);
99
100 /*******************************************************************************
101 * Code
102 ******************************************************************************/
103
104 /* Clock Selection for IP */
105 /**
106 * brief Configure the clock selection muxes.
107 * param connection : Clock to be configured.
108 * return Nothing
109 */
CLOCK_AttachClk(clock_attach_id_t connection)110 void CLOCK_AttachClk(clock_attach_id_t connection)
111 {
112 uint8_t mux;
113 uint8_t sel;
114 uint16_t item;
115 uint32_t tmp32 = (uint32_t)connection;
116 uint32_t i;
117 volatile uint32_t *pClkSel;
118
119 pClkSel = &(SYSCON->SYSTICKCLKSELX[0]);
120
121 if (kNONE_to_NONE != connection)
122 {
123 for (i = 0U; i < 2U; i++)
124 {
125 if (tmp32 == 0U)
126 {
127 break;
128 }
129 item = (uint16_t)GET_ID_ITEM(tmp32);
130 if (item != 0U)
131 {
132 mux = (uint8_t)GET_ID_ITEM_MUX(item);
133 sel = (uint8_t)GET_ID_ITEM_SEL(item);
134 if (mux == CM_RTCOSC32KCLKSEL)
135 {
136 PMC->RTCOSC32K = (PMC->RTCOSC32K & ~PMC_RTCOSC32K_SEL_MASK) | PMC_RTCOSC32K_SEL(sel);
137 }
138 else if (mux == CM_OSTIMERCLKSEL)
139 {
140 PMC->OSTIMERr = (PMC->OSTIMERr & ~PMC_OSTIMER_OSTIMERCLKSEL_MASK) | PMC_OSTIMER_OSTIMERCLKSEL(sel);
141 }
142 else
143 {
144 pClkSel[mux] = sel;
145 }
146 }
147 tmp32 = GET_ID_NEXT_ITEM(tmp32); /* pick up next descriptor */
148 }
149 }
150 }
151
152 /* Return the actual clock attach id */
153 /**
154 * brief Get the actual clock attach id.
155 * This fuction uses the offset in input attach id, then it reads the actual source value in
156 * the register and combine the offset to obtain an actual attach id.
157 * param attachId : Clock attach id to get.
158 * return Clock source value.
159 */
CLOCK_GetClockAttachId(clock_attach_id_t attachId)160 clock_attach_id_t CLOCK_GetClockAttachId(clock_attach_id_t attachId)
161 {
162 uint8_t mux;
163 uint32_t actualSel;
164 uint32_t tmp32 = (uint32_t)attachId;
165 uint32_t i;
166 uint32_t actualAttachId = 0U;
167 uint32_t selector = GET_ID_SELECTOR(tmp32);
168 volatile uint32_t *pClkSel;
169
170 pClkSel = &(SYSCON->SYSTICKCLKSELX[0]);
171
172 if (kNONE_to_NONE == attachId)
173 {
174 return kNONE_to_NONE;
175 }
176
177 for (i = 0U; i < 2U; i++)
178 {
179 mux = (uint8_t)GET_ID_ITEM_MUX(tmp32);
180 if (tmp32 != 0UL)
181 {
182 if (mux == CM_RTCOSC32KCLKSEL)
183 {
184 actualSel = ((PMC->RTCOSC32K) & PMC_RTCOSC32K_SEL_MASK) >> PMC_RTCOSC32K_SEL_SHIFT;
185 }
186 else if (mux == CM_OSTIMERCLKSEL)
187 {
188 actualSel = ((PMC->OSTIMERr) & PMC_OSTIMER_OSTIMERCLKSEL_MASK) >> PMC_OSTIMER_OSTIMERCLKSEL_SHIFT;
189 }
190 else
191 {
192 actualSel = pClkSel[mux];
193 }
194
195 /* Consider the combination of two registers */
196 actualAttachId |= CLK_ATTACH_ID(mux, actualSel, i);
197 }
198 tmp32 = GET_ID_NEXT_ITEM(tmp32); /*!< pick up next descriptor */
199 }
200
201 actualAttachId |= selector;
202
203 return (clock_attach_id_t)actualAttachId;
204 }
205
206 /* Set IP Clock Divider */
207 /**
208 * brief Setup peripheral clock dividers.
209 * param div_name : Clock divider name
210 * param divided_by_value: Value to be divided
211 * param reset : Whether to reset the divider counter.
212 * return Nothing
213 */
CLOCK_SetClkDiv(clock_div_name_t div_name,uint32_t divided_by_value,bool reset)214 void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset)
215 {
216 volatile uint32_t *pClkDiv;
217
218 pClkDiv = &(SYSCON->SYSTICKCLKDIV0);
219 if ((div_name >= kCLOCK_DivFlexFrg0) && (div_name <= kCLOCK_DivFlexFrg7))
220 {
221 /*!< Flexcomm Interface function clock = (clock selected via FCCLKSEL) / (1+ MULT /DIV), DIV = 0xFF */
222 ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] =
223 SYSCON_FLEXFRG0CTRL_DIV_MASK | SYSCON_FLEXFRG0CTRL_MULT(divided_by_value);
224 }
225 else
226 {
227 if (reset)
228 {
229 ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = 1UL << 29U;
230 }
231 if (divided_by_value == 0U) /*!< halt */
232 {
233 ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = 1UL << 30U;
234 }
235 else
236 {
237 ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = (divided_by_value - 1U);
238 }
239 }
240 }
241
242 /* Set RTC 1KHz Clock Divider */
243 /**
244 * brief Setup rtc 1khz clock divider.
245 * param divided_by_value: Value to be divided
246 * return Nothing
247 */
CLOCK_SetRtc1khzClkDiv(uint32_t divided_by_value)248 void CLOCK_SetRtc1khzClkDiv(uint32_t divided_by_value)
249 {
250 PMC->RTCOSC32K =
251 (PMC->RTCOSC32K & ~PMC_RTCOSC32K_CLK1KHZDIV_MASK) | PMC_RTCOSC32K_CLK1KHZDIV(divided_by_value - 28U);
252 }
253
254 /* Set RTC 1KHz Clock Divider */
255 /**
256 * brief Setup rtc 1hz clock divider.
257 * param divided_by_value: Value to be divided
258 * return Nothing
259 */
CLOCK_SetRtc1hzClkDiv(uint32_t divided_by_value)260 void CLOCK_SetRtc1hzClkDiv(uint32_t divided_by_value)
261 {
262 if (divided_by_value == 0U) /*!< halt */
263 {
264 PMC->RTCOSC32K |= (1UL << PMC_RTCOSC32K_CLK1HZDIVHALT_SHIFT);
265 }
266 else
267 {
268 PMC->RTCOSC32K =
269 (PMC->RTCOSC32K & ~PMC_RTCOSC32K_CLK1HZDIV_MASK) | PMC_RTCOSC32K_CLK1HZDIV(divided_by_value - 31744U);
270 }
271 }
272
273 /* Set FRO Clocking */
274 /**
275 * brief Initialize the Core clock to given frequency (12, 48 or 96 MHz).
276 * Turns on FRO and uses default CCO, if freq is 12000000, then high speed output is off, else high speed output is
277 * enabled.
278 * param iFreq : Desired frequency (must be one of #CLK_FRO_12MHZ or #CLK_FRO_48MHZ or #CLK_FRO_96MHZ)
279 * return returns success or fail status.
280 */
CLOCK_SetupFROClocking(uint32_t iFreq)281 status_t CLOCK_SetupFROClocking(uint32_t iFreq)
282 {
283 if ((iFreq != 12000000U) && (iFreq != 96000000U))
284 {
285 return kStatus_Fail;
286 }
287 /* Enable Analog Control module */
288 SYSCON->PRESETCTRLCLR[2] = (1UL << SYSCON_PRESETCTRL2_ANALOG_CTRL_RST_SHIFT);
289 SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_ANALOG_CTRL_MASK;
290 /* Power up the FRO192M */
291 POWER_DisablePD(kPDRUNCFG_PD_FRO192M);
292
293 if (iFreq == 96000000U)
294 {
295 ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_ENA_96MHZCLK(1);
296 }
297 /* always enable
298 else if (iFreq == 48000000U)
299 {
300 ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_ENA_48MHZCLK(1);
301 }*/
302 else
303 {
304 ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_ENA_12MHZCLK(1);
305 }
306 return kStatus_Success;
307 }
308
309 /* Set the FLASH wait states for the passed frequency */
310 /**
311 * brief Set the flash wait states for the input freuqency.
312 * param iFreq: Input frequency
313 * return Nothing
314 */
315 typedef struct
316 {
317 uint32_t waitstate;
318 uint32_t freqMax;
319 } WaitStateInterval_t;
320
321 /* clang-format off */
322 /* Wait state if frequency is inferior to the one specified */
323 static const WaitStateInterval_t IntervalList[] = {
324 {0, 11000000},
325 {1, 22000000},
326 {2, 33000000},
327 {3, 44000000},
328 {4, 55000000},
329 {5, 66000000},
330 {6, 84000000},
331 {7, 104000000},
332 {8, 119000000},
333 {9, 129000000},
334 {10, 144000000},
335 {11, 150000000} /* Maximum allowed frequency (150 MHz) */
336 };
337 /* clang-format on */
338
CLOCK_SetFLASHAccessCyclesForFreq(uint32_t system_freq_hz)339 void CLOCK_SetFLASHAccessCyclesForFreq(uint32_t system_freq_hz)
340 {
341 /* Flash Controller & FMC internal number of Wait States (minus 1) */
342 uint32_t num_wait_states = 15UL; /* Default to the maximum number of wait states */
343 uint32_t prefetch_enable_mask = SYSCON->FMCCR & SYSCON_FMCCR_PREFEN_MASK;
344
345 for (size_t cnt = 0; cnt < (sizeof(IntervalList) / sizeof(WaitStateInterval_t)); cnt++)
346 {
347 if (system_freq_hz <= IntervalList[cnt].freqMax)
348 {
349 num_wait_states = IntervalList[cnt].waitstate;
350 break;
351 }
352 }
353
354 /*The prefetch bit must be disabled before any flash commands*/
355 SYSCON->FMCCR &= ~SYSCON_FMCCR_PREFEN_MASK;
356
357 FLASH->INT_CLR_STATUS = 0x1F; /* Clear all status flags */
358
359 FLASH->DATAW[0] = (FLASH->DATAW[0] & 0xFFFFFFF0UL) |
360 (num_wait_states & (SYSCON_FMCCR_FLASHTIM_MASK >> SYSCON_FMCCR_FLASHTIM_SHIFT));
361
362 FLASH->CMD = 0x2; /* CMD_SET_READ_MODE */
363
364 /* Wait until the cmd is completed (without error) */
365 while ((FLASH->INT_STATUS & FLASH_INT_STATUS_DONE_MASK) == 0UL)
366 {
367 }
368
369 /* Adjust FMC waiting time cycles (num_wait_states) */
370 SYSCON->FMCCR = (SYSCON->FMCCR & ~SYSCON_FMCCR_FLASHTIM_MASK) |
371 ((num_wait_states << SYSCON_FMCCR_FLASHTIM_SHIFT) & SYSCON_FMCCR_FLASHTIM_MASK);
372
373 /* restore prefetch enable */
374 SYSCON->FMCCR |= prefetch_enable_mask;
375 }
376
377 /* Set EXT OSC Clk */
378 /**
379 * brief Initialize the external osc clock to given frequency.
380 * Crystal oscillator with an operating frequency of 12 MHz to 32 MHz.
381 * Option for external clock input (bypass mode) for clock frequencies of up to 25 MHz.
382 * param iFreq : Desired frequency (must be equal to exact rate in Hz)
383 * return returns success or fail status.
384 */
CLOCK_SetupExtClocking(uint32_t iFreq)385 status_t CLOCK_SetupExtClocking(uint32_t iFreq)
386 {
387 if (iFreq > 32000000U)
388 {
389 return kStatus_Fail;
390 }
391 /* Turn on power for crystal 32 MHz */
392 POWER_DisablePD(kPDRUNCFG_PD_XTAL32M);
393 POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M);
394 /* Enable clock_in clock for clock module. */
395 SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK;
396
397 /* Wait for external osc clock to be valid. */
398 while((ANACTRL->XO32M_STATUS & ANACTRL_XO32M_STATUS_XO_READY_MASK) == 0U)
399 {
400 }
401
402 s_Ext_Clk_Freq = iFreq;
403 return kStatus_Success;
404 }
405
406 /* Set I2S MCLK Clk */
407 /**
408 * brief Initialize the I2S MCLK clock to given frequency.
409 * param iFreq : Desired frequency (must be equal to exact rate in Hz)
410 * return returns success or fail status.
411 */
CLOCK_SetupI2SMClkClocking(uint32_t iFreq)412 status_t CLOCK_SetupI2SMClkClocking(uint32_t iFreq)
413 {
414 s_I2S_Mclk_Freq = iFreq;
415 return kStatus_Success;
416 }
417
418 /* Set PLU CLKIN Clk */
419 /**
420 * brief Initialize the PLU CLKIN clock to given frequency.
421 * param iFreq : Desired frequency (must be equal to exact rate in Hz)
422 * return returns success or fail status.
423 */
CLOCK_SetupPLUClkInClocking(uint32_t iFreq)424 status_t CLOCK_SetupPLUClkInClocking(uint32_t iFreq)
425 {
426 s_PLU_ClkIn_Freq = iFreq;
427 return kStatus_Success;
428 }
429
430 /* Get CLOCK OUT Clk */
431 /*! brief Return Frequency of ClockOut
432 * return Frequency of ClockOut
433 */
CLOCK_GetClockOutClkFreq(void)434 uint32_t CLOCK_GetClockOutClkFreq(void)
435 {
436 uint32_t freq = 0U;
437
438 switch (SYSCON->CLKOUTSEL)
439 {
440 case 0U:
441 freq = CLOCK_GetCoreSysClkFreq();
442 break;
443
444 case 1U:
445 freq = CLOCK_GetPll0OutFreq();
446 break;
447
448 case 2U:
449 freq = CLOCK_GetExtClkFreq();
450 break;
451
452 case 3U:
453 freq = CLOCK_GetFroHfFreq();
454 break;
455
456 case 4U:
457 freq = CLOCK_GetFro1MFreq();
458 break;
459
460 case 5U:
461 freq = CLOCK_GetPll1OutFreq();
462 break;
463
464 case 6U:
465 freq = CLOCK_GetOsc32KFreq();
466 break;
467
468 case 7U:
469 freq = 0U;
470 break;
471
472 default:
473 freq = 0U;
474 break;
475 }
476 return freq / ((SYSCON->CLKOUTDIV & 0xffU) + 1U);
477 }
478
479 /* Get CAN Clk */
480 /*! brief Return Frequency of Can Clock
481 * return Frequency of Can.
482 */
CLOCK_GetMCanClkFreq(void)483 uint32_t CLOCK_GetMCanClkFreq(void)
484 {
485 uint32_t freq = 0U;
486
487 switch (SYSCON->CANCLKSEL)
488 {
489 case 0U:
490 freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->CANCLKDIV & SYSCON_CANCLKDIV_DIV_MASK) + 1U);
491 break;
492 case 1U:
493 freq = CLOCK_GetFro1MFreq();
494 break;
495 case 2U:
496 freq = CLOCK_GetOsc32KFreq();
497 break;
498 case 7U:
499 freq = 0U;
500 break;
501
502 default:
503 freq = 0U;
504 break;
505 }
506
507 return freq;
508 }
509
510 /* Get ADC Clk */
511 /*! brief Return Frequency of Adc Clock
512 * return Frequency of Adc.
513 */
CLOCK_GetAdcClkFreq(void)514 uint32_t CLOCK_GetAdcClkFreq(void)
515 {
516 uint32_t freq = 0U;
517
518 switch (SYSCON->ADCCLKSEL)
519 {
520 case 0U:
521 freq = CLOCK_GetCoreSysClkFreq();
522 break;
523 case 1U:
524 freq = CLOCK_GetPll0OutFreq();
525 break;
526 case 2U:
527 freq = CLOCK_GetFroHfFreq();
528 break;
529 case 7U:
530 freq = 0U;
531 break;
532
533 default:
534 freq = 0U;
535 break;
536 }
537
538 return freq / ((SYSCON->ADCCLKDIV & SYSCON_ADCCLKDIV_DIV_MASK) + 1U);
539 }
540
541 /* Get USB0 Clk */
542 /*! brief Return Frequency of Usb0 Clock
543 * return Frequency of Usb0 Clock.
544 */
CLOCK_GetUsb0ClkFreq(void)545 uint32_t CLOCK_GetUsb0ClkFreq(void)
546 {
547 uint32_t freq = 0U;
548
549 switch (SYSCON->USB0CLKSEL)
550 {
551 case 0U:
552 freq = CLOCK_GetCoreSysClkFreq();
553 break;
554 case 1U:
555 freq = CLOCK_GetPll0OutFreq();
556 break;
557 case 3U:
558 freq = CLOCK_GetFroHfFreq();
559 break;
560 case 5U:
561 freq = CLOCK_GetPll1OutFreq();
562 break;
563 case 7U:
564 freq = 0U;
565 break;
566
567 default:
568 freq = 0U;
569 break;
570 }
571
572 return freq / ((SYSCON->USB0CLKDIV & 0xffU) + 1U);
573 }
574
575 /* Get USB1 Clk */
576 /*! brief Return Frequency of Usb1 Clock
577 * return Frequency of Usb1 Clock.
578 */
CLOCK_GetUsb1ClkFreq(void)579 uint32_t CLOCK_GetUsb1ClkFreq(void)
580 {
581 return ((ANACTRL->XO32M_CTRL & ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT_MASK) != 0UL) ? s_Ext_Clk_Freq : 0U;
582 }
583
584 /* Get MCLK Clk */
585 /*! brief Return Frequency of MClk Clock
586 * return Frequency of MClk Clock.
587 */
CLOCK_GetMclkClkFreq(void)588 uint32_t CLOCK_GetMclkClkFreq(void)
589 {
590 uint32_t freq = 0U;
591
592 switch (SYSCON->MCLKCLKSEL)
593 {
594 case 0U:
595 freq = CLOCK_GetFroHfFreq();
596 break;
597 case 1U:
598 freq = CLOCK_GetPll0OutFreq();
599 break;
600 case 7U:
601 freq = 0U;
602 break;
603
604 default:
605 freq = 0U;
606 break;
607 }
608
609 return freq / ((SYSCON->MCLKDIV & 0xffU) + 1U);
610 }
611
612 /* Get SCTIMER Clk */
613 /*! brief Return Frequency of SCTimer Clock
614 * return Frequency of SCTimer Clock.
615 */
CLOCK_GetSctClkFreq(void)616 uint32_t CLOCK_GetSctClkFreq(void)
617 {
618 uint32_t freq = 0U;
619
620 switch (SYSCON->SCTCLKSEL)
621 {
622 case 0U:
623 freq = CLOCK_GetCoreSysClkFreq();
624 break;
625 case 1U:
626 freq = CLOCK_GetPll0OutFreq();
627 break;
628 case 2U:
629 freq = CLOCK_GetExtClkFreq();
630 break;
631 case 3U:
632 freq = CLOCK_GetFroHfFreq();
633 break;
634 case 5U:
635 freq = CLOCK_GetI2SMClkFreq();
636 break;
637 case 7U:
638 freq = 0U;
639 break;
640
641 default:
642 freq = 0U;
643 break;
644 }
645
646 return freq / ((SYSCON->SCTCLKDIV & 0xffU) + 1U);
647 }
648
649 /* Get FRO 12M Clk */
650 /*! brief Return Frequency of FRO 12MHz
651 * return Frequency of FRO 12MHz
652 */
CLOCK_GetFro12MFreq(void)653 uint32_t CLOCK_GetFro12MFreq(void)
654 {
655 return ((ANACTRL->FRO192M_CTRL & ANACTRL_FRO192M_CTRL_ENA_12MHZCLK_MASK) != 0UL) ? 12000000U : 0U;
656 }
657
658 /* Get FRO 1M Clk */
659 /*! brief Return Frequency of FRO 1MHz
660 * return Frequency of FRO 1MHz
661 */
CLOCK_GetFro1MFreq(void)662 uint32_t CLOCK_GetFro1MFreq(void)
663 {
664 return ((SYSCON->CLOCK_CTRL & SYSCON_CLOCK_CTRL_FRO1MHZ_CLK_ENA_MASK) != 0UL) ? 1000000U : 0U;
665 }
666
667 /* Get EXT OSC Clk */
668 /*! brief Return Frequency of External Clock
669 * return Frequency of External Clock. If no external clock is used returns 0.
670 */
CLOCK_GetExtClkFreq(void)671 uint32_t CLOCK_GetExtClkFreq(void)
672 {
673 return ((ANACTRL->XO32M_CTRL & ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK) != 0UL) ? s_Ext_Clk_Freq : 0U;
674 }
675
676 /* Get WATCH DOG Clk */
677 /*! brief Return Frequency of Watchdog
678 * return Frequency of Watchdog
679 */
CLOCK_GetWdtClkFreq(void)680 uint32_t CLOCK_GetWdtClkFreq(void)
681 {
682 return CLOCK_GetFro1MFreq() / ((SYSCON->WDTCLKDIV & SYSCON_WDTCLKDIV_DIV_MASK) + 1U);
683 }
684
685 /* Get HF FRO Clk */
686 /*! brief Return Frequency of High-Freq output of FRO
687 * return Frequency of High-Freq output of FRO
688 */
CLOCK_GetFroHfFreq(void)689 uint32_t CLOCK_GetFroHfFreq(void)
690 {
691 return ((ANACTRL->FRO192M_CTRL & ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK) != 0UL) ? 96000000U : 0U;
692 }
693
694 /* Get SYSTEM PLL Clk */
695 /*! brief Return Frequency of PLL
696 * return Frequency of PLL
697 */
CLOCK_GetPll0OutFreq(void)698 uint32_t CLOCK_GetPll0OutFreq(void)
699 {
700 return s_Pll0_Freq;
701 }
702
703 /* Get USB PLL Clk */
704 /*! brief Return Frequency of USB PLL
705 * return Frequency of PLL
706 */
CLOCK_GetPll1OutFreq(void)707 uint32_t CLOCK_GetPll1OutFreq(void)
708 {
709 return s_Pll1_Freq;
710 }
711
712 /* Get RTC OSC Clk */
713 /*! brief Return Frequency of 32kHz osc
714 * return Frequency of 32kHz osc
715 */
CLOCK_GetOsc32KFreq(void)716 uint32_t CLOCK_GetOsc32KFreq(void)
717 {
718 return ((0UL == (PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_FRO32K_MASK)) &&
719 (0UL == (PMC->RTCOSC32K & PMC_RTCOSC32K_SEL_MASK))) ?
720 CLK_RTC_32K_CLK :
721 ((0UL == (PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_XTAL32K_MASK)) &&
722 ((PMC->RTCOSC32K & PMC_RTCOSC32K_SEL_MASK) != 0UL)) ?
723 CLK_RTC_32K_CLK :
724 0UL;
725 }
726
727 /* Get MAIN Clk */
728 /*! brief Return Frequency of Core System
729 * return Frequency of Core System
730 */
CLOCK_GetCoreSysClkFreq(void)731 uint32_t CLOCK_GetCoreSysClkFreq(void)
732 {
733 uint32_t freq = 0U;
734
735 switch (SYSCON->MAINCLKSELB)
736 {
737 case 0U:
738 if (SYSCON->MAINCLKSELA == 0U)
739 {
740 freq = CLOCK_GetFro12MFreq();
741 }
742 else if (SYSCON->MAINCLKSELA == 1U)
743 {
744 freq = CLOCK_GetExtClkFreq();
745 }
746 else if (SYSCON->MAINCLKSELA == 2U)
747 {
748 freq = CLOCK_GetFro1MFreq();
749 }
750 else if (SYSCON->MAINCLKSELA == 3U)
751 {
752 freq = CLOCK_GetFroHfFreq();
753 }
754 else
755 {
756 /* Added comments to avoid the violation of MISRA C-2012 rule 15.7 */
757 }
758 break;
759 case 1U:
760 freq = CLOCK_GetPll0OutFreq();
761 break;
762 case 2U:
763 freq = CLOCK_GetPll1OutFreq();
764 break;
765
766 case 3U:
767 freq = CLOCK_GetOsc32KFreq();
768 break;
769
770 default:
771 freq = 0U;
772 break;
773 }
774
775 return freq;
776 }
777
778 /* Get I2S MCLK Clk */
779 /*! brief Return Frequency of I2S MCLK Clock
780 * return Frequency of I2S MCLK Clock
781 */
CLOCK_GetI2SMClkFreq(void)782 uint32_t CLOCK_GetI2SMClkFreq(void)
783 {
784 return s_I2S_Mclk_Freq;
785 }
786
787 /* Get PLU CLKIN Clk */
788 /*! brief Return Frequency of PLU CLKIN Clock
789 * return Frequency of PLU CLKIN Clock
790 */
CLOCK_GetPLUClkInFreq(void)791 uint32_t CLOCK_GetPLUClkInFreq(void)
792 {
793 return s_PLU_ClkIn_Freq;
794 }
795
796 /* Get FLEXCOMM input clock */
797 /*! brief Return Frequency of flexcomm input clock
798 * param id : flexcomm instance id
799 * return Frequency value
800 */
CLOCK_GetFlexCommInputClock(uint32_t id)801 uint32_t CLOCK_GetFlexCommInputClock(uint32_t id)
802 {
803 uint32_t freq = 0U;
804
805 switch (SYSCON->FCCLKSELX[id])
806 {
807 case 0U:
808 freq = CLOCK_GetCoreSysClkFreq();
809 break;
810 case 1U:
811 freq = CLOCK_GetPll0OutFreq() / ((SYSCON->PLL0CLKDIV & 0xffU) + 1U);
812 break;
813 case 2U:
814 freq = CLOCK_GetFro12MFreq();
815 break;
816 case 3U:
817 freq = CLOCK_GetFroHfFreq() / ((SYSCON->FROHFDIV & 0xffU) + 1U);
818 break;
819 case 4U:
820 freq = CLOCK_GetFro1MFreq();
821 break;
822 case 5U:
823 freq = CLOCK_GetI2SMClkFreq();
824 break;
825 case 6U:
826 freq = CLOCK_GetOsc32KFreq();
827 break;
828 case 7U:
829 freq = 0U;
830 break;
831
832 default:
833 freq = 0U;
834 break;
835 }
836
837 return freq;
838 }
839
840 /* Get FLEXCOMM Clk */
CLOCK_GetFlexCommClkFreq(uint32_t id)841 uint32_t CLOCK_GetFlexCommClkFreq(uint32_t id)
842 {
843 uint32_t freq = 0U;
844 uint32_t frgMul = 0U;
845 uint32_t frgDiv = 0U;
846
847 freq = CLOCK_GetFlexCommInputClock(id);
848 frgMul = (SYSCON->FLEXFRGXCTRL[id] & SYSCON_FLEXFRG0CTRL_MULT_MASK) >> 8U;
849 frgDiv = SYSCON->FLEXFRGXCTRL[id] & SYSCON_FLEXFRG0CTRL_DIV_MASK;
850 return (uint32_t)(((uint64_t)freq * ((uint64_t)frgDiv + 1ULL)) / (frgMul + frgDiv + 1UL));
851 }
852
853 /* Get HS_LPSI Clk */
CLOCK_GetHsLspiClkFreq(void)854 uint32_t CLOCK_GetHsLspiClkFreq(void)
855 {
856 uint32_t freq = 0U;
857
858 switch (SYSCON->HSLSPICLKSEL)
859 {
860 case 0U:
861 freq = CLOCK_GetCoreSysClkFreq();
862 break;
863 case 1U:
864 freq = CLOCK_GetPll0OutFreq() / ((SYSCON->PLL0CLKDIV & 0xffU) + 1U);
865 break;
866 case 2U:
867 freq = CLOCK_GetFro12MFreq();
868 break;
869 case 3U:
870 freq = CLOCK_GetFroHfFreq() / ((SYSCON->FROHFDIV & 0xffU) + 1U);
871 break;
872 case 4U:
873 freq = CLOCK_GetFro1MFreq();
874 break;
875 case 6U:
876 freq = CLOCK_GetOsc32KFreq();
877 break;
878 case 7U:
879 freq = 0U;
880 break;
881
882 default:
883 freq = 0U;
884 break;
885 }
886
887 return freq;
888 }
889
890 /* Get CTimer Clk */
891 /*! brief Return Frequency of CTimer functional Clock
892 * return Frequency of CTimer functional Clock
893 */
CLOCK_GetCTimerClkFreq(uint32_t id)894 uint32_t CLOCK_GetCTimerClkFreq(uint32_t id)
895 {
896 uint32_t freq = 0U;
897
898 switch (SYSCON->CTIMERCLKSELX[id])
899 {
900 case 0U:
901 freq = CLOCK_GetCoreSysClkFreq();
902 break;
903 case 1U:
904 freq = CLOCK_GetPll0OutFreq();
905 break;
906 case 3U:
907 freq = CLOCK_GetFroHfFreq();
908 break;
909 case 4U:
910 freq = CLOCK_GetFro1MFreq();
911 break;
912 case 5U:
913 freq = CLOCK_GetI2SMClkFreq();
914 break;
915 case 6U:
916 freq = CLOCK_GetOsc32KFreq();
917 break;
918 case 7U:
919 freq = 0U;
920 break;
921
922 default:
923 freq = 0U;
924 break;
925 }
926
927 return freq;
928 }
929
930 /* Get Systick Clk */
931 /*! brief Return Frequency of SystickClock
932 * return Frequency of Systick Clock
933 */
CLOCK_GetSystickClkFreq(uint32_t id)934 uint32_t CLOCK_GetSystickClkFreq(uint32_t id)
935 {
936 uint32_t freq = 0U;
937
938 switch (SYSCON->SYSTICKCLKSELX[id])
939 {
940 case 0U:
941 /*Niobe4mini just has one SYSTICKSEL and SYSTICKDIV register, Fix coverity problem in this way temporarily
942 */
943 freq = CLOCK_GetCoreSysClkFreq() / (((SYSCON->SYSTICKCLKDIV0) & 0xffU) + 1U);
944 break;
945 case 1U:
946 freq = CLOCK_GetFro1MFreq();
947 break;
948 case 2U:
949 freq = CLOCK_GetOsc32KFreq();
950 break;
951 case 7U:
952 freq = 0U;
953 break;
954
955 default:
956 freq = 0U;
957 break;
958 }
959
960 return freq;
961 }
962
963 /* Set FlexComm Clock */
964 /**
965 * brief Set the flexcomm output frequency.
966 * param id : flexcomm instance id
967 * freq : output frequency
968 * return 0 : the frequency range is out of range.
969 * 1 : switch successfully.
970 */
CLOCK_SetFlexCommClock(uint32_t id,uint32_t freq)971 uint32_t CLOCK_SetFlexCommClock(uint32_t id, uint32_t freq)
972 {
973 uint32_t input = CLOCK_GetFlexCommClkFreq(id);
974 uint32_t mul;
975
976 if ((freq > 48000000UL) || (freq > input) || (input / freq >= 2UL))
977 {
978 /* FRG output frequency should be less than equal to 48MHz */
979 return 0UL;
980 }
981 else
982 {
983 mul = (uint32_t)((((uint64_t)input - freq) * 256ULL) / ((uint64_t)freq));
984 SYSCON->FLEXFRGXCTRL[id] = (mul << 8U) | 0xFFU;
985 return 1UL;
986 }
987 }
988
989 /* Get IP Clk */
990 /*! brief Return Frequency of selected clock
991 * return Frequency of selected clock
992 */
CLOCK_GetFreq(clock_name_t clockName)993 uint32_t CLOCK_GetFreq(clock_name_t clockName)
994 {
995 uint32_t freq;
996 switch (clockName)
997 {
998 case kCLOCK_CoreSysClk:
999 freq = CLOCK_GetCoreSysClkFreq();
1000 break;
1001 case kCLOCK_BusClk:
1002 freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->AHBCLKDIV & 0xffU) + 1U);
1003 break;
1004 case kCLOCK_ClockOut:
1005 freq = CLOCK_GetClockOutClkFreq();
1006 break;
1007 case kCLOCK_Pll1Out:
1008 freq = CLOCK_GetPll1OutFreq();
1009 break;
1010 case kCLOCK_Mclk:
1011 freq = CLOCK_GetMclkClkFreq();
1012 break;
1013 case kCLOCK_FroHf:
1014 freq = CLOCK_GetFroHfFreq();
1015 break;
1016 case kCLOCK_Fro12M:
1017 freq = CLOCK_GetFro12MFreq();
1018 break;
1019 case kCLOCK_Fro1M:
1020 freq = CLOCK_GetFro1MFreq();
1021 break;
1022 case kCLOCK_ExtClk:
1023 freq = CLOCK_GetExtClkFreq();
1024 break;
1025 case kCLOCK_Pll0Out:
1026 freq = CLOCK_GetPll0OutFreq();
1027 break;
1028 case kCLOCK_FlexI2S:
1029 freq = CLOCK_GetI2SMClkFreq();
1030 break;
1031 default:
1032 freq = 0U;
1033 break;
1034 }
1035 return freq;
1036 }
1037
1038 /* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */
pllFindSel(uint32_t M,uint32_t * pSelP,uint32_t * pSelI,uint32_t * pSelR)1039 static void pllFindSel(uint32_t M, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR)
1040 {
1041 uint32_t seli, selp;
1042 /* bandwidth: compute selP from Multiplier */
1043 if ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_SEL_EXT_MASK) != 0UL) /* normal mode */
1044 {
1045 selp = (M >> 2U) + 1U;
1046 if (selp >= 31U)
1047 {
1048 selp = 31U;
1049 }
1050 *pSelP = selp;
1051
1052 if (M >= 8000UL)
1053 {
1054 seli = 1UL;
1055 }
1056 else if (M >= 122UL)
1057 {
1058 seli = (uint32_t)(8000UL / M); /*floor(8000/M) */
1059 }
1060 else
1061 {
1062 seli = 2UL * ((uint32_t)(M / 4UL)) + 3UL; /* 2*floor(M/4) + 3 */
1063 }
1064
1065 if (seli >= 63UL)
1066 {
1067 seli = 63UL;
1068 }
1069 *pSelI = seli;
1070
1071 *pSelR = 0UL;
1072 }
1073 else
1074 {
1075 /* Note: If the spread spectrum mode, choose N to ensure 3 MHz < Fin/N < 5 MHz */
1076 *pSelP = 3U;
1077 *pSelI = 4U;
1078 *pSelR = 4U;
1079 }
1080 }
1081
1082 /* Get predivider (N) from PLL0 NDEC setting */
findPll0PreDiv(void)1083 static uint32_t findPll0PreDiv(void)
1084 {
1085 uint32_t preDiv = 1UL;
1086
1087 /* Direct input is not used? */
1088 if ((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_BYPASSPREDIV_MASK) == 0UL)
1089 {
1090 preDiv = SYSCON->PLL0NDEC & SYSCON_PLL0NDEC_NDIV_MASK;
1091 if (preDiv == 0UL)
1092 {
1093 preDiv = 1UL;
1094 }
1095 }
1096 return preDiv;
1097 }
1098
1099 /* Get predivider (N) from PLL1 NDEC setting */
findPll1PreDiv(void)1100 static uint32_t findPll1PreDiv(void)
1101 {
1102 uint32_t preDiv = 1UL;
1103
1104 /* Direct input is not used? */
1105 if ((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_BYPASSPREDIV_MASK) == 0UL)
1106 {
1107 preDiv = SYSCON->PLL1NDEC & SYSCON_PLL1NDEC_NDIV_MASK;
1108 if (preDiv == 0UL)
1109 {
1110 preDiv = 1UL;
1111 }
1112 }
1113 return preDiv;
1114 }
1115
1116 /* Get postdivider (P) from PLL0 PDEC setting */
findPll0PostDiv(void)1117 static uint32_t findPll0PostDiv(void)
1118 {
1119 uint32_t postDiv = 1UL;
1120
1121 if ((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_BYPASSPOSTDIV_MASK) == 0UL)
1122 {
1123 if ((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_BYPASSPOSTDIV2_MASK) != 0UL)
1124 {
1125 postDiv = SYSCON->PLL0PDEC & SYSCON_PLL0PDEC_PDIV_MASK;
1126 }
1127 else
1128 {
1129 postDiv = 2UL * (SYSCON->PLL0PDEC & SYSCON_PLL0PDEC_PDIV_MASK);
1130 }
1131 if (postDiv == 0UL)
1132 {
1133 postDiv = 2UL;
1134 }
1135 }
1136 return postDiv;
1137 }
1138
1139 /* Get postdivider (P) from PLL1 PDEC setting. */
findPll1PostDiv(void)1140 static uint32_t findPll1PostDiv(void)
1141 {
1142 uint32_t postDiv = 1UL;
1143
1144 if ((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_BYPASSPOSTDIV_MASK) == 0UL)
1145 {
1146 if ((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_BYPASSPOSTDIV2_MASK) != 0UL)
1147 {
1148 postDiv = SYSCON->PLL1PDEC & SYSCON_PLL1PDEC_PDIV_MASK;
1149 }
1150 else
1151 {
1152 postDiv = 2UL * (SYSCON->PLL1PDEC & SYSCON_PLL1PDEC_PDIV_MASK);
1153 }
1154 if (postDiv == 0UL)
1155 {
1156 postDiv = 2UL;
1157 }
1158 }
1159
1160 return postDiv;
1161 }
1162
1163 /* Get multiplier (M) from PLL0 SSCG and SEL_EXT settings */
findPll0MMult(void)1164 static float findPll0MMult(void)
1165 {
1166 float mMult = 1.0F;
1167 float mMult_fract;
1168 uint32_t mMult_int;
1169
1170 if ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_SEL_EXT_MASK) != 0UL)
1171 {
1172 mMult =
1173 (float)(uint32_t)((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_MDIV_EXT_MASK) >> SYSCON_PLL0SSCG1_MDIV_EXT_SHIFT);
1174 }
1175 else
1176 {
1177 mMult_int = ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_MD_MBS_MASK) << 7U);
1178 mMult_int = mMult_int | ((SYSCON->PLL0SSCG0) >> PLL0_SSCG_MD_INT_P);
1179 mMult_fract = ((float)(uint32_t)((SYSCON->PLL0SSCG0) & PLL0_SSCG_MD_FRACT_M) /
1180 (float)(uint32_t)(1UL << PLL0_SSCG_MD_INT_P));
1181 mMult = (float)mMult_int + mMult_fract;
1182 }
1183 if (0ULL == ((uint64_t)mMult))
1184 {
1185 mMult = 1.0F;
1186 }
1187 return mMult;
1188 }
1189
1190 /* Get multiplier (M) from PLL1 MDEC. */
findPll1MMult(void)1191 static uint32_t findPll1MMult(void)
1192 {
1193 uint32_t mMult = 1UL;
1194
1195 mMult = SYSCON->PLL1MDEC & SYSCON_PLL1MDEC_MDIV_MASK;
1196
1197 if (mMult == 0UL)
1198 {
1199 mMult = 1UL;
1200 }
1201
1202 return mMult;
1203 }
1204
1205 /* Find greatest common divisor between m and n */
FindGreatestCommonDivisor(uint32_t m,uint32_t n)1206 static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n)
1207 {
1208 uint32_t tmp;
1209
1210 while (n != 0U)
1211 {
1212 tmp = n;
1213 n = m % n;
1214 m = tmp;
1215 }
1216
1217 return m;
1218 }
1219
1220 /*
1221 * Set PLL0 output based on desired output rate.
1222 * In this function, the it calculates the PLL0 setting for output frequency from input clock
1223 * frequency. The calculation would cost a few time. So it is not recommaned to use it frequently.
1224 * the "pllctrl", "pllndec", "pllpdec", "pllmdec" would updated in this function.
1225 */
CLOCK_GetPll0ConfigInternal(uint32_t finHz,uint32_t foutHz,pll_setup_t * pSetup,bool useSS)1226 static pll_error_t CLOCK_GetPll0ConfigInternal(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useSS)
1227 {
1228 uint32_t nDivOutHz, fccoHz;
1229 uint32_t pllPreDivider, pllMultiplier, pllPostDivider;
1230 uint32_t pllDirectInput, pllDirectOutput;
1231 uint32_t pllSelP, pllSelI, pllSelR, uplimoff;
1232
1233 /* Baseline parameters (no input or output dividers) */
1234 pllPreDivider = 1U; /* 1 implies pre-divider will be disabled */
1235 pllPostDivider = 1U; /* 1 implies post-divider will be disabled */
1236 pllDirectOutput = 1U;
1237
1238 /* Verify output rate parameter */
1239 if (foutHz > PLL_MAX_CCO_FREQ_MHZ)
1240 {
1241 /* Maximum PLL output with post divider=1 cannot go above this frequency */
1242 return kStatus_PLL_OutputTooHigh;
1243 }
1244 if (foutHz < (PLL_MIN_CCO_FREQ_MHZ / (PVALMAX << 1U)))
1245 {
1246 /* Minmum PLL output with maximum post divider cannot go below this frequency */
1247 return kStatus_PLL_OutputTooLow;
1248 }
1249
1250 /* If using SS mode, input clock needs to be between 3MHz and 20MHz */
1251 if (useSS)
1252 {
1253 /* Verify input rate parameter */
1254 if (finHz < PLL_MIN_IN_SSMODE)
1255 {
1256 /* Input clock into the PLL cannot be lower than this */
1257 return kStatus_PLL_InputTooLow;
1258 }
1259 /* PLL input in SS mode must be under 20MHz */
1260 if (finHz > (PLL_MAX_IN_SSMODE * NVALMAX))
1261 {
1262 return kStatus_PLL_InputTooHigh;
1263 }
1264 }
1265 else
1266 {
1267 /* Verify input rate parameter */
1268 if (finHz < PLL_LOWER_IN_LIMIT)
1269 {
1270 /* Input clock into the PLL cannot be lower than this */
1271 return kStatus_PLL_InputTooLow;
1272 }
1273 if (finHz > PLL_HIGHER_IN_LIMIT)
1274 {
1275 /* Input clock into the PLL cannot be higher than this */
1276 return kStatus_PLL_InputTooHigh;
1277 }
1278 }
1279
1280 /* Find the optimal CCO frequency for the output and input that
1281 will keep it inside the PLL CCO range. This may require
1282 tweaking the post-divider for the PLL. */
1283 fccoHz = foutHz;
1284 while (fccoHz < PLL_MIN_CCO_FREQ_MHZ)
1285 {
1286 /* CCO output is less than minimum CCO range, so the CCO output
1287 needs to be bumped up and the post-divider is used to bring
1288 the PLL output back down. */
1289 pllPostDivider++;
1290 if (pllPostDivider > PVALMAX)
1291 {
1292 return kStatus_PLL_OutsideIntLimit;
1293 }
1294
1295 /* Target CCO goes up, PLL output goes down */
1296 /* divide-by-2 divider in the post-divider is always work*/
1297 fccoHz = foutHz * (pllPostDivider * 2U);
1298 pllDirectOutput = 0U;
1299 }
1300
1301 /* Determine if a pre-divider is needed to get the best frequency */
1302 if ((finHz > PLL_LOWER_IN_LIMIT) && (fccoHz >= finHz) && (useSS == false))
1303 {
1304 uint32_t a = FindGreatestCommonDivisor(fccoHz, finHz);
1305
1306 if (a > PLL_LOWER_IN_LIMIT)
1307 {
1308 a = finHz / a;
1309 if ((a != 0U) && (a < PLL_MAX_N_DIV))
1310 {
1311 pllPreDivider = a;
1312 }
1313 }
1314 }
1315
1316 /* Bypass pre-divider hardware if pre-divider is 1 */
1317 if (pllPreDivider > 1U)
1318 {
1319 pllDirectInput = 0U;
1320 }
1321 else
1322 {
1323 pllDirectInput = 1U;
1324 }
1325
1326 /* Determine PLL multipler */
1327 nDivOutHz = (finHz / pllPreDivider);
1328 pllMultiplier = (fccoHz / nDivOutHz);
1329
1330 /* Find optimal values for filter */
1331 if (useSS == false)
1332 {
1333 /* Will bumping up M by 1 get us closer to the desired CCO frequency? */
1334 if ((nDivOutHz * ((pllMultiplier * 2U) + 1U)) < (fccoHz * 2U))
1335 {
1336 pllMultiplier++;
1337 }
1338
1339 /* Setup filtering */
1340 pllFindSel(pllMultiplier, &pllSelP, &pllSelI, &pllSelR);
1341 uplimoff = 0U;
1342
1343 /* Get encoded value for M (mult) and use manual filter, disable SS mode */
1344 pSetup->pllsscg[1] =
1345 (uint32_t)((PLL_SSCG1_MDEC_VAL_SET(pllMultiplier)) | (1UL << SYSCON_PLL0SSCG1_SEL_EXT_SHIFT));
1346 }
1347 else
1348 {
1349 uint64_t fc;
1350
1351 /* Filtering will be handled by SSC */
1352 pllSelR = 0UL;
1353 pllSelI = 0UL;
1354 pllSelP = 0UL;
1355 uplimoff = 1U;
1356
1357 /* The PLL multiplier will get very close and slightly under the
1358 desired target frequency. A small fractional component can be
1359 added to fine tune the frequency upwards to the target. */
1360 fc = ((uint64_t)(uint32_t)(fccoHz % nDivOutHz) << 25UL) / nDivOutHz;
1361
1362 /* Set multiplier */
1363 pSetup->pllsscg[0] = (uint32_t)(PLL0_SSCG_MD_INT_SET(pllMultiplier) | PLL0_SSCG_MD_FRACT_SET((uint32_t)fc));
1364 pSetup->pllsscg[1] = (uint32_t)(PLL0_SSCG_MD_INT_SET(pllMultiplier) >> 32U);
1365 }
1366
1367 /* Get encoded values for N (prediv) and P (postdiv) */
1368 pSetup->pllndec = PLL_NDEC_VAL_SET(pllPreDivider);
1369 pSetup->pllpdec = PLL_PDEC_VAL_SET(pllPostDivider);
1370
1371 /* PLL control */
1372 pSetup->pllctrl = (pllSelR << SYSCON_PLL0CTRL_SELR_SHIFT) | /* Filter coefficient */
1373 (pllSelI << SYSCON_PLL0CTRL_SELI_SHIFT) | /* Filter coefficient */
1374 (pllSelP << SYSCON_PLL0CTRL_SELP_SHIFT) | /* Filter coefficient */
1375 (0UL << SYSCON_PLL0CTRL_BYPASSPLL_SHIFT) | /* PLL bypass mode disabled */
1376 (uplimoff << SYSCON_PLL0CTRL_LIMUPOFF_SHIFT) | /* SS/fractional mode disabled */
1377 (pllDirectInput << SYSCON_PLL0CTRL_BYPASSPREDIV_SHIFT) | /* Bypass pre-divider? */
1378 (pllDirectOutput << SYSCON_PLL0CTRL_BYPASSPOSTDIV_SHIFT) | /* Bypass post-divider? */
1379 (1UL << SYSCON_PLL0CTRL_CLKEN_SHIFT); /* Ensure the PLL clock output */
1380
1381 return kStatus_PLL_Success;
1382 }
1383
1384 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1385 /* Alloct the static buffer for cache. */
1386 static pll_setup_t s_PllSetupCacheStruct[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT];
1387 static uint32_t s_FinHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0};
1388 static uint32_t s_FoutHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0};
1389 static bool s_UseSSCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {false};
1390 static uint32_t s_PllSetupCacheIdx = 0U;
1391 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
1392
1393 /*
1394 * Calculate the PLL setting values from input clock freq to output freq.
1395 */
CLOCK_GetPll0Config(uint32_t finHz,uint32_t foutHz,pll_setup_t * pSetup,bool useSS)1396 static pll_error_t CLOCK_GetPll0Config(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useSS)
1397 {
1398 pll_error_t retErr;
1399 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1400 uint32_t i;
1401
1402 for (i = 0U; i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT; i++)
1403 {
1404 if ((finHz == s_FinHzCache[i]) && (foutHz == s_FoutHzCache[i]) && (useSS == s_UseSSCache[i]))
1405 {
1406 /* Hit the target in cache buffer. */
1407 pSetup->pllctrl = s_PllSetupCacheStruct[i].pllctrl;
1408 pSetup->pllndec = s_PllSetupCacheStruct[i].pllndec;
1409 pSetup->pllpdec = s_PllSetupCacheStruct[i].pllpdec;
1410 pSetup->pllsscg[0] = s_PllSetupCacheStruct[i].pllsscg[0];
1411 pSetup->pllsscg[1] = s_PllSetupCacheStruct[i].pllsscg[1];
1412 retErr = kStatus_PLL_Success;
1413 break;
1414 }
1415 }
1416
1417 if (i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1418 {
1419 return retErr;
1420 }
1421 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
1422
1423 retErr = CLOCK_GetPll0ConfigInternal(finHz, foutHz, pSetup, useSS);
1424
1425 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1426 /* Cache the most recent calulation result into buffer. */
1427 s_FinHzCache[s_PllSetupCacheIdx] = finHz;
1428 s_FoutHzCache[s_PllSetupCacheIdx] = foutHz;
1429 s_UseSSCache[s_PllSetupCacheIdx] = useSS;
1430
1431 s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllctrl = pSetup->pllctrl;
1432 s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllndec = pSetup->pllndec;
1433 s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllpdec = pSetup->pllpdec;
1434 s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllsscg[0] = pSetup->pllsscg[0];
1435 s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllsscg[1] = pSetup->pllsscg[1];
1436 /* Update the index for next available buffer. */
1437 s_PllSetupCacheIdx = (s_PllSetupCacheIdx + 1U) % CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT;
1438 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
1439
1440 return retErr;
1441 }
1442
1443 /* Update local PLL rate variable */
CLOCK_GetPLL0OutFromSetupUpdate(pll_setup_t * pSetup)1444 static void CLOCK_GetPLL0OutFromSetupUpdate(pll_setup_t *pSetup)
1445 {
1446 s_Pll0_Freq = CLOCK_GetPLL0OutFromSetup(pSetup);
1447 }
1448
1449 /* Update local PLL1 rate variable */
CLOCK_GetPLL1OutFromSetupUpdate(pll_setup_t * pSetup)1450 static void CLOCK_GetPLL1OutFromSetupUpdate(pll_setup_t *pSetup)
1451 {
1452 s_Pll1_Freq = CLOCK_GetPLL1OutFromSetup(pSetup);
1453 }
1454
1455 /* Return System PLL input clock rate */
1456 /*! brief Return PLL0 input clock rate
1457 * return PLL0 input clock rate
1458 */
CLOCK_GetPLL0InClockRate(void)1459 uint32_t CLOCK_GetPLL0InClockRate(void)
1460 {
1461 uint32_t clkRate = 0U;
1462
1463 switch ((SYSCON->PLL0CLKSEL & SYSCON_PLL0CLKSEL_SEL_MASK))
1464 {
1465 case 0x00U:
1466 clkRate = CLK_FRO_12MHZ;
1467 break;
1468
1469 case 0x01U:
1470 clkRate = CLOCK_GetExtClkFreq();
1471 break;
1472
1473 case 0x02U:
1474 clkRate = CLOCK_GetFro1MFreq();
1475 break;
1476
1477 case 0x03U:
1478 clkRate = CLOCK_GetOsc32KFreq();
1479 break;
1480
1481 default:
1482 clkRate = 0U;
1483 break;
1484 }
1485
1486 return clkRate;
1487 }
1488
1489 /* Return PLL1 input clock rate */
CLOCK_GetPLL1InClockRate(void)1490 uint32_t CLOCK_GetPLL1InClockRate(void)
1491 {
1492 uint32_t clkRate = 0U;
1493
1494 switch ((SYSCON->PLL1CLKSEL & SYSCON_PLL1CLKSEL_SEL_MASK))
1495 {
1496 case 0x00U:
1497 clkRate = CLK_FRO_12MHZ;
1498 break;
1499
1500 case 0x01U:
1501 clkRate = CLOCK_GetExtClkFreq();
1502 break;
1503
1504 case 0x02U:
1505 clkRate = CLOCK_GetFro1MFreq();
1506 break;
1507
1508 case 0x03U:
1509 clkRate = CLOCK_GetOsc32KFreq();
1510 break;
1511
1512 default:
1513 clkRate = 0U;
1514 break;
1515 }
1516
1517 return clkRate;
1518 }
1519
1520 /* Return PLL0 output clock rate from setup structure */
1521 /*! brief Return PLL0 output clock rate from setup structure
1522 * param pSetup : Pointer to a PLL setup structure
1523 * return PLL0 output clock rate the setup structure will generate
1524 */
CLOCK_GetPLL0OutFromSetup(pll_setup_t * pSetup)1525 uint32_t CLOCK_GetPLL0OutFromSetup(pll_setup_t *pSetup)
1526 {
1527 uint32_t clkRate = 0;
1528 uint32_t prediv, postdiv;
1529 float workRate = 0.0F;
1530
1531 /* Get the input clock frequency of PLL. */
1532 clkRate = CLOCK_GetPLL0InClockRate();
1533
1534 if (((pSetup->pllctrl & SYSCON_PLL0CTRL_BYPASSPLL_MASK) == 0UL) &&
1535 ((pSetup->pllctrl & SYSCON_PLL0CTRL_CLKEN_MASK) != 0UL) &&
1536 ((PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_PLL0_MASK) == 0UL) &&
1537 ((PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_PLL0_SSCG_MASK) == 0UL))
1538 {
1539 prediv = findPll0PreDiv();
1540 postdiv = findPll0PostDiv();
1541 /* Adjust input clock */
1542 clkRate = clkRate / prediv;
1543 /* MDEC used for rate */
1544 workRate = (float)clkRate * (float)findPll0MMult();
1545 workRate /= (float)postdiv;
1546 }
1547
1548 return (uint32_t)workRate;
1549 }
1550
1551 /* Return PLL1 output clock rate from setup structure */
1552 /*! brief Return PLL1 output clock rate from setup structure
1553 * param pSetup : Pointer to a PLL setup structure
1554 * return PLL0 output clock rate the setup structure will generate
1555 */
CLOCK_GetPLL1OutFromSetup(pll_setup_t * pSetup)1556 uint32_t CLOCK_GetPLL1OutFromSetup(pll_setup_t *pSetup)
1557 {
1558 uint32_t clkRate = 0;
1559 uint32_t prediv, postdiv;
1560 uint32_t workRate = 0UL;
1561
1562 /* Get the input clock frequency of PLL. */
1563 clkRate = CLOCK_GetPLL1InClockRate();
1564
1565 if (((pSetup->pllctrl & SYSCON_PLL1CTRL_BYPASSPLL_MASK) == 0UL) &&
1566 ((pSetup->pllctrl & SYSCON_PLL1CTRL_CLKEN_MASK) != 0UL) &&
1567 ((PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_PLL1_MASK) == 0UL))
1568 {
1569 prediv = findPll1PreDiv();
1570 postdiv = findPll1PostDiv();
1571 /* Adjust input clock */
1572 clkRate = clkRate / prediv;
1573 /* MDEC used for rate */
1574 workRate = clkRate * findPll1MMult();
1575 workRate /= postdiv;
1576 }
1577
1578 return workRate;
1579 }
1580
1581 /* Set the current PLL0 Rate */
1582 /*! brief Store the current PLL rate
1583 * param rate: Current rate of the PLL
1584 * return Nothing
1585 **/
CLOCK_SetStoredPLL0ClockRate(uint32_t rate)1586 void CLOCK_SetStoredPLL0ClockRate(uint32_t rate)
1587 {
1588 s_Pll0_Freq = rate;
1589 }
1590
1591 /* Return PLL0 output clock rate */
1592 /*! brief Return PLL0 output clock rate
1593 * param recompute : Forces a PLL rate recomputation if true
1594 * return PLL0 output clock rate
1595 * note The PLL rate is cached in the driver in a variable as
1596 * the rate computation function can take some time to perform. It
1597 * is recommended to use 'false' with the 'recompute' parameter.
1598 */
CLOCK_GetPLL0OutClockRate(bool recompute)1599 uint32_t CLOCK_GetPLL0OutClockRate(bool recompute)
1600 {
1601 pll_setup_t Setup;
1602 uint32_t rate;
1603
1604 if ((recompute) || (s_Pll0_Freq == 0U))
1605 {
1606 Setup.pllctrl = SYSCON->PLL0CTRL;
1607 Setup.pllndec = SYSCON->PLL0NDEC;
1608 Setup.pllpdec = SYSCON->PLL0PDEC;
1609 Setup.pllsscg[0] = SYSCON->PLL0SSCG0;
1610 Setup.pllsscg[1] = SYSCON->PLL0SSCG1;
1611
1612 CLOCK_GetPLL0OutFromSetupUpdate(&Setup);
1613 }
1614
1615 rate = s_Pll0_Freq;
1616
1617 return rate;
1618 }
1619
1620 /*! brief Return PLL1 output clock rate
1621 * param recompute : Forces a PLL rate recomputation if true
1622 * return PLL1 output clock rate
1623 * note The PLL rate is cached in the driver in a variable as
1624 * the rate computation function can take some time to perform. It
1625 * is recommended to use 'false' with the 'recompute' parameter.
1626 */
CLOCK_GetPLL1OutClockRate(bool recompute)1627 uint32_t CLOCK_GetPLL1OutClockRate(bool recompute)
1628 {
1629 pll_setup_t Setup;
1630 uint32_t rate;
1631
1632 if ((recompute) || (s_Pll1_Freq == 0U))
1633 {
1634 Setup.pllctrl = SYSCON->PLL1CTRL;
1635 Setup.pllndec = SYSCON->PLL1NDEC;
1636 Setup.pllpdec = SYSCON->PLL1PDEC;
1637 Setup.pllmdec = SYSCON->PLL1MDEC;
1638 CLOCK_GetPLL1OutFromSetupUpdate(&Setup);
1639 }
1640
1641 rate = s_Pll1_Freq;
1642
1643 return rate;
1644 }
1645
1646 /* Set PLL0 output based on the passed PLL setup data */
1647 /*! brief Set PLL output based on the passed PLL setup data
1648 * param pControl : Pointer to populated PLL control structure to generate setup with
1649 * param pSetup : Pointer to PLL setup structure to be filled
1650 * return PLL_ERROR_SUCCESS on success, or PLL setup error code
1651 * note Actual frequency for setup may vary from the desired frequency based on the
1652 * accuracy of input clocks, rounding, non-fractional PLL mode, etc.
1653 */
CLOCK_SetupPLL0Data(pll_config_t * pControl,pll_setup_t * pSetup)1654 pll_error_t CLOCK_SetupPLL0Data(pll_config_t *pControl, pll_setup_t *pSetup)
1655 {
1656 uint32_t inRate;
1657 bool useSS = (bool)((pControl->flags & PLL_CONFIGFLAG_FORCENOFRACT) == 0UL);
1658
1659 pll_error_t pllError;
1660
1661 /* Determine input rate for the PLL */
1662 if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0UL)
1663 {
1664 inRate = pControl->inputRate;
1665 }
1666 else
1667 {
1668 inRate = CLOCK_GetPLL0InClockRate();
1669 }
1670
1671 /* PLL flag options */
1672 pllError = CLOCK_GetPll0Config(inRate, pControl->desiredRate, pSetup, useSS);
1673 if ((useSS) && (pllError == kStatus_PLL_Success))
1674 {
1675 /* If using SS mode, then some tweaks are made to the generated setup */
1676 pSetup->pllsscg[1] |= (uint32_t)pControl->ss_mf | (uint32_t)pControl->ss_mr | (uint32_t)pControl->ss_mc;
1677 if (pControl->mfDither)
1678 {
1679 pSetup->pllsscg[1] |= (1UL << SYSCON_PLL0SSCG1_DITHER_SHIFT);
1680 }
1681 }
1682
1683 return pllError;
1684 }
1685
1686 /* Set PLL0 output from PLL setup structure */
1687 /*! brief Set PLL output from PLL setup structure (precise frequency)
1688 * param pSetup : Pointer to populated PLL setup structure
1689 * param flagcfg : Flag configuration for PLL config structure
1690 * return PLL_ERROR_SUCCESS on success, or PLL setup error code
1691 * note This function will power off the PLL, setup the PLL with the
1692 * new setup data, and then optionally powerup the PLL, wait for PLL lock,
1693 * and adjust system voltages to the new PLL rate. The function will not
1694 * alter any source clocks (ie, main systen clock) that may use the PLL,
1695 * so these should be setup prior to and after exiting the function.
1696 */
CLOCK_SetupPLL0Prec(pll_setup_t * pSetup,uint32_t flagcfg)1697 pll_error_t CLOCK_SetupPLL0Prec(pll_setup_t *pSetup, uint32_t flagcfg)
1698 {
1699 uint32_t inRate, clkRate, prediv;
1700 uint32_t pll_lock_wait_time = 0U;
1701 uint32_t max_pll_lock_wait_time = 0U;
1702 /* Power off PLL during setup changes */
1703 POWER_EnablePD(kPDRUNCFG_PD_PLL0);
1704 POWER_EnablePD(kPDRUNCFG_PD_PLL0_SSCG);
1705
1706 pSetup->flags = flagcfg;
1707
1708 /* Write PLL setup data */
1709 SYSCON->PLL0CTRL = pSetup->pllctrl;
1710 SYSCON->PLL0NDEC = pSetup->pllndec;
1711 SYSCON->PLL0NDEC = pSetup->pllndec | (1UL << SYSCON_PLL0NDEC_NREQ_SHIFT); /* latch */
1712 SYSCON->PLL0PDEC = pSetup->pllpdec;
1713 SYSCON->PLL0PDEC = pSetup->pllpdec | (1UL << SYSCON_PLL0PDEC_PREQ_SHIFT); /* latch */
1714 SYSCON->PLL0SSCG0 = pSetup->pllsscg[0];
1715 SYSCON->PLL0SSCG1 = pSetup->pllsscg[1];
1716 SYSCON->PLL0SSCG1 =
1717 pSetup->pllsscg[1] | (1UL << SYSCON_PLL0SSCG1_MREQ_SHIFT) | (1UL << SYSCON_PLL0SSCG1_MD_REQ_SHIFT); /* latch */
1718
1719 POWER_DisablePD(kPDRUNCFG_PD_PLL0);
1720 POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG);
1721
1722 if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0UL)
1723 {
1724 if ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_SEL_EXT_MASK) != 0UL) /* normal mode */
1725 {
1726 inRate = CLOCK_GetPLL0InClockRate();
1727 prediv = findPll0PreDiv();
1728 /* Adjust input clock */
1729 clkRate = inRate / prediv;
1730
1731 /* Need wait at least (500us + 400/Fref) (Fref in Hz result in s) to ensure the PLL is stable.
1732 The lock bit could be used to shorten the wait time when freq<20MHZ */
1733 max_pll_lock_wait_time = 500U + (400000000U / clkRate);
1734
1735 if (clkRate < 20000000UL)
1736 {
1737 pll_lock_wait_time = 0U;
1738 while ((CLOCK_IsPLL0Locked() == false) && (pll_lock_wait_time < max_pll_lock_wait_time))
1739 {
1740 pll_lock_wait_time += 100U;
1741 SDK_DelayAtLeastUs(100U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1742 }
1743 }
1744 else
1745 {
1746 SDK_DelayAtLeastUs(max_pll_lock_wait_time, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1747 }
1748 }
1749 else /* spread spectrum mode */
1750 {
1751 SDK_DelayAtLeastUs(6000U,
1752 SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); /* software should use a 6 ms time interval to
1753 insure the PLL will be stable */
1754 }
1755 }
1756
1757 /* Update current programmed PLL rate var */
1758 CLOCK_GetPLL0OutFromSetupUpdate(pSetup);
1759
1760 /* System voltage adjustment, occurs prior to setting main system clock */
1761 if ((pSetup->flags & PLL_SETUPFLAG_ADGVOLT) != 0UL)
1762 {
1763 POWER_SetVoltageForFreq(s_Pll0_Freq);
1764 }
1765
1766 return kStatus_PLL_Success;
1767 }
1768
1769 /* Setup PLL Frequency from pre-calculated value */
1770 /**
1771 * brief Set PLL0 output from PLL setup structure (precise frequency)
1772 * param pSetup : Pointer to populated PLL setup structure
1773 * return kStatus_PLL_Success on success, or PLL setup error code
1774 * note This function will power off the PLL, setup the PLL with the
1775 * new setup data, and then optionally powerup the PLL, wait for PLL lock,
1776 * and adjust system voltages to the new PLL rate. The function will not
1777 * alter any source clocks (ie, main systen clock) that may use the PLL,
1778 * so these should be setup prior to and after exiting the function.
1779 */
CLOCK_SetPLL0Freq(const pll_setup_t * pSetup)1780 pll_error_t CLOCK_SetPLL0Freq(const pll_setup_t *pSetup)
1781 {
1782 uint32_t inRate, clkRate, prediv;
1783 uint32_t pll_lock_wait_time = 0U;
1784 uint32_t max_pll_lock_wait_time = 0U;
1785 /* Power off PLL during setup changes */
1786 POWER_EnablePD(kPDRUNCFG_PD_PLL0);
1787 POWER_EnablePD(kPDRUNCFG_PD_PLL0_SSCG);
1788
1789 /* Write PLL setup data */
1790 SYSCON->PLL0CTRL = pSetup->pllctrl;
1791 SYSCON->PLL0NDEC = pSetup->pllndec;
1792 SYSCON->PLL0NDEC = pSetup->pllndec | (1UL << SYSCON_PLL0NDEC_NREQ_SHIFT); /* latch */
1793 SYSCON->PLL0PDEC = pSetup->pllpdec;
1794 SYSCON->PLL0PDEC = pSetup->pllpdec | (1UL << SYSCON_PLL0PDEC_PREQ_SHIFT); /* latch */
1795 SYSCON->PLL0SSCG0 = pSetup->pllsscg[0];
1796 SYSCON->PLL0SSCG1 = pSetup->pllsscg[1];
1797 SYSCON->PLL0SSCG1 =
1798 pSetup->pllsscg[1] | (1UL << SYSCON_PLL0SSCG1_MD_REQ_SHIFT) | (1UL << SYSCON_PLL0SSCG1_MREQ_SHIFT); /* latch */
1799
1800 POWER_DisablePD(kPDRUNCFG_PD_PLL0);
1801 POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG);
1802
1803 if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
1804 {
1805 if ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_SEL_EXT_MASK) != 0UL) /* normal mode */
1806 {
1807 inRate = CLOCK_GetPLL0InClockRate();
1808 prediv = findPll0PreDiv();
1809 /* Adjust input clock */
1810 clkRate = inRate / prediv;
1811
1812 /* Need wait at least (500us + 400/Fref) (Fref in Hz result in s) to ensure the PLL is
1813 stable. The lock bit could be used to shorten the wait time when freq<20MHZ */
1814 max_pll_lock_wait_time = 500U + (400000000U / clkRate);
1815
1816 if (clkRate < 20000000UL)
1817 {
1818 pll_lock_wait_time = 0U;
1819 while ((CLOCK_IsPLL0Locked() == false) && (pll_lock_wait_time < max_pll_lock_wait_time))
1820 {
1821 pll_lock_wait_time += 100U;
1822 SDK_DelayAtLeastUs(100U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1823 }
1824 }
1825 else
1826 {
1827 SDK_DelayAtLeastUs(max_pll_lock_wait_time, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1828 }
1829 }
1830 else /* spread spectrum mode */
1831 {
1832 SDK_DelayAtLeastUs(6000U,
1833 SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); /* software should use a 6 ms time interval
1834 to insure the PLL will be stable */
1835 }
1836 }
1837
1838 /* Update current programmed PLL rate var */
1839 s_Pll0_Freq = pSetup->pllRate;
1840
1841 return kStatus_PLL_Success;
1842 }
1843
1844 /* Setup PLL1 Frequency from pre-calculated value */
1845 /**
1846 * brief Set PLL1 output from PLL setup structure (precise frequency)
1847 * param pSetup : Pointer to populated PLL setup structure
1848 * return kStatus_PLL_Success on success, or PLL setup error code
1849 * note This function will power off the PLL, setup the PLL with the
1850 * new setup data, and then optionally powerup the PLL, wait for PLL lock,
1851 * and adjust system voltages to the new PLL rate. The function will not
1852 * alter any source clocks (ie, main systen clock) that may use the PLL,
1853 * so these should be setup prior to and after exiting the function.
1854 */
CLOCK_SetPLL1Freq(const pll_setup_t * pSetup)1855 pll_error_t CLOCK_SetPLL1Freq(const pll_setup_t *pSetup)
1856 {
1857 uint32_t inRate, clkRate, prediv;
1858 uint32_t pll_lock_wait_time = 0U;
1859 uint32_t max_pll_lock_wait_time = 0U;
1860 /* Power off PLL during setup changes */
1861 POWER_EnablePD(kPDRUNCFG_PD_PLL1);
1862
1863 /* Write PLL setup data */
1864 SYSCON->PLL1CTRL = pSetup->pllctrl;
1865 SYSCON->PLL1NDEC = pSetup->pllndec;
1866 SYSCON->PLL1NDEC = pSetup->pllndec | (1UL << SYSCON_PLL1NDEC_NREQ_SHIFT); /* latch */
1867 SYSCON->PLL1PDEC = pSetup->pllpdec;
1868 SYSCON->PLL1PDEC = pSetup->pllpdec | (1UL << SYSCON_PLL1PDEC_PREQ_SHIFT); /* latch */
1869 SYSCON->PLL1MDEC = pSetup->pllmdec;
1870 SYSCON->PLL1MDEC = pSetup->pllmdec | (1UL << SYSCON_PLL1MDEC_MREQ_SHIFT); /* latch */
1871
1872 POWER_DisablePD(kPDRUNCFG_PD_PLL1);
1873
1874 if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
1875 {
1876 inRate = CLOCK_GetPLL1InClockRate();
1877 prediv = findPll1PreDiv();
1878 /* Adjust input clock */
1879 clkRate = inRate / prediv;
1880
1881 /* Need wait at least (500us + 400/Fref) (Fref in Hz result in s) to ensure the PLL is stable.
1882 The lock bit could be used to shorten the wait time when freq<20MHZ */
1883 max_pll_lock_wait_time = 500U + (400000000U / clkRate);
1884
1885 if (clkRate < 20000000UL)
1886 {
1887 pll_lock_wait_time = 0U;
1888 while ((CLOCK_IsPLL1Locked() == false) && (pll_lock_wait_time < max_pll_lock_wait_time))
1889 {
1890 pll_lock_wait_time += 100U;
1891 SDK_DelayAtLeastUs(100U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1892 }
1893 }
1894 else
1895 {
1896 SDK_DelayAtLeastUs(max_pll_lock_wait_time, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1897 }
1898 }
1899
1900 /* Update current programmed PLL rate var */
1901 s_Pll1_Freq = pSetup->pllRate;
1902
1903 return kStatus_PLL_Success;
1904 }
1905
1906 /* Set PLL0 clock based on the input frequency and multiplier */
1907 /*! brief Set PLL0 output based on the multiplier and input frequency
1908 * param multiply_by : multiplier
1909 * param input_freq : Clock input frequency of the PLL
1910 * return Nothing
1911 * note Unlike the Chip_Clock_SetupSystemPLLPrec() function, this
1912 * function does not disable or enable PLL power, wait for PLL lock,
1913 * or adjust system voltages. These must be done in the application.
1914 * The function will not alter any source clocks (ie, main systen clock)
1915 * that may use the PLL, so these should be setup prior to and after
1916 * exiting the function.
1917 */
CLOCK_SetupPLL0Mult(uint32_t multiply_by,uint32_t input_freq)1918 void CLOCK_SetupPLL0Mult(uint32_t multiply_by, uint32_t input_freq)
1919 {
1920 uint32_t cco_freq = input_freq * multiply_by;
1921 uint32_t pdec = 1U;
1922 uint32_t selr;
1923 uint32_t seli;
1924 uint32_t selp;
1925 uint32_t mdec, ndec;
1926
1927 while (cco_freq < 275000000U)
1928 {
1929 multiply_by <<= 1U; /* double value in each iteration */
1930 pdec <<= 1U; /* correspondingly double pdec to cancel effect of double msel */
1931 cco_freq = input_freq * multiply_by;
1932 }
1933
1934 selr = 0U;
1935
1936 if (multiply_by >= 8000UL)
1937 {
1938 seli = 1UL;
1939 }
1940 else if (multiply_by >= 122UL)
1941 {
1942 seli = (uint32_t)(8000UL / multiply_by); /*floor(8000/M) */
1943 }
1944 else
1945 {
1946 seli = 2UL * ((uint32_t)(multiply_by / 4UL)) + 3UL; /* 2*floor(M/4) + 3 */
1947 }
1948
1949 if (seli >= 63U)
1950 {
1951 seli = 63U;
1952 }
1953
1954 {
1955 selp = 31U;
1956 }
1957
1958 if (pdec > 1U)
1959 {
1960 pdec = pdec / 2U; /* Account for minus 1 encoding */
1961 /* Translate P value */
1962 }
1963
1964 mdec = (uint32_t)PLL_SSCG1_MDEC_VAL_SET(multiply_by);
1965 ndec = 0x1U; /* pre divide by 1 (hardcoded) */
1966
1967 SYSCON->PLL0CTRL = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_BYPASSPOSTDIV(0) |
1968 SYSCON_PLL0CTRL_BYPASSPOSTDIV2(0) | (selr << SYSCON_PLL0CTRL_SELR_SHIFT) |
1969 (seli << SYSCON_PLL0CTRL_SELI_SHIFT) | (selp << SYSCON_PLL0CTRL_SELP_SHIFT);
1970 SYSCON->PLL0PDEC = pdec | (1UL << SYSCON_PLL0PDEC_PREQ_SHIFT); /* set Pdec value and assert preq */
1971 SYSCON->PLL0NDEC = ndec | (1UL << SYSCON_PLL0NDEC_NREQ_SHIFT); /* set Pdec value and assert preq */
1972 SYSCON->PLL0SSCG1 = mdec | (1UL << SYSCON_PLL0SSCG1_MREQ_SHIFT); /* select non sscg MDEC value, assert
1973 mreq and select mdec value */
1974 }
1975
1976 /* Enable USB DEVICE FULL SPEED clock */
1977 /*! brief Enable USB Device FS clock.
1978 * param src : clock source
1979 * param freq: clock frequency
1980 * Enable USB Device Full Speed clock.
1981 */
CLOCK_EnableUsbfs0DeviceClock(clock_usbfs_src_t src,uint32_t freq)1982 bool CLOCK_EnableUsbfs0DeviceClock(clock_usbfs_src_t src, uint32_t freq)
1983 {
1984 bool ret = true;
1985
1986 CLOCK_DisableClock(kCLOCK_Usbd0);
1987
1988 if (kCLOCK_UsbfsSrcFro == src)
1989 {
1990 switch (freq)
1991 {
1992 case 96000000U:
1993 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
1994 break;
1995
1996 default:
1997 ret = false;
1998 break;
1999 }
2000 /* Turn ON FRO HF */
2001 POWER_DisablePD(kPDRUNCFG_PD_FRO192M);
2002 /* Enable FRO 96MHz output */
2003 ANACTRL->FRO192M_CTRL =
2004 ANACTRL->FRO192M_CTRL | ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK | ANACTRL_FRO192M_CTRL_USBCLKADJ_MASK;
2005 /* Select FRO 96 or 48 MHz */
2006 CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
2007 }
2008 else
2009 {
2010 /*!< Configure XTAL32M */
2011 POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */
2012 POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */
2013 (void)CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */
2014 SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */
2015 ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */
2016
2017 /*!< Set up PLL1 */
2018 POWER_DisablePD(kPDRUNCFG_PD_PLL1);
2019 CLOCK_AttachClk(kEXT_CLK_to_PLL1); /*!< Switch PLL1CLKSEL to EXT_CLK */
2020 const pll_setup_t pll1Setup = {
2021 .pllctrl = SYSCON_PLL1CTRL_CLKEN_MASK | SYSCON_PLL1CTRL_SELI(19U) | SYSCON_PLL1CTRL_SELP(9U),
2022 .pllndec = SYSCON_PLL1NDEC_NDIV(1U),
2023 .pllpdec = SYSCON_PLL1PDEC_PDIV(5U),
2024 .pllmdec = SYSCON_PLL1MDEC_MDIV(30U),
2025 .pllRate = 48000000U,
2026 .flags = PLL_SETUPFLAG_WAITLOCK};
2027 (void)CLOCK_SetPLL1Freq(&pll1Setup);
2028
2029 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
2030 CLOCK_AttachClk(kPLL1_to_USB0_CLK);
2031 SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2032 }
2033 CLOCK_EnableClock(kCLOCK_Usbd0);
2034 CLOCK_EnableClock(kCLOCK_UsbRam1);
2035
2036 return ret;
2037 }
2038
2039 /* Enable USB HOST FULL SPEED clock */
2040 /*! brief Enable USB HOST FS clock.
2041 * param src : clock source
2042 * param freq: clock frequency
2043 * Enable USB HOST Full Speed clock.
2044 */
CLOCK_EnableUsbfs0HostClock(clock_usbfs_src_t src,uint32_t freq)2045 bool CLOCK_EnableUsbfs0HostClock(clock_usbfs_src_t src, uint32_t freq)
2046 {
2047 bool ret = true;
2048
2049 CLOCK_DisableClock(kCLOCK_Usbhmr0);
2050 CLOCK_DisableClock(kCLOCK_Usbhsl0);
2051
2052 if (kCLOCK_UsbfsSrcFro == src)
2053 {
2054 switch (freq)
2055 {
2056 case 96000000U:
2057 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
2058 break;
2059
2060 default:
2061 ret = false;
2062 break;
2063 }
2064 /* Turn ON FRO HF */
2065 POWER_DisablePD(kPDRUNCFG_PD_FRO192M);
2066 /* Enable FRO 96MHz output */
2067 ANACTRL->FRO192M_CTRL = ANACTRL->FRO192M_CTRL | ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK;
2068 /* Select FRO 96 MHz */
2069 CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
2070 }
2071 else
2072 {
2073 /*!< Configure XTAL32M */
2074 POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */
2075 POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */
2076 (void)CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */
2077 SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */
2078 ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */
2079
2080 /*!< Set up PLL1 */
2081 POWER_DisablePD(kPDRUNCFG_PD_PLL1);
2082 CLOCK_AttachClk(kEXT_CLK_to_PLL1); /*!< Switch PLL1CLKSEL to EXT_CLK */
2083 const pll_setup_t pll1Setup = {
2084 .pllctrl = SYSCON_PLL1CTRL_CLKEN_MASK | SYSCON_PLL1CTRL_SELI(19U) | SYSCON_PLL1CTRL_SELP(9U),
2085 .pllndec = SYSCON_PLL1NDEC_NDIV(1U),
2086 .pllpdec = SYSCON_PLL1PDEC_PDIV(5U),
2087 .pllmdec = SYSCON_PLL1MDEC_MDIV(30U),
2088 .pllRate = 48000000U,
2089 .flags = PLL_SETUPFLAG_WAITLOCK};
2090 (void)CLOCK_SetPLL1Freq(&pll1Setup);
2091
2092 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
2093 CLOCK_AttachClk(kPLL1_to_USB0_CLK);
2094 SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2095 }
2096 CLOCK_EnableClock(kCLOCK_Usbhmr0);
2097 CLOCK_EnableClock(kCLOCK_Usbhsl0);
2098 CLOCK_EnableClock(kCLOCK_UsbRam1);
2099
2100 return ret;
2101 }
2102
2103 /* Enable USB PHY clock */
CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src,uint32_t freq)2104 bool CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src, uint32_t freq)
2105 {
2106 volatile uint32_t i;
2107 uint32_t phyPllDiv = 0U;
2108 uint16_t multiplier = 0U;
2109 bool ret = true;
2110
2111 POWER_DisablePD(kPDRUNCFG_PD_XTAL32M);
2112 POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M);
2113 POWER_DisablePD(kPDRUNCFG_PD_FRO32K); /*!< Ensure FRO32k is on */
2114 POWER_DisablePD(kPDRUNCFG_PD_XTAL32K); /*!< Ensure xtal32k is on */
2115 POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /*!< Ensure xtal32k is on */
2116 POWER_DisablePD(kPDRUNCFG_PD_LDOUSBHS); /*!< Ensure xtal32k is on */
2117
2118 SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_ANALOG_CTRL(1);
2119 SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_PHY(1);
2120
2121 /* wait to make sure PHY power is fully up */
2122 i = 100000U;
2123 while ((i--) != 0U)
2124 {
2125 __ASM("nop");
2126 }
2127
2128 USBPHY->CTRL_CLR = USBPHY_CTRL_SFTRST_MASK;
2129
2130 multiplier = (uint16_t)(480000000UL / freq);
2131
2132 switch (multiplier)
2133 {
2134 case 15U:
2135 {
2136 phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(0U);
2137 break;
2138 }
2139 case 16U:
2140 {
2141 phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(1U);
2142 break;
2143 }
2144 case 20U:
2145 {
2146 phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(2U);
2147 break;
2148 }
2149 case 24U:
2150 {
2151 phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(4U);
2152 break;
2153 }
2154 case 25U:
2155 {
2156 phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(5U);
2157 break;
2158 }
2159 case 30U:
2160 {
2161 phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(6U);
2162 break;
2163 }
2164 default:
2165 {
2166 ret = false;
2167 break;
2168 }
2169 }
2170
2171 if (ret)
2172 {
2173 USBPHY->PLL_SIC = (USBPHY->PLL_SIC & ~USBPHY_PLL_SIC_PLL_DIV_SEL(0x7)) | phyPllDiv;
2174 USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_SET_PLL_REG_ENABLE_MASK;
2175 USBPHY->PLL_SIC_CLR = (1UL << 16U); // Reserved. User must set this bit to 0x0
2176 USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_SET_PLL_POWER_MASK;
2177 USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_SET_PLL_EN_USB_CLKS_MASK;
2178
2179 USBPHY->CTRL_CLR = USBPHY_CTRL_CLR_CLKGATE_MASK;
2180 USBPHY->PWD_SET = 0x0;
2181 }
2182
2183 return ret;
2184 }
2185
2186 /* Enable USB DEVICE HIGH SPEED clock */
CLOCK_EnableUsbhs0DeviceClock(clock_usbhs_src_t src,uint32_t freq)2187 bool CLOCK_EnableUsbhs0DeviceClock(clock_usbhs_src_t src, uint32_t freq)
2188 {
2189 SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_RAM(1);
2190 SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_DEV(1);
2191
2192 /* 16 MHz will be driven by the tb on the xtal1 pin of XTAL32M */
2193 SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clock_in clock for clock module. */
2194 ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT(1);
2195 return true;
2196 }
2197
2198 /* Enable USB HOST HIGH SPEED clock */
CLOCK_EnableUsbhs0HostClock(clock_usbhs_src_t src,uint32_t freq)2199 bool CLOCK_EnableUsbhs0HostClock(clock_usbhs_src_t src, uint32_t freq)
2200 {
2201 SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_RAM(1);
2202 SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_HOST(1);
2203
2204 /* 16 MHz will be driven by the tb on the xtal1 pin of XTAL32M */
2205 SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clock_in clock for clock module. */
2206 ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT(1);
2207
2208 return true;
2209 }
2210
2211 /*! @brief Enable the OSTIMER 32k clock.
2212 * @return Nothing
2213 */
CLOCK_EnableOstimer32kClock(void)2214 void CLOCK_EnableOstimer32kClock(void)
2215 {
2216 PMC->OSTIMERr |= PMC_OSTIMER_CLOCKENABLE_MASK;
2217 }
2218