1 /**************************************************************************//**
\r
4 * @brief M2351 series Clock Controller (CLK) driver source file
\r
7 * Copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
\r
8 *****************************************************************************/
\r
10 /** @addtogroup Standard_Driver Standard Driver
\r
14 /** @addtogroup CLK_Driver CLK Driver
\r
19 /** @addtogroup CLK_EXPORTED_FUNCTIONS CLK Exported Functions
\r
25 * @brief Disable frequency output function
\r
28 * @details This function disable frequency output function.
\r
30 void CLK_DisableCKO(void)
\r
32 /* Disable CKO clock source */
\r
33 CLK->APBCLK0 &= (~CLK_APBCLK0_CLKOCKEN_Msk);
\r
38 * @brief This function enable frequency divider module clock.
\r
39 * enable frequency divider clock function and configure frequency divider.
\r
40 * @param[in] u32ClkSrc is frequency divider function clock source. Including :
\r
41 * - \ref CLK_CLKSEL1_CLKOSEL_HXT
\r
42 * - \ref CLK_CLKSEL1_CLKOSEL_LXT
\r
43 * - \ref CLK_CLKSEL1_CLKOSEL_HCLK
\r
44 * - \ref CLK_CLKSEL1_CLKOSEL_HIRC
\r
45 * @param[in] u32ClkDiv is divider output frequency selection.
\r
46 * @param[in] u32ClkDivBy1En is frequency divided by one enable.
\r
49 * @details Output selected clock to CKO. The output clock frequency is divided by u32ClkDiv.
\r
51 * CKO frequency = (Clock source frequency) / 2^(u32ClkDiv + 1)
\r
52 * This function is just used to set CKO clock.
\r
53 * User must enable I/O for CKO clock output pin by themselves.
\r
55 void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv, uint32_t u32ClkDivBy1En)
\r
57 /* CKO = clock source / 2^(u32ClkDiv + 1) */
\r
58 CLK->CLKOCTL = CLK_CLKOCTL_CLKOEN_Msk | u32ClkDiv | (u32ClkDivBy1En << CLK_CLKOCTL_DIV1EN_Pos);
\r
60 /* Enable CKO clock source */
\r
61 CLK->APBCLK0 |= CLK_APBCLK0_CLKOCKEN_Msk;
\r
63 /* Select CKO clock source */
\r
64 CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_CLKOSEL_Msk)) | (u32ClkSrc);
\r
69 * @brief Enter to Power-down mode
\r
72 * @details This function is used to let system enter to Power-down mode. \n
\r
73 * The register write-protection function should be disabled before using this function.
\r
75 void CLK_PowerDown(void)
\r
77 /* Set the processor uses deep sleep as its low power mode */
\r
78 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
\r
80 /* Set system Power-down enabled*/
\r
81 CLK->PWRCTL |= CLK_PWRCTL_PDEN_Msk;
\r
83 /* Chip enter Power-down mode after CPU run WFI instruction */
\r
90 * @brief Enter to Idle mode
\r
93 * @details This function let system enter to Idle mode. \n
\r
94 * The register write-protection function should be disabled before using this function.
\r
98 /* Set the processor uses sleep as its low power mode */
\r
99 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
\r
101 /* Set chip in idle mode because of WFI command */
\r
102 CLK->PWRCTL &= ~CLK_PWRCTL_PDEN_Msk;
\r
104 /* Chip enter idle mode after CPU run WFI instruction */
\r
110 * @brief Get external high speed crystal clock frequency
\r
112 * @return External high frequency crystal frequency
\r
113 * @details This function get external high frequency crystal frequency. The frequency unit is Hz.
\r
115 __NONSECURE_ENTRY_WEAK
\r
116 uint32_t CLK_GetHXTFreq(void)
\r
118 uint32_t u32Freq = 0UL;
\r
119 uint32_t u32HXTEN = CLK->PWRCTL & CLK_PWRCTL_HXTEN_Msk;
\r
134 * @brief Get external low speed crystal clock frequency
\r
136 * @return External low speed crystal clock frequency
\r
137 * @details This function get external low frequency crystal frequency. The frequency unit is Hz.
\r
140 __NONSECURE_ENTRY_WEAK
\r
141 uint32_t CLK_GetLXTFreq(void)
\r
143 uint32_t u32Freq = 0UL;
\r
144 uint32_t u32LXTEN = CLK->PWRCTL & CLK_PWRCTL_LXTEN_Msk;
\r
159 * @brief Get HCLK frequency
\r
161 * @return HCLK frequency
\r
162 * @details This function get HCLK frequency. The frequency unit is Hz.
\r
165 __NONSECURE_ENTRY_WEAK
\r
166 uint32_t CLK_GetHCLKFreq(void)
\r
168 SystemCoreClockUpdate();
\r
169 return SystemCoreClock;
\r
173 * @brief Get PCLK0 frequency
\r
175 * @return PCLK0 frequency
\r
176 * @details This function get PCLK0 frequency. The frequency unit is Hz.
\r
179 __NONSECURE_ENTRY_WEAK
\r
180 uint32_t CLK_GetPCLK0Freq(void)
\r
182 SystemCoreClockUpdate();
\r
183 return (SystemCoreClock >> ((CLK->PCLKDIV & CLK_PCLKDIV_APB0DIV_Msk) >> CLK_PCLKDIV_APB0DIV_Pos));
\r
187 * @brief Get PCLK1 frequency
\r
189 * @return PCLK1 frequency
\r
190 * @details This function get PCLK1 frequency. The frequency unit is Hz.
\r
193 __NONSECURE_ENTRY_WEAK
\r
194 uint32_t CLK_GetPCLK1Freq(void)
\r
196 SystemCoreClockUpdate();
\r
197 return (SystemCoreClock >> ((CLK->PCLKDIV & CLK_PCLKDIV_APB1DIV_Msk) >> CLK_PCLKDIV_APB1DIV_Pos));
\r
201 * @brief Get CPU frequency
\r
203 * @return CPU frequency
\r
204 * @details This function get CPU frequency. The frequency unit is Hz.
\r
207 __NONSECURE_ENTRY_WEAK
\r
208 uint32_t CLK_GetCPUFreq(void)
\r
210 uint32_t u32Freq, u32HclkSrc, u32HclkDiv;
\r
211 uint32_t au32ClkTbl[] = {__HXT, __LXT, 0UL, __LIRC, 0UL, __HIRC48, 0UL, __HIRC};
\r
212 uint32_t u32PllReg, u32FIN, u32NF, u32NR, u32NO;
\r
213 uint8_t au8NoTbl[4] = {1U, 2U, 2U, 4U};
\r
214 uint32_t u32RTCCKEN = CLK->APBCLK0 & CLK_APBCLK0_RTCCKEN_Msk;
\r
216 /* Update PLL Clock */
\r
217 u32PllReg = CLK->PLLCTL;
\r
219 if(u32PllReg & (CLK_PLLCTL_PD_Msk | CLK_PLLCTL_OE_Msk))
\r
221 PllClock = 0UL; /* PLL is in power down mode or fix low */
\r
223 else /* PLL is in normal mode */
\r
226 /* PLL source clock */
\r
227 if(u32PllReg & CLK_PLLCTL_PLLSRC_Msk)
\r
229 u32FIN = __HIRC; /* PLL source clock from HIRC */
\r
233 u32FIN = __HXT; /* PLL source clock from HXT */
\r
236 /* Calculate PLL frequency */
\r
237 if(u32PllReg & CLK_PLLCTL_BP_Msk)
\r
239 PllClock = u32FIN; /* PLL is in bypass mode */
\r
243 /* PLL is output enabled in normal work mode */
\r
244 u32NO = au8NoTbl[((u32PllReg & CLK_PLLCTL_OUTDIV_Msk) >> CLK_PLLCTL_OUTDIV_Pos)];
\r
245 u32NF = ((u32PllReg & CLK_PLLCTL_FBDIV_Msk) >> CLK_PLLCTL_FBDIV_Pos) + 2UL;
\r
246 u32NR = ((u32PllReg & CLK_PLLCTL_INDIV_Msk) >> CLK_PLLCTL_INDIV_Pos) + 1UL;
\r
248 /* u32FIN is shifted 2 bits to avoid overflow */
\r
249 PllClock = (((u32FIN >> 2) * (u32NF << 1)) / (u32NR * u32NO) << 2);
\r
253 /* HCLK clock source */
\r
254 u32HclkSrc = CLK->CLKSEL0 & CLK_CLKSEL0_HCLKSEL_Msk;
\r
256 if(u32HclkSrc == CLK_CLKSEL0_HCLKSEL_LXT)
\r
259 if(u32RTCCKEN == 0UL)
\r
261 CLK->APBCLK0 |= CLK_APBCLK0_RTCCKEN_Msk; /* Enable RTC clock to get LXT clock source */
\r
264 if(RTC->LXTCTL & RTC_LXTCTL_C32KS_Msk)
\r
266 u32Freq = __LIRC32; /* LXT clock source is LIRC32 */
\r
270 u32Freq = __LXT; /* LXT clock source is external LXT */
\r
273 if(u32RTCCKEN == 0UL)
\r
275 CLK->APBCLK0 &= (~CLK_APBCLK0_RTCCKEN_Msk); /* Disable RTC clock if it is disabled before */
\r
279 else if(u32HclkSrc == CLK_CLKSEL0_HCLKSEL_PLL)
\r
281 u32Freq = PllClock;/* Use PLL clock */
\r
285 u32Freq = au32ClkTbl[u32HclkSrc]; /* Use the clock sources directly */
\r
288 /* HCLK clock source divider */
\r
289 u32HclkDiv = (CLK->CLKDIV0 & CLK_CLKDIV0_HCLKDIV_Msk) + 1UL;
\r
291 /* Update System Core Clock */
\r
292 SystemCoreClock = u32Freq / u32HclkDiv;
\r
294 /* Update Cycles per micro second */
\r
295 CyclesPerUs = (SystemCoreClock + 500000UL) / 1000000UL;
\r
297 return SystemCoreClock;
\r
301 * @brief Set HCLK frequency
\r
302 * @param[in] u32Hclk is HCLK frequency.
\r
303 * The range of u32Hclk is 24 MHz ~ 64 MHz if power level is PL0.
\r
304 * The range of u32Hclk is 24 MHz ~ 48 MHz if power level is PL1.
\r
305 * @return HCLK frequency
\r
306 * @details This function is used to set HCLK frequency. The frequency unit is Hz. \n
\r
307 * The register write-protection function should be disabled before using this function.
\r
309 uint32_t CLK_SetCoreClock(uint32_t u32Hclk)
\r
311 uint32_t u32HIRCSTB, u32PLSTATUS;
\r
313 /* Read HIRC clock source stable flag */
\r
314 u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;
\r
316 /* Read power level status */
\r
317 u32PLSTATUS = SYS->PLSTS & SYS_PLSTS_PLSTATUS_Msk;
\r
319 /* Check HCLK frequency range */
\r
320 if((u32PLSTATUS == SYS_PLSTS_PLSTATUS_PL0) && (u32Hclk > FREQ_64MHZ))
\r
322 u32Hclk = FREQ_64MHZ;
\r
324 else if((u32PLSTATUS == SYS_PLSTS_PLSTATUS_PL1) && (u32Hclk > FREQ_48MHZ))
\r
326 u32Hclk = FREQ_48MHZ;
\r
328 else if(u32Hclk < FREQ_24MHZ)
\r
330 u32Hclk = FREQ_24MHZ;
\r
333 /* Switch HCLK clock source to HIRC clock for safe */
\r
334 CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
\r
335 CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
\r
336 CLK->CLKSEL0 |= CLK_CLKSEL0_HCLKSEL_Msk;
\r
337 CLK->CLKDIV0 &= (~CLK_CLKDIV0_HCLKDIV_Msk);
\r
339 /* Enable Flash access cycle auto-tuning function */
\r
340 FMC->CYCCTL &= (~FMC_CYCCTL_FADIS_Msk);
\r
342 /* Configure PLL setting if HXT clock is stable */
\r
343 if(CLK->STATUS & CLK_STATUS_HXTSTB_Msk)
\r
345 u32Hclk = CLK_EnablePLL(CLK_PLLCTL_PLLSRC_HXT, u32Hclk);
\r
347 /* Configure PLL setting if HXT clock is not stable */
\r
350 u32Hclk = CLK_EnablePLL(CLK_PLLCTL_PLLSRC_HIRC, u32Hclk);
\r
352 /* Read HIRC clock source stable flag */
\r
353 u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;
\r
356 /* Select HCLK clock source to PLL,
\r
357 Select HCLK clock source divider as 1
\r
358 and update system core clock
\r
360 CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL, CLK_CLKDIV0_HCLK(1UL));
\r
362 /* Disable HIRC if HIRC is disabled before setting core clock */
\r
363 if(u32HIRCSTB == 0UL)
\r
365 CLK->PWRCTL &= ~CLK_PWRCTL_HIRCEN_Msk;
\r
368 /* Return actually HCLK frequency is PLL frequency divide 1 */
\r
374 * @brief Set HCLK clock source and HCLK clock divider
\r
375 * @param[in] u32ClkSrc is HCLK clock source. Including :
\r
376 * - \ref CLK_CLKSEL0_HCLKSEL_HXT
\r
377 * - \ref CLK_CLKSEL0_HCLKSEL_LXT
\r
378 * - \ref CLK_CLKSEL0_HCLKSEL_PLL
\r
379 * - \ref CLK_CLKSEL0_HCLKSEL_LIRC
\r
380 * - \ref CLK_CLKSEL0_HCLKSEL_HIRC48
\r
381 * - \ref CLK_CLKSEL0_HCLKSEL_HIRC
\r
382 * @param[in] u32ClkDiv is HCLK clock divider. Including :
\r
383 * - \ref CLK_CLKDIV0_HCLK(x)
\r
385 * @details This function set HCLK clock source and HCLK clock divider.
\r
386 * The register write-protection function should be disabled before using this function.
\r
388 void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
\r
390 uint32_t u32HIRCSTB;
\r
392 /* Read HIRC clock source stable flag */
\r
393 u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;
\r
395 /* Switch to HIRC for Safe. Avoid HCLK too high when applying new divider. */
\r
396 CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
\r
397 CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
\r
398 CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | CLK_CLKSEL0_HCLKSEL_HIRC;
\r
400 /* Enable Flash access cycle auto-tuning function */
\r
401 FMC->CYCCTL &= (~FMC_CYCCTL_FADIS_Msk);
\r
403 /* Apply new Divider */
\r
404 CLK->CLKDIV0 = (CLK->CLKDIV0 & (~CLK_CLKDIV0_HCLKDIV_Msk)) | u32ClkDiv;
\r
406 /* Disable Flash access cycle auto-tuning function and set Flash access cycle if HCLK switches to HIRC48 */
\r
407 if(u32ClkSrc == CLK_CLKSEL0_HCLKSEL_HIRC48)
\r
409 FMC->CYCCTL = (FMC->CYCCTL & (~FMC_CYCCTL_CYCLE_Msk)) | FMC_CYCCTL_FADIS_Msk | (3UL);
\r
412 /* Switch HCLK to new HCLK source */
\r
413 CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | u32ClkSrc;
\r
415 /* Update System Core Clock */
\r
416 SystemCoreClockUpdate();
\r
418 /* Disable HIRC if HIRC is disabled before switching HCLK source */
\r
419 if(u32HIRCSTB == 0UL)
\r
421 CLK->PWRCTL &= ~CLK_PWRCTL_HIRCEN_Msk;
\r
425 * @brief This function set selected module clock source and module clock divider
\r
426 * @param[in] u32ModuleIdx is module index.
\r
427 * @param[in] u32ClkSrc is module clock source.
\r
428 * @param[in] u32ClkDiv is module clock divider.
\r
430 * @details Valid parameter combinations listed in following table:
\r
432 * |Module index |Clock source |Divider |
\r
433 * | :---------------- | :----------------------------------- | :----------------------- |
\r
434 * |\ref SDH0_MODULE |\ref CLK_CLKSEL0_SDH0SEL_HXT |\ref CLK_CLKDIV0_SDH0(x) |
\r
435 * |\ref SDH0_MODULE |\ref CLK_CLKSEL0_SDH0SEL_PLL |\ref CLK_CLKDIV0_SDH0(x) |
\r
436 * |\ref SDH0_MODULE |\ref CLK_CLKSEL0_SDH0SEL_HCLK |\ref CLK_CLKDIV0_SDH0(x) |
\r
437 * |\ref SDH0_MODULE |\ref CLK_CLKSEL0_SDH0SEL_HIRC |\ref CLK_CLKDIV0_SDH0(x) |
\r
438 * |\ref WDT_MODULE |\ref CLK_CLKSEL1_WDTSEL_LXT | x |
\r
439 * |\ref WDT_MODULE |\ref CLK_CLKSEL1_WDTSEL_HCLK_DIV2048 | x |
\r
440 * |\ref WDT_MODULE |\ref CLK_CLKSEL1_WDTSEL_LIRC | x |
\r
441 * |\ref EADC_MODULE | x |\ref CLK_CLKDIV0_EADC(x) |
\r
442 * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_HXT | x |
\r
443 * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_LXT | x |
\r
444 * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_PCLK0 | x |
\r
445 * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_EXT_TRG | x |
\r
446 * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_LIRC | x |
\r
447 * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_HIRC | x |
\r
448 * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_HXT | x |
\r
449 * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_LXT | x |
\r
450 * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_PCLK0 | x |
\r
451 * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_EXT_TRG | x |
\r
452 * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_LIRC | x |
\r
453 * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_HIRC | x |
\r
454 * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_HXT | x |
\r
455 * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_LXT | x |
\r
456 * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_PCLK1 | x |
\r
457 * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_EXT_TRG | x |
\r
458 * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_LIRC | x |
\r
459 * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_HIRC | x |
\r
460 * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_HXT | x |
\r
461 * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_LXT | x |
\r
462 * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_PCLK1 | x |
\r
463 * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_EXT_TRG | x |
\r
464 * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_LIRC | x |
\r
465 * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_HIRC | x |
\r
466 * |\ref UART0_MODULE |\ref CLK_CLKSEL1_UART0SEL_HXT |\ref CLK_CLKDIV0_UART0(x) |
\r
467 * |\ref UART0_MODULE |\ref CLK_CLKSEL1_UART0SEL_PLL |\ref CLK_CLKDIV0_UART0(x) |
\r
468 * |\ref UART0_MODULE |\ref CLK_CLKSEL1_UART0SEL_LXT |\ref CLK_CLKDIV0_UART0(x) |
\r
469 * |\ref UART0_MODULE |\ref CLK_CLKSEL1_UART0SEL_HIRC |\ref CLK_CLKDIV0_UART0(x) |
\r
470 * |\ref UART1_MODULE |\ref CLK_CLKSEL1_UART1SEL_HXT |\ref CLK_CLKDIV0_UART1(x) |
\r
471 * |\ref UART1_MODULE |\ref CLK_CLKSEL1_UART1SEL_PLL |\ref CLK_CLKDIV0_UART1(x) |
\r
472 * |\ref UART1_MODULE |\ref CLK_CLKSEL1_UART1SEL_LXT |\ref CLK_CLKDIV0_UART1(x) |
\r
473 * |\ref UART1_MODULE |\ref CLK_CLKSEL1_UART1SEL_HIRC |\ref CLK_CLKDIV0_UART1(x) |
\r
474 * |\ref UART2_MODULE |\ref CLK_CLKSEL3_UART2SEL_HXT |\ref CLK_CLKDIV4_UART2(x) |
\r
475 * |\ref UART2_MODULE |\ref CLK_CLKSEL3_UART2SEL_PLL |\ref CLK_CLKDIV4_UART2(x) |
\r
476 * |\ref UART2_MODULE |\ref CLK_CLKSEL3_UART2SEL_LXT |\ref CLK_CLKDIV4_UART2(x) |
\r
477 * |\ref UART2_MODULE |\ref CLK_CLKSEL3_UART2SEL_HIRC |\ref CLK_CLKDIV4_UART2(x) |
\r
478 * |\ref UART3_MODULE |\ref CLK_CLKSEL3_UART3SEL_HXT |\ref CLK_CLKDIV4_UART3(x) |
\r
479 * |\ref UART3_MODULE |\ref CLK_CLKSEL3_UART3SEL_PLL |\ref CLK_CLKDIV4_UART3(x) |
\r
480 * |\ref UART3_MODULE |\ref CLK_CLKSEL3_UART3SEL_LXT |\ref CLK_CLKDIV4_UART3(x) |
\r
481 * |\ref UART3_MODULE |\ref CLK_CLKSEL3_UART3SEL_HIRC |\ref CLK_CLKDIV4_UART3(x) |
\r
482 * |\ref UART4_MODULE |\ref CLK_CLKSEL3_UART4SEL_HXT |\ref CLK_CLKDIV4_UART4(x) |
\r
483 * |\ref UART4_MODULE |\ref CLK_CLKSEL3_UART4SEL_PLL |\ref CLK_CLKDIV4_UART4(x) |
\r
484 * |\ref UART4_MODULE |\ref CLK_CLKSEL3_UART4SEL_LXT |\ref CLK_CLKDIV4_UART4(x) |
\r
485 * |\ref UART4_MODULE |\ref CLK_CLKSEL3_UART4SEL_HIRC |\ref CLK_CLKDIV4_UART4(x) |
\r
486 * |\ref UART5_MODULE |\ref CLK_CLKSEL3_UART5SEL_HXT |\ref CLK_CLKDIV4_UART5(x) |
\r
487 * |\ref UART5_MODULE |\ref CLK_CLKSEL3_UART5SEL_PLL |\ref CLK_CLKDIV4_UART5(x) |
\r
488 * |\ref UART5_MODULE |\ref CLK_CLKSEL3_UART5SEL_LXT |\ref CLK_CLKDIV4_UART5(x) |
\r
489 * |\ref UART5_MODULE |\ref CLK_CLKSEL3_UART5SEL_HIRC |\ref CLK_CLKDIV4_UART5(x) |
\r
490 * |\ref CLKO_MODULE |\ref CLK_CLKSEL1_CLKOSEL_HXT | x |
\r
491 * |\ref CLKO_MODULE |\ref CLK_CLKSEL1_CLKOSEL_LXT | x |
\r
492 * |\ref CLKO_MODULE |\ref CLK_CLKSEL1_CLKOSEL_HCLK | x |
\r
493 * |\ref CLKO_MODULE |\ref CLK_CLKSEL1_CLKOSEL_HIRC | x |
\r
494 * |\ref WWDT_MODULE |\ref CLK_CLKSEL1_WWDTSEL_HCLK_DIV2048 | x |
\r
495 * |\ref WWDT_MODULE |\ref CLK_CLKSEL1_WWDTSEL_LIRC | x |
\r
496 * |\ref RTC_MODULE |\ref CLK_CLKSEL3_RTCSEL_LXT | x |
\r
497 * |\ref RTC_MODULE |\ref CLK_CLKSEL3_RTCSEL_LIRC | x |
\r
498 * |\ref I2S0_MODULE |\ref CLK_CLKSEL3_I2S0SEL_HXT | x |
\r
499 * |\ref I2S0_MODULE |\ref CLK_CLKSEL3_I2S0SEL_PLL | x |
\r
500 * |\ref I2S0_MODULE |\ref CLK_CLKSEL3_I2S0SEL_PCLK0 | x |
\r
501 * |\ref I2S0_MODULE |\ref CLK_CLKSEL3_I2S0SEL_HIRC | x |
\r
502 * |\ref QSPI0_MODULE |\ref CLK_CLKSEL2_QSPI0SEL_HXT | x |
\r
503 * |\ref QSPI0_MODULE |\ref CLK_CLKSEL2_QSPI0SEL_PLL | x |
\r
504 * |\ref QSPI0_MODULE |\ref CLK_CLKSEL2_QSPI0SEL_PCLK0 | x |
\r
505 * |\ref QSPI0_MODULE |\ref CLK_CLKSEL2_QSPI0SEL_HIRC | x |
\r
506 * |\ref SPI0_MODULE |\ref CLK_CLKSEL2_SPI0SEL_HXT | x |
\r
507 * |\ref SPI0_MODULE |\ref CLK_CLKSEL2_SPI0SEL_PLL | x |
\r
508 * |\ref SPI0_MODULE |\ref CLK_CLKSEL2_SPI0SEL_PCLK1 | x |
\r
509 * |\ref SPI0_MODULE |\ref CLK_CLKSEL2_SPI0SEL_HIRC | x |
\r
510 * |\ref SPI1_MODULE |\ref CLK_CLKSEL2_SPI1SEL_HXT | x |
\r
511 * |\ref SPI1_MODULE |\ref CLK_CLKSEL2_SPI1SEL_PLL | x |
\r
512 * |\ref SPI1_MODULE |\ref CLK_CLKSEL2_SPI1SEL_PCLK0 | x |
\r
513 * |\ref SPI1_MODULE |\ref CLK_CLKSEL2_SPI1SEL_HIRC | x |
\r
514 * |\ref SPI2_MODULE |\ref CLK_CLKSEL2_SPI2SEL_HXT | x |
\r
515 * |\ref SPI2_MODULE |\ref CLK_CLKSEL2_SPI2SEL_PLL | x |
\r
516 * |\ref SPI2_MODULE |\ref CLK_CLKSEL2_SPI2SEL_PCLK1 | x |
\r
517 * |\ref SPI2_MODULE |\ref CLK_CLKSEL2_SPI2SEL_HIRC | x |
\r
518 * |\ref SPI3_MODULE |\ref CLK_CLKSEL2_SPI3SEL_HXT | x |
\r
519 * |\ref SPI3_MODULE |\ref CLK_CLKSEL2_SPI3SEL_PLL | x |
\r
520 * |\ref SPI3_MODULE |\ref CLK_CLKSEL2_SPI3SEL_PCLK0 | x |
\r
521 * |\ref SPI3_MODULE |\ref CLK_CLKSEL2_SPI3SEL_HIRC | x |
\r
522 * |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0SEL_HXT |\ref CLK_CLKDIV1_SC0(x) |
\r
523 * |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0SEL_PLL |\ref CLK_CLKDIV1_SC0(x) |
\r
524 * |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0SEL_PCLK0 |\ref CLK_CLKDIV1_SC0(x) |
\r
525 * |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0SEL_HIRC |\ref CLK_CLKDIV1_SC0(x) |
\r
526 * |\ref SC1_MODULE |\ref CLK_CLKSEL3_SC1SEL_HXT |\ref CLK_CLKDIV1_SC1(x) |
\r
527 * |\ref SC1_MODULE |\ref CLK_CLKSEL3_SC1SEL_PLL |\ref CLK_CLKDIV1_SC1(x) |
\r
528 * |\ref SC1_MODULE |\ref CLK_CLKSEL3_SC1SEL_PCLK1 |\ref CLK_CLKDIV1_SC1(x) |
\r
529 * |\ref SC1_MODULE |\ref CLK_CLKSEL3_SC1SEL_HIRC |\ref CLK_CLKDIV1_SC1(x) |
\r
530 * |\ref SC2_MODULE |\ref CLK_CLKSEL3_SC2SEL_HXT |\ref CLK_CLKDIV1_SC2(x) |
\r
531 * |\ref SC2_MODULE |\ref CLK_CLKSEL3_SC2SEL_PLL |\ref CLK_CLKDIV1_SC2(x) |
\r
532 * |\ref SC2_MODULE |\ref CLK_CLKSEL3_SC2SEL_PCLK0 |\ref CLK_CLKDIV1_SC2(x) |
\r
533 * |\ref SC2_MODULE |\ref CLK_CLKSEL3_SC2SEL_HIRC |\ref CLK_CLKDIV1_SC2(x) |
\r
534 * |\ref USBH_MODULE |\ref CLK_CLKSEL0_USBSEL_HIRC48 |\ref CLK_CLKDIV0_USB(x) |
\r
535 * |\ref USBH_MODULE |\ref CLK_CLKSEL0_USBSEL_PLL |\ref CLK_CLKDIV0_USB(x) |
\r
536 * |\ref OTG_MODULE |\ref CLK_CLKSEL0_USBSEL_HIRC48 |\ref CLK_CLKDIV0_USB(x) |
\r
537 * |\ref OTG_MODULE |\ref CLK_CLKSEL0_USBSEL_PLL |\ref CLK_CLKDIV0_USB(x) |
\r
538 * |\ref USBD_MODULE |\ref CLK_CLKSEL0_USBSEL_HIRC48 |\ref CLK_CLKDIV0_USB(x) |
\r
539 * |\ref USBD_MODULE |\ref CLK_CLKSEL0_USBSEL_PLL |\ref CLK_CLKDIV0_USB(x) |
\r
541 void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv)
\r
543 uint32_t u32Sel = 0UL, u32Div = 0UL;
\r
544 uint32_t au32SelTbl[4] = {0x0UL, 0x4UL, 0x8UL, 0xCUL};
\r
545 uint32_t au32DivTbl[4] = {0x0UL, 0x4UL, 0x8UL, 0x10UL};
\r
547 if(MODULE_CLKDIV_Msk(u32ModuleIdx) != MODULE_NoMsk)
\r
549 /* Get clock divider control register address */
\r
550 u32Div = (uint32_t)&CLK->CLKDIV0 + (au32DivTbl[MODULE_CLKDIV(u32ModuleIdx)]);
\r
551 /* Apply new divider */
\r
552 M32(u32Div) = (M32(u32Div) & (~(MODULE_CLKDIV_Msk(u32ModuleIdx) << MODULE_CLKDIV_Pos(u32ModuleIdx)))) | u32ClkDiv;
\r
555 if(MODULE_CLKSEL_Msk(u32ModuleIdx) != MODULE_NoMsk)
\r
557 /* Get clock select control register address */
\r
558 u32Sel = (uint32_t)&CLK->CLKSEL0 + (au32SelTbl[MODULE_CLKSEL(u32ModuleIdx)]);
\r
559 /* Set new clock selection setting */
\r
560 M32(u32Sel) = (M32(u32Sel) & (~(MODULE_CLKSEL_Msk(u32ModuleIdx) << MODULE_CLKSEL_Pos(u32ModuleIdx)))) | u32ClkSrc;
\r
565 * @brief Set SysTick clock source
\r
566 * @param[in] u32ClkSrc is module clock source. Including:
\r
567 * - \ref CLK_CLKSEL0_STCLKSEL_HXT
\r
568 * - \ref CLK_CLKSEL0_STCLKSEL_LXT
\r
569 * - \ref CLK_CLKSEL0_STCLKSEL_HXT_DIV2
\r
570 * - \ref CLK_CLKSEL0_STCLKSEL_HCLK_DIV2
\r
571 * - \ref CLK_CLKSEL0_STCLKSEL_HIRC_DIV2
\r
573 * @details This function set SysTick clock source. \n
\r
574 * The register write-protection function should be disabled before using this function.
\r
576 void CLK_SetSysTickClockSrc(uint32_t u32ClkSrc)
\r
578 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc;
\r
582 * @brief Enable clock source
\r
583 * @param[in] u32ClkMask is clock source mask. Including :
\r
584 * - \ref CLK_PWRCTL_HXTEN_Msk
\r
585 * - \ref CLK_PWRCTL_LXTEN_Msk
\r
586 * - \ref CLK_PWRCTL_HIRCEN_Msk
\r
587 * - \ref CLK_PWRCTL_LIRCEN_Msk
\r
588 * - \ref CLK_PWRCTL_HIRC48EN_Msk
\r
590 * @details This function enable clock source. \n
\r
591 * The register write-protection function should be disabled before using this function.
\r
593 void CLK_EnableXtalRC(uint32_t u32ClkMask)
\r
595 CLK->PWRCTL |= u32ClkMask;
\r
599 * @brief Disable clock source
\r
600 * @param[in] u32ClkMask is clock source mask. Including :
\r
601 * - \ref CLK_PWRCTL_HXTEN_Msk
\r
602 * - \ref CLK_PWRCTL_LXTEN_Msk
\r
603 * - \ref CLK_PWRCTL_HIRCEN_Msk
\r
604 * - \ref CLK_PWRCTL_LIRCEN_Msk
\r
605 * - \ref CLK_PWRCTL_HIRC48EN_Msk
\r
607 * @details This function disable clock source. \n
\r
608 * The register write-protection function should be disabled before using this function.
\r
610 void CLK_DisableXtalRC(uint32_t u32ClkMask)
\r
612 CLK->PWRCTL &= ~u32ClkMask;
\r
616 * @brief This function enable module clock
\r
617 * @param[in] u32ModuleIdx is module index. Including :
\r
618 * - \ref PDMA0_MODULE
\r
619 * - \ref PDMA1_MODULE
\r
620 * - \ref ISP_MODULE
\r
621 * - \ref EBI_MODULE
\r
622 * - \ref SDH0_MODULE
\r
623 * - \ref CRC_MODULE
\r
624 * - \ref CRPT_MODULE
\r
625 * - \ref USBH_MODULE
\r
626 * - \ref WDT_MODULE
\r
627 * - \ref WWDT_MODULE
\r
628 * - \ref RTC_MODULE
\r
629 * - \ref TMR0_MODULE
\r
630 * - \ref TMR1_MODULE
\r
631 * - \ref TMR2_MODULE
\r
632 * - \ref TMR3_MODULE
\r
633 * - \ref CLKO_MODULE
\r
634 * - \ref ACMP01_MODULE
\r
635 * - \ref I2C0_MODULE
\r
636 * - \ref I2C1_MODULE
\r
637 * - \ref I2C2_MODULE
\r
638 * - \ref QSPI0_MODULE
\r
639 * - \ref SPI0_MODULE
\r
640 * - \ref SPI1_MODULE
\r
641 * - \ref SPI2_MODULE
\r
642 * - \ref SPI3_MODULE
\r
643 * - \ref UART0_MODULE
\r
644 * - \ref UART1_MODULE
\r
645 * - \ref UART2_MODULE
\r
646 * - \ref UART3_MODULE
\r
647 * - \ref UART4_MODULE
\r
648 * - \ref UART5_MODULE
\r
649 * - \ref CAN0_MODULE
\r
650 * - \ref OTG_MODULE
\r
651 * - \ref USBD_MODULE
\r
652 * - \ref EADC_MODULE
\r
653 * - \ref I2S0_MODULE
\r
654 * - \ref SC0_MODULE
\r
655 * - \ref SC1_MODULE
\r
656 * - \ref SC2_MODULE
\r
657 * - \ref USCI0_MODULE
\r
658 * - \ref USCI1_MODULE
\r
659 * - \ref DAC_MODULE
\r
660 * - \ref EPWM0_MODULE
\r
661 * - \ref EPWM1_MODULE
\r
662 * - \ref BPWM0_MODULE
\r
663 * - \ref BPWM1_MODULE
\r
664 * - \ref QEI0_MODULE
\r
665 * - \ref QEI1_MODULE
\r
666 * - \ref QEI0_MODULE
\r
667 * - \ref TRNG_MODULE
\r
668 * - \ref ECAP0_MODULE
\r
669 * - \ref ECAP1_MODULE
\r
671 * @details This function enable module clock.
\r
673 void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
\r
675 uint32_t u32TmpVal = 0UL, u32TmpAddr = 0UL;
\r
677 u32TmpVal = (1UL << MODULE_IP_EN_Pos(u32ModuleIdx));
\r
678 u32TmpAddr = (uint32_t)&CLK->AHBCLK;
\r
679 u32TmpAddr += ((MODULE_APBCLK(u32ModuleIdx) * 4UL));
\r
681 *(volatile uint32_t *)u32TmpAddr |= u32TmpVal;
\r
685 * @brief This function disable module clock
\r
686 * @param[in] u32ModuleIdx is module index
\r
687 * - \ref PDMA0_MODULE
\r
688 * - \ref PDMA1_MODULE
\r
689 * - \ref ISP_MODULE
\r
690 * - \ref EBI_MODULE
\r
691 * - \ref SDH0_MODULE
\r
692 * - \ref CRC_MODULE
\r
693 * - \ref CRPT_MODULE
\r
694 * - \ref USBH_MODULE
\r
695 * - \ref WDT_MODULE
\r
696 * - \ref WWDT_MODULE
\r
697 * - \ref RTC_MODULE
\r
698 * - \ref TMR0_MODULE
\r
699 * - \ref TMR1_MODULE
\r
700 * - \ref TMR2_MODULE
\r
701 * - \ref TMR3_MODULE
\r
702 * - \ref CLKO_MODULE
\r
703 * - \ref ACMP01_MODULE
\r
704 * - \ref I2C0_MODULE
\r
705 * - \ref I2C1_MODULE
\r
706 * - \ref I2C2_MODULE
\r
707 * - \ref QSPI0_MODULE
\r
708 * - \ref SPI0_MODULE
\r
709 * - \ref SPI1_MODULE
\r
710 * - \ref SPI2_MODULE
\r
711 * - \ref SPI3_MODULE
\r
712 * - \ref UART0_MODULE
\r
713 * - \ref UART1_MODULE
\r
714 * - \ref UART2_MODULE
\r
715 * - \ref UART3_MODULE
\r
716 * - \ref UART4_MODULE
\r
717 * - \ref UART5_MODULE
\r
718 * - \ref CAN0_MODULE
\r
719 * - \ref OTG_MODULE
\r
720 * - \ref USBD_MODULE
\r
721 * - \ref EADC_MODULE
\r
722 * - \ref I2S0_MODULE
\r
723 * - \ref SC0_MODULE
\r
724 * - \ref SC1_MODULE
\r
725 * - \ref SC2_MODULE
\r
726 * - \ref USCI0_MODULE
\r
727 * - \ref USCI1_MODULE
\r
728 * - \ref DAC_MODULE
\r
729 * - \ref EPWM0_MODULE
\r
730 * - \ref EPWM1_MODULE
\r
731 * - \ref BPWM0_MODULE
\r
732 * - \ref BPWM1_MODULE
\r
733 * - \ref QEI0_MODULE
\r
734 * - \ref QEI1_MODULE
\r
735 * - \ref QEI0_MODULE
\r
736 * - \ref TRNG_MODULE
\r
737 * - \ref ECAP0_MODULE
\r
738 * - \ref ECAP1_MODULE
\r
740 * @details This function disable module clock.
\r
742 void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
\r
744 uint32_t u32TmpVal = 0UL, u32TmpAddr = 0UL;
\r
746 u32TmpVal = ~(1UL << MODULE_IP_EN_Pos(u32ModuleIdx));
\r
747 u32TmpAddr = (uint32_t)&CLK->AHBCLK;
\r
748 u32TmpAddr += ((MODULE_APBCLK(u32ModuleIdx) * 4UL));
\r
750 *(uint32_t *)u32TmpAddr &= u32TmpVal;
\r
755 * @brief Set PLL frequency
\r
756 * @param[in] u32PllClkSrc is PLL clock source. Including :
\r
757 * - \ref CLK_PLLCTL_PLLSRC_HXT
\r
758 * - \ref CLK_PLLCTL_PLLSRC_HIRC
\r
759 * @param[in] u32PllFreq is PLL frequency. The range of u32PllFreq is 24 MHz ~ 144 MHz.
\r
760 * @return PLL frequency
\r
761 * @details This function is used to configure PLLCTL register to set specified PLL frequency. \n
\r
762 * The register write-protection function should be disabled before using this function.
\r
764 uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
\r
766 uint32_t u32PllSrcClk, u32NR, u32NF, u32NO, u32PllClk;
\r
767 uint32_t u32Tmp, u32Tmp2, u32Tmp3, u32Min, u32MinNF, u32MinNR;
\r
769 /* Disable PLL first to avoid unstable when setting PLL */
\r
772 /* PLL source clock is from HXT */
\r
773 if(u32PllClkSrc == CLK_PLLCTL_PLLSRC_HXT)
\r
776 /* Enable HXT clock */
\r
777 CLK->PWRCTL |= CLK_PWRCTL_HXTEN_Msk;
\r
779 /* Wait for HXT clock ready */
\r
780 CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);
\r
782 /* Select PLL source clock from HXT */
\r
783 u32PllSrcClk = __HXT;
\r
786 /* PLL source clock is from HIRC */
\r
790 /* Enable HIRC clock */
\r
791 CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
\r
793 /* Wait for HIRC clock ready */
\r
794 CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
\r
796 /* Select PLL source clock from HIRC */
\r
797 u32PllSrcClk = __HIRC;
\r
800 /* Check PLL frequency range */
\r
801 if((u32PllFreq <= FREQ_144MHZ) && (u32PllFreq >= FREQ_24MHZ))
\r
804 /* Select "NO" according to request frequency */
\r
805 if((u32PllFreq < FREQ_48MHZ) && (u32PllFreq >= FREQ_24MHZ))
\r
808 u32PllFreq = u32PllFreq << 2;
\r
810 else if((u32PllFreq < FREQ_96MHZ) && (u32PllFreq >= FREQ_48MHZ))
\r
813 u32PllFreq = u32PllFreq << 1;
\r
820 /* u32NR start from 3 to avoid calculation overflow */
\r
823 /* Find best solution */
\r
824 u32Min = (uint32_t) - 1;
\r
828 for(; u32NR <= 32UL; u32NR++)
\r
830 u32Tmp = u32PllSrcClk / u32NR;
\r
831 if((u32Tmp >= FREQ_2MHZ) && (u32Tmp <= FREQ_8MHZ))
\r
833 for(u32NF = 2UL; u32NF <= 513UL; u32NF++)
\r
835 u32Tmp2 = (u32Tmp * u32NF) << 1;
\r
836 if((u32Tmp2 >= FREQ_96MHZ) && (u32Tmp2 <= FREQ_200MHZ))
\r
838 u32Tmp3 = (u32Tmp2 > u32PllFreq) ? u32Tmp2 - u32PllFreq : u32PllFreq - u32Tmp2;
\r
839 if(u32Tmp3 < u32Min)
\r
845 /* Break when get good results */
\r
856 /* Enable and apply new PLL setting. */
\r
857 CLK->PLLCTL = u32PllClkSrc | (u32NO << 14) | ((u32MinNR - 1UL) << 9) | (u32MinNF - 2UL);
\r
859 /* Actual PLL output clock frequency */
\r
860 u32PllClk = u32PllSrcClk / ((u32NO + 1UL) * u32MinNR) * (u32MinNF << 1);
\r
866 /* Wrong frequency request. Just return default setting. */
\r
867 if((SYS->PLSTS & SYS_PLSTS_PLSTATUS_Msk) == SYS_PLCTL_PLSEL_PL0)
\r
870 /* Apply default PLL setting and return */
\r
871 CLK->PLLCTL = u32PllClkSrc | CLK_PLLCTL_64MHz_HXT;
\r
873 /* Actual PLL output clock frequency */
\r
874 u32PllClk = FREQ_64MHZ;
\r
880 /* Apply default PLL setting and return */
\r
881 CLK->PLLCTL = u32PllClkSrc | CLK_PLLCTL_48MHz_HXT;
\r
883 /* Actual PLL output clock frequency */
\r
884 u32PllClk = FREQ_48MHZ;
\r
889 /* Wait for PLL clock stable */
\r
890 CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);
\r
892 /* Return actual PLL output clock frequency */
\r
897 * @brief Disable PLL
\r
900 * @details This function set PLL in Power-down mode. \n
\r
901 * The register write-protection function should be disabled before using this function.
\r
903 void CLK_DisablePLL(void)
\r
905 CLK->PLLCTL |= CLK_PLLCTL_PD_Msk;
\r
909 * @brief This function check selected clock source status
\r
910 * @param[in] u32ClkMask is selected clock source. Including :
\r
911 * - \ref CLK_STATUS_HXTSTB_Msk
\r
912 * - \ref CLK_STATUS_LXTSTB_Msk
\r
913 * - \ref CLK_STATUS_HIRCSTB_Msk
\r
914 * - \ref CLK_STATUS_LIRCSTB_Msk
\r
915 * - \ref CLK_STATUS_PLLSTB_Msk
\r
916 * - \ref CLK_STATUS_HIRC48STB_Msk
\r
917 * - \ref CLK_STATUS_EXTLXTSTB_Msk
\r
918 * - \ref CLK_STATUS_LIRC32STB_Msk
\r
919 * @retval 0 clock is not stable
\r
920 * @retval 1 clock is stable
\r
921 * @details To wait for clock ready by specified clock source stable flag or timeout (~300ms)
\r
923 uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
\r
925 int32_t i32TimeOutCnt = 2400000;
\r
926 uint32_t u32Ret = 1U;
\r
928 while((CLK->STATUS & u32ClkMask) != u32ClkMask)
\r
930 if(i32TimeOutCnt-- <= 0)
\r
940 * @brief Enable System Tick counter
\r
941 * @param[in] u32ClkSrc is System Tick clock source. Including:
\r
942 * - \ref CLK_CLKSEL0_STCLKSEL_HXT
\r
943 * - \ref CLK_CLKSEL0_STCLKSEL_LXT
\r
944 * - \ref CLK_CLKSEL0_STCLKSEL_HXT_DIV2
\r
945 * - \ref CLK_CLKSEL0_STCLKSEL_HCLK_DIV2
\r
946 * - \ref CLK_CLKSEL0_STCLKSEL_HIRC_DIV2
\r
947 * - \ref CLK_CLKSEL0_STCLKSEL_HCLK
\r
948 * @param[in] u32Count is System Tick reload value. It could be 0~0xFFFFFF.
\r
950 * @details This function set System Tick clock source, reload value, enable System Tick counter and interrupt. \n
\r
951 * The register write-protection function should be disabled before using this function.
\r
953 void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
\r
955 /* Set System Tick counter disabled */
\r
956 SysTick->CTRL = 0UL;
\r
958 /* Set System Tick clock source */
\r
959 if(u32ClkSrc == CLK_CLKSEL0_STCLKSEL_HCLK)
\r
961 SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
\r
965 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc;
\r
968 /* Set System Tick reload value */
\r
969 SysTick->LOAD = u32Count;
\r
971 /* Clear System Tick current value and counter flag */
\r
972 SysTick->VAL = 0UL;
\r
974 /* Set System Tick interrupt enabled and counter enabled */
\r
975 SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
\r
979 * @brief Disable System Tick counter
\r
982 * @details This function disable System Tick counter.
\r
984 void CLK_DisableSysTick(void)
\r
986 /* Set System Tick counter disabled */
\r
987 SysTick->CTRL = 0UL;
\r
991 * @brief Power-down mode selected
\r
992 * @param[in] u32PDMode is power down mode index. Including :
\r
993 * - \ref CLK_PMUCTL_PDMSEL_PD
\r
994 * - \ref CLK_PMUCTL_PDMSEL_LLPD
\r
995 * - \ref CLK_PMUCTL_PDMSEL_FWPD
\r
996 * - \ref CLK_PMUCTL_PDMSEL_ULLPD
\r
997 * - \ref CLK_PMUCTL_PDMSEL_SPD
\r
998 * - \ref CLK_PMUCTL_PDMSEL_DPD
\r
1000 * @details This function is used to set power-down mode.
\r
1002 void CLK_SetPowerDownMode(uint32_t u32PDMode)
\r
1004 CLK->PMUCTL = (CLK->PMUCTL & (~CLK_PMUCTL_PDMSEL_Msk)) | (u32PDMode);
\r
1008 * @brief Set Wake-up pin trigger type at Deep Power down mode
\r
1009 * @param[in] u32TriggerType Wake-up pin trigger type
\r
1010 * - \ref CLK_DPDWKPIN_RISING
\r
1011 * - \ref CLK_DPDWKPIN_FALLING
\r
1012 * - \ref CLK_DPDWKPIN_BOTHEDGE
\r
1014 * @details This function is used to enable Wake-up pin trigger type.
\r
1017 void CLK_EnableDPDWKPin(uint32_t u32TriggerType)
\r
1019 CLK->PMUCTL = (CLK->PMUCTL & (~CLK_PMUCTL_WKPINEN_Msk)) | (u32TriggerType);
\r
1023 * @brief Get power manager wake up source
\r
1026 * @details This function get power manager wake up source.
\r
1029 uint32_t CLK_GetPMUWKSrc(void)
\r
1031 return (CLK->PMUSTS);
\r
1035 * @brief Set specified GPIO as wake up source at Standby Power-down mode
\r
1036 * @param[in] u32Port GPIO port. It could be 0~3.
\r
1037 * @param[in] u32Pin The pin of specified GPIO port. It could be 0 ~ 15.
\r
1038 * @param[in] u32TriggerType Wake-up pin trigger type
\r
1039 * - \ref CLK_SPDWKPIN_RISING
\r
1040 * - \ref CLK_SPDWKPIN_FALLING
\r
1041 * @param[in] u32DebounceEn Standby Power-down mode wake-up pin de-bounce function
\r
1042 * - \ref CLK_SPDWKPIN_DEBOUNCEEN
\r
1043 * - \ref CLK_SPDWKPIN_DEBOUNCEDIS
\r
1045 * @details This function is used to set specified GPIO as wake up source at Standby Power-down mode.
\r
1048 void CLK_EnableSPDWKPin(uint32_t u32Port, uint32_t u32Pin, uint32_t u32TriggerType, uint32_t u32DebounceEn)
\r
1050 uint32_t u32TmpAddr = 0UL;
\r
1051 uint32_t u32TmpVal = 0UL;
\r
1053 /* GPx Stand-by Power-down Wake-up Pin Select */
\r
1054 u32TmpAddr = (uint32_t)&CLK->PASWKCTL;
\r
1055 u32TmpAddr += (0x4UL * u32Port);
\r
1057 u32TmpVal = inpw((uint32_t *)u32TmpAddr);
\r
1058 u32TmpVal = (u32TmpVal & ~(CLK_PASWKCTL_WKPSEL_Msk | CLK_PASWKCTL_PRWKEN_Msk | CLK_PASWKCTL_PFWKEN_Msk | CLK_PASWKCTL_DBEN_Msk | CLK_PASWKCTL_WKEN_Msk)) |
\r
1059 (u32Pin << CLK_PASWKCTL_WKPSEL_Pos) | u32TriggerType | u32DebounceEn | CLK_SPDWKPIN_ENABLE;
\r
1060 outpw((uint32_t *)u32TmpAddr, u32TmpVal);
\r
1064 * @brief Get PLL clock frequency
\r
1066 * @return PLL frequency
\r
1067 * @details This function get PLL frequency. The frequency unit is Hz.
\r
1070 __NONSECURE_ENTRY_WEAK
\r
1071 uint32_t CLK_GetPLLClockFreq(void)
\r
1073 uint32_t u32PllFreq = 0UL, u32PllReg;
\r
1074 uint32_t u32FIN, u32NF, u32NR, u32NO;
\r
1075 uint8_t au8NoTbl[4] = {1U, 2U, 2U, 4U};
\r
1077 u32PllReg = CLK->PLLCTL;
\r
1079 if(u32PllReg & (CLK_PLLCTL_PD_Msk | CLK_PLLCTL_OE_Msk))
\r
1081 u32PllFreq = 0UL; /* PLL is in power down mode or fix low */
\r
1083 else /* PLL is in normal mode */
\r
1086 /* PLL source clock */
\r
1087 if(u32PllReg & CLK_PLLCTL_PLLSRC_Msk)
\r
1089 u32FIN = __HIRC; /* PLL source clock from HIRC */
\r
1093 u32FIN = __HXT; /* PLL source clock from HXT */
\r
1096 /* Calculate PLL frequency */
\r
1097 if(u32PllReg & CLK_PLLCTL_BP_Msk)
\r
1099 u32PllFreq = u32FIN; /* PLL is in bypass mode */
\r
1103 /* PLL is output enabled in normal work mode */
\r
1104 u32NO = au8NoTbl[((u32PllReg & CLK_PLLCTL_OUTDIV_Msk) >> CLK_PLLCTL_OUTDIV_Pos)];
\r
1105 u32NF = ((u32PllReg & CLK_PLLCTL_FBDIV_Msk) >> CLK_PLLCTL_FBDIV_Pos) + 2UL;
\r
1106 u32NR = ((u32PllReg & CLK_PLLCTL_INDIV_Msk) >> CLK_PLLCTL_INDIV_Pos) + 1UL;
\r
1108 /* u32FIN is shifted 2 bits to avoid overflow */
\r
1109 u32PllFreq = (((u32FIN >> 2) * (u32NF << 1)) / (u32NR * u32NO) << 2);
\r
1113 return u32PllFreq;
\r
1117 * @brief Get selected module clock source
\r
1118 * @param[in] u32ModuleIdx is module index.
\r
1119 * - \ref SDH0_MODULE
\r
1120 * - \ref USBH_MODULE
\r
1121 * - \ref WDT_MODULE
\r
1122 * - \ref WWDT_MODULE
\r
1123 * - \ref RTC_MODULE
\r
1124 * - \ref TMR0_MODULE
\r
1125 * - \ref TMR1_MODULE
\r
1126 * - \ref TMR2_MODULE
\r
1127 * - \ref TMR3_MODULE
\r
1128 * - \ref CLKO_MODULE
\r
1129 * - \ref QSPI0_MODULE
\r
1130 * - \ref SPI0_MODULE
\r
1131 * - \ref SPI1_MODULE
\r
1132 * - \ref SPI2_MODULE
\r
1133 * - \ref SPI3_MODULE
\r
1134 * - \ref UART0_MODULE
\r
1135 * - \ref UART1_MODULE
\r
1136 * - \ref UART2_MODULE
\r
1137 * - \ref UART3_MODULE
\r
1138 * - \ref UART4_MODULE
\r
1139 * - \ref UART5_MODULE
\r
1140 * - \ref OTG_MODULE
\r
1141 * - \ref USBD_MODULE
\r
1142 * - \ref I2S0_MODULE
\r
1143 * - \ref SC0_MODULE
\r
1144 * - \ref SC1_MODULE
\r
1145 * - \ref SC2_MODULE
\r
1146 * - \ref EPWM0_MODULE
\r
1147 * - \ref EPWM1_MODULE
\r
1148 * - \ref BPWM0_MODULE
\r
1149 * - \ref BPWM1_MODULE
\r
1150 * @return Selected module clock source setting
\r
1151 * @details This function get selected module clock source.
\r
1154 __NONSECURE_ENTRY_WEAK
\r
1155 uint32_t CLK_GetModuleClockSource(uint32_t u32ModuleIdx)
\r
1157 uint32_t u32TmpVal = 0UL, u32TmpAddr = 0UL;
\r
1158 uint32_t au32SelTbl[4] = {0x0UL, 0x4UL, 0x8UL, 0xCUL};
\r
1160 /* Get clock source selection setting */
\r
1161 if(u32ModuleIdx == EPWM0_MODULE)
\r
1163 u32TmpVal = ((CLK->CLKSEL2 & CLK_CLKSEL2_EPWM0SEL_Msk) >> CLK_CLKSEL2_EPWM0SEL_Pos);
\r
1165 else if(u32ModuleIdx == EPWM1_MODULE)
\r
1167 u32TmpVal = ((CLK->CLKSEL2 & CLK_CLKSEL2_EPWM1SEL_Msk) >> CLK_CLKSEL2_EPWM1SEL_Pos);
\r
1169 else if(u32ModuleIdx == BPWM0_MODULE)
\r
1171 u32TmpVal = ((CLK->CLKSEL2 & CLK_CLKSEL2_BPWM0SEL_Msk) >> CLK_CLKSEL2_BPWM0SEL_Pos);
\r
1173 else if(u32ModuleIdx == BPWM1_MODULE)
\r
1175 u32TmpVal = ((CLK->CLKSEL2 & CLK_CLKSEL2_BPWM1SEL_Msk) >> CLK_CLKSEL2_BPWM1SEL_Pos);
\r
1177 else if(MODULE_CLKSEL_Msk(u32ModuleIdx) != MODULE_NoMsk)
\r
1179 /* Get clock select control register address */
\r
1180 u32TmpAddr = (uint32_t)&CLK->CLKSEL0 + (au32SelTbl[MODULE_CLKSEL(u32ModuleIdx)]);
\r
1182 /* Get clock source selection setting */
\r
1183 u32TmpVal = ((inpw((uint32_t *)u32TmpAddr) & (MODULE_CLKSEL_Msk(u32ModuleIdx) << MODULE_CLKSEL_Pos(u32ModuleIdx))) >> MODULE_CLKSEL_Pos(u32ModuleIdx));
\r
1190 * @brief Get selected module clock divider number
\r
1191 * @param[in] u32ModuleIdx is module index.
\r
1192 * - \ref SDH0_MODULE
\r
1193 * - \ref USBH_MODULE
\r
1194 * - \ref UART0_MODULE
\r
1195 * - \ref UART1_MODULE
\r
1196 * - \ref UART2_MODULE
\r
1197 * - \ref UART3_MODULE
\r
1198 * - \ref UART4_MODULE
\r
1199 * - \ref UART5_MODULE
\r
1200 * - \ref OTG_MODULE
\r
1201 * - \ref USBD_MODULE
\r
1202 * - \ref SC0_MODULE
\r
1203 * - \ref SC1_MODULE
\r
1204 * - \ref SC2_MODULE
\r
1205 * - \ref EADC_MODULE
\r
1206 * @return Selected module clock divider number setting
\r
1207 * @details This function get selected module clock divider number.
\r
1210 __NONSECURE_ENTRY_WEAK
\r
1211 uint32_t CLK_GetModuleClockDivider(uint32_t u32ModuleIdx)
\r
1213 uint32_t u32TmpVal = 0UL, u32TmpAddr = 0UL;
\r
1214 uint32_t au32DivTbl[4] = {0x0UL, 0x4UL, 0x8UL, 0x10UL};
\r
1216 if(MODULE_CLKDIV_Msk(u32ModuleIdx) != MODULE_NoMsk)
\r
1218 /* Get clock divider control register address */
\r
1219 u32TmpAddr = (uint32_t)&CLK->CLKDIV0 + (au32DivTbl[MODULE_CLKDIV(u32ModuleIdx)]);
\r
1220 /* Get clock divider number setting */
\r
1221 u32TmpVal = ((inpw((uint32_t *)u32TmpAddr) & (MODULE_CLKDIV_Msk(u32ModuleIdx) << MODULE_CLKDIV_Pos(u32ModuleIdx))) >> MODULE_CLKDIV_Pos(u32ModuleIdx));
\r
1228 /*@}*/ /* end of group CLK_EXPORTED_FUNCTIONS */
\r
1230 /*@}*/ /* end of group CLK_Driver */
\r
1232 /*@}*/ /* end of group Standard_Driver */
\r
1234 /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/
\r