2 * Copyright 2017 - 2019 , NXP
\r
3 * All rights reserved.
\r
5 * SPDX-License-Identifier: BSD-3-Clause
\r
8 #include "fsl_clock.h"
\r
9 #include "fsl_power.h"
\r
10 /*******************************************************************************
\r
12 ******************************************************************************/
\r
13 /* Component ID definition, used by tools. */
\r
14 #ifndef FSL_COMPONENT_ID
\r
15 #define FSL_COMPONENT_ID "platform.drivers.clock"
\r
17 #define NVALMAX (0x100U)
\r
18 #define PVALMAX (0x20U)
\r
19 #define MVALMAX (0x10000U)
\r
21 #define PLL_MAX_N_DIV 0x100U
\r
23 /*--------------------------------------------------------------------------
\r
24 !!! If required these #defines can be moved to chip library file
\r
25 ----------------------------------------------------------------------------*/
\r
27 #define PLL_SSCG1_MDEC_VAL_P (10U) /* MDEC is in bits 25 downto 10 */
\r
28 #define PLL_SSCG1_MDEC_VAL_M (0xFFFFULL << PLL_SSCG1_MDEC_VAL_P)
\r
29 #define PLL_NDEC_VAL_P (0U) /* NDEC is in bits 9:0 */
\r
30 #define PLL_NDEC_VAL_M (0xFFUL << PLL_NDEC_VAL_P)
\r
31 #define PLL_PDEC_VAL_P (0U) /*!< PDEC is in bits 6:0 */
\r
32 #define PLL_PDEC_VAL_M (0x1FUL << PLL_PDEC_VAL_P)
\r
34 #define PLL_MIN_CCO_FREQ_MHZ (275000000U)
\r
35 #define PLL_MAX_CCO_FREQ_MHZ (550000000U)
\r
36 #define PLL_LOWER_IN_LIMIT (2000U) /*!< Minimum PLL input rate */
\r
37 #define PLL_HIGHER_IN_LIMIT (150000000U) /*!< Maximum PLL input rate */
\r
38 #define PLL_MIN_IN_SSMODE (3000000U)
\r
39 #define PLL_MAX_IN_SSMODE \
\r
40 (100000000U) /*!< Not find the value in UM, Just use the maximum frequency which device support */
\r
43 #define PLL_NDEC_VAL_SET(value) (((unsigned long)(value) << PLL_NDEC_VAL_P) & PLL_NDEC_VAL_M)
\r
45 #define PLL_PDEC_VAL_SET(value) (((unsigned long)(value) << PLL_PDEC_VAL_P) & PLL_PDEC_VAL_M)
\r
47 #define PLL_SSCG1_MDEC_VAL_SET(value) (((uint64_t)(value) << PLL_SSCG1_MDEC_VAL_P) & PLL_SSCG1_MDEC_VAL_M)
\r
49 /* PLL0 SSCG control1 */
\r
50 #define PLL0_SSCG_MD_FRACT_P 0U
\r
51 #define PLL0_SSCG_MD_INT_P 25U
\r
52 #define PLL0_SSCG_MD_FRACT_M (0x1FFFFFFUL << PLL0_SSCG_MD_FRACT_P)
\r
53 #define PLL0_SSCG_MD_INT_M ((uint64_t)0xFFUL << PLL0_SSCG_MD_INT_P)
\r
55 #define PLL0_SSCG_MD_FRACT_SET(value) (((uint64_t)(value) << PLL0_SSCG_MD_FRACT_P) & PLL0_SSCG_MD_FRACT_M)
\r
56 #define PLL0_SSCG_MD_INT_SET(value) (((uint64_t)(value) << PLL0_SSCG_MD_INT_P) & PLL0_SSCG_MD_INT_M)
\r
58 /* Saved value of PLL output rate, computed whenever needed to save run-time
\r
59 computation on each call to retrive the PLL rate. */
\r
60 static uint32_t s_Pll0_Freq;
\r
61 static uint32_t s_Pll1_Freq;
\r
63 /** External clock rate on the CLKIN pin in Hz. If not used,
\r
64 set this to 0. Otherwise, set it to the exact rate in Hz this pin is
\r
66 static uint32_t s_Ext_Clk_Freq = 16000000U;
\r
67 static uint32_t s_I2S_Mclk_Freq = 0U;
\r
68 static uint32_t s_PLU_ClkIn_Freq = 0U;
\r
70 /*******************************************************************************
\r
72 ******************************************************************************/
\r
74 /*******************************************************************************
\r
76 ******************************************************************************/
\r
77 /* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */
\r
78 static void pllFindSel(uint32_t M, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR);
\r
79 /* Get predivider (N) from PLL0 NDEC setting */
\r
80 static uint32_t findPll0PreDiv(void);
\r
81 /* Get predivider (N) from PLL1 NDEC setting */
\r
82 static uint32_t findPll1PreDiv(void);
\r
83 /* Get postdivider (P) from PLL0 PDEC setting */
\r
84 static uint32_t findPll0PostDiv(void);
\r
85 /* Get multiplier (M) from PLL0 MDEC and SSCG settings */
\r
86 static float findPll0MMult(void);
\r
87 /* Get the greatest common divisor */
\r
88 static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n);
\r
89 /* Set PLL output based on desired output rate */
\r
90 static pll_error_t CLOCK_GetPll0Config(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useSS);
\r
91 /* Update local PLL rate variable */
\r
92 static void CLOCK_GetPLL0OutFromSetupUpdate(pll_setup_t *pSetup);
\r
94 /*******************************************************************************
\r
96 ******************************************************************************/
\r
98 /* Clock Selection for IP */
\r
100 * brief Configure the clock selection muxes.
\r
101 * param connection : Clock to be configured.
\r
104 void CLOCK_AttachClk(clock_attach_id_t connection)
\r
109 uint32_t tmp32 = (uint32_t)connection;
\r
111 volatile uint32_t *pClkSel;
\r
113 pClkSel = &(SYSCON->SYSTICKCLKSELX[0]);
\r
115 if (kNONE_to_NONE != connection)
\r
117 for (i = 0U; i < 2U; i++)
\r
123 item = (uint16_t)GET_ID_ITEM(tmp32);
\r
126 mux = GET_ID_ITEM_MUX(item);
\r
127 sel = GET_ID_ITEM_SEL(item);
\r
128 if (mux == CM_RTCOSC32KCLKSEL)
\r
130 PMC->RTCOSC32K |= sel;
\r
134 pClkSel[mux] = sel;
\r
137 tmp32 = GET_ID_NEXT_ITEM(tmp32); /* pick up next descriptor */
\r
142 /* Return the actual clock attach id */
\r
144 * brief Get the actual clock attach id.
\r
145 * This fuction uses the offset in input attach id, then it reads the actual source value in
\r
146 * the register and combine the offset to obtain an actual attach id.
\r
147 * param attachId : Clock attach id to get.
\r
148 * return Clock source value.
\r
150 clock_attach_id_t CLOCK_GetClockAttachId(clock_attach_id_t attachId)
\r
154 uint32_t tmp32 = (uint32_t)attachId;
\r
156 uint32_t actualAttachId = 0U;
\r
157 uint32_t selector = GET_ID_SELECTOR(tmp32);
\r
158 volatile uint32_t *pClkSel;
\r
160 pClkSel = &(SYSCON->SYSTICKCLKSELX[0]);
\r
162 if (kNONE_to_NONE == attachId)
\r
164 return kNONE_to_NONE;
\r
167 for (i = 0U; i < 2U; i++)
\r
169 mux = GET_ID_ITEM_MUX(tmp32);
\r
172 if (mux == CM_RTCOSC32KCLKSEL)
\r
174 actualSel = (uint8_t)(PMC->RTCOSC32K);
\r
178 actualSel = (uint8_t)(pClkSel[mux]);
\r
181 /* Consider the combination of two registers */
\r
182 actualAttachId |= CLK_ATTACH_ID(mux, actualSel, i);
\r
184 tmp32 = GET_ID_NEXT_ITEM(tmp32); /*!< pick up next descriptor */
\r
187 actualAttachId |= selector;
\r
189 return (clock_attach_id_t)actualAttachId;
\r
192 /* Set IP Clock Divider */
\r
194 * brief Setup peripheral clock dividers.
\r
195 * param div_name : Clock divider name
\r
196 * param divided_by_value: Value to be divided
\r
197 * param reset : Whether to reset the divider counter.
\r
200 void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset)
\r
202 volatile uint32_t *pClkDiv;
\r
204 pClkDiv = &(SYSCON->SYSTICKCLKDIV0);
\r
207 pClkDiv[(uint8_t)div_name] = 1UL << 29U;
\r
209 if (divided_by_value == 0U) /*!< halt */
\r
211 pClkDiv[(uint8_t)div_name] = 1UL << 30U;
\r
215 pClkDiv[(uint8_t)div_name] = (divided_by_value - 1U);
\r
219 /* Set RTC 1KHz Clock Divider */
\r
221 * brief Setup rtc 1khz clock divider.
\r
222 * param divided_by_value: Value to be divided
\r
225 void CLOCK_SetRtc1khzClkDiv(uint32_t divided_by_value)
\r
227 PMC->RTCOSC32K |= (((divided_by_value - 28U) << PMC_RTCOSC32K_CLK1KHZDIV_SHIFT) | PMC_RTCOSC32K_CLK1KHZDIV_MASK);
\r
230 /* Set RTC 1KHz Clock Divider */
\r
232 * brief Setup rtc 1hz clock divider.
\r
233 * param divided_by_value: Value to be divided
\r
236 void CLOCK_SetRtc1hzClkDiv(uint32_t divided_by_value)
\r
238 if (divided_by_value == 0U) /*!< halt */
\r
240 PMC->RTCOSC32K |= (1UL << PMC_RTCOSC32K_CLK1HZDIVHALT_SHIFT);
\r
245 (((divided_by_value - 31744U) << PMC_RTCOSC32K_CLK1HZDIV_SHIFT) | PMC_RTCOSC32K_CLK1HZDIV_MASK);
\r
249 /* Set FRO Clocking */
\r
251 * brief Initialize the Core clock to given frequency (12, 48 or 96 MHz).
\r
252 * Turns on FRO and uses default CCO, if freq is 12000000, then high speed output is off, else high speed output is
\r
254 * param iFreq : Desired frequency (must be one of #CLK_FRO_12MHZ or #CLK_FRO_48MHZ or #CLK_FRO_96MHZ)
\r
255 * return returns success or fail status.
\r
257 status_t CLOCK_SetupFROClocking(uint32_t iFreq)
\r
259 if ((iFreq != 12000000U) && (iFreq != 48000000U) && (iFreq != 96000000U))
\r
261 return kStatus_Fail;
\r
263 /* Enable Analog Control module */
\r
264 SYSCON->PRESETCTRLCLR[2] = (1UL << SYSCON_PRESETCTRL2_ANALOG_CTRL_RST_SHIFT);
\r
265 SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_ANALOG_CTRL_MASK;
\r
266 /* Power up the FRO192M */
\r
267 POWER_DisablePD(kPDRUNCFG_PD_FRO192M);
\r
269 if (iFreq == 96000000U)
\r
271 ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_ENA_96MHZCLK(1);
\r
274 else if (iFreq == 48000000U)
\r
276 ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_ENA_48MHZCLK(1);
\r
280 ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_ENA_12MHZCLK(1);
\r
282 return kStatus_Success;
\r
285 /* Set the FLASH wait states for the passed frequency */
\r
287 * brief Set the flash wait states for the input freuqency.
\r
288 * param iFreq: Input frequency
\r
291 void CLOCK_SetFLASHAccessCyclesForFreq(uint32_t iFreq)
\r
293 uint32_t num_wait_states; /* Flash Controller & FMC internal number of Wait States (minus 1) */
\r
295 if (iFreq <= 11000000UL)
\r
298 num_wait_states = 0UL;
\r
300 else if (iFreq <= 22000000UL)
\r
302 /* [11 MHz - 22 MHz] */
\r
303 num_wait_states = 1UL;
\r
305 else if (iFreq <= 33000000UL)
\r
307 /* [22 MHz - 33 MHz] */
\r
308 num_wait_states = 2UL;
\r
310 else if (iFreq <= 44000000UL)
\r
312 /* [33 MHz - 44 MHz] */
\r
313 num_wait_states = 3UL;
\r
315 else if (iFreq <= 55000000UL)
\r
317 /* [44 MHz - 55 MHz] */
\r
318 num_wait_states = 4UL;
\r
320 else if (iFreq <= 66000000UL)
\r
322 /* [55 MHz - 662 MHz] */
\r
323 num_wait_states = 5UL;
\r
325 else if (iFreq <= 77000000UL)
\r
327 /* [66 MHz - 77 MHz] */
\r
328 num_wait_states = 6UL;
\r
330 else if (iFreq <= 88000000UL)
\r
332 /* [77 MHz - 88 MHz] */
\r
333 num_wait_states = 7UL;
\r
335 else if (iFreq <= 100000000UL)
\r
337 /* [88 MHz - 100 MHz] */
\r
338 num_wait_states = 8UL;
\r
340 else if (iFreq <= 115000000UL)
\r
342 /* [100 MHz - 115 MHz] */
\r
343 num_wait_states = 9UL;
\r
345 else if (iFreq <= 130000000UL)
\r
347 /* [115 MHz - 130 MHz] */
\r
348 num_wait_states = 10UL;
\r
350 else if (iFreq <= 150000000UL)
\r
352 /* [130 MHz - 150 MHz] */
\r
353 num_wait_states = 11UL;
\r
357 /* Above 150 MHz */
\r
358 num_wait_states = 12UL;
\r
361 FLASH->INT_CLR_STATUS = 0x1FUL; /* Clear all status flags */
\r
363 FLASH->DATAW[0] = (FLASH->DATAW[0] & 0xFFFFFFF0UL) |
\r
364 (num_wait_states & (SYSCON_FMCCR_FLASHTIM_MASK >> SYSCON_FMCCR_FLASHTIM_SHIFT));
\r
366 FLASH->CMD = 0x2; /* CMD_SET_READ_MODE */
\r
368 /* Wait until the cmd is completed (without error) */
\r
369 while (0UL == (FLASH->INT_STATUS & FLASH_INT_STATUS_DONE_MASK))
\r
374 /* Adjust FMC waiting time cycles (num_wait_states) */
\r
375 SYSCON->FMCCR = (SYSCON->FMCCR & ~SYSCON_FMCCR_FLASHTIM_MASK) |
\r
376 ((num_wait_states << SYSCON_FMCCR_FLASHTIM_SHIFT) & SYSCON_FMCCR_FLASHTIM_MASK);
\r
379 /* Set EXT OSC Clk */
\r
381 * brief Initialize the external osc clock to given frequency.
\r
382 * param iFreq : Desired frequency (must be equal to exact rate in Hz)
\r
383 * return returns success or fail status.
\r
385 status_t CLOCK_SetupExtClocking(uint32_t iFreq)
\r
387 if (iFreq >= 32000000U)
\r
389 return kStatus_Fail;
\r
391 /* Turn on power for crystal 32 MHz */
\r
392 POWER_DisablePD(kPDRUNCFG_PD_XTAL32M);
\r
393 POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M);
\r
394 /* Enable clock_in clock for clock module. */
\r
395 SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK;
\r
397 s_Ext_Clk_Freq = iFreq;
\r
398 return kStatus_Success;
\r
401 /* Set I2S MCLK Clk */
\r
403 * brief Initialize the I2S MCLK clock to given frequency.
\r
404 * param iFreq : Desired frequency (must be equal to exact rate in Hz)
\r
405 * return returns success or fail status.
\r
407 status_t CLOCK_SetupI2SMClkClocking(uint32_t iFreq)
\r
409 s_I2S_Mclk_Freq = iFreq;
\r
410 return kStatus_Success;
\r
413 /* Set PLU CLKIN Clk */
\r
415 * brief Initialize the PLU CLKIN clock to given frequency.
\r
416 * param iFreq : Desired frequency (must be equal to exact rate in Hz)
\r
417 * return returns success or fail status.
\r
419 status_t CLOCK_SetupPLUClkInClocking(uint32_t iFreq)
\r
421 s_PLU_ClkIn_Freq = iFreq;
\r
422 return kStatus_Success;
\r
425 /* Get CLOCK OUT Clk */
\r
426 /*! brief Return Frequency of ClockOut
\r
427 * return Frequency of ClockOut
\r
429 uint32_t CLOCK_GetClockOutClkFreq(void)
\r
431 uint32_t freq = 0U;
\r
433 switch (SYSCON->CLKOUTSEL)
\r
436 freq = CLOCK_GetCoreSysClkFreq();
\r
440 freq = CLOCK_GetPll0OutFreq();
\r
444 freq = CLOCK_GetExtClkFreq();
\r
448 freq = CLOCK_GetFroHfFreq();
\r
452 freq = CLOCK_GetFro1MFreq();
\r
456 freq = CLOCK_GetPll1OutFreq();
\r
460 freq = CLOCK_GetOsc32KFreq();
\r
471 return freq / ((SYSCON->CLKOUTDIV & 0xffU) + 1U);
\r
475 /*! brief Return Frequency of Adc Clock
\r
476 * return Frequency of Adc.
\r
478 uint32_t CLOCK_GetAdcClkFreq(void)
\r
480 uint32_t freq = 0U;
\r
482 switch (SYSCON->ADCCLKSEL)
\r
485 freq = CLOCK_GetCoreSysClkFreq();
\r
488 freq = CLOCK_GetPll0OutFreq();
\r
491 freq = CLOCK_GetFroHfFreq();
\r
502 return freq / ((SYSCON->ADCCLKDIV & SYSCON_ADCCLKDIV_DIV_MASK) + 1U);
\r
506 /*! brief Return Frequency of Usb0 Clock
\r
507 * return Frequency of Usb0 Clock.
\r
509 uint32_t CLOCK_GetUsb0ClkFreq(void)
\r
511 uint32_t freq = 0U;
\r
513 switch (SYSCON->USB0CLKSEL)
\r
516 freq = CLOCK_GetCoreSysClkFreq();
\r
519 freq = CLOCK_GetPll0OutFreq();
\r
522 freq = CLOCK_GetFroHfFreq();
\r
525 freq = CLOCK_GetPll1OutFreq();
\r
536 return freq / ((SYSCON->USB0CLKDIV & 0xffU) + 1U);
\r
540 /*! brief Return Frequency of Usb1 Clock
\r
541 * return Frequency of Usb1 Clock.
\r
543 uint32_t CLOCK_GetUsb1ClkFreq(void)
\r
545 return ((ANACTRL->XO32M_CTRL & ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT_MASK) != 0UL) ? s_Ext_Clk_Freq : 0U;
\r
549 /*! brief Return Frequency of MClk Clock
\r
550 * return Frequency of MClk Clock.
\r
552 uint32_t CLOCK_GetMclkClkFreq(void)
\r
554 uint32_t freq = 0U;
\r
556 switch (SYSCON->MCLKCLKSEL)
\r
559 freq = CLOCK_GetFroHfFreq();
\r
562 freq = CLOCK_GetPll0OutFreq();
\r
573 return freq / ((SYSCON->MCLKDIV & 0xffU) + 1U);
\r
576 /* Get SCTIMER Clk */
\r
577 /*! brief Return Frequency of SCTimer Clock
\r
578 * return Frequency of SCTimer Clock.
\r
580 uint32_t CLOCK_GetSctClkFreq(void)
\r
582 uint32_t freq = 0U;
\r
584 switch (SYSCON->SCTCLKSEL)
\r
587 freq = CLOCK_GetCoreSysClkFreq();
\r
590 freq = CLOCK_GetPll0OutFreq();
\r
593 freq = CLOCK_GetExtClkFreq();
\r
596 freq = CLOCK_GetFroHfFreq();
\r
599 freq = CLOCK_GetI2SMClkFreq();
\r
610 return freq / ((SYSCON->SCTCLKDIV & 0xffU) + 1U);
\r
614 /*! brief Return Frequency of SDIO Clock
\r
615 * return Frequency of SDIO Clock.
\r
617 uint32_t CLOCK_GetSdioClkFreq(void)
\r
619 uint32_t freq = 0U;
\r
621 switch (SYSCON->SDIOCLKSEL)
\r
624 freq = CLOCK_GetCoreSysClkFreq();
\r
627 freq = CLOCK_GetPll0OutFreq();
\r
630 freq = CLOCK_GetFroHfFreq();
\r
633 freq = CLOCK_GetPll1OutFreq();
\r
643 return freq / ((SYSCON->SDIOCLKDIV & 0xffU) + 1U);
\r
646 /* Get FRO 12M Clk */
\r
647 /*! brief Return Frequency of FRO 12MHz
\r
648 * return Frequency of FRO 12MHz
\r
650 uint32_t CLOCK_GetFro12MFreq(void)
\r
652 return ((ANACTRL->FRO192M_CTRL & ANACTRL_FRO192M_CTRL_ENA_12MHZCLK_MASK) != 0UL) ? 12000000U : 0U;
\r
655 /* Get FRO 1M Clk */
\r
656 /*! brief Return Frequency of FRO 1MHz
\r
657 * return Frequency of FRO 1MHz
\r
659 uint32_t CLOCK_GetFro1MFreq(void)
\r
661 return ((SYSCON->CLOCK_CTRL & SYSCON_CLOCK_CTRL_FRO1MHZ_CLK_ENA_MASK) != 0UL) ? 1000000U : 0U;
\r
664 /* Get EXT OSC Clk */
\r
665 /*! brief Return Frequency of External Clock
\r
666 * return Frequency of External Clock. If no external clock is used returns 0.
\r
668 uint32_t CLOCK_GetExtClkFreq(void)
\r
670 return ((ANACTRL->XO32M_CTRL & ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK) != 0UL) ? s_Ext_Clk_Freq : 0U;
\r
673 /* Get WATCH DOG Clk */
\r
674 /*! brief Return Frequency of Watchdog
\r
675 * return Frequency of Watchdog
\r
677 uint32_t CLOCK_GetWdtClkFreq(void)
\r
679 return CLOCK_GetFro1MFreq() / ((SYSCON->WDTCLKDIV & SYSCON_WDTCLKDIV_DIV_MASK) + 1U);
\r
682 /* Get HF FRO Clk */
\r
683 /*! brief Return Frequency of High-Freq output of FRO
\r
684 * return Frequency of High-Freq output of FRO
\r
686 uint32_t CLOCK_GetFroHfFreq(void)
\r
688 return ((ANACTRL->FRO192M_CTRL & ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK) != 0UL) ? 96000000U : 0U;
\r
691 /* Get SYSTEM PLL Clk */
\r
692 /*! brief Return Frequency of PLL
\r
693 * return Frequency of PLL
\r
695 uint32_t CLOCK_GetPll0OutFreq(void)
\r
697 return s_Pll0_Freq;
\r
700 /* Get USB PLL Clk */
\r
701 /*! brief Return Frequency of USB PLL
\r
702 * return Frequency of PLL
\r
704 uint32_t CLOCK_GetPll1OutFreq(void)
\r
706 return s_Pll1_Freq;
\r
709 /* Get RTC OSC Clk */
\r
710 /*! brief Return Frequency of 32kHz osc
\r
711 * return Frequency of 32kHz osc
\r
713 uint32_t CLOCK_GetOsc32KFreq(void)
\r
715 return ((0UL == (PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_FRO32K_MASK)) &&
\r
716 (0UL == (PMC->RTCOSC32K & PMC_RTCOSC32K_SEL_MASK))) ?
\r
718 ((0UL == (PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_XTAL32K_MASK)) &&
\r
719 (0UL != (PMC->RTCOSC32K & PMC_RTCOSC32K_SEL_MASK))) ?
\r
725 /*! brief Return Frequency of Core System
\r
726 * return Frequency of Core System
\r
728 uint32_t CLOCK_GetCoreSysClkFreq(void)
\r
730 uint32_t freq = 0U;
\r
732 switch (SYSCON->MAINCLKSELB)
\r
735 if (SYSCON->MAINCLKSELA == 0U)
\r
737 freq = CLOCK_GetFro12MFreq();
\r
739 else if (SYSCON->MAINCLKSELA == 1U)
\r
741 freq = CLOCK_GetExtClkFreq();
\r
743 else if (SYSCON->MAINCLKSELA == 2U)
\r
745 freq = CLOCK_GetFro1MFreq();
\r
747 else if (SYSCON->MAINCLKSELA == 3U)
\r
749 freq = CLOCK_GetFroHfFreq();
\r
753 /* Add comments to prevent the case of MISRA C-2012 rule 15.7. */
\r
757 freq = CLOCK_GetPll0OutFreq();
\r
760 freq = CLOCK_GetPll1OutFreq();
\r
764 freq = CLOCK_GetOsc32KFreq();
\r
775 /* Get I2S MCLK Clk */
\r
776 /*! brief Return Frequency of I2S MCLK Clock
\r
777 * return Frequency of I2S MCLK Clock
\r
779 uint32_t CLOCK_GetI2SMClkFreq(void)
\r
781 return s_I2S_Mclk_Freq;
\r
784 /* Get PLU CLKIN Clk */
\r
785 /*! brief Return Frequency of PLU CLKIN Clock
\r
786 * return Frequency of PLU CLKIN Clock
\r
788 uint32_t CLOCK_GetPLUClkInFreq(void)
\r
790 return s_PLU_ClkIn_Freq;
\r
793 /* Get FLEXCOMM input clock */
\r
794 /*! brief Return Frequency of flexcomm input clock
\r
795 * param id : flexcomm instance id
\r
796 * return Frequency value
\r
798 uint32_t CLOCK_GetFlexCommInputClock(uint32_t id)
\r
800 uint32_t freq = 0U;
\r
802 switch (SYSCON->FCCLKSELX[id])
\r
805 freq = CLOCK_GetCoreSysClkFreq();
\r
808 freq = CLOCK_GetPll0OutFreq() / ((SYSCON->PLL0CLKDIV & 0xffU) + 1U);
\r
811 freq = CLOCK_GetFro12MFreq();
\r
814 freq = CLOCK_GetFroHfFreq() / ((SYSCON->FROHFDIV & 0xffU) + 1U);
\r
817 freq = CLOCK_GetFro1MFreq();
\r
820 freq = CLOCK_GetI2SMClkFreq();
\r
823 freq = CLOCK_GetOsc32KFreq();
\r
837 /* Get FLEXCOMM Clk */
\r
838 uint32_t CLOCK_GetFlexCommClkFreq(uint32_t id)
\r
840 uint32_t freq = 0U;
\r
843 freq = CLOCK_GetFlexCommInputClock(id);
\r
844 temp = SYSCON->FLEXFRGXCTRL[id] & SYSCON_FLEXFRG0CTRL_MULT_MASK;
\r
845 return freq / (1U + (temp) / ((SYSCON->FLEXFRGXCTRL[id] & SYSCON_FLEXFRG0CTRL_DIV_MASK) + 1U));
\r
848 /* Get HS_LPSI Clk */
\r
849 uint32_t CLOCK_GetHsLspiClkFreq(void)
\r
851 uint32_t freq = 0U;
\r
853 switch (SYSCON->HSLSPICLKSEL)
\r
856 freq = CLOCK_GetCoreSysClkFreq();
\r
859 freq = CLOCK_GetPll0OutFreq() / ((SYSCON->PLL0CLKDIV & 0xffU) + 1U);
\r
862 freq = CLOCK_GetFro12MFreq();
\r
865 freq = CLOCK_GetFroHfFreq() / ((SYSCON->FROHFDIV & 0xffU) + 1U);
\r
868 freq = CLOCK_GetFro1MFreq();
\r
871 freq = CLOCK_GetOsc32KFreq();
\r
885 /* Get CTimer Clk */
\r
886 /*! brief Return Frequency of CTimer functional Clock
\r
887 * return Frequency of CTimer functional Clock
\r
889 uint32_t CLOCK_GetCTimerClkFreq(uint32_t id)
\r
891 uint32_t freq = 0U;
\r
893 switch (SYSCON->CTIMERCLKSELX[id])
\r
896 freq = CLOCK_GetCoreSysClkFreq();
\r
899 freq = CLOCK_GetPll0OutFreq();
\r
902 freq = CLOCK_GetFroHfFreq();
\r
905 freq = CLOCK_GetFro1MFreq();
\r
908 freq = CLOCK_GetI2SMClkFreq();
\r
911 freq = CLOCK_GetOsc32KFreq();
\r
925 /* Get Systick Clk */
\r
926 /*! brief Return Frequency of SystickClock
\r
927 * return Frequency of Systick Clock
\r
929 uint32_t CLOCK_GetSystickClkFreq(uint32_t id)
\r
931 volatile uint32_t *pSystickClkDiv;
\r
932 pSystickClkDiv = &(SYSCON->SYSTICKCLKDIV0);
\r
933 uint32_t freq = 0U;
\r
935 switch (SYSCON->SYSTICKCLKSELX[id])
\r
938 freq = CLOCK_GetCoreSysClkFreq() / ((pSystickClkDiv[id] & 0xffU) + 1U);
\r
941 freq = CLOCK_GetFro1MFreq();
\r
944 freq = CLOCK_GetOsc32KFreq();
\r
958 /* Set FlexComm Clock */
\r
960 * brief Set the flexcomm output frequency.
\r
961 * param id : flexcomm instance id
\r
962 * freq : output frequency
\r
963 * return 0 : the frequency range is out of range.
\r
964 * 1 : switch successfully.
\r
966 uint32_t CLOCK_SetFlexCommClock(uint32_t id, uint32_t freq)
\r
968 uint32_t input = CLOCK_GetFlexCommClkFreq(id);
\r
971 if ((freq > 48000000UL) || (freq > input) || (input / freq >= 2UL))
\r
973 /* FRG output frequency should be less than equal to 48MHz */
\r
978 mul = (uint32_t)((((uint64_t)input - freq) * 256ULL) / ((uint64_t)freq));
\r
979 SYSCON->FLEXFRGXCTRL[id] = (mul << 8U) | 0xFFU;
\r
985 /*! brief Return Frequency of selected clock
\r
986 * return Frequency of selected clock
\r
988 uint32_t CLOCK_GetFreq(clock_name_t clockName)
\r
993 case kCLOCK_CoreSysClk:
\r
994 freq = CLOCK_GetCoreSysClkFreq();
\r
996 case kCLOCK_BusClk:
\r
997 freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->AHBCLKDIV & 0xffU) + 1U);
\r
999 case kCLOCK_ClockOut:
\r
1000 freq = CLOCK_GetClockOutClkFreq();
\r
1002 case kCLOCK_Pll1Out:
\r
1003 freq = CLOCK_GetPll1OutFreq();
\r
1006 freq = CLOCK_GetMclkClkFreq();
\r
1008 case kCLOCK_FroHf:
\r
1009 freq = CLOCK_GetFroHfFreq();
\r
1011 case kCLOCK_Fro12M:
\r
1012 freq = CLOCK_GetFro12MFreq();
\r
1014 case kCLOCK_ExtClk:
\r
1015 freq = CLOCK_GetExtClkFreq();
\r
1017 case kCLOCK_Pll0Out:
\r
1018 freq = CLOCK_GetPll0OutFreq();
\r
1020 case kCLOCK_FlexI2S:
\r
1021 freq = CLOCK_GetI2SMClkFreq();
\r
1030 /* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */
\r
1031 static void pllFindSel(uint32_t M, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR)
\r
1033 uint32_t seli, selp;
\r
1034 /* bandwidth: compute selP from Multiplier */
\r
1035 if ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_MDIV_EXT_MASK) != 0UL) /* normal mode */
\r
1037 selp = (M >> 2U) + 1U;
\r
1048 else if (M >= 122UL)
\r
1050 seli = (uint32_t)(8000UL / M); /*floor(8000/M) */
\r
1054 seli = 2UL * ((uint32_t)(M / 4UL)) + 3UL; /* 2*floor(M/4) + 3 */
\r
1067 /* Note: If the spread spectrum mode, choose N to ensure 3 MHz < Fin/N < 5 MHz */
\r
1074 /* Get predivider (N) from PLL0 NDEC setting */
\r
1075 static uint32_t findPll0PreDiv(void)
\r
1077 uint32_t preDiv = 1UL;
\r
1079 /* Direct input is not used? */
\r
1080 if ((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_BYPASSPREDIV_MASK) == 0UL)
\r
1082 preDiv = SYSCON->PLL0NDEC & SYSCON_PLL0NDEC_NDIV_MASK;
\r
1083 if (preDiv == 0UL)
\r
1091 /* Get predivider (N) from PLL1 NDEC setting */
\r
1092 static uint32_t findPll1PreDiv(void)
\r
1094 uint32_t preDiv = 1UL;
\r
1096 /* Direct input is not used? */
\r
1097 if ((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_BYPASSPREDIV_MASK) == 0UL)
\r
1099 preDiv = SYSCON->PLL1NDEC & SYSCON_PLL1NDEC_NDIV_MASK;
\r
1100 if (preDiv == 0UL)
\r
1108 /* Get postdivider (P) from PLL0 PDEC setting */
\r
1109 static uint32_t findPll0PostDiv(void)
\r
1111 uint32_t postDiv = 1UL;
\r
1113 if ((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_BYPASSPOSTDIV_MASK) == 0UL)
\r
1115 if ((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_BYPASSPOSTDIV2_MASK) != 0UL)
\r
1117 postDiv = SYSCON->PLL0PDEC & SYSCON_PLL0PDEC_PDIV_MASK;
\r
1121 postDiv = 2UL * (SYSCON->PLL0PDEC & SYSCON_PLL0PDEC_PDIV_MASK);
\r
1123 if (postDiv == 0UL)
\r
1131 /* Get multiplier (M) from PLL0 SSCG and SEL_EXT settings */
\r
1132 static float findPll0MMult(void)
\r
1134 float mMult = 1.0F;
\r
1135 float mMult_fract;
\r
1136 uint32_t mMult_int;
\r
1138 if ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_SEL_EXT_MASK) != 0UL)
\r
1141 (float)(uint32_t)((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_MDIV_EXT_MASK) >> SYSCON_PLL0SSCG1_MDIV_EXT_SHIFT);
\r
1145 mMult_int = ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_MD_MBS_MASK) << 7U);
\r
1146 mMult_int = mMult_int | ((SYSCON->PLL0SSCG0) >> PLL0_SSCG_MD_INT_P);
\r
1147 mMult_fract = ((float)(uint32_t)((SYSCON->PLL0SSCG0) & PLL0_SSCG_MD_FRACT_M) /
\r
1148 (float)(uint32_t)(1UL << PLL0_SSCG_MD_INT_P));
\r
1149 mMult = (float)mMult_int + mMult_fract;
\r
1151 if (mMult == 0.0F)
\r
1158 /* Find greatest common divisor between m and n */
\r
1159 static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n)
\r
1174 * Set PLL0 output based on desired output rate.
\r
1175 * In this function, the it calculates the PLL0 setting for output frequency from input clock
\r
1176 * frequency. The calculation would cost a few time. So it is not recommaned to use it frequently.
\r
1177 * the "pllctrl", "pllndec", "pllpdec", "pllmdec" would updated in this function.
\r
1179 static pll_error_t CLOCK_GetPll0ConfigInternal(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useSS)
\r
1181 uint32_t nDivOutHz, fccoHz;
\r
1182 uint32_t pllPreDivider, pllMultiplier, pllPostDivider;
\r
1183 uint32_t pllDirectInput, pllDirectOutput;
\r
1184 uint32_t pllSelP, pllSelI, pllSelR, uplimoff;
\r
1186 /* Baseline parameters (no input or output dividers) */
\r
1187 pllPreDivider = 1U; /* 1 implies pre-divider will be disabled */
\r
1188 pllPostDivider = 1U; /* 1 implies post-divider will be disabled */
\r
1189 pllDirectOutput = 1U;
\r
1191 /* Verify output rate parameter */
\r
1192 if (foutHz > PLL_MAX_CCO_FREQ_MHZ)
\r
1194 /* Maximum PLL output with post divider=1 cannot go above this frequency */
\r
1195 return kStatus_PLL_OutputTooHigh;
\r
1197 if (foutHz < (PLL_MIN_CCO_FREQ_MHZ / (PVALMAX << 1U)))
\r
1199 /* Minmum PLL output with maximum post divider cannot go below this frequency */
\r
1200 return kStatus_PLL_OutputTooLow;
\r
1203 /* If using SS mode, input clock needs to be between 3MHz and 20MHz */
\r
1206 /* Verify input rate parameter */
\r
1207 if (finHz < PLL_MIN_IN_SSMODE)
\r
1209 /* Input clock into the PLL cannot be lower than this */
\r
1210 return kStatus_PLL_InputTooLow;
\r
1212 /* PLL input in SS mode must be under 20MHz */
\r
1213 if (finHz > (PLL_MAX_IN_SSMODE * NVALMAX))
\r
1215 return kStatus_PLL_InputTooHigh;
\r
1220 /* Verify input rate parameter */
\r
1221 if (finHz < PLL_LOWER_IN_LIMIT)
\r
1223 /* Input clock into the PLL cannot be lower than this */
\r
1224 return kStatus_PLL_InputTooLow;
\r
1226 if (finHz > PLL_HIGHER_IN_LIMIT)
\r
1228 /* Input clock into the PLL cannot be higher than this */
\r
1229 return kStatus_PLL_InputTooHigh;
\r
1233 /* Find the optimal CCO frequency for the output and input that
\r
1234 will keep it inside the PLL CCO range. This may require
\r
1235 tweaking the post-divider for the PLL. */
\r
1237 while (fccoHz < PLL_MIN_CCO_FREQ_MHZ)
\r
1239 /* CCO output is less than minimum CCO range, so the CCO output
\r
1240 needs to be bumped up and the post-divider is used to bring
\r
1241 the PLL output back down. */
\r
1243 if (pllPostDivider > PVALMAX)
\r
1245 return kStatus_PLL_OutsideIntLimit;
\r
1248 /* Target CCO goes up, PLL output goes down */
\r
1249 /* divide-by-2 divider in the post-divider is always work*/
\r
1250 fccoHz = foutHz * (pllPostDivider * 2U);
\r
1251 pllDirectOutput = 0U;
\r
1254 /* Determine if a pre-divider is needed to get the best frequency */
\r
1255 if ((finHz > PLL_LOWER_IN_LIMIT) && (fccoHz >= finHz) && (useSS == false))
\r
1257 uint32_t a = FindGreatestCommonDivisor(fccoHz, finHz);
\r
1259 if (a > PLL_LOWER_IN_LIMIT)
\r
1262 if ((a != 0U) && (a < PLL_MAX_N_DIV))
\r
1264 pllPreDivider = a;
\r
1269 /* Bypass pre-divider hardware if pre-divider is 1 */
\r
1270 if (pllPreDivider > 1U)
\r
1272 pllDirectInput = 0U;
\r
1276 pllDirectInput = 1U;
\r
1279 /* Determine PLL multipler */
\r
1280 nDivOutHz = (finHz / pllPreDivider);
\r
1281 pllMultiplier = (fccoHz / nDivOutHz);
\r
1283 /* Find optimal values for filter */
\r
1284 if (useSS == false)
\r
1286 /* Will bumping up M by 1 get us closer to the desired CCO frequency? */
\r
1287 if ((nDivOutHz * ((pllMultiplier * 2U) + 1U)) < (fccoHz * 2U))
\r
1292 /* Setup filtering */
\r
1293 pllFindSel(pllMultiplier, &pllSelP, &pllSelI, &pllSelR);
\r
1296 /* Get encoded value for M (mult) and use manual filter, disable SS mode */
\r
1297 pSetup->pllsscg[1] =
\r
1298 (uint32_t)((PLL_SSCG1_MDEC_VAL_SET(pllMultiplier)) | (1UL << SYSCON_PLL0SSCG1_SEL_EXT_SHIFT));
\r
1304 /* Filtering will be handled by SSC */
\r
1310 /* The PLL multiplier will get very close and slightly under the
\r
1311 desired target frequency. A small fractional component can be
\r
1312 added to fine tune the frequency upwards to the target. */
\r
1313 fc = (((uint64_t)fccoHz % (uint64_t)nDivOutHz) << 25U) / nDivOutHz;
\r
1315 /* Set multiplier */
\r
1316 pSetup->pllsscg[0] = (uint32_t)(PLL0_SSCG_MD_INT_SET(pllMultiplier) | PLL0_SSCG_MD_FRACT_SET((uint32_t)fc));
\r
1317 pSetup->pllsscg[1] = (uint32_t)(PLL0_SSCG_MD_INT_SET(pllMultiplier) >> 32U);
\r
1320 /* Get encoded values for N (prediv) and P (postdiv) */
\r
1321 pSetup->pllndec = PLL_NDEC_VAL_SET(pllPreDivider);
\r
1322 pSetup->pllpdec = PLL_PDEC_VAL_SET(pllPostDivider);
\r
1325 pSetup->pllctrl = (pllSelR << SYSCON_PLL0CTRL_SELR_SHIFT) | /* Filter coefficient */
\r
1326 (pllSelI << SYSCON_PLL0CTRL_SELI_SHIFT) | /* Filter coefficient */
\r
1327 (pllSelP << SYSCON_PLL0CTRL_SELP_SHIFT) | /* Filter coefficient */
\r
1328 (0UL << SYSCON_PLL0CTRL_BYPASSPLL_SHIFT) | /* PLL bypass mode disabled */
\r
1329 (uplimoff << SYSCON_PLL0CTRL_LIMUPOFF_SHIFT) | /* SS/fractional mode disabled */
\r
1330 (pllDirectInput << SYSCON_PLL0CTRL_BYPASSPREDIV_SHIFT) | /* Bypass pre-divider? */
\r
1331 (pllDirectOutput << SYSCON_PLL0CTRL_BYPASSPOSTDIV_SHIFT) | /* Bypass post-divider? */
\r
1332 (1UL << SYSCON_PLL0CTRL_CLKEN_SHIFT); /* Ensure the PLL clock output */
\r
1334 return kStatus_PLL_Success;
\r
1337 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
\r
1338 /* Alloct the static buffer for cache. */
\r
1339 static pll_setup_t s_PllSetupCacheStruct[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT];
\r
1340 static uint32_t s_FinHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0};
\r
1341 static uint32_t s_FoutHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0};
\r
1342 static bool s_UseSSCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {false};
\r
1343 static uint32_t s_PllSetupCacheIdx = 0U;
\r
1344 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
\r
1347 * Calculate the PLL setting values from input clock freq to output freq.
\r
1349 static pll_error_t CLOCK_GetPll0Config(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useSS)
\r
1351 pll_error_t retErr;
\r
1352 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
\r
1355 for (i = 0U; i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT; i++)
\r
1357 if ((finHz == s_FinHzCache[i]) && (foutHz == s_FoutHzCache[i]) && (useSS == s_UseSSCache[i]))
\r
1359 /* Hit the target in cache buffer. */
\r
1360 pSetup->pllctrl = s_PllSetupCacheStruct[i].pllctrl;
\r
1361 pSetup->pllndec = s_PllSetupCacheStruct[i].pllndec;
\r
1362 pSetup->pllpdec = s_PllSetupCacheStruct[i].pllpdec;
\r
1363 pSetup->pllsscg[0] = s_PllSetupCacheStruct[i].pllsscg[0];
\r
1364 pSetup->pllsscg[1] = s_PllSetupCacheStruct[i].pllsscg[1];
\r
1365 retErr = kStatus_PLL_Success;
\r
1370 if (i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
\r
1374 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
\r
1376 retErr = CLOCK_GetPll0ConfigInternal(finHz, foutHz, pSetup, useSS);
\r
1378 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
\r
1379 /* Cache the most recent calulation result into buffer. */
\r
1380 s_FinHzCache[s_PllSetupCacheIdx] = finHz;
\r
1381 s_FoutHzCache[s_PllSetupCacheIdx] = foutHz;
\r
1382 s_UseSSCache[s_PllSetupCacheIdx] = useSS;
\r
1384 s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllctrl = pSetup->pllctrl;
\r
1385 s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllndec = pSetup->pllndec;
\r
1386 s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllpdec = pSetup->pllpdec;
\r
1387 s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllsscg[0] = pSetup->pllsscg[0];
\r
1388 s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllsscg[1] = pSetup->pllsscg[1];
\r
1389 /* Update the index for next available buffer. */
\r
1390 s_PllSetupCacheIdx = (s_PllSetupCacheIdx + 1U) % CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT;
\r
1391 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
\r
1396 /* Update local PLL rate variable */
\r
1397 static void CLOCK_GetPLL0OutFromSetupUpdate(pll_setup_t *pSetup)
\r
1399 s_Pll0_Freq = CLOCK_GetPLL0OutFromSetup(pSetup);
\r
1402 /* Return System PLL input clock rate */
\r
1403 /*! brief Return PLL0 input clock rate
\r
1404 * return PLL0 input clock rate
\r
1406 uint32_t CLOCK_GetPLL0InClockRate(void)
\r
1408 uint32_t clkRate = 0U;
\r
1410 switch ((SYSCON->PLL0CLKSEL & SYSCON_PLL0CLKSEL_SEL_MASK))
\r
1413 clkRate = CLK_FRO_12MHZ;
\r
1417 clkRate = CLOCK_GetExtClkFreq();
\r
1421 clkRate = CLOCK_GetFro1MFreq();
\r
1425 clkRate = CLOCK_GetOsc32KFreq();
\r
1436 /* Return PLL1 input clock rate */
\r
1437 uint32_t CLOCK_GetPLL1InClockRate(void)
\r
1439 uint32_t clkRate = 0U;
\r
1441 switch ((SYSCON->PLL1CLKSEL & SYSCON_PLL1CLKSEL_SEL_MASK))
\r
1444 clkRate = CLK_FRO_12MHZ;
\r
1448 clkRate = CLOCK_GetExtClkFreq();
\r
1452 clkRate = CLOCK_GetFro1MFreq();
\r
1456 clkRate = CLOCK_GetOsc32KFreq();
\r
1467 /* Return PLL0 output clock rate from setup structure */
\r
1468 /*! brief Return PLL0 output clock rate from setup structure
\r
1469 * param pSetup : Pointer to a PLL setup structure
\r
1470 * return PLL0 output clock rate the setup structure will generate
\r
1472 uint32_t CLOCK_GetPLL0OutFromSetup(pll_setup_t *pSetup)
\r
1474 uint32_t clkRate = 0;
\r
1475 uint32_t prediv, postdiv;
\r
1476 float workRate = 0.0F;
\r
1478 /* Get the input clock frequency of PLL. */
\r
1479 clkRate = CLOCK_GetPLL0InClockRate();
\r
1481 if (((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_BYPASSPLL_MASK) == 0UL) &&
\r
1482 ((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_CLKEN_MASK) != 0UL) &&
\r
1483 ((PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_PLL0_MASK) == 0UL) &&
\r
1484 ((PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_PLL0_SSCG_MASK) == 0UL))
\r
1486 prediv = findPll0PreDiv();
\r
1487 postdiv = findPll0PostDiv();
\r
1488 /* Adjust input clock */
\r
1489 clkRate = clkRate / prediv;
\r
1490 /* MDEC used for rate */
\r
1491 workRate = (float)clkRate * (float)findPll0MMult();
\r
1492 workRate /= (float)postdiv;
\r
1495 return (uint32_t)workRate;
\r
1498 /* Set the current PLL0 Rate */
\r
1499 /*! brief Store the current PLL rate
\r
1500 * param rate: Current rate of the PLL
\r
1503 void CLOCK_SetStoredPLL0ClockRate(uint32_t rate)
\r
1505 s_Pll0_Freq = rate;
\r
1508 /* Return PLL0 output clock rate */
\r
1509 /*! brief Return PLL0 output clock rate
\r
1510 * param recompute : Forces a PLL rate recomputation if true
\r
1511 * return PLL0 output clock rate
\r
1512 * note The PLL rate is cached in the driver in a variable as
\r
1513 * the rate computation function can take some time to perform. It
\r
1514 * is recommended to use 'false' with the 'recompute' parameter.
\r
1516 uint32_t CLOCK_GetPLL0OutClockRate(bool recompute)
\r
1518 pll_setup_t Setup;
\r
1521 if ((recompute) || (s_Pll0_Freq == 0U))
\r
1523 Setup.pllctrl = SYSCON->PLL0CTRL;
\r
1524 Setup.pllndec = SYSCON->PLL0NDEC;
\r
1525 Setup.pllpdec = SYSCON->PLL0PDEC;
\r
1526 Setup.pllsscg[0] = SYSCON->PLL0SSCG0;
\r
1527 Setup.pllsscg[1] = SYSCON->PLL0SSCG1;
\r
1529 CLOCK_GetPLL0OutFromSetupUpdate(&Setup);
\r
1532 rate = s_Pll0_Freq;
\r
1537 /* Set PLL0 output based on the passed PLL setup data */
\r
1538 /*! brief Set PLL output based on the passed PLL setup data
\r
1539 * param pControl : Pointer to populated PLL control structure to generate setup with
\r
1540 * param pSetup : Pointer to PLL setup structure to be filled
\r
1541 * return PLL_ERROR_SUCCESS on success, or PLL setup error code
\r
1542 * note Actual frequency for setup may vary from the desired frequency based on the
\r
1543 * accuracy of input clocks, rounding, non-fractional PLL mode, etc.
\r
1545 pll_error_t CLOCK_SetupPLL0Data(pll_config_t *pControl, pll_setup_t *pSetup)
\r
1548 bool useSS = ((pControl->flags & PLL_CONFIGFLAG_FORCENOFRACT) == 0U);
\r
1550 pll_error_t pllError;
\r
1552 /* Determine input rate for the PLL */
\r
1553 if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0U)
\r
1555 inRate = pControl->inputRate;
\r
1559 inRate = CLOCK_GetPLL0InClockRate();
\r
1562 /* PLL flag options */
\r
1563 pllError = CLOCK_GetPll0Config(inRate, pControl->desiredRate, pSetup, useSS);
\r
1564 if ((useSS) && (pllError == kStatus_PLL_Success))
\r
1566 /* If using SS mode, then some tweaks are made to the generated setup */
\r
1567 pSetup->pllsscg[1] |= (uint32_t)pControl->ss_mf | (uint32_t)pControl->ss_mr | (uint32_t)pControl->ss_mc;
\r
1568 if (pControl->mfDither)
\r
1570 pSetup->pllsscg[1] |= (1UL << SYSCON_PLL0SSCG1_DITHER_SHIFT);
\r
1577 /* Set PLL0 output from PLL setup structure */
\r
1578 /*! brief Set PLL output from PLL setup structure (precise frequency)
\r
1579 * param pSetup : Pointer to populated PLL setup structure
\r
1580 * param flagcfg : Flag configuration for PLL config structure
\r
1581 * return PLL_ERROR_SUCCESS on success, or PLL setup error code
\r
1582 * note This function will power off the PLL, setup the PLL with the
\r
1583 * new setup data, and then optionally powerup the PLL, wait for PLL lock,
\r
1584 * and adjust system voltages to the new PLL rate. The function will not
\r
1585 * alter any source clocks (ie, main systen clock) that may use the PLL,
\r
1586 * so these should be setup prior to and after exiting the function.
\r
1588 pll_error_t CLOCK_SetupPLL0Prec(pll_setup_t *pSetup, uint32_t flagcfg)
\r
1590 uint32_t inRate, clkRate, prediv;
\r
1592 /* Power off PLL during setup changes */
\r
1593 POWER_EnablePD(kPDRUNCFG_PD_PLL0);
\r
1594 POWER_EnablePD(kPDRUNCFG_PD_PLL0_SSCG);
\r
1596 pSetup->flags = flagcfg;
\r
1598 /* Write PLL setup data */
\r
1599 SYSCON->PLL0CTRL = pSetup->pllctrl;
\r
1600 SYSCON->PLL0NDEC = pSetup->pllndec;
\r
1601 SYSCON->PLL0NDEC = pSetup->pllndec | (1UL << SYSCON_PLL0NDEC_NREQ_SHIFT); /* latch */
\r
1602 SYSCON->PLL0PDEC = pSetup->pllpdec;
\r
1603 SYSCON->PLL0PDEC = pSetup->pllpdec | (1UL << SYSCON_PLL0PDEC_PREQ_SHIFT); /* latch */
\r
1604 SYSCON->PLL0SSCG0 = pSetup->pllsscg[0];
\r
1605 SYSCON->PLL0SSCG1 = pSetup->pllsscg[1];
\r
1606 SYSCON->PLL0SSCG1 =
\r
1607 pSetup->pllsscg[1] | (1UL << SYSCON_PLL0SSCG1_MREQ_SHIFT) | (1UL << SYSCON_PLL0SSCG1_MD_REQ_SHIFT); /* latch */
\r
1609 POWER_DisablePD(kPDRUNCFG_PD_PLL0);
\r
1610 POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG);
\r
1612 if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
\r
1614 if ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_MDIV_EXT_MASK) != 0UL) /* normal mode */
\r
1616 inRate = CLOCK_GetPLL0InClockRate();
\r
1617 prediv = findPll0PreDiv();
\r
1618 /* Adjust input clock */
\r
1619 clkRate = inRate / prediv;
\r
1620 /* The lock signal is only reliable between fref[2] :100 kHz to 20 MHz. */
\r
1621 if ((clkRate >= 100000UL) && (clkRate <= 20000000UL))
\r
1623 while (CLOCK_IsPLL0Locked() == false)
\r
1629 SDK_DelayAtLeastUs(6000U,
\r
1630 SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); /* software should use a 6 ms time interval
\r
1631 to insure the PLL will be stable */
\r
1634 else /* spread spectrum mode */
\r
1636 SDK_DelayAtLeastUs(6000U,
\r
1637 SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); /* software should use a 6 ms time interval to
\r
1638 insure the PLL will be stable */
\r
1642 /* Update current programmed PLL rate var */
\r
1643 CLOCK_GetPLL0OutFromSetupUpdate(pSetup);
\r
1645 /* System voltage adjustment, occurs prior to setting main system clock */
\r
1646 if ((pSetup->flags & PLL_SETUPFLAG_ADGVOLT) != 0U)
\r
1648 POWER_SetVoltageForFreq(s_Pll0_Freq);
\r
1651 return kStatus_PLL_Success;
\r
1654 /* Setup PLL Frequency from pre-calculated value */
\r
1656 * brief Set PLL0 output from PLL setup structure (precise frequency)
\r
1657 * param pSetup : Pointer to populated PLL setup structure
\r
1658 * return kStatus_PLL_Success on success, or PLL setup error code
\r
1659 * note This function will power off the PLL, setup the PLL with the
\r
1660 * new setup data, and then optionally powerup the PLL, wait for PLL lock,
\r
1661 * and adjust system voltages to the new PLL rate. The function will not
\r
1662 * alter any source clocks (ie, main systen clock) that may use the PLL,
\r
1663 * so these should be setup prior to and after exiting the function.
\r
1665 pll_error_t CLOCK_SetPLL0Freq(const pll_setup_t *pSetup)
\r
1667 uint32_t inRate, clkRate, prediv;
\r
1668 /* Power off PLL during setup changes */
\r
1669 POWER_EnablePD(kPDRUNCFG_PD_PLL0);
\r
1670 POWER_EnablePD(kPDRUNCFG_PD_PLL0_SSCG);
\r
1672 /* Write PLL setup data */
\r
1673 SYSCON->PLL0CTRL = pSetup->pllctrl;
\r
1674 SYSCON->PLL0NDEC = pSetup->pllndec;
\r
1675 SYSCON->PLL0NDEC = pSetup->pllndec | (1UL << SYSCON_PLL0NDEC_NREQ_SHIFT); /* latch */
\r
1676 SYSCON->PLL0PDEC = pSetup->pllpdec;
\r
1677 SYSCON->PLL0PDEC = pSetup->pllpdec | (1UL << SYSCON_PLL0PDEC_PREQ_SHIFT); /* latch */
\r
1678 SYSCON->PLL0SSCG0 = pSetup->pllsscg[0];
\r
1679 SYSCON->PLL0SSCG1 = pSetup->pllsscg[1];
\r
1680 SYSCON->PLL0SSCG1 =
\r
1681 pSetup->pllsscg[1] | (1UL << SYSCON_PLL0SSCG1_MD_REQ_SHIFT) | (1UL << SYSCON_PLL0SSCG1_MREQ_SHIFT); /* latch */
\r
1683 POWER_DisablePD(kPDRUNCFG_PD_PLL0);
\r
1684 POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG);
\r
1686 if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
\r
1688 if ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_MDIV_EXT_MASK) != 0UL) /* normal mode */
\r
1690 inRate = CLOCK_GetPLL0InClockRate();
\r
1691 prediv = findPll0PreDiv();
\r
1692 /* Adjust input clock */
\r
1693 clkRate = inRate / prediv;
\r
1694 /* The lock signal is only reliable between fref[2] :100 kHz to 20 MHz. */
\r
1695 if ((clkRate >= 100000UL) && (clkRate <= 20000000UL))
\r
1697 while (CLOCK_IsPLL0Locked() == false)
\r
1703 SDK_DelayAtLeastUs(6000U,
\r
1704 SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); /* software should use a 6 ms time interval
\r
1705 to insure the PLL will be stable */
\r
1708 else /* spread spectrum mode */
\r
1710 SDK_DelayAtLeastUs(6000U,
\r
1711 SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); /* software should use a 6 ms time interval to
\r
1712 insure the PLL will be stable */
\r
1716 /* Update current programmed PLL rate var */
\r
1717 s_Pll0_Freq = pSetup->pllRate;
\r
1719 return kStatus_PLL_Success;
\r
1722 /* Setup PLL1 Frequency from pre-calculated value */
\r
1724 * brief Set PLL1 output from PLL setup structure (precise frequency)
\r
1725 * param pSetup : Pointer to populated PLL setup structure
\r
1726 * return kStatus_PLL_Success on success, or PLL setup error code
\r
1727 * note This function will power off the PLL, setup the PLL with the
\r
1728 * new setup data, and then optionally powerup the PLL, wait for PLL lock,
\r
1729 * and adjust system voltages to the new PLL rate. The function will not
\r
1730 * alter any source clocks (ie, main systen clock) that may use the PLL,
\r
1731 * so these should be setup prior to and after exiting the function.
\r
1733 pll_error_t CLOCK_SetPLL1Freq(const pll_setup_t *pSetup)
\r
1735 uint32_t inRate, clkRate, prediv;
\r
1736 /* Power off PLL during setup changes */
\r
1737 POWER_EnablePD(kPDRUNCFG_PD_PLL1);
\r
1739 /* Write PLL setup data */
\r
1740 SYSCON->PLL1CTRL = pSetup->pllctrl;
\r
1741 SYSCON->PLL1NDEC = pSetup->pllndec;
\r
1742 SYSCON->PLL1NDEC = pSetup->pllndec | (1UL << SYSCON_PLL1NDEC_NREQ_SHIFT); /* latch */
\r
1743 SYSCON->PLL1PDEC = pSetup->pllpdec;
\r
1744 SYSCON->PLL1PDEC = pSetup->pllpdec | (1UL << SYSCON_PLL1PDEC_PREQ_SHIFT); /* latch */
\r
1745 SYSCON->PLL1MDEC = pSetup->pllmdec;
\r
1746 SYSCON->PLL1MDEC = pSetup->pllmdec | (1UL << SYSCON_PLL1MDEC_MREQ_SHIFT); /* latch */
\r
1748 POWER_DisablePD(kPDRUNCFG_PD_PLL1);
\r
1750 if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
\r
1752 inRate = CLOCK_GetPLL1InClockRate();
\r
1753 prediv = findPll1PreDiv();
\r
1754 /* Adjust input clock */
\r
1755 clkRate = inRate / prediv;
\r
1756 /* The lock signal is only reliable between fref[2] :100 kHz to 20 MHz. */
\r
1757 if ((clkRate >= 100000UL) && (clkRate <= 20000000UL))
\r
1759 while (CLOCK_IsPLL1Locked() == false)
\r
1765 SDK_DelayAtLeastUs(6000U,
\r
1766 SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); /* software should use a 6 ms time interval to
\r
1767 insure the PLL will be stable */
\r
1771 /* Update current programmed PLL rate var */
\r
1772 s_Pll0_Freq = pSetup->pllRate;
\r
1774 return kStatus_PLL_Success;
\r
1777 /* Set PLL0 clock based on the input frequency and multiplier */
\r
1778 /*! brief Set PLL0 output based on the multiplier and input frequency
\r
1779 * param multiply_by : multiplier
\r
1780 * param input_freq : Clock input frequency of the PLL
\r
1782 * note Unlike the Chip_Clock_SetupSystemPLLPrec() function, this
\r
1783 * function does not disable or enable PLL power, wait for PLL lock,
\r
1784 * or adjust system voltages. These must be done in the application.
\r
1785 * The function will not alter any source clocks (ie, main systen clock)
\r
1786 * that may use the PLL, so these should be setup prior to and after
\r
1787 * exiting the function.
\r
1789 void CLOCK_SetupPLL0Mult(uint32_t multiply_by, uint32_t input_freq)
\r
1791 uint32_t cco_freq = input_freq * multiply_by;
\r
1792 uint32_t pdec = 1U;
\r
1796 uint32_t mdec, ndec;
\r
1798 while (cco_freq < 275000000U)
\r
1800 multiply_by <<= 1U; /* double value in each iteration */
\r
1801 pdec <<= 1U; /* correspondingly double pdec to cancel effect of double msel */
\r
1802 cco_freq = input_freq * multiply_by;
\r
1807 if (multiply_by >= 8000UL)
\r
1811 else if (multiply_by >= 122UL)
\r
1813 seli = (uint32_t)(8000UL / multiply_by); /*floor(8000/M) */
\r
1817 seli = 2UL * ((uint32_t)(multiply_by / 4UL)) + 3UL; /* 2*floor(M/4) + 3 */
\r
1831 pdec = pdec / 2U; /* Account for minus 1 encoding */
\r
1832 /* Translate P value */
\r
1835 mdec = (uint32_t)PLL_SSCG1_MDEC_VAL_SET(multiply_by);
\r
1836 ndec = 0x1U; /* pre divide by 1 (hardcoded) */
\r
1838 SYSCON->PLL0CTRL = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_BYPASSPOSTDIV(0) |
\r
1839 SYSCON_PLL0CTRL_BYPASSPOSTDIV2(0) | (selr << SYSCON_PLL0CTRL_SELR_SHIFT) |
\r
1840 (seli << SYSCON_PLL0CTRL_SELI_SHIFT) | (selp << SYSCON_PLL0CTRL_SELP_SHIFT);
\r
1841 SYSCON->PLL0PDEC = pdec | (1UL << SYSCON_PLL0PDEC_PREQ_SHIFT); /* set Pdec value and assert preq */
\r
1842 SYSCON->PLL0NDEC = ndec | (1UL << SYSCON_PLL0NDEC_NREQ_SHIFT); /* set Pdec value and assert preq */
\r
1843 SYSCON->PLL0SSCG1 =
\r
1844 mdec | (1UL << SYSCON_PLL0SSCG1_MREQ_SHIFT); /* select non sscg MDEC value, assert mreq and select mdec value */
\r
1847 /* Enable USB DEVICE FULL SPEED clock */
\r
1848 /*! brief Enable USB Device FS clock.
\r
1849 * param src : clock source
\r
1850 * param freq: clock frequency
\r
1851 * Enable USB Device Full Speed clock.
\r
1853 bool CLOCK_EnableUsbfs0DeviceClock(clock_usbfs_src_t src, uint32_t freq)
\r
1857 CLOCK_DisableClock(kCLOCK_Usbd0);
\r
1859 if (kCLOCK_UsbfsSrcFro == src)
\r
1864 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
\r
1871 /* Turn ON FRO HF */
\r
1872 POWER_DisablePD(kPDRUNCFG_PD_FRO192M);
\r
1873 /* Enable FRO 96MHz output */
\r
1874 ANACTRL->FRO192M_CTRL = ANACTRL->FRO192M_CTRL | ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK;
\r
1875 /* Select FRO 96 or 48 MHz */
\r
1876 CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
\r
1880 /*!< Configure XTAL32M */
\r
1881 POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */
\r
1882 POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */
\r
1883 (void)CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */
\r
1884 SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */
\r
1885 ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */
\r
1887 /*!< Set up PLL1 */
\r
1888 POWER_DisablePD(kPDRUNCFG_PD_PLL1);
\r
1889 CLOCK_AttachClk(kEXT_CLK_to_PLL1); /*!< Switch PLL1CLKSEL to EXT_CLK */
\r
1890 const pll_setup_t pll1Setup = {
\r
1891 .pllctrl = SYSCON_PLL1CTRL_CLKEN_MASK | SYSCON_PLL1CTRL_SELI(19U) | SYSCON_PLL1CTRL_SELP(9U),
\r
1892 .pllndec = SYSCON_PLL1NDEC_NDIV(1U),
\r
1893 .pllpdec = SYSCON_PLL1PDEC_PDIV(5U),
\r
1894 .pllmdec = SYSCON_PLL1MDEC_MDIV(30U),
\r
1895 .pllRate = 48000000U,
\r
1896 .flags = PLL_SETUPFLAG_WAITLOCK};
\r
1897 (void)CLOCK_SetPLL1Freq(&pll1Setup);
\r
1899 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
\r
1900 CLOCK_AttachClk(kPLL1_to_USB0_CLK);
\r
1901 SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
\r
1903 CLOCK_EnableClock(kCLOCK_Usbd0);
\r
1904 CLOCK_EnableClock(kCLOCK_UsbRam1);
\r
1909 /* Enable USB HOST FULL SPEED clock */
\r
1910 /*! brief Enable USB HOST FS clock.
\r
1911 * param src : clock source
\r
1912 * param freq: clock frequency
\r
1913 * Enable USB HOST Full Speed clock.
\r
1915 bool CLOCK_EnableUsbfs0HostClock(clock_usbfs_src_t src, uint32_t freq)
\r
1919 CLOCK_DisableClock(kCLOCK_Usbhmr0);
\r
1920 CLOCK_DisableClock(kCLOCK_Usbhsl0);
\r
1922 if (kCLOCK_UsbfsSrcFro == src)
\r
1927 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
\r
1934 /* Turn ON FRO HF */
\r
1935 POWER_DisablePD(kPDRUNCFG_PD_FRO192M);
\r
1936 /* Enable FRO 96MHz output */
\r
1937 ANACTRL->FRO192M_CTRL = ANACTRL->FRO192M_CTRL | ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK;
\r
1938 /* Select FRO 96 MHz */
\r
1939 CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
\r
1943 /*!< Configure XTAL32M */
\r
1944 POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */
\r
1945 POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */
\r
1946 (void)CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */
\r
1947 SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */
\r
1948 ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */
\r
1950 /*!< Set up PLL1 */
\r
1951 POWER_DisablePD(kPDRUNCFG_PD_PLL1);
\r
1952 CLOCK_AttachClk(kEXT_CLK_to_PLL1); /*!< Switch PLL1CLKSEL to EXT_CLK */
\r
1953 const pll_setup_t pll1Setup = {
\r
1954 .pllctrl = SYSCON_PLL1CTRL_CLKEN_MASK | SYSCON_PLL1CTRL_SELI(19U) | SYSCON_PLL1CTRL_SELP(9U),
\r
1955 .pllndec = SYSCON_PLL1NDEC_NDIV(1U),
\r
1956 .pllpdec = SYSCON_PLL1PDEC_PDIV(5U),
\r
1957 .pllmdec = SYSCON_PLL1MDEC_MDIV(30U),
\r
1958 .pllRate = 48000000U,
\r
1959 .flags = PLL_SETUPFLAG_WAITLOCK};
\r
1960 (void)CLOCK_SetPLL1Freq(&pll1Setup);
\r
1962 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
\r
1963 CLOCK_AttachClk(kPLL1_to_USB0_CLK);
\r
1964 SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
\r
1966 CLOCK_EnableClock(kCLOCK_Usbhmr0);
\r
1967 CLOCK_EnableClock(kCLOCK_Usbhsl0);
\r
1968 CLOCK_EnableClock(kCLOCK_UsbRam1);
\r
1973 /* Enable USB PHY clock */
\r
1974 bool CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src, uint32_t freq)
\r
1976 volatile uint32_t i;
\r
1978 POWER_DisablePD(kPDRUNCFG_PD_XTAL32M);
\r
1979 POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M);
\r
1980 POWER_DisablePD(kPDRUNCFG_PD_FRO32K); /*!< Ensure FRO32k is on */
\r
1981 POWER_DisablePD(kPDRUNCFG_PD_XTAL32K); /*!< Ensure xtal32k is on */
\r
1982 POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /*!< Ensure xtal32k is on */
\r
1983 POWER_DisablePD(kPDRUNCFG_PD_LDOUSBHS); /*!< Ensure xtal32k is on */
\r
1985 /* wait to make sure PHY power is fully up */
\r
1987 while ((i--) != 0U)
\r
1992 SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_ANALOG_CTRL(1);
\r
1993 SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_PHY(1);
\r
1995 USBPHY->CTRL_CLR = USBPHY_CTRL_SFTRST_MASK;
\r
1996 USBPHY->PLL_SIC = (USBPHY->PLL_SIC & ~USBPHY_PLL_SIC_PLL_DIV_SEL(0x7)) | USBPHY_PLL_SIC_PLL_DIV_SEL(0x06);
\r
1997 USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_SET_PLL_REG_ENABLE_MASK;
\r
1998 USBPHY->PLL_SIC_CLR = (1UL << 16U); // Reserved. User must set this bit to 0x0
\r
1999 USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_SET_PLL_POWER_MASK;
\r
2000 USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_SET_PLL_EN_USB_CLKS_MASK;
\r
2002 USBPHY->CTRL_CLR = USBPHY_CTRL_CLR_CLKGATE_MASK;
\r
2003 USBPHY->PWD_SET = 0x0;
\r
2008 /* Enable USB DEVICE HIGH SPEED clock */
\r
2009 bool CLOCK_EnableUsbhs0DeviceClock(clock_usbhs_src_t src, uint32_t freq)
\r
2011 SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_RAM(1);
\r
2012 SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_DEV(1);
\r
2014 /* 16 MHz will be driven by the tb on the xtal1 pin of XTAL32M */
\r
2015 SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clock_in clock for clock module. */
\r
2016 ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT(1);
\r
2020 /* Enable USB HOST HIGH SPEED clock */
\r
2021 bool CLOCK_EnableUsbhs0HostClock(clock_usbhs_src_t src, uint32_t freq)
\r
2023 SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_RAM(1);
\r
2024 SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_HOST(1);
\r
2026 /* 16 MHz will be driven by the tb on the xtal1 pin of XTAL32M */
\r
2027 SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clock_in clock for clock module. */
\r
2028 ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT(1);
\r