1 /**************************************************************************//**
2  * @file     clk.c
3  * @version  V3.00
4  * @brief    M2351 series Clock Controller (CLK) driver source file
5  *
6  * @copyright SPDX-License-Identifier: Apache-2.0
7  * @copyright Copyright (C) 2016-2020 Nuvoton Technology Corp. All rights reserved.
8  *****************************************************************************/
9 #include "NuMicro.h"
10 /** @addtogroup Standard_Driver Standard Driver
11   @{
12 */
13 
14 /** @addtogroup CLK_Driver CLK Driver
15   @{
16 */
17 
18 
19 /** @addtogroup CLK_EXPORTED_FUNCTIONS CLK Exported Functions
20   @{
21 */
22 
23 
24 /**
25   * @brief      Disable frequency output function
26   * @param      None
27   * @return     None
28   * @details    This function disable frequency output function.
29   */
CLK_DisableCKO(void)30 void CLK_DisableCKO(void)
31 {
32     /* Disable CKO clock source */
33     CLK->APBCLK0 &= (~CLK_APBCLK0_CLKOCKEN_Msk);
34 }
35 
36 
37 /**
38   * @brief      This function enable frequency divider module clock.
39   *             enable frequency divider clock function and configure frequency divider.
40   * @param[in]  u32ClkSrc is frequency divider function clock source. Including :
41   *             - \ref CLK_CLKSEL1_CLKOSEL_HXT
42   *             - \ref CLK_CLKSEL1_CLKOSEL_LXT
43   *             - \ref CLK_CLKSEL1_CLKOSEL_HCLK
44   *             - \ref CLK_CLKSEL1_CLKOSEL_HIRC
45   * @param[in]  u32ClkDiv is divider output frequency selection.
46   * @param[in]  u32ClkDivBy1En is frequency divided by one enable.
47   * @return     None
48   *
49   * @details    Output selected clock to CKO. The output clock frequency is divided by u32ClkDiv.
50   *             The formula is:
51   *                 CKO frequency = (Clock source frequency) / 2^(u32ClkDiv + 1)
52   *             This function is just used to set CKO clock.
53   *             User must enable I/O for CKO clock output pin by themselves.
54   */
CLK_EnableCKO(uint32_t u32ClkSrc,uint32_t u32ClkDiv,uint32_t u32ClkDivBy1En)55 void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv, uint32_t u32ClkDivBy1En)
56 {
57     /* CKO = clock source / 2^(u32ClkDiv + 1) */
58     CLK->CLKOCTL = CLK_CLKOCTL_CLKOEN_Msk | u32ClkDiv | (u32ClkDivBy1En << CLK_CLKOCTL_DIV1EN_Pos);
59 
60     /* Enable CKO clock source */
61     CLK->APBCLK0 |= CLK_APBCLK0_CLKOCKEN_Msk;
62 
63     /* Select CKO clock source */
64     CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_CLKOSEL_Msk)) | (u32ClkSrc);
65 
66 }
67 
68 /**
69   * @brief      Enter to Power-down mode
70   * @param      None
71   * @return     None
72   * @details    This function is used to let system enter to Power-down mode. \n
73   *             The register write-protection function should be disabled before using this function.
74   */
CLK_PowerDown(void)75 void CLK_PowerDown(void)
76 {
77     /* Set the processor uses deep sleep as its low power mode */
78     SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
79 
80     /* Set system Power-down enabled*/
81     CLK->PWRCTL |= CLK_PWRCTL_PDEN_Msk;
82 
83     /* Chip enter Power-down mode after CPU run WFI instruction */
84     __WFI();
85 }
86 
87 
88 
89 /**
90   * @brief      Enter to Idle mode
91   * @param      None
92   * @return     None
93   * @details    This function let system enter to Idle mode. \n
94   *             The register write-protection function should be disabled before using this function.
95   */
CLK_Idle(void)96 void CLK_Idle(void)
97 {
98     /* Set the processor uses sleep as its low power mode */
99     SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
100 
101     /* Set chip in idle mode because of WFI command */
102     CLK->PWRCTL &= ~CLK_PWRCTL_PDEN_Msk;
103 
104     /* Chip enter idle mode after CPU run WFI instruction */
105     __WFI();
106 }
107 
108 
109 /**
110   * @brief      Get external high speed crystal clock frequency
111   * @param      None
112   * @return     External high frequency crystal frequency
113   * @details    This function get external high frequency crystal frequency. The frequency unit is Hz.
114   */
115 __NONSECURE_ENTRY_WEAK
CLK_GetHXTFreq(void)116 uint32_t CLK_GetHXTFreq(void)
117 {
118     uint32_t u32Freq = 0UL;
119     uint32_t u32HXTEN = CLK->PWRCTL & CLK_PWRCTL_HXTEN_Msk;
120 
121     if(u32HXTEN)
122     {
123         u32Freq = __HXT;
124     }
125     else
126     {
127         u32Freq = 0UL;
128     }
129 
130     return u32Freq;
131 }
132 
133 /**
134   * @brief      Get external low speed crystal clock frequency
135   * @param      None
136   * @return     External low speed crystal clock frequency
137   * @details    This function get external low frequency crystal frequency. The frequency unit is Hz.
138   */
139 
140 __NONSECURE_ENTRY_WEAK
CLK_GetLXTFreq(void)141 uint32_t CLK_GetLXTFreq(void)
142 {
143     uint32_t u32Freq = 0UL;
144     uint32_t u32LXTEN = CLK->PWRCTL & CLK_PWRCTL_LXTEN_Msk;
145 
146     if(u32LXTEN)
147     {
148         u32Freq = __LXT;
149     }
150     else
151     {
152         u32Freq = 0UL;
153     }
154 
155     return u32Freq;
156 }
157 
158 /**
159   * @brief      Get HCLK frequency
160   * @param      None
161   * @return     HCLK frequency
162   * @details    This function get HCLK frequency. The frequency unit is Hz.
163   */
164 
165 __NONSECURE_ENTRY_WEAK
CLK_GetHCLKFreq(void)166 uint32_t CLK_GetHCLKFreq(void)
167 {
168     SystemCoreClockUpdate();
169     return SystemCoreClock;
170 }
171 
172 /**
173   * @brief      Get PCLK0 frequency
174   * @param      None
175   * @return     PCLK0 frequency
176   * @details    This function get PCLK0 frequency. The frequency unit is Hz.
177   */
178 
179 __NONSECURE_ENTRY_WEAK
CLK_GetPCLK0Freq(void)180 uint32_t CLK_GetPCLK0Freq(void)
181 {
182     SystemCoreClockUpdate();
183     return (SystemCoreClock >> ((CLK->PCLKDIV & CLK_PCLKDIV_APB0DIV_Msk) >> CLK_PCLKDIV_APB0DIV_Pos));
184 }
185 
186 /**
187   * @brief      Get PCLK1 frequency
188   * @param      None
189   * @return     PCLK1 frequency
190   * @details    This function get PCLK1 frequency. The frequency unit is Hz.
191   */
192 
193 __NONSECURE_ENTRY_WEAK
CLK_GetPCLK1Freq(void)194 uint32_t CLK_GetPCLK1Freq(void)
195 {
196     SystemCoreClockUpdate();
197     return (SystemCoreClock >> ((CLK->PCLKDIV & CLK_PCLKDIV_APB1DIV_Msk) >> CLK_PCLKDIV_APB1DIV_Pos));
198 }
199 
200 /**
201   * @brief      Get CPU frequency
202   * @param      None
203   * @return     CPU frequency
204   * @details    This function get CPU frequency. The frequency unit is Hz.
205   */
206 
207 __NONSECURE_ENTRY_WEAK
CLK_GetCPUFreq(void)208 uint32_t CLK_GetCPUFreq(void)
209 {
210     uint32_t u32Freq, u32HclkSrc, u32HclkDiv;
211     uint32_t au32ClkTbl[] = {__HXT, __LXT, 0UL, __LIRC, 0UL, __HIRC48, 0UL, __HIRC};
212     uint32_t u32PllReg, u32FIN, u32NF, u32NR, u32NO;
213     uint8_t au8NoTbl[4] = {1U, 2U, 2U, 4U};
214     uint32_t u32RTCCKEN = CLK->APBCLK0 & CLK_APBCLK0_RTCCKEN_Msk;
215 
216     /* Update PLL Clock */
217     u32PllReg = CLK->PLLCTL;
218 
219     if(u32PllReg & (CLK_PLLCTL_PD_Msk | CLK_PLLCTL_OE_Msk))
220     {
221         PllClock = 0UL;           /* PLL is in power down mode or fix low */
222     }
223     else                        /* PLL is in normal mode */
224     {
225 
226         /* PLL source clock */
227         if(u32PllReg & CLK_PLLCTL_PLLSRC_Msk)
228         {
229             u32FIN = __HIRC;    /* PLL source clock from HIRC */
230         }
231         else
232         {
233             u32FIN = __HXT;     /* PLL source clock from HXT */
234         }
235 
236         /* Calculate PLL frequency */
237         if(u32PllReg & CLK_PLLCTL_BP_Msk)
238         {
239             PllClock = u32FIN;  /* PLL is in bypass mode */
240         }
241         else
242         {
243             /* PLL is output enabled in normal work mode */
244             u32NO = au8NoTbl[((u32PllReg & CLK_PLLCTL_OUTDIV_Msk) >> CLK_PLLCTL_OUTDIV_Pos)];
245             u32NF = ((u32PllReg & CLK_PLLCTL_FBDIV_Msk) >> CLK_PLLCTL_FBDIV_Pos) + 2UL;
246             u32NR = ((u32PllReg & CLK_PLLCTL_INDIV_Msk) >> CLK_PLLCTL_INDIV_Pos) + 1UL;
247 
248             /* u32FIN is shifted 2 bits to avoid overflow */
249             PllClock = (((u32FIN >> 2) * (u32NF << 1)) / (u32NR * u32NO) << 2);
250         }
251     }
252 
253     /* HCLK clock source */
254     u32HclkSrc = CLK->CLKSEL0 & CLK_CLKSEL0_HCLKSEL_Msk;
255 
256     if(u32HclkSrc == CLK_CLKSEL0_HCLKSEL_LXT)
257     {
258 
259         if(u32RTCCKEN == 0UL)
260         {
261             CLK->APBCLK0 |= CLK_APBCLK0_RTCCKEN_Msk; /* Enable RTC clock to get LXT clock source */
262         }
263 
264         if(RTC->LXTCTL & RTC_LXTCTL_C32KS_Msk)
265         {
266             u32Freq = __LIRC32; /* LXT clock source is LIRC32 */
267         }
268         else
269         {
270             u32Freq = __LXT;    /* LXT clock source is external LXT */
271         }
272 
273         if(u32RTCCKEN == 0UL)
274         {
275             CLK->APBCLK0 &= (~CLK_APBCLK0_RTCCKEN_Msk); /* Disable RTC clock if it is disabled before */
276         }
277 
278     }
279     else if(u32HclkSrc == CLK_CLKSEL0_HCLKSEL_PLL)
280     {
281         u32Freq = PllClock;/* Use PLL clock */
282     }
283     else
284     {
285         u32Freq = au32ClkTbl[u32HclkSrc]; /* Use the clock sources directly */
286     }
287 
288     /* HCLK clock source divider */
289     u32HclkDiv = (CLK->CLKDIV0 & CLK_CLKDIV0_HCLKDIV_Msk) + 1UL;
290 
291     /* Update System Core Clock */
292     SystemCoreClock = u32Freq / u32HclkDiv;
293 
294     /* Update Cycles per micro second */
295     CyclesPerUs = (SystemCoreClock + 500000UL) / 1000000UL;
296 
297     return SystemCoreClock;
298 }
299 
300 /**
301   * @brief      Set HCLK frequency
302   * @param[in]  u32Hclk is HCLK frequency.
303   *             The range of u32Hclk is 24 MHz ~ 64 MHz if power level is PL0.
304   *             The range of u32Hclk is 24 MHz ~ 48 MHz if power level is PL1.
305   * @return     HCLK frequency
306   * @details    This function is used to set HCLK frequency. The frequency unit is Hz. \n
307   *             The register write-protection function should be disabled before using this function.
308   */
CLK_SetCoreClock(uint32_t u32Hclk)309 uint32_t CLK_SetCoreClock(uint32_t u32Hclk)
310 {
311     uint32_t u32HIRCSTB, u32PLSTATUS;
312 
313     /* Read HIRC clock source stable flag */
314     u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;
315 
316     /* Read power level status */
317     u32PLSTATUS = SYS->PLSTS & SYS_PLSTS_PLSTATUS_Msk;
318 
319     /* Check HCLK frequency range */
320     if((u32PLSTATUS == SYS_PLSTS_PLSTATUS_PL0) && (u32Hclk > FREQ_64MHZ))
321     {
322         u32Hclk = FREQ_64MHZ;
323     }
324     else if((u32PLSTATUS == SYS_PLSTS_PLSTATUS_PL1) && (u32Hclk > FREQ_48MHZ))
325     {
326         u32Hclk = FREQ_48MHZ;
327     }
328     else if(u32Hclk < FREQ_24MHZ)
329     {
330         u32Hclk = FREQ_24MHZ;
331     }
332 
333     /* Switch HCLK clock source to HIRC clock for safe */
334     CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
335     CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
336     CLK->CLKSEL0 |= CLK_CLKSEL0_HCLKSEL_Msk;
337     CLK->CLKDIV0 &= (~CLK_CLKDIV0_HCLKDIV_Msk);
338 
339     /* Enable Flash access cycle auto-tuning function */
340     FMC->CYCCTL &= (~FMC_CYCCTL_FADIS_Msk);
341 
342     /* Configure PLL setting if HXT clock is stable */
343     if(CLK->STATUS & CLK_STATUS_HXTSTB_Msk)
344     {
345         u32Hclk = CLK_EnablePLL(CLK_PLLCTL_PLLSRC_HXT, u32Hclk);
346     }
347     /* Configure PLL setting if HXT clock is not stable */
348     else
349     {
350         u32Hclk = CLK_EnablePLL(CLK_PLLCTL_PLLSRC_HIRC, u32Hclk);
351 
352         /* Read HIRC clock source stable flag */
353         u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;
354     }
355 
356     /* Select HCLK clock source to PLL,
357        Select HCLK clock source divider as 1
358        and update system core clock
359     */
360     CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL, CLK_CLKDIV0_HCLK(1UL));
361 
362     /* Disable HIRC if HIRC is disabled before setting core clock */
363     if(u32HIRCSTB == 0UL)
364     {
365         CLK->PWRCTL &= ~CLK_PWRCTL_HIRCEN_Msk;
366     }
367 
368     /* Return actually HCLK frequency is PLL frequency divide 1 */
369     return u32Hclk;
370 }
371 
372 
373 /**
374   * @brief      Set HCLK clock source and HCLK clock divider
375   * @param[in]  u32ClkSrc is HCLK clock source. Including :
376   *             - \ref CLK_CLKSEL0_HCLKSEL_HXT
377   *             - \ref CLK_CLKSEL0_HCLKSEL_LXT
378   *             - \ref CLK_CLKSEL0_HCLKSEL_PLL
379   *             - \ref CLK_CLKSEL0_HCLKSEL_LIRC
380   *             - \ref CLK_CLKSEL0_HCLKSEL_HIRC48
381   *             - \ref CLK_CLKSEL0_HCLKSEL_HIRC
382   * @param[in]  u32ClkDiv is HCLK clock divider. Including :
383   *             - \ref CLK_CLKDIV0_HCLK(x)
384   * @return     None
385   * @details    This function set HCLK clock source and HCLK clock divider.
386   *             The register write-protection function should be disabled before using this function.
387   */
CLK_SetHCLK(uint32_t u32ClkSrc,uint32_t u32ClkDiv)388 void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
389 {
390     uint32_t u32HIRCSTB;
391 
392     /* Read HIRC clock source stable flag */
393     u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;
394 
395     /* Switch to HIRC for Safe. Avoid HCLK too high when applying new divider. */
396     CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
397     CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
398     CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | CLK_CLKSEL0_HCLKSEL_HIRC;
399 
400     /* Enable Flash access cycle auto-tuning function */
401     FMC->CYCCTL &= (~FMC_CYCCTL_FADIS_Msk);
402 
403     /* Apply new Divider */
404     CLK->CLKDIV0 = (CLK->CLKDIV0 & (~CLK_CLKDIV0_HCLKDIV_Msk)) | u32ClkDiv;
405 
406     /* Disable Flash access cycle auto-tuning function and set Flash access cycle if HCLK switches to HIRC48 */
407     if(u32ClkSrc == CLK_CLKSEL0_HCLKSEL_HIRC48)
408     {
409         FMC->CYCCTL = (FMC->CYCCTL & (~FMC_CYCCTL_CYCLE_Msk)) | FMC_CYCCTL_FADIS_Msk | (3UL);
410     }
411 
412     /* Switch HCLK to new HCLK source */
413     CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | u32ClkSrc;
414 
415     /* Update System Core Clock */
416     SystemCoreClockUpdate();
417 
418     /* Disable HIRC if HIRC is disabled before switching HCLK source */
419     if(u32HIRCSTB == 0UL)
420     {
421         CLK->PWRCTL &= ~CLK_PWRCTL_HIRCEN_Msk;
422     }
423 }
424 /**
425   * @brief      This function set selected module clock source and module clock divider
426   * @param[in]  u32ModuleIdx is module index.
427   * @param[in]  u32ClkSrc is module clock source.
428   * @param[in]  u32ClkDiv is module clock divider.
429   * @return     None
430   * @details    Valid parameter combinations listed in following table:
431   *
432   * |Module index        |Clock source                          |Divider                   |
433   * | :----------------  | :----------------------------------- | :----------------------- |
434   * |\ref SDH0_MODULE    |\ref CLK_CLKSEL0_SDH0SEL_HXT          |\ref CLK_CLKDIV0_SDH0(x)  |
435   * |\ref SDH0_MODULE    |\ref CLK_CLKSEL0_SDH0SEL_PLL          |\ref CLK_CLKDIV0_SDH0(x)  |
436   * |\ref SDH0_MODULE    |\ref CLK_CLKSEL0_SDH0SEL_HCLK         |\ref CLK_CLKDIV0_SDH0(x)  |
437   * |\ref SDH0_MODULE    |\ref CLK_CLKSEL0_SDH0SEL_HIRC         |\ref CLK_CLKDIV0_SDH0(x)  |
438   * |\ref WDT_MODULE     |\ref CLK_CLKSEL1_WDTSEL_LXT           | x                        |
439   * |\ref WDT_MODULE     |\ref CLK_CLKSEL1_WDTSEL_HCLK_DIV2048  | x                        |
440   * |\ref WDT_MODULE     |\ref CLK_CLKSEL1_WDTSEL_LIRC          | x                        |
441   * |\ref EADC_MODULE    | x                                    |\ref CLK_CLKDIV0_EADC(x)  |
442   * |\ref TMR0_MODULE    |\ref CLK_CLKSEL1_TMR0SEL_HXT          | x                        |
443   * |\ref TMR0_MODULE    |\ref CLK_CLKSEL1_TMR0SEL_LXT          | x                        |
444   * |\ref TMR0_MODULE    |\ref CLK_CLKSEL1_TMR0SEL_PCLK0        | x                        |
445   * |\ref TMR0_MODULE    |\ref CLK_CLKSEL1_TMR0SEL_EXT_TRG      | x                        |
446   * |\ref TMR0_MODULE    |\ref CLK_CLKSEL1_TMR0SEL_LIRC         | x                        |
447   * |\ref TMR0_MODULE    |\ref CLK_CLKSEL1_TMR0SEL_HIRC         | x                        |
448   * |\ref TMR1_MODULE    |\ref CLK_CLKSEL1_TMR1SEL_HXT          | x                        |
449   * |\ref TMR1_MODULE    |\ref CLK_CLKSEL1_TMR1SEL_LXT          | x                        |
450   * |\ref TMR1_MODULE    |\ref CLK_CLKSEL1_TMR1SEL_PCLK0        | x                        |
451   * |\ref TMR1_MODULE    |\ref CLK_CLKSEL1_TMR1SEL_EXT_TRG      | x                        |
452   * |\ref TMR1_MODULE    |\ref CLK_CLKSEL1_TMR1SEL_LIRC         | x                        |
453   * |\ref TMR1_MODULE    |\ref CLK_CLKSEL1_TMR1SEL_HIRC         | x                        |
454   * |\ref TMR2_MODULE    |\ref CLK_CLKSEL1_TMR2SEL_HXT          | x                        |
455   * |\ref TMR2_MODULE    |\ref CLK_CLKSEL1_TMR2SEL_LXT          | x                        |
456   * |\ref TMR2_MODULE    |\ref CLK_CLKSEL1_TMR2SEL_PCLK1        | x                        |
457   * |\ref TMR2_MODULE    |\ref CLK_CLKSEL1_TMR2SEL_EXT_TRG      | x                        |
458   * |\ref TMR2_MODULE    |\ref CLK_CLKSEL1_TMR2SEL_LIRC         | x                        |
459   * |\ref TMR2_MODULE    |\ref CLK_CLKSEL1_TMR2SEL_HIRC         | x                        |
460   * |\ref TMR3_MODULE    |\ref CLK_CLKSEL1_TMR3SEL_HXT          | x                        |
461   * |\ref TMR3_MODULE    |\ref CLK_CLKSEL1_TMR3SEL_LXT          | x                        |
462   * |\ref TMR3_MODULE    |\ref CLK_CLKSEL1_TMR3SEL_PCLK1        | x                        |
463   * |\ref TMR3_MODULE    |\ref CLK_CLKSEL1_TMR3SEL_EXT_TRG      | x                        |
464   * |\ref TMR3_MODULE    |\ref CLK_CLKSEL1_TMR3SEL_LIRC         | x                        |
465   * |\ref TMR3_MODULE    |\ref CLK_CLKSEL1_TMR3SEL_HIRC         | x                        |
466   * |\ref UART0_MODULE   |\ref CLK_CLKSEL1_UART0SEL_HXT         |\ref CLK_CLKDIV0_UART0(x) |
467   * |\ref UART0_MODULE   |\ref CLK_CLKSEL1_UART0SEL_PLL         |\ref CLK_CLKDIV0_UART0(x) |
468   * |\ref UART0_MODULE   |\ref CLK_CLKSEL1_UART0SEL_LXT         |\ref CLK_CLKDIV0_UART0(x) |
469   * |\ref UART0_MODULE   |\ref CLK_CLKSEL1_UART0SEL_HIRC        |\ref CLK_CLKDIV0_UART0(x) |
470   * |\ref UART1_MODULE   |\ref CLK_CLKSEL1_UART1SEL_HXT         |\ref CLK_CLKDIV0_UART1(x) |
471   * |\ref UART1_MODULE   |\ref CLK_CLKSEL1_UART1SEL_PLL         |\ref CLK_CLKDIV0_UART1(x) |
472   * |\ref UART1_MODULE   |\ref CLK_CLKSEL1_UART1SEL_LXT         |\ref CLK_CLKDIV0_UART1(x) |
473   * |\ref UART1_MODULE   |\ref CLK_CLKSEL1_UART1SEL_HIRC        |\ref CLK_CLKDIV0_UART1(x) |
474   * |\ref UART2_MODULE   |\ref CLK_CLKSEL3_UART2SEL_HXT         |\ref CLK_CLKDIV4_UART2(x) |
475   * |\ref UART2_MODULE   |\ref CLK_CLKSEL3_UART2SEL_PLL         |\ref CLK_CLKDIV4_UART2(x) |
476   * |\ref UART2_MODULE   |\ref CLK_CLKSEL3_UART2SEL_LXT         |\ref CLK_CLKDIV4_UART2(x) |
477   * |\ref UART2_MODULE   |\ref CLK_CLKSEL3_UART2SEL_HIRC        |\ref CLK_CLKDIV4_UART2(x) |
478   * |\ref UART3_MODULE   |\ref CLK_CLKSEL3_UART3SEL_HXT         |\ref CLK_CLKDIV4_UART3(x) |
479   * |\ref UART3_MODULE   |\ref CLK_CLKSEL3_UART3SEL_PLL         |\ref CLK_CLKDIV4_UART3(x) |
480   * |\ref UART3_MODULE   |\ref CLK_CLKSEL3_UART3SEL_LXT         |\ref CLK_CLKDIV4_UART3(x) |
481   * |\ref UART3_MODULE   |\ref CLK_CLKSEL3_UART3SEL_HIRC        |\ref CLK_CLKDIV4_UART3(x) |
482   * |\ref UART4_MODULE   |\ref CLK_CLKSEL3_UART4SEL_HXT         |\ref CLK_CLKDIV4_UART4(x) |
483   * |\ref UART4_MODULE   |\ref CLK_CLKSEL3_UART4SEL_PLL         |\ref CLK_CLKDIV4_UART4(x) |
484   * |\ref UART4_MODULE   |\ref CLK_CLKSEL3_UART4SEL_LXT         |\ref CLK_CLKDIV4_UART4(x) |
485   * |\ref UART4_MODULE   |\ref CLK_CLKSEL3_UART4SEL_HIRC        |\ref CLK_CLKDIV4_UART4(x) |
486   * |\ref UART5_MODULE   |\ref CLK_CLKSEL3_UART5SEL_HXT         |\ref CLK_CLKDIV4_UART5(x) |
487   * |\ref UART5_MODULE   |\ref CLK_CLKSEL3_UART5SEL_PLL         |\ref CLK_CLKDIV4_UART5(x) |
488   * |\ref UART5_MODULE   |\ref CLK_CLKSEL3_UART5SEL_LXT         |\ref CLK_CLKDIV4_UART5(x) |
489   * |\ref UART5_MODULE   |\ref CLK_CLKSEL3_UART5SEL_HIRC        |\ref CLK_CLKDIV4_UART5(x) |
490   * |\ref CLKO_MODULE    |\ref CLK_CLKSEL1_CLKOSEL_HXT          | x                        |
491   * |\ref CLKO_MODULE    |\ref CLK_CLKSEL1_CLKOSEL_LXT          | x                        |
492   * |\ref CLKO_MODULE    |\ref CLK_CLKSEL1_CLKOSEL_HCLK         | x                        |
493   * |\ref CLKO_MODULE    |\ref CLK_CLKSEL1_CLKOSEL_HIRC         | x                        |
494   * |\ref WWDT_MODULE    |\ref CLK_CLKSEL1_WWDTSEL_HCLK_DIV2048 | x                        |
495   * |\ref WWDT_MODULE    |\ref CLK_CLKSEL1_WWDTSEL_LIRC         | x                        |
496   * |\ref RTC_MODULE     |\ref CLK_CLKSEL3_RTCSEL_LXT           | x                        |
497   * |\ref RTC_MODULE     |\ref CLK_CLKSEL3_RTCSEL_LIRC          | x                        |
498   * |\ref I2S0_MODULE    |\ref CLK_CLKSEL3_I2S0SEL_HXT          | x                        |
499   * |\ref I2S0_MODULE    |\ref CLK_CLKSEL3_I2S0SEL_PLL          | x                        |
500   * |\ref I2S0_MODULE    |\ref CLK_CLKSEL3_I2S0SEL_PCLK0        | x                        |
501   * |\ref I2S0_MODULE    |\ref CLK_CLKSEL3_I2S0SEL_HIRC         | x                        |
502   * |\ref QSPI0_MODULE   |\ref CLK_CLKSEL2_QSPI0SEL_HXT         | x                        |
503   * |\ref QSPI0_MODULE   |\ref CLK_CLKSEL2_QSPI0SEL_PLL         | x                        |
504   * |\ref QSPI0_MODULE   |\ref CLK_CLKSEL2_QSPI0SEL_PCLK0       | x                        |
505   * |\ref QSPI0_MODULE   |\ref CLK_CLKSEL2_QSPI0SEL_HIRC        | x                        |
506   * |\ref SPI0_MODULE    |\ref CLK_CLKSEL2_SPI0SEL_HXT          | x                        |
507   * |\ref SPI0_MODULE    |\ref CLK_CLKSEL2_SPI0SEL_PLL          | x                        |
508   * |\ref SPI0_MODULE    |\ref CLK_CLKSEL2_SPI0SEL_PCLK1        | x                        |
509   * |\ref SPI0_MODULE    |\ref CLK_CLKSEL2_SPI0SEL_HIRC         | x                        |
510   * |\ref SPI1_MODULE    |\ref CLK_CLKSEL2_SPI1SEL_HXT          | x                        |
511   * |\ref SPI1_MODULE    |\ref CLK_CLKSEL2_SPI1SEL_PLL          | x                        |
512   * |\ref SPI1_MODULE    |\ref CLK_CLKSEL2_SPI1SEL_PCLK0        | x                        |
513   * |\ref SPI1_MODULE    |\ref CLK_CLKSEL2_SPI1SEL_HIRC         | x                        |
514   * |\ref SPI2_MODULE    |\ref CLK_CLKSEL2_SPI2SEL_HXT          | x                        |
515   * |\ref SPI2_MODULE    |\ref CLK_CLKSEL2_SPI2SEL_PLL          | x                        |
516   * |\ref SPI2_MODULE    |\ref CLK_CLKSEL2_SPI2SEL_PCLK1        | x                        |
517   * |\ref SPI2_MODULE    |\ref CLK_CLKSEL2_SPI2SEL_HIRC         | x                        |
518   * |\ref SPI3_MODULE    |\ref CLK_CLKSEL2_SPI3SEL_HXT          | x                        |
519   * |\ref SPI3_MODULE    |\ref CLK_CLKSEL2_SPI3SEL_PLL          | x                        |
520   * |\ref SPI3_MODULE    |\ref CLK_CLKSEL2_SPI3SEL_PCLK0        | x                        |
521   * |\ref SPI3_MODULE    |\ref CLK_CLKSEL2_SPI3SEL_HIRC         | x                        |
522   * |\ref SC0_MODULE     |\ref CLK_CLKSEL3_SC0SEL_HXT           |\ref CLK_CLKDIV1_SC0(x)   |
523   * |\ref SC0_MODULE     |\ref CLK_CLKSEL3_SC0SEL_PLL           |\ref CLK_CLKDIV1_SC0(x)   |
524   * |\ref SC0_MODULE     |\ref CLK_CLKSEL3_SC0SEL_PCLK0         |\ref CLK_CLKDIV1_SC0(x)   |
525   * |\ref SC0_MODULE     |\ref CLK_CLKSEL3_SC0SEL_HIRC          |\ref CLK_CLKDIV1_SC0(x)   |
526   * |\ref SC1_MODULE     |\ref CLK_CLKSEL3_SC1SEL_HXT           |\ref CLK_CLKDIV1_SC1(x)   |
527   * |\ref SC1_MODULE     |\ref CLK_CLKSEL3_SC1SEL_PLL           |\ref CLK_CLKDIV1_SC1(x)   |
528   * |\ref SC1_MODULE     |\ref CLK_CLKSEL3_SC1SEL_PCLK1         |\ref CLK_CLKDIV1_SC1(x)   |
529   * |\ref SC1_MODULE     |\ref CLK_CLKSEL3_SC1SEL_HIRC          |\ref CLK_CLKDIV1_SC1(x)   |
530   * |\ref SC2_MODULE     |\ref CLK_CLKSEL3_SC2SEL_HXT           |\ref CLK_CLKDIV1_SC2(x)   |
531   * |\ref SC2_MODULE     |\ref CLK_CLKSEL3_SC2SEL_PLL           |\ref CLK_CLKDIV1_SC2(x)   |
532   * |\ref SC2_MODULE     |\ref CLK_CLKSEL3_SC2SEL_PCLK0         |\ref CLK_CLKDIV1_SC2(x)   |
533   * |\ref SC2_MODULE     |\ref CLK_CLKSEL3_SC2SEL_HIRC          |\ref CLK_CLKDIV1_SC2(x)   |
534   * |\ref USBH_MODULE    |\ref CLK_CLKSEL0_USBSEL_HIRC48        |\ref CLK_CLKDIV0_USB(x)   |
535   * |\ref USBH_MODULE    |\ref CLK_CLKSEL0_USBSEL_PLL           |\ref CLK_CLKDIV0_USB(x)   |
536   * |\ref OTG_MODULE     |\ref CLK_CLKSEL0_USBSEL_HIRC48        |\ref CLK_CLKDIV0_USB(x)   |
537   * |\ref OTG_MODULE     |\ref CLK_CLKSEL0_USBSEL_PLL           |\ref CLK_CLKDIV0_USB(x)   |
538   * |\ref USBD_MODULE    |\ref CLK_CLKSEL0_USBSEL_HIRC48        |\ref CLK_CLKDIV0_USB(x)   |
539   * |\ref USBD_MODULE    |\ref CLK_CLKSEL0_USBSEL_PLL           |\ref CLK_CLKDIV0_USB(x)   |
540   */
CLK_SetModuleClock(uint32_t u32ModuleIdx,uint32_t u32ClkSrc,uint32_t u32ClkDiv)541 void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv)
542 {
543     uint32_t u32Sel = 0UL, u32Div = 0UL;
544     uint32_t au32SelTbl[4] = {0x0UL, 0x4UL, 0x8UL, 0xCUL};
545     uint32_t au32DivTbl[4] = {0x0UL, 0x4UL, 0x8UL, 0x10UL};
546 
547     if(MODULE_CLKDIV_Msk(u32ModuleIdx) != MODULE_NoMsk)
548     {
549         /* Get clock divider control register address */
550         u32Div = (uint32_t)&CLK->CLKDIV0 + (au32DivTbl[MODULE_CLKDIV(u32ModuleIdx)]);
551         /* Apply new divider */
552         M32(u32Div) = (M32(u32Div) & (~(MODULE_CLKDIV_Msk(u32ModuleIdx) << MODULE_CLKDIV_Pos(u32ModuleIdx)))) | u32ClkDiv;
553     }
554 
555     if(MODULE_CLKSEL_Msk(u32ModuleIdx) != MODULE_NoMsk)
556     {
557         /* Get clock select control register address */
558         u32Sel = (uint32_t)&CLK->CLKSEL0 + (au32SelTbl[MODULE_CLKSEL(u32ModuleIdx)]);
559         /* Set new clock selection setting */
560         M32(u32Sel) = (M32(u32Sel) & (~(MODULE_CLKSEL_Msk(u32ModuleIdx) << MODULE_CLKSEL_Pos(u32ModuleIdx)))) | u32ClkSrc;
561     }
562 }
563 
564 /**
565   * @brief      Set SysTick clock source
566   * @param[in]  u32ClkSrc is module clock source. Including:
567   *             - \ref CLK_CLKSEL0_STCLKSEL_HXT
568   *             - \ref CLK_CLKSEL0_STCLKSEL_LXT
569   *             - \ref CLK_CLKSEL0_STCLKSEL_HXT_DIV2
570   *             - \ref CLK_CLKSEL0_STCLKSEL_HCLK_DIV2
571   *             - \ref CLK_CLKSEL0_STCLKSEL_HIRC_DIV2
572   * @return     None
573   * @details    This function set SysTick clock source. \n
574   *             The register write-protection function should be disabled before using this function.
575   */
CLK_SetSysTickClockSrc(uint32_t u32ClkSrc)576 void CLK_SetSysTickClockSrc(uint32_t u32ClkSrc)
577 {
578     CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc;
579 }
580 
581 /**
582   * @brief      Enable clock source
583   * @param[in]  u32ClkMask is clock source mask. Including :
584   *             - \ref CLK_PWRCTL_HXTEN_Msk
585   *             - \ref CLK_PWRCTL_LXTEN_Msk
586   *             - \ref CLK_PWRCTL_HIRCEN_Msk
587   *             - \ref CLK_PWRCTL_LIRCEN_Msk
588   *             - \ref CLK_PWRCTL_HIRC48EN_Msk
589   * @return     None
590   * @details    This function enable clock source. \n
591   *             The register write-protection function should be disabled before using this function.
592   */
CLK_EnableXtalRC(uint32_t u32ClkMask)593 void CLK_EnableXtalRC(uint32_t u32ClkMask)
594 {
595     CLK->PWRCTL |= u32ClkMask;
596 }
597 
598 /**
599   * @brief      Disable clock source
600   * @param[in]  u32ClkMask is clock source mask. Including :
601   *             - \ref CLK_PWRCTL_HXTEN_Msk
602   *             - \ref CLK_PWRCTL_LXTEN_Msk
603   *             - \ref CLK_PWRCTL_HIRCEN_Msk
604   *             - \ref CLK_PWRCTL_LIRCEN_Msk
605   *             - \ref CLK_PWRCTL_HIRC48EN_Msk
606   * @return     None
607   * @details    This function disable clock source. \n
608   *             The register write-protection function should be disabled before using this function.
609   */
CLK_DisableXtalRC(uint32_t u32ClkMask)610 void CLK_DisableXtalRC(uint32_t u32ClkMask)
611 {
612     CLK->PWRCTL &= ~u32ClkMask;
613 }
614 
615 /**
616   * @brief      This function enable module clock
617   * @param[in]  u32ModuleIdx is module index. Including :
618   *             - \ref PDMA0_MODULE
619   *             - \ref PDMA1_MODULE
620   *             - \ref ISP_MODULE
621   *             - \ref EBI_MODULE
622   *             - \ref SDH0_MODULE
623   *             - \ref CRC_MODULE
624   *             - \ref CRPT_MODULE
625   *             - \ref FMCIDLE_MODULE
626   *             - \ref USBH_MODULE
627   *             - \ref WDT_MODULE
628   *             - \ref WWDT_MODULE
629   *             - \ref RTC_MODULE
630   *             - \ref TMR0_MODULE
631   *             - \ref TMR1_MODULE
632   *             - \ref TMR2_MODULE
633   *             - \ref TMR3_MODULE
634   *             - \ref CLKO_MODULE
635   *             - \ref ACMP01_MODULE
636   *             - \ref I2C0_MODULE
637   *             - \ref I2C1_MODULE
638   *             - \ref I2C2_MODULE
639   *             - \ref QSPI0_MODULE
640   *             - \ref SPI0_MODULE
641   *             - \ref SPI1_MODULE
642   *             - \ref SPI2_MODULE
643   *             - \ref SPI3_MODULE
644   *             - \ref UART0_MODULE
645   *             - \ref UART1_MODULE
646   *             - \ref UART2_MODULE
647   *             - \ref UART3_MODULE
648   *             - \ref UART4_MODULE
649   *             - \ref UART5_MODULE
650   *             - \ref CAN0_MODULE
651   *             - \ref OTG_MODULE
652   *             - \ref USBD_MODULE
653   *             - \ref EADC_MODULE
654   *             - \ref I2S0_MODULE
655   *             - \ref SC0_MODULE
656   *             - \ref SC1_MODULE
657   *             - \ref SC2_MODULE
658   *             - \ref USCI0_MODULE
659   *             - \ref USCI1_MODULE
660   *             - \ref DAC_MODULE
661   *             - \ref EPWM0_MODULE
662   *             - \ref EPWM1_MODULE
663   *             - \ref BPWM0_MODULE
664   *             - \ref BPWM1_MODULE
665   *             - \ref QEI0_MODULE
666   *             - \ref QEI1_MODULE
667   *             - \ref QEI0_MODULE
668   *             - \ref TRNG_MODULE
669   *             - \ref ECAP0_MODULE
670   *             - \ref ECAP1_MODULE
671   * @return     None
672   * @details    This function enable module clock.
673   */
CLK_EnableModuleClock(uint32_t u32ModuleIdx)674 void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
675 {
676     uint32_t u32TmpVal = 0UL, u32TmpAddr = 0UL;
677 
678     u32TmpVal = (1UL << MODULE_IP_EN_Pos(u32ModuleIdx));
679     u32TmpAddr = (uint32_t)&CLK->AHBCLK;
680     u32TmpAddr += ((MODULE_APBCLK(u32ModuleIdx) * 4UL));
681 
682     *(volatile uint32_t *)u32TmpAddr |= u32TmpVal;
683 }
684 
685 /**
686   * @brief      This function disable module clock
687   * @param[in]  u32ModuleIdx is module index
688   *             - \ref PDMA0_MODULE
689   *             - \ref PDMA1_MODULE
690   *             - \ref ISP_MODULE
691   *             - \ref EBI_MODULE
692   *             - \ref SDH0_MODULE
693   *             - \ref CRC_MODULE
694   *             - \ref CRPT_MODULE
695   *             - \ref FMCIDLE_MODULE
696   *             - \ref USBH_MODULE
697   *             - \ref WDT_MODULE
698   *             - \ref WWDT_MODULE
699   *             - \ref RTC_MODULE
700   *             - \ref TMR0_MODULE
701   *             - \ref TMR1_MODULE
702   *             - \ref TMR2_MODULE
703   *             - \ref TMR3_MODULE
704   *             - \ref CLKO_MODULE
705   *             - \ref ACMP01_MODULE
706   *             - \ref I2C0_MODULE
707   *             - \ref I2C1_MODULE
708   *             - \ref I2C2_MODULE
709   *             - \ref QSPI0_MODULE
710   *             - \ref SPI0_MODULE
711   *             - \ref SPI1_MODULE
712   *             - \ref SPI2_MODULE
713   *             - \ref SPI3_MODULE
714   *             - \ref UART0_MODULE
715   *             - \ref UART1_MODULE
716   *             - \ref UART2_MODULE
717   *             - \ref UART3_MODULE
718   *             - \ref UART4_MODULE
719   *             - \ref UART5_MODULE
720   *             - \ref CAN0_MODULE
721   *             - \ref OTG_MODULE
722   *             - \ref USBD_MODULE
723   *             - \ref EADC_MODULE
724   *             - \ref I2S0_MODULE
725   *             - \ref SC0_MODULE
726   *             - \ref SC1_MODULE
727   *             - \ref SC2_MODULE
728   *             - \ref USCI0_MODULE
729   *             - \ref USCI1_MODULE
730   *             - \ref DAC_MODULE
731   *             - \ref EPWM0_MODULE
732   *             - \ref EPWM1_MODULE
733   *             - \ref BPWM0_MODULE
734   *             - \ref BPWM1_MODULE
735   *             - \ref QEI0_MODULE
736   *             - \ref QEI1_MODULE
737   *             - \ref QEI0_MODULE
738   *             - \ref TRNG_MODULE
739   *             - \ref ECAP0_MODULE
740   *             - \ref ECAP1_MODULE
741   * @return     None
742   * @details    This function disable module clock.
743   */
CLK_DisableModuleClock(uint32_t u32ModuleIdx)744 void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
745 {
746     uint32_t u32TmpVal = 0UL, u32TmpAddr = 0UL;
747 
748     u32TmpVal = ~(1UL << MODULE_IP_EN_Pos(u32ModuleIdx));
749     u32TmpAddr = (uint32_t)&CLK->AHBCLK;
750     u32TmpAddr += ((MODULE_APBCLK(u32ModuleIdx) * 4UL));
751 
752     *(uint32_t *)u32TmpAddr &= u32TmpVal;
753 }
754 
755 
756 /**
757   * @brief      Set PLL frequency
758   * @param[in]  u32PllClkSrc is PLL clock source. Including :
759   *             - \ref CLK_PLLCTL_PLLSRC_HXT
760   *             - \ref CLK_PLLCTL_PLLSRC_HIRC
761   * @param[in]  u32PllFreq is PLL frequency. The range of u32PllFreq is 24 MHz ~ 144 MHz.
762   * @return     PLL frequency
763   * @details    This function is used to configure PLLCTL register to set specified PLL frequency. \n
764   *             The register write-protection function should be disabled before using this function.
765   */
CLK_EnablePLL(uint32_t u32PllClkSrc,uint32_t u32PllFreq)766 uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
767 {
768     uint32_t u32PllSrcClk, u32NR, u32NF, u32NO, u32PllClk;
769     uint32_t u32Tmp, u32Tmp2, u32Tmp3, u32Min, u32MinNF, u32MinNR;
770 
771     /* Disable PLL first to avoid unstable when setting PLL */
772     CLK_DisablePLL();
773 
774     /* PLL source clock is from HXT */
775     if(u32PllClkSrc == CLK_PLLCTL_PLLSRC_HXT)
776     {
777 
778         /* Enable HXT clock */
779         CLK->PWRCTL |= CLK_PWRCTL_HXTEN_Msk;
780 
781         /* Wait for HXT clock ready */
782         CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);
783 
784         /* Select PLL source clock from HXT */
785         u32PllSrcClk = __HXT;
786     }
787 
788     /* PLL source clock is from HIRC */
789     else
790     {
791 
792         /* Enable HIRC clock */
793         CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
794 
795         /* Wait for HIRC clock ready */
796         CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
797 
798         /* Select PLL source clock from HIRC */
799         u32PllSrcClk = __HIRC;
800     }
801 
802     /* Check PLL frequency range */
803     if((u32PllFreq <= FREQ_144MHZ) && (u32PllFreq >= FREQ_24MHZ))
804     {
805 
806         /* Select "NO" according to request frequency */
807         if((u32PllFreq < FREQ_48MHZ) && (u32PllFreq >= FREQ_24MHZ))
808         {
809             u32NO = 3UL;
810             u32PllFreq = u32PllFreq << 2;
811         }
812         else if((u32PllFreq < FREQ_96MHZ) && (u32PllFreq >= FREQ_48MHZ))
813         {
814             u32NO = 1UL;
815             u32PllFreq = u32PllFreq << 1;
816         }
817         else
818         {
819             u32NO = 0UL;
820         }
821 
822         /* u32NR start from 3 to avoid calculation overflow */
823         u32NR = 3UL;
824 
825         /* Find best solution */
826         u32Min = (uint32_t) - 1;
827         u32MinNR = 0UL;
828         u32MinNF = 0UL;
829 
830         for(; u32NR <= 32UL; u32NR++)
831         {
832             u32Tmp = u32PllSrcClk / u32NR;
833             if((u32Tmp >= FREQ_2MHZ) && (u32Tmp <= FREQ_8MHZ))
834             {
835                 for(u32NF = 2UL; u32NF <= 513UL; u32NF++)
836                 {
837                     u32Tmp2 = (u32Tmp * u32NF) << 1;
838                     if((u32Tmp2 >= FREQ_96MHZ) && (u32Tmp2 <= FREQ_200MHZ))
839                     {
840                         u32Tmp3 = (u32Tmp2 > u32PllFreq) ? u32Tmp2 - u32PllFreq : u32PllFreq - u32Tmp2;
841                         if(u32Tmp3 < u32Min)
842                         {
843                             u32Min = u32Tmp3;
844                             u32MinNR = u32NR;
845                             u32MinNF = u32NF;
846 
847                             /* Break when get good results */
848                             if(u32Min == 0UL)
849                             {
850                                 break;
851                             }
852                         }
853                     }
854                 }
855             }
856         }
857 
858         /* Enable and apply new PLL setting. */
859         CLK->PLLCTL = u32PllClkSrc | (u32NO << 14) | ((u32MinNR - 1UL) << 9) | (u32MinNF - 2UL);
860 
861         /* Actual PLL output clock frequency */
862         u32PllClk = u32PllSrcClk / ((u32NO + 1UL) * u32MinNR) * (u32MinNF << 1);
863 
864     }
865     else
866     {
867 
868         /* Wrong frequency request. Just return default setting. */
869         if((SYS->PLSTS & SYS_PLSTS_PLSTATUS_Msk) == SYS_PLCTL_PLSEL_PL0)
870         {
871 
872             /* Apply default PLL setting and return */
873             CLK->PLLCTL = u32PllClkSrc | CLK_PLLCTL_64MHz_HXT;
874 
875             /* Actual PLL output clock frequency */
876             u32PllClk = FREQ_64MHZ;
877 
878         }
879         else
880         {
881 
882             /* Apply default PLL setting and return */
883             CLK->PLLCTL = u32PllClkSrc | CLK_PLLCTL_48MHz_HXT;
884 
885             /* Actual PLL output clock frequency */
886             u32PllClk = FREQ_48MHZ;
887         }
888 
889     }
890 
891     /* Wait for PLL clock stable */
892     CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);
893 
894     /* Return actual PLL output clock frequency */
895     return u32PllClk;
896 }
897 
898 /**
899   * @brief      Disable PLL
900   * @param      None
901   * @return     None
902   * @details    This function set PLL in Power-down mode. \n
903   *             The register write-protection function should be disabled before using this function.
904   */
CLK_DisablePLL(void)905 void CLK_DisablePLL(void)
906 {
907     CLK->PLLCTL |= CLK_PLLCTL_PD_Msk;
908 }
909 
910 /**
911   * @brief      This function check selected clock source status
912   * @param[in]  u32ClkMask is selected clock source. Including :
913   *             - \ref CLK_STATUS_HXTSTB_Msk
914   *             - \ref CLK_STATUS_LXTSTB_Msk
915   *             - \ref CLK_STATUS_HIRCSTB_Msk
916   *             - \ref CLK_STATUS_LIRCSTB_Msk
917   *             - \ref CLK_STATUS_PLLSTB_Msk
918   *             - \ref CLK_STATUS_HIRC48STB_Msk
919   *             - \ref CLK_STATUS_EXTLXTSTB_Msk
920   *             - \ref CLK_STATUS_LIRC32STB_Msk
921   * @retval     0  clock is not stable
922   * @retval     1  clock is stable
923   * @details    To wait for clock ready by specified clock source stable flag or timeout (~300ms)
924   */
CLK_WaitClockReady(uint32_t u32ClkMask)925 uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
926 {
927     int32_t i32TimeOutCnt = 2400000;
928     uint32_t u32Ret = 1U;
929 
930     while((CLK->STATUS & u32ClkMask) != u32ClkMask)
931     {
932         if(i32TimeOutCnt-- <= 0)
933         {
934             u32Ret = 0U;
935             break;
936         }
937     }
938     return u32Ret;
939 }
940 
941 /**
942   * @brief      Enable System Tick counter
943   * @param[in]  u32ClkSrc is System Tick clock source. Including:
944   *             - \ref CLK_CLKSEL0_STCLKSEL_HXT
945   *             - \ref CLK_CLKSEL0_STCLKSEL_LXT
946   *             - \ref CLK_CLKSEL0_STCLKSEL_HXT_DIV2
947   *             - \ref CLK_CLKSEL0_STCLKSEL_HCLK_DIV2
948   *             - \ref CLK_CLKSEL0_STCLKSEL_HIRC_DIV2
949   *             - \ref CLK_CLKSEL0_STCLKSEL_HCLK
950   * @param[in]  u32Count is System Tick reload value. It could be 0~0xFFFFFF.
951   * @return     None
952   * @details    This function set System Tick clock source, reload value, enable System Tick counter and interrupt. \n
953   *             The register write-protection function should be disabled before using this function.
954   */
CLK_EnableSysTick(uint32_t u32ClkSrc,uint32_t u32Count)955 void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
956 {
957     /* Set System Tick counter disabled */
958     SysTick->CTRL = 0UL;
959 
960     /* Set System Tick clock source */
961     if(u32ClkSrc == CLK_CLKSEL0_STCLKSEL_HCLK)
962     {
963         SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
964     }
965     else
966     {
967         CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc;
968     }
969 
970     /* Set System Tick reload value */
971     SysTick->LOAD = u32Count;
972 
973     /* Clear System Tick current value and counter flag */
974     SysTick->VAL = 0UL;
975 
976     /* Set System Tick interrupt enabled and counter enabled */
977     SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
978 }
979 
980 /**
981   * @brief      Disable System Tick counter
982   * @param      None
983   * @return     None
984   * @details    This function disable System Tick counter.
985   */
CLK_DisableSysTick(void)986 void CLK_DisableSysTick(void)
987 {
988     /* Set System Tick counter disabled */
989     SysTick->CTRL = 0UL;
990 }
991 
992 /**
993   * @brief      Power-down mode selected
994   * @param[in]  u32PDMode is power down mode index. Including :
995   *             - \ref CLK_PMUCTL_PDMSEL_PD
996   *             - \ref CLK_PMUCTL_PDMSEL_LLPD
997   *             - \ref CLK_PMUCTL_PDMSEL_FWPD
998   *             - \ref CLK_PMUCTL_PDMSEL_ULLPD
999   *             - \ref CLK_PMUCTL_PDMSEL_SPD
1000   *             - \ref CLK_PMUCTL_PDMSEL_DPD
1001   * @return     None
1002   * @details    This function is used to set power-down mode.
1003   */
CLK_SetPowerDownMode(uint32_t u32PDMode)1004 void CLK_SetPowerDownMode(uint32_t u32PDMode)
1005 {
1006     CLK->PMUCTL = (CLK->PMUCTL & (~CLK_PMUCTL_PDMSEL_Msk)) | (u32PDMode);
1007 }
1008 
1009 /**
1010  * @brief       Set Wake-up pin trigger type at Deep Power down mode
1011  * @param[in]   u32TriggerType Wake-up pin trigger type
1012  *              - \ref CLK_DPDWKPIN_RISING
1013  *              - \ref CLK_DPDWKPIN_FALLING
1014  *              - \ref CLK_DPDWKPIN_BOTHEDGE
1015  * @return      None
1016  * @details     This function is used to enable Wake-up pin trigger type.
1017  */
1018 
CLK_EnableDPDWKPin(uint32_t u32TriggerType)1019 void CLK_EnableDPDWKPin(uint32_t u32TriggerType)
1020 {
1021     CLK->PMUCTL = (CLK->PMUCTL & (~CLK_PMUCTL_WKPINEN_Msk)) | (u32TriggerType);
1022 }
1023 
1024 /**
1025  * @brief       Get power manager wake up source
1026  * @param[in]   None
1027  * @return      None
1028  * @details     This function get power manager wake up source.
1029  */
1030 
CLK_GetPMUWKSrc(void)1031 uint32_t CLK_GetPMUWKSrc(void)
1032 {
1033     return (CLK->PMUSTS);
1034 }
1035 
1036 /**
1037  * @brief       Set specified GPIO as wake up source at Standby Power-down mode
1038  * @param[in]   u32Port GPIO port. It could be 0~3.
1039  * @param[in]   u32Pin  The pin of specified GPIO port. It could be 0 ~ 15.
1040  * @param[in]   u32TriggerType Wake-up pin trigger type
1041  *              - \ref CLK_SPDWKPIN_RISING
1042  *              - \ref CLK_SPDWKPIN_FALLING
1043  * @param[in]   u32DebounceEn Standby Power-down mode wake-up pin de-bounce function
1044  *              - \ref CLK_SPDWKPIN_DEBOUNCEEN
1045  *              - \ref CLK_SPDWKPIN_DEBOUNCEDIS
1046  * @return      None
1047  * @details     This function is used to set specified GPIO as wake up source at Standby Power-down mode.
1048  */
1049 
CLK_EnableSPDWKPin(uint32_t u32Port,uint32_t u32Pin,uint32_t u32TriggerType,uint32_t u32DebounceEn)1050 void CLK_EnableSPDWKPin(uint32_t u32Port, uint32_t u32Pin, uint32_t u32TriggerType, uint32_t u32DebounceEn)
1051 {
1052     uint32_t u32TmpAddr = 0UL;
1053     uint32_t u32TmpVal = 0UL;
1054 
1055     /* GPx Stand-by Power-down Wake-up Pin Select */
1056     u32TmpAddr = (uint32_t)&CLK->PASWKCTL;
1057     u32TmpAddr += (0x4UL * u32Port);
1058 
1059     u32TmpVal = inpw((uint32_t *)u32TmpAddr);
1060     u32TmpVal = (u32TmpVal & ~(CLK_PASWKCTL_WKPSEL_Msk | CLK_PASWKCTL_PRWKEN_Msk | CLK_PASWKCTL_PFWKEN_Msk | CLK_PASWKCTL_DBEN_Msk | CLK_PASWKCTL_WKEN_Msk)) |
1061                 (u32Pin << CLK_PASWKCTL_WKPSEL_Pos) | u32TriggerType | u32DebounceEn | CLK_SPDWKPIN_ENABLE;
1062     outpw((uint32_t *)u32TmpAddr, u32TmpVal);
1063 }
1064 
1065 /**
1066   * @brief      Get PLL clock frequency
1067   * @param      None
1068   * @return     PLL frequency
1069   * @details    This function get PLL frequency. The frequency unit is Hz.
1070   */
1071 
1072 __NONSECURE_ENTRY_WEAK
CLK_GetPLLClockFreq(void)1073 uint32_t CLK_GetPLLClockFreq(void)
1074 {
1075     uint32_t u32PllFreq = 0UL, u32PllReg;
1076     uint32_t u32FIN, u32NF, u32NR, u32NO;
1077     uint8_t au8NoTbl[4] = {1U, 2U, 2U, 4U};
1078 
1079     u32PllReg = CLK->PLLCTL;
1080 
1081     if(u32PllReg & (CLK_PLLCTL_PD_Msk | CLK_PLLCTL_OE_Msk))
1082     {
1083         u32PllFreq = 0UL;          /* PLL is in power down mode or fix low */
1084     }
1085     else                        /* PLL is in normal mode */
1086     {
1087 
1088         /* PLL source clock */
1089         if(u32PllReg & CLK_PLLCTL_PLLSRC_Msk)
1090         {
1091             u32FIN = __HIRC;    /* PLL source clock from HIRC */
1092         }
1093         else
1094         {
1095             u32FIN = __HXT;     /* PLL source clock from HXT */
1096         }
1097 
1098         /* Calculate PLL frequency */
1099         if(u32PllReg & CLK_PLLCTL_BP_Msk)
1100         {
1101             u32PllFreq = u32FIN;  /* PLL is in bypass mode */
1102         }
1103         else
1104         {
1105             /* PLL is output enabled in normal work mode */
1106             u32NO = au8NoTbl[((u32PllReg & CLK_PLLCTL_OUTDIV_Msk) >> CLK_PLLCTL_OUTDIV_Pos)];
1107             u32NF = ((u32PllReg & CLK_PLLCTL_FBDIV_Msk) >> CLK_PLLCTL_FBDIV_Pos) + 2UL;
1108             u32NR = ((u32PllReg & CLK_PLLCTL_INDIV_Msk) >> CLK_PLLCTL_INDIV_Pos) + 1UL;
1109 
1110             /* u32FIN is shifted 2 bits to avoid overflow */
1111             u32PllFreq = (((u32FIN >> 2) * (u32NF << 1)) / (u32NR * u32NO) << 2);
1112         }
1113     }
1114 
1115     return u32PllFreq;
1116 }
1117 
1118 /**
1119   * @brief      Get selected module clock source
1120   * @param[in]  u32ModuleIdx is module index.
1121   *             - \ref SDH0_MODULE
1122   *             - \ref USBH_MODULE
1123   *             - \ref WDT_MODULE
1124   *             - \ref WWDT_MODULE
1125   *             - \ref RTC_MODULE
1126   *             - \ref TMR0_MODULE
1127   *             - \ref TMR1_MODULE
1128   *             - \ref TMR2_MODULE
1129   *             - \ref TMR3_MODULE
1130   *             - \ref CLKO_MODULE
1131   *             - \ref QSPI0_MODULE
1132   *             - \ref SPI0_MODULE
1133   *             - \ref SPI1_MODULE
1134   *             - \ref SPI2_MODULE
1135   *             - \ref SPI3_MODULE
1136   *             - \ref UART0_MODULE
1137   *             - \ref UART1_MODULE
1138   *             - \ref UART2_MODULE
1139   *             - \ref UART3_MODULE
1140   *             - \ref UART4_MODULE
1141   *             - \ref UART5_MODULE
1142   *             - \ref OTG_MODULE
1143   *             - \ref USBD_MODULE
1144   *             - \ref I2S0_MODULE
1145   *             - \ref SC0_MODULE
1146   *             - \ref SC1_MODULE
1147   *             - \ref SC2_MODULE
1148   *             - \ref EPWM0_MODULE
1149   *             - \ref EPWM1_MODULE
1150   *             - \ref BPWM0_MODULE
1151   *             - \ref BPWM1_MODULE
1152   * @return     Selected module clock source setting
1153   * @details    This function get selected module clock source.
1154   */
1155 
1156 __NONSECURE_ENTRY_WEAK
CLK_GetModuleClockSource(uint32_t u32ModuleIdx)1157 uint32_t CLK_GetModuleClockSource(uint32_t u32ModuleIdx)
1158 {
1159     uint32_t u32TmpVal = 0UL, u32TmpAddr = 0UL;
1160     uint32_t au32SelTbl[4] = {0x0UL, 0x4UL, 0x8UL, 0xCUL};
1161 
1162     /* Get clock source selection setting */
1163     if(u32ModuleIdx == EPWM0_MODULE)
1164     {
1165         u32TmpVal = ((CLK->CLKSEL2 & CLK_CLKSEL2_EPWM0SEL_Msk) >> CLK_CLKSEL2_EPWM0SEL_Pos);
1166     }
1167     else if(u32ModuleIdx == EPWM1_MODULE)
1168     {
1169         u32TmpVal = ((CLK->CLKSEL2 & CLK_CLKSEL2_EPWM1SEL_Msk) >> CLK_CLKSEL2_EPWM1SEL_Pos);
1170     }
1171     else if(u32ModuleIdx == BPWM0_MODULE)
1172     {
1173         u32TmpVal = ((CLK->CLKSEL2 & CLK_CLKSEL2_BPWM0SEL_Msk) >> CLK_CLKSEL2_BPWM0SEL_Pos);
1174     }
1175     else if(u32ModuleIdx == BPWM1_MODULE)
1176     {
1177         u32TmpVal = ((CLK->CLKSEL2 & CLK_CLKSEL2_BPWM1SEL_Msk) >> CLK_CLKSEL2_BPWM1SEL_Pos);
1178     }
1179     else if(MODULE_CLKSEL_Msk(u32ModuleIdx) != MODULE_NoMsk)
1180     {
1181         /* Get clock select control register address */
1182         u32TmpAddr = (uint32_t)&CLK->CLKSEL0 + (au32SelTbl[MODULE_CLKSEL(u32ModuleIdx)]);
1183 
1184         /* Get clock source selection setting */
1185         u32TmpVal = ((inpw((uint32_t *)u32TmpAddr) & (MODULE_CLKSEL_Msk(u32ModuleIdx) << MODULE_CLKSEL_Pos(u32ModuleIdx))) >> MODULE_CLKSEL_Pos(u32ModuleIdx));
1186     }
1187 
1188     return u32TmpVal;
1189 }
1190 
1191 /**
1192   * @brief      Get selected module clock divider number
1193   * @param[in]  u32ModuleIdx is module index.
1194   *             - \ref SDH0_MODULE
1195   *             - \ref USBH_MODULE
1196   *             - \ref UART0_MODULE
1197   *             - \ref UART1_MODULE
1198   *             - \ref UART2_MODULE
1199   *             - \ref UART3_MODULE
1200   *             - \ref UART4_MODULE
1201   *             - \ref UART5_MODULE
1202   *             - \ref OTG_MODULE
1203   *             - \ref USBD_MODULE
1204   *             - \ref SC0_MODULE
1205   *             - \ref SC1_MODULE
1206   *             - \ref SC2_MODULE
1207   *             - \ref EADC_MODULE
1208   * @return     Selected module clock divider number setting
1209   * @details    This function get selected module clock divider number.
1210   */
1211 
1212 __NONSECURE_ENTRY_WEAK
CLK_GetModuleClockDivider(uint32_t u32ModuleIdx)1213 uint32_t CLK_GetModuleClockDivider(uint32_t u32ModuleIdx)
1214 {
1215     uint32_t u32TmpVal = 0UL, u32TmpAddr = 0UL;
1216     uint32_t au32DivTbl[4] = {0x0UL, 0x4UL, 0x8UL, 0x10UL};
1217 
1218     if(MODULE_CLKDIV_Msk(u32ModuleIdx) != MODULE_NoMsk)
1219     {
1220         /* Get clock divider control register address */
1221         u32TmpAddr = (uint32_t)&CLK->CLKDIV0 + (au32DivTbl[MODULE_CLKDIV(u32ModuleIdx)]);
1222         /* Get clock divider number setting */
1223         u32TmpVal = ((inpw((uint32_t *)u32TmpAddr) & (MODULE_CLKDIV_Msk(u32ModuleIdx) << MODULE_CLKDIV_Pos(u32ModuleIdx))) >> MODULE_CLKDIV_Pos(u32ModuleIdx));
1224     }
1225 
1226     return u32TmpVal;
1227 }
1228 
1229 
1230 /*@}*/ /* end of group CLK_EXPORTED_FUNCTIONS */
1231 
1232 /*@}*/ /* end of group CLK_Driver */
1233 
1234 /*@}*/ /* end of group Standard_Driver */
1235 
1236