2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
\r
3 * Copyright 2016 - 2019 , NXP
\r
4 * All rights reserved.
\r
7 * SPDX-License-Identifier: BSD-3-Clause
\r
10 #include "fsl_clock.h"
\r
11 #include "fsl_power.h"
\r
12 /*******************************************************************************
\r
14 ******************************************************************************/
\r
15 /* Component ID definition, used by tools. */
\r
16 #ifndef FSL_COMPONENT_ID
\r
17 #define FSL_COMPONENT_ID "platform.drivers.clock"
\r
19 #define NVALMAX (0x100U)
\r
20 #define PVALMAX (0x20U)
\r
21 #define MVALMAX (0x8000U)
\r
23 #define USB_NVALMAX (0x4U)
\r
24 #define USB_PVALMAX (0x8U)
\r
25 #define USB_MVALMAX (0x100U)
\r
27 #define PLL_MAX_N_DIV 0x100U
\r
28 #define USB_PLL_MAX_N_DIV 0x100U
\r
30 #define PLL_MDEC_VAL_P (0U) /*!< MDEC is in bits 16 downto 0 */
\r
31 #define PLL_MDEC_VAL_M (0x1FFFFUL << PLL_MDEC_VAL_P) /*!< NDEC is in bits 9 downto 0 */
\r
32 #define PLL_NDEC_VAL_P (0U) /*!< NDEC is in bits 9:0 */
\r
33 #define PLL_NDEC_VAL_M (0x3FFUL << PLL_NDEC_VAL_P)
\r
34 #define PLL_PDEC_VAL_P (0U) /*!< PDEC is in bits 6:0 */
\r
35 #define PLL_PDEC_VAL_M (0x7FUL << PLL_PDEC_VAL_P)
\r
37 #define PLL_MIN_CCO_FREQ_MHZ (275000000U)
\r
38 #define PLL_MAX_CCO_FREQ_MHZ (550000000U)
\r
39 #define PLL_LOWER_IN_LIMIT (4000U) /*!< Minimum PLL input rate */
\r
40 #define PLL_MIN_IN_SSMODE (2000000U)
\r
41 #define PLL_MAX_IN_SSMODE (4000000U)
\r
43 /*!< Middle of the range values for spread-spectrum */
\r
44 #define PLL_SSCG_MF_FREQ_VALUE 4U
\r
45 #define PLL_SSCG_MC_COMP_VALUE 2U
\r
46 #define PLL_SSCG_MR_DEPTH_VALUE 4U
\r
47 #define PLL_SSCG_DITHER_VALUE 0U
\r
49 /*!< USB PLL CCO MAX AND MIN FREQ */
\r
50 #define USB_PLL_MIN_CCO_FREQ_MHZ (156000000U)
\r
51 #define USB_PLL_MAX_CCO_FREQ_MHZ (320000000U)
\r
52 #define USB_PLL_LOWER_IN_LIMIT (1000000U) /*!< Minimum PLL input rate */
\r
54 #define USB_PLL_MSEL_VAL_P (0U) /*!< MSEL is in bits 7 downto 0 */
\r
55 #define USB_PLL_MSEL_VAL_M (0xFFU)
\r
56 #define USB_PLL_PSEL_VAL_P (8U) /*!< PDEC is in bits 9:8 */
\r
57 #define USB_PLL_PSEL_VAL_M (0x3U)
\r
58 #define USB_PLL_NSEL_VAL_P (10U) /*!< NDEC is in bits 11:10 */
\r
59 #define USB_PLL_NSEL_VAL_M (0x3U)
\r
61 /*!< SWITCH USB POSTDIVIDER FOR REGITSER WRITING */
\r
62 #define SWITCH_USB_PSEL(x) \
\r
63 (((x) == 0x0U) ? 0x1U : ((x) == 0x1U) ? 0x02U : ((x) == 0x2U) ? 0x4U : ((x) == 3U) ? 0x8U : 0U)
\r
65 /*!< SYS PLL NDEC reg */
\r
66 #define PLL_NDEC_VAL_SET(value) (((unsigned long)(value) << PLL_NDEC_VAL_P) & PLL_NDEC_VAL_M)
\r
67 /*!< SYS PLL PDEC reg */
\r
68 #define PLL_PDEC_VAL_SET(value) (((unsigned long)(value) << PLL_PDEC_VAL_P) & PLL_PDEC_VAL_M)
\r
69 /*!< SYS PLL MDEC reg */
\r
70 #define PLL_MDEC_VAL_SET(value) (((unsigned long)(value) << PLL_MDEC_VAL_P) & PLL_MDEC_VAL_M)
\r
72 /*!< SYS PLL NSEL reg */
\r
73 #define USB_PLL_NSEL_VAL_SET(value) (((unsigned long)(value)&USB_PLL_NSEL_VAL_M) << USB_PLL_NSEL_VAL_P)
\r
74 /*!< SYS PLL PSEL reg */
\r
75 #define USB_PLL_PSEL_VAL_SET(value) (((unsigned long)(value)&USB_PLL_PSEL_VAL_M) << USB_PLL_PSEL_VAL_P)
\r
76 /*!< SYS PLL MSEL reg */
\r
77 #define USB_PLL_MSEL_VAL_SET(value) (((unsigned long)(value)&USB_PLL_MSEL_VAL_M) << USB_PLL_MSEL_VAL_P)
\r
79 /*!< FRAC control */
\r
80 #define AUDIO_PLL_FRACT_MD_P (0U)
\r
81 #define AUDIO_PLL_FRACT_MD_INT_P (15U)
\r
82 #define AUDIO_PLL_FRACT_MD_M (0x7FFFUL << AUDIO_PLL_FRACT_MD_P)
\r
83 #define AUDIO_PLL_FRACT_MD_INT_M (0x7FUL << AUDIO_PLL_FRACT_MD_INT_P)
\r
85 #define AUDIO_PLL_MD_FRACT_SET(value) (((unsigned long)(value) << AUDIO_PLL_FRACT_MD_P) & PLL_FRAC_MD_FRACT_M)
\r
86 #define AUDIO_PLL_MD_INT_SET(value) (((unsigned long)(value) << AUDIO_PLL_FRACT_MD_INT_P) & AUDIO_PLL_FRACT_MD_INT_M)
\r
88 /* Saved value of PLL output rate, computed whenever needed to save run-time
\r
89 computation on each call to retrive the PLL rate. */
\r
90 static uint32_t s_Pll_Freq;
\r
91 static uint32_t s_Usb_Pll_Freq;
\r
92 static uint32_t s_Audio_Pll_Freq;
\r
94 /** External clock rate on the CLKIN pin in Hz. If not used,
\r
95 set this to 0. Otherwise, set it to the exact rate in Hz this pin is
\r
97 static const uint32_t g_I2S_Mclk_Freq = 0U;
\r
98 static const uint32_t g_Ext_Clk_Freq = 12000000U;
\r
99 static const uint32_t g_Lcd_Clk_In_Freq = 0U;
\r
101 /*******************************************************************************
\r
103 ******************************************************************************/
\r
105 /*******************************************************************************
\r
107 ******************************************************************************/
\r
108 /* Find encoded NDEC value for raw N value, max N = NVALMAX */
\r
109 static uint32_t pllEncodeN(uint32_t N);
\r
110 /* Find decoded N value for raw NDEC value */
\r
111 static uint32_t pllDecodeN(uint32_t NDEC);
\r
112 /* Find encoded PDEC value for raw P value, max P = PVALMAX */
\r
113 static uint32_t pllEncodeP(uint32_t P);
\r
114 /* Find decoded P value for raw PDEC value */
\r
115 static uint32_t pllDecodeP(uint32_t PDEC);
\r
116 /* Find encoded MDEC value for raw M value, max M = MVALMAX */
\r
117 static uint32_t pllEncodeM(uint32_t M);
\r
118 /* Find decoded M value for raw MDEC value */
\r
119 static uint32_t pllDecodeM(uint32_t MDEC);
\r
120 /* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */
\r
121 static void pllFindSel(uint32_t M, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR);
\r
122 /* Get predivider (N) from PLL NDEC setting */
\r
123 static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg);
\r
124 /* Get postdivider (P) from PLL PDEC setting */
\r
125 static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg);
\r
126 /* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */
\r
127 static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg);
\r
128 /* Convert the binary to fractional part */
\r
129 static double Binary2Fractional(uint32_t binaryPart);
\r
130 /* Calculate the powerTimes' power of 2 */
\r
131 static uint32_t power2Cal(uint32_t powerTimes);
\r
132 /* Get the greatest common divisor */
\r
133 static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n);
\r
134 /* Set PLL output based on desired output rate */
\r
135 static pll_error_t CLOCK_GetPllConfig(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup);
\r
137 /* Update local PLL rate variable */
\r
138 static void CLOCK_GetSystemPLLOutFromSetupUpdate(pll_setup_t *pSetup);
\r
139 static void CLOCK_GetAudioPLLOutFromSetupUpdate(pll_setup_t *pSetup);
\r
142 * @brief Set fro clock frequency.
\r
143 * Due to LPC540xx 0A silicon and LPC540xx 1B silicon have different ROM addresses for set fro
\r
144 * frequency api, so add this api to get rom version.
\r
145 * @param base romVersion pointer to recieve rom version.
\r
147 #if defined(FSL_FROHF_SETTING_API_ADDRESS_DETERMINE_BY_ROM_VERSION) && \
\r
148 (FSL_FROHF_SETTING_API_ADDRESS_DETERMINE_BY_ROM_VERSION)
\r
149 static uint32_t CLOCK_GetRomVersion(uint8_t *romVersion);
\r
152 static const uint8_t wdtFreqLookup[32] = {0, 8, 12, 15, 18, 20, 24, 26, 28, 30, 32, 34, 36, 38, 40, 41,
\r
153 42, 44, 45, 46, 48, 49, 50, 52, 53, 54, 56, 57, 58, 59, 60, 61};
\r
154 /*******************************************************************************
\r
156 ******************************************************************************/
\r
157 #if defined(FSL_FROHF_SETTING_API_ADDRESS_DETERMINE_BY_ROM_VERSION) && \
\r
158 (FSL_FROHF_SETTING_API_ADDRESS_DETERMINE_BY_ROM_VERSION)
\r
159 static uint32_t CLOCK_GetRomVersion(uint8_t *romVersion)
\r
161 uint32_t command[5] = {0U}, result[4] = {0U};
\r
166 ((void (*)(uint32_t cmd[5], uint32_t stat[4]))FSL_FEATURE_SYSCON_IAP_ENTRY_LOCATION)(command, result);
\r
168 *romVersion = (uint8_t)(result[1]);
\r
176 * Initialize the Core clock to given frequency (12, 48 or 96 MHz), this API is implememnt in ROM code.
\r
177 * Turns on FRO and uses default CCO, if freq is 12000000, then high speed output is off, else high speed
\r
178 * output is enabled.
\r
179 * Usage: CLOCK_SetupFROClocking(frequency), (frequency must be one of 12, 48 or 96 MHz)
\r
180 * Note: Need to make sure ROM and OTP has power(PDRUNCFG0[17,29]= 0U) before calling this API since this API is
\r
181 * implemented in ROM code and the FROHF TRIM value is stored in OTP
\r
183 * param froFreq target fro frequency.
\r
187 void CLOCK_SetupFROClocking(uint32_t froFreq)
\r
189 uint32_t froRomAddr = 0U;
\r
190 #if defined(FSL_FROHF_SETTING_API_ADDRESS_DETERMINE_BY_ROM_VERSION) && \
\r
191 (FSL_FROHF_SETTING_API_ADDRESS_DETERMINE_BY_ROM_VERSION)
\r
192 uint8_t romVersion = 0U;
\r
194 if (CLOCK_GetRomVersion(&romVersion) == (uint32_t)kStatus_Success)
\r
196 if (romVersion == FSL_ROM_VERSION_1B)
\r
198 froRomAddr = FSL_ROM_VERSION_1B_FRO_SETTING_ADDR;
\r
202 froRomAddr = FSL_ROM_VERSION_0A_FRO_SETTING_ADDR;
\r
205 (*((void (*)(uint32_t funcname))(froRomAddr)))(froFreq);
\r
208 froRomAddr = FSL_ROM_VERSION_0A_FRO_SETTING_ADDR;
\r
210 (*((void (*)(uint32_t))(froRomAddr)))(froFreq);
\r
214 /* Clock Selection for IP */
\r
216 * brief Configure the clock selection muxes.
\r
217 * param connection : Clock to be configured.
\r
220 void CLOCK_AttachClk(clock_attach_id_t connection)
\r
225 uint32_t tmp32 = (uint32_t)connection;
\r
227 volatile uint32_t *pClkSel;
\r
229 pClkSel = &(SYSCON->STICKCLKSEL);
\r
231 if (kNONE_to_NONE != connection)
\r
233 for (i = 0U; i < 2U; i++)
\r
239 item = (uint16_t)GET_ID_ITEM(tmp32);
\r
242 mux = GET_ID_ITEM_MUX(item);
\r
243 sel = GET_ID_ITEM_SEL(item);
\r
244 if (mux == CM_ASYNCAPB)
\r
246 SYSCON->ASYNCAPBCTRL = SYSCON_ASYNCAPBCTRL_ENABLE(1);
\r
247 ASYNC_SYSCON->ASYNCAPBCLKSELA = sel;
\r
251 ((volatile uint32_t *)pClkSel)[mux] = sel;
\r
254 tmp32 = GET_ID_NEXT_ITEM(tmp32); /* pick up next descriptor */
\r
259 /* Return the actual clock attach id */
\r
261 * brief Get the actual clock attach id.
\r
262 * This fuction uses the offset in input attach id, then it reads the actual source value in
\r
263 * the register and combine the offset to obtain an actual attach id.
\r
264 * param attachId : Clock attach id to get.
\r
265 * return Clock source value.
\r
267 clock_attach_id_t CLOCK_GetClockAttachId(clock_attach_id_t attachId)
\r
271 uint32_t tmp32 = (uint32_t)attachId;
\r
273 uint32_t actualAttachId = 0U;
\r
274 uint32_t selector = GET_ID_SELECTOR(tmp32);
\r
275 volatile uint32_t *pClkSel;
\r
277 pClkSel = &(SYSCON->STICKCLKSEL);
\r
279 if (kNONE_to_NONE == attachId)
\r
281 return kNONE_to_NONE;
\r
284 for (i = 0U; i < 2U; i++)
\r
286 mux = GET_ID_ITEM_MUX(tmp32);
\r
289 if (mux == CM_ASYNCAPB)
\r
291 actualSel = (uint8_t)(ASYNC_SYSCON->ASYNCAPBCLKSELA);
\r
295 actualSel = (uint8_t)(((volatile uint32_t *)pClkSel)[mux]);
\r
298 /* Consider the combination of two registers */
\r
299 actualAttachId |= CLK_ATTACH_ID(mux, actualSel, i);
\r
301 tmp32 = GET_ID_NEXT_ITEM(tmp32); /*!< pick up next descriptor */
\r
304 actualAttachId |= selector;
\r
306 return (clock_attach_id_t)actualAttachId;
\r
309 /* Set IP Clock Divider */
\r
311 * brief Setup peripheral clock dividers.
\r
312 * param div_name : Clock divider name
\r
313 * param divided_by_value: Value to be divided
\r
314 * param reset : Whether to reset the divider counter.
\r
317 void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset)
\r
319 volatile uint32_t *pClkDiv;
\r
321 pClkDiv = &(SYSCON->SYSTICKCLKDIV);
\r
324 ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = 1UL << 29U;
\r
326 if (divided_by_value == 0U) /*!< halt */
\r
328 ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = 1UL << 30U;
\r
332 ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = (divided_by_value - 1U);
\r
336 /* Get CLOCK OUT Clk */
\r
337 /*! brief Return Frequency of ClockOut
\r
338 * return Frequency of ClockOut
\r
340 uint32_t CLOCK_GetClockOutClkFreq(void)
\r
342 uint32_t freq = 0U;
\r
344 switch (SYSCON->CLKOUTSELA)
\r
347 freq = CLOCK_GetCoreSysClkFreq();
\r
351 freq = CLOCK_GetExtClkFreq();
\r
355 freq = CLOCK_GetWdtOscFreq();
\r
359 freq = CLOCK_GetFroHfFreq();
\r
363 freq = CLOCK_GetPllOutFreq();
\r
367 freq = CLOCK_GetUsbPllOutFreq();
\r
371 freq = CLOCK_GetAudioPllOutFreq();
\r
375 freq = CLOCK_GetOsc32KFreq();
\r
382 return freq / ((SYSCON->CLKOUTDIV & 0xffU) + 1U);
\r
385 /* Get SPIFI Clk */
\r
386 /*! brief Return Frequency of Spifi Clock
\r
387 * return Frequency of Spifi.
\r
389 uint32_t CLOCK_GetSpifiClkFreq(void)
\r
391 uint32_t freq = 0U;
\r
393 switch (SYSCON->SPIFICLKSEL)
\r
396 freq = CLOCK_GetCoreSysClkFreq();
\r
399 freq = CLOCK_GetPllOutFreq();
\r
402 freq = CLOCK_GetUsbPllOutFreq();
\r
405 freq = CLOCK_GetFroHfFreq();
\r
408 freq = CLOCK_GetAudioPllOutFreq();
\r
418 return freq / ((SYSCON->SPIFICLKDIV & 0xffU) + 1U);
\r
422 /*! brief Return Frequency of Adc Clock
\r
423 * return Frequency of Adc Clock.
\r
425 uint32_t CLOCK_GetAdcClkFreq(void)
\r
427 uint32_t freq = 0U;
\r
429 switch (SYSCON->ADCCLKSEL)
\r
432 freq = CLOCK_GetFroHfFreq();
\r
435 freq = CLOCK_GetPllOutFreq();
\r
438 freq = CLOCK_GetUsbPllOutFreq();
\r
441 freq = CLOCK_GetAudioPllOutFreq();
\r
451 return freq / ((SYSCON->ADCCLKDIV & 0xffU) + 1U);
\r
455 /*! brief Return Frequency of Usb0 Clock
\r
456 * return Frequency of Usb0 Clock.
\r
458 uint32_t CLOCK_GetUsb0ClkFreq(void)
\r
460 uint32_t freq = 0U;
\r
462 switch (SYSCON->USB0CLKSEL)
\r
465 freq = CLOCK_GetFroHfFreq();
\r
468 freq = CLOCK_GetPllOutFreq();
\r
471 freq = CLOCK_GetUsbPllOutFreq();
\r
482 return freq / ((SYSCON->USB0CLKDIV & 0xffU) + 1U);
\r
486 /*! brief Return Frequency of Usb1 Clock
\r
487 * return Frequency of Usb1 Clock.
\r
489 uint32_t CLOCK_GetUsb1ClkFreq(void)
\r
491 uint32_t freq = 0U;
\r
493 switch (SYSCON->USB1CLKSEL)
\r
496 freq = CLOCK_GetCoreSysClkFreq();
\r
499 freq = CLOCK_GetPllOutFreq();
\r
502 freq = CLOCK_GetUsbPllOutFreq();
\r
513 return freq / ((SYSCON->USB1CLKDIV & 0xffU) + 1U);
\r
517 /*! brief Return Frequency of MClk Clock
\r
518 * return Frequency of MClk Clock.
\r
520 uint32_t CLOCK_GetMclkClkFreq(void)
\r
522 uint32_t freq = 0U;
\r
524 switch (SYSCON->MCLKCLKSEL)
\r
527 freq = CLOCK_GetFroHfFreq() / ((SYSCON->FROHFDIV & 0xffu) + 1U);
\r
530 freq = CLOCK_GetAudioPllOutFreq();
\r
541 return freq / ((SYSCON->MCLKDIV & 0xffU) + 1U);
\r
544 /* Get SCTIMER Clk */
\r
545 /*! brief Return Frequency of SCTimer Clock
\r
546 * return Frequency of SCTimer Clock.
\r
548 uint32_t CLOCK_GetSctClkFreq(void)
\r
550 uint32_t freq = 0U;
\r
552 switch (SYSCON->SCTCLKSEL)
\r
555 freq = CLOCK_GetCoreSysClkFreq();
\r
558 freq = CLOCK_GetPllOutFreq();
\r
561 freq = CLOCK_GetFroHfFreq();
\r
564 freq = CLOCK_GetAudioPllOutFreq();
\r
575 return freq / ((SYSCON->SCTCLKDIV & 0xffU) + 1U);
\r
579 /*! brief Return Frequency of SDIO Clock
\r
580 * return Frequency of SDIO Clock.
\r
582 uint32_t CLOCK_GetSdioClkFreq(void)
\r
584 uint32_t freq = 0U;
\r
586 switch (SYSCON->SDIOCLKSEL)
\r
589 freq = CLOCK_GetCoreSysClkFreq();
\r
592 freq = CLOCK_GetPllOutFreq();
\r
595 freq = CLOCK_GetUsbPllOutFreq();
\r
598 freq = CLOCK_GetFroHfFreq();
\r
601 freq = CLOCK_GetAudioPllOutFreq();
\r
611 return freq / ((SYSCON->SDIOCLKDIV & 0xffU) + 1U);
\r
615 /*! brief Return Frequency of LCD Clock
\r
616 * return Frequency of LCD Clock.
\r
618 uint32_t CLOCK_GetLcdClkFreq(void)
\r
620 uint32_t freq = 0U;
\r
622 switch (SYSCON->LCDCLKSEL)
\r
625 freq = CLOCK_GetCoreSysClkFreq();
\r
628 freq = CLOCK_GetLcdClkIn();
\r
631 freq = CLOCK_GetFroHfFreq();
\r
642 return freq / ((SYSCON->LCDCLKDIV & 0xffU) + 1U);
\r
645 /* Get LCD CLK IN Clk */
\r
646 /*! brief Return Frequency of LCD CLKIN Clock
\r
647 * return Frequency of LCD CLKIN Clock.
\r
649 uint32_t CLOCK_GetLcdClkIn(void)
\r
651 return g_Lcd_Clk_In_Freq;
\r
654 /* Get FRO 12M Clk */
\r
655 /*! brief Return Frequency of FRO 12MHz
\r
656 * return Frequency of FRO 12MHz
\r
658 uint32_t CLOCK_GetFro12MFreq(void)
\r
660 return ((SYSCON->PDRUNCFG[0] & SYSCON_PDRUNCFG_PDEN_FRO_MASK) != 0UL) ? 0U : 12000000U;
\r
663 /* Get EXT OSC Clk */
\r
664 /*! brief Return Frequency of External Clock
\r
665 * return Frequency of External Clock. If no external clock is used returns 0.
\r
667 uint32_t CLOCK_GetExtClkFreq(void)
\r
669 return g_Ext_Clk_Freq;
\r
672 /* Get WATCH DOG Clk */
\r
673 /*! brief Return Frequency of Watchdog Oscillator
\r
674 * return Frequency of Watchdog Oscillator
\r
676 uint32_t CLOCK_GetWdtOscFreq(void)
\r
678 uint8_t freq_sel, div_sel;
\r
679 if ((SYSCON->PDRUNCFG[0] & SYSCON_PDRUNCFG_PDEN_WDT_OSC_MASK) != 0UL)
\r
685 div_sel = (uint8_t)(((SYSCON->WDTOSCCTRL & 0x1fU) + 1U) << 1U);
\r
687 wdtFreqLookup[((SYSCON->WDTOSCCTRL & SYSCON_WDTOSCCTRL_FREQSEL_MASK) >> SYSCON_WDTOSCCTRL_FREQSEL_SHIFT)];
\r
688 return ((uint32_t)freq_sel * 50000U) / ((uint32_t)div_sel);
\r
692 /* Get HF FRO Clk */
\r
693 /*! brief Return Frequency of High-Freq output of FRO
\r
694 * return Frequency of High-Freq output of FRO
\r
696 uint32_t CLOCK_GetFroHfFreq(void)
\r
698 if (((SYSCON->PDRUNCFG[0] & SYSCON_PDRUNCFG_PDEN_FRO_MASK) != 0UL) ||
\r
699 (0UL == (SYSCON->FROCTRL & SYSCON_FROCTRL_HSPDCLK_MASK)))
\r
704 if ((SYSCON->FROCTRL & SYSCON_FROCTRL_SEL_MASK) != 0UL)
\r
714 /* Get SYSTEM PLL Clk */
\r
715 /*! brief Return Frequency of PLL
\r
716 * return Frequency of PLL
\r
718 uint32_t CLOCK_GetPllOutFreq(void)
\r
723 /* Get AUDIO PLL Clk */
\r
724 /*! brief Return Frequency of AUDIO PLL
\r
725 * return Frequency of PLL
\r
727 uint32_t CLOCK_GetAudioPllOutFreq(void)
\r
729 return s_Audio_Pll_Freq;
\r
732 /* Get USB PLL Clk */
\r
733 /*! brief Return Frequency of USB PLL
\r
734 * return Frequency of PLL
\r
736 uint32_t CLOCK_GetUsbPllOutFreq(void)
\r
738 return s_Usb_Pll_Freq;
\r
741 /* Get RTC OSC Clk */
\r
742 /*! brief Return Frequency of 32kHz osc
\r
743 * return Frequency of 32kHz osc
\r
745 uint32_t CLOCK_GetOsc32KFreq(void)
\r
747 return CLK_RTC_32K_CLK; /* Needs to be corrected to check that RTC Clock is enabled */
\r
751 /*! brief Return Frequency of Core System
\r
752 * return Frequency of Core System
\r
754 uint32_t CLOCK_GetCoreSysClkFreq(void)
\r
756 uint32_t freq = 0U;
\r
758 switch (SYSCON->MAINCLKSELB)
\r
761 if (SYSCON->MAINCLKSELA == 0U)
\r
763 freq = CLOCK_GetFro12MFreq();
\r
765 else if (SYSCON->MAINCLKSELA == 1U)
\r
767 freq = CLOCK_GetExtClkFreq();
\r
769 else if (SYSCON->MAINCLKSELA == 2U)
\r
771 freq = CLOCK_GetWdtOscFreq();
\r
773 else if (SYSCON->MAINCLKSELA == 3U)
\r
775 freq = CLOCK_GetFroHfFreq();
\r
779 /* Add comment to prevent the case of rule 15.7. */
\r
783 freq = CLOCK_GetPllOutFreq();
\r
787 freq = CLOCK_GetOsc32KFreq();
\r
798 /* Get I2S MCLK Clk */
\r
799 /*! brief Return Frequency of I2S MCLK Clock
\r
800 * return Frequency of I2S MCLK Clock
\r
802 uint32_t CLOCK_GetI2SMClkFreq(void)
\r
804 return g_I2S_Mclk_Freq;
\r
807 /* Get ASYNC APB Clk */
\r
808 /*! brief Return Frequency of Asynchronous APB Clock
\r
809 * return Frequency of Asynchronous APB Clock Clock
\r
811 uint32_t CLOCK_GetAsyncApbClkFreq(void)
\r
813 async_clock_src_t clkSrc;
\r
816 clkSrc = CLOCK_GetAsyncApbClkSrc();
\r
820 case kCLOCK_AsyncMainClk:
\r
821 clkRate = CLOCK_GetCoreSysClkFreq();
\r
823 case kCLOCK_AsyncFro12Mhz:
\r
824 clkRate = CLK_FRO_12MHZ;
\r
835 /*! brief Return Frequency of MCAN Clock
\r
836 * param MCanSel : 0U: MCAN0; 1U: MCAN1
\r
837 * return Frequency of MCAN Clock
\r
839 uint32_t CLOCK_GetMCanClkFreq(uint32_t MCanSel)
\r
841 uint32_t freq = 0U;
\r
845 freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->CAN0CLKDIV & 0xffU) + 1U);
\r
848 freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->CAN1CLKDIV & 0xffU) + 1U);
\r
859 /* Get FLEXCOMM Clk */
\r
860 /*! brief Return Frequency of Flexcomm functional Clock
\r
861 * return Frequency of Flexcomm functional Clock
\r
863 uint32_t CLOCK_GetFlexCommClkFreq(uint32_t id)
\r
865 uint32_t freq = 0U;
\r
869 switch (SYSCON->FCLKSEL[id])
\r
872 freq = CLOCK_GetFro12MFreq();
\r
875 freq = CLOCK_GetFroHfFreq() / ((SYSCON->FROHFDIV & 0xffu) + 1U);
\r
878 freq = CLOCK_GetAudioPllOutFreq();
\r
881 freq = CLOCK_GetI2SMClkFreq();
\r
884 freq = CLOCK_GetFrgClkFreq();
\r
894 switch (SYSCON->FCLKSEL10)
\r
897 freq = CLOCK_GetCoreSysClkFreq();
\r
900 freq = CLOCK_GetPllOutFreq();
\r
903 freq = CLOCK_GetUsbPllOutFreq();
\r
906 freq = CLOCK_GetFroHfFreq();
\r
909 freq = CLOCK_GetAudioPllOutFreq();
\r
921 uint32_t CLOCK_GetFRGInputClock(void)
\r
923 uint32_t freq = 0U;
\r
925 switch (SYSCON->FRGCLKSEL)
\r
928 freq = CLOCK_GetCoreSysClkFreq();
\r
931 freq = CLOCK_GetPllOutFreq();
\r
934 freq = CLOCK_GetFro12MFreq();
\r
937 freq = CLOCK_GetFroHfFreq();
\r
949 /*! brief Return Frequency of frg
\r
950 * return Frequency of FRG
\r
952 uint32_t CLOCK_GetFrgClkFreq(void)
\r
954 uint32_t freq = 0U;
\r
956 if ((SYSCON->FRGCTRL & SYSCON_FRGCTRL_DIV_MASK) == SYSCON_FRGCTRL_DIV_MASK)
\r
958 freq = (uint32_t)(((uint64_t)CLOCK_GetFRGInputClock() * (SYSCON_FRGCTRL_DIV_MASK + 1U)) /
\r
959 ((SYSCON_FRGCTRL_DIV_MASK + 1U) +
\r
960 ((SYSCON->FRGCTRL & SYSCON_FRGCTRL_MULT_MASK) >> SYSCON_FRGCTRL_MULT_SHIFT)));
\r
971 /*! brief Return Frequency of dmic
\r
972 * return Frequency of DMIC
\r
974 uint32_t CLOCK_GetDmicClkFreq(void)
\r
976 uint32_t freq = 0U;
\r
978 switch (SYSCON->DMICCLKSEL)
\r
981 freq = CLOCK_GetFro12MFreq();
\r
984 freq = CLOCK_GetFroHfFreq();
\r
987 freq = CLOCK_GetPllOutFreq();
\r
990 freq = CLOCK_GetI2SMClkFreq();
\r
993 freq = CLOCK_GetCoreSysClkFreq();
\r
996 freq = CLOCK_GetWdtOscFreq();
\r
1003 return freq / ((SYSCON->DMICCLKDIV & 0xffU) + 1U);
\r
1008 uint32_t CLOCK_SetFRGClock(uint32_t freq)
\r
1010 assert(0UL != freq);
\r
1012 uint32_t input = CLOCK_GetFRGInputClock();
\r
1015 if ((freq > 48000000U) || (freq > input) || (input / freq >= 2U))
\r
1017 /* FRG output frequency should be less than equal to 48MHz */
\r
1022 mul = (uint32_t)((((uint64_t)input - freq) * 256U) / ((uint64_t)freq));
\r
1023 SYSCON->FRGCTRL = (mul << SYSCON_FRGCTRL_MULT_SHIFT) | SYSCON_FRGCTRL_DIV_MASK;
\r
1029 /*! brief Return Frequency of selected clock
\r
1030 * return Frequency of selected clock
\r
1032 uint32_t CLOCK_GetFreq(clock_name_t clockName)
\r
1035 switch (clockName)
\r
1037 case kCLOCK_CoreSysClk:
\r
1038 freq = CLOCK_GetCoreSysClkFreq();
\r
1040 case kCLOCK_BusClk:
\r
1041 freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->AHBCLKDIV & 0xffU) + 1U);
\r
1043 case kCLOCK_ClockOut:
\r
1044 freq = CLOCK_GetClockOutClkFreq();
\r
1047 freq = CLOCK_GetMclkClkFreq();
\r
1049 case kCLOCK_FroHf:
\r
1050 freq = CLOCK_GetFroHfFreq();
\r
1052 case kCLOCK_Fro12M:
\r
1053 freq = CLOCK_GetFro12MFreq();
\r
1055 case kCLOCK_ExtClk:
\r
1056 freq = CLOCK_GetExtClkFreq();
\r
1058 case kCLOCK_PllOut:
\r
1059 freq = CLOCK_GetPllOutFreq();
\r
1061 case kCLOCK_WdtOsc:
\r
1062 freq = CLOCK_GetWdtOscFreq();
\r
1065 freq = CLOCK_GetFrgClkFreq();
\r
1068 case kCLOCK_AsyncApbClk:
\r
1069 freq = CLOCK_GetAsyncApbClkFreq();
\r
1079 /* Find encoded NDEC value for raw N value, max N = NVALMAX */
\r
1080 static uint32_t pllEncodeN(uint32_t N)
\r
1101 for (i = N; i <= NVALMAX; i++)
\r
1103 x = (((x ^ (x >> 2U) ^ (x >> 3U) ^ (x >> 4U)) & 1U) << 7U) | ((x >> 1U) & 0x7FU);
\r
1108 return x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P);
\r
1111 /* Find decoded N value for raw NDEC value */
\r
1112 static uint32_t pllDecodeN(uint32_t NDEC)
\r
1134 for (i = NVALMAX; i >= 3U; i--)
\r
1136 x = (((x ^ (x >> 2U) ^ (x >> 3U) ^ (x >> 4U)) & 1U) << 7U) | ((x >> 1U) & 0x7FU);
\r
1137 if ((x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P)) == NDEC)
\r
1139 /* Decoded value of NDEC */
\r
1150 /* Find encoded PDEC value for raw P value, max P = PVALMAX */
\r
1151 static uint32_t pllEncodeP(uint32_t P)
\r
1172 for (i = P; i <= PVALMAX; i++)
\r
1174 x = (((x ^ (x >> 2U)) & 1U) << 4U) | ((x >> 1U) & 0xFU);
\r
1179 return x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P);
\r
1182 /* Find decoded P value for raw PDEC value */
\r
1183 static uint32_t pllDecodeP(uint32_t PDEC)
\r
1205 for (i = PVALMAX; i >= 3U; i--)
\r
1207 x = (((x ^ (x >> 2U)) & 1U) << 4U) | ((x >> 1U) & 0xFU);
\r
1208 if ((x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P)) == PDEC)
\r
1210 /* Decoded value of PDEC */
\r
1221 /* Find encoded MDEC value for raw M value, max M = MVALMAX */
\r
1222 static uint32_t pllEncodeM(uint32_t M)
\r
1243 for (i = M; i <= MVALMAX; i++)
\r
1245 x = (((x ^ (x >> 1U)) & 1U) << 14U) | ((x >> 1U) & 0x3FFFU);
\r
1250 return x & (PLL_MDEC_VAL_M >> PLL_MDEC_VAL_P);
\r
1253 /* Find decoded M value for raw MDEC value */
\r
1254 static uint32_t pllDecodeM(uint32_t MDEC)
\r
1276 for (i = MVALMAX; i >= 3U; i--)
\r
1278 x = (((x ^ (x >> 1U)) & 1U) << 14U) | ((x >> 1U) & 0x3FFFU);
\r
1279 if ((x & (PLL_MDEC_VAL_M >> PLL_MDEC_VAL_P)) == MDEC)
\r
1281 /* Decoded value of MDEC */
\r
1292 /* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */
\r
1293 static void pllFindSel(uint32_t M, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR)
\r
1295 /* bandwidth: compute selP from Multiplier */
\r
1298 *pSelP = (M >> 1U) + 1U;
\r
1302 *pSelP = PVALMAX - 1U;
\r
1305 /* bandwidth: compute selI from Multiplier */
\r
1310 else if (M > 8192U)
\r
1314 else if (M > 2048U)
\r
1318 else if (M >= 501U)
\r
1322 else if (M >= 60U)
\r
1324 *pSelI = 4U * (1024U / (M + 9U));
\r
1328 *pSelI = (M & 0x3CU) + 4U;
\r
1331 if (*pSelI > ((0x3FUL << SYSCON_SYSPLLCTRL_SELI_SHIFT) >> SYSCON_SYSPLLCTRL_SELI_SHIFT))
\r
1333 *pSelI = ((0x3FUL << SYSCON_SYSPLLCTRL_SELI_SHIFT) >> SYSCON_SYSPLLCTRL_SELI_SHIFT);
\r
1339 /* Get predivider (N) from PLL NDEC setting */
\r
1340 static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg)
\r
1342 uint32_t preDiv = 1;
\r
1344 /* Direct input is not used? */
\r
1345 if ((ctrlReg & (1UL << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT)) == 0U)
\r
1347 /* Decode NDEC value to get (N) pre divider */
\r
1348 preDiv = pllDecodeN(nDecReg & 0x3FFU);
\r
1355 /* Adjusted by 1, directi is used to bypass */
\r
1359 /* Get postdivider (P) from PLL PDEC setting */
\r
1360 static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg)
\r
1362 uint32_t postDiv = 1U;
\r
1364 /* Direct input is not used? */
\r
1365 if ((ctrlReg & SYSCON_SYSPLLCTRL_DIRECTO_MASK) == 0U)
\r
1367 /* Decode PDEC value to get (P) post divider */
\r
1368 postDiv = 2U * pllDecodeP(pDecReg & 0x7FU);
\r
1369 if (postDiv == 0U)
\r
1375 /* Adjusted by 1, directo is used to bypass */
\r
1379 /* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */
\r
1380 static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg)
\r
1382 uint32_t mMult = 1U;
\r
1384 /* Decode MDEC value to get (M) multiplier */
\r
1385 mMult = pllDecodeM(mDecReg & 0x1FFFFU);
\r
1395 /* Calculate the powerTimes' power of 2 */
\r
1396 static uint32_t power2Cal(uint32_t powerTimes)
\r
1398 uint32_t ret = 1U;
\r
1400 for (i = 0; i < powerTimes; i++)
\r
1408 /* Convert the binary to fractional part */
\r
1409 static double Binary2Fractional(uint32_t binaryPart)
\r
1411 double fractional = 0.0;
\r
1412 for (uint32_t i = 0U; i <= 14U; i++)
\r
1414 fractional += (double)(uint32_t)((binaryPart >> i) & 0x1U) / (double)(uint32_t)power2Cal(15U - i);
\r
1416 return fractional;
\r
1419 /* Find greatest common divisor between m and n */
\r
1420 static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n)
\r
1435 * Set PLL output based on desired output rate.
\r
1436 * In this function, the it calculates the PLL setting for output frequency from input clock
\r
1437 * frequency. The calculation would cost a few time. So it is not recommaned to use it frequently.
\r
1438 * the "pllctrl", "pllndec", "pllpdec", "pllmdec" would updated in this function.
\r
1440 static pll_error_t CLOCK_GetPllConfigInternal(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup)
\r
1442 uint32_t nDivOutHz, fccoHz, multFccoDiv;
\r
1443 uint32_t pllPreDivider, pllMultiplier, pllPostDivider;
\r
1444 uint32_t pllDirectInput, pllDirectOutput;
\r
1445 uint32_t pllSelP, pllSelI, pllSelR, uplimoff;
\r
1447 /* Baseline parameters (no input or output dividers) */
\r
1448 pllPreDivider = 1U; /* 1 implies pre-divider will be disabled */
\r
1449 pllPostDivider = 0U; /* 0 implies post-divider will be disabled */
\r
1450 pllDirectOutput = 1U;
\r
1453 /* Verify output rate parameter */
\r
1454 if (foutHz > PLL_MAX_CCO_FREQ_MHZ)
\r
1456 /* Maximum PLL output with post divider=1 cannot go above this frequency */
\r
1457 return kStatus_PLL_OutputTooHigh;
\r
1459 if (foutHz < (PLL_MIN_CCO_FREQ_MHZ / (PVALMAX << 1U)))
\r
1461 /* Minmum PLL output with maximum post divider cannot go below this frequency */
\r
1462 return kStatus_PLL_OutputTooLow;
\r
1465 /* Verify input rate parameter */
\r
1466 if (finHz < PLL_LOWER_IN_LIMIT)
\r
1468 /* Input clock into the PLL cannot be lower than this */
\r
1469 return kStatus_PLL_InputTooLow;
\r
1472 /* Find the optimal CCO frequency for the output and input that
\r
1473 will keep it inside the PLL CCO range. This may require
\r
1474 tweaking the post-divider for the PLL. */
\r
1476 while (fccoHz < PLL_MIN_CCO_FREQ_MHZ)
\r
1478 /* CCO output is less than minimum CCO range, so the CCO output
\r
1479 needs to be bumped up and the post-divider is used to bring
\r
1480 the PLL output back down. */
\r
1482 if (pllPostDivider > PVALMAX)
\r
1484 return kStatus_PLL_OutsideIntLimit;
\r
1487 /* Target CCO goes up, PLL output goes down */
\r
1488 fccoHz = foutHz * (pllPostDivider * 2U);
\r
1489 pllDirectOutput = 0U;
\r
1492 /* Determine if a pre-divider is needed to get the best frequency */
\r
1493 if ((finHz > PLL_LOWER_IN_LIMIT) && (fccoHz >= finHz))
\r
1495 uint32_t a = FindGreatestCommonDivisor(fccoHz, (multFccoDiv * finHz));
\r
1499 a = (multFccoDiv * finHz) / a;
\r
1500 if ((a != 0U) && (a < PLL_MAX_N_DIV))
\r
1502 pllPreDivider = a;
\r
1507 /* Bypass pre-divider hardware if pre-divider is 1 */
\r
1508 if (pllPreDivider > 1U)
\r
1510 pllDirectInput = 0U;
\r
1514 pllDirectInput = 1U;
\r
1517 /* Determine PLL multipler */
\r
1518 nDivOutHz = (finHz / pllPreDivider);
\r
1519 pllMultiplier = (fccoHz / nDivOutHz) / multFccoDiv;
\r
1521 /* Find optimal values for filter */
\r
1522 /* Will bumping up M by 1 get us closer to the desired CCO frequency? */
\r
1523 if ((nDivOutHz * ((multFccoDiv * pllMultiplier * 2U) + 1U)) < (fccoHz * 2U))
\r
1528 /* Setup filtering */
\r
1529 pllFindSel(pllMultiplier, &pllSelP, &pllSelI, &pllSelR);
\r
1532 /* Get encoded value for M (mult) and use manual filter, disable SS mode */
\r
1533 pSetup->pllmdec = PLL_MDEC_VAL_SET(pllEncodeM(pllMultiplier));
\r
1535 /* Get encoded values for N (prediv) and P (postdiv) */
\r
1536 pSetup->pllndec = PLL_NDEC_VAL_SET(pllEncodeN(pllPreDivider));
\r
1537 pSetup->pllpdec = PLL_PDEC_VAL_SET(pllEncodeP(pllPostDivider));
\r
1540 pSetup->pllctrl = (pllSelR << SYSCON_SYSPLLCTRL_SELR_SHIFT) | /* Filter coefficient */
\r
1541 (pllSelI << SYSCON_SYSPLLCTRL_SELI_SHIFT) | /* Filter coefficient */
\r
1542 (pllSelP << SYSCON_SYSPLLCTRL_SELP_SHIFT) | /* Filter coefficient */
\r
1543 (0UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT) | /* PLL bypass mode disabled */
\r
1544 (uplimoff << SYSCON_SYSPLLCTRL_UPLIMOFF_SHIFT) | /* SS/fractional mode disabled */
\r
1545 (pllDirectInput << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT) | /* Bypass pre-divider? */
\r
1546 (pllDirectOutput << SYSCON_SYSPLLCTRL_DIRECTO_SHIFT); /* Bypass post-divider? */
\r
1548 return kStatus_PLL_Success;
\r
1551 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
\r
1552 /* Alloct the static buffer for cache. */
\r
1553 static pll_setup_t gPllSetupCacheStruct[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT];
\r
1554 static uint32_t gFinHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0};
\r
1555 static uint32_t gFoutHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0};
\r
1556 static uint32_t gPllSetupCacheIdx = 0U;
\r
1557 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
\r
1560 * Calculate the PLL setting values from input clock freq to output freq.
\r
1562 static pll_error_t CLOCK_GetPllConfig(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup)
\r
1564 pll_error_t retErr;
\r
1565 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
\r
1568 for (i = 0U; i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT; i++)
\r
1570 if ((finHz == gFinHzCache[i]) && (foutHz == gFoutHzCache[i]))
\r
1572 /* Hit the target in cache buffer. */
\r
1573 pSetup->pllctrl = gPllSetupCacheStruct[i].pllctrl;
\r
1574 pSetup->pllndec = gPllSetupCacheStruct[i].pllndec;
\r
1575 pSetup->pllpdec = gPllSetupCacheStruct[i].pllpdec;
\r
1576 pSetup->pllmdec = gPllSetupCacheStruct[i].pllmdec;
\r
1577 retErr = kStatus_PLL_Success;
\r
1582 if (i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
\r
1586 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
\r
1588 /* No cache or did not hit the cache. */
\r
1589 retErr = CLOCK_GetPllConfigInternal(finHz, foutHz, pSetup);
\r
1591 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
\r
1592 if (kStatus_PLL_Success == retErr)
\r
1594 /* Cache the most recent calulation result into buffer. */
\r
1595 gFinHzCache[gPllSetupCacheIdx] = finHz;
\r
1596 gFoutHzCache[gPllSetupCacheIdx] = foutHz;
\r
1598 gPllSetupCacheStruct[gPllSetupCacheIdx].pllctrl = pSetup->pllctrl;
\r
1599 gPllSetupCacheStruct[gPllSetupCacheIdx].pllndec = pSetup->pllndec;
\r
1600 gPllSetupCacheStruct[gPllSetupCacheIdx].pllpdec = pSetup->pllpdec;
\r
1601 gPllSetupCacheStruct[gPllSetupCacheIdx].pllmdec = pSetup->pllmdec;
\r
1602 /* Update the index for next available buffer. */
\r
1603 gPllSetupCacheIdx = (gPllSetupCacheIdx + 1U) % CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT;
\r
1605 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
\r
1610 /* Update SYSTEM PLL rate variable */
\r
1611 static void CLOCK_GetSystemPLLOutFromSetupUpdate(pll_setup_t *pSetup)
\r
1613 s_Pll_Freq = CLOCK_GetSystemPLLOutFromSetup(pSetup);
\r
1616 /* Update AUDIO PLL rate variable */
\r
1617 static void CLOCK_GetAudioPLLOutFromSetupUpdate(pll_setup_t *pSetup)
\r
1619 s_Audio_Pll_Freq = CLOCK_GetAudioPLLOutFromSetup(pSetup);
\r
1622 /* Update AUDIO Fractional PLL rate variable */
\r
1623 static void CLOCK_GetAudioPLLOutFromAudioFracSetupUpdate(pll_setup_t *pSetup)
\r
1625 s_Audio_Pll_Freq = CLOCK_GetAudioPLLOutFromFractSetup(pSetup);
\r
1628 /* Update USB PLL rate variable */
\r
1629 static void CLOCK_GetUsbPLLOutFromSetupUpdate(const usb_pll_setup_t *pSetup)
\r
1631 s_Usb_Pll_Freq = CLOCK_GetUsbPLLOutFromSetup(pSetup);
\r
1634 /* Return System PLL input clock rate */
\r
1635 /*! brief Return System PLL input clock rate
\r
1636 * return System PLL input clock rate
\r
1638 uint32_t CLOCK_GetSystemPLLInClockRate(void)
\r
1640 uint32_t clkRate = 0U;
\r
1642 switch ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK))
\r
1645 clkRate = CLK_FRO_12MHZ;
\r
1649 clkRate = CLOCK_GetExtClkFreq();
\r
1653 clkRate = CLOCK_GetWdtOscFreq();
\r
1657 clkRate = CLOCK_GetOsc32KFreq();
\r
1668 /* Return Audio PLL input clock rate */
\r
1669 /*! brief Return Audio PLL input clock rate
\r
1670 * return Audio PLL input clock rate
\r
1672 uint32_t CLOCK_GetAudioPLLInClockRate(void)
\r
1674 uint32_t clkRate = 0U;
\r
1676 switch ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK))
\r
1679 clkRate = CLK_FRO_12MHZ;
\r
1683 clkRate = CLOCK_GetExtClkFreq();
\r
1694 /* Return System PLL output clock rate from setup structure */
\r
1695 /*! brief Return System PLL output clock rate from setup structure
\r
1696 * param pSetup : Pointer to a PLL setup structure
\r
1697 * return System PLL output clock rate the setup structure will generate
\r
1699 uint32_t CLOCK_GetSystemPLLOutFromSetup(pll_setup_t *pSetup)
\r
1701 uint32_t prediv, postdiv, mMult, inPllRate;
\r
1702 uint64_t workRate;
\r
1704 inPllRate = CLOCK_GetSystemPLLInClockRate();
\r
1705 /* If the PLL is bypassed, PLL would not be used and the output of PLL module would just be the input clock*/
\r
1706 if ((pSetup->pllctrl & (SYSCON_SYSPLLCTRL_BYPASS_MASK)) == 0U)
\r
1708 /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */
\r
1711 * Pre-divider is only available when the DIRECTI is disabled.
\r
1713 if (0U == (pSetup->pllctrl & SYSCON_SYSPLLCTRL_DIRECTI_MASK))
\r
1715 prediv = findPllPreDiv(pSetup->pllctrl, pSetup->pllndec);
\r
1719 prediv = 1U; /* The pre-divider is bypassed. */
\r
1723 * Post-divider is only available when the DIRECTO is disabled.
\r
1725 if (0U == (pSetup->pllctrl & SYSCON_SYSPLLCTRL_DIRECTO_MASK))
\r
1727 postdiv = findPllPostDiv(pSetup->pllctrl, pSetup->pllpdec);
\r
1731 postdiv = 1U; /* The post-divider is bypassed. */
\r
1733 /* Adjust input clock */
\r
1734 inPllRate = inPllRate / prediv;
\r
1736 /* MDEC used for rate */
\r
1737 mMult = findPllMMult(pSetup->pllctrl, pSetup->pllmdec);
\r
1738 workRate = (uint64_t)inPllRate * (uint64_t)mMult;
\r
1740 workRate = workRate / ((uint64_t)postdiv);
\r
1741 workRate = workRate * 2U; /* SYS PLL hardware cco is divide by 2 before to M-DIVIDER*/
\r
1745 /* In bypass mode */
\r
1746 workRate = (uint64_t)inPllRate;
\r
1749 return (uint32_t)workRate;
\r
1752 /* Return Usb PLL output clock rate from setup structure */
\r
1753 /*! brief Return System USB PLL output clock rate from setup structure
\r
1754 * param pSetup : Pointer to a PLL setup structure
\r
1755 * return System PLL output clock rate the setup structure will generate
\r
1757 uint32_t CLOCK_GetUsbPLLOutFromSetup(const usb_pll_setup_t *pSetup)
\r
1759 uint32_t nsel, psel, msel, inPllRate;
\r
1760 uint64_t workRate;
\r
1761 inPllRate = CLOCK_GetExtClkFreq();
\r
1762 msel = pSetup->msel;
\r
1763 psel = pSetup->psel;
\r
1764 nsel = pSetup->nsel;
\r
1766 /* Make sure the PSEL is correct. */
\r
1767 if (0U == SWITCH_USB_PSEL(psel))
\r
1772 if (pSetup->fbsel)
\r
1774 /*integer_mode: Fout = M*(Fin/N), Fcco = 2*P*M*(Fin/N) */
\r
1775 workRate = ((uint64_t)inPllRate) * ((uint64_t)msel + 1U) / ((uint64_t)nsel + 1U);
\r
1779 /* non integer_mode: Fout = M*(Fin/N)/(2*P), Fcco = M * (Fin/N) */
\r
1780 workRate = ((uint64_t)inPllRate / ((uint64_t)nsel + 1U)) * (msel + 1U) / (2U * SWITCH_USB_PSEL(psel));
\r
1783 return (uint32_t)workRate;
\r
1786 /* Return Audio PLL output clock rate from setup structure */
\r
1787 /*! brief Return System AUDIO PLL output clock rate from setup structure
\r
1788 * param pSetup : Pointer to a PLL setup structure
\r
1789 * return System PLL output clock rate the setup structure will generate
\r
1791 uint32_t CLOCK_GetAudioPLLOutFromSetup(pll_setup_t *pSetup)
\r
1793 uint32_t prediv, postdiv, mMult, inPllRate;
\r
1794 uint64_t workRate;
\r
1796 inPllRate = CLOCK_GetAudioPLLInClockRate();
\r
1797 if ((pSetup->pllctrl & (1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT)) == 0U)
\r
1799 /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */
\r
1802 * Pre-divider is only available when the DIRECTI is disabled.
\r
1804 if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTI_MASK))
\r
1806 prediv = findPllPreDiv(pSetup->pllctrl, pSetup->pllndec);
\r
1810 prediv = 1U; /* The pre-divider is bypassed. */
\r
1814 * Post-divider is only available when the DIRECTO is disabled.
\r
1816 if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTO_MASK))
\r
1818 postdiv = findPllPostDiv(pSetup->pllctrl, pSetup->pllpdec);
\r
1822 postdiv = 1U; /* The post-divider is bypassed. */
\r
1824 /* Adjust input clock */
\r
1825 inPllRate = inPllRate / prediv;
\r
1827 /* MDEC used for rate */
\r
1828 mMult = findPllMMult(pSetup->pllctrl, pSetup->pllmdec);
\r
1829 workRate = (uint64_t)inPllRate * (uint64_t)mMult;
\r
1831 workRate = workRate / ((uint64_t)postdiv);
\r
1832 workRate = workRate * 2U; /* SYS PLL hardware cco is divide by 2 before to M-DIVIDER*/
\r
1836 /* In bypass mode */
\r
1837 workRate = (uint64_t)inPllRate;
\r
1840 return (uint32_t)workRate;
\r
1843 /* Return Audio PLL output clock rate from audio fractioanl setup structure */
\r
1844 /*! brief Return System AUDIO PLL output clock rate from audio fractioanl setup structure
\r
1845 * param pSetup : Pointer to a PLL setup structure
\r
1846 * return System PLL output clock rate the setup structure will generate
\r
1848 uint32_t CLOCK_GetAudioPLLOutFromFractSetup(pll_setup_t *pSetup)
\r
1850 uint32_t prediv, postdiv, inPllRate;
\r
1851 double workRate, mMultFactional;
\r
1853 inPllRate = CLOCK_GetAudioPLLInClockRate();
\r
1854 if ((pSetup->pllctrl & (1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT)) == 0U)
\r
1856 /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */
\r
1859 * Pre-divider is only available when the DIRECTI is disabled.
\r
1861 if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTI_MASK))
\r
1863 prediv = findPllPreDiv(pSetup->pllctrl, pSetup->pllndec);
\r
1867 prediv = 1U; /* The pre-divider is bypassed. */
\r
1871 * Post-divider is only available when the DIRECTO is disabled.
\r
1873 if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTO_MASK))
\r
1875 postdiv = findPllPostDiv(pSetup->pllctrl, pSetup->pllpdec);
\r
1879 postdiv = 1U; /* The post-divider is bypassed. */
\r
1881 /* Adjust input clock */
\r
1882 inPllRate = inPllRate / prediv;
\r
1884 mMultFactional = (double)(uint32_t)(pSetup->audpllfrac >> 15) +
\r
1885 (double)(uint32_t)Binary2Fractional(pSetup->audpllfrac & 0x7FFFU);
\r
1886 workRate = (double)inPllRate * (double)mMultFactional;
\r
1888 workRate = workRate / ((double)postdiv);
\r
1889 workRate = workRate * 2.0; /* SYS PLL hardware cco is divide by 2 before to M-DIVIDER*/
\r
1893 /* In bypass mode */
\r
1894 workRate = (double)(uint64_t)inPllRate;
\r
1897 return (uint32_t)workRate;
\r
1900 /* Set the current PLL Rate */
\r
1901 /*! brief Store the current PLL rate
\r
1902 * param rate: Current rate of the PLL
\r
1905 void CLOCK_SetStoredPLLClockRate(uint32_t rate)
\r
1907 s_Pll_Freq = rate;
\r
1910 /* Set the current Audio PLL Rate */
\r
1911 /*! brief Store the current AUDIO PLL rate
\r
1912 * param rate: Current rate of the PLL
\r
1915 void CLOCK_SetStoredAudioPLLClockRate(uint32_t rate)
\r
1917 s_Audio_Pll_Freq = rate;
\r
1920 /* Set the current Usb PLL Rate */
\r
1921 void CLOCK_SetStoredUsbPLLClockRate(uint32_t rate)
\r
1923 s_Usb_Pll_Freq = rate;
\r
1926 /* Return System PLL output clock rate */
\r
1927 /*! brief Return System PLL output clock rate
\r
1928 * param recompute : Forces a PLL rate recomputation if true
\r
1929 * return System PLL output clock rate
\r
1930 * note The PLL rate is cached in the driver in a variable as
\r
1931 * the rate computation function can take some time to perform. It
\r
1932 * is recommended to use 'false' with the 'recompute' parameter.
\r
1934 uint32_t CLOCK_GetSystemPLLOutClockRate(bool recompute)
\r
1936 pll_setup_t Setup;
\r
1939 if ((recompute) || (s_Pll_Freq == 0U))
\r
1941 Setup.pllctrl = SYSCON->SYSPLLCTRL;
\r
1942 Setup.pllndec = SYSCON->SYSPLLNDEC;
\r
1943 Setup.pllpdec = SYSCON->SYSPLLPDEC;
\r
1944 Setup.pllmdec = SYSCON->SYSPLLMDEC;
\r
1946 CLOCK_GetSystemPLLOutFromSetupUpdate(&Setup);
\r
1949 rate = s_Pll_Freq;
\r
1954 /* Return AUDIO PLL output clock rate */
\r
1955 /*! brief Return System AUDIO PLL output clock rate
\r
1956 * param recompute : Forces a AUDIO PLL rate recomputation if true
\r
1957 * return System AUDIO PLL output clock rate
\r
1958 * note The AUDIO PLL rate is cached in the driver in a variable as
\r
1959 * the rate computation function can take some time to perform. It
\r
1960 * is recommended to use 'false' with the 'recompute' parameter.
\r
1962 uint32_t CLOCK_GetAudioPLLOutClockRate(bool recompute)
\r
1964 pll_setup_t Setup;
\r
1967 if ((recompute) || (s_Audio_Pll_Freq == 0U))
\r
1969 Setup.pllctrl = SYSCON->AUDPLLCTRL;
\r
1970 Setup.pllndec = SYSCON->AUDPLLNDEC;
\r
1971 Setup.pllpdec = SYSCON->AUDPLLPDEC;
\r
1972 Setup.pllmdec = SYSCON->AUDPLLMDEC;
\r
1974 CLOCK_GetAudioPLLOutFromSetupUpdate(&Setup);
\r
1977 rate = s_Audio_Pll_Freq;
\r
1981 /* Return USB PLL output clock rate */
\r
1982 uint32_t CLOCK_GetUsbPLLOutClockRate(bool recompute)
\r
1984 usb_pll_setup_t Setup;
\r
1987 if ((recompute) || (s_Usb_Pll_Freq == 0U))
\r
1989 Setup.msel = (uint8_t)((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_MSEL_SHIFT) & SYSCON_USBPLLCTRL_MSEL_MASK);
\r
1990 Setup.psel = (uint8_t)((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_PSEL_SHIFT) & SYSCON_USBPLLCTRL_PSEL_MASK);
\r
1991 Setup.nsel = (uint8_t)((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_NSEL_SHIFT) & SYSCON_USBPLLCTRL_NSEL_MASK);
\r
1992 Setup.fbsel = (((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_FBSEL_SHIFT) & SYSCON_USBPLLCTRL_FBSEL_MASK) != 0UL);
\r
1994 (((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_BYPASS_SHIFT) & SYSCON_USBPLLCTRL_BYPASS_MASK) != 0UL);
\r
1996 (((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_DIRECT_SHIFT) & SYSCON_USBPLLCTRL_DIRECT_MASK) != 0UL);
\r
1997 CLOCK_GetUsbPLLOutFromSetupUpdate(&Setup);
\r
2000 rate = s_Usb_Pll_Freq;
\r
2004 /* Set PLL output based on the passed PLL setup data */
\r
2005 /*! brief Set PLL output based on the passed PLL setup data
\r
2006 * param pControl : Pointer to populated PLL control structure to generate setup with
\r
2007 * param pSetup : Pointer to PLL setup structure to be filled
\r
2008 * return PLL_ERROR_SUCCESS on success, or PLL setup error code
\r
2009 * note Actual frequency for setup may vary from the desired frequency based on the
\r
2010 * accuracy of input clocks, rounding, non-fractional PLL mode, etc.
\r
2012 pll_error_t CLOCK_SetupPLLData(pll_config_t *pControl, pll_setup_t *pSetup)
\r
2015 pll_error_t pllError;
\r
2017 /* Determine input rate for the PLL */
\r
2018 if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0U)
\r
2020 inRate = pControl->inputRate;
\r
2024 inRate = CLOCK_GetSystemPLLInClockRate();
\r
2027 /* PLL flag options */
\r
2028 pllError = CLOCK_GetPllConfig(inRate, pControl->desiredRate, pSetup);
\r
2029 pSetup->pllRate = pControl->desiredRate;
\r
2033 /* Set PLL output from PLL setup structure */
\r
2034 /*! brief Set PLL output from PLL setup structure (precise frequency)
\r
2035 * param pSetup : Pointer to populated PLL setup structure
\r
2036 * param flagcfg : Flag configuration for PLL config structure
\r
2037 * return PLL_ERROR_SUCCESS on success, or PLL setup error code
\r
2038 * note This function will power off the PLL, setup the PLL with the
\r
2039 * new setup data, and then optionally powerup the PLL, wait for PLL lock,
\r
2040 * and adjust system voltages to the new PLL rate. The function will not
\r
2041 * alter any source clocks (ie, main systen clock) that may use the PLL,
\r
2042 * so these should be setup prior to and after exiting the function.
\r
2044 pll_error_t CLOCK_SetupSystemPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg)
\r
2046 if ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK) == 0x01U)
\r
2048 /* Turn on the ext clock if system pll input select clk_in */
\r
2049 CLOCK_Enable_SysOsc(true);
\r
2051 /* Enable power for PLLs */
\r
2053 /* Power off PLL during setup changes */
\r
2054 POWER_EnablePD(kPDRUNCFG_PD_SYS_PLL0);
\r
2056 pSetup->flags = flagcfg;
\r
2058 /* Write PLL setup data */
\r
2059 SYSCON->SYSPLLCTRL = pSetup->pllctrl;
\r
2060 SYSCON->SYSPLLNDEC = pSetup->pllndec;
\r
2061 SYSCON->SYSPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
\r
2062 SYSCON->SYSPLLPDEC = pSetup->pllpdec;
\r
2063 SYSCON->SYSPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
\r
2064 SYSCON->SYSPLLMDEC = pSetup->pllmdec;
\r
2065 SYSCON->SYSPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_SYSPLLMDEC_MREQ_SHIFT); /* latch */
\r
2067 /* Flags for lock or power on */
\r
2068 if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
\r
2070 /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
\r
2071 uint32_t maxCCO = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
\r
2072 uint32_t curSSCTRL = SYSCON->SYSPLLMDEC & ~(1UL << 17U);
\r
2074 /* Initialize and power up PLL */
\r
2075 SYSCON->SYSPLLMDEC = maxCCO;
\r
2076 POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
\r
2078 /* Set mreq to activate */
\r
2079 SYSCON->SYSPLLMDEC = maxCCO | (1UL << 17U);
\r
2081 /* Delay for 72 uSec @ 12Mhz */
\r
2082 SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
\r
2084 /* clear mreq to prepare for restoring mreq */
\r
2085 SYSCON->SYSPLLMDEC = curSSCTRL;
\r
2087 /* set original value back and activate */
\r
2088 SYSCON->SYSPLLMDEC = curSSCTRL | (1UL << 17U);
\r
2090 /* Enable peripheral states by setting low */
\r
2091 POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
\r
2093 if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
\r
2095 while (CLOCK_IsSystemPLLLocked() == false)
\r
2100 /* Update current programmed PLL rate var */
\r
2101 CLOCK_GetSystemPLLOutFromSetupUpdate(pSetup);
\r
2103 /* System voltage adjustment, occurs prior to setting main system clock */
\r
2104 if ((pSetup->flags & PLL_SETUPFLAG_ADGVOLT) != 0U)
\r
2106 POWER_SetVoltageForFreq(s_Pll_Freq);
\r
2109 return kStatus_PLL_Success;
\r
2112 /* Set AUDIO PLL output from AUDIO PLL setup structure */
\r
2113 /*! brief Set AUDIO PLL output from AUDIOPLL setup structure (precise frequency)
\r
2114 * param pSetup : Pointer to populated PLL setup structure
\r
2115 * param flagcfg : Flag configuration for PLL config structure
\r
2116 * return PLL_ERROR_SUCCESS on success, or PLL setup error code
\r
2117 * note This function will power off the PLL, setup the PLL with the
\r
2118 * new setup data, and then optionally powerup the AUDIO PLL, wait for PLL lock,
\r
2119 * and adjust system voltages to the new AUDIOPLL rate. The function will not
\r
2120 * alter any source clocks (ie, main systen clock) that may use the AUDIO PLL,
\r
2121 * so these should be setup prior to and after exiting the function.
\r
2123 pll_error_t CLOCK_SetupAudioPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg)
\r
2125 if ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK) == 0x01U)
\r
2127 /* Turn on the ext clock if system pll input select clk_in */
\r
2128 CLOCK_Enable_SysOsc(true);
\r
2130 /* Enable power VD3 for PLLs */
\r
2132 /* Power off PLL during setup changes */
\r
2133 POWER_EnablePD(kPDRUNCFG_PD_AUDIO_PLL);
\r
2135 pSetup->flags = flagcfg;
\r
2137 /* Write PLL setup data */
\r
2138 SYSCON->AUDPLLCTRL = pSetup->pllctrl;
\r
2139 SYSCON->AUDPLLNDEC = pSetup->pllndec;
\r
2140 SYSCON->AUDPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
\r
2141 SYSCON->AUDPLLPDEC = pSetup->pllpdec;
\r
2142 SYSCON->AUDPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
\r
2143 SYSCON->AUDPLLMDEC = pSetup->pllmdec;
\r
2144 SYSCON->AUDPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_SYSPLLMDEC_MREQ_SHIFT); /* latch */
\r
2145 SYSCON->AUDPLLFRAC = SYSCON_AUDPLLFRAC_SEL_EXT(1); /* disable fractional function */
\r
2147 /* Flags for lock or power on */
\r
2148 if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
\r
2150 /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
\r
2151 uint32_t maxCCO = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
\r
2152 uint32_t curSSCTRL = SYSCON->AUDPLLMDEC & ~(1UL << 17U);
\r
2154 /* Initialize and power up PLL */
\r
2155 SYSCON->AUDPLLMDEC = maxCCO;
\r
2156 POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
\r
2158 /* Set mreq to activate */
\r
2159 SYSCON->AUDPLLMDEC = maxCCO | (1UL << 17U);
\r
2161 /* Delay for 72 uSec @ 12Mhz */
\r
2162 SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
\r
2164 /* clear mreq to prepare for restoring mreq */
\r
2165 SYSCON->AUDPLLMDEC = curSSCTRL;
\r
2167 /* set original value back and activate */
\r
2168 SYSCON->AUDPLLMDEC = curSSCTRL | (1UL << 17U);
\r
2170 /* Enable peripheral states by setting low */
\r
2171 POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
\r
2173 if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
\r
2175 while (CLOCK_IsAudioPLLLocked() == false)
\r
2180 /* Update current programmed PLL rate var */
\r
2181 CLOCK_GetAudioPLLOutFromSetupUpdate(pSetup);
\r
2183 return kStatus_PLL_Success;
\r
2186 /* Set AUDIO PLL output from AUDIO PLL fractional setup structure */
\r
2187 /*! brief Set AUDIO PLL output from AUDIOPLL setup structure using the Audio Fractional divider register(precise
\r
2189 * param pSetup : Pointer to populated PLL setup structure
\r
2190 * param flagcfg : Flag configuration for PLL config structure
\r
2191 * return PLL_ERROR_SUCCESS on success, or PLL setup error code
\r
2192 * note This function will power off the PLL, setup the PLL with the
\r
2193 * new setup data, and then optionally powerup the AUDIO PLL, wait for PLL lock,
\r
2194 * and adjust system voltages to the new AUDIOPLL rate. The function will not
\r
2195 * alter any source clocks (ie, main systen clock) that may use the AUDIO PLL,
\r
2196 * so these should be setup prior to and after exiting the function.
\r
2198 pll_error_t CLOCK_SetupAudioPLLPrecFract(pll_setup_t *pSetup, uint32_t flagcfg)
\r
2200 if ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK) == 0x01U)
\r
2202 /* Turn on the ext clock if system pll input select clk_in */
\r
2203 CLOCK_Enable_SysOsc(true);
\r
2205 /* Enable power VD3 for PLLs */
\r
2207 /* Power off PLL during setup changes */
\r
2208 POWER_EnablePD(kPDRUNCFG_PD_AUDIO_PLL);
\r
2210 pSetup->flags = flagcfg;
\r
2212 /* Write PLL setup data */
\r
2213 SYSCON->AUDPLLCTRL = pSetup->pllctrl;
\r
2214 SYSCON->AUDPLLNDEC = pSetup->pllndec;
\r
2215 SYSCON->AUDPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
\r
2216 SYSCON->AUDPLLPDEC = pSetup->pllpdec;
\r
2217 SYSCON->AUDPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
\r
2218 SYSCON->AUDPLLMDEC = pSetup->pllmdec;
\r
2219 SYSCON->AUDPLLFRAC = SYSCON_AUDPLLFRAC_SEL_EXT(0); /* enable fractional function */
\r
2220 SYSCON->AUDPLLFRAC = pSetup->audpllfrac;
\r
2221 SYSCON->AUDPLLFRAC = pSetup->audpllfrac | (1UL << SYSCON_AUDPLLFRAC_REQ_SHIFT);
\r
2223 /* Enable peripheral states by setting low */
\r
2224 POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
\r
2226 if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
\r
2228 while (CLOCK_IsAudioPLLLocked() == false)
\r
2233 /* Update current programmed PLL rate var */
\r
2234 CLOCK_GetAudioPLLOutFromAudioFracSetupUpdate(pSetup);
\r
2236 return kStatus_PLL_Success;
\r
2239 /* Set Audio PLL output based on the passed Audio PLL setup data */
\r
2240 /*! brief Set AUDIO PLL output based on the passed AUDIO PLL setup data
\r
2241 * param pControl : Pointer to populated PLL control structure to generate setup with
\r
2242 * param pSetup : Pointer to PLL setup structure to be filled
\r
2243 * return PLL_ERROR_SUCCESS on success, or PLL setup error code
\r
2244 * note Actual frequency for setup may vary from the desired frequency based on the
\r
2245 * accuracy of input clocks, rounding, non-fractional PLL mode, etc.
\r
2247 pll_error_t CLOCK_SetupAudioPLLData(pll_config_t *pControl, pll_setup_t *pSetup)
\r
2250 pll_error_t pllError;
\r
2252 /* Determine input rate for the PLL */
\r
2253 if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0U)
\r
2255 inRate = pControl->inputRate;
\r
2259 inRate = CLOCK_GetAudioPLLInClockRate();
\r
2262 /* PLL flag options */
\r
2263 pllError = CLOCK_GetPllConfig(inRate, pControl->desiredRate, pSetup);
\r
2264 pSetup->pllRate = pControl->desiredRate;
\r
2268 /* Setup PLL Frequency from pre-calculated value */
\r
2270 * brief Set PLL output from PLL setup structure (precise frequency)
\r
2271 * param pSetup : Pointer to populated PLL setup structure
\r
2272 * return kStatus_PLL_Success on success, or PLL setup error code
\r
2273 * note This function will power off the PLL, setup the PLL with the
\r
2274 * new setup data, and then optionally powerup the PLL, wait for PLL lock,
\r
2275 * and adjust system voltages to the new PLL rate. The function will not
\r
2276 * alter any source clocks (ie, main systen clock) that may use the PLL,
\r
2277 * so these should be setup prior to and after exiting the function.
\r
2279 pll_error_t CLOCK_SetPLLFreq(const pll_setup_t *pSetup)
\r
2281 if ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK) == 0x01U)
\r
2283 /* Turn on the ext clock if system pll input select clk_in */
\r
2284 CLOCK_Enable_SysOsc(true);
\r
2286 /* Enable power VD3 for PLLs */
\r
2288 /* Power off PLL during setup changes */
\r
2289 POWER_EnablePD(kPDRUNCFG_PD_SYS_PLL0);
\r
2291 /* Write PLL setup data */
\r
2292 SYSCON->SYSPLLCTRL = pSetup->pllctrl;
\r
2293 SYSCON->SYSPLLNDEC = pSetup->pllndec;
\r
2294 SYSCON->SYSPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
\r
2295 SYSCON->SYSPLLPDEC = pSetup->pllpdec;
\r
2296 SYSCON->SYSPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
\r
2297 SYSCON->SYSPLLMDEC = pSetup->pllmdec;
\r
2298 SYSCON->SYSPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_SYSPLLMDEC_MREQ_SHIFT); /* latch */
\r
2300 /* Flags for lock or power on */
\r
2301 if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
\r
2303 /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
\r
2304 uint32_t maxCCO = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
\r
2305 uint32_t curSSCTRL = SYSCON->SYSPLLMDEC & ~(1UL << 17U);
\r
2307 /* Initialize and power up PLL */
\r
2308 SYSCON->SYSPLLMDEC = maxCCO;
\r
2309 POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
\r
2311 /* Set mreq to activate */
\r
2312 SYSCON->SYSPLLMDEC = maxCCO | (1UL << 17U);
\r
2314 /* Delay for 72 uSec @ 12Mhz */
\r
2315 SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
\r
2317 /* clear mreq to prepare for restoring mreq */
\r
2318 SYSCON->SYSPLLMDEC = curSSCTRL;
\r
2320 /* set original value back and activate */
\r
2321 SYSCON->SYSPLLMDEC = curSSCTRL | (1UL << 17U);
\r
2323 /* Enable peripheral states by setting low */
\r
2324 POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
\r
2326 if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
\r
2328 while (CLOCK_IsSystemPLLLocked() == false)
\r
2333 /* Update current programmed PLL rate var */
\r
2334 s_Pll_Freq = pSetup->pllRate;
\r
2336 return kStatus_PLL_Success;
\r
2339 /* Setup Audio PLL Frequency from pre-calculated value */
\r
2341 * brief Set Audio PLL output from Audio PLL setup structure (precise frequency)
\r
2342 * param pSetup : Pointer to populated PLL setup structure
\r
2343 * return kStatus_PLL_Success on success, or Audio PLL setup error code
\r
2344 * note This function will power off the PLL, setup the Audio PLL with the
\r
2345 * new setup data, and then optionally powerup the PLL, wait for Audio PLL lock,
\r
2346 * and adjust system voltages to the new PLL rate. The function will not
\r
2347 * alter any source clocks (ie, main systen clock) that may use the Audio PLL,
\r
2348 * so these should be setup prior to and after exiting the function.
\r
2350 pll_error_t CLOCK_SetAudioPLLFreq(const pll_setup_t *pSetup)
\r
2352 if ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK) == 0x01U)
\r
2354 /* Turn on the ext clock if system pll input select clk_in */
\r
2355 CLOCK_Enable_SysOsc(true);
\r
2357 /* Enable power VD3 for PLLs */
\r
2359 /* Power off Audio PLL during setup changes */
\r
2360 POWER_EnablePD(kPDRUNCFG_PD_AUDIO_PLL);
\r
2362 /* Write Audio PLL setup data */
\r
2363 SYSCON->AUDPLLCTRL = pSetup->pllctrl;
\r
2364 SYSCON->AUDPLLFRAC = pSetup->audpllfrac;
\r
2365 SYSCON->AUDPLLFRAC = pSetup->audpllfrac | (1UL << SYSCON_AUDPLLFRAC_REQ_SHIFT); /* latch */
\r
2366 SYSCON->AUDPLLNDEC = pSetup->pllndec;
\r
2367 SYSCON->AUDPLLNDEC = pSetup->pllndec | (1UL << SYSCON_AUDPLLNDEC_NREQ_SHIFT); /* latch */
\r
2368 SYSCON->AUDPLLPDEC = pSetup->pllpdec;
\r
2369 SYSCON->AUDPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_AUDPLLPDEC_PREQ_SHIFT); /* latch */
\r
2370 SYSCON->AUDPLLMDEC = pSetup->pllmdec;
\r
2371 SYSCON->AUDPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_AUDPLLMDEC_MREQ_SHIFT); /* latch */
\r
2372 SYSCON->AUDPLLFRAC = SYSCON_AUDPLLFRAC_SEL_EXT(1); /* disable fractional function */
\r
2374 /* Flags for lock or power on */
\r
2375 if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
\r
2377 /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
\r
2378 uint32_t maxCCO = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
\r
2379 uint32_t curSSCTRL = SYSCON->SYSPLLMDEC & ~(1UL << 17U);
\r
2381 /* Initialize and power up PLL */
\r
2382 SYSCON->SYSPLLMDEC = maxCCO;
\r
2383 POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
\r
2385 /* Set mreq to activate */
\r
2386 SYSCON->SYSPLLMDEC = maxCCO | (1UL << 17U);
\r
2388 /* Delay for 72 uSec @ 12Mhz */
\r
2389 SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
\r
2391 /* clear mreq to prepare for restoring mreq */
\r
2392 SYSCON->SYSPLLMDEC = curSSCTRL;
\r
2394 /* set original value back and activate */
\r
2395 SYSCON->SYSPLLMDEC = curSSCTRL | (1UL << 17U);
\r
2397 /* Enable peripheral states by setting low */
\r
2398 POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
\r
2400 if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
\r
2402 while (CLOCK_IsAudioPLLLocked() == false)
\r
2407 /* Update current programmed PLL rate var */
\r
2408 s_Audio_Pll_Freq = pSetup->pllRate;
\r
2410 return kStatus_PLL_Success;
\r
2413 /* Setup USB PLL Frequency from pre-calculated value */
\r
2415 * brief Set USB PLL output from USB PLL setup structure (precise frequency)
\r
2416 * param pSetup : Pointer to populated USB PLL setup structure
\r
2417 * return kStatus_PLL_Success on success, or USB PLL setup error code
\r
2418 * note This function will power off the USB PLL, setup the PLL with the
\r
2419 * new setup data, and then optionally powerup the USB PLL, wait for USB PLL lock,
\r
2420 * and adjust system voltages to the new USB PLL rate. The function will not
\r
2421 * alter any source clocks (ie, usb pll clock) that may use the USB PLL,
\r
2422 * so these should be setup prior to and after exiting the function.
\r
2424 pll_error_t CLOCK_SetUsbPLLFreq(const usb_pll_setup_t *pSetup)
\r
2426 uint32_t usbpllctrl, fccoHz;
\r
2427 uint8_t msel, psel, nsel;
\r
2428 bool pllDirectInput, pllDirectOutput, pllfbsel;
\r
2430 msel = pSetup->msel;
\r
2431 psel = pSetup->psel;
\r
2432 nsel = pSetup->nsel;
\r
2433 pllDirectOutput = pSetup->direct;
\r
2434 pllDirectInput = pSetup->bypass;
\r
2435 pllfbsel = pSetup->fbsel;
\r
2437 /* Input clock into the PLL cannot be lower than this */
\r
2438 if (pSetup->inputRate < USB_PLL_LOWER_IN_LIMIT)
\r
2440 return kStatus_PLL_InputTooLow;
\r
2445 /*integer_mode: Fout = M*(Fin/N), Fcco = 2*P*M*(Fin/N) */
\r
2446 fccoHz = (pSetup->inputRate / ((uint32_t)nsel + 1U)) * 2U * (msel + 1U) * SWITCH_USB_PSEL(psel);
\r
2448 /* USB PLL CCO out rate cannot be lower than this */
\r
2449 if (fccoHz < USB_PLL_MIN_CCO_FREQ_MHZ)
\r
2451 return kStatus_PLL_CCOTooLow;
\r
2453 /* USB PLL CCO out rate cannot be Higher than this */
\r
2454 if (fccoHz > USB_PLL_MAX_CCO_FREQ_MHZ)
\r
2456 return kStatus_PLL_CCOTooHigh;
\r
2461 /* non integer_mode: Fout = M*(Fin/N)/(2*P), Fcco = M * (Fin/N) */
\r
2462 fccoHz = pSetup->inputRate / ((uint32_t)nsel + 1U) * (msel + 1U);
\r
2464 /* USB PLL CCO out rate cannot be lower than this */
\r
2465 if (fccoHz < USB_PLL_MIN_CCO_FREQ_MHZ)
\r
2467 return kStatus_PLL_CCOTooLow;
\r
2469 /* USB PLL CCO out rate cannot be Higher than this */
\r
2470 if (fccoHz > USB_PLL_MAX_CCO_FREQ_MHZ)
\r
2472 return kStatus_PLL_CCOTooHigh;
\r
2476 /* If configure the USB HOST clock, VD5 power for USB PHY should be enable
\r
2477 before the PLL is working */
\r
2478 /* Turn on the ext clock for usb pll input */
\r
2479 CLOCK_Enable_SysOsc(true);
\r
2481 /* Enable power VD3 for PLLs */
\r
2484 /* Power on the VD5 for USB PHY */
\r
2485 POWER_SetUsbPhy();
\r
2487 /* Power off USB PLL during setup changes */
\r
2488 POWER_EnablePD(kPDRUNCFG_PD_USB_PLL);
\r
2490 /* Write USB PLL setup data */
\r
2491 usbpllctrl = USB_PLL_NSEL_VAL_SET(nsel) | /* NSEL VALUE */
\r
2492 USB_PLL_PSEL_VAL_SET(psel) | /* PSEL VALUE */
\r
2493 USB_PLL_MSEL_VAL_SET(msel) | /* MSEL VALUE */
\r
2494 (uint32_t)pllDirectInput << SYSCON_USBPLLCTRL_BYPASS_SHIFT | /* BYPASS DISABLE */
\r
2495 (uint32_t)pllDirectOutput << SYSCON_USBPLLCTRL_DIRECT_SHIFT | /* DIRECTO DISABLE */
\r
2496 (uint32_t)pllfbsel << SYSCON_USBPLLCTRL_FBSEL_SHIFT; /* FBSEL SELECT */
\r
2498 SYSCON->USBPLLCTRL = usbpllctrl;
\r
2500 POWER_DisablePD(kPDRUNCFG_PD_USB_PLL);
\r
2502 /* Delay for 72 uSec @ 12Mhz for the usb pll to lock */
\r
2503 SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
\r
2504 if (false == pllDirectInput)
\r
2506 while (CLOCK_IsUsbPLLLocked() == false)
\r
2510 CLOCK_GetUsbPLLOutFromSetupUpdate(pSetup);
\r
2511 return kStatus_PLL_Success;
\r
2514 /* Set System PLL clock based on the input frequency and multiplier */
\r
2515 /*! brief Set PLL output based on the multiplier and input frequency
\r
2516 * param multiply_by : multiplier
\r
2517 * param input_freq : Clock input frequency of the PLL
\r
2519 * note Unlike the Chip_Clock_SetupSystemPLLPrec() function, this
\r
2520 * function does not disable or enable PLL power, wait for PLL lock,
\r
2521 * or adjust system voltages. These must be done in the application.
\r
2522 * The function will not alter any source clocks (ie, main systen clock)
\r
2523 * that may use the PLL, so these should be setup prior to and after
\r
2524 * exiting the function.
\r
2526 void CLOCK_SetupSystemPLLMult(uint32_t multiply_by, uint32_t input_freq)
\r
2528 uint32_t cco_freq = input_freq * multiply_by;
\r
2529 uint32_t pdec = 1U;
\r
2533 uint32_t mdec, ndec;
\r
2535 uint32_t directo = SYSCON_SYSPLLCTRL_DIRECTO(1);
\r
2537 while (cco_freq < 275000000U)
\r
2539 multiply_by <<= 1U; /* double value in each iteration */
\r
2540 pdec <<= 1U; /* correspondingly double pdec to cancel effect of double msel */
\r
2541 cco_freq = input_freq * multiply_by;
\r
2544 if (multiply_by < 60U)
\r
2546 seli = (multiply_by & 0x3cU) + 4U;
\r
2547 selp = (multiply_by >> 1U) + 1U;
\r
2552 if (multiply_by > 16384U)
\r
2556 else if (multiply_by > 8192U)
\r
2560 else if (multiply_by > 2048U)
\r
2564 else if (multiply_by >= 501U)
\r
2570 seli = 4U * (1024U / (multiply_by + 9U));
\r
2576 directo = 0U; /* use post divider */
\r
2577 pdec = pdec / 2U; /* Account for minus 1 encoding */
\r
2578 /* Translate P value */
\r
2582 pdec = 0x62U; /* 1 * 2 */
\r
2585 pdec = 0x42U; /* 2 * 2 */
\r
2588 pdec = 0x02U; /* 4 * 2 */
\r
2591 pdec = 0x0bU; /* 8 * 2 */
\r
2594 pdec = 0x11U; /* 16 * 2 */
\r
2597 pdec = 0x08U; /* 32 * 2 */
\r
2605 mdec = PLL_MDEC_VAL_SET(pllEncodeM(multiply_by));
\r
2606 ndec = 0x302U; /* pre divide by 1 (hardcoded) */
\r
2608 SYSCON->SYSPLLCTRL = directo | (selr << SYSCON_SYSPLLCTRL_SELR_SHIFT) | (seli << SYSCON_SYSPLLCTRL_SELI_SHIFT) |
\r
2609 (selp << SYSCON_SYSPLLCTRL_SELP_SHIFT);
\r
2610 SYSCON->SYSPLLPDEC = pdec | (1U << 7U); /* set Pdec value and assert preq */
\r
2611 SYSCON->SYSPLLNDEC = ndec | (1UL << 10U); /* set Pdec value and assert preq */
\r
2612 SYSCON->SYSPLLMDEC = (1UL << 17U) | mdec; /* select non sscg MDEC value, assert mreq and select mdec value */
\r
2615 /* Enable USB DEVICE FULL SPEED clock */
\r
2616 /*! brief Enable USB Device FS clock.
\r
2617 * param src : clock source
\r
2618 * param freq: clock frequency
\r
2619 * Enable USB Device Full Speed clock.
\r
2621 bool CLOCK_EnableUsbfs0DeviceClock(clock_usb_src_t src, uint32_t freq)
\r
2625 CLOCK_DisableClock(kCLOCK_Usbd0);
\r
2627 if (kCLOCK_UsbSrcFro == src)
\r
2632 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2U, false); /*!< Div by 2 to get 48MHz, no divider reset */
\r
2636 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false); /*!< Div by 1 to get 48MHz, no divider reset */
\r
2643 /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
\r
2644 SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
\r
2645 SYSCON_FROCTRL_USBCLKADJ_MASK;
\r
2646 /* Select FRO 96 or 48 MHz */
\r
2647 CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
\r
2651 /*Set the USB PLL as the Usb0 CLK*/
\r
2652 POWER_DisablePD(kPDRUNCFG_PD_USB_PLL);
\r
2654 usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
\r
2656 (void)CLOCK_SetUsbPLLFreq(&pll_setup);
\r
2657 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
\r
2658 CLOCK_AttachClk(kUSB_PLL_to_USB0_CLK);
\r
2659 SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
\r
2661 CLOCK_EnableClock(kCLOCK_Usbd0);
\r
2662 CLOCK_EnableClock(kCLOCK_UsbRam1);
\r
2667 /* Enable USB HOST FULL SPEED clock */
\r
2668 /*! brief Enable USB HOST FS clock.
\r
2669 * param src : clock source
\r
2670 * param freq: clock frequency
\r
2671 * Enable USB HOST Full Speed clock.
\r
2673 bool CLOCK_EnableUsbfs0HostClock(clock_usb_src_t src, uint32_t freq)
\r
2677 CLOCK_DisableClock(kCLOCK_Usbhmr0);
\r
2678 CLOCK_DisableClock(kCLOCK_Usbhsl0);
\r
2680 if (kCLOCK_UsbSrcFro == src)
\r
2685 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2U, false); /*!< Div by 2 to get 48MHz, no divider reset */
\r
2689 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false); /*!< Div by 1 to get 48MHz, no divider reset */
\r
2696 /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
\r
2697 SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
\r
2698 SYSCON_FROCTRL_USBCLKADJ_MASK;
\r
2699 /* Select FRO 96 or 48 MHz */
\r
2700 CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
\r
2704 /*Set the USB PLL as the Usb0 CLK*/
\r
2705 POWER_DisablePD(kPDRUNCFG_PD_USB_PLL);
\r
2707 usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
\r
2709 (void)CLOCK_SetUsbPLLFreq(&pll_setup);
\r
2710 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
\r
2711 CLOCK_AttachClk(kUSB_PLL_to_USB0_CLK);
\r
2712 SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
\r
2714 CLOCK_EnableClock(kCLOCK_Usbhmr0);
\r
2715 CLOCK_EnableClock(kCLOCK_Usbhsl0);
\r
2716 CLOCK_EnableClock(kCLOCK_UsbRam1);
\r
2721 /* Enable USB DEVICE HIGH SPEED clock */
\r
2722 /*! brief Enable USB Device HS clock.
\r
2723 * param src : clock source
\r
2724 * param freq: clock frequency
\r
2725 * Enable USB Device High Speed clock.
\r
2727 bool CLOCK_EnableUsbhs0DeviceClock(clock_usb_src_t src, uint32_t freq)
\r
2730 CLOCK_DisableClock(kCLOCK_Usbd1);
\r
2731 /* Power on the VD5 for USB PHY */
\r
2732 POWER_SetUsbPhy();
\r
2733 if (kCLOCK_UsbSrcFro == src)
\r
2738 CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 2U, false); /*!< Div by 2 to get 48MHz, no divider reset */
\r
2742 CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1U, false); /*!< Div by 1 to get 48MHz, no divider reset */
\r
2749 /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
\r
2750 SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
\r
2751 SYSCON_FROCTRL_USBCLKADJ_MASK;
\r
2752 /* Select FRO 96 or 48 MHz */
\r
2753 CLOCK_AttachClk(kFRO_HF_to_USB1_CLK);
\r
2757 SDK_DelayAtLeastUs(50, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
\r
2758 usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
\r
2760 (void)CLOCK_SetUsbPLLFreq(&pll_setup);
\r
2762 /* Select USB PLL output as USB clock src */
\r
2763 CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1U, false);
\r
2764 CLOCK_AttachClk(kUSB_PLL_to_USB1_CLK);
\r
2767 SDK_DelayAtLeastUs(50, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
\r
2768 /* Enable USB1D and USB1RAM */
\r
2769 CLOCK_EnableClock(kCLOCK_Usbd1);
\r
2770 CLOCK_EnableClock(kCLOCK_UsbRam1);
\r
2771 POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /* Turn on power for USB PHY */
\r
2775 /* Enable USB HOST HIGH SPEED clock */
\r
2776 /*! brief Enable USB HOST HS clock.
\r
2777 * param src : clock source
\r
2778 * param freq: clock frequency
\r
2779 * Enable USB HOST High Speed clock.
\r
2781 bool CLOCK_EnableUsbhs0HostClock(clock_usb_src_t src, uint32_t freq)
\r
2784 CLOCK_DisableClock(kCLOCK_Usbh1);
\r
2785 /* Power on the VD5 for USB PHY */
\r
2786 POWER_SetUsbPhy();
\r
2787 if (kCLOCK_UsbSrcFro == src)
\r
2792 CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 2U, false); /*!< Div by 2 to get 48MHz, no divider reset */
\r
2796 CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1U, false); /*!< Div by 1 to get 48MHz, no divider reset */
\r
2803 /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
\r
2804 SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
\r
2805 SYSCON_FROCTRL_USBCLKADJ_MASK;
\r
2806 /* Select FRO 96 or 48 MHz */
\r
2807 CLOCK_AttachClk(kFRO_HF_to_USB1_CLK);
\r
2811 SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
\r
2812 usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
\r
2814 (void)CLOCK_SetUsbPLLFreq(&pll_setup);
\r
2816 /* Select USB PLL output as USB clock src */
\r
2817 CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1U, false);
\r
2818 CLOCK_AttachClk(kUSB_PLL_to_USB1_CLK);
\r
2821 SDK_DelayAtLeastUs(50, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
\r
2822 /* Enable USBh1 and USB1RAM */
\r
2823 CLOCK_EnableClock(kCLOCK_Usbh1);
\r
2824 CLOCK_EnableClock(kCLOCK_UsbRam1);
\r
2825 POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /* Turn on power for USB PHY */
\r