]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_MPU_M23_Nuvoton_NuMaker_PFM_M2351_IAR_GCC/Nuvoton_Code/StdDriver/src/clk.c
Add Cortex M23 GCC and IAR ports. Add demo projects for Nuvoton NuMaker-PFM-2351.
[freertos] / FreeRTOS / Demo / CORTEX_MPU_M23_Nuvoton_NuMaker_PFM_M2351_IAR_GCC / Nuvoton_Code / StdDriver / src / clk.c
1 /**************************************************************************//**\r
2  * @file     clk.c\r
3  * @version  V3.00\r
4  * @brief    M2351 series Clock Controller (CLK) driver source file\r
5  *\r
6  * @note\r
7  * Copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.\r
8  *****************************************************************************/\r
9 #include "NuMicro.h"\r
10 /** @addtogroup Standard_Driver Standard Driver\r
11   @{\r
12 */\r
13 \r
14 /** @addtogroup CLK_Driver CLK Driver\r
15   @{\r
16 */\r
17 \r
18 \r
19 /** @addtogroup CLK_EXPORTED_FUNCTIONS CLK Exported Functions\r
20   @{\r
21 */\r
22 \r
23 \r
24 /**\r
25   * @brief      Disable frequency output function\r
26   * @param      None\r
27   * @return     None\r
28   * @details    This function disable frequency output function.\r
29   */\r
30 void CLK_DisableCKO(void)\r
31 {\r
32     /* Disable CKO clock source */\r
33     CLK->APBCLK0 &= (~CLK_APBCLK0_CLKOCKEN_Msk);\r
34 }\r
35 \r
36 \r
37 /**\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
47   * @return     None\r
48   *\r
49   * @details    Output selected clock to CKO. The output clock frequency is divided by u32ClkDiv.\r
50   *             The formula is:\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
54   */\r
55 void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv, uint32_t u32ClkDivBy1En)\r
56 {\r
57     /* CKO = clock source / 2^(u32ClkDiv + 1) */\r
58     CLK->CLKOCTL = CLK_CLKOCTL_CLKOEN_Msk | u32ClkDiv | (u32ClkDivBy1En << CLK_CLKOCTL_DIV1EN_Pos);\r
59 \r
60     /* Enable CKO clock source */\r
61     CLK->APBCLK0 |= CLK_APBCLK0_CLKOCKEN_Msk;\r
62 \r
63     /* Select CKO clock source */\r
64     CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_CLKOSEL_Msk)) | (u32ClkSrc);\r
65 \r
66 }\r
67 \r
68 /**\r
69   * @brief      Enter to Power-down mode\r
70   * @param      None\r
71   * @return     None\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
74   */\r
75 void CLK_PowerDown(void)\r
76 {\r
77     /* Set the processor uses deep sleep as its low power mode */\r
78     SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;\r
79 \r
80     /* Set system Power-down enabled*/\r
81     CLK->PWRCTL |= CLK_PWRCTL_PDEN_Msk;\r
82 \r
83     /* Chip enter Power-down mode after CPU run WFI instruction */\r
84     __WFI();\r
85 }\r
86 \r
87 \r
88 \r
89 /**\r
90   * @brief      Enter to Idle mode\r
91   * @param      None\r
92   * @return     None\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
95   */\r
96 void CLK_Idle(void)\r
97 {\r
98     /* Set the processor uses sleep as its low power mode */\r
99     SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;\r
100 \r
101     /* Set chip in idle mode because of WFI command */\r
102     CLK->PWRCTL &= ~CLK_PWRCTL_PDEN_Msk;\r
103 \r
104     /* Chip enter idle mode after CPU run WFI instruction */\r
105     __WFI();\r
106 }\r
107 \r
108 \r
109 /**\r
110   * @brief      Get external high speed crystal clock frequency\r
111   * @param      None\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
114   */\r
115 __NONSECURE_ENTRY_WEAK\r
116 uint32_t CLK_GetHXTFreq(void)\r
117 {\r
118     uint32_t u32Freq = 0UL;\r
119     uint32_t u32HXTEN = CLK->PWRCTL & CLK_PWRCTL_HXTEN_Msk;\r
120 \r
121     if(u32HXTEN)\r
122     {\r
123         u32Freq = __HXT;\r
124     }\r
125     else\r
126     {\r
127         u32Freq = 0UL;\r
128     }\r
129 \r
130     return u32Freq;\r
131 }\r
132 \r
133 /**\r
134   * @brief      Get external low speed crystal clock frequency\r
135   * @param      None\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
138   */\r
139 \r
140 __NONSECURE_ENTRY_WEAK\r
141 uint32_t CLK_GetLXTFreq(void)\r
142 {\r
143     uint32_t u32Freq = 0UL;\r
144     uint32_t u32LXTEN = CLK->PWRCTL & CLK_PWRCTL_LXTEN_Msk;\r
145 \r
146     if(u32LXTEN)\r
147     {\r
148         u32Freq = __LXT;\r
149     }\r
150     else\r
151     {\r
152         u32Freq = 0UL;\r
153     }\r
154 \r
155     return u32Freq;\r
156 }\r
157 \r
158 /**\r
159   * @brief      Get HCLK frequency\r
160   * @param      None\r
161   * @return     HCLK frequency\r
162   * @details    This function get HCLK frequency. The frequency unit is Hz.\r
163   */\r
164 \r
165 __NONSECURE_ENTRY_WEAK\r
166 uint32_t CLK_GetHCLKFreq(void)\r
167 {\r
168     SystemCoreClockUpdate();\r
169     return SystemCoreClock;\r
170 }\r
171 \r
172 /**\r
173   * @brief      Get PCLK0 frequency\r
174   * @param      None\r
175   * @return     PCLK0 frequency\r
176   * @details    This function get PCLK0 frequency. The frequency unit is Hz.\r
177   */\r
178 \r
179 __NONSECURE_ENTRY_WEAK\r
180 uint32_t CLK_GetPCLK0Freq(void)\r
181 {\r
182     SystemCoreClockUpdate();\r
183     return (SystemCoreClock >> ((CLK->PCLKDIV & CLK_PCLKDIV_APB0DIV_Msk) >> CLK_PCLKDIV_APB0DIV_Pos));\r
184 }\r
185 \r
186 /**\r
187   * @brief      Get PCLK1 frequency\r
188   * @param      None\r
189   * @return     PCLK1 frequency\r
190   * @details    This function get PCLK1 frequency. The frequency unit is Hz.\r
191   */\r
192 \r
193 __NONSECURE_ENTRY_WEAK\r
194 uint32_t CLK_GetPCLK1Freq(void)\r
195 {\r
196     SystemCoreClockUpdate();\r
197     return (SystemCoreClock >> ((CLK->PCLKDIV & CLK_PCLKDIV_APB1DIV_Msk) >> CLK_PCLKDIV_APB1DIV_Pos));\r
198 }\r
199 \r
200 /**\r
201   * @brief      Get CPU frequency\r
202   * @param      None\r
203   * @return     CPU frequency\r
204   * @details    This function get CPU frequency. The frequency unit is Hz.\r
205   */\r
206 \r
207 __NONSECURE_ENTRY_WEAK\r
208 uint32_t CLK_GetCPUFreq(void)\r
209 {\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
215 \r
216     /* Update PLL Clock */\r
217     u32PllReg = CLK->PLLCTL;\r
218 \r
219     if(u32PllReg & (CLK_PLLCTL_PD_Msk | CLK_PLLCTL_OE_Msk))\r
220     {\r
221         PllClock = 0UL;           /* PLL is in power down mode or fix low */\r
222     }\r
223     else                        /* PLL is in normal mode */\r
224     {\r
225 \r
226         /* PLL source clock */\r
227         if(u32PllReg & CLK_PLLCTL_PLLSRC_Msk)\r
228         {\r
229             u32FIN = __HIRC;    /* PLL source clock from HIRC */\r
230         }\r
231         else\r
232         {\r
233             u32FIN = __HXT;     /* PLL source clock from HXT */\r
234         }\r
235 \r
236         /* Calculate PLL frequency */\r
237         if(u32PllReg & CLK_PLLCTL_BP_Msk)\r
238         {\r
239             PllClock = u32FIN;  /* PLL is in bypass mode */\r
240         }\r
241         else\r
242         {\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
247 \r
248             /* u32FIN is shifted 2 bits to avoid overflow */\r
249             PllClock = (((u32FIN >> 2) * (u32NF << 1)) / (u32NR * u32NO) << 2);\r
250         }\r
251     }\r
252 \r
253     /* HCLK clock source */\r
254     u32HclkSrc = CLK->CLKSEL0 & CLK_CLKSEL0_HCLKSEL_Msk;\r
255 \r
256     if(u32HclkSrc == CLK_CLKSEL0_HCLKSEL_LXT)\r
257     {\r
258 \r
259         if(u32RTCCKEN == 0UL)\r
260         {\r
261             CLK->APBCLK0 |= CLK_APBCLK0_RTCCKEN_Msk; /* Enable RTC clock to get LXT clock source */\r
262         }\r
263 \r
264         if(RTC->LXTCTL & RTC_LXTCTL_C32KS_Msk)\r
265         {\r
266             u32Freq = __LIRC32; /* LXT clock source is LIRC32 */\r
267         }\r
268         else\r
269         {\r
270             u32Freq = __LXT;    /* LXT clock source is external LXT */\r
271         }\r
272 \r
273         if(u32RTCCKEN == 0UL)\r
274         {\r
275             CLK->APBCLK0 &= (~CLK_APBCLK0_RTCCKEN_Msk); /* Disable RTC clock if it is disabled before */\r
276         }\r
277 \r
278     }\r
279     else if(u32HclkSrc == CLK_CLKSEL0_HCLKSEL_PLL)\r
280     {\r
281         u32Freq = PllClock;/* Use PLL clock */\r
282     }\r
283     else\r
284     {\r
285         u32Freq = au32ClkTbl[u32HclkSrc]; /* Use the clock sources directly */\r
286     }\r
287 \r
288     /* HCLK clock source divider */\r
289     u32HclkDiv = (CLK->CLKDIV0 & CLK_CLKDIV0_HCLKDIV_Msk) + 1UL;\r
290 \r
291     /* Update System Core Clock */\r
292     SystemCoreClock = u32Freq / u32HclkDiv;\r
293 \r
294     /* Update Cycles per micro second */\r
295     CyclesPerUs = (SystemCoreClock + 500000UL) / 1000000UL;\r
296 \r
297     return SystemCoreClock;\r
298 }\r
299 \r
300 /**\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
308   */\r
309 uint32_t CLK_SetCoreClock(uint32_t u32Hclk)\r
310 {\r
311     uint32_t u32HIRCSTB, u32PLSTATUS;\r
312 \r
313     /* Read HIRC clock source stable flag */\r
314     u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;\r
315 \r
316     /* Read power level status */\r
317     u32PLSTATUS = SYS->PLSTS & SYS_PLSTS_PLSTATUS_Msk;\r
318 \r
319     /* Check HCLK frequency range */\r
320     if((u32PLSTATUS == SYS_PLSTS_PLSTATUS_PL0) && (u32Hclk > FREQ_64MHZ))\r
321     {\r
322         u32Hclk = FREQ_64MHZ;\r
323     }\r
324     else if((u32PLSTATUS == SYS_PLSTS_PLSTATUS_PL1) && (u32Hclk > FREQ_48MHZ))\r
325     {\r
326         u32Hclk = FREQ_48MHZ;\r
327     }\r
328     else if(u32Hclk < FREQ_24MHZ)\r
329     {\r
330         u32Hclk = FREQ_24MHZ;\r
331     }\r
332 \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
338 \r
339     /* Enable Flash access cycle auto-tuning function */\r
340     FMC->CYCCTL &= (~FMC_CYCCTL_FADIS_Msk);\r
341 \r
342     /* Configure PLL setting if HXT clock is stable */\r
343     if(CLK->STATUS & CLK_STATUS_HXTSTB_Msk)\r
344     {\r
345         u32Hclk = CLK_EnablePLL(CLK_PLLCTL_PLLSRC_HXT, u32Hclk);\r
346     }\r
347     /* Configure PLL setting if HXT clock is not stable */\r
348     else\r
349     {\r
350         u32Hclk = CLK_EnablePLL(CLK_PLLCTL_PLLSRC_HIRC, u32Hclk);\r
351 \r
352         /* Read HIRC clock source stable flag */\r
353         u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;\r
354     }\r
355 \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
359     */\r
360     CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL, CLK_CLKDIV0_HCLK(1UL));\r
361 \r
362     /* Disable HIRC if HIRC is disabled before setting core clock */\r
363     if(u32HIRCSTB == 0UL)\r
364     {\r
365         CLK->PWRCTL &= ~CLK_PWRCTL_HIRCEN_Msk;\r
366     }\r
367 \r
368     /* Return actually HCLK frequency is PLL frequency divide 1 */\r
369     return u32Hclk;\r
370 }\r
371 \r
372 \r
373 /**\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
384   * @return     None\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
387   */\r
388 void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)\r
389 {\r
390     uint32_t u32HIRCSTB;\r
391 \r
392     /* Read HIRC clock source stable flag */\r
393     u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;\r
394 \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
399 \r
400     /* Enable Flash access cycle auto-tuning function */\r
401     FMC->CYCCTL &= (~FMC_CYCCTL_FADIS_Msk);\r
402 \r
403     /* Apply new Divider */\r
404     CLK->CLKDIV0 = (CLK->CLKDIV0 & (~CLK_CLKDIV0_HCLKDIV_Msk)) | u32ClkDiv;\r
405 \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
408     {\r
409         FMC->CYCCTL = (FMC->CYCCTL & (~FMC_CYCCTL_CYCLE_Msk)) | FMC_CYCCTL_FADIS_Msk | (3UL);\r
410     }\r
411 \r
412     /* Switch HCLK to new HCLK source */\r
413     CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | u32ClkSrc;\r
414 \r
415     /* Update System Core Clock */\r
416     SystemCoreClockUpdate();\r
417 \r
418     /* Disable HIRC if HIRC is disabled before switching HCLK source */\r
419     if(u32HIRCSTB == 0UL)\r
420     {\r
421         CLK->PWRCTL &= ~CLK_PWRCTL_HIRCEN_Msk;\r
422     }\r
423 }\r
424 /**\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
429   * @return     None\r
430   * @details    Valid parameter combinations listed in following table:\r
431   *\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
540   */\r
541 void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv)\r
542 {\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
546 \r
547     if(MODULE_CLKDIV_Msk(u32ModuleIdx) != MODULE_NoMsk)\r
548     {\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
553     }\r
554 \r
555     if(MODULE_CLKSEL_Msk(u32ModuleIdx) != MODULE_NoMsk)\r
556     {\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
561     }\r
562 }\r
563 \r
564 /**\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
572   * @return     None\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
575   */\r
576 void CLK_SetSysTickClockSrc(uint32_t u32ClkSrc)\r
577 {\r
578     CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc;\r
579 }\r
580 \r
581 /**\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
589   * @return     None\r
590   * @details    This function enable clock source. \n\r
591   *             The register write-protection function should be disabled before using this function.\r
592   */\r
593 void CLK_EnableXtalRC(uint32_t u32ClkMask)\r
594 {\r
595     CLK->PWRCTL |= u32ClkMask;\r
596 }\r
597 \r
598 /**\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
606   * @return     None\r
607   * @details    This function disable clock source. \n\r
608   *             The register write-protection function should be disabled before using this function.\r
609   */\r
610 void CLK_DisableXtalRC(uint32_t u32ClkMask)\r
611 {\r
612     CLK->PWRCTL &= ~u32ClkMask;\r
613 }\r
614 \r
615 /**\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
670   * @return     None\r
671   * @details    This function enable module clock.\r
672   */\r
673 void CLK_EnableModuleClock(uint32_t u32ModuleIdx)\r
674 {\r
675     uint32_t u32TmpVal = 0UL, u32TmpAddr = 0UL;\r
676 \r
677     u32TmpVal = (1UL << MODULE_IP_EN_Pos(u32ModuleIdx));\r
678     u32TmpAddr = (uint32_t)&CLK->AHBCLK;\r
679     u32TmpAddr += ((MODULE_APBCLK(u32ModuleIdx) * 4UL));\r
680 \r
681     *(volatile uint32_t *)u32TmpAddr |= u32TmpVal;\r
682 }\r
683 \r
684 /**\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
739   * @return     None\r
740   * @details    This function disable module clock.\r
741   */\r
742 void CLK_DisableModuleClock(uint32_t u32ModuleIdx)\r
743 {\r
744     uint32_t u32TmpVal = 0UL, u32TmpAddr = 0UL;\r
745 \r
746     u32TmpVal = ~(1UL << MODULE_IP_EN_Pos(u32ModuleIdx));\r
747     u32TmpAddr = (uint32_t)&CLK->AHBCLK;\r
748     u32TmpAddr += ((MODULE_APBCLK(u32ModuleIdx) * 4UL));\r
749 \r
750     *(uint32_t *)u32TmpAddr &= u32TmpVal;\r
751 }\r
752 \r
753 \r
754 /**\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
763   */\r
764 uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)\r
765 {\r
766     uint32_t u32PllSrcClk, u32NR, u32NF, u32NO, u32PllClk;\r
767     uint32_t u32Tmp, u32Tmp2, u32Tmp3, u32Min, u32MinNF, u32MinNR;\r
768 \r
769     /* Disable PLL first to avoid unstable when setting PLL */\r
770     CLK_DisablePLL();\r
771 \r
772     /* PLL source clock is from HXT */\r
773     if(u32PllClkSrc == CLK_PLLCTL_PLLSRC_HXT)\r
774     {\r
775 \r
776         /* Enable HXT clock */\r
777         CLK->PWRCTL |= CLK_PWRCTL_HXTEN_Msk;\r
778 \r
779         /* Wait for HXT clock ready */\r
780         CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);\r
781 \r
782         /* Select PLL source clock from HXT */\r
783         u32PllSrcClk = __HXT;\r
784     }\r
785 \r
786     /* PLL source clock is from HIRC */\r
787     else\r
788     {\r
789 \r
790         /* Enable HIRC clock */\r
791         CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;\r
792 \r
793         /* Wait for HIRC clock ready */\r
794         CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);\r
795 \r
796         /* Select PLL source clock from HIRC */\r
797         u32PllSrcClk = __HIRC;\r
798     }\r
799 \r
800     /* Check PLL frequency range */\r
801     if((u32PllFreq <= FREQ_144MHZ) && (u32PllFreq >= FREQ_24MHZ))\r
802     {\r
803 \r
804         /* Select "NO" according to request frequency */\r
805         if((u32PllFreq < FREQ_48MHZ) && (u32PllFreq >= FREQ_24MHZ))\r
806         {\r
807             u32NO = 3UL;\r
808             u32PllFreq = u32PllFreq << 2;\r
809         }\r
810         else if((u32PllFreq < FREQ_96MHZ) && (u32PllFreq >= FREQ_48MHZ))\r
811         {\r
812             u32NO = 1UL;\r
813             u32PllFreq = u32PllFreq << 1;\r
814         }\r
815         else\r
816         {\r
817             u32NO = 0UL;\r
818         }\r
819 \r
820         /* u32NR start from 3 to avoid calculation overflow */\r
821         u32NR = 3UL;\r
822 \r
823         /* Find best solution */\r
824         u32Min = (uint32_t) - 1;\r
825         u32MinNR = 0UL;\r
826         u32MinNF = 0UL;\r
827 \r
828         for(; u32NR <= 32UL; u32NR++)\r
829         {\r
830             u32Tmp = u32PllSrcClk / u32NR;\r
831             if((u32Tmp >= FREQ_2MHZ) && (u32Tmp <= FREQ_8MHZ))\r
832             {\r
833                 for(u32NF = 2UL; u32NF <= 513UL; u32NF++)\r
834                 {\r
835                     u32Tmp2 = (u32Tmp * u32NF) << 1;\r
836                     if((u32Tmp2 >= FREQ_96MHZ) && (u32Tmp2 <= FREQ_200MHZ))\r
837                     {\r
838                         u32Tmp3 = (u32Tmp2 > u32PllFreq) ? u32Tmp2 - u32PllFreq : u32PllFreq - u32Tmp2;\r
839                         if(u32Tmp3 < u32Min)\r
840                         {\r
841                             u32Min = u32Tmp3;\r
842                             u32MinNR = u32NR;\r
843                             u32MinNF = u32NF;\r
844 \r
845                             /* Break when get good results */\r
846                             if(u32Min == 0UL)\r
847                             {\r
848                                 break;\r
849                             }\r
850                         }\r
851                     }\r
852                 }\r
853             }\r
854         }\r
855 \r
856         /* Enable and apply new PLL setting. */\r
857         CLK->PLLCTL = u32PllClkSrc | (u32NO << 14) | ((u32MinNR - 1UL) << 9) | (u32MinNF - 2UL);\r
858 \r
859         /* Actual PLL output clock frequency */\r
860         u32PllClk = u32PllSrcClk / ((u32NO + 1UL) * u32MinNR) * (u32MinNF << 1);\r
861 \r
862     }\r
863     else\r
864     {\r
865 \r
866         /* Wrong frequency request. Just return default setting. */\r
867         if((SYS->PLSTS & SYS_PLSTS_PLSTATUS_Msk) == SYS_PLCTL_PLSEL_PL0)\r
868         {\r
869 \r
870             /* Apply default PLL setting and return */\r
871             CLK->PLLCTL = u32PllClkSrc | CLK_PLLCTL_64MHz_HXT;\r
872 \r
873             /* Actual PLL output clock frequency */\r
874             u32PllClk = FREQ_64MHZ;\r
875 \r
876         }\r
877         else\r
878         {\r
879 \r
880             /* Apply default PLL setting and return */\r
881             CLK->PLLCTL = u32PllClkSrc | CLK_PLLCTL_48MHz_HXT;\r
882 \r
883             /* Actual PLL output clock frequency */\r
884             u32PllClk = FREQ_48MHZ;\r
885         }\r
886 \r
887     }\r
888 \r
889     /* Wait for PLL clock stable */\r
890     CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);\r
891 \r
892     /* Return actual PLL output clock frequency */\r
893     return u32PllClk;\r
894 }\r
895 \r
896 /**\r
897   * @brief      Disable PLL\r
898   * @param      None\r
899   * @return     None\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
902   */\r
903 void CLK_DisablePLL(void)\r
904 {\r
905     CLK->PLLCTL |= CLK_PLLCTL_PD_Msk;\r
906 }\r
907 \r
908 /**\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
922   */\r
923 uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)\r
924 {\r
925     int32_t i32TimeOutCnt = 2400000;\r
926     uint32_t u32Ret = 1U;\r
927 \r
928     while((CLK->STATUS & u32ClkMask) != u32ClkMask)\r
929     {\r
930         if(i32TimeOutCnt-- <= 0)\r
931         {\r
932             u32Ret = 0U;\r
933             break;\r
934         }\r
935     }\r
936     return u32Ret;\r
937 }\r
938 \r
939 /**\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
949   * @return     None\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
952   */\r
953 void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)\r
954 {\r
955     /* Set System Tick counter disabled */\r
956     SysTick->CTRL = 0UL;\r
957 \r
958     /* Set System Tick clock source */\r
959     if(u32ClkSrc == CLK_CLKSEL0_STCLKSEL_HCLK)\r
960     {\r
961         SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;\r
962     }\r
963     else\r
964     {\r
965         CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc;\r
966     }\r
967 \r
968     /* Set System Tick reload value */\r
969     SysTick->LOAD = u32Count;\r
970 \r
971     /* Clear System Tick current value and counter flag */\r
972     SysTick->VAL = 0UL;\r
973 \r
974     /* Set System Tick interrupt enabled and counter enabled */\r
975     SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;\r
976 }\r
977 \r
978 /**\r
979   * @brief      Disable System Tick counter\r
980   * @param      None\r
981   * @return     None\r
982   * @details    This function disable System Tick counter.\r
983   */\r
984 void CLK_DisableSysTick(void)\r
985 {\r
986     /* Set System Tick counter disabled */\r
987     SysTick->CTRL = 0UL;\r
988 }\r
989 \r
990 /**\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
999   * @return     None\r
1000   * @details    This function is used to set power-down mode.\r
1001   */\r
1002 void CLK_SetPowerDownMode(uint32_t u32PDMode)\r
1003 {\r
1004     CLK->PMUCTL = (CLK->PMUCTL & (~CLK_PMUCTL_PDMSEL_Msk)) | (u32PDMode);\r
1005 }\r
1006 \r
1007 /**\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
1013  * @return      None\r
1014  * @details     This function is used to enable Wake-up pin trigger type.\r
1015  */\r
1016 \r
1017 void CLK_EnableDPDWKPin(uint32_t u32TriggerType)\r
1018 {\r
1019     CLK->PMUCTL = (CLK->PMUCTL & (~CLK_PMUCTL_WKPINEN_Msk)) | (u32TriggerType);\r
1020 }\r
1021 \r
1022 /**\r
1023  * @brief       Get power manager wake up source\r
1024  * @param[in]   None\r
1025  * @return      None\r
1026  * @details     This function get power manager wake up source.\r
1027  */\r
1028 \r
1029 uint32_t CLK_GetPMUWKSrc(void)\r
1030 {\r
1031     return (CLK->PMUSTS);\r
1032 }\r
1033 \r
1034 /**\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
1044  * @return      None\r
1045  * @details     This function is used to set specified GPIO as wake up source at Standby Power-down mode.\r
1046  */\r
1047 \r
1048 void CLK_EnableSPDWKPin(uint32_t u32Port, uint32_t u32Pin, uint32_t u32TriggerType, uint32_t u32DebounceEn)\r
1049 {\r
1050     uint32_t u32TmpAddr = 0UL;\r
1051     uint32_t u32TmpVal = 0UL;\r
1052 \r
1053     /* GPx Stand-by Power-down Wake-up Pin Select */\r
1054     u32TmpAddr = (uint32_t)&CLK->PASWKCTL;\r
1055     u32TmpAddr += (0x4UL * u32Port);\r
1056 \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
1061 }\r
1062 \r
1063 /**\r
1064   * @brief      Get PLL clock frequency\r
1065   * @param      None\r
1066   * @return     PLL frequency\r
1067   * @details    This function get PLL frequency. The frequency unit is Hz.\r
1068   */\r
1069 \r
1070 __NONSECURE_ENTRY_WEAK\r
1071 uint32_t CLK_GetPLLClockFreq(void)\r
1072 {\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
1076 \r
1077     u32PllReg = CLK->PLLCTL;\r
1078 \r
1079     if(u32PllReg & (CLK_PLLCTL_PD_Msk | CLK_PLLCTL_OE_Msk))\r
1080     {\r
1081         u32PllFreq = 0UL;          /* PLL is in power down mode or fix low */\r
1082     }\r
1083     else                        /* PLL is in normal mode */\r
1084     {\r
1085 \r
1086         /* PLL source clock */\r
1087         if(u32PllReg & CLK_PLLCTL_PLLSRC_Msk)\r
1088         {\r
1089             u32FIN = __HIRC;    /* PLL source clock from HIRC */\r
1090         }\r
1091         else\r
1092         {\r
1093             u32FIN = __HXT;     /* PLL source clock from HXT */\r
1094         }\r
1095 \r
1096         /* Calculate PLL frequency */\r
1097         if(u32PllReg & CLK_PLLCTL_BP_Msk)\r
1098         {\r
1099             u32PllFreq = u32FIN;  /* PLL is in bypass mode */\r
1100         }\r
1101         else\r
1102         {\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
1107 \r
1108             /* u32FIN is shifted 2 bits to avoid overflow */\r
1109             u32PllFreq = (((u32FIN >> 2) * (u32NF << 1)) / (u32NR * u32NO) << 2);\r
1110         }\r
1111     }\r
1112 \r
1113     return u32PllFreq;\r
1114 }\r
1115 \r
1116 /**\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
1152   */\r
1153 \r
1154 __NONSECURE_ENTRY_WEAK\r
1155 uint32_t CLK_GetModuleClockSource(uint32_t u32ModuleIdx)\r
1156 {\r
1157     uint32_t u32TmpVal = 0UL, u32TmpAddr = 0UL;\r
1158     uint32_t au32SelTbl[4] = {0x0UL, 0x4UL, 0x8UL, 0xCUL};\r
1159 \r
1160     /* Get clock source selection setting */\r
1161     if(u32ModuleIdx == EPWM0_MODULE)\r
1162     {\r
1163         u32TmpVal = ((CLK->CLKSEL2 & CLK_CLKSEL2_EPWM0SEL_Msk) >> CLK_CLKSEL2_EPWM0SEL_Pos);\r
1164     }\r
1165     else if(u32ModuleIdx == EPWM1_MODULE)\r
1166     {\r
1167         u32TmpVal = ((CLK->CLKSEL2 & CLK_CLKSEL2_EPWM1SEL_Msk) >> CLK_CLKSEL2_EPWM1SEL_Pos);\r
1168     }\r
1169     else if(u32ModuleIdx == BPWM0_MODULE)\r
1170     {\r
1171         u32TmpVal = ((CLK->CLKSEL2 & CLK_CLKSEL2_BPWM0SEL_Msk) >> CLK_CLKSEL2_BPWM0SEL_Pos);\r
1172     }\r
1173     else if(u32ModuleIdx == BPWM1_MODULE)\r
1174     {\r
1175         u32TmpVal = ((CLK->CLKSEL2 & CLK_CLKSEL2_BPWM1SEL_Msk) >> CLK_CLKSEL2_BPWM1SEL_Pos);\r
1176     }\r
1177     else if(MODULE_CLKSEL_Msk(u32ModuleIdx) != MODULE_NoMsk)\r
1178     {\r
1179         /* Get clock select control register address */\r
1180         u32TmpAddr = (uint32_t)&CLK->CLKSEL0 + (au32SelTbl[MODULE_CLKSEL(u32ModuleIdx)]);\r
1181 \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
1184     }\r
1185 \r
1186     return u32TmpVal;\r
1187 }\r
1188 \r
1189 /**\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
1208   */\r
1209 \r
1210 __NONSECURE_ENTRY_WEAK\r
1211 uint32_t CLK_GetModuleClockDivider(uint32_t u32ModuleIdx)\r
1212 {\r
1213     uint32_t u32TmpVal = 0UL, u32TmpAddr = 0UL;\r
1214     uint32_t au32DivTbl[4] = {0x0UL, 0x4UL, 0x8UL, 0x10UL};\r
1215 \r
1216     if(MODULE_CLKDIV_Msk(u32ModuleIdx) != MODULE_NoMsk)\r
1217     {\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
1222     }\r
1223 \r
1224     return u32TmpVal;\r
1225 }\r
1226 \r
1227 \r
1228 /*@}*/ /* end of group CLK_EXPORTED_FUNCTIONS */\r
1229 \r
1230 /*@}*/ /* end of group CLK_Driver */\r
1231 \r
1232 /*@}*/ /* end of group Standard_Driver */\r
1233 \r
1234 /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/\r