fsl_clock.c 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976
  1. /*
  2. * Copyright (c) 2017 - 2018 , NXP
  3. * All rights reserved.
  4. *
  5. * SPDX-License-Identifier: BSD-3-Clause
  6. */
  7. #include "fsl_common.h"
  8. #include "fsl_clock.h"
  9. #include "fsl_power.h"
  10. /*******************************************************************************
  11. * Definitions
  12. ******************************************************************************/
  13. /* Component ID definition, used by tools. */
  14. #ifndef FSL_COMPONENT_ID
  15. #define FSL_COMPONENT_ID "platform.drivers.clock"
  16. #endif
  17. #define NVALMAX (0x100U)
  18. #define PVALMAX (0x20U)
  19. #define MVALMAX (0x8000U)
  20. #define USB_NVALMAX (0x4U)
  21. #define USB_PVALMAX (0x8U)
  22. #define USB_MVALMAX (0x100U)
  23. #define PLL_MAX_N_DIV 0x100U
  24. #define USB_PLL_MAX_N_DIV 0x100U
  25. /*--------------------------------------------------------------------------
  26. !!! If required these #defines can be moved to chip library file
  27. ----------------------------------------------------------------------------*/
  28. #define PLL_SSCG1_MDEC_VAL_P (10U) /* MDEC is in bits 16 downto 0 */
  29. #define PLL_SSCG1_MDEC_VAL_M (0x3FFFC00ULL << PLL_SSCG1_MDEC_VAL_P) /* NDEC is in bits 9 downto 0 */
  30. #define PLL_NDEC_VAL_P (0U) /* NDEC is in bits 9:0 */
  31. #define PLL_NDEC_VAL_M (0xFFUL << PLL_NDEC_VAL_P)
  32. #define PLL_PDEC_VAL_P (0U) /*!< PDEC is in bits 6:0 */
  33. #define PLL_PDEC_VAL_M (0x1FUL << PLL_PDEC_VAL_P)
  34. #define PLL_MIN_CCO_FREQ_MHZ (275000000U)
  35. #define PLL_MAX_CCO_FREQ_MHZ (550000000U)
  36. #define PLL_LOWER_IN_LIMIT (4000U) /*!< Minimum PLL input rate */
  37. #define PLL_MIN_IN_SSMODE (2000000U)
  38. #define PLL_MAX_IN_SSMODE (4000000U)
  39. /*!< Middle of the range values for spread-spectrum */
  40. #define PLL_SSCG_MF_FREQ_VALUE 4U
  41. #define PLL_SSCG_MC_COMP_VALUE 2U
  42. #define PLL_SSCG_MR_DEPTH_VALUE 4U
  43. #define PLL_SSCG_DITHER_VALUE 0U
  44. /* PLL NDEC reg */
  45. #define PLL_NDEC_VAL_SET(value) (((unsigned long)(value) << PLL_NDEC_VAL_P) & PLL_NDEC_VAL_M)
  46. /* PLL PDEC reg */
  47. #define PLL_PDEC_VAL_SET(value) (((unsigned long)(value) << PLL_PDEC_VAL_P) & PLL_PDEC_VAL_M)
  48. /* SSCG control0 */
  49. #define PLL_SSCG1_MDEC_VAL_SET(value) (((unsigned long)(value) << PLL_SSCG1_MDEC_VAL_P) & PLL_SSCG1_MDEC_VAL_M)
  50. /* SSCG control1 */
  51. #define PLL_SSCG_MD_FRACT_P 0U
  52. #define PLL_SSCG_MD_INT_P 25U
  53. #define PLL_SSCG_MD_FRACT_M (0x1FFFFFFUL << PLL_SSCG_MD_FRACT_P)
  54. #define PLL_SSCG_MD_INT_M ((uint64_t)0xFFUL << PLL_SSCG_MD_INT_P)
  55. #define PLL_SSCG_MD_FRACT_SET(value) (((uint64_t)(value) << PLL_SSCG_MD_FRACT_P) & PLL_SSCG_MD_FRACT_M)
  56. #define PLL_SSCG_MD_INT_SET(value) (((uint64_t)(value) << PLL_SSCG_MD_INT_P) & PLL_SSCG_MD_INT_M)
  57. /* Saved value of PLL output rate, computed whenever needed to save run-time
  58. computation on each call to retrive the PLL rate. */
  59. static uint32_t s_Pll_Freq;
  60. static uint32_t s_Usb_Pll_Freq;
  61. /** External clock rate on the CLKIN pin in Hz. If not used,
  62. set this to 0. Otherwise, set it to the exact rate in Hz this pin is
  63. being driven at. */
  64. static uint32_t s_Ext_Clk_Freq = 16000000U;
  65. static uint32_t s_I2S_Mclk_Freq = 0U;
  66. /*******************************************************************************
  67. * Variables
  68. ******************************************************************************/
  69. /*******************************************************************************
  70. * Prototypes
  71. ******************************************************************************/
  72. /* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */
  73. static void pllFindSel(uint32_t M, bool bypassFBDIV2, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR);
  74. /* Get predivider (N) from PLL NDEC setting */
  75. static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg);
  76. /* Get postdivider (P) from PLL PDEC setting */
  77. static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg);
  78. /* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */
  79. static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg);
  80. /* Get the greatest common divisor */
  81. static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n);
  82. /* Set PLL output based on desired output rate */
  83. static pll_error_t CLOCK_GetPllConfig(
  84. uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useFeedbackDiv2, bool useSS);
  85. /* Update local PLL rate variable */
  86. static void CLOCK_GetPLL0OutFromSetupUpdate(pll_setup_t *pSetup);
  87. /*******************************************************************************
  88. * Code
  89. ******************************************************************************/
  90. /* Clock Selection for IP */
  91. /**
  92. * brief Configure the clock selection muxes.
  93. * param connection : Clock to be configured.
  94. * return Nothing
  95. */
  96. void CLOCK_AttachClk(clock_attach_id_t connection)
  97. {
  98. uint8_t mux;
  99. uint8_t sel;
  100. uint16_t item;
  101. uint32_t i;
  102. volatile uint32_t *pClkSel;
  103. pClkSel = &(SYSCON->SYSTICKCLKSELX[0]);
  104. if (connection != kNONE_to_NONE)
  105. {
  106. for (i = 0U; i < 2U; i++)
  107. {
  108. if (connection == 0U)
  109. {
  110. break;
  111. }
  112. item = (uint16_t)GET_ID_ITEM(connection);
  113. if (item)
  114. {
  115. mux = GET_ID_ITEM_MUX(item);
  116. sel = GET_ID_ITEM_SEL(item);
  117. if (mux == CM_RTCOSC32KCLKSEL)
  118. {
  119. PMC->RTCOSC32K |= sel;
  120. }
  121. else
  122. {
  123. pClkSel[mux] = sel;
  124. }
  125. }
  126. connection = GET_ID_NEXT_ITEM(connection); /* pick up next descriptor */
  127. }
  128. }
  129. }
  130. /* Return the actual clock attach id */
  131. /**
  132. * brief Get the actual clock attach id.
  133. * This fuction uses the offset in input attach id, then it reads the actual source value in
  134. * the register and combine the offset to obtain an actual attach id.
  135. * param attachId : Clock attach id to get.
  136. * return Clock source value.
  137. */
  138. clock_attach_id_t CLOCK_GetClockAttachId(clock_attach_id_t attachId)
  139. {
  140. uint8_t mux;
  141. uint8_t actualSel;
  142. uint32_t i;
  143. uint32_t actualAttachId = 0U;
  144. uint32_t selector = GET_ID_SELECTOR(attachId);
  145. volatile uint32_t *pClkSel;
  146. pClkSel = &(SYSCON->SYSTICKCLKSELX[0]);
  147. if (attachId == kNONE_to_NONE)
  148. {
  149. return kNONE_to_NONE;
  150. }
  151. for (i = 0U; i < 2U; i++)
  152. {
  153. mux = GET_ID_ITEM_MUX(attachId);
  154. if (attachId)
  155. {
  156. if (mux == CM_RTCOSC32KCLKSEL)
  157. {
  158. actualSel = PMC->RTCOSC32K;
  159. }
  160. else
  161. {
  162. actualSel = pClkSel[mux];
  163. }
  164. /* Consider the combination of two registers */
  165. actualAttachId |= CLK_ATTACH_ID(mux, actualSel, i);
  166. }
  167. attachId = GET_ID_NEXT_ITEM(attachId); /*!< pick up next descriptor */
  168. }
  169. actualAttachId |= selector;
  170. return (clock_attach_id_t)actualAttachId;
  171. }
  172. /* Set IP Clock Divider */
  173. /**
  174. * brief Setup peripheral clock dividers.
  175. * param div_name : Clock divider name
  176. * param divided_by_value: Value to be divided
  177. * param reset : Whether to reset the divider counter.
  178. * return Nothing
  179. */
  180. void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset)
  181. {
  182. volatile uint32_t *pClkDiv;
  183. pClkDiv = &(SYSCON->SYSTICKCLKDIV0);
  184. if (reset)
  185. {
  186. pClkDiv[div_name] = 1U << 29U;
  187. }
  188. if (divided_by_value == 0U) /*!< halt */
  189. {
  190. pClkDiv[div_name] = 1U << 30U;
  191. }
  192. else
  193. {
  194. pClkDiv[div_name] = (divided_by_value - 1U);
  195. }
  196. }
  197. /* Set RTC 1KHz Clock Divider */
  198. /**
  199. * brief Setup rtc 1khz clock divider.
  200. * param divided_by_value: Value to be divided
  201. * return Nothing
  202. */
  203. void CLOCK_SetRtc1khzClkDiv(uint32_t divided_by_value)
  204. {
  205. PMC->RTCOSC32K |= (((divided_by_value - 28U) << PMC_RTCOSC32K_CLK1KHZDIV_SHIFT) | PMC_RTCOSC32K_CLK1KHZDIV_MASK);
  206. }
  207. /* Set RTC 1KHz Clock Divider */
  208. /**
  209. * brief Setup rtc 1hz clock divider.
  210. * param divided_by_value: Value to be divided
  211. * return Nothing
  212. */
  213. void CLOCK_SetRtc1hzClkDiv(uint32_t divided_by_value)
  214. {
  215. if (divided_by_value == 0U) /*!< halt */
  216. {
  217. PMC->RTCOSC32K |= (1U << PMC_RTCOSC32K_CLK1HZDIVHALT_SHIFT);
  218. }
  219. else
  220. {
  221. PMC->RTCOSC32K |=
  222. (((divided_by_value - 31744U) << PMC_RTCOSC32K_CLK1HZDIV_SHIFT) | PMC_RTCOSC32K_CLK1HZDIV_MASK);
  223. }
  224. }
  225. /* Set FRO Clocking */
  226. /**
  227. * brief Initialize the Core clock to given frequency (12, 48 or 96 MHz).
  228. * Turns on FRO and uses default CCO, if freq is 12000000, then high speed output is off, else high speed output is
  229. * enabled.
  230. * param iFreq : Desired frequency (must be one of #CLK_FRO_12MHZ or #CLK_FRO_48MHZ or #CLK_FRO_96MHZ)
  231. * return returns success or fail status.
  232. */
  233. status_t CLOCK_SetupFROClocking(uint32_t iFreq)
  234. {
  235. if ((iFreq != 12000000U) && (iFreq != 48000000U) && (iFreq != 96000000U))
  236. {
  237. return kStatus_Fail;
  238. }
  239. /* Enable Analog Control module */
  240. SYSCON->PRESETCTRLCLR[2] = (1U << SYSCON_PRESETCTRL2_ANALOG_CTRL_RST_SHIFT);
  241. SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_ANALOG_CTRL_MASK;
  242. /* Power up the FRO192M */
  243. POWER_DisablePD(kPDRUNCFG_PD_FRO192M);
  244. if (iFreq == 96000000U)
  245. {
  246. ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_ENA_96MHZCLK(1);
  247. }
  248. else if (iFreq == 48000000U)
  249. {
  250. ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_ENA_48MHZCLK(1);
  251. }
  252. else
  253. {
  254. ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_ENA_12MHZCLK(1);
  255. }
  256. return 0U;
  257. }
  258. /* Set the FLASH wait states for the passed frequency */
  259. /**
  260. * brief Set the flash wait states for the input freuqency.
  261. * param iFreq : Input frequency
  262. * return Nothing
  263. */
  264. void CLOCK_SetFLASHAccessCyclesForFreq(uint32_t iFreq)
  265. {
  266. uint32_t num_wait_states;
  267. float f_num_wait_states = 0.00000009 * ((float)iFreq);
  268. /* Rational : timing is closed at 100MHz+10% tolerance, hence the ¡®9¡¯ in the formula above */
  269. num_wait_states = (uint32_t)f_num_wait_states;
  270. /*
  271. * It is guaranteed by design that "num_wait_states = 8"
  272. * will fit all frequencies (below and including) 100 MHz.
  273. */
  274. if (num_wait_states >= 9)
  275. {
  276. num_wait_states = 8;
  277. }
  278. /* Don't alter other bits */
  279. SYSCON->FMCCR = (SYSCON->FMCCR & ~SYSCON_FMCCR_FMCTIM_MASK) |
  280. ((num_wait_states << SYSCON_FMCCR_FMCTIM_SHIFT) & SYSCON_FMCCR_FMCTIM_MASK);
  281. }
  282. /* Set EXT OSC Clk */
  283. /**
  284. * brief Initialize the external osc clock to given frequency.
  285. * param iFreq : Desired frequency (must be equal to exact rate in Hz)
  286. * return returns success or fail status.
  287. */
  288. status_t CLOCK_SetupExtClocking(uint32_t iFreq)
  289. {
  290. if (iFreq >= 32000000U)
  291. {
  292. return kStatus_Fail;
  293. }
  294. /* Turn on power for crystal 32 MHz */
  295. POWER_DisablePD(kPDRUNCFG_PD_XTAL32M);
  296. POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M);
  297. /* Enable clock_in clock for clock module. */
  298. SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK;
  299. s_Ext_Clk_Freq = iFreq;
  300. return 0U;
  301. }
  302. /* Set I2S MCLK Clk */
  303. /**
  304. * brief Initialize the I2S MCLK clock to given frequency.
  305. * param iFreq : Desired frequency (must be equal to exact rate in Hz)
  306. * return returns success or fail status.
  307. */
  308. status_t CLOCK_SetupI2SMClkClocking(uint32_t iFreq)
  309. {
  310. s_I2S_Mclk_Freq = iFreq;
  311. return 0U;
  312. }
  313. /* Get CLOCK OUT Clk */
  314. /*! brief Return Frequency of ClockOut
  315. * return Frequency of ClockOut
  316. */
  317. uint32_t CLOCK_GetClockOutClkFreq(void)
  318. {
  319. uint32_t freq = 0U;
  320. switch (SYSCON->CLKOUTSEL)
  321. {
  322. case 0U:
  323. freq = CLOCK_GetCoreSysClkFreq();
  324. break;
  325. case 1U:
  326. freq = CLOCK_GetPll0OutFreq();
  327. break;
  328. case 2U:
  329. freq = CLOCK_GetExtClkFreq();
  330. break;
  331. case 3U:
  332. freq = CLOCK_GetFroHfFreq();
  333. break;
  334. case 4U:
  335. freq = CLOCK_GetFro1MFreq();
  336. break;
  337. case 5U:
  338. freq = CLOCK_GetPll1OutFreq();
  339. break;
  340. case 6U:
  341. freq = CLOCK_GetOsc32KFreq();
  342. break;
  343. case 7U:
  344. freq = 0U;
  345. break;
  346. default:
  347. break;
  348. }
  349. return freq / ((SYSCON->CLKOUTDIV & 0xffU) + 1U);
  350. }
  351. /* Get ADC Clk */
  352. /*! brief Return Frequency of Adc Clock
  353. * return Frequency of Adc.
  354. */
  355. uint32_t CLOCK_GetAdcClkFreq(void)
  356. {
  357. uint32_t freq = 0U;
  358. switch (SYSCON->ADCCLKSEL)
  359. {
  360. case 0U:
  361. freq = CLOCK_GetCoreSysClkFreq();
  362. break;
  363. case 1U:
  364. freq = CLOCK_GetPll0OutFreq();
  365. break;
  366. case 2U:
  367. freq = CLOCK_GetFroHfFreq();
  368. break;
  369. case 7U:
  370. freq = 0U;
  371. break;
  372. default:
  373. break;
  374. }
  375. return freq / ((SYSCON->ADCCLKDIV & SYSCON_ADCCLKDIV_DIV_MASK) + 1U);
  376. }
  377. /* Get USB0 Clk */
  378. /*! brief Return Frequency of Usb0 Clock
  379. * return Frequency of Usb0 Clock.
  380. */
  381. uint32_t CLOCK_GetUsb0ClkFreq(void)
  382. {
  383. uint32_t freq = 0U;
  384. switch (SYSCON->USB0CLKSEL)
  385. {
  386. case 0U:
  387. freq = CLOCK_GetCoreSysClkFreq();
  388. break;
  389. case 1U:
  390. freq = CLOCK_GetPll0OutFreq();
  391. break;
  392. case 3U:
  393. freq = CLOCK_GetFroHfFreq();
  394. break;
  395. case 5U:
  396. freq = CLOCK_GetPll1OutFreq();
  397. break;
  398. case 7U:
  399. freq = 0U;
  400. break;
  401. default:
  402. break;
  403. }
  404. return freq / ((SYSCON->USB0CLKDIV & 0xffU) + 1U);
  405. }
  406. /* Get USB1 Clk */
  407. /*! brief Return Frequency of Usb1 Clock
  408. * return Frequency of Usb1 Clock.
  409. */
  410. uint32_t CLOCK_GetUsb1ClkFreq(void)
  411. {
  412. return (ANACTRL->XO32M_CTRL & ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT_MASK) ? s_Ext_Clk_Freq : 0U;
  413. }
  414. /* Get MCLK Clk */
  415. /*! brief Return Frequency of MClk Clock
  416. * return Frequency of MClk Clock.
  417. */
  418. uint32_t CLOCK_GetMclkClkFreq(void)
  419. {
  420. uint32_t freq = 0U;
  421. switch (SYSCON->MCLKCLKSEL)
  422. {
  423. case 0U:
  424. freq = CLOCK_GetFroHfFreq();
  425. break;
  426. case 1U:
  427. freq = CLOCK_GetPll0OutFreq();
  428. break;
  429. case 7U:
  430. freq = 0U;
  431. break;
  432. default:
  433. break;
  434. }
  435. return freq / ((SYSCON->MCLKDIV & 0xffU) + 1U);
  436. }
  437. /* Get SCTIMER Clk */
  438. /*! brief Return Frequency of SCTimer Clock
  439. * return Frequency of SCTimer Clock.
  440. */
  441. uint32_t CLOCK_GetSctClkFreq(void)
  442. {
  443. uint32_t freq = 0U;
  444. switch (SYSCON->SCTCLKSEL)
  445. {
  446. case 0U:
  447. freq = CLOCK_GetCoreSysClkFreq();
  448. break;
  449. case 1U:
  450. freq = CLOCK_GetPll0OutFreq();
  451. break;
  452. case 2U:
  453. freq = CLOCK_GetExtClkFreq();
  454. break;
  455. case 3U:
  456. freq = CLOCK_GetFroHfFreq();
  457. break;
  458. case 5U:
  459. freq = CLOCK_GetI2SMClkFreq();
  460. break;
  461. case 7U:
  462. freq = 0U;
  463. break;
  464. default:
  465. break;
  466. }
  467. return freq / ((SYSCON->SCTCLKDIV & 0xffU) + 1U);
  468. }
  469. /* Get SDIO Clk */
  470. /*! brief Return Frequency of SDIO Clock
  471. * return Frequency of SDIO Clock.
  472. */
  473. uint32_t CLOCK_GetSdioClkFreq(void)
  474. {
  475. uint32_t freq = 0U;
  476. switch (SYSCON->SDIOCLKSEL)
  477. {
  478. case 0U:
  479. freq = CLOCK_GetCoreSysClkFreq();
  480. break;
  481. case 1U:
  482. freq = CLOCK_GetPll0OutFreq();
  483. break;
  484. case 3U:
  485. freq = CLOCK_GetFroHfFreq();
  486. break;
  487. case 5U:
  488. freq = CLOCK_GetPll1OutFreq();
  489. break;
  490. case 7U:
  491. freq = 0U;
  492. break;
  493. default:
  494. break;
  495. }
  496. return freq / ((SYSCON->SDIOCLKDIV & 0xffU) + 1U);
  497. }
  498. /* Get FRO 12M Clk */
  499. /*! brief Return Frequency of FRO 12MHz
  500. * return Frequency of FRO 12MHz
  501. */
  502. uint32_t CLOCK_GetFro12MFreq(void)
  503. {
  504. return (PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_FRO192M_MASK) ?
  505. 0 :
  506. (ANACTRL->FRO192M_CTRL & ANACTRL_FRO192M_CTRL_ENA_12MHZCLK_MASK) ? 12000000U : 0U;
  507. }
  508. /* Get FRO 1M Clk */
  509. /*! brief Return Frequency of FRO 1MHz
  510. * return Frequency of FRO 1MHz
  511. */
  512. uint32_t CLOCK_GetFro1MFreq(void)
  513. {
  514. return (SYSCON->CLOCK_CTRL & SYSCON_CLOCK_CTRL_FRO1MHZ_CLK_ENA_MASK) ? 1000000U : 0U;
  515. }
  516. /* Get EXT OSC Clk */
  517. /*! brief Return Frequency of External Clock
  518. * return Frequency of External Clock. If no external clock is used returns 0.
  519. */
  520. uint32_t CLOCK_GetExtClkFreq(void)
  521. {
  522. return (ANACTRL->XO32M_CTRL & ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK) ? s_Ext_Clk_Freq : 0U;
  523. }
  524. /* Get WATCH DOG Clk */
  525. /*! brief Return Frequency of Watchdog
  526. * return Frequency of Watchdog
  527. */
  528. uint32_t CLOCK_GetWdtClkFreq(void)
  529. {
  530. return CLOCK_GetFro1MFreq() / ((SYSCON->WDTCLKDIV & SYSCON_WDTCLKDIV_DIV_MASK) + 1U);
  531. }
  532. /* Get HF FRO Clk */
  533. /*! brief Return Frequency of High-Freq output of FRO
  534. * return Frequency of High-Freq output of FRO
  535. */
  536. uint32_t CLOCK_GetFroHfFreq(void)
  537. {
  538. return (PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_FRO192M_MASK) ?
  539. 0 :
  540. (ANACTRL->FRO192M_CTRL & ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK) ? 96000000U : 0U;
  541. }
  542. /* Get SYSTEM PLL Clk */
  543. /*! brief Return Frequency of PLL
  544. * return Frequency of PLL
  545. */
  546. uint32_t CLOCK_GetPll0OutFreq(void)
  547. {
  548. return s_Pll_Freq;
  549. }
  550. /* Get USB PLL Clk */
  551. /*! brief Return Frequency of USB PLL
  552. * return Frequency of PLL
  553. */
  554. uint32_t CLOCK_GetPll1OutFreq(void)
  555. {
  556. return s_Usb_Pll_Freq;
  557. }
  558. /* Get RTC OSC Clk */
  559. /*! brief Return Frequency of 32kHz osc
  560. * return Frequency of 32kHz osc
  561. */
  562. uint32_t CLOCK_GetOsc32KFreq(void)
  563. {
  564. return ((~(PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_FRO32K_MASK)) && (PMC->RTCOSC32K & PMC_RTCOSC32K_SEL(0))) ?
  565. CLK_RTC_32K_CLK :
  566. ((~(PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_XTAL32K_MASK)) && (PMC->RTCOSC32K & PMC_RTCOSC32K_SEL(1))) ?
  567. CLK_RTC_32K_CLK :
  568. 0U;
  569. }
  570. /* Get MAIN Clk */
  571. /*! brief Return Frequency of Core System
  572. * return Frequency of Core System
  573. */
  574. uint32_t CLOCK_GetCoreSysClkFreq(void)
  575. {
  576. uint32_t freq = 0U;
  577. switch (SYSCON->MAINCLKSELB)
  578. {
  579. case 0U:
  580. if (SYSCON->MAINCLKSELA == 0U)
  581. {
  582. freq = CLOCK_GetFro12MFreq();
  583. }
  584. else if (SYSCON->MAINCLKSELA == 1U)
  585. {
  586. freq = CLOCK_GetExtClkFreq();
  587. }
  588. else if (SYSCON->MAINCLKSELA == 2U)
  589. {
  590. freq = CLOCK_GetFro1MFreq();
  591. }
  592. else if (SYSCON->MAINCLKSELA == 3U)
  593. {
  594. freq = CLOCK_GetFroHfFreq();
  595. }
  596. else
  597. {
  598. }
  599. break;
  600. case 1U:
  601. freq = CLOCK_GetPll0OutFreq();
  602. break;
  603. case 2U:
  604. freq = CLOCK_GetPll1OutFreq();
  605. break;
  606. case 3U:
  607. freq = CLOCK_GetOsc32KFreq();
  608. break;
  609. default:
  610. break;
  611. }
  612. return freq;
  613. }
  614. /* Get I2S MCLK Clk */
  615. /*! brief Return Frequency of I2S MCLK Clock
  616. * return Frequency of I2S MCLK Clock
  617. */
  618. uint32_t CLOCK_GetI2SMClkFreq(void)
  619. {
  620. return s_I2S_Mclk_Freq;
  621. }
  622. /* Get FLEXCOMM input clock */
  623. /*! brief Return Frequency of flexcomm input clock
  624. * param id : flexcomm instance id
  625. * return Frequency value
  626. */
  627. uint32_t CLOCK_GetFlexCommInputClock(uint32_t id)
  628. {
  629. uint32_t freq = 0U;
  630. switch (SYSCON->FCCLKSELX[id])
  631. {
  632. case 0U:
  633. freq = CLOCK_GetCoreSysClkFreq();
  634. break;
  635. case 1U:
  636. freq = CLOCK_GetPll0OutFreq() / ((SYSCON->PLL0CLKDIV & 0xffU) + 1U);
  637. break;
  638. case 2U:
  639. freq = CLOCK_GetFro12MFreq();
  640. break;
  641. case 3U:
  642. freq = CLOCK_GetFroHfFreq() / ((SYSCON->FROHFDIV & 0xffU) + 1U);
  643. break;
  644. case 4U:
  645. freq = CLOCK_GetFro1MFreq();
  646. break;
  647. case 5U:
  648. freq = CLOCK_GetI2SMClkFreq();
  649. break;
  650. case 6U:
  651. freq = CLOCK_GetOsc32KFreq();
  652. break;
  653. case 7U:
  654. freq = 0U;
  655. break;
  656. default:
  657. break;
  658. }
  659. return freq;
  660. }
  661. /* Get FLEXCOMM Clk */
  662. uint32_t CLOCK_GetFlexCommClkFreq(uint32_t id)
  663. {
  664. uint32_t freq = 0U;
  665. freq = CLOCK_GetFlexCommInputClock(id);
  666. return freq / (1 +
  667. (SYSCON->FLEXFRGXCTRL[id] & SYSCON_FLEXFRG0CTRL_MULT_MASK) /
  668. ((SYSCON->FLEXFRGXCTRL[id] & SYSCON_FLEXFRG0CTRL_DIV_MASK) + 1U));
  669. }
  670. /* Get HS_LPSI Clk */
  671. uint32_t CLOCK_GetHsLspiClkFreq(void)
  672. {
  673. uint32_t freq = 0U;
  674. switch (SYSCON->HSLSPICLKSEL)
  675. {
  676. case 0U:
  677. freq = CLOCK_GetCoreSysClkFreq();
  678. break;
  679. case 1U:
  680. freq = CLOCK_GetPll0OutFreq() / ((SYSCON->PLL0CLKDIV & 0xffU) + 1U);
  681. break;
  682. case 2U:
  683. freq = CLOCK_GetFro12MFreq();
  684. break;
  685. case 3U:
  686. freq = CLOCK_GetFroHfFreq();
  687. break;
  688. case 4U:
  689. freq = CLOCK_GetFro1MFreq();
  690. break;
  691. case 6U:
  692. freq = CLOCK_GetOsc32KFreq();
  693. break;
  694. case 7U:
  695. freq = 0U;
  696. break;
  697. default:
  698. break;
  699. }
  700. return freq;
  701. }
  702. /* Get CTimer Clk */
  703. /*! brief Return Frequency of CTimer functional Clock
  704. * return Frequency of CTimer functional Clock
  705. */
  706. uint32_t CLOCK_GetCTimerClkFreq(uint32_t id)
  707. {
  708. uint32_t freq = 0U;
  709. switch (SYSCON->CTIMERCLKSELX[id])
  710. {
  711. case 0U:
  712. freq = CLOCK_GetCoreSysClkFreq();
  713. break;
  714. case 1U:
  715. freq = CLOCK_GetPll0OutFreq();
  716. break;
  717. case 3U:
  718. freq = CLOCK_GetFroHfFreq();
  719. break;
  720. case 4U:
  721. freq = CLOCK_GetFro1MFreq();
  722. break;
  723. case 5U:
  724. freq = CLOCK_GetI2SMClkFreq();
  725. break;
  726. case 6U:
  727. freq = CLOCK_GetOsc32KFreq();
  728. break;
  729. case 7U:
  730. freq = 0U;
  731. break;
  732. default:
  733. break;
  734. }
  735. return freq;
  736. }
  737. /* Get Systick Clk */
  738. /*! brief Return Frequency of SystickClock
  739. * return Frequency of Systick Clock
  740. */
  741. uint32_t CLOCK_GetSystickClkFreq(uint32_t id)
  742. {
  743. volatile uint32_t *pSystickClkDiv;
  744. pSystickClkDiv = &(SYSCON->SYSTICKCLKDIV0);
  745. uint32_t freq = 0U;
  746. switch (SYSCON->SYSTICKCLKSELX[id])
  747. {
  748. case 0U:
  749. freq = CLOCK_GetCoreSysClkFreq() / ((pSystickClkDiv[id] & 0xffU) + 1U);
  750. break;
  751. case 1U:
  752. freq = CLOCK_GetFro1MFreq();
  753. break;
  754. case 2U:
  755. freq = CLOCK_GetOsc32KFreq();
  756. break;
  757. case 7U:
  758. freq = 0U;
  759. break;
  760. default:
  761. break;
  762. }
  763. return freq;
  764. }
  765. /* Set FlexComm Clock */
  766. /**
  767. * brief Set the flexcomm output frequency.
  768. * param id : flexcomm instance id
  769. * freq : output frequency
  770. * return 0 : the frequency range is out of range.
  771. * 1 : switch successfully.
  772. */
  773. uint32_t CLOCK_SetFlexCommClock(uint32_t id, uint32_t freq)
  774. {
  775. uint32_t input = CLOCK_GetFlexCommClkFreq(id);
  776. uint32_t mul;
  777. if ((freq > 48000000) || (freq > input) || (input / freq >= 2))
  778. {
  779. /* FRG output frequency should be less than equal to 48MHz */
  780. return 0;
  781. }
  782. else
  783. {
  784. mul = ((uint64_t)(input - freq) * 256) / ((uint64_t)freq);
  785. SYSCON->FLEXFRGXCTRL[id] = (mul << 8U) | 0xFFU;
  786. return 1;
  787. }
  788. }
  789. /* Get IP Clk */
  790. /*! brief Return Frequency of selected clock
  791. * return Frequency of selected clock
  792. */
  793. uint32_t CLOCK_GetFreq(clock_name_t clockName)
  794. {
  795. uint32_t freq;
  796. switch (clockName)
  797. {
  798. case kCLOCK_CoreSysClk:
  799. freq = CLOCK_GetCoreSysClkFreq();
  800. break;
  801. case kCLOCK_BusClk:
  802. freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->AHBCLKDIV & 0xffU) + 1U);
  803. break;
  804. case kCLOCK_ClockOut:
  805. freq = CLOCK_GetClockOutClkFreq();
  806. break;
  807. case kCLOCK_Adc:
  808. freq = CLOCK_GetAdcClkFreq();
  809. break;
  810. case kCLOCK_Usb0:
  811. freq = CLOCK_GetUsb0ClkFreq();
  812. break;
  813. case kCLOCK_Usb1:
  814. freq = CLOCK_GetUsb1ClkFreq();
  815. break;
  816. case kCLOCK_Pll1Out:
  817. freq = CLOCK_GetPll1OutFreq();
  818. break;
  819. case kCLOCK_Mclk:
  820. freq = CLOCK_GetMclkClkFreq();
  821. break;
  822. case kCLOCK_FroHf:
  823. freq = CLOCK_GetFroHfFreq();
  824. break;
  825. case kCLOCK_Fro12M:
  826. freq = CLOCK_GetFro12MFreq();
  827. break;
  828. case kCLOCK_ExtClk:
  829. freq = CLOCK_GetExtClkFreq();
  830. break;
  831. case kCLOCK_Pll0Out:
  832. freq = CLOCK_GetPll0OutFreq();
  833. break;
  834. case kCLOCK_WdtClk:
  835. freq = CLOCK_GetWdtClkFreq();
  836. break;
  837. case kCLOCK_Sct:
  838. freq = CLOCK_GetSctClkFreq();
  839. break;
  840. case kCLOCK_SDio:
  841. freq = CLOCK_GetSdioClkFreq();
  842. break;
  843. case kCLOCK_FlexI2S:
  844. freq = CLOCK_GetI2SMClkFreq();
  845. break;
  846. case kCLOCK_Flexcomm0:
  847. freq = CLOCK_GetFlexCommClkFreq(0U);
  848. break;
  849. case kCLOCK_Flexcomm1:
  850. freq = CLOCK_GetFlexCommClkFreq(1U);
  851. break;
  852. case kCLOCK_Flexcomm2:
  853. freq = CLOCK_GetFlexCommClkFreq(2U);
  854. break;
  855. case kCLOCK_Flexcomm3:
  856. freq = CLOCK_GetFlexCommClkFreq(3U);
  857. break;
  858. case kCLOCK_Flexcomm4:
  859. freq = CLOCK_GetFlexCommClkFreq(4U);
  860. break;
  861. case kCLOCK_Flexcomm5:
  862. freq = CLOCK_GetFlexCommClkFreq(5U);
  863. break;
  864. case kCLOCK_Flexcomm6:
  865. freq = CLOCK_GetFlexCommClkFreq(6U);
  866. break;
  867. case kCLOCK_Flexcomm7:
  868. freq = CLOCK_GetFlexCommClkFreq(7U);
  869. break;
  870. case kCLOCK_HsLspi:
  871. freq = CLOCK_GetHsLspiClkFreq();
  872. break;
  873. case kCLOCK_CTmier0:
  874. freq = CLOCK_GetCTimerClkFreq(0U);
  875. break;
  876. case kCLOCK_CTmier1:
  877. freq = CLOCK_GetCTimerClkFreq(1U);
  878. break;
  879. case kCLOCK_CTmier2:
  880. freq = CLOCK_GetCTimerClkFreq(2U);
  881. break;
  882. case kCLOCK_CTmier3:
  883. freq = CLOCK_GetCTimerClkFreq(3U);
  884. break;
  885. case kCLOCK_CTmier4:
  886. freq = CLOCK_GetCTimerClkFreq(4U);
  887. break;
  888. case kCLOCK_Systick0:
  889. freq = CLOCK_GetSystickClkFreq(0U);
  890. break;
  891. case kCLOCK_Systick1:
  892. freq = CLOCK_GetSystickClkFreq(1U);
  893. break;
  894. default:
  895. freq = 0U;
  896. break;
  897. }
  898. return freq;
  899. }
  900. /* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */
  901. static void pllFindSel(uint32_t M, bool bypassFBDIV2, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR)
  902. {
  903. uint32_t seli, selp;
  904. /* bandwidth: compute selP from Multiplier */
  905. if (SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_MDIV_EXT_MASK)
  906. {
  907. selp = (M >> 2U) + 1U;
  908. if (selp >= 31U)
  909. {
  910. selp = 31U;
  911. }
  912. *pSelP = selp;
  913. seli = (M >> 1U) + 4U;
  914. if (seli >= 63U)
  915. {
  916. seli = 63U;
  917. }
  918. *pSelI = seli;
  919. *pSelR = 0U;
  920. }
  921. else
  922. {
  923. *pSelP = 3U;
  924. *pSelI = 4U;
  925. *pSelR = 4U;
  926. }
  927. }
  928. /* Get predivider (N) from PLL NDEC setting */
  929. static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg)
  930. {
  931. uint32_t preDiv = 1;
  932. /* Direct input is not used? */
  933. if ((ctrlReg & (1UL << SYSCON_PLL0CTRL_BYPASSPREDIV_SHIFT)) == 0U)
  934. {
  935. /* Decode NDEC value to get (N) pre divider */
  936. preDiv = (nDecReg & SYSCON_PLL0NDEC_NDIV_MASK) >> SYSCON_PLL0NDEC_NDIV_SHIFT;
  937. if (preDiv == 0U)
  938. {
  939. preDiv = 1U;
  940. }
  941. }
  942. /* Adjusted by 1, directi is used to bypass */
  943. return preDiv;
  944. }
  945. /* Get postdivider (P) from PLL PDEC setting */
  946. static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg)
  947. {
  948. uint32_t postDiv = 1U;
  949. /* Direct input is not used? */
  950. if ((ctrlReg & SYSCON_PLL0CTRL_BYPASSPOSTDIV_MASK) == 0U)
  951. {
  952. /* Decode PDEC value to get (P) post divider */
  953. postDiv = 2U * ((pDecReg & SYSCON_PLL0PDEC_PDIV_MASK) >> SYSCON_PLL0PDEC_PDIV_SHIFT);
  954. if (postDiv == 0U)
  955. {
  956. postDiv = 2U;
  957. }
  958. }
  959. /* Adjusted by 1, directo is used to bypass */
  960. return postDiv;
  961. }
  962. /* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */
  963. static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg)
  964. {
  965. uint32_t mMult = 1U;
  966. /* Decode MDEC value to get (M) multiplier */
  967. mMult = (mDecReg & SYSCON_PLL0SSCG1_MDIV_EXT_MASK) >> SYSCON_PLL0SSCG1_MDIV_EXT_SHIFT;
  968. /* Extra multiply by 2 needed? */
  969. if ((ctrlReg & (SYSCON_PLL0CTRL_BYPASSPOSTDIV2_MASK)) == 0U)
  970. {
  971. mMult = mMult << 1U;
  972. }
  973. if (mMult == 0U)
  974. {
  975. mMult = 1U;
  976. }
  977. return mMult;
  978. }
  979. /* Find greatest common divisor between m and n */
  980. static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n)
  981. {
  982. uint32_t tmp;
  983. while (n != 0U)
  984. {
  985. tmp = n;
  986. n = m % n;
  987. m = tmp;
  988. }
  989. return m;
  990. }
  991. /*
  992. * Set PLL output based on desired output rate.
  993. * In this function, the it calculates the PLL setting for output frequency from input clock
  994. * frequency. The calculation would cost a few time. So it is not recommaned to use it frequently.
  995. * the "pllctrl", "pllndec", "pllpdec", "pllmdec" would updated in this function.
  996. */
  997. static pll_error_t CLOCK_GetPllConfigInternal(
  998. uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useFeedbackDiv2, bool useSS)
  999. {
  1000. uint32_t nDivOutHz, fccoHz, multFccoDiv;
  1001. uint32_t pllPreDivider, pllMultiplier, pllBypassFBDIV2, pllPostDivider;
  1002. uint32_t pllDirectInput, pllDirectOutput;
  1003. uint32_t pllSelP, pllSelI, pllSelR, bandsel, uplimoff;
  1004. /* Baseline parameters (no input or output dividers) */
  1005. pllPreDivider = 1U; /* 1 implies pre-divider will be disabled */
  1006. pllPostDivider = 0U; /* 0 implies post-divider will be disabled */
  1007. pllDirectOutput = 1U;
  1008. if (useFeedbackDiv2)
  1009. {
  1010. /* Using feedback divider for M, so disable bypass */
  1011. pllBypassFBDIV2 = 0U;
  1012. }
  1013. else
  1014. {
  1015. pllBypassFBDIV2 = 1U;
  1016. }
  1017. multFccoDiv = (2U - pllBypassFBDIV2);
  1018. /* Verify output rate parameter */
  1019. if (foutHz > PLL_MAX_CCO_FREQ_MHZ)
  1020. {
  1021. /* Maximum PLL output with post divider=1 cannot go above this frequency */
  1022. return kStatus_PLL_OutputTooHigh;
  1023. }
  1024. if (foutHz < (PLL_MIN_CCO_FREQ_MHZ / (PVALMAX << 1U)))
  1025. {
  1026. /* Minmum PLL output with maximum post divider cannot go below this frequency */
  1027. return kStatus_PLL_OutputTooLow;
  1028. }
  1029. /* If using SS mode, input clock needs to be between 2MHz and 4MHz */
  1030. if (useSS)
  1031. {
  1032. /* Verify input rate parameter */
  1033. if (finHz < PLL_MIN_IN_SSMODE)
  1034. {
  1035. /* Input clock into the PLL cannot be lower than this */
  1036. return kStatus_PLL_InputTooLow;
  1037. }
  1038. /* PLL input in SS mode must be under 4MHz */
  1039. pllPreDivider = finHz / ((PLL_MIN_IN_SSMODE + PLL_MAX_IN_SSMODE) / 2);
  1040. if (pllPreDivider > NVALMAX)
  1041. {
  1042. return kStatus_PLL_InputTooHigh;
  1043. }
  1044. }
  1045. else
  1046. {
  1047. /* Verify input rate parameter */
  1048. if (finHz < PLL_LOWER_IN_LIMIT)
  1049. {
  1050. /* Input clock into the PLL cannot be lower than this */
  1051. return kStatus_PLL_InputTooLow;
  1052. }
  1053. }
  1054. /* Find the optimal CCO frequency for the output and input that
  1055. will keep it inside the PLL CCO range. This may require
  1056. tweaking the post-divider for the PLL. */
  1057. fccoHz = foutHz;
  1058. while (fccoHz < PLL_MIN_CCO_FREQ_MHZ)
  1059. {
  1060. /* CCO output is less than minimum CCO range, so the CCO output
  1061. needs to be bumped up and the post-divider is used to bring
  1062. the PLL output back down. */
  1063. pllPostDivider++;
  1064. if (pllPostDivider > PVALMAX)
  1065. {
  1066. return kStatus_PLL_OutsideIntLimit;
  1067. }
  1068. /* Target CCO goes up, PLL output goes down */
  1069. fccoHz = foutHz * (pllPostDivider * 2U);
  1070. pllDirectOutput = 0U;
  1071. }
  1072. /* Determine if a pre-divider is needed to get the best frequency */
  1073. if ((finHz > PLL_LOWER_IN_LIMIT) && (fccoHz >= finHz) && (useSS == false))
  1074. {
  1075. uint32_t a = FindGreatestCommonDivisor(fccoHz, (multFccoDiv * finHz));
  1076. if (a > 20000U)
  1077. {
  1078. a = (multFccoDiv * finHz) / a;
  1079. if ((a != 0U) && (a < PLL_MAX_N_DIV))
  1080. {
  1081. pllPreDivider = a;
  1082. }
  1083. }
  1084. }
  1085. /* Bypass pre-divider hardware if pre-divider is 1 */
  1086. if (pllPreDivider > 1U)
  1087. {
  1088. pllDirectInput = 0U;
  1089. }
  1090. else
  1091. {
  1092. pllDirectInput = 1U;
  1093. }
  1094. /* Determine PLL multipler */
  1095. nDivOutHz = (finHz / pllPreDivider);
  1096. pllMultiplier = (fccoHz / nDivOutHz) / multFccoDiv;
  1097. /* Find optimal values for filter */
  1098. if (useSS == false)
  1099. {
  1100. /* Will bumping up M by 1 get us closer to the desired CCO frequency? */
  1101. if ((nDivOutHz * ((multFccoDiv * pllMultiplier * 2U) + 1U)) < (fccoHz * 2U))
  1102. {
  1103. pllMultiplier++;
  1104. }
  1105. /* Setup filtering */
  1106. pllFindSel(pllMultiplier, pllBypassFBDIV2, &pllSelP, &pllSelI, &pllSelR);
  1107. bandsel = 1U;
  1108. uplimoff = 0U;
  1109. /* Get encoded value for M (mult) and use manual filter, disable SS mode */
  1110. pSetup->pllsscg[1] = (PLL_SSCG1_MDEC_VAL_SET(pllMultiplier)) | (1U << SYSCON_PLL0SSCG1_SEL_EXT_SHIFT);
  1111. }
  1112. else
  1113. {
  1114. uint64_t fc;
  1115. /* Filtering will be handled by SSC */
  1116. pllSelR = pllSelI = pllSelP = 0U;
  1117. bandsel = 0U;
  1118. uplimoff = 1U;
  1119. /* The PLL multiplier will get very close and slightly under the
  1120. desired target frequency. A small fractional component can be
  1121. added to fine tune the frequency upwards to the target. */
  1122. fc = ((uint64_t)(fccoHz % (multFccoDiv * nDivOutHz)) << 11U) / (multFccoDiv * nDivOutHz);
  1123. /* Set multiplier */
  1124. pSetup->pllsscg[0] = (uint32_t)(PLL_SSCG_MD_INT_SET(pllMultiplier) | PLL_SSCG_MD_FRACT_SET((uint32_t)fc));
  1125. pSetup->pllsscg[1] = PLL_SSCG_MD_INT_SET(pllMultiplier) >> 32U;
  1126. }
  1127. /* Get encoded values for N (prediv) and P (postdiv) */
  1128. pSetup->pllndec = PLL_NDEC_VAL_SET(pllPreDivider);
  1129. pSetup->pllpdec = PLL_PDEC_VAL_SET(pllPostDivider);
  1130. /* PLL control */
  1131. pSetup->pllctrl = (pllSelR << SYSCON_PLL0CTRL_SELR_SHIFT) | /* Filter coefficient */
  1132. (pllSelI << SYSCON_PLL0CTRL_SELI_SHIFT) | /* Filter coefficient */
  1133. (pllSelP << SYSCON_PLL0CTRL_SELP_SHIFT) | /* Filter coefficient */
  1134. (0 << SYSCON_PLL0CTRL_BYPASSPLL_SHIFT) | /* PLL bypass mode disabled */
  1135. (pllBypassFBDIV2 << SYSCON_PLL0CTRL_BYPASSPOSTDIV2_SHIFT) | /* Extra M / 2 divider? */
  1136. (uplimoff << SYSCON_PLL0CTRL_LIMUPOFF_SHIFT) | /* SS/fractional mode disabled */
  1137. (bandsel << SYSCON_PLL0CTRL_BWDIRECT_SHIFT) | /* Manual bandwidth selection enabled */
  1138. (pllDirectInput << SYSCON_PLL0CTRL_BYPASSPREDIV_SHIFT) | /* Bypass pre-divider? */
  1139. (pllDirectOutput << SYSCON_PLL0CTRL_BYPASSPOSTDIV_SHIFT); /* Bypass post-divider? */
  1140. return kStatus_PLL_Success;
  1141. }
  1142. #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
  1143. /* Alloct the static buffer for cache. */
  1144. static pll_setup_t s_PllSetupCacheStruct[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT];
  1145. static uint32_t s_FinHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0};
  1146. static uint32_t s_FoutHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0};
  1147. static bool s_UseFeedbackDiv2Cache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {false};
  1148. static bool s_UseSSCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {false};
  1149. static uint32_t s_PllSetupCacheIdx = 0U;
  1150. #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
  1151. /*
  1152. * Calculate the PLL setting values from input clock freq to output freq.
  1153. */
  1154. static pll_error_t CLOCK_GetPllConfig(
  1155. uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useFeedbackDiv2, bool useSS)
  1156. {
  1157. pll_error_t retErr;
  1158. #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
  1159. uint32_t i;
  1160. for (i = 0U; i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT; i++)
  1161. {
  1162. if ((finHz == s_FinHzCache[i]) && (foutHz == s_FoutHzCache[i]) &&
  1163. (useFeedbackDiv2 == s_UseFeedbackDiv2Cache[i]) && (useSS == s_UseSSCache[i]))
  1164. {
  1165. /* Hit the target in cache buffer. */
  1166. pSetup->pllctrl = s_PllSetupCacheStruct[i].pllctrl;
  1167. pSetup->pllndec = s_PllSetupCacheStruct[i].pllndec;
  1168. pSetup->pllpdec = s_PllSetupCacheStruct[i].pllpdec;
  1169. pSetup->pllsscg[0] = s_PllSetupCacheStruct[i].pllsscg[0];
  1170. pSetup->pllsscg[1] = s_PllSetupCacheStruct[i].pllsscg[1];
  1171. retErr = kStatus_PLL_Success;
  1172. break;
  1173. }
  1174. }
  1175. if (i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
  1176. {
  1177. return retErr;
  1178. }
  1179. #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
  1180. retErr = CLOCK_GetPllConfigInternal(finHz, foutHz, pSetup, useFeedbackDiv2, useSS);
  1181. #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
  1182. /* Cache the most recent calulation result into buffer. */
  1183. s_FinHzCache[s_PllSetupCacheIdx] = finHz;
  1184. s_FoutHzCache[s_PllSetupCacheIdx] = foutHz;
  1185. s_UseFeedbackDiv2Cache[s_PllSetupCacheIdx] = useFeedbackDiv2;
  1186. s_UseSSCache[s_PllSetupCacheIdx] = useSS;
  1187. s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllctrl = pSetup->pllctrl;
  1188. s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllndec = pSetup->pllndec;
  1189. s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllpdec = pSetup->pllpdec;
  1190. s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllsscg[0] = pSetup->pllsscg[0];
  1191. s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllsscg[1] = pSetup->pllsscg[1];
  1192. /* Update the index for next available buffer. */
  1193. s_PllSetupCacheIdx = (s_PllSetupCacheIdx + 1U) % CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT;
  1194. #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
  1195. return retErr;
  1196. }
  1197. /* Update local PLL rate variable */
  1198. static void CLOCK_GetPLL0OutFromSetupUpdate(pll_setup_t *pSetup)
  1199. {
  1200. s_Pll_Freq = CLOCK_GetPLL0OutFromSetup(pSetup);
  1201. }
  1202. /* Return System PLL input clock rate */
  1203. /*! brief Return PLL0 input clock rate
  1204. * return PLL0 input clock rate
  1205. */
  1206. uint32_t CLOCK_GetPLL0InClockRate(void)
  1207. {
  1208. uint32_t clkRate = 0U;
  1209. switch ((SYSCON->PLL0CLKSEL & SYSCON_PLL0CLKSEL_SEL_MASK))
  1210. {
  1211. case 0x00U:
  1212. clkRate = CLK_FRO_12MHZ;
  1213. break;
  1214. case 0x01U:
  1215. clkRate = CLOCK_GetExtClkFreq();
  1216. break;
  1217. case 0x02U:
  1218. clkRate = CLOCK_GetFro1MFreq();
  1219. break;
  1220. case 0x03U:
  1221. clkRate = CLOCK_GetOsc32KFreq();
  1222. break;
  1223. default:
  1224. clkRate = 0U;
  1225. break;
  1226. }
  1227. return clkRate;
  1228. }
  1229. /* Return PLL1 input clock rate */
  1230. uint32_t CLOCK_GetPLL1InClockRate(void)
  1231. {
  1232. uint32_t clkRate = 0U;
  1233. switch ((SYSCON->PLL1CLKSEL & SYSCON_PLL1CLKSEL_SEL_MASK))
  1234. {
  1235. case 0x00U:
  1236. clkRate = CLK_FRO_12MHZ;
  1237. break;
  1238. case 0x01U:
  1239. clkRate = CLOCK_GetExtClkFreq();
  1240. break;
  1241. case 0x02U:
  1242. clkRate = CLOCK_GetFro1MFreq();
  1243. break;
  1244. case 0x03U:
  1245. clkRate = CLOCK_GetOsc32KFreq();
  1246. break;
  1247. default:
  1248. clkRate = 0U;
  1249. break;
  1250. }
  1251. return clkRate;
  1252. }
  1253. /* Return System PLL output clock rate from setup structure */
  1254. /*! brief Return System PLL output clock rate from setup structure
  1255. * param pSetup : Pointer to a PLL setup structure
  1256. * return System PLL output clock rate the setup structure will generate
  1257. */
  1258. uint32_t CLOCK_GetPLL0OutFromSetup(pll_setup_t *pSetup)
  1259. {
  1260. uint32_t prediv, postdiv, inPllRate;
  1261. uint64_t mMult, workRate;
  1262. /* Get the input clock frequency of PLL. */
  1263. inPllRate = CLOCK_GetPLL0InClockRate();
  1264. /*
  1265. * If the PLL is bypassed, PLL would not be used and the output of PLL module would just be the input clock.
  1266. */
  1267. if ((pSetup->pllctrl & (SYSCON_PLL0CTRL_BYPASSPLL_MASK)) == 0U)
  1268. {
  1269. /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */
  1270. /*
  1271. * 1. Pre-divider
  1272. * Pre-divider is only available when the DIRECTI is disabled.
  1273. */
  1274. if (0U == (pSetup->pllctrl & SYSCON_PLL0CTRL_BYPASSPREDIV_MASK))
  1275. {
  1276. prediv = findPllPreDiv(pSetup->pllctrl, pSetup->pllndec);
  1277. }
  1278. else
  1279. {
  1280. prediv = 1U; /* The pre-divider is bypassed. */
  1281. }
  1282. /* Adjust input clock */
  1283. inPllRate = inPllRate / prediv;
  1284. /*
  1285. * 2. M divider
  1286. * If using the SS, use the multiplier.
  1287. */
  1288. if (pSetup->pllsscg[1] & (SYSCON_PLL0SSCG1_SEL_EXT_MASK))
  1289. {
  1290. /* MDEC used for rate */
  1291. mMult = findPllMMult(pSetup->pllctrl, pSetup->pllsscg[1]);
  1292. workRate = (uint64_t)inPllRate * (uint64_t)mMult;
  1293. }
  1294. else
  1295. {
  1296. uint64_t fract;
  1297. /* SS multipler used for rate */
  1298. mMult = ((pSetup->pllsscg[0] & PLL_SSCG_MD_INT_M) >> PLL_SSCG_MD_INT_P) +
  1299. ((pSetup->pllsscg[1] & SYSCON_PLL0SSCG1_MD_MBS_MASK) << 0x7U);
  1300. workRate = (uint64_t)inPllRate * (uint64_t)mMult;
  1301. /* Adjust by fractional */
  1302. fract = (uint64_t)(pSetup->pllsscg[1] & PLL_SSCG_MD_FRACT_M) >> PLL_SSCG_MD_FRACT_P;
  1303. workRate = workRate + ((inPllRate * fract) / 0x800U);
  1304. }
  1305. /*
  1306. * 3. Post-divider
  1307. * Post-divider is only available when the DIRECTO is disabled.
  1308. */
  1309. if (0U == (pSetup->pllctrl & SYSCON_PLL0CTRL_BYPASSPOSTDIV_MASK))
  1310. {
  1311. postdiv = findPllPostDiv(pSetup->pllctrl, pSetup->pllpdec);
  1312. }
  1313. else
  1314. {
  1315. postdiv = 1U; /* The post-divider is bypassed. */
  1316. }
  1317. workRate = workRate / ((uint64_t)postdiv);
  1318. }
  1319. else
  1320. {
  1321. /* In bypass mode */
  1322. workRate = (uint64_t)inPllRate;
  1323. }
  1324. return (uint32_t)workRate;
  1325. }
  1326. /* Set the current PLL Rate */
  1327. /*! brief Store the current PLL rate
  1328. * param rate: Current rate of the PLL
  1329. * return Nothing
  1330. **/
  1331. void CLOCK_SetStoredPLLClockRate(uint32_t rate)
  1332. {
  1333. s_Pll_Freq = rate;
  1334. }
  1335. /* Return System PLL output clock rate */
  1336. /*! brief Return PLL0 output clock rate
  1337. * param recompute : Forces a PLL rate recomputation if true
  1338. * return PLL0 output clock rate
  1339. * note The PLL rate is cached in the driver in a variable as
  1340. * the rate computation function can take some time to perform. It
  1341. * is recommended to use 'false' with the 'recompute' parameter.
  1342. */
  1343. uint32_t CLOCK_GetPLL0OutClockRate(bool recompute)
  1344. {
  1345. pll_setup_t Setup;
  1346. uint32_t rate;
  1347. if ((recompute) || (s_Pll_Freq == 0U))
  1348. {
  1349. Setup.pllctrl = SYSCON->PLL0CTRL;
  1350. Setup.pllndec = SYSCON->PLL0NDEC;
  1351. Setup.pllpdec = SYSCON->PLL0PDEC;
  1352. Setup.pllsscg[0] = SYSCON->PLL0SSCG0;
  1353. Setup.pllsscg[1] = SYSCON->PLL0SSCG1;
  1354. CLOCK_GetPLL0OutFromSetupUpdate(&Setup);
  1355. }
  1356. rate = s_Pll_Freq;
  1357. return rate;
  1358. }
  1359. /* Set PLL output based on the passed PLL setup data */
  1360. /*! brief Set PLL output based on the passed PLL setup data
  1361. * param pControl : Pointer to populated PLL control structure to generate setup with
  1362. * param pSetup : Pointer to PLL setup structure to be filled
  1363. * return PLL_ERROR_SUCCESS on success, or PLL setup error code
  1364. * note Actual frequency for setup may vary from the desired frequency based on the
  1365. * accuracy of input clocks, rounding, non-fractional PLL mode, etc.
  1366. */
  1367. pll_error_t CLOCK_SetupPLLData(pll_config_t *pControl, pll_setup_t *pSetup)
  1368. {
  1369. uint32_t inRate;
  1370. bool useSS = (bool)((pControl->flags & PLL_CONFIGFLAG_FORCENOFRACT) == 0U);
  1371. bool useFbDiv2;
  1372. pll_error_t pllError;
  1373. /* Determine input rate for the PLL */
  1374. if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0U)
  1375. {
  1376. inRate = pControl->inputRate;
  1377. }
  1378. else
  1379. {
  1380. inRate = CLOCK_GetPLL0InClockRate();
  1381. }
  1382. if ((pSetup->flags & PLL_SETUPFLAG_USEFEEDBACKDIV2) != 0U)
  1383. {
  1384. useFbDiv2 = true;
  1385. }
  1386. else
  1387. {
  1388. useFbDiv2 = false;
  1389. }
  1390. /* PLL flag options */
  1391. pllError = CLOCK_GetPllConfig(inRate, pControl->desiredRate, pSetup, useFbDiv2, useSS);
  1392. if ((useSS) && (pllError == kStatus_PLL_Success))
  1393. {
  1394. /* If using SS mode, then some tweaks are made to the generated setup */
  1395. pSetup->pllsscg[1] |= (uint32_t)pControl->ss_mf | (uint32_t)pControl->ss_mr | (uint32_t)pControl->ss_mc;
  1396. if (pControl->mfDither)
  1397. {
  1398. pSetup->pllsscg[1] |= (1U << SYSCON_PLL0SSCG1_DITHER_SHIFT);
  1399. }
  1400. }
  1401. return pllError;
  1402. }
  1403. /* Set PLL output from PLL setup structure */
  1404. /*! brief Set PLL output from PLL setup structure (precise frequency)
  1405. * param pSetup : Pointer to populated PLL setup structure
  1406. * param flagcfg : Flag configuration for PLL config structure
  1407. * return PLL_ERROR_SUCCESS on success, or PLL setup error code
  1408. * note This function will power off the PLL, setup the PLL with the
  1409. * new setup data, and then optionally powerup the PLL, wait for PLL lock,
  1410. * and adjust system voltages to the new PLL rate. The function will not
  1411. * alter any source clocks (ie, main systen clock) that may use the PLL,
  1412. * so these should be setup prior to and after exiting the function.
  1413. */
  1414. pll_error_t CLOCK_SetupPLL0Prec(pll_setup_t *pSetup, uint32_t flagcfg)
  1415. {
  1416. /* Power off PLL during setup changes */
  1417. POWER_EnablePD(kPDRUNCFG_PD_PLL0);
  1418. POWER_EnablePD(kPDRUNCFG_PD_PLL0_SSCG);
  1419. pSetup->flags = flagcfg;
  1420. /* Write PLL setup data */
  1421. SYSCON->PLL0CTRL = pSetup->pllctrl;
  1422. SYSCON->PLL0NDEC = pSetup->pllndec;
  1423. SYSCON->PLL0NDEC = pSetup->pllndec | (1U << SYSCON_PLL0NDEC_NREQ_SHIFT); /* latch */
  1424. SYSCON->PLL0PDEC = pSetup->pllpdec;
  1425. SYSCON->PLL0PDEC = pSetup->pllpdec | (1U << SYSCON_PLL0PDEC_PREQ_SHIFT); /* latch */
  1426. SYSCON->PLL0SSCG0 = pSetup->pllsscg[0];
  1427. SYSCON->PLL0SSCG1 = pSetup->pllsscg[1];
  1428. SYSCON->PLL0SSCG1 =
  1429. pSetup->pllsscg[1] | (1U << SYSCON_PLL0SSCG1_MREQ_SHIFT) | (1U << SYSCON_PLL0SSCG1_MD_REQ_SHIFT); /* latch */
  1430. POWER_DisablePD(kPDRUNCFG_PD_PLL0);
  1431. POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG);
  1432. if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
  1433. {
  1434. while (CLOCK_IsPLL0Locked() == false)
  1435. {
  1436. }
  1437. }
  1438. /* Update current programmed PLL rate var */
  1439. CLOCK_GetPLL0OutFromSetupUpdate(pSetup);
  1440. /* System voltage adjustment, occurs prior to setting main system clock */
  1441. if ((pSetup->flags & PLL_SETUPFLAG_ADGVOLT) != 0U)
  1442. {
  1443. // POWER_SetVoltageForFreq(s_Pll_Freq);
  1444. }
  1445. return kStatus_PLL_Success;
  1446. }
  1447. /* Setup PLL Frequency from pre-calculated value */
  1448. /**
  1449. * brief Set PLL output from PLL setup structure (precise frequency)
  1450. * param pSetup : Pointer to populated PLL setup structure
  1451. * return kStatus_PLL_Success on success, or PLL setup error code
  1452. * note This function will power off the PLL, setup the PLL with the
  1453. * new setup data, and then optionally powerup the PLL, wait for PLL lock,
  1454. * and adjust system voltages to the new PLL rate. The function will not
  1455. * alter any source clocks (ie, main systen clock) that may use the PLL,
  1456. * so these should be setup prior to and after exiting the function.
  1457. */
  1458. pll_error_t CLOCK_SetPLL0Freq(const pll_setup_t *pSetup)
  1459. {
  1460. /* Power off PLL during setup changes */
  1461. POWER_EnablePD(kPDRUNCFG_PD_PLL0);
  1462. POWER_EnablePD(kPDRUNCFG_PD_PLL0_SSCG);
  1463. /* Write PLL setup data */
  1464. SYSCON->PLL0CTRL = pSetup->pllctrl;
  1465. SYSCON->PLL0NDEC = pSetup->pllndec;
  1466. SYSCON->PLL0NDEC = pSetup->pllndec | (1U << SYSCON_PLL0NDEC_NREQ_SHIFT); /* latch */
  1467. SYSCON->PLL0PDEC = pSetup->pllpdec;
  1468. SYSCON->PLL0PDEC = pSetup->pllpdec | (1U << SYSCON_PLL0PDEC_PREQ_SHIFT); /* latch */
  1469. SYSCON->PLL0SSCG0 = pSetup->pllsscg[0];
  1470. SYSCON->PLL0SSCG1 = pSetup->pllsscg[1];
  1471. SYSCON->PLL0SSCG1 =
  1472. pSetup->pllsscg[1] | (1U << SYSCON_PLL0SSCG1_MD_REQ_SHIFT) | (1U << SYSCON_PLL0SSCG1_MREQ_SHIFT); /* latch */
  1473. POWER_DisablePD(kPDRUNCFG_PD_PLL0);
  1474. POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG);
  1475. if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
  1476. {
  1477. while (CLOCK_IsPLL0Locked() == false)
  1478. {
  1479. }
  1480. }
  1481. /* Update current programmed PLL rate var */
  1482. s_Pll_Freq = pSetup->pllRate;
  1483. return kStatus_PLL_Success;
  1484. }
  1485. /* Setup PLL1 Frequency from pre-calculated value */
  1486. /**
  1487. * brief Set PLL output from PLL setup structure (precise frequency)
  1488. * param pSetup : Pointer to populated PLL setup structure
  1489. * return kStatus_PLL_Success on success, or PLL setup error code
  1490. * note This function will power off the PLL, setup the PLL with the
  1491. * new setup data, and then optionally powerup the PLL, wait for PLL lock,
  1492. * and adjust system voltages to the new PLL rate. The function will not
  1493. * alter any source clocks (ie, main systen clock) that may use the PLL,
  1494. * so these should be setup prior to and after exiting the function.
  1495. */
  1496. pll_error_t CLOCK_SetPLL1Freq(const pll_setup_t *pSetup)
  1497. {
  1498. /* Power off PLL during setup changes */
  1499. POWER_EnablePD(kPDRUNCFG_PD_PLL1);
  1500. /* Write PLL setup data */
  1501. SYSCON->PLL1CTRL = pSetup->pllctrl;
  1502. SYSCON->PLL1NDEC = pSetup->pllndec;
  1503. SYSCON->PLL1NDEC = pSetup->pllndec | (1U << SYSCON_PLL1NDEC_NREQ_SHIFT); /* latch */
  1504. SYSCON->PLL1PDEC = pSetup->pllpdec;
  1505. SYSCON->PLL1PDEC = pSetup->pllpdec | (1U << SYSCON_PLL1PDEC_PREQ_SHIFT); /* latch */
  1506. SYSCON->PLL1MDEC = pSetup->pllmdec;
  1507. SYSCON->PLL1MDEC = pSetup->pllmdec | (1U << SYSCON_PLL1MDEC_MREQ_SHIFT); /* latch */
  1508. POWER_DisablePD(kPDRUNCFG_PD_PLL1);
  1509. if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
  1510. {
  1511. while (CLOCK_IsPLL1Locked() == false)
  1512. {
  1513. }
  1514. }
  1515. /* Update current programmed PLL rate var */
  1516. s_Pll_Freq = pSetup->pllRate;
  1517. return kStatus_PLL_Success;
  1518. }
  1519. /* Set System PLL clock based on the input frequency and multiplier */
  1520. /*! brief Set PLL output based on the multiplier and input frequency
  1521. * param multiply_by : multiplier
  1522. * param input_freq : Clock input frequency of the PLL
  1523. * return Nothing
  1524. * note Unlike the Chip_Clock_SetupSystemPLLPrec() function, this
  1525. * function does not disable or enable PLL power, wait for PLL lock,
  1526. * or adjust system voltages. These must be done in the application.
  1527. * The function will not alter any source clocks (ie, main systen clock)
  1528. * that may use the PLL, so these should be setup prior to and after
  1529. * exiting the function.
  1530. */
  1531. void CLOCK_SetupPLL0Mult(uint32_t multiply_by, uint32_t input_freq)
  1532. {
  1533. uint32_t cco_freq = input_freq * multiply_by;
  1534. uint32_t pdec = 1U;
  1535. uint32_t selr;
  1536. uint32_t seli;
  1537. uint32_t selp;
  1538. uint32_t mdec, ndec;
  1539. uint32_t directo = SYSCON_PLL0CTRL_BYPASSPOSTDIV(1);
  1540. while (cco_freq < 275000000U)
  1541. {
  1542. multiply_by <<= 1U; /* double value in each iteration */
  1543. pdec <<= 1U; /* correspondingly double pdec to cancel effect of double msel */
  1544. cco_freq = input_freq * multiply_by;
  1545. }
  1546. selr = 0U;
  1547. seli = (multiply_by >> 1U) + 4U;
  1548. if (seli >= 63U)
  1549. {
  1550. seli = 63U;
  1551. }
  1552. selp = (multiply_by >> 2U) + 1U;
  1553. {
  1554. selp = 31U;
  1555. }
  1556. if (pdec > 1U)
  1557. {
  1558. directo = 0U; /* use post divider */
  1559. pdec = pdec / 2U; /* Account for minus 1 encoding */
  1560. /* Translate P value */
  1561. }
  1562. mdec = PLL_SSCG1_MDEC_VAL_SET(multiply_by);
  1563. ndec = 0x1U; /* pre divide by 1 (hardcoded) */
  1564. SYSCON->PLL0CTRL = SYSCON_PLL0CTRL_BWDIRECT(1) | directo | SYSCON_PLL0CTRL_BYPASSPOSTDIV2(1) |
  1565. (selr << SYSCON_PLL0CTRL_SELR_SHIFT) | (seli << SYSCON_PLL0CTRL_SELI_SHIFT) |
  1566. (selp << SYSCON_PLL0CTRL_SELP_SHIFT);
  1567. SYSCON->PLL0PDEC = pdec | (1U << 7U); /* set Pdec value and assert preq */
  1568. SYSCON->PLL0NDEC = ndec | (1U << 10U); /* set Pdec value and assert preq */
  1569. SYSCON->PLL0SSCG1 = mdec | (1U << 17U); /* select non sscg MDEC value, assert mreq and select mdec value */
  1570. }
  1571. /* Enable USB DEVICE FULL SPEED clock */
  1572. /*! brief Enable USB Device FS clock.
  1573. * param src : clock source
  1574. * param freq: clock frequency
  1575. * Enable USB Device Full Speed clock.
  1576. */
  1577. bool CLOCK_EnableUsbfs0DeviceClock(clock_usbfs_src_t src, uint32_t freq)
  1578. {
  1579. bool ret = true;
  1580. CLOCK_DisableClock(kCLOCK_Usbd0);
  1581. if (kCLOCK_UsbfsSrcFro == src)
  1582. {
  1583. switch (freq)
  1584. {
  1585. case 96000000U:
  1586. CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
  1587. break;
  1588. default:
  1589. ret = false;
  1590. break;
  1591. }
  1592. /* Turn ON FRO HF */
  1593. POWER_DisablePD(kPDRUNCFG_PD_FRO192M);
  1594. /* Enable FRO 96MHz output */
  1595. ANACTRL->FRO192M_CTRL = ANACTRL->FRO192M_CTRL | ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK;
  1596. /* Select FRO 96 or 48 MHz */
  1597. CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
  1598. }
  1599. else
  1600. {
  1601. /*Set the USB PLL as the Usb0 CLK*/
  1602. POWER_DisablePD(kPDRUNCFG_PD_PLL1);
  1603. POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /*!< Ensure XTAL32K is on */
  1604. POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /*!< Ensure XTAL32K is on */
  1605. SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /*!< Ensure CLK_IN is on */
  1606. ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK;
  1607. CLOCK_AttachClk(kEXT_CLK_to_PLL1); /*!< Switch PLL0 clock source selector to XTAL16M */
  1608. const pll_setup_t pll1Setup = {
  1609. .pllctrl = SYSCON_PLL1CTRL_CLKEN_MASK | SYSCON_PLL1CTRL_SELI(16U) | SYSCON_PLL1CTRL_SELP(7U),
  1610. .pllndec = SYSCON_PLL1NDEC_NDIV(1U),
  1611. .pllpdec = SYSCON_PLL1PDEC_PDIV(4U),
  1612. .pllmdec = SYSCON_PLL1MDEC_MDIV(24U),
  1613. .pllRate = 48000000U,
  1614. .flags = PLL_SETUPFLAG_WAITLOCK,
  1615. };
  1616. CLOCK_SetPLL1Freq(&pll1Setup); /*!< Configure PLL1 to the desired values */
  1617. CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
  1618. CLOCK_AttachClk(kPLL1_to_USB0_CLK);
  1619. uint32_t delay = 100000;
  1620. while (delay--)
  1621. {
  1622. __asm("nop");
  1623. }
  1624. }
  1625. CLOCK_EnableClock(kCLOCK_Usbd0);
  1626. CLOCK_EnableClock(kCLOCK_UsbRam1);
  1627. return ret;
  1628. }
  1629. /* Enable USB HOST FULL SPEED clock */
  1630. /*! brief Enable USB HOST FS clock.
  1631. * param src : clock source
  1632. * param freq: clock frequency
  1633. * Enable USB HOST Full Speed clock.
  1634. */
  1635. bool CLOCK_EnableUsbfs0HostClock(clock_usbfs_src_t src, uint32_t freq)
  1636. {
  1637. bool ret = true;
  1638. CLOCK_DisableClock(kCLOCK_Usbhmr0);
  1639. CLOCK_DisableClock(kCLOCK_Usbhsl0);
  1640. if (kCLOCK_UsbfsSrcFro == src)
  1641. {
  1642. switch (freq)
  1643. {
  1644. case 96000000U:
  1645. CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
  1646. break;
  1647. default:
  1648. ret = false;
  1649. break;
  1650. }
  1651. /* Turn ON FRO HF */
  1652. POWER_DisablePD(kPDRUNCFG_PD_FRO192M);
  1653. /* Enable FRO 96MHz output */
  1654. ANACTRL->FRO192M_CTRL = ANACTRL->FRO192M_CTRL | ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK;
  1655. /* Select FRO 96 MHz */
  1656. CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
  1657. }
  1658. else
  1659. {
  1660. /*Set the USB PLL as the Usb0 CLK*/
  1661. POWER_DisablePD(kPDRUNCFG_PD_PLL1);
  1662. POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /*!< Ensure XTAL32K is on */
  1663. POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /*!< Ensure XTAL32K is on */
  1664. SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /*!< Ensure CLK_IN is on */
  1665. ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK;
  1666. CLOCK_AttachClk(kEXT_CLK_to_PLL1); /*!< Switch PLL0 clock source selector to XTAL16M */
  1667. const pll_setup_t pll1Setup = {
  1668. .pllctrl = SYSCON_PLL1CTRL_CLKEN_MASK | SYSCON_PLL1CTRL_SELI(16U) | SYSCON_PLL1CTRL_SELP(7U),
  1669. .pllndec = SYSCON_PLL1NDEC_NDIV(1U),
  1670. .pllpdec = SYSCON_PLL1PDEC_PDIV(4U),
  1671. .pllmdec = SYSCON_PLL1MDEC_MDIV(24U),
  1672. .pllRate = 48000000U,
  1673. .flags = PLL_SETUPFLAG_WAITLOCK,
  1674. };
  1675. CLOCK_SetPLL1Freq(&pll1Setup); /*!< Configure PLL1 to the desired values */
  1676. CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
  1677. CLOCK_AttachClk(kPLL1_to_USB0_CLK);
  1678. uint32_t delay = 100000;
  1679. while (delay--)
  1680. {
  1681. __asm("nop");
  1682. }
  1683. }
  1684. CLOCK_EnableClock(kCLOCK_Usbhmr0);
  1685. CLOCK_EnableClock(kCLOCK_Usbhsl0);
  1686. CLOCK_EnableClock(kCLOCK_UsbRam1);
  1687. return ret;
  1688. }
  1689. /* Enable USB PHY clock */
  1690. bool CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src, uint32_t freq)
  1691. {
  1692. volatile uint32_t i;
  1693. POWER_DisablePD(kPDRUNCFG_PD_XTAL32M);
  1694. POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M);
  1695. POWER_DisablePD(kPDRUNCFG_PD_FRO32K); /*!< Ensure FRO32k is on */
  1696. POWER_DisablePD(kPDRUNCFG_PD_XTAL32K); /*!< Ensure xtal32k is on */
  1697. POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /*!< Ensure xtal32k is on */
  1698. POWER_DisablePD(kPDRUNCFG_PD_LDOUSBHS); /*!< Ensure xtal32k is on */
  1699. /* wait to make sure PHY power is fully up */
  1700. i = 100000;
  1701. while (i--)
  1702. {
  1703. __asm("nop");
  1704. }
  1705. SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_ANALOG_CTRL(1);
  1706. SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_PHY(1);
  1707. USBPHY->CTRL_CLR = USBPHY_CTRL_SFTRST_MASK;
  1708. USBPHY->PLL_SIC = (USBPHY->PLL_SIC & ~USBPHY_PLL_SIC_PLL_DIV_SEL(0x7)) | USBPHY_PLL_SIC_PLL_DIV_SEL(0x06);
  1709. USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_SET_PLL_REG_ENABLE_MASK;
  1710. USBPHY->PLL_SIC_CLR = USBPHY_PLL_SIC_SET_PLL_BYPASS_MASK;
  1711. USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_SET_PLL_POWER_MASK;
  1712. USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_SET_PLL_EN_USB_CLKS_MASK;
  1713. USBPHY->PLL_SIC_SET =
  1714. USBPHY_PLL_SIC_SET_MISC2_CONTROL0_MASK; /* enables auto power down of PHY PLL during suspend */
  1715. USBPHY->CTRL_CLR = USBPHY_CTRL_CLR_CLKGATE_MASK;
  1716. USBPHY->PWD_SET = 0x0;
  1717. return true;
  1718. }
  1719. /* Enable USB DEVICE HIGH SPEED clock */
  1720. bool CLOCK_EnableUsbhs0DeviceClock(clock_usbhs_src_t src, uint32_t freq)
  1721. {
  1722. SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_RAM(1);
  1723. SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_DEV(1);
  1724. /* 16 MHz will be driven by the tb on the xtal1 pin of XTAL32M */
  1725. SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clock_in clock for clock module. */
  1726. ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT(1);
  1727. return true;
  1728. }
  1729. /* Enable USB HOST HIGH SPEED clock */
  1730. bool CLOCK_EnableUsbhs0HostClock(clock_usbhs_src_t src, uint32_t freq)
  1731. {
  1732. SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_RAM(1);
  1733. SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_HOST(1);
  1734. /* 16 MHz will be driven by the tb on the xtal1 pin of XTAL32M */
  1735. SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clock_in clock for clock module. */
  1736. ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT(1);
  1737. return true;
  1738. }