diff options
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1051/drivers/fsl_clock.c')
-rw-r--r-- | lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1051/drivers/fsl_clock.c | 1505 |
1 files changed, 1505 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1051/drivers/fsl_clock.c b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1051/drivers/fsl_clock.c new file mode 100644 index 000000000..11926c5ee --- /dev/null +++ b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1051/drivers/fsl_clock.c | |||
@@ -0,0 +1,1505 @@ | |||
1 | /* | ||
2 | * Copyright 2017 - 2020 NXP | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * SPDX-License-Identifier: BSD-3-Clause | ||
6 | */ | ||
7 | |||
8 | #include "fsl_clock.h" | ||
9 | /* Component ID definition, used by tools. */ | ||
10 | #ifndef FSL_COMPONENT_ID | ||
11 | #define FSL_COMPONENT_ID "platform.drivers.clock" | ||
12 | #endif | ||
13 | |||
14 | /******************************************************************************* | ||
15 | * Definitions | ||
16 | ******************************************************************************/ | ||
17 | /* To make full use of CM7 hardware FPU, use double instead of uint64_t in clock driver to | ||
18 | achieve better performance, it is depend on the IDE Floating point settings, if double precision is selected | ||
19 | in IDE, clock_64b_t will switch to double type automatically. only support IAR and MDK here */ | ||
20 | #if __FPU_USED | ||
21 | |||
22 | #if (defined(__ICCARM__)) | ||
23 | |||
24 | #if (__ARMVFP__ >= __ARMFPV5__) && \ | ||
25 | (__ARM_FP == 0xE) /*0xe implies support for half, single and double precision operations*/ | ||
26 | typedef double clock_64b_t; | ||
27 | #else | ||
28 | typedef uint64_t clock_64b_t; | ||
29 | #endif | ||
30 | |||
31 | #elif (defined(__GNUC__)) | ||
32 | |||
33 | #if (__ARM_FP == 0xE) /*0xe implies support for half, single and double precision operations*/ | ||
34 | typedef double clock_64b_t; | ||
35 | #else | ||
36 | typedef uint64_t clock_64b_t; | ||
37 | #endif | ||
38 | |||
39 | #elif defined(__CC_ARM) || defined(__ARMCC_VERSION) | ||
40 | |||
41 | #if defined __TARGET_FPU_FPV5_D16 | ||
42 | typedef double clock_64b_t; | ||
43 | #else | ||
44 | typedef uint64_t clock_64b_t; | ||
45 | #endif | ||
46 | |||
47 | #else | ||
48 | typedef uint64_t clock_64b_t; | ||
49 | #endif | ||
50 | |||
51 | #else | ||
52 | typedef uint64_t clock_64b_t; | ||
53 | #endif | ||
54 | |||
55 | /******************************************************************************* | ||
56 | * Variables | ||
57 | ******************************************************************************/ | ||
58 | |||
59 | /* External XTAL (OSC) clock frequency. */ | ||
60 | volatile uint32_t g_xtalFreq; | ||
61 | /* External RTC XTAL clock frequency. */ | ||
62 | volatile uint32_t g_rtcXtalFreq; | ||
63 | |||
64 | /******************************************************************************* | ||
65 | * Prototypes | ||
66 | ******************************************************************************/ | ||
67 | |||
68 | /*! | ||
69 | * @brief Get the periph clock frequency. | ||
70 | * | ||
71 | * @return Periph clock frequency in Hz. | ||
72 | */ | ||
73 | static uint32_t CLOCK_GetPeriphClkFreq(void); | ||
74 | |||
75 | /*! | ||
76 | * @brief Get the frequency of PLL USB1 software clock. | ||
77 | * | ||
78 | * @return The frequency of PLL USB1 software clock. | ||
79 | */ | ||
80 | static uint32_t CLOCK_GetPllUsb1SWFreq(void); | ||
81 | |||
82 | /******************************************************************************* | ||
83 | * Code | ||
84 | ******************************************************************************/ | ||
85 | |||
86 | static uint32_t CLOCK_GetPeriphClkFreq(void) | ||
87 | { | ||
88 | uint32_t freq; | ||
89 | |||
90 | /* Periph_clk2_clk ---> Periph_clk */ | ||
91 | if ((CCM->CBCDR & CCM_CBCDR_PERIPH_CLK_SEL_MASK) != 0U) | ||
92 | { | ||
93 | switch (CCM->CBCMR & CCM_CBCMR_PERIPH_CLK2_SEL_MASK) | ||
94 | { | ||
95 | /* Pll3_sw_clk ---> Periph_clk2_clk ---> Periph_clk */ | ||
96 | case CCM_CBCMR_PERIPH_CLK2_SEL(0U): | ||
97 | freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1); | ||
98 | break; | ||
99 | |||
100 | /* Osc_clk ---> Periph_clk2_clk ---> Periph_clk */ | ||
101 | case CCM_CBCMR_PERIPH_CLK2_SEL(1U): | ||
102 | freq = CLOCK_GetOscFreq(); | ||
103 | break; | ||
104 | |||
105 | case CCM_CBCMR_PERIPH_CLK2_SEL(2U): | ||
106 | freq = CLOCK_GetPllFreq(kCLOCK_PllSys); | ||
107 | break; | ||
108 | |||
109 | case CCM_CBCMR_PERIPH_CLK2_SEL(3U): | ||
110 | default: | ||
111 | freq = 0U; | ||
112 | break; | ||
113 | } | ||
114 | |||
115 | freq /= (((CCM->CBCDR & CCM_CBCDR_PERIPH_CLK2_PODF_MASK) >> CCM_CBCDR_PERIPH_CLK2_PODF_SHIFT) + 1U); | ||
116 | } | ||
117 | /* Pre_Periph_clk ---> Periph_clk */ | ||
118 | else | ||
119 | { | ||
120 | switch (CCM->CBCMR & CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK) | ||
121 | { | ||
122 | /* PLL2 ---> Pre_Periph_clk ---> Periph_clk */ | ||
123 | case CCM_CBCMR_PRE_PERIPH_CLK_SEL(0U): | ||
124 | freq = CLOCK_GetPllFreq(kCLOCK_PllSys); | ||
125 | break; | ||
126 | |||
127 | /* PLL2 PFD2 ---> Pre_Periph_clk ---> Periph_clk */ | ||
128 | case CCM_CBCMR_PRE_PERIPH_CLK_SEL(1U): | ||
129 | freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2); | ||
130 | break; | ||
131 | |||
132 | /* PLL2 PFD0 ---> Pre_Periph_clk ---> Periph_clk */ | ||
133 | case CCM_CBCMR_PRE_PERIPH_CLK_SEL(2U): | ||
134 | freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd0); | ||
135 | break; | ||
136 | |||
137 | /* PLL1 divided(/2) ---> Pre_Periph_clk ---> Periph_clk */ | ||
138 | case CCM_CBCMR_PRE_PERIPH_CLK_SEL(3U): | ||
139 | freq = CLOCK_GetPllFreq(kCLOCK_PllArm) / | ||
140 | (((CCM->CACRR & CCM_CACRR_ARM_PODF_MASK) >> CCM_CACRR_ARM_PODF_SHIFT) + 1U); | ||
141 | break; | ||
142 | |||
143 | default: | ||
144 | freq = 0U; | ||
145 | break; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | return freq; | ||
150 | } | ||
151 | |||
152 | static uint32_t CLOCK_GetPllUsb1SWFreq(void) | ||
153 | { | ||
154 | uint32_t freq; | ||
155 | |||
156 | switch ((CCM->CCSR & CCM_CCSR_PLL3_SW_CLK_SEL_MASK) >> CCM_CCSR_PLL3_SW_CLK_SEL_SHIFT) | ||
157 | { | ||
158 | case 0: | ||
159 | { | ||
160 | freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1); | ||
161 | break; | ||
162 | } | ||
163 | case 1: | ||
164 | { | ||
165 | freq = 24000000UL; | ||
166 | break; | ||
167 | } | ||
168 | default: | ||
169 | freq = 0UL; | ||
170 | break; | ||
171 | } | ||
172 | |||
173 | return freq; | ||
174 | } | ||
175 | |||
176 | /*! | ||
177 | * brief Initialize the external 24MHz clock. | ||
178 | * | ||
179 | * This function supports two modes: | ||
180 | * 1. Use external crystal oscillator. | ||
181 | * 2. Bypass the external crystal oscillator, using input source clock directly. | ||
182 | * | ||
183 | * After this function, please call ref CLOCK_SetXtal0Freq to inform clock driver | ||
184 | * the external clock frequency. | ||
185 | * | ||
186 | * param bypassXtalOsc Pass in true to bypass the external crystal oscillator. | ||
187 | * note This device does not support bypass external crystal oscillator, so | ||
188 | * the input parameter should always be false. | ||
189 | */ | ||
190 | void CLOCK_InitExternalClk(bool bypassXtalOsc) | ||
191 | { | ||
192 | /* This device does not support bypass XTAL OSC. */ | ||
193 | assert(!bypassXtalOsc); | ||
194 | |||
195 | CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power up */ | ||
196 | while ((XTALOSC24M->LOWPWR_CTRL & XTALOSC24M_LOWPWR_CTRL_XTALOSC_PWRUP_STAT_MASK) == 0U) | ||
197 | { | ||
198 | } | ||
199 | CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; /* detect freq */ | ||
200 | while ((CCM_ANALOG->MISC0 & CCM_ANALOG_MISC0_OSC_XTALOK_MASK) == 0UL) | ||
201 | { | ||
202 | } | ||
203 | CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; | ||
204 | } | ||
205 | |||
206 | /*! | ||
207 | * brief Deinitialize the external 24MHz clock. | ||
208 | * | ||
209 | * This function disables the external 24MHz clock. | ||
210 | * | ||
211 | * After this function, please call ref CLOCK_SetXtal0Freq to set external clock | ||
212 | * frequency to 0. | ||
213 | */ | ||
214 | void CLOCK_DeinitExternalClk(void) | ||
215 | { | ||
216 | CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power down */ | ||
217 | } | ||
218 | |||
219 | /*! | ||
220 | * brief Switch the OSC. | ||
221 | * | ||
222 | * This function switches the OSC source for SoC. | ||
223 | * | ||
224 | * param osc OSC source to switch to. | ||
225 | */ | ||
226 | void CLOCK_SwitchOsc(clock_osc_t osc) | ||
227 | { | ||
228 | if (osc == kCLOCK_RcOsc) | ||
229 | { | ||
230 | XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_SET_OSC_SEL_MASK; | ||
231 | } | ||
232 | else | ||
233 | { | ||
234 | XTALOSC24M->LOWPWR_CTRL_CLR = XTALOSC24M_LOWPWR_CTRL_CLR_OSC_SEL_MASK; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | /*! | ||
239 | * brief Initialize the RC oscillator 24MHz clock. | ||
240 | */ | ||
241 | void CLOCK_InitRcOsc24M(void) | ||
242 | { | ||
243 | XTALOSC24M->LOWPWR_CTRL |= XTALOSC24M_LOWPWR_CTRL_RC_OSC_EN_MASK; | ||
244 | } | ||
245 | |||
246 | /*! | ||
247 | * brief Power down the RCOSC 24M clock. | ||
248 | */ | ||
249 | void CLOCK_DeinitRcOsc24M(void) | ||
250 | { | ||
251 | XTALOSC24M->LOWPWR_CTRL &= ~XTALOSC24M_LOWPWR_CTRL_RC_OSC_EN_MASK; | ||
252 | } | ||
253 | |||
254 | /*! | ||
255 | * brief Gets the AHB clock frequency. | ||
256 | * | ||
257 | * return The AHB clock frequency value in hertz. | ||
258 | */ | ||
259 | uint32_t CLOCK_GetAhbFreq(void) | ||
260 | { | ||
261 | return CLOCK_GetPeriphClkFreq() / (((CCM->CBCDR & CCM_CBCDR_AHB_PODF_MASK) >> CCM_CBCDR_AHB_PODF_SHIFT) + 1U); | ||
262 | } | ||
263 | |||
264 | /*! | ||
265 | * brief Gets the SEMC clock frequency. | ||
266 | * | ||
267 | * return The SEMC clock frequency value in hertz. | ||
268 | */ | ||
269 | uint32_t CLOCK_GetSemcFreq(void) | ||
270 | { | ||
271 | uint32_t freq; | ||
272 | |||
273 | /* SEMC alternative clock ---> SEMC Clock */ | ||
274 | if ((CCM->CBCDR & CCM_CBCDR_SEMC_CLK_SEL_MASK) != 0U) | ||
275 | { | ||
276 | /* PLL3 PFD1 ---> SEMC alternative clock ---> SEMC Clock */ | ||
277 | if ((CCM->CBCDR & CCM_CBCDR_SEMC_ALT_CLK_SEL_MASK) != 0U) | ||
278 | { | ||
279 | freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd1); | ||
280 | } | ||
281 | /* PLL2 PFD2 ---> SEMC alternative clock ---> SEMC Clock */ | ||
282 | else | ||
283 | { | ||
284 | freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2); | ||
285 | } | ||
286 | } | ||
287 | /* Periph_clk ---> SEMC Clock */ | ||
288 | else | ||
289 | { | ||
290 | freq = CLOCK_GetPeriphClkFreq(); | ||
291 | } | ||
292 | |||
293 | freq /= (((CCM->CBCDR & CCM_CBCDR_SEMC_PODF_MASK) >> CCM_CBCDR_SEMC_PODF_SHIFT) + 1U); | ||
294 | |||
295 | return freq; | ||
296 | } | ||
297 | |||
298 | /*! | ||
299 | * brief Gets the IPG clock frequency. | ||
300 | * | ||
301 | * return The IPG clock frequency value in hertz. | ||
302 | */ | ||
303 | uint32_t CLOCK_GetIpgFreq(void) | ||
304 | { | ||
305 | return CLOCK_GetAhbFreq() / (((CCM->CBCDR & CCM_CBCDR_IPG_PODF_MASK) >> CCM_CBCDR_IPG_PODF_SHIFT) + 1U); | ||
306 | } | ||
307 | |||
308 | uint32_t CLOCK_GetPerClkFreq(void) | ||
309 | { | ||
310 | uint32_t freq; | ||
311 | |||
312 | /* Osc_clk ---> PER Clock*/ | ||
313 | if ((CCM->CSCMR1 & CCM_CSCMR1_PERCLK_CLK_SEL_MASK) != 0U) | ||
314 | { | ||
315 | freq = CLOCK_GetOscFreq(); | ||
316 | } | ||
317 | /* Periph_clk ---> AHB Clock ---> IPG Clock ---> PER Clock */ | ||
318 | else | ||
319 | { | ||
320 | freq = CLOCK_GetIpgFreq(); | ||
321 | } | ||
322 | |||
323 | freq /= (((CCM->CSCMR1 & CCM_CSCMR1_PERCLK_PODF_MASK) >> CCM_CSCMR1_PERCLK_PODF_SHIFT) + 1U); | ||
324 | |||
325 | return freq; | ||
326 | } | ||
327 | |||
328 | /*! | ||
329 | * brief Gets the clock frequency for a specific clock name. | ||
330 | * | ||
331 | * This function checks the current clock configurations and then calculates | ||
332 | * the clock frequency for a specific clock name defined in clock_name_t. | ||
333 | * | ||
334 | * param clockName Clock names defined in clock_name_t | ||
335 | * return Clock frequency value in hertz | ||
336 | */ | ||
337 | uint32_t CLOCK_GetFreq(clock_name_t name) | ||
338 | { | ||
339 | uint32_t freq; | ||
340 | |||
341 | switch (name) | ||
342 | { | ||
343 | case kCLOCK_CpuClk: | ||
344 | case kCLOCK_AhbClk: | ||
345 | freq = CLOCK_GetAhbFreq(); | ||
346 | break; | ||
347 | |||
348 | case kCLOCK_SemcClk: | ||
349 | freq = CLOCK_GetSemcFreq(); | ||
350 | break; | ||
351 | |||
352 | case kCLOCK_IpgClk: | ||
353 | freq = CLOCK_GetIpgFreq(); | ||
354 | break; | ||
355 | |||
356 | case kCLOCK_PerClk: | ||
357 | freq = CLOCK_GetPerClkFreq(); | ||
358 | break; | ||
359 | |||
360 | case kCLOCK_OscClk: | ||
361 | freq = CLOCK_GetOscFreq(); | ||
362 | break; | ||
363 | case kCLOCK_RtcClk: | ||
364 | freq = CLOCK_GetRtcFreq(); | ||
365 | break; | ||
366 | case kCLOCK_ArmPllClk: | ||
367 | freq = CLOCK_GetPllFreq(kCLOCK_PllArm); | ||
368 | break; | ||
369 | case kCLOCK_Usb1PllClk: | ||
370 | freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1); | ||
371 | break; | ||
372 | case kCLOCK_Usb1PllPfd0Clk: | ||
373 | freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd0); | ||
374 | break; | ||
375 | case kCLOCK_Usb1PllPfd1Clk: | ||
376 | freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd1); | ||
377 | break; | ||
378 | case kCLOCK_Usb1PllPfd2Clk: | ||
379 | freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd2); | ||
380 | break; | ||
381 | case kCLOCK_Usb1PllPfd3Clk: | ||
382 | freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd3); | ||
383 | break; | ||
384 | case kCLOCK_Usb1SwClk: | ||
385 | freq = CLOCK_GetPllUsb1SWFreq(); | ||
386 | break; | ||
387 | case kCLOCK_Usb1Sw120MClk: | ||
388 | freq = CLOCK_GetPllUsb1SWFreq() / 4UL; | ||
389 | break; | ||
390 | case kCLOCK_Usb1Sw60MClk: | ||
391 | freq = CLOCK_GetPllUsb1SWFreq() / 8UL; | ||
392 | break; | ||
393 | case kCLOCK_Usb1Sw80MClk: | ||
394 | freq = CLOCK_GetPllUsb1SWFreq() / 6UL; | ||
395 | break; | ||
396 | case kCLOCK_Usb2PllClk: | ||
397 | freq = CLOCK_GetPllFreq(kCLOCK_PllUsb2); | ||
398 | break; | ||
399 | case kCLOCK_SysPllClk: | ||
400 | freq = CLOCK_GetPllFreq(kCLOCK_PllSys); | ||
401 | break; | ||
402 | case kCLOCK_SysPllPfd0Clk: | ||
403 | freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd0); | ||
404 | break; | ||
405 | case kCLOCK_SysPllPfd1Clk: | ||
406 | freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd1); | ||
407 | break; | ||
408 | case kCLOCK_SysPllPfd2Clk: | ||
409 | freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2); | ||
410 | break; | ||
411 | case kCLOCK_SysPllPfd3Clk: | ||
412 | freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd3); | ||
413 | break; | ||
414 | case kCLOCK_EnetPll0Clk: | ||
415 | freq = CLOCK_GetPllFreq(kCLOCK_PllEnet); | ||
416 | break; | ||
417 | case kCLOCK_EnetPll1Clk: | ||
418 | freq = CLOCK_GetPllFreq(kCLOCK_PllEnet25M); | ||
419 | break; | ||
420 | case kCLOCK_AudioPllClk: | ||
421 | freq = CLOCK_GetPllFreq(kCLOCK_PllAudio); | ||
422 | break; | ||
423 | case kCLOCK_VideoPllClk: | ||
424 | freq = CLOCK_GetPllFreq(kCLOCK_PllVideo); | ||
425 | break; | ||
426 | default: | ||
427 | freq = 0U; | ||
428 | break; | ||
429 | } | ||
430 | |||
431 | return freq; | ||
432 | } | ||
433 | |||
434 | /*! | ||
435 | * brief Gets the frequency of selected clock root. | ||
436 | * | ||
437 | * param clockRoot The clock root used to get the frequency, please refer to @ref clock_root_t. | ||
438 | * return The frequency of selected clock root. | ||
439 | */ | ||
440 | uint32_t CLOCK_GetClockRootFreq(clock_root_t clockRoot) | ||
441 | { | ||
442 | const clock_name_t clockRootSourceArray[][6] = CLOCK_ROOT_SOUCE; | ||
443 | const clock_mux_t clockRootMuxTupleArray[] = CLOCK_ROOT_MUX_TUPLE; | ||
444 | const clock_div_t clockRootDivTupleArray[][2] = CLOCK_ROOT_DIV_TUPLE; | ||
445 | uint32_t freq = 0UL; | ||
446 | clock_mux_t clockRootMuxTuple = clockRootMuxTupleArray[(uint8_t)clockRoot]; | ||
447 | clock_div_t clockRootPreDivTuple = clockRootDivTupleArray[(uint8_t)clockRoot][0]; | ||
448 | clock_div_t clockRootPostDivTuple = clockRootDivTupleArray[(uint8_t)clockRoot][1]; | ||
449 | uint32_t clockRootMuxValue = (CCM_TUPLE_REG(CCM, clockRootMuxTuple) & CCM_TUPLE_MASK(clockRootMuxTuple)) >> | ||
450 | CCM_TUPLE_SHIFT(clockRootMuxTuple); | ||
451 | clock_name_t clockSourceName; | ||
452 | |||
453 | clockSourceName = clockRootSourceArray[(uint8_t)clockRoot][clockRootMuxValue]; | ||
454 | |||
455 | assert(clockSourceName != kCLOCK_NoneName); | ||
456 | |||
457 | freq = CLOCK_GetFreq(clockSourceName); | ||
458 | |||
459 | if (clockRootPreDivTuple != kCLOCK_NonePreDiv) | ||
460 | { | ||
461 | freq /= ((CCM_TUPLE_REG(CCM, clockRootPreDivTuple) & CCM_TUPLE_MASK(clockRootPreDivTuple)) >> | ||
462 | CCM_TUPLE_SHIFT(clockRootPreDivTuple)) + | ||
463 | 1UL; | ||
464 | } | ||
465 | |||
466 | freq /= ((CCM_TUPLE_REG(CCM, clockRootPostDivTuple) & CCM_TUPLE_MASK(clockRootPostDivTuple)) >> | ||
467 | CCM_TUPLE_SHIFT(clockRootPostDivTuple)) + | ||
468 | 1UL; | ||
469 | |||
470 | return freq; | ||
471 | } | ||
472 | |||
473 | /*! brief Enable USB HS clock. | ||
474 | * | ||
475 | * This function only enables the access to USB HS prepheral, upper layer | ||
476 | * should first call the ref CLOCK_EnableUsbhs0PhyPllClock to enable the PHY | ||
477 | * clock to use USB HS. | ||
478 | * | ||
479 | * param src USB HS does not care about the clock source, here must be ref kCLOCK_UsbSrcUnused. | ||
480 | * param freq USB HS does not care about the clock source, so this parameter is ignored. | ||
481 | * retval true The clock is set successfully. | ||
482 | * retval false The clock source is invalid to get proper USB HS clock. | ||
483 | */ | ||
484 | bool CLOCK_EnableUsbhs0Clock(clock_usb_src_t src, uint32_t freq) | ||
485 | { | ||
486 | uint32_t i; | ||
487 | CCM->CCGR6 |= CCM_CCGR6_CG0_MASK; | ||
488 | USB1->USBCMD |= USBHS_USBCMD_RST_MASK; | ||
489 | |||
490 | /* Add a delay between RST and RS so make sure there is a DP pullup sequence*/ | ||
491 | for (i = 0; i < 400000U; i++) | ||
492 | { | ||
493 | __ASM("nop"); | ||
494 | } | ||
495 | PMU->REG_3P0 = (PMU->REG_3P0 & (~PMU_REG_3P0_OUTPUT_TRG_MASK)) | | ||
496 | (PMU_REG_3P0_OUTPUT_TRG(0x17) | PMU_REG_3P0_ENABLE_LINREG_MASK); | ||
497 | return true; | ||
498 | } | ||
499 | |||
500 | /*! brief Enable USB HS clock. | ||
501 | * | ||
502 | * This function only enables the access to USB HS prepheral, upper layer | ||
503 | * should first call the ref CLOCK_EnableUsbhs0PhyPllClock to enable the PHY | ||
504 | * clock to use USB HS. | ||
505 | * | ||
506 | * param src USB HS does not care about the clock source, here must be ref kCLOCK_UsbSrcUnused. | ||
507 | * param freq USB HS does not care about the clock source, so this parameter is ignored. | ||
508 | * retval true The clock is set successfully. | ||
509 | * retval false The clock source is invalid to get proper USB HS clock. | ||
510 | */ | ||
511 | bool CLOCK_EnableUsbhs1Clock(clock_usb_src_t src, uint32_t freq) | ||
512 | { | ||
513 | uint32_t i = 0; | ||
514 | CCM->CCGR6 |= CCM_CCGR6_CG0_MASK; | ||
515 | USB2->USBCMD |= USBHS_USBCMD_RST_MASK; | ||
516 | |||
517 | /* Add a delay between RST and RS so make sure there is a DP pullup sequence*/ | ||
518 | for (i = 0; i < 400000U; i++) | ||
519 | { | ||
520 | __ASM("nop"); | ||
521 | } | ||
522 | PMU->REG_3P0 = (PMU->REG_3P0 & (~PMU_REG_3P0_OUTPUT_TRG_MASK)) | | ||
523 | (PMU_REG_3P0_OUTPUT_TRG(0x17) | PMU_REG_3P0_ENABLE_LINREG_MASK); | ||
524 | return true; | ||
525 | } | ||
526 | |||
527 | /*! brief Enable USB HS PHY PLL clock. | ||
528 | * | ||
529 | * This function enables the internal 480MHz USB PHY PLL clock. | ||
530 | * | ||
531 | * param src USB HS PHY PLL clock source. | ||
532 | * param freq The frequency specified by src. | ||
533 | * retval true The clock is set successfully. | ||
534 | * retval false The clock source is invalid to get proper USB HS clock. | ||
535 | */ | ||
536 | bool CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src, uint32_t freq) | ||
537 | { | ||
538 | const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U}; | ||
539 | if ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_ENABLE_MASK) != 0U) | ||
540 | { | ||
541 | CCM_ANALOG->PLL_USB1 |= CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK; | ||
542 | } | ||
543 | else | ||
544 | { | ||
545 | CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll); | ||
546 | } | ||
547 | USBPHY1->CTRL &= ~USBPHY_CTRL_SFTRST_MASK; /* release PHY from reset */ | ||
548 | USBPHY1->CTRL &= ~USBPHY_CTRL_CLKGATE_MASK; | ||
549 | |||
550 | USBPHY1->PWD = 0; | ||
551 | USBPHY1->CTRL |= USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK | USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK | | ||
552 | USBPHY_CTRL_ENUTMILEVEL2_MASK | USBPHY_CTRL_ENUTMILEVEL3_MASK; | ||
553 | return true; | ||
554 | } | ||
555 | |||
556 | /*! brief Disable USB HS PHY PLL clock. | ||
557 | * | ||
558 | * This function disables USB HS PHY PLL clock. | ||
559 | */ | ||
560 | void CLOCK_DisableUsbhs0PhyPllClock(void) | ||
561 | { | ||
562 | CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK; | ||
563 | USBPHY1->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* Set to 1U to gate clocks */ | ||
564 | } | ||
565 | |||
566 | /*! | ||
567 | * brief Initialize the ARM PLL. | ||
568 | * | ||
569 | * This function initialize the ARM PLL with specific settings | ||
570 | * | ||
571 | * param config configuration to set to PLL. | ||
572 | */ | ||
573 | void CLOCK_InitArmPll(const clock_arm_pll_config_t *config) | ||
574 | { | ||
575 | /* Bypass PLL first */ | ||
576 | CCM_ANALOG->PLL_ARM = (CCM_ANALOG->PLL_ARM & (~CCM_ANALOG_PLL_ARM_BYPASS_CLK_SRC_MASK)) | | ||
577 | CCM_ANALOG_PLL_ARM_BYPASS_MASK | CCM_ANALOG_PLL_ARM_BYPASS_CLK_SRC(config->src); | ||
578 | |||
579 | CCM_ANALOG->PLL_ARM = | ||
580 | (CCM_ANALOG->PLL_ARM & (~(CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK | CCM_ANALOG_PLL_ARM_POWERDOWN_MASK))) | | ||
581 | CCM_ANALOG_PLL_ARM_ENABLE_MASK | CCM_ANALOG_PLL_ARM_DIV_SELECT(config->loopDivider); | ||
582 | |||
583 | while ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_LOCK_MASK) == 0UL) | ||
584 | { | ||
585 | } | ||
586 | |||
587 | /* Disable Bypass */ | ||
588 | CCM_ANALOG->PLL_ARM &= ~CCM_ANALOG_PLL_ARM_BYPASS_MASK; | ||
589 | } | ||
590 | |||
591 | /*! | ||
592 | * brief De-initialize the ARM PLL. | ||
593 | */ | ||
594 | void CLOCK_DeinitArmPll(void) | ||
595 | { | ||
596 | CCM_ANALOG->PLL_ARM = CCM_ANALOG_PLL_ARM_POWERDOWN_MASK; | ||
597 | } | ||
598 | |||
599 | /*! | ||
600 | * brief Initialize the System PLL. | ||
601 | * | ||
602 | * This function initializes the System PLL with specific settings | ||
603 | * | ||
604 | * param config Configuration to set to PLL. | ||
605 | */ | ||
606 | void CLOCK_InitSysPll(const clock_sys_pll_config_t *config) | ||
607 | { | ||
608 | /* Bypass PLL first */ | ||
609 | CCM_ANALOG->PLL_SYS = (CCM_ANALOG->PLL_SYS & (~CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC_MASK)) | | ||
610 | CCM_ANALOG_PLL_SYS_BYPASS_MASK | CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC(config->src); | ||
611 | |||
612 | CCM_ANALOG->PLL_SYS = | ||
613 | (CCM_ANALOG->PLL_SYS & (~(CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK | CCM_ANALOG_PLL_SYS_POWERDOWN_MASK))) | | ||
614 | CCM_ANALOG_PLL_SYS_ENABLE_MASK | CCM_ANALOG_PLL_SYS_DIV_SELECT(config->loopDivider); | ||
615 | |||
616 | /* Initialize the fractional mode */ | ||
617 | CCM_ANALOG->PLL_SYS_NUM = CCM_ANALOG_PLL_SYS_NUM_A(config->numerator); | ||
618 | CCM_ANALOG->PLL_SYS_DENOM = CCM_ANALOG_PLL_SYS_DENOM_B(config->denominator); | ||
619 | |||
620 | /* Initialize the spread spectrum mode */ | ||
621 | CCM_ANALOG->PLL_SYS_SS = CCM_ANALOG_PLL_SYS_SS_STEP(config->ss_step) | | ||
622 | CCM_ANALOG_PLL_SYS_SS_ENABLE(config->ss_enable) | | ||
623 | CCM_ANALOG_PLL_SYS_SS_STOP(config->ss_stop); | ||
624 | |||
625 | while ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_LOCK_MASK) == 0UL) | ||
626 | { | ||
627 | } | ||
628 | |||
629 | /* Disable Bypass */ | ||
630 | CCM_ANALOG->PLL_SYS &= ~CCM_ANALOG_PLL_SYS_BYPASS_MASK; | ||
631 | } | ||
632 | |||
633 | /*! | ||
634 | * brief De-initialize the System PLL. | ||
635 | */ | ||
636 | void CLOCK_DeinitSysPll(void) | ||
637 | { | ||
638 | CCM_ANALOG->PLL_SYS = CCM_ANALOG_PLL_SYS_POWERDOWN_MASK; | ||
639 | } | ||
640 | |||
641 | /*! | ||
642 | * brief Initialize the USB1 PLL. | ||
643 | * | ||
644 | * This function initializes the USB1 PLL with specific settings | ||
645 | * | ||
646 | * param config Configuration to set to PLL. | ||
647 | */ | ||
648 | void CLOCK_InitUsb1Pll(const clock_usb_pll_config_t *config) | ||
649 | { | ||
650 | /* Bypass PLL first */ | ||
651 | CCM_ANALOG->PLL_USB1 = (CCM_ANALOG->PLL_USB1 & (~CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_MASK)) | | ||
652 | CCM_ANALOG_PLL_USB1_BYPASS_MASK | CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC(config->src); | ||
653 | |||
654 | CCM_ANALOG->PLL_USB1 = (CCM_ANALOG->PLL_USB1 & (~CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK)) | | ||
655 | CCM_ANALOG_PLL_USB1_ENABLE_MASK | CCM_ANALOG_PLL_USB1_POWER_MASK | | ||
656 | CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK | CCM_ANALOG_PLL_USB1_DIV_SELECT(config->loopDivider); | ||
657 | |||
658 | while ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_LOCK_MASK) == 0UL) | ||
659 | { | ||
660 | } | ||
661 | |||
662 | /* Disable Bypass */ | ||
663 | CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_BYPASS_MASK; | ||
664 | } | ||
665 | |||
666 | /*! | ||
667 | * brief Deinitialize the USB1 PLL. | ||
668 | */ | ||
669 | void CLOCK_DeinitUsb1Pll(void) | ||
670 | { | ||
671 | CCM_ANALOG->PLL_USB1 = 0U; | ||
672 | } | ||
673 | |||
674 | /*! | ||
675 | * brief Initialize the USB2 PLL. | ||
676 | * | ||
677 | * This function initializes the USB2 PLL with specific settings | ||
678 | * | ||
679 | * param config Configuration to set to PLL. | ||
680 | */ | ||
681 | void CLOCK_InitUsb2Pll(const clock_usb_pll_config_t *config) | ||
682 | { | ||
683 | /* Bypass PLL first */ | ||
684 | CCM_ANALOG->PLL_USB2 = (CCM_ANALOG->PLL_USB2 & (~CCM_ANALOG_PLL_USB2_BYPASS_CLK_SRC_MASK)) | | ||
685 | CCM_ANALOG_PLL_USB2_BYPASS_MASK | CCM_ANALOG_PLL_USB2_BYPASS_CLK_SRC(config->src); | ||
686 | |||
687 | CCM_ANALOG->PLL_USB2 = (CCM_ANALOG->PLL_USB2 & (~CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK)) | | ||
688 | CCM_ANALOG_PLL_USB2_ENABLE_MASK | CCM_ANALOG_PLL_USB2_POWER_MASK | | ||
689 | CCM_ANALOG_PLL_USB2_EN_USB_CLKS_MASK | CCM_ANALOG_PLL_USB2_DIV_SELECT(config->loopDivider); | ||
690 | |||
691 | while ((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_LOCK_MASK) == 0UL) | ||
692 | { | ||
693 | } | ||
694 | |||
695 | /* Disable Bypass */ | ||
696 | CCM_ANALOG->PLL_USB2 &= ~CCM_ANALOG_PLL_USB2_BYPASS_MASK; | ||
697 | } | ||
698 | |||
699 | /*! | ||
700 | * brief Deinitialize the USB2 PLL. | ||
701 | */ | ||
702 | void CLOCK_DeinitUsb2Pll(void) | ||
703 | { | ||
704 | CCM_ANALOG->PLL_USB2 = 0U; | ||
705 | } | ||
706 | |||
707 | /*! | ||
708 | * brief Initializes the Audio PLL. | ||
709 | * | ||
710 | * This function initializes the Audio PLL with specific settings | ||
711 | * | ||
712 | * param config Configuration to set to PLL. | ||
713 | */ | ||
714 | void CLOCK_InitAudioPll(const clock_audio_pll_config_t *config) | ||
715 | { | ||
716 | uint32_t pllAudio; | ||
717 | uint32_t misc2 = 0; | ||
718 | |||
719 | /* Bypass PLL first */ | ||
720 | CCM_ANALOG->PLL_AUDIO = (CCM_ANALOG->PLL_AUDIO & (~CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC_MASK)) | | ||
721 | CCM_ANALOG_PLL_AUDIO_BYPASS_MASK | CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC(config->src); | ||
722 | |||
723 | CCM_ANALOG->PLL_AUDIO_NUM = CCM_ANALOG_PLL_AUDIO_NUM_A(config->numerator); | ||
724 | CCM_ANALOG->PLL_AUDIO_DENOM = CCM_ANALOG_PLL_AUDIO_DENOM_B(config->denominator); | ||
725 | |||
726 | /* | ||
727 | * Set post divider: | ||
728 | * | ||
729 | * ------------------------------------------------------------------------ | ||
730 | * | config->postDivider | PLL_AUDIO[POST_DIV_SELECT] | MISC2[AUDIO_DIV] | | ||
731 | * ------------------------------------------------------------------------ | ||
732 | * | 1 | 2 | 0 | | ||
733 | * ------------------------------------------------------------------------ | ||
734 | * | 2 | 1 | 0 | | ||
735 | * ------------------------------------------------------------------------ | ||
736 | * | 4 | 2 | 3 | | ||
737 | * ------------------------------------------------------------------------ | ||
738 | * | 8 | 1 | 3 | | ||
739 | * ------------------------------------------------------------------------ | ||
740 | * | 16 | 0 | 3 | | ||
741 | * ------------------------------------------------------------------------ | ||
742 | */ | ||
743 | pllAudio = | ||
744 | (CCM_ANALOG->PLL_AUDIO & (~(CCM_ANALOG_PLL_AUDIO_DIV_SELECT_MASK | CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK))) | | ||
745 | CCM_ANALOG_PLL_AUDIO_ENABLE_MASK | CCM_ANALOG_PLL_AUDIO_DIV_SELECT(config->loopDivider); | ||
746 | |||
747 | switch (config->postDivider) | ||
748 | { | ||
749 | case 16: | ||
750 | pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(0); | ||
751 | misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; | ||
752 | break; | ||
753 | |||
754 | case 8: | ||
755 | pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1); | ||
756 | misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; | ||
757 | break; | ||
758 | |||
759 | case 4: | ||
760 | pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2); | ||
761 | misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; | ||
762 | break; | ||
763 | |||
764 | case 2: | ||
765 | pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1); | ||
766 | break; | ||
767 | |||
768 | default: | ||
769 | pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2); | ||
770 | break; | ||
771 | } | ||
772 | |||
773 | CCM_ANALOG->MISC2 = | ||
774 | (CCM_ANALOG->MISC2 & ~(CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK)) | misc2; | ||
775 | |||
776 | CCM_ANALOG->PLL_AUDIO = pllAudio; | ||
777 | |||
778 | while ((CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK_MASK) == 0UL) | ||
779 | { | ||
780 | } | ||
781 | |||
782 | /* Disable Bypass */ | ||
783 | CCM_ANALOG->PLL_AUDIO &= ~CCM_ANALOG_PLL_AUDIO_BYPASS_MASK; | ||
784 | } | ||
785 | |||
786 | /*! | ||
787 | * brief De-initialize the Audio PLL. | ||
788 | */ | ||
789 | void CLOCK_DeinitAudioPll(void) | ||
790 | { | ||
791 | CCM_ANALOG->PLL_AUDIO = (uint32_t)CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK; | ||
792 | } | ||
793 | |||
794 | /*! | ||
795 | * brief Initialize the video PLL. | ||
796 | * | ||
797 | * This function configures the Video PLL with specific settings | ||
798 | * | ||
799 | * param config configuration to set to PLL. | ||
800 | */ | ||
801 | void CLOCK_InitVideoPll(const clock_video_pll_config_t *config) | ||
802 | { | ||
803 | uint32_t pllVideo; | ||
804 | uint32_t misc2 = 0; | ||
805 | |||
806 | /* Bypass PLL first */ | ||
807 | CCM_ANALOG->PLL_VIDEO = (CCM_ANALOG->PLL_VIDEO & (~CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC_MASK)) | | ||
808 | CCM_ANALOG_PLL_VIDEO_BYPASS_MASK | CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC(config->src); | ||
809 | |||
810 | CCM_ANALOG->PLL_VIDEO_NUM = CCM_ANALOG_PLL_VIDEO_NUM_A(config->numerator); | ||
811 | CCM_ANALOG->PLL_VIDEO_DENOM = CCM_ANALOG_PLL_VIDEO_DENOM_B(config->denominator); | ||
812 | |||
813 | /* | ||
814 | * Set post divider: | ||
815 | * | ||
816 | * ------------------------------------------------------------------------ | ||
817 | * | config->postDivider | PLL_VIDEO[POST_DIV_SELECT] | MISC2[VIDEO_DIV] | | ||
818 | * ------------------------------------------------------------------------ | ||
819 | * | 1 | 2 | 0 | | ||
820 | * ------------------------------------------------------------------------ | ||
821 | * | 2 | 1 | 0 | | ||
822 | * ------------------------------------------------------------------------ | ||
823 | * | 4 | 2 | 3 | | ||
824 | * ------------------------------------------------------------------------ | ||
825 | * | 8 | 1 | 3 | | ||
826 | * ------------------------------------------------------------------------ | ||
827 | * | 16 | 0 | 3 | | ||
828 | * ------------------------------------------------------------------------ | ||
829 | */ | ||
830 | pllVideo = | ||
831 | (CCM_ANALOG->PLL_VIDEO & (~(CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK | CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK))) | | ||
832 | CCM_ANALOG_PLL_VIDEO_ENABLE_MASK | CCM_ANALOG_PLL_VIDEO_DIV_SELECT(config->loopDivider); | ||
833 | |||
834 | switch (config->postDivider) | ||
835 | { | ||
836 | case 16: | ||
837 | pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(0); | ||
838 | misc2 = CCM_ANALOG_MISC2_VIDEO_DIV(3); | ||
839 | break; | ||
840 | |||
841 | case 8: | ||
842 | pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1); | ||
843 | misc2 = CCM_ANALOG_MISC2_VIDEO_DIV(3); | ||
844 | break; | ||
845 | |||
846 | case 4: | ||
847 | pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2); | ||
848 | misc2 = CCM_ANALOG_MISC2_VIDEO_DIV(3); | ||
849 | break; | ||
850 | |||
851 | case 2: | ||
852 | pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1); | ||
853 | break; | ||
854 | |||
855 | default: | ||
856 | pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2); | ||
857 | break; | ||
858 | } | ||
859 | |||
860 | CCM_ANALOG->MISC2 = (CCM_ANALOG->MISC2 & ~CCM_ANALOG_MISC2_VIDEO_DIV_MASK) | misc2; | ||
861 | |||
862 | CCM_ANALOG->PLL_VIDEO = pllVideo; | ||
863 | |||
864 | while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0UL) | ||
865 | { | ||
866 | } | ||
867 | |||
868 | /* Disable Bypass */ | ||
869 | CCM_ANALOG->PLL_VIDEO &= ~CCM_ANALOG_PLL_VIDEO_BYPASS_MASK; | ||
870 | } | ||
871 | |||
872 | /*! | ||
873 | * brief De-initialize the Video PLL. | ||
874 | */ | ||
875 | void CLOCK_DeinitVideoPll(void) | ||
876 | { | ||
877 | CCM_ANALOG->PLL_VIDEO = CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK; | ||
878 | } | ||
879 | |||
880 | /*! | ||
881 | * brief Initialize the ENET PLL. | ||
882 | * | ||
883 | * This function initializes the ENET PLL with specific settings. | ||
884 | * | ||
885 | * param config Configuration to set to PLL. | ||
886 | */ | ||
887 | void CLOCK_InitEnetPll(const clock_enet_pll_config_t *config) | ||
888 | { | ||
889 | uint32_t enet_pll = CCM_ANALOG_PLL_ENET_DIV_SELECT(config->loopDivider); | ||
890 | |||
891 | CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC_MASK)) | | ||
892 | CCM_ANALOG_PLL_ENET_BYPASS_MASK | CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC(config->src); | ||
893 | |||
894 | if (config->enableClkOutput) | ||
895 | { | ||
896 | enet_pll |= CCM_ANALOG_PLL_ENET_ENABLE_MASK; | ||
897 | } | ||
898 | |||
899 | if (config->enableClkOutput25M) | ||
900 | { | ||
901 | enet_pll |= CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_MASK; | ||
902 | } | ||
903 | |||
904 | CCM_ANALOG->PLL_ENET = | ||
905 | (CCM_ANALOG->PLL_ENET & (~(CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK | CCM_ANALOG_PLL_ENET_POWERDOWN_MASK))) | | ||
906 | enet_pll; | ||
907 | |||
908 | /* Wait for stable */ | ||
909 | while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0UL) | ||
910 | { | ||
911 | } | ||
912 | |||
913 | /* Disable Bypass */ | ||
914 | CCM_ANALOG->PLL_ENET &= ~CCM_ANALOG_PLL_ENET_BYPASS_MASK; | ||
915 | } | ||
916 | |||
917 | /*! | ||
918 | * brief Deinitialize the ENET PLL. | ||
919 | * | ||
920 | * This function disables the ENET PLL. | ||
921 | */ | ||
922 | void CLOCK_DeinitEnetPll(void) | ||
923 | { | ||
924 | CCM_ANALOG->PLL_ENET = CCM_ANALOG_PLL_ENET_POWERDOWN_MASK; | ||
925 | } | ||
926 | |||
927 | /*! | ||
928 | * brief Get current PLL output frequency. | ||
929 | * | ||
930 | * This function get current output frequency of specific PLL | ||
931 | * | ||
932 | * param pll pll name to get frequency. | ||
933 | * return The PLL output frequency in hertz. | ||
934 | */ | ||
935 | uint32_t CLOCK_GetPllFreq(clock_pll_t pll) | ||
936 | { | ||
937 | uint32_t freq; | ||
938 | uint32_t divSelect; | ||
939 | clock_64b_t freqTmp; | ||
940 | |||
941 | const uint32_t enetRefClkFreq[] = { | ||
942 | 25000000U, /* 25M */ | ||
943 | 50000000U, /* 50M */ | ||
944 | 100000000U, /* 100M */ | ||
945 | 125000000U /* 125M */ | ||
946 | }; | ||
947 | |||
948 | /* check if PLL is enabled */ | ||
949 | if (!CLOCK_IsPllEnabled(CCM_ANALOG, pll)) | ||
950 | { | ||
951 | return 0U; | ||
952 | } | ||
953 | |||
954 | /* get pll reference clock */ | ||
955 | freq = CLOCK_GetPllBypassRefClk(CCM_ANALOG, pll); | ||
956 | |||
957 | /* check if pll is bypassed */ | ||
958 | if (CLOCK_IsPllBypassed(CCM_ANALOG, pll)) | ||
959 | { | ||
960 | return freq; | ||
961 | } | ||
962 | |||
963 | switch (pll) | ||
964 | { | ||
965 | case kCLOCK_PllArm: | ||
966 | freq = ((freq * ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK) >> | ||
967 | CCM_ANALOG_PLL_ARM_DIV_SELECT_SHIFT)) >> | ||
968 | 1U); | ||
969 | break; | ||
970 | case kCLOCK_PllSys: | ||
971 | /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */ | ||
972 | freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_SYS_NUM))); | ||
973 | freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_SYS_DENOM)); | ||
974 | |||
975 | if ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK) != 0U) | ||
976 | { | ||
977 | freq *= 22U; | ||
978 | } | ||
979 | else | ||
980 | { | ||
981 | freq *= 20U; | ||
982 | } | ||
983 | |||
984 | freq += (uint32_t)freqTmp; | ||
985 | break; | ||
986 | |||
987 | case kCLOCK_PllUsb1: | ||
988 | freq = (freq * (((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK) != 0UL) ? 22U : 20U)); | ||
989 | break; | ||
990 | |||
991 | case kCLOCK_PllAudio: | ||
992 | /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */ | ||
993 | divSelect = | ||
994 | (CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_AUDIO_DIV_SELECT_SHIFT; | ||
995 | |||
996 | freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_AUDIO_NUM))); | ||
997 | freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_AUDIO_DENOM)); | ||
998 | |||
999 | freq = freq * divSelect + (uint32_t)freqTmp; | ||
1000 | |||
1001 | /* AUDIO PLL output = PLL output frequency / POSTDIV. */ | ||
1002 | |||
1003 | /* | ||
1004 | * Post divider: | ||
1005 | * | ||
1006 | * PLL_AUDIO[POST_DIV_SELECT]: | ||
1007 | * 0x00: 4 | ||
1008 | * 0x01: 2 | ||
1009 | * 0x02: 1 | ||
1010 | * | ||
1011 | * MISC2[AUDO_DIV]: | ||
1012 | * 0x00: 1 | ||
1013 | * 0x01: 2 | ||
1014 | * 0x02: 1 | ||
1015 | * 0x03: 4 | ||
1016 | */ | ||
1017 | switch (CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT_MASK) | ||
1018 | { | ||
1019 | case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(0U): | ||
1020 | freq = freq >> 2U; | ||
1021 | break; | ||
1022 | |||
1023 | case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1U): | ||
1024 | freq = freq >> 1U; | ||
1025 | break; | ||
1026 | |||
1027 | case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2U): | ||
1028 | freq = freq >> 0U; | ||
1029 | break; | ||
1030 | |||
1031 | default: | ||
1032 | assert(false); | ||
1033 | break; | ||
1034 | } | ||
1035 | |||
1036 | switch (CCM_ANALOG->MISC2 & (CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK)) | ||
1037 | { | ||
1038 | case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(1) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(1): | ||
1039 | freq >>= 2U; | ||
1040 | break; | ||
1041 | |||
1042 | case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(0) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(1): | ||
1043 | freq >>= 1U; | ||
1044 | break; | ||
1045 | |||
1046 | case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(0) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(0): | ||
1047 | case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(1) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(0): | ||
1048 | freq >>= 0U; | ||
1049 | break; | ||
1050 | |||
1051 | default: | ||
1052 | assert(false); | ||
1053 | break; | ||
1054 | } | ||
1055 | break; | ||
1056 | |||
1057 | case kCLOCK_PllVideo: | ||
1058 | /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */ | ||
1059 | divSelect = | ||
1060 | (CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_VIDEO_DIV_SELECT_SHIFT; | ||
1061 | |||
1062 | freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_VIDEO_NUM))); | ||
1063 | freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_VIDEO_DENOM)); | ||
1064 | freq = freq * divSelect + (uint32_t)freqTmp; | ||
1065 | |||
1066 | /* VIDEO PLL output = PLL output frequency / POSTDIV. */ | ||
1067 | |||
1068 | /* | ||
1069 | * Post divider: | ||
1070 | * | ||
1071 | * PLL_VIDEO[POST_DIV_SELECT]: | ||
1072 | * 0x00: 4 | ||
1073 | * 0x01: 2 | ||
1074 | * 0x02: 1 | ||
1075 | * | ||
1076 | * MISC2[VIDEO_DIV]: | ||
1077 | * 0x00: 1 | ||
1078 | * 0x01: 2 | ||
1079 | * 0x02: 1 | ||
1080 | * 0x03: 4 | ||
1081 | */ | ||
1082 | switch (CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT_MASK) | ||
1083 | { | ||
1084 | case CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(0U): | ||
1085 | freq = freq >> 2U; | ||
1086 | break; | ||
1087 | |||
1088 | case CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1U): | ||
1089 | freq = freq >> 1U; | ||
1090 | break; | ||
1091 | |||
1092 | case CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2U): | ||
1093 | freq = freq >> 0U; | ||
1094 | break; | ||
1095 | |||
1096 | default: | ||
1097 | assert(false); | ||
1098 | break; | ||
1099 | } | ||
1100 | |||
1101 | switch (CCM_ANALOG->MISC2 & CCM_ANALOG_MISC2_VIDEO_DIV_MASK) | ||
1102 | { | ||
1103 | case CCM_ANALOG_MISC2_VIDEO_DIV(3U): | ||
1104 | freq >>= 2U; | ||
1105 | break; | ||
1106 | |||
1107 | case CCM_ANALOG_MISC2_VIDEO_DIV(1U): | ||
1108 | freq >>= 1U; | ||
1109 | break; | ||
1110 | |||
1111 | case CCM_ANALOG_MISC2_VIDEO_DIV(0U): | ||
1112 | case CCM_ANALOG_MISC2_VIDEO_DIV(2U): | ||
1113 | freq >>= 0U; | ||
1114 | break; | ||
1115 | |||
1116 | default: | ||
1117 | assert(false); | ||
1118 | break; | ||
1119 | } | ||
1120 | break; | ||
1121 | case kCLOCK_PllEnet: | ||
1122 | divSelect = | ||
1123 | (CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_ENET_DIV_SELECT_SHIFT; | ||
1124 | freq = enetRefClkFreq[divSelect]; | ||
1125 | break; | ||
1126 | |||
1127 | case kCLOCK_PllEnet25M: | ||
1128 | /* ref_enetpll1 if fixed at 25MHz. */ | ||
1129 | freq = 25000000UL; | ||
1130 | break; | ||
1131 | |||
1132 | case kCLOCK_PllUsb2: | ||
1133 | freq = (freq * (((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK) != 0U) ? 22U : 20U)); | ||
1134 | break; | ||
1135 | default: | ||
1136 | freq = 0U; | ||
1137 | break; | ||
1138 | } | ||
1139 | |||
1140 | return freq; | ||
1141 | } | ||
1142 | |||
1143 | /*! | ||
1144 | * brief Initialize the System PLL PFD. | ||
1145 | * | ||
1146 | * This function initializes the System PLL PFD. During new value setting, | ||
1147 | * the clock output is disabled to prevent glitch. | ||
1148 | * | ||
1149 | * param pfd Which PFD clock to enable. | ||
1150 | * param pfdFrac The PFD FRAC value. | ||
1151 | * note It is recommended that PFD settings are kept between 12-35. | ||
1152 | */ | ||
1153 | void CLOCK_InitSysPfd(clock_pfd_t pfd, uint8_t pfdFrac) | ||
1154 | { | ||
1155 | uint32_t pfdIndex = (uint32_t)pfd; | ||
1156 | uint32_t pfd528; | ||
1157 | |||
1158 | pfd528 = CCM_ANALOG->PFD_528 & | ||
1159 | ~(((uint32_t)((uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_528_PFD0_FRAC_MASK) | ||
1160 | << (8UL * pfdIndex))); | ||
1161 | |||
1162 | /* Disable the clock output first. */ | ||
1163 | CCM_ANALOG->PFD_528 = pfd528 | ((uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8UL * pfdIndex)); | ||
1164 | |||
1165 | /* Set the new value and enable output. */ | ||
1166 | CCM_ANALOG->PFD_528 = pfd528 | (CCM_ANALOG_PFD_528_PFD0_FRAC(pfdFrac) << (8UL * pfdIndex)); | ||
1167 | } | ||
1168 | |||
1169 | /*! | ||
1170 | * brief De-initialize the System PLL PFD. | ||
1171 | * | ||
1172 | * This function disables the System PLL PFD. | ||
1173 | * | ||
1174 | * param pfd Which PFD clock to disable. | ||
1175 | */ | ||
1176 | void CLOCK_DeinitSysPfd(clock_pfd_t pfd) | ||
1177 | { | ||
1178 | CCM_ANALOG->PFD_528 |= (uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8U * (uint8_t)pfd); | ||
1179 | } | ||
1180 | |||
1181 | /*! | ||
1182 | * brief Initialize the USB1 PLL PFD. | ||
1183 | * | ||
1184 | * This function initializes the USB1 PLL PFD. During new value setting, | ||
1185 | * the clock output is disabled to prevent glitch. | ||
1186 | * | ||
1187 | * param pfd Which PFD clock to enable. | ||
1188 | * param pfdFrac The PFD FRAC value. | ||
1189 | * note It is recommended that PFD settings are kept between 12-35. | ||
1190 | */ | ||
1191 | void CLOCK_InitUsb1Pfd(clock_pfd_t pfd, uint8_t pfdFrac) | ||
1192 | { | ||
1193 | uint32_t pfdIndex = (uint32_t)pfd; | ||
1194 | uint32_t pfd480; | ||
1195 | |||
1196 | pfd480 = CCM_ANALOG->PFD_480 & | ||
1197 | ~(((uint32_t)((uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) | ||
1198 | << (8UL * pfdIndex))); | ||
1199 | |||
1200 | /* Disable the clock output first. */ | ||
1201 | CCM_ANALOG->PFD_480 = pfd480 | ((uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8UL * pfdIndex)); | ||
1202 | |||
1203 | /* Set the new value and enable output. */ | ||
1204 | CCM_ANALOG->PFD_480 = pfd480 | (CCM_ANALOG_PFD_480_PFD0_FRAC(pfdFrac) << (8UL * pfdIndex)); | ||
1205 | } | ||
1206 | |||
1207 | /*! | ||
1208 | * brief De-initialize the USB1 PLL PFD. | ||
1209 | * | ||
1210 | * This function disables the USB1 PLL PFD. | ||
1211 | * | ||
1212 | * param pfd Which PFD clock to disable. | ||
1213 | */ | ||
1214 | void CLOCK_DeinitUsb1Pfd(clock_pfd_t pfd) | ||
1215 | { | ||
1216 | CCM_ANALOG->PFD_480 |= (uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8UL * (uint8_t)pfd); | ||
1217 | } | ||
1218 | |||
1219 | /*! | ||
1220 | * brief Get current System PLL PFD output frequency. | ||
1221 | * | ||
1222 | * This function get current output frequency of specific System PLL PFD | ||
1223 | * | ||
1224 | * param pfd pfd name to get frequency. | ||
1225 | * return The PFD output frequency in hertz. | ||
1226 | */ | ||
1227 | uint32_t CLOCK_GetSysPfdFreq(clock_pfd_t pfd) | ||
1228 | { | ||
1229 | uint32_t freq = CLOCK_GetPllFreq(kCLOCK_PllSys); | ||
1230 | |||
1231 | switch (pfd) | ||
1232 | { | ||
1233 | case kCLOCK_Pfd0: | ||
1234 | freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD0_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD0_FRAC_SHIFT); | ||
1235 | break; | ||
1236 | |||
1237 | case kCLOCK_Pfd1: | ||
1238 | freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD1_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD1_FRAC_SHIFT); | ||
1239 | break; | ||
1240 | |||
1241 | case kCLOCK_Pfd2: | ||
1242 | freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD2_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD2_FRAC_SHIFT); | ||
1243 | break; | ||
1244 | |||
1245 | case kCLOCK_Pfd3: | ||
1246 | freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD3_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD3_FRAC_SHIFT); | ||
1247 | break; | ||
1248 | |||
1249 | default: | ||
1250 | freq = 0U; | ||
1251 | break; | ||
1252 | } | ||
1253 | freq *= 18U; | ||
1254 | |||
1255 | return freq; | ||
1256 | } | ||
1257 | |||
1258 | /*! | ||
1259 | * brief Get current USB1 PLL PFD output frequency. | ||
1260 | * | ||
1261 | * This function get current output frequency of specific USB1 PLL PFD | ||
1262 | * | ||
1263 | * param pfd pfd name to get frequency. | ||
1264 | * return The PFD output frequency in hertz. | ||
1265 | */ | ||
1266 | uint32_t CLOCK_GetUsb1PfdFreq(clock_pfd_t pfd) | ||
1267 | { | ||
1268 | uint32_t freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1); | ||
1269 | |||
1270 | switch (pfd) | ||
1271 | { | ||
1272 | case kCLOCK_Pfd0: | ||
1273 | freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD0_FRAC_SHIFT); | ||
1274 | break; | ||
1275 | |||
1276 | case kCLOCK_Pfd1: | ||
1277 | freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD1_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD1_FRAC_SHIFT); | ||
1278 | break; | ||
1279 | |||
1280 | case kCLOCK_Pfd2: | ||
1281 | freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD2_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD2_FRAC_SHIFT); | ||
1282 | break; | ||
1283 | |||
1284 | case kCLOCK_Pfd3: | ||
1285 | freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD3_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD3_FRAC_SHIFT); | ||
1286 | break; | ||
1287 | |||
1288 | default: | ||
1289 | freq = 0U; | ||
1290 | break; | ||
1291 | } | ||
1292 | freq *= 18U; | ||
1293 | |||
1294 | return freq; | ||
1295 | } | ||
1296 | |||
1297 | /*! brief Enable USB HS PHY PLL clock. | ||
1298 | * | ||
1299 | * This function enables the internal 480MHz USB PHY PLL clock. | ||
1300 | * | ||
1301 | * param src USB HS PHY PLL clock source. | ||
1302 | * param freq The frequency specified by src. | ||
1303 | * retval true The clock is set successfully. | ||
1304 | * retval false The clock source is invalid to get proper USB HS clock. | ||
1305 | */ | ||
1306 | bool CLOCK_EnableUsbhs1PhyPllClock(clock_usb_phy_src_t src, uint32_t freq) | ||
1307 | { | ||
1308 | const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U}; | ||
1309 | CLOCK_InitUsb2Pll(&g_ccmConfigUsbPll); | ||
1310 | USBPHY2->CTRL &= ~USBPHY_CTRL_SFTRST_MASK; /* release PHY from reset */ | ||
1311 | USBPHY2->CTRL &= ~USBPHY_CTRL_CLKGATE_MASK; | ||
1312 | |||
1313 | USBPHY2->PWD = 0; | ||
1314 | USBPHY2->CTRL |= USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK | USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK | | ||
1315 | USBPHY_CTRL_ENUTMILEVEL2_MASK | USBPHY_CTRL_ENUTMILEVEL3_MASK; | ||
1316 | |||
1317 | return true; | ||
1318 | } | ||
1319 | |||
1320 | /*! brief Disable USB HS PHY PLL clock. | ||
1321 | * | ||
1322 | * This function disables USB HS PHY PLL clock. | ||
1323 | */ | ||
1324 | void CLOCK_DisableUsbhs1PhyPllClock(void) | ||
1325 | { | ||
1326 | CCM_ANALOG->PLL_USB2 &= ~CCM_ANALOG_PLL_USB2_EN_USB_CLKS_MASK; | ||
1327 | USBPHY2->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* Set to 1U to gate clocks */ | ||
1328 | } | ||
1329 | |||
1330 | /*! | ||
1331 | * brief Set the clock source and the divider of the clock output1. | ||
1332 | * | ||
1333 | * param selection The clock source to be output, please refer to clock_output1_selection_t. | ||
1334 | * param divider The divider of the output clock signal, please refer to clock_output_divider_t. | ||
1335 | */ | ||
1336 | void CLOCK_SetClockOutput1(clock_output1_selection_t selection, clock_output_divider_t divider) | ||
1337 | { | ||
1338 | uint32_t tmp32; | ||
1339 | |||
1340 | tmp32 = CCM->CCOSR; | ||
1341 | if (selection == kCLOCK_DisableClockOutput1) | ||
1342 | { | ||
1343 | tmp32 &= ~CCM_CCOSR_CLKO1_EN_MASK; | ||
1344 | } | ||
1345 | else | ||
1346 | { | ||
1347 | tmp32 |= CCM_CCOSR_CLKO1_EN_MASK; | ||
1348 | tmp32 &= ~(CCM_CCOSR_CLKO1_SEL_MASK | CCM_CCOSR_CLKO1_DIV_MASK); | ||
1349 | tmp32 |= CCM_CCOSR_CLKO1_SEL(selection) | CCM_CCOSR_CLKO1_DIV(divider); | ||
1350 | } | ||
1351 | CCM->CCOSR = tmp32; | ||
1352 | } | ||
1353 | |||
1354 | /*! | ||
1355 | * brief Set the clock source and the divider of the clock output2. | ||
1356 | * | ||
1357 | * param selection The clock source to be output, please refer to clock_output2_selection_t. | ||
1358 | * param divider The divider of the output clock signal, please refer to clock_output_divider_t. | ||
1359 | */ | ||
1360 | void CLOCK_SetClockOutput2(clock_output2_selection_t selection, clock_output_divider_t divider) | ||
1361 | { | ||
1362 | uint32_t tmp32; | ||
1363 | |||
1364 | tmp32 = CCM->CCOSR; | ||
1365 | if (selection == kCLOCK_DisableClockOutput2) | ||
1366 | { | ||
1367 | tmp32 &= CCM_CCOSR_CLKO2_EN_MASK; | ||
1368 | } | ||
1369 | else | ||
1370 | { | ||
1371 | tmp32 |= CCM_CCOSR_CLKO2_EN_MASK; | ||
1372 | tmp32 &= ~(CCM_CCOSR_CLKO2_SEL_MASK | CCM_CCOSR_CLKO2_DIV_MASK); | ||
1373 | tmp32 |= CCM_CCOSR_CLKO2_SEL(selection) | CCM_CCOSR_CLKO2_DIV(divider); | ||
1374 | } | ||
1375 | |||
1376 | CCM->CCOSR = tmp32; | ||
1377 | } | ||
1378 | |||
1379 | /*! | ||
1380 | * brief Get the frequency of clock output1 clock signal. | ||
1381 | * | ||
1382 | * return The frequency of clock output1 clock signal. | ||
1383 | */ | ||
1384 | uint32_t CLOCK_GetClockOutCLKO1Freq(void) | ||
1385 | { | ||
1386 | uint32_t freq = 0U; | ||
1387 | uint32_t tmp32; | ||
1388 | |||
1389 | tmp32 = CCM->CCOSR; | ||
1390 | |||
1391 | if ((tmp32 & CCM_CCOSR_CLKO1_EN_MASK) != 0UL) | ||
1392 | { | ||
1393 | switch ((tmp32 & CCM_CCOSR_CLKO1_SEL_MASK) >> CCM_CCOSR_CLKO1_SEL_SHIFT) | ||
1394 | { | ||
1395 | case (uint32_t)kCLOCK_OutputPllUsb1: | ||
1396 | freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 2U; | ||
1397 | break; | ||
1398 | case (uint32_t)kCLOCK_OutputPllSys: | ||
1399 | freq = CLOCK_GetPllFreq(kCLOCK_PllSys) / 2U; | ||
1400 | break; | ||
1401 | case (uint32_t)kCLOCK_OutputPllVideo: | ||
1402 | freq = CLOCK_GetPllFreq(kCLOCK_PllVideo) / 2U; | ||
1403 | break; | ||
1404 | case (uint32_t)kCLOCK_OutputSemcClk: | ||
1405 | freq = CLOCK_GetSemcFreq(); | ||
1406 | break; | ||
1407 | case (uint32_t)kCLOCK_OutputLcdifPixClk: | ||
1408 | freq = CLOCK_GetClockRootFreq(kCLOCK_LcdifClkRoot); | ||
1409 | break; | ||
1410 | case (uint32_t)kCLOCK_OutputAhbClk: | ||
1411 | freq = CLOCK_GetAhbFreq(); | ||
1412 | break; | ||
1413 | case (uint32_t)kCLOCK_OutputIpgClk: | ||
1414 | freq = CLOCK_GetIpgFreq(); | ||
1415 | break; | ||
1416 | case (uint32_t)kCLOCK_OutputPerClk: | ||
1417 | freq = CLOCK_GetPerClkFreq(); | ||
1418 | break; | ||
1419 | case (uint32_t)kCLOCK_OutputCkilSyncClk: | ||
1420 | freq = CLOCK_GetRtcFreq(); | ||
1421 | break; | ||
1422 | case (uint32_t)kCLOCK_OutputPll4MainClk: | ||
1423 | freq = CLOCK_GetPllFreq(kCLOCK_PllAudio); | ||
1424 | break; | ||
1425 | default: | ||
1426 | /* This branch should never be hit. */ | ||
1427 | break; | ||
1428 | } | ||
1429 | |||
1430 | freq /= (((tmp32 & CCM_CCOSR_CLKO1_DIV_MASK) >> CCM_CCOSR_CLKO1_DIV_SHIFT) + 1U); | ||
1431 | } | ||
1432 | else | ||
1433 | { | ||
1434 | freq = 0UL; | ||
1435 | } | ||
1436 | |||
1437 | return freq; | ||
1438 | } | ||
1439 | |||
1440 | /*! | ||
1441 | * brief Get the frequency of clock output2 clock signal. | ||
1442 | * | ||
1443 | * return The frequency of clock output2 clock signal. | ||
1444 | */ | ||
1445 | uint32_t CLOCK_GetClockOutClkO2Freq(void) | ||
1446 | { | ||
1447 | uint32_t freq = 0U; | ||
1448 | uint32_t tmp32; | ||
1449 | |||
1450 | tmp32 = CCM->CCOSR; | ||
1451 | |||
1452 | if ((tmp32 & CCM_CCOSR_CLKO2_EN_MASK) != 0UL) | ||
1453 | { | ||
1454 | switch ((tmp32 & CCM_CCOSR_CLKO2_SEL_MASK) >> CCM_CCOSR_CLKO2_SEL_SHIFT) | ||
1455 | { | ||
1456 | case (uint32_t)kCLOCK_OutputUsdhc1Clk: | ||
1457 | freq = CLOCK_GetClockRootFreq(kCLOCK_Usdhc1ClkRoot); | ||
1458 | break; | ||
1459 | case (uint32_t)kCLOCK_OutputLpi2cClk: | ||
1460 | freq = CLOCK_GetClockRootFreq(kCLOCK_Lpi2cClkRoot); | ||
1461 | break; | ||
1462 | case (uint32_t)kCLOCK_OutputCsiClk: | ||
1463 | freq = CLOCK_GetClockRootFreq(kCLOCK_CsiClkRoot); | ||
1464 | break; | ||
1465 | case (uint32_t)kCLOCK_OutputOscClk: | ||
1466 | freq = CLOCK_GetOscFreq(); | ||
1467 | break; | ||
1468 | case (uint32_t)kCLOCK_OutputUsdhc2Clk: | ||
1469 | freq = CLOCK_GetClockRootFreq(kCLOCK_Usdhc2ClkRoot); | ||
1470 | break; | ||
1471 | case (uint32_t)kCLOCK_OutputSai1Clk: | ||
1472 | freq = CLOCK_GetClockRootFreq(kCLOCK_Sai1ClkRoot); | ||
1473 | break; | ||
1474 | case (uint32_t)kCLOCK_OutputSai2Clk: | ||
1475 | freq = CLOCK_GetClockRootFreq(kCLOCK_Sai2ClkRoot); | ||
1476 | break; | ||
1477 | case (uint32_t)kCLOCK_OutputSai3Clk: | ||
1478 | freq = CLOCK_GetClockRootFreq(kCLOCK_Sai3ClkRoot); | ||
1479 | break; | ||
1480 | case (uint32_t)kCLOCK_OutputCanClk: | ||
1481 | freq = CLOCK_GetClockRootFreq(kCLOCK_CanClkRoot); | ||
1482 | break; | ||
1483 | case (uint32_t)kCLOCK_OutputFlexspiClk: | ||
1484 | freq = CLOCK_GetClockRootFreq(kCLOCK_FlexspiClkRoot); | ||
1485 | break; | ||
1486 | case (uint32_t)kCLOCK_OutputUartClk: | ||
1487 | freq = CLOCK_GetClockRootFreq(kCLOCK_UartClkRoot); | ||
1488 | break; | ||
1489 | case (uint32_t)kCLOCK_OutputSpdif0Clk: | ||
1490 | freq = CLOCK_GetClockRootFreq(kCLOCK_SpdifClkRoot); | ||
1491 | break; | ||
1492 | default: | ||
1493 | /* This branch should never be hit. */ | ||
1494 | break; | ||
1495 | } | ||
1496 | |||
1497 | freq /= (((tmp32 & CCM_CCOSR_CLKO2_DIV_MASK) >> CCM_CCOSR_CLKO2_DIV_SHIFT) + 1U); | ||
1498 | } | ||
1499 | else | ||
1500 | { | ||
1501 | freq = 0UL; | ||
1502 | } | ||
1503 | |||
1504 | return freq; | ||
1505 | } | ||