1 /**************************************************************************//**
2  * @file     clk.c
3  * @version  V1.0
4  * @brief    M2L31 series CLK driver source file
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  * @copyright (C) 2023 Nuvoton Technology Corp. All rights reserved.
8  *****************************************************************************/
9 
10 #include "NuMicro.h"
11 
12 /** @addtogroup Standard_Driver Standard Driver
13   @{
14 */
15 
16 /** @addtogroup CLK_Driver CLK Driver
17   @{
18 */
19 
20 int32_t g_CLK_i32ErrCode = 0;   /*!< CLK global error code */
21 
22 /** @addtogroup CLK_EXPORTED_FUNCTIONS CLK Exported Functions
23   @{
24 */
25 
26 /**
27   * @brief      Disable clock divider output function
28   * @param      None
29   * @return     None
30   * @details    This function disable clock divider output function.
31   */
CLK_DisableCKO(void)32 void CLK_DisableCKO(void)
33 {
34     /* Disable CKO clock source */
35     CLK_DisableModuleClock(CLKO_MODULE);
36 }
37 
38 /**
39   * @brief      This function enable clock divider output module clock,
40   *             enable clock divider output function and set frequency selection.
41   * @param[in]  u32ClkSrc is frequency divider function clock source. Including :
42   *             - \ref CLK_CLKSEL1_CLKOSEL_HXT
43   *             - \ref CLK_CLKSEL1_CLKOSEL_LXT
44   *             - \ref CLK_CLKSEL1_CLKOSEL_HCLK
45   *             - \ref CLK_CLKSEL1_CLKOSEL_HIRC
46   *             - \ref CLK_CLKSEL1_CLKOSEL_LIRC
47   *             - \ref CLK_CLKSEL1_CLKOSEL_PLL
48   *             - \ref CLK_CLKSEL1_CLKOSEL_HIRC48M
49   *             - \ref CLK_CLKSEL1_CLKOSEL_MIRC
50   * @param[in]  u32ClkDiv is divider output frequency selection. It could be 0~15.
51   * @param[in]  u32ClkDivBy1En is clock divided by one enabled.
52   * @return     None
53   * @details    Output selected clock to CKO. The output clock frequency is divided by u32ClkDiv. \n
54   *             The formula is: \n
55   *                 CKO frequency = (Clock source frequency) / 2^(u32ClkDiv + 1) \n
56   *             This function is just used to set CKO clock.
57   *             User must enable I/O for CKO clock output pin by themselves. \n
58   */
CLK_EnableCKO(uint32_t u32ClkSrc,uint32_t u32ClkDiv,uint32_t u32ClkDivBy1En)59 void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv, uint32_t u32ClkDivBy1En)
60 {
61     /* CKO = clock source / 2^(u32ClkDiv + 1) */
62     CLK->CLKOCTL = CLK_CLKOCTL_CLKOEN_Msk | (u32ClkDiv) | (u32ClkDivBy1En << CLK_CLKOCTL_DIV1EN_Pos);
63 
64     /* Enable CKO clock source */
65     CLK_EnableModuleClock(CLKO_MODULE);
66 
67     /* Select CKO clock source */
68     CLK_SetModuleClock(CLKO_MODULE, u32ClkSrc, 0UL);
69 }
70 
71 /**
72   * @brief      Enter to Power-down mode
73   * @param      None
74   * @return     None
75   * @details    This function is used to let system enter to Power-down mode. \n
76   *             The register write-protection function should be disabled before using this function.
77   */
CLK_PowerDown(void)78 void CLK_PowerDown(void)
79 {
80     uint32_t u32HIRCTRIMCTL;
81 
82     /* Set the processor uses deep sleep as its low power mode */
83     SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
84 
85     /* Set system Power-down enabled */
86     CLK->PWRCTL |= (CLK_PWRCTL_PDEN_Msk);
87 
88     /* Store HIRC control register */
89     u32HIRCTRIMCTL = SYS->IRCTCTL;
90 
91     /* Disable HIRC auto trim */
92     SYS->HIRCTCTL &= (~SYS_HIRCTCTL_FREQSEL_Msk);
93 
94     /* Chip enter Power-down mode after CPU run WFI instruction */
95     __WFI();
96 
97     /* Restore HIRC control register */
98     SYS->IRCTCTL = u32HIRCTRIMCTL;
99 }
100 
101 /**
102   * @brief      Enter to Idle mode
103   * @param      None
104   * @return     None
105   * @details    This function let system enter to Idle mode. \n
106   *             The register write-protection function should be disabled before using this function.
107   */
CLK_Idle(void)108 void CLK_Idle(void)
109 {
110     /* Set the processor uses sleep as its low power mode */
111     SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
112 
113     /* Set chip in idle mode because of WFI command */
114     CLK->PWRCTL &= ~CLK_PWRCTL_PDEN_Msk;
115 
116     /* Chip enter idle mode after CPU run WFI instruction */
117     __WFI();
118 }
119 
120 /**
121   * @brief      Get external high speed crystal clock frequency
122   * @param      None
123   * @return     External high frequency crystal frequency
124   * @details    This function get external high frequency crystal frequency. The frequency unit is Hz.
125   */
CLK_GetHXTFreq(void)126 uint32_t CLK_GetHXTFreq(void)
127 {
128     uint32_t u32Freq;
129 
130     if((CLK->PWRCTL & CLK_PWRCTL_HXTEN_Msk) == CLK_PWRCTL_HXTEN_Msk)
131     {
132         u32Freq = __HXT;
133     }
134     else
135     {
136         u32Freq = 0UL;
137     }
138 
139     return u32Freq;
140 }
141 
142 
143 /**
144   * @brief      Get external low speed crystal clock frequency
145   * @param      None
146   * @return     External low speed crystal clock frequency
147   * @details    This function get external low frequency crystal frequency. The frequency unit is Hz.
148   */
CLK_GetLXTFreq(void)149 uint32_t CLK_GetLXTFreq(void)
150 {
151     uint32_t u32Freq;
152     if((CLK->PWRCTL & CLK_PWRCTL_LXTEN_Msk) == CLK_PWRCTL_LXTEN_Msk)
153     {
154         u32Freq = __LXT;
155     }
156     else
157     {
158         u32Freq = 0UL;
159     }
160 
161     return u32Freq;
162 }
163 
164 /**
165   * @brief      Get PCLK0 frequency
166   * @param      None
167   * @return     PCLK0 frequency
168   * @details    This function get PCLK0 frequency. The frequency unit is Hz.
169   */
CLK_GetPCLK0Freq(void)170 uint32_t CLK_GetPCLK0Freq(void)
171 {
172     uint32_t u32Freq;
173     SystemCoreClockUpdate();
174 
175     if((CLK->PCLKDIV & CLK_PCLKDIV_APB0DIV_Msk) == CLK_PCLKDIV_APB0DIV_DIV1)
176     {
177         u32Freq = SystemCoreClock;
178     }
179     else if((CLK->PCLKDIV & CLK_PCLKDIV_APB0DIV_Msk) == CLK_PCLKDIV_APB0DIV_DIV2)
180     {
181         u32Freq = SystemCoreClock / 2UL;
182     }
183     else if((CLK->PCLKDIV & CLK_PCLKDIV_APB0DIV_Msk) == CLK_PCLKDIV_APB0DIV_DIV4)
184     {
185         u32Freq = SystemCoreClock / 4UL;
186     }
187     else if((CLK->PCLKDIV & CLK_PCLKDIV_APB0DIV_Msk) == CLK_PCLKDIV_APB0DIV_DIV8)
188     {
189         u32Freq = SystemCoreClock / 8UL;
190     }
191     else if((CLK->PCLKDIV & CLK_PCLKDIV_APB0DIV_Msk) == CLK_PCLKDIV_APB0DIV_DIV16)
192     {
193         u32Freq = SystemCoreClock / 16UL;
194     }
195     else
196     {
197         u32Freq = SystemCoreClock;
198     }
199 
200     return u32Freq;
201 }
202 
203 
204 /**
205   * @brief      Get PCLK1 frequency
206   * @param      None
207   * @return     PCLK1 frequency
208   * @details    This function get PCLK1 frequency. The frequency unit is Hz.
209   */
CLK_GetPCLK1Freq(void)210 uint32_t CLK_GetPCLK1Freq(void)
211 {
212     uint32_t u32Freq;
213     SystemCoreClockUpdate();
214 
215     if((CLK->PCLKDIV & CLK_PCLKDIV_APB1DIV_Msk) == CLK_PCLKDIV_APB1DIV_DIV1)
216     {
217         u32Freq = SystemCoreClock;
218     }
219     else if((CLK->PCLKDIV & CLK_PCLKDIV_APB1DIV_Msk) == CLK_PCLKDIV_APB1DIV_DIV2)
220     {
221         u32Freq = SystemCoreClock / 2UL;
222     }
223     else if((CLK->PCLKDIV & CLK_PCLKDIV_APB1DIV_Msk) == CLK_PCLKDIV_APB1DIV_DIV4)
224     {
225         u32Freq = SystemCoreClock / 4UL;
226     }
227     else if((CLK->PCLKDIV & CLK_PCLKDIV_APB1DIV_Msk) == CLK_PCLKDIV_APB1DIV_DIV8)
228     {
229         u32Freq = SystemCoreClock / 8UL;
230     }
231     else if((CLK->PCLKDIV & CLK_PCLKDIV_APB1DIV_Msk) == CLK_PCLKDIV_APB1DIV_DIV16)
232     {
233         u32Freq = SystemCoreClock / 16UL;
234     }
235     else
236     {
237         u32Freq = SystemCoreClock;
238     }
239 
240     return u32Freq;
241 }
242 
243 
244 /**
245   * @brief      Get HCLK frequency
246   * @param      None
247   * @return     HCLK frequency
248   * @details    This function get HCLK frequency. The frequency unit is Hz.
249   */
CLK_GetHCLKFreq(void)250 uint32_t CLK_GetHCLKFreq(void)
251 {
252     SystemCoreClockUpdate();
253     return SystemCoreClock;
254 }
255 
256 
257 /**
258   * @brief      Get HCLK1 frequency
259   * @param      None
260   * @return     HCLK1 frequency
261   * @details    This function get HCLK1 frequency. The frequency unit is Hz.
262   */
CLK_GetHCLK1Freq(void)263 uint32_t CLK_GetHCLK1Freq(void)
264 {
265     uint32_t u32Freq, u32ClkSrc;
266     uint32_t u32Hclk1Div;
267     uint32_t au32Hclk1SrcTbl[5] = {__HIRC, __MIRC, __LXT, __LIRC, __HIRC48 };
268 
269     if (CLK->AHBCLK1 & CLK_AHBCLK1_HCLK1EN_Msk)
270     {
271         u32ClkSrc = (CLK->CLKSEL0 & CLK_CLKSEL0_HCLK1SEL_Msk) >> CLK_CLKSEL0_HCLK1SEL_Pos;
272         u32Hclk1Div = (LPSCC->CLKDIV0 & LPSCC_CLKDIV0_HCLK1DIV_Msk) >> LPSCC_CLKDIV0_HCLK1DIV_Pos;
273         u32Freq = au32Hclk1SrcTbl[u32ClkSrc] / (u32Hclk1Div + 1);
274         if (u32ClkSrc == 4)     // For HIRC48M div 2
275             u32Freq = u32Freq / 2;
276     }
277     else
278     {
279         u32Freq = 0;
280     }
281 
282     return u32Freq;
283 }
284 
285 
286 /**
287   * @brief      Get PCLK2 frequency
288   * @param      None
289   * @return     PCLK2 frequency
290   * @details    This function get PCLK2 frequency. The frequency unit is Hz.
291   */
CLK_GetPCLK2Freq(void)292 uint32_t CLK_GetPCLK2Freq(void)
293 {
294     uint32_t u32Freq;
295 
296     if((LPSCC->CLKDIV0 & LPSCC_CLKDIV0_APB2DIV_Msk) == LPSCC_CLKDIV0_PCLK2DIV1)
297     {
298         u32Freq = CLK_GetHCLK1Freq();
299     }
300     else if((LPSCC->CLKDIV0 & LPSCC_CLKDIV0_APB2DIV_Msk) == LPSCC_CLKDIV0_PCLK2DIV2)
301     {
302         u32Freq = CLK_GetHCLK1Freq() / 2UL;
303     }
304     else if((LPSCC->CLKDIV0 & LPSCC_CLKDIV0_APB2DIV_Msk) == LPSCC_CLKDIV0_PCLK2DIV4)
305     {
306         u32Freq = CLK_GetHCLK1Freq() / 4UL;
307     }
308     else if((LPSCC->CLKDIV0 & LPSCC_CLKDIV0_APB2DIV_Msk) == LPSCC_CLKDIV0_PCLK2DIV8)
309     {
310         u32Freq = CLK_GetHCLK1Freq() / 8UL;
311     }
312     else if((LPSCC->CLKDIV0 & LPSCC_CLKDIV0_APB2DIV_Msk) == LPSCC_CLKDIV0_PCLK2DIV16)
313     {
314         u32Freq = CLK_GetHCLK1Freq() / 16UL;
315     }
316     else
317     {
318         u32Freq = CLK_GetHCLK1Freq();
319     }
320 
321     return u32Freq;
322 }
323 
324 /**
325   * @brief      Get CPU frequency
326   * @param      None
327   * @return     CPU frequency
328   * @details    This function get CPU frequency. The frequency unit is Hz.
329   */
CLK_GetCPUFreq(void)330 uint32_t CLK_GetCPUFreq(void)
331 {
332     SystemCoreClockUpdate();
333     return SystemCoreClock;
334 }
335 
336 
337 /**
338   * @brief      Set HCLK frequency
339   * @param[in]  u32Hclk is HCLK frequency. The range of u32Hclk is running up to 72MHz.
340   * @return     HCLK frequency
341   * @details    This function is used to set HCLK frequency. The frequency unit is Hz. \n
342   *             The register write-protection function should be disabled before using this function.
343   */
CLK_SetCoreClock(uint32_t u32Hclk)344 uint32_t CLK_SetCoreClock(uint32_t u32Hclk)
345 {
346     uint32_t u32HIRCSTB;
347 
348     /* Read HIRC clock source stable flag */
349     u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;
350 
351     /* The range of u32Hclk is running up to 72 MHz */
352     if(u32Hclk > FREQ_72MHZ)
353     {
354         u32Hclk = FREQ_72MHZ;
355     }
356 
357     /* Switch HCLK clock source to HIRC clock for safe */
358     CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
359     CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
360     CLK->CLKSEL0 |= CLK_CLKSEL0_HCLK0SEL_Msk;
361     CLK->CLKDIV0 &= (~CLK_CLKDIV0_HCLK0DIV_Msk);
362 
363     /* Configure PLL setting if HXT clock is enabled */
364     if((CLK->PWRCTL & CLK_PWRCTL_HXTEN_Msk) == CLK_PWRCTL_HXTEN_Msk)
365     {
366         u32Hclk = CLK_EnablePLL(CLK_PLLCTL_PLLSRC_HXT, u32Hclk);
367     }
368     /* Configure PLL setting if HXT clock is not enabled */
369     else
370     {
371         u32Hclk = CLK_EnablePLL(CLK_PLLCTL_PLLSRC_HIRC, u32Hclk);
372 
373         /* Read HIRC clock source stable flag */
374         u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;
375     }
376 
377     /* Select HCLK clock source to PLL,
378        and update system core clock
379     */
380     CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL, CLK_CLKDIV0_HCLK(1UL));
381 
382     /* Disable HIRC if HIRC is disabled before setting core clock */
383     if(u32HIRCSTB == 0UL)
384     {
385         CLK->PWRCTL &= ~CLK_PWRCTL_HIRCEN_Msk;
386     }
387 
388     /* Return actually HCLK frequency is PLL frequency divide 1 */
389     return u32Hclk;
390 }
391 
392 /**
393   * @brief      This function set HCLK clock source and HCLK clock divider
394   * @param[in]  u32ClkSrc is HCLK clock source. Including :
395   *             - \ref CLK_CLKSEL0_HCLKSEL_HXT
396   *             - \ref CLK_CLKSEL0_HCLKSEL_LXT
397   *             - \ref CLK_CLKSEL0_HCLKSEL_PLL
398   *             - \ref CLK_CLKSEL0_HCLKSEL_LIRC
399   *             - \ref CLK_CLKSEL0_HCLKSEL_HIRC
400   *             - \ref CLK_CLKSEL0_HCLKSEL_MIRC
401   *             - \ref CLK_CLKSEL0_HCLKSEL_HIRC48M
402   * @param[in]  u32ClkDiv is HCLK clock divider. Including :
403   *             - \ref CLK_CLKDIV0_HCLK(x)
404   * @return     None
405   * @details    This function set HCLK clock source and HCLK clock divider. \n
406   *             The register write-protection function should be disabled before using this function.
407   */
CLK_SetHCLK(uint32_t u32ClkSrc,uint32_t u32ClkDiv)408 void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
409 {
410     uint32_t u32HIRCSTB;
411 
412     /* Read HIRC clock source stable flag */
413     u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;
414 
415     /* Switch RMC access cycle to maximum value for safe */
416     RMC->CYCCTL = 4;
417 
418     /* Switch to HIRC for Safe. Avoid HCLK too high when applying new divider. */
419     CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
420     CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
421     CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLK0SEL_Msk)) | CLK_CLKSEL0_HCLK0SEL_HIRC;
422 
423     /* Apply new Divider */
424     CLK->CLKDIV0 = (CLK->CLKDIV0 & (~CLK_CLKDIV0_HCLK0DIV_Msk)) | u32ClkDiv;
425 
426     /* Switch HCLK to new HCLK source */
427     CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLK0SEL_Msk)) | u32ClkSrc;
428 
429     /* Update System Core Clock */
430     SystemCoreClockUpdate();
431 
432     /* Switch RMC access cycle to suitable value base on HCLK */
433     if (SystemCoreClock > 50000000)
434         RMC->CYCCTL = 4;
435     else if (SystemCoreClock > 25000000)
436         RMC->CYCCTL = 3;
437     else
438         RMC->CYCCTL = 2;
439 
440     /* Disable HIRC if HIRC is disabled before switching HCLK source */
441     if(u32HIRCSTB == 0UL)
442     {
443         CLK->PWRCTL &= ~CLK_PWRCTL_HIRCEN_Msk;
444     }
445 }
446 
447 /**
448   * @brief      This function set selected module clock source and module clock divider
449   * @param[in]  u32ModuleIdx is module index.
450   * @param[in]  u32ClkSrc is module clock source.
451   * @param[in]  u32ClkDiv is module clock divider.
452   * @return     None
453   * @details    Valid parameter combinations listed in following table:
454   *
455   * |Module index       |Clock source                           |Divider                    |
456   * | :---------------- | :-----------------------------------  | :----------------------   |
457   * |\ref CANFD0_MODULE |\ref CLK_CLKSEL0_CANFD0SEL_HCLK        |\ref CLK_CLKDIV5_CANFD0(x) |
458   * |\ref CANFD0_MODULE |\ref CLK_CLKSEL0_CANFD0SEL_HIRC        |\ref CLK_CLKDIV5_CANFD0(x) |
459   * |\ref CANFD0_MODULE |\ref CLK_CLKSEL0_CANFD0SEL_HIRC48M     |\ref CLK_CLKDIV5_CANFD0(x) |
460   * |\ref CANFD0_MODULE |\ref CLK_CLKSEL0_CANFD0SEL_HXT         |\ref CLK_CLKDIV5_CANFD0(x) |
461   * |\ref CANFD1_MODULE |\ref CLK_CLKSEL0_CANFD1SEL_HCLK        |\ref CLK_CLKDIV5_CANFD1(x) |
462   * |\ref CANFD1_MODULE |\ref CLK_CLKSEL0_CANFD1SEL_HIRC        |\ref CLK_CLKDIV5_CANFD1(x) |
463   * |\ref CANFD1_MODULE |\ref CLK_CLKSEL0_CANFD1SEL_HIRC48M     |\ref CLK_CLKDIV5_CANFD1(x) |
464   * |\ref CANFD1_MODULE |\ref CLK_CLKSEL0_CANFD1SEL_HXT         |\ref CLK_CLKDIV5_CANFD1(x) |
465   * |\ref CLKO_MODULE   |\ref CLK_CLKSEL1_CLKOSEL_HCLK          | x                         |
466   * |\ref CLKO_MODULE   |\ref CLK_CLKSEL1_CLKOSEL_HIRC          | x                         |
467   * |\ref CLKO_MODULE   |\ref CLK_CLKSEL1_CLKOSEL_HIRC48M       | x                         |
468   * |\ref CLKO_MODULE   |\ref CLK_CLKSEL1_CLKOSEL_HXT           | x                         |
469   * |\ref CLKO_MODULE   |\ref CLK_CLKSEL1_CLKOSEL_LIRC          | x                         |
470   * |\ref CLKO_MODULE   |\ref CLK_CLKSEL1_CLKOSEL_LXT           | x                         |
471   * |\ref CLKO_MODULE   |\ref CLK_CLKSEL1_CLKOSEL_MIRC          | x                         |
472   * |\ref CLKO_MODULE   |\ref CLK_CLKSEL1_CLKOSEL_PLL           | x                         |
473   * |\ref EADC0_MODULE  |\ref CLK_CLKSEL0_EADC0SEL_HCLK         |\ref CLK_CLKDIV0_EADC0(x)  |
474   * |\ref EADC0_MODULE  |\ref CLK_CLKSEL0_EADC0SEL_HIRC         |\ref CLK_CLKDIV0_EADC0(x)  |
475   * |\ref EADC0_MODULE  |\ref CLK_CLKSEL0_EADC0SEL_PLL          |\ref CLK_CLKDIV0_EADC0(x)  |
476   * |\ref EPWM0_MODULE  |\ref CLK_CLKSEL2_EPWM0SEL_HCLK         | x                         |
477   * |\ref EPWM0_MODULE  |\ref CLK_CLKSEL2_EPWM0SEL_PCLK0        | x                         |
478   * |\ref EPWM1_MODULE  |\ref CLK_CLKSEL2_EPWM1SEL_HCLK         | x                         |
479   * |\ref EPWM1_MODULE  |\ref CLK_CLKSEL2_EPWM1SEL_PCLK1        | x                         |
480   * |\ref HCLK1_MODULE  |\ref CLK_CLKSEL0_HCLK1SEL_HIRC         |\ref LPSCC_CLKDIV0_HCLK1(x)|
481   * |\ref HCLK1_MODULE  |\ref CLK_CLKSEL0_HCLK1SEL_HIRC48M_DIV2 |\ref LPSCC_CLKDIV0_HCLK1(x)|
482   * |\ref HCLK1_MODULE  |\ref CLK_CLKSEL0_HCLK1SEL_LIRC         |\ref LPSCC_CLKDIV0_HCLK1(x)|
483   * |\ref HCLK1_MODULE  |\ref CLK_CLKSEL0_HCLK1SEL_LXT          |\ref LPSCC_CLKDIV0_HCLK1(x)|
484   * |\ref HCLK1_MODULE  |\ref CLK_CLKSEL0_HCLK1SEL_MIRC         |\ref LPSCC_CLKDIV0_HCLK1(x)|
485   * |\ref LPADC0_MODULE |\ref LPSCC_CLKSEL0_LPADC0SEL_HIRC      |\ref LPSCC_CLKDIV0_LPADC0(x)|
486   * |\ref LPADC0_MODULE |\ref LPSCC_CLKSEL0_LPADC0SEL_LXT       |\ref LPSCC_CLKDIV0_LPADC0(x)|
487   * |\ref LPADC0_MODULE |\ref LPSCC_CLKSEL0_LPADC0SEL_MIRC      |\ref LPSCC_CLKDIV0_LPADC0(x)|
488   * |\ref LPADC0_MODULE |\ref LPSCC_CLKSEL0_LPADC0SEL_PCLK2     |\ref LPSCC_CLKDIV0_LPADC0(x)|
489   * |\ref LPSPI0_MODULE |\ref LPSCC_CLKSEL0_LPSPI0SEL_HIRC      | x                         |
490   * |\ref LPSPI0_MODULE |\ref LPSCC_CLKSEL0_LPSPI0SEL_MIRC      | x                         |
491   * |\ref LPTMR0_MODULE |\ref LPSCC_CLKSEL0_LPTMR0SEL_EXT       | x                         |
492   * |\ref LPTMR0_MODULE |\ref LPSCC_CLKSEL0_LPTMR0SEL_HIRC      | x                         |
493   * |\ref LPTMR0_MODULE |\ref LPSCC_CLKSEL0_LPTMR0SEL_LIRC      | x                         |
494   * |\ref LPTMR0_MODULE |\ref LPSCC_CLKSEL0_LPTMR0SEL_LXT       | x                         |
495   * |\ref LPTMR0_MODULE |\ref LPSCC_CLKSEL0_LPTMR0SEL_MIRC      | x                         |
496   * |\ref LPTMR1_MODULE |\ref LPSCC_CLKSEL0_LPTMR1SEL_EXT       | x                         |
497   * |\ref LPTMR1_MODULE |\ref LPSCC_CLKSEL0_LPTMR1SEL_HIRC      | x                         |
498   * |\ref LPTMR1_MODULE |\ref LPSCC_CLKSEL0_LPTMR1SEL_LIRC      | x                         |
499   * |\ref LPTMR1_MODULE |\ref LPSCC_CLKSEL0_LPTMR1SEL_LXT       | x                         |
500   * |\ref LPTMR1_MODULE |\ref LPSCC_CLKSEL0_LPTMR1SEL_MIRC      | x                         |
501   * |\ref LPUART0_MODULE|\ref LPSCC_CLKSEL0_LPUART0SEL_HIRC     |\ref LPSCC_CLKDIV0_LPUART0(x)|
502   * |\ref LPUART0_MODULE|\ref LPSCC_CLKSEL0_LPUART0SEL_LXT      |\ref LPSCC_CLKDIV0_LPUART0(x)|
503   * |\ref LPUART0_MODULE|\ref LPSCC_CLKSEL0_LPUART0SEL_MIRC     |\ref LPSCC_CLKDIV0_LPUART0(x)|
504   * |\ref PWM0_MODULE   |\ref CLK_CLKSEL3_PWM0SEL_HCLK          | x                         |
505   * |\ref PWM0_MODULE   |\ref CLK_CLKSEL3_PWM0SEL_PCLK0         | x                         |
506   * |\ref PWM1_MODULE   |\ref CLK_CLKSEL3_PWM1SEL_HCLK          | x                         |
507   * |\ref PWM1_MODULE   |\ref CLK_CLKSEL3_PWM1SEL_PCLK1         | x                         |
508   * |\ref QSPI0_MODULE  |\ref CLK_CLKSEL2_QSPI0SEL_HIRC         | x                         |
509   * |\ref QSPI0_MODULE  |\ref CLK_CLKSEL2_QSPI0SEL_HXT          | x                         |
510   * |\ref QSPI0_MODULE  |\ref CLK_CLKSEL2_QSPI0SEL_PCLK0        | x                         |
511   * |\ref QSPI0_MODULE  |\ref CLK_CLKSEL2_QSPI0SEL_PLL          | x                         |
512   * |\ref SPI0_MODULE   |\ref CLK_CLKSEL2_SPI0SEL_HIRC          | x                         |
513   * |\ref SPI0_MODULE   |\ref CLK_CLKSEL2_SPI0SEL_HIRC48M       | x                         |
514   * |\ref SPI0_MODULE   |\ref CLK_CLKSEL2_SPI0SEL_HXT           | x                         |
515   * |\ref SPI0_MODULE   |\ref CLK_CLKSEL2_SPI0SEL_PCLK1         | x                         |
516   * |\ref SPI0_MODULE   |\ref CLK_CLKSEL2_SPI0SEL_PLL           | x                         |
517   * |\ref SPI1_MODULE   |\ref CLK_CLKSEL2_SPI1SEL_HIRC          | x                         |
518   * |\ref SPI1_MODULE   |\ref CLK_CLKSEL2_SPI1SEL_HIRC48M       | x                         |
519   * |\ref SPI1_MODULE   |\ref CLK_CLKSEL2_SPI1SEL_HXT           | x                         |
520   * |\ref SPI1_MODULE   |\ref CLK_CLKSEL2_SPI1SEL_PCLK0         | x                         |
521   * |\ref SPI1_MODULE   |\ref CLK_CLKSEL2_SPI1SEL_PLL           | x                         |
522   * |\ref SPI2_MODULE   |\ref CLK_CLKSEL3_SPI2SEL_HIRC          | x                         |
523   * |\ref SPI2_MODULE   |\ref CLK_CLKSEL3_SPI2SEL_HIRC48M       | x                         |
524   * |\ref SPI2_MODULE   |\ref CLK_CLKSEL3_SPI2SEL_HXT           | x                         |
525   * |\ref SPI2_MODULE   |\ref CLK_CLKSEL3_SPI2SEL_PCLK1         | x                         |
526   * |\ref SPI2_MODULE   |\ref CLK_CLKSEL3_SPI2SEL_PLL           | x                         |
527   * |\ref SPI3_MODULE   |\ref CLK_CLKSEL3_SPI3SEL_HIRC          | x                         |
528   * |\ref SPI3_MODULE   |\ref CLK_CLKSEL3_SPI3SEL_HIRC48M       | x                         |
529   * |\ref SPI3_MODULE   |\ref CLK_CLKSEL3_SPI3SEL_HXT           | x                         |
530   * |\ref SPI3_MODULE   |\ref CLK_CLKSEL3_SPI3SEL_PCLK0         | x                         |
531   * |\ref SPI3_MODULE   |\ref CLK_CLKSEL3_SPI3SEL_PLL           | x                         |
532   * |\ref ST_MODULE     |\ref CLK_CLKSEL0_STCLKSEL_HCLK         | x                         |
533   * |\ref ST_MODULE     |\ref CLK_CLKSEL0_STCLKSEL_HCLK_DIV2    | x                         |
534   * |\ref ST_MODULE     |\ref CLK_CLKSEL0_STCLKSEL_HIRC_DIV2    | x                         |
535   * |\ref ST_MODULE     |\ref CLK_CLKSEL0_STCLKSEL_HXT          | x                         |
536   * |\ref ST_MODULE     |\ref CLK_CLKSEL0_STCLKSEL_HXT_DIV2     | x                         |
537   * |\ref ST_MODULE     |\ref CLK_CLKSEL0_STCLKSEL_LXT          | x                         |
538   * |\ref TK_MODULE     |\ref CLK_CLKSEL2_TKSEL_HIRC            | x                         |
539   * |\ref TK_MODULE     |\ref CLK_CLKSEL2_TKSEL_MIRC            | x                         |
540   * |\ref TMR0_MODULE   |\ref CLK_CLKSEL1_TMR0SEL_EXT           | x                         |
541   * |\ref TMR0_MODULE   |\ref CLK_CLKSEL1_TMR0SEL_HIRC          | x                         |
542   * |\ref TMR0_MODULE   |\ref CLK_CLKSEL1_TMR0SEL_HXT           | x                         |
543   * |\ref TMR0_MODULE   |\ref CLK_CLKSEL1_TMR0SEL_LIRC          | x                         |
544   * |\ref TMR0_MODULE   |\ref CLK_CLKSEL1_TMR0SEL_LXT           | x                         |
545   * |\ref TMR0_MODULE   |\ref CLK_CLKSEL1_TMR0SEL_PCLK0         | x                         |
546   * |\ref TMR1_MODULE   |\ref CLK_CLKSEL1_TMR1SEL_EXT           | x                         |
547   * |\ref TMR1_MODULE   |\ref CLK_CLKSEL1_TMR1SEL_HIRC          | x                         |
548   * |\ref TMR1_MODULE   |\ref CLK_CLKSEL1_TMR1SEL_HXT           | x                         |
549   * |\ref TMR1_MODULE   |\ref CLK_CLKSEL1_TMR1SEL_LIRC          | x                         |
550   * |\ref TMR1_MODULE   |\ref CLK_CLKSEL1_TMR1SEL_LXT           | x                         |
551   * |\ref TMR1_MODULE   |\ref CLK_CLKSEL1_TMR1SEL_PCLK0         | x                         |
552   * |\ref TMR2_MODULE   |\ref CLK_CLKSEL1_TMR2SEL_EXT           | x                         |
553   * |\ref TMR2_MODULE   |\ref CLK_CLKSEL1_TMR2SEL_HIRC          | x                         |
554   * |\ref TMR2_MODULE   |\ref CLK_CLKSEL1_TMR2SEL_HXT           | x                         |
555   * |\ref TMR2_MODULE   |\ref CLK_CLKSEL1_TMR2SEL_LIRC          | x                         |
556   * |\ref TMR2_MODULE   |\ref CLK_CLKSEL1_TMR2SEL_LXT           | x                         |
557   * |\ref TMR2_MODULE   |\ref CLK_CLKSEL1_TMR2SEL_PCLK1         | x                         |
558   * |\ref TMR3_MODULE   |\ref CLK_CLKSEL1_TMR3SEL_EXT           | x                         |
559   * |\ref TMR3_MODULE   |\ref CLK_CLKSEL1_TMR3SEL_HIRC          | x                         |
560   * |\ref TMR3_MODULE   |\ref CLK_CLKSEL1_TMR3SEL_HXT           | x                         |
561   * |\ref TMR3_MODULE   |\ref CLK_CLKSEL1_TMR3SEL_LIRC          | x                         |
562   * |\ref TMR3_MODULE   |\ref CLK_CLKSEL1_TMR3SEL_LXT           | x                         |
563   * |\ref TMR3_MODULE   |\ref CLK_CLKSEL1_TMR3SEL_PCLK1         | x                         |
564   * |\ref TTMR0_MODULE  |\ref LPSCC_CLKSEL0_TTMR0SEL_HIRC       | x                         |
565   * |\ref TTMR0_MODULE  |\ref LPSCC_CLKSEL0_TTMR0SEL_LIRC       | x                         |
566   * |\ref TTMR0_MODULE  |\ref LPSCC_CLKSEL0_TTMR0SEL_LXT        | x                         |
567   * |\ref TTMR0_MODULE  |\ref LPSCC_CLKSEL0_TTMR0SEL_MIRC       | x                         |
568   * |\ref TTMR1_MODULE  |\ref LPSCC_CLKSEL0_TTMR1SEL_HIRC       | x                         |
569   * |\ref TTMR1_MODULE  |\ref LPSCC_CLKSEL0_TTMR1SEL_LIRC       | x                         |
570   * |\ref TTMR1_MODULE  |\ref LPSCC_CLKSEL0_TTMR1SEL_LXT        | x                         |
571   * |\ref TTMR1_MODULE  |\ref LPSCC_CLKSEL0_TTMR1SEL_MIRC       | x                         |
572   * |\ref UART0_MODULE  |\ref CLK_CLKSEL4_UART0SEL_HIRC         |\ref CLK_CLKDIV0_UART0(x)  |
573   * |\ref UART0_MODULE  |\ref CLK_CLKSEL4_UART0SEL_HIRC48M      |\ref CLK_CLKDIV0_UART0(x)  |
574   * |\ref UART0_MODULE  |\ref CLK_CLKSEL4_UART0SEL_HXT          |\ref CLK_CLKDIV0_UART0(x)  |
575   * |\ref UART0_MODULE  |\ref CLK_CLKSEL4_UART0SEL_LXT          |\ref CLK_CLKDIV0_UART0(x)  |
576   * |\ref UART0_MODULE  |\ref CLK_CLKSEL4_UART0SEL_MIRC         |\ref CLK_CLKDIV0_UART0(x)  |
577   * |\ref UART0_MODULE  |\ref CLK_CLKSEL4_UART0SEL_PLL          |\ref CLK_CLKDIV0_UART0(x)  |
578   * |\ref UART1_MODULE  |\ref CLK_CLKSEL4_UART1SEL_HIRC         |\ref CLK_CLKDIV0_UART1(x)  |
579   * |\ref UART1_MODULE  |\ref CLK_CLKSEL4_UART1SEL_HIRC48M      |\ref CLK_CLKDIV0_UART1(x)  |
580   * |\ref UART1_MODULE  |\ref CLK_CLKSEL4_UART1SEL_HXT          |\ref CLK_CLKDIV0_UART1(x)  |
581   * |\ref UART1_MODULE  |\ref CLK_CLKSEL4_UART1SEL_LXT          |\ref CLK_CLKDIV0_UART1(x)  |
582   * |\ref UART1_MODULE  |\ref CLK_CLKSEL4_UART1SEL_MIRC         |\ref CLK_CLKDIV0_UART1(x)  |
583   * |\ref UART1_MODULE  |\ref CLK_CLKSEL4_UART1SEL_PLL          |\ref CLK_CLKDIV0_UART1(x)  |
584   * |\ref UART2_MODULE  |\ref CLK_CLKSEL4_UART2SEL_HIRC         |\ref CLK_CLKDIV4_UART2(x)  |
585   * |\ref UART2_MODULE  |\ref CLK_CLKSEL4_UART2SEL_HIRC48M      |\ref CLK_CLKDIV4_UART2(x)  |
586   * |\ref UART2_MODULE  |\ref CLK_CLKSEL4_UART2SEL_HXT          |\ref CLK_CLKDIV4_UART2(x)  |
587   * |\ref UART2_MODULE  |\ref CLK_CLKSEL4_UART2SEL_LXT          |\ref CLK_CLKDIV4_UART2(x)  |
588   * |\ref UART2_MODULE  |\ref CLK_CLKSEL4_UART2SEL_MIRC         |\ref CLK_CLKDIV4_UART2(x)  |
589   * |\ref UART2_MODULE  |\ref CLK_CLKSEL4_UART2SEL_PLL          |\ref CLK_CLKDIV4_UART2(x)  |
590   * |\ref UART3_MODULE  |\ref CLK_CLKSEL4_UART3SEL_HIRC         |\ref CLK_CLKDIV4_UART3(x)  |
591   * |\ref UART3_MODULE  |\ref CLK_CLKSEL4_UART3SEL_HIRC48M      |\ref CLK_CLKDIV4_UART3(x)  |
592   * |\ref UART3_MODULE  |\ref CLK_CLKSEL4_UART3SEL_HXT          |\ref CLK_CLKDIV4_UART3(x)  |
593   * |\ref UART3_MODULE  |\ref CLK_CLKSEL4_UART3SEL_LXT          |\ref CLK_CLKDIV4_UART3(x)  |
594   * |\ref UART3_MODULE  |\ref CLK_CLKSEL4_UART3SEL_MIRC         |\ref CLK_CLKDIV4_UART3(x)  |
595   * |\ref UART3_MODULE  |\ref CLK_CLKSEL4_UART3SEL_PLL          |\ref CLK_CLKDIV4_UART3(x)  |
596   * |\ref UART4_MODULE  |\ref CLK_CLKSEL4_UART4SEL_HIRC         |\ref CLK_CLKDIV4_UART4(x)  |
597   * |\ref UART4_MODULE  |\ref CLK_CLKSEL4_UART4SEL_HIRC48M      |\ref CLK_CLKDIV4_UART4(x)  |
598   * |\ref UART4_MODULE  |\ref CLK_CLKSEL4_UART4SEL_HXT          |\ref CLK_CLKDIV4_UART4(x)  |
599   * |\ref UART4_MODULE  |\ref CLK_CLKSEL4_UART4SEL_LXT          |\ref CLK_CLKDIV4_UART4(x)  |
600   * |\ref UART4_MODULE  |\ref CLK_CLKSEL4_UART4SEL_MIRC         |\ref CLK_CLKDIV4_UART4(x)  |
601   * |\ref UART4_MODULE  |\ref CLK_CLKSEL4_UART4SEL_PLL          |\ref CLK_CLKDIV4_UART4(x)  |
602   * |\ref UART5_MODULE  |\ref CLK_CLKSEL4_UART5SEL_HIRC         |\ref CLK_CLKDIV4_UART5(x)  |
603   * |\ref UART5_MODULE  |\ref CLK_CLKSEL4_UART5SEL_HIRC48M      |\ref CLK_CLKDIV4_UART5(x)  |
604   * |\ref UART5_MODULE  |\ref CLK_CLKSEL4_UART5SEL_HXT          |\ref CLK_CLKDIV4_UART5(x)  |
605   * |\ref UART5_MODULE  |\ref CLK_CLKSEL4_UART5SEL_LXT          |\ref CLK_CLKDIV4_UART5(x)  |
606   * |\ref UART5_MODULE  |\ref CLK_CLKSEL4_UART5SEL_MIRC         |\ref CLK_CLKDIV4_UART5(x)  |
607   * |\ref UART5_MODULE  |\ref CLK_CLKSEL4_UART5SEL_PLL          |\ref CLK_CLKDIV4_UART5(x)  |
608   * |\ref UART6_MODULE  |\ref CLK_CLKSEL4_UART6SEL_HIRC         |\ref CLK_CLKDIV4_UART6(x)  |
609   * |\ref UART6_MODULE  |\ref CLK_CLKSEL4_UART6SEL_HIRC48M      |\ref CLK_CLKDIV4_UART6(x)  |
610   * |\ref UART6_MODULE  |\ref CLK_CLKSEL4_UART6SEL_HXT          |\ref CLK_CLKDIV4_UART6(x)  |
611   * |\ref UART6_MODULE  |\ref CLK_CLKSEL4_UART6SEL_LXT          |\ref CLK_CLKDIV4_UART6(x)  |
612   * |\ref UART6_MODULE  |\ref CLK_CLKSEL4_UART6SEL_MIRC         |\ref CLK_CLKDIV4_UART6(x)  |
613   * |\ref UART6_MODULE  |\ref CLK_CLKSEL4_UART6SEL_PLL          |\ref CLK_CLKDIV4_UART6(x)  |
614   * |\ref UART7_MODULE  |\ref CLK_CLKSEL4_UART7SEL_HIRC         |\ref CLK_CLKDIV4_UART7(x)  |
615   * |\ref UART7_MODULE  |\ref CLK_CLKSEL4_UART7SEL_HIRC48M      |\ref CLK_CLKDIV4_UART7(x)  |
616   * |\ref UART7_MODULE  |\ref CLK_CLKSEL4_UART7SEL_HXT          |\ref CLK_CLKDIV4_UART7(x)  |
617   * |\ref UART7_MODULE  |\ref CLK_CLKSEL4_UART7SEL_LXT          |\ref CLK_CLKDIV4_UART7(x)  |
618   * |\ref UART7_MODULE  |\ref CLK_CLKSEL4_UART7SEL_MIRC         |\ref CLK_CLKDIV4_UART7(x)  |
619   * |\ref UART7_MODULE  |\ref CLK_CLKSEL4_UART7SEL_PLL          |\ref CLK_CLKDIV4_UART7(x)  |
620   * |\ref USBD_MODULE   |\ref CLK_CLKSEL0_USBSEL_HIRC48M        |\ref CLK_CLKDIV0_USB(x)    |
621   * |\ref USBD_MODULE   |\ref CLK_CLKSEL0_USBSEL_PLL            |\ref CLK_CLKDIV0_USB(x)    |
622   * |\ref USBH_MODULE   |\ref CLK_CLKSEL0_USBSEL_HIRC48M        |\ref CLK_CLKDIV0_USB(x)    |
623   * |\ref USBH_MODULE   |\ref CLK_CLKSEL0_USBSEL_PLL            |\ref CLK_CLKDIV0_USB(x)    |
624   * |\ref WDT_MODULE    |\ref LPSCC_CLKSEL0_WDTSEL_HCLK1_DIV2048| x                         |
625   * |\ref WDT_MODULE    |\ref LPSCC_CLKSEL0_WDTSEL_LIRC         | x                         |
626   * |\ref WDT_MODULE    |\ref LPSCC_CLKSEL0_WDTSEL_LXT          | x                         |
627   * |\ref WWDT_MODULE   |\ref CLK_CLKSEL1_WWDTSEL_HCLK_DIV2048  | x                         |
628   * |\ref WWDT_MODULE   |\ref CLK_CLKSEL1_WWDTSEL_LIRC          | x                         |
629   *
630   */
CLK_SetModuleClock(uint32_t u32ModuleIdx,uint32_t u32ClkSrc,uint32_t u32ClkDiv)631 void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv)
632 {
633     uint32_t u32sel = 0, u32div = 0;
634     uint32_t u32SelTbl[6] = {0x0, 0x04, 0x08, 0x0C, 0x38, 0x0}; /* CLKSEL offset on MODULE index, 0x0:CLKSEL0, 0x1:CLKSEL1, 0x2:CLKSEL2, 0x3:CLKSEL3, 0x4:CLKSEL4, 0x5:LPSCC_CLKSEL0 */
635     uint32_t u32DivTbl[4] = {0x0, 0x10, 0x1C, 0x0};             /* CLKDIV offset on MODULE index, 0x0:CLKDIV0, 0x1:CLKDIV4, 0x2:CLKDIV5, 0x3:LPSCC_CLKDIV0 */
636     uint32_t u32mask;
637 
638     if(MODULE_CLKDIV_Msk(u32ModuleIdx) != MODULE_NoMsk)
639     {
640         /* Get clock divider control register address */
641         if (MODULE_CLKDIV(u32ModuleIdx) == 3)
642         {
643             u32div = (uint32_t)&LPSCC->CLKDIV0;
644         }
645         else
646         {
647             u32div = (uint32_t)&CLK->CLKDIV0 + (u32DivTbl[MODULE_CLKDIV(u32ModuleIdx)]);
648         }
649 
650         /* Convert mask bit number to mask */
651         switch(MODULE_CLKDIV_Msk(u32ModuleIdx))
652         {
653         case 1:
654             u32mask = 0x1;
655             break;
656         case 2:
657             u32mask = 0x3;
658             break;
659         case 3:
660             u32mask = 0x7;
661             break;
662         case 4:
663             u32mask = 0xF;
664             break;
665         case 8:
666             u32mask = 0xFF;
667             break;
668         default:
669             u32mask = 0;
670             break;
671         }
672 
673         /* Apply new divider */
674         M32(u32div) = (M32(u32div) & (~(u32mask << MODULE_CLKDIV_Pos(u32ModuleIdx)))) | u32ClkDiv;
675     }
676 
677     if(MODULE_CLKSEL_Msk(u32ModuleIdx) != MODULE_NoMsk)
678     {
679         /* Get clock select control register address */
680         if (MODULE_CLKSEL(u32ModuleIdx) == 5)
681         {
682             u32sel = (uint32_t)&LPSCC->CLKSEL0;
683         }
684         else
685         {
686             u32sel = (uint32_t)&CLK->CLKSEL0 + (u32SelTbl[MODULE_CLKSEL(u32ModuleIdx)]);
687         }
688 
689         /* Convert mask bit number to mask */
690         switch(MODULE_CLKSEL_Msk(u32ModuleIdx))
691         {
692         case 1:
693             u32mask = 0x1;
694             break;
695         case 2:
696             u32mask = 0x3;
697             break;
698         case 3:
699             u32mask = 0x7;
700             break;
701         case 4:
702             u32mask = 0xF;
703             break;
704         case 8:
705             u32mask = 0xFF;
706             break;
707         default:
708             u32mask = 0;
709             break;
710         }
711 
712         /* Set new clock selection setting */
713         M32(u32sel) = (M32(u32sel) & (~(u32mask << MODULE_CLKSEL_Pos(u32ModuleIdx)))) | u32ClkSrc;
714     }
715 }
716 
717 /**
718   * @brief      Set SysTick clock source
719   * @param[in]  u32ClkSrc is module clock source. Including:
720   *             - \ref CLK_CLKSEL0_STCLKSEL_HXT
721   *             - \ref CLK_CLKSEL0_STCLKSEL_LXT
722   *             - \ref CLK_CLKSEL0_STCLKSEL_HXT_DIV2
723   *             - \ref CLK_CLKSEL0_STCLKSEL_HCLK_DIV2
724   *             - \ref CLK_CLKSEL0_STCLKSEL_HIRC_DIV2
725   *             - \ref CLK_CLKSEL0_STCLKSEL_HCLK
726   * @return     None
727   * @details    This function set SysTick clock source. \n
728   *             The register write-protection function should be disabled before using this function.
729   */
CLK_SetSysTickClockSrc(uint32_t u32ClkSrc)730 void CLK_SetSysTickClockSrc(uint32_t u32ClkSrc)
731 {
732     CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc;
733 }
734 
735 /**
736   * @brief      Enable clock source
737   * @param[in]  u32ClkMask is clock source mask. Including :
738   *             - \ref CLK_PWRCTL_HXTEN_Msk
739   *             - \ref CLK_PWRCTL_LXTEN_Msk
740   *             - \ref CLK_PWRCTL_HIRCEN_Msk
741   *             - \ref CLK_PWRCTL_LIRCEN_Msk
742   *             - \ref CLK_PWRCTL_HIRC48MEN_Msk
743   *             - \ref CLK_PWRCTL_MIRCEN_Msk
744   * @return     None
745   * @details    This function enable clock source. \n
746   *             The register write-protection function should be disabled before using this function.
747   */
CLK_EnableXtalRC(uint32_t u32ClkMask)748 void CLK_EnableXtalRC(uint32_t u32ClkMask)
749 {
750     CLK->PWRCTL |= u32ClkMask;
751 }
752 
753 /**
754   * @brief      Disable clock source
755   * @param[in]  u32ClkMask is clock source mask. Including :
756   *             - \ref CLK_PWRCTL_HXTEN_Msk
757   *             - \ref CLK_PWRCTL_LXTEN_Msk
758   *             - \ref CLK_PWRCTL_HIRCEN_Msk
759   *             - \ref CLK_PWRCTL_LIRCEN_Msk
760   *             - \ref CLK_PWRCTL_HIRC48MEN_Msk
761   *             - \ref CLK_PWRCTL_MIRCEN_Msk
762   * @return     None
763   * @details    This function disable clock source. \n
764   *             The register write-protection function should be disabled before using this function.
765   */
CLK_DisableXtalRC(uint32_t u32ClkMask)766 void CLK_DisableXtalRC(uint32_t u32ClkMask)
767 {
768     CLK->PWRCTL &= ~u32ClkMask;
769 }
770 
771 /**
772   * @brief      Enable module clock
773   * @param[in]  u32ModuleIdx is module index. Including :
774   *             - \ref ACMP01_MODULE
775   *             - \ref ACMP2_MODULE
776   *             - \ref CANFD0_MODULE
777   *             - \ref CANFD1_MODULE
778   *             - \ref CANRAM0_MODULE
779   *             - \ref CANRAM1_MODULE
780   *             - \ref CLKO_MODULE
781   *             - \ref CRC_MODULE
782   *             - \ref CRPT_MODULE
783   *             - \ref DAC_MODULE
784   *             - \ref EADC0_MODULE
785   *             - \ref EBI_MODULE
786   *             - \ref ECAP0_MODULE
787   *             - \ref ECAP1_MODULE
788   *             - \ref EPWM0_MODULE
789   *             - \ref EPWM1_MODULE
790   *             - \ref EQEI0_MODULE
791   *             - \ref EQEI1_MODULE
792   *             - \ref GPA_MODULE
793   *             - \ref GPB_MODULE
794   *             - \ref GPC_MODULE
795   *             - \ref GPD_MODULE
796   *             - \ref GPE_MODULE
797   *             - \ref GPF_MODULE
798   *             - \ref GPG_MODULE
799   *             - \ref GPH_MODULE
800   *             - \ref HCLK1_MODULE
801   *             - \ref I2C0_MODULE
802   *             - \ref I2C1_MODULE
803   *             - \ref I2C2_MODULE
804   *             - \ref I2C3_MODULE
805   *             - \ref ISP_MODULE
806   *             - \ref KS_MODULE
807   *             - \ref LPADC0_MODULE
808   *             - \ref LPGPIO_MODULE
809   *             - \ref LPI2C0_MODULE
810   *             - \ref LPI2C0_MODULE
811   *             - \ref LPPDMA0_MODULE
812   *             - \ref LPSPI0_MODULE
813   *             - \ref LPSRAM_MODULE
814   *             - \ref LPTMR0_MODULE
815   *             - \ref LPTMR1_MODULE
816   *             - \ref LPUART0_MODULE
817   *             - \ref OPA_MODULE
818   *             - \ref OTG_MODULE
819   *             - \ref PDMA0_MODULE
820   *             - \ref PWM0_MODULE
821   *             - \ref PWM1_MODULE
822   *             - \ref QSPI0_MODULE
823   *             - \ref RTC_MODULE
824   *             - \ref SPI0_MODULE
825   *             - \ref SPI1_MODULE
826   *             - \ref SPI2_MODULE
827   *             - \ref SPI3_MODULE
828   *             - \ref ST_MODULE
829   *             - \ref TK_MODULE
830   *             - \ref TMR0_MODULE
831   *             - \ref TMR1_MODULE
832   *             - \ref TMR2_MODULE
833   *             - \ref TMR3_MODULE
834   *             - \ref TRNG_MODULE
835   *             - \ref TTMR0_MODULE
836   *             - \ref TTMR1_MODULE
837   *             - \ref UART0_MODULE
838   *             - \ref UART1_MODULE
839   *             - \ref UART2_MODULE
840   *             - \ref UART3_MODULE
841   *             - \ref UART4_MODULE
842   *             - \ref UART5_MODULE
843   *             - \ref UART6_MODULE
844   *             - \ref UART7_MODULE
845   *             - \ref USBD_MODULE
846   *             - \ref USBH_MODULE
847   *             - \ref USCI0_MODULE
848   *             - \ref USCI1_MODULE
849   *             - \ref UTCPD0_MODULE
850   *             - \ref WDT_MODULE
851   *             - \ref WWDT_MODULE
852   * @return     None
853   * @details    This function is used to enable module clock.
854   */
CLK_EnableModuleClock(uint32_t u32ModuleIdx)855 void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
856 {
857     uint32_t u32ClkTbl[6] = {0x0, 0x4, 0x8, 0x34, 0x54, 00};    /* AHBCLK/APBCLK offset on MODULE index, 0x0:AHBCLK, 0x1:APBCLK0, 0x2:APBCLK1, 0x3:APBCLK2, 0x4:AHBCLK1, 0x5:LPSCC_CLKEN0 */
858 
859     if (MODULE_APBCLK(u32ModuleIdx) == 5)
860     {
861         *(volatile uint32_t *)((uint32_t)&LPSCC->CLKEN0)  |= 1 << MODULE_IP_EN_Pos(u32ModuleIdx);
862     }
863     else
864     {
865         *(volatile uint32_t *)((uint32_t)&CLK->AHBCLK0 + (u32ClkTbl[MODULE_APBCLK(u32ModuleIdx)]))  |= 1 << MODULE_IP_EN_Pos(u32ModuleIdx);
866     }
867 }
868 
869 /**
870   * @brief      Disable module clock
871   * @param[in]  u32ModuleIdx is module index. Including :
872   *             - \ref ACMP01_MODULE
873   *             - \ref ACMP2_MODULE
874   *             - \ref CANFD0_MODULE
875   *             - \ref CANFD1_MODULE
876   *             - \ref CANRAM0_MODULE
877   *             - \ref CANRAM1_MODULE
878   *             - \ref CLKO_MODULE
879   *             - \ref CRC_MODULE
880   *             - \ref CRPT_MODULE
881   *             - \ref DAC_MODULE
882   *             - \ref EADC0_MODULE
883   *             - \ref EBI_MODULE
884   *             - \ref ECAP0_MODULE
885   *             - \ref ECAP1_MODULE
886   *             - \ref EPWM0_MODULE
887   *             - \ref EPWM1_MODULE
888   *             - \ref EQEI0_MODULE
889   *             - \ref EQEI1_MODULE
890   *             - \ref GPA_MODULE
891   *             - \ref GPB_MODULE
892   *             - \ref GPC_MODULE
893   *             - \ref GPD_MODULE
894   *             - \ref GPE_MODULE
895   *             - \ref GPF_MODULE
896   *             - \ref GPG_MODULE
897   *             - \ref GPH_MODULE
898   *             - \ref HCLK1_MODULE
899   *             - \ref I2C0_MODULE
900   *             - \ref I2C1_MODULE
901   *             - \ref I2C2_MODULE
902   *             - \ref I2C3_MODULE
903   *             - \ref ISP_MODULE
904   *             - \ref KS_MODULE
905   *             - \ref LPADC0_MODULE
906   *             - \ref LPGPIO_MODULE
907   *             - \ref LPI2C0_MODULE
908   *             - \ref LPI2C0_MODULE
909   *             - \ref LPPDMA0_MODULE
910   *             - \ref LPSPI0_MODULE
911   *             - \ref LPSRAM_MODULE
912   *             - \ref LPTMR0_MODULE
913   *             - \ref LPTMR1_MODULE
914   *             - \ref LPUART0_MODULE
915   *             - \ref OPA_MODULE
916   *             - \ref OTG_MODULE
917   *             - \ref PDMA0_MODULE
918   *             - \ref PWM0_MODULE
919   *             - \ref PWM1_MODULE
920   *             - \ref QSPI0_MODULE
921   *             - \ref RTC_MODULE
922   *             - \ref SPI0_MODULE
923   *             - \ref SPI1_MODULE
924   *             - \ref SPI2_MODULE
925   *             - \ref SPI3_MODULE
926   *             - \ref ST_MODULE
927   *             - \ref TK_MODULE
928   *             - \ref TMR0_MODULE
929   *             - \ref TMR1_MODULE
930   *             - \ref TMR2_MODULE
931   *             - \ref TMR3_MODULE
932   *             - \ref TRNG_MODULE
933   *             - \ref TTMR0_MODULE
934   *             - \ref TTMR1_MODULE
935   *             - \ref UART0_MODULE
936   *             - \ref UART1_MODULE
937   *             - \ref UART2_MODULE
938   *             - \ref UART3_MODULE
939   *             - \ref UART4_MODULE
940   *             - \ref UART5_MODULE
941   *             - \ref UART6_MODULE
942   *             - \ref UART7_MODULE
943   *             - \ref USBD_MODULE
944   *             - \ref USBH_MODULE
945   *             - \ref USCI0_MODULE
946   *             - \ref USCI1_MODULE
947   *             - \ref UTCPD0_MODULE
948   *             - \ref WDT_MODULE
949   *             - \ref WWDT_MODULE
950   * @return     None
951   * @details    This function is used to disable module clock.
952   */
CLK_DisableModuleClock(uint32_t u32ModuleIdx)953 void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
954 {
955     uint32_t u32ClkTbl[6] = {0x0, 0x4, 0x8, 0x34, 0x54, 00};    /* AHBCLK/APBCLK offset on MODULE index, 0x0:AHBCLK, 0x1:APBCLK0, 0x2:APBCLK1, 0x3:APBCLK2, 0x4:AHBCLK1, 0x5:LPSCC_CLKEN0 */
956 
957     if (MODULE_APBCLK(u32ModuleIdx) == 5)
958     {
959         *(volatile uint32_t *)((uint32_t)&LPSCC->CLKEN0)  &= ~(1 << MODULE_IP_EN_Pos(u32ModuleIdx));
960     }
961     else
962     {
963         *(volatile uint32_t *)((uint32_t)&CLK->AHBCLK0 + (u32ClkTbl[MODULE_APBCLK(u32ModuleIdx)]))  &= ~(1 << MODULE_IP_EN_Pos(u32ModuleIdx));
964     }
965 }
966 
967 
968 /**
969   * @brief      Set PLL frequency
970   * @param[in]  u32PllClkSrc is PLL clock source. Including :
971   *             - \ref CLK_PLLCTL_PLLSRC_HXT
972   *             - \ref CLK_PLLCTL_PLLSRC_HIRC
973   * @param[in]  u32PllFreq is PLL frequency.
974   * @return     PLL frequency
975   * @details    This function is used to configure PLLCTL register to set specified PLL frequency. \n
976   *             The register write-protection function should be disabled before using this function.
977   */
CLK_EnablePLL(uint32_t u32PllClkSrc,uint32_t u32PllFreq)978 uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
979 {
980     uint32_t u32PllSrcClk, u32NR, u32NF, u32NO, u32CLK_SRC, u32Outdiv;
981     uint32_t u32Fref, u32Fvco, u32FoutOffset, u32Fout, u32MinFoutOffset, u32MinNF, u32MinNR;
982     uint32_t u32PLL_UpperLimit;
983 
984     /* Disable PLL first to avoid unstable when setting PLL */
985     CLK_DisablePLL();
986 
987     /* PLL source clock is from HXT */
988     if(u32PllClkSrc == CLK_PLLCTL_PLLSRC_HXT)
989     {
990         /* Enable HXT clock */
991         CLK->PWRCTL |= CLK_PWRCTL_HXTEN_Msk;
992 
993         /* Wait for HXT clock ready */
994         CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);
995 
996         /* Select PLL source clock from HXT */
997         u32CLK_SRC = CLK_PLLCTL_PLLSRC_HXT;
998         u32PllSrcClk = __HXT;
999 
1000         /* u32NR start from 1 since NR = INDIV + 1 */
1001         u32NR = 1UL;
1002     }
1003 
1004     /* PLL source clock is from HIRC */
1005     else
1006     {
1007         /* Enable HIRC clock */
1008         CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
1009 
1010         /* Wait for HIRC clock ready */
1011         CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
1012 
1013         /* Select PLL source clock from HIRC */
1014         u32CLK_SRC = CLK_PLLCTL_PLLSRC_HIRC;
1015         u32PllSrcClk = __HIRC;
1016 
1017         /* u32NR start from 1 since NR = INDIV + 1 */
1018         u32NR = 1UL;
1019     }
1020 
1021     /* u32PllFreq = FOUT = (FIN * 2 * (NF.x) / NR / NO) */
1022 
1023     /* Select "NO" according to request frequency */
1024     /* Constraint: PLL output frequency must <= 500MHz */
1025     /*             PLL output frequency must > 25MHz */
1026     u32PLL_UpperLimit = FREQ_500MHZ;
1027     if((u32PllFreq <= u32PLL_UpperLimit) && (u32PllFreq >= FREQ_25MHZ))
1028     {
1029         if (u32PllFreq <= FREQ_120MHZ)
1030         {
1031             /* NO = 4 only can support up to 120MHz to meet all constraints */
1032             u32NO = 4;
1033             u32Outdiv = 3;
1034         }
1035         else if (u32PllFreq <= FREQ_240MHZ)
1036         {
1037             /* NO = 2 only can support up to 240MHz to meet all constraints */
1038             u32NO = 2;
1039             u32Outdiv = 1;
1040         }
1041         else
1042         {
1043             /* NO = 1 only can support up to 500MHz to meet all constraints */
1044             u32NO = 1;
1045             u32Outdiv = 0;
1046         }
1047     }
1048     else
1049     {
1050         /* Wrong frequency request. Just return default setting. */
1051         goto lexit;
1052     }
1053 
1054     /* Find best solution for NR and NF */
1055     u32MinFoutOffset = (uint32_t) 0xFFFFFFFF;   /* initial u32MinFoutOffset to max value of uint32_t */
1056     u32MinNR = 0;
1057     u32MinNF = 0;
1058     for(; u32NR <= 32; u32NR++) /* max NR = 32 since NR = INDIV + 1 and INDIV = 0 ~ 31 */
1059     {
1060         u32Fref = u32PllSrcClk / u32NR;         /* FREF = FIN / NR */
1061         /* Constraint 2: 1MHz <= FREF <= 8MHz */
1062         if((u32Fref >= 1000000) && (u32Fref <= 8000000))
1063         {
1064             for(u32NF = 12; u32NF <= 255; u32NF++) /* NF = 12~255 and NF = FBDIV + 2 */
1065             {
1066                 u32Fvco = u32Fref * 2 * u32NF;  /* FVCO = FIN * 2 * (NF.x) / NR */
1067                 /* Constraint 3: 100MHz <= FVCO <= 500MHz */
1068                 if((u32Fvco >= 100000000) && (u32Fvco < 500000000))
1069                 {
1070                     u32Fout = u32Fvco / u32NO;
1071                     u32FoutOffset = (u32Fout > u32PllFreq) ? (u32Fout - u32PllFreq) : (u32PllFreq - u32Fout);
1072                     if(u32FoutOffset < u32MinFoutOffset)
1073                     {
1074                         /* Keep current FOUT and try to find better one */
1075                         u32MinFoutOffset = u32FoutOffset;
1076                         u32MinNR = u32NR;
1077                         u32MinNF = u32NF;
1078 
1079                         /* Break when get perfect results */
1080                         if(u32MinFoutOffset == 0)
1081                             break;
1082                     }
1083                 }
1084             }
1085         }
1086     }
1087 
1088     /* Enable and apply new PLL setting. */
1089     CLK->PLLCTL2 = (u32Outdiv << CLK_PLLCTL2_OUTDIV_Pos) |
1090                    ((u32MinNR - 1) << CLK_PLLCTL2_INDIV_Pos) |
1091                    ((u32MinNF - 2) << CLK_PLLCTL2_FBDIV_Pos);
1092     CLK->PLLCTL = u32CLK_SRC;
1093 
1094     /* Wait for PLL clock stable */
1095     CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);
1096 
1097     /* Return actual PLL output clock frequency */
1098     return (u32PllSrcClk / (u32NO * u32MinNR) * u32MinNF);
1099 
1100 lexit:
1101 
1102     /* Apply default PLL setting and return */
1103     CLK->PLLCTL2 = CLK_PLLCTL_72MHz;
1104     if(u32PllClkSrc == CLK_PLLCTL_PLLSRC_HXT)
1105         CLK->PLLCTL = CLK_PLLCTL_PLLSRC_HXT;
1106     else
1107         CLK->PLLCTL = CLK_PLLCTL_PLLSRC_HIRC;
1108 
1109     /* Wait for PLL clock stable */
1110     CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);
1111 
1112     return CLK_GetPLLClockFreq();
1113 }
1114 
1115 /**
1116   * @brief      Disable PLL
1117   * @param      None
1118   * @return     None
1119   * @details    This function set PLL in Power-down mode. \n
1120   *             The register write-protection function should be disabled before using this function.
1121   */
CLK_DisablePLL(void)1122 void CLK_DisablePLL(void)
1123 {
1124     CLK->PLLCTL |= CLK_PLLCTL_PD_Msk;
1125 }
1126 
1127 
1128 /**
1129   * @brief      This function check selected clock source status
1130   * @param[in]  u32ClkMask is selected clock source. Including :
1131   *             - \ref CLK_STATUS_HXTSTB_Msk
1132   *             - \ref CLK_STATUS_LXTSTB_Msk
1133   *             - \ref CLK_STATUS_HIRCSTB_Msk
1134   *             - \ref CLK_STATUS_LIRCSTB_Msk
1135   *             - \ref CLK_STATUS_PLLSTB_Msk
1136   *             - \ref CLK_STATUS_MIRCSTB_Msk
1137   *             - \ref CLK_STATUS_HIRC48MSTB_Msk
1138   * @retval     0  clock is not stable
1139   * @retval     1  clock is stable
1140   * @details    To wait for clock ready by specified clock source stable flag or timeout (~300ms)
1141   * @note       This function sets g_CLK_i32ErrCode to CLK_TIMEOUT_ERR if clock source status is not stable
1142   */
CLK_WaitClockReady(uint32_t u32ClkMask)1143 uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
1144 {
1145     int32_t i32TimeOutCnt = 2160000;
1146     uint32_t u32Ret = 1U;
1147 
1148     while((CLK->STATUS & u32ClkMask) != u32ClkMask)
1149     {
1150         if(i32TimeOutCnt-- <= 0)
1151         {
1152             u32Ret = 0U;
1153             break;
1154         }
1155     }
1156 
1157     if(i32TimeOutCnt == 0)
1158         g_CLK_i32ErrCode = CLK_TIMEOUT_ERR;
1159 
1160     return u32Ret;
1161 }
1162 
1163 /**
1164   * @brief      Enable System Tick counter
1165   * @param[in]  u32ClkSrc is System Tick clock source. Including:
1166   *             - \ref CLK_CLKSEL0_STCLKSEL_HXT
1167   *             - \ref CLK_CLKSEL0_STCLKSEL_LXT
1168   *             - \ref CLK_CLKSEL0_STCLKSEL_HXT_DIV2
1169   *             - \ref CLK_CLKSEL0_STCLKSEL_HCLK_DIV2
1170   *             - \ref CLK_CLKSEL0_STCLKSEL_HIRC_DIV2
1171   *             - \ref CLK_CLKSEL0_STCLKSEL_HCLK
1172   * @param[in]  u32Count is System Tick reload value. It could be 0~0xFFFFFF.
1173   * @return     None
1174   * @details    This function set System Tick clock source, reload value, enable System Tick counter and interrupt. \n
1175   *             The register write-protection function should be disabled before using this function.
1176   */
CLK_EnableSysTick(uint32_t u32ClkSrc,uint32_t u32Count)1177 void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
1178 {
1179     /* Set System Tick counter disabled */
1180     SysTick->CTRL = 0UL;
1181 
1182     /* Set System Tick clock source */
1183     if( u32ClkSrc == CLK_CLKSEL0_STCLKSEL_HCLK )
1184     {
1185         /* Disable System Tick clock source from external reference clock */
1186         CLK->AHBCLK0 &= ~CLK_AHBCLK0_STCKEN_Msk;
1187 
1188         /* Select System Tick clock source from core clock */
1189         SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
1190     }
1191     else
1192     {
1193         /* Enable System Tick clock source from external reference clock */
1194         CLK->AHBCLK0 |= CLK_AHBCLK0_STCKEN_Msk;
1195 
1196         /* Select System Tick external reference clock source */
1197         CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc;
1198 
1199         /* Select System Tick clock source from external reference clock */
1200         SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk;
1201     }
1202 
1203     /* Set System Tick reload value */
1204     SysTick->LOAD = u32Count;
1205 
1206     /* Clear System Tick current value and counter flag */
1207     SysTick->VAL = 0UL;
1208 
1209     /* Set System Tick interrupt enabled and counter enabled */
1210     SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
1211 }
1212 
1213 /**
1214   * @brief      Disable System Tick counter
1215   * @param      None
1216   * @return     None
1217   * @details    This function disable System Tick counter.
1218   */
CLK_DisableSysTick(void)1219 void CLK_DisableSysTick(void)
1220 {
1221     /* Set System Tick counter disabled */
1222     SysTick->CTRL = 0UL;
1223 }
1224 
1225 
1226 /**
1227   * @brief      Power-down mode selected
1228   * @param[in]  u32PDMode is power down mode index. Including :
1229   *             - \ref CLK_PMUCTL_PDMSEL_NPD0
1230   *             - \ref CLK_PMUCTL_PDMSEL_NPD1
1231   *             - \ref CLK_PMUCTL_PDMSEL_NPD2
1232   *             - \ref CLK_PMUCTL_PDMSEL_NPD3
1233   *             - \ref CLK_PMUCTL_PDMSEL_NPD4
1234   *             - \ref CLK_PMUCTL_PDMSEL_NPD5
1235   *             - \ref CLK_PMUCTL_PDMSEL_SPD0
1236   *             - \ref CLK_PMUCTL_PDMSEL_SPD1
1237   *             - \ref CLK_PMUCTL_PDMSEL_SPD2
1238   *             - \ref CLK_PMUCTL_PDMSEL_DPD0
1239   *             - \ref CLK_PMUCTL_PDMSEL_DPD1
1240   * @return     None
1241   * @details    This function is used to set power-down mode.
1242   */
1243 
CLK_SetPowerDownMode(uint32_t u32PDMode)1244 void CLK_SetPowerDownMode(uint32_t u32PDMode)
1245 {
1246     CLK->PMUCTL = (CLK->PMUCTL & ~(CLK_PMUCTL_PDMSEL_Msk)) | u32PDMode;
1247 }
1248 
1249 
1250 /**
1251  * @brief       Set Wake-up pin trigger type at Deep Power down mode
1252  *
1253  * @param[in]   u32Pin  The pin of specified GPIO.
1254  *                      CLK_DPDWKPIN_0:GPC.0, CLK_DPDWKPIN_1:GPB.0, CLK_DPDWKPIN_2:GPB.2, CLK_DPDWKPIN_3:GPB.12, CLK_DPDWKPIN_4:GPF.6, CLK_DPDWKPIN_5:GPA.12
1255  *              - \ref CLK_DPDWKPIN_0
1256  *              - \ref CLK_DPDWKPIN_1
1257  *              - \ref CLK_DPDWKPIN_2
1258  *              - \ref CLK_DPDWKPIN_3
1259  *              - \ref CLK_DPDWKPIN_4
1260  *              - \ref CLK_DPDWKPIN_5
1261  * @param[in]   u32TriggerType
1262  *              - \ref CLK_DPDWKPIN_DISABLE
1263  *              - \ref CLK_DPDWKPIN_RISING
1264  *              - \ref CLK_DPDWKPIN_FALLING
1265  *              - \ref CLK_DPDWKPIN_BOTHEDGE
1266  * @return      None
1267  *
1268  * @details     This function is used to enable Wake-up pin trigger type.
1269  */
CLK_EnableDPDWKPin(uint32_t u32Pin,uint32_t u32TriggerType)1270 void CLK_EnableDPDWKPin(uint32_t u32Pin, uint32_t u32TriggerType)
1271 {
1272     switch (u32Pin)
1273     {
1274     case CLK_DPDWKPIN_0:
1275         CLK->PMUWKCTL = (CLK->PMUWKCTL & ~CLK_PMUWKCTL_WKPINEN0_Msk) | (u32TriggerType << CLK_PMUWKCTL_WKPINEN0_Pos);
1276         break;
1277     case CLK_DPDWKPIN_1:
1278         CLK->PMUWKCTL = (CLK->PMUWKCTL & ~CLK_PMUWKCTL_WKPINEN1_Msk) | (u32TriggerType << CLK_PMUWKCTL_WKPINEN1_Pos);
1279         break;
1280     case CLK_DPDWKPIN_2:
1281         CLK->PMUWKCTL = (CLK->PMUWKCTL & ~CLK_PMUWKCTL_WKPINEN2_Msk) | (u32TriggerType << CLK_PMUWKCTL_WKPINEN2_Pos);
1282         break;
1283     case CLK_DPDWKPIN_3:
1284         CLK->PMUWKCTL = (CLK->PMUWKCTL & ~CLK_PMUWKCTL_WKPINEN3_Msk) | (u32TriggerType << CLK_PMUWKCTL_WKPINEN3_Pos);
1285         break;
1286     case CLK_DPDWKPIN_4:
1287         CLK->PMUWKCTL = (CLK->PMUWKCTL & ~CLK_PMUWKCTL_WKPINEN4_Msk) | (u32TriggerType << CLK_PMUWKCTL_WKPINEN4_Pos);
1288         break;
1289     case CLK_DPDWKPIN_5:
1290         CLK->PMUWKCTL = (CLK->PMUWKCTL & ~CLK_PMUWKCTL_WKPINEN5_Msk) | (u32TriggerType << CLK_PMUWKCTL_WKPINEN5_Pos);
1291         break;
1292     }
1293 }
1294 
1295 /**
1296  * @brief      Get power manager wake up source
1297  *
1298  * @param[in]   None
1299  * @return      None
1300  *
1301  * @details     This function get power manager wake up source.
1302  */
1303 
CLK_GetPMUWKSrc(void)1304 uint32_t CLK_GetPMUWKSrc(void)
1305 {
1306     return (CLK->PMUSTS);
1307 }
1308 
1309 /**
1310  * @brief       Set specified GPIO as wake up source at Stand-by Power down mode
1311  *
1312  * @param[in]   u32Port GPIO port. It could be 0 ~ 3.
1313  * @param[in]   u32Pin  The pin of specified GPIO port. It could be 0 ~ 15.
1314  * @param[in]   u32TriggerType
1315  *              - \ref CLK_SPDWKPIN_RISING
1316  *              - \ref CLK_SPDWKPIN_FALLING
1317  * @param[in]   u32DebounceEn
1318  *              - \ref CLK_SPDWKPIN_DEBOUNCEEN
1319  *              - \ref CLK_SPDWKPIN_DEBOUNCEDIS
1320  * @return      None
1321  *
1322  * @details     This function is used to set specified GPIO as wake up source
1323  *              at Stand-by Power down mode.
1324  */
CLK_EnableSPDWKPin(uint32_t u32Port,uint32_t u32Pin,uint32_t u32TriggerType,uint32_t u32DebounceEn)1325 void CLK_EnableSPDWKPin(uint32_t u32Port, uint32_t u32Pin, uint32_t u32TriggerType, uint32_t u32DebounceEn)
1326 {
1327     uint32_t u32tmpAddr = 0UL;
1328     uint32_t u32tmpVal = 0UL;
1329 
1330     /* GPx Stand-by Power-down Wake-up Pin Select */
1331     u32tmpAddr = (uint32_t)&CLK->PAPWCTL;
1332     u32tmpAddr += (0x4UL * u32Port);
1333 
1334     u32tmpVal = inpw((uint32_t *)u32tmpAddr);
1335     u32tmpVal = (u32tmpVal & ~(CLK_PAPWCTL_WKPSEL0_Msk | CLK_PAPWCTL_PRWKEN0_Msk | CLK_PAPWCTL_PFWKEN0_Msk | CLK_PAPWCTL_DBEN0_Msk | CLK_PAPWCTL_WKEN0_Msk)) |
1336                 (u32Pin << CLK_PAPWCTL_WKPSEL0_Pos) | u32TriggerType | u32DebounceEn | CLK_SPDWKPIN_ENABLE;
1337     outpw((uint32_t *)u32tmpAddr, u32tmpVal);
1338 }
1339 
1340 /**
1341   * @brief      Get PLL clock frequency
1342   * @param      None
1343   * @return     PLL frequency
1344   * @details    This function get PLL frequency. The frequency unit is Hz.
1345   */
CLK_GetPLLClockFreq(void)1346 uint32_t CLK_GetPLLClockFreq(void)
1347 {
1348     uint32_t u32PllFreq = 0UL, u32PllReg, u32Pll2Reg;
1349     uint32_t u32FIN, u32NF, u32NR, u32NO;
1350     uint8_t au8NoTbl[4] = {1U, 2U, 2U, 4U};
1351 
1352     u32PllReg = CLK->PLLCTL;
1353     u32Pll2Reg = CLK->PLLCTL2;
1354 
1355     if(u32PllReg & (CLK_PLLCTL_PD_Msk | CLK_PLLCTL_OE_Msk))
1356     {
1357         u32PllFreq = 0UL;           /* PLL is in power down mode or fix low */
1358     }
1359     else if((u32PllReg & CLK_PLLCTL_BP_Msk) == CLK_PLLCTL_BP_Msk)
1360     {
1361         if((u32PllReg & CLK_PLLCTL_PLLSRC_HIRC) == CLK_PLLCTL_PLLSRC_HIRC)
1362         {
1363             u32FIN = __HIRC;    /* PLL source clock from HIRC */
1364         }
1365         else
1366         {
1367             u32FIN = __HXT;     /* PLL source clock from HXT */
1368         }
1369 
1370         u32PllFreq = u32FIN;
1371     }
1372     else
1373     {
1374         if((u32PllReg & CLK_PLLCTL_PLLSRC_HIRC) == CLK_PLLCTL_PLLSRC_HIRC)
1375         {
1376             u32FIN = __HIRC;    /* PLL source clock from HIRC */
1377         }
1378         else
1379         {
1380             u32FIN = __HXT;     /* PLL source clock from HXT */
1381         }
1382         /* PLL is output enabled in normal work mode */
1383         u32NO = au8NoTbl[((u32Pll2Reg & CLK_PLLCTL2_OUTDIV_Msk) >> CLK_PLLCTL2_OUTDIV_Pos)];
1384         u32NF = ((u32Pll2Reg & CLK_PLLCTL2_FBDIV_Msk) >> CLK_PLLCTL2_FBDIV_Pos) + 2UL;
1385         u32NR = ((u32Pll2Reg & CLK_PLLCTL2_INDIV_Msk) >> CLK_PLLCTL2_INDIV_Pos) + 1UL;
1386 
1387         /* u32FIN is shifted right 2 bits first to avoid overflow. */
1388         /* It will be shifted left 2 bits back later. */
1389         u32PllFreq = (((u32FIN >> 2) * u32NF) / (u32NR * u32NO) << 2) * 2UL;
1390     }
1391 
1392     return u32PllFreq;
1393 }
1394 
1395 /**
1396   * @brief      Get selected module clock source
1397   * @param[in]  u32ModuleIdx is module index.
1398   *             - \ref CANFD0_MODULE
1399   *             - \ref CANFD1_MODULE
1400   *             - \ref CLKO_MODULE
1401   *             - \ref EADC0_MODULE
1402   *             - \ref EPWM0_MODULE
1403   *             - \ref EPWM1_MODULE
1404   *             - \ref HCLK1_MODULE
1405   *             - \ref LPADC0_MODULE
1406   *             - \ref LPSPI0_MODULE
1407   *             - \ref LPTMR0_MODULE
1408   *             - \ref LPTMR1_MODULE
1409   *             - \ref LPUART0_MODULE
1410   *             - \ref PWM0_MODULE
1411   *             - \ref PWM1_MODULE
1412   *             - \ref QSPI0_MODULE
1413   *             - \ref SPI0_MODULE
1414   *             - \ref SPI1_MODULE
1415   *             - \ref SPI2_MODULE
1416   *             - \ref SPI3_MODULE
1417   *             - \ref ST_MODULE
1418   *             - \ref TK_MODULE
1419   *             - \ref TMR0_MODULE
1420   *             - \ref TMR1_MODULE
1421   *             - \ref TMR2_MODULE
1422   *             - \ref TMR3_MODULE
1423   *             - \ref TTMR0_MODULE
1424   *             - \ref TTMR1_MODULE
1425   *             - \ref UART0_MODULE
1426   *             - \ref UART1_MODULE
1427   *             - \ref UART2_MODULE
1428   *             - \ref UART3_MODULE
1429   *             - \ref UART4_MODULE
1430   *             - \ref UART5_MODULE
1431   *             - \ref UART6_MODULE
1432   *             - \ref UART7_MODULE
1433   *             - \ref USBD_MODULE
1434   *             - \ref USBH_MODULE
1435   *             - \ref WDT_MODULE
1436   *             - \ref WWDT_MODULE
1437   * @return     Selected module clock source setting
1438   * @details    This function get selected module clock source.
1439   */
CLK_GetModuleClockSource(uint32_t u32ModuleIdx)1440 uint32_t CLK_GetModuleClockSource(uint32_t u32ModuleIdx)
1441 {
1442     uint32_t u32sel = 0;
1443     uint32_t u32SelTbl[6] = {0x0, 0x04, 0x08, 0x0C, 0x38, 0x0}; /* CLKSEL offset on MODULE index, 0x0:CLKSEL0, 0x1:CLKSEL1, 0x2:CLKSEL2, 0x3:CLKSEL3, 0x4:CLKSEL4, 0x5:LPSCC_CLKSEL0 */
1444     uint32_t u32mask;
1445 
1446     /* Get clock source selection setting */
1447     if(MODULE_CLKSEL_Msk(u32ModuleIdx) != MODULE_NoMsk)
1448     {
1449         /* Get clock select control register address */
1450         if (MODULE_CLKSEL(u32ModuleIdx) == 5)
1451         {
1452             u32sel = (uint32_t)&LPSCC->CLKSEL0;
1453         }
1454         else
1455         {
1456             u32sel = (uint32_t)&CLK->CLKSEL0 + (u32SelTbl[MODULE_CLKSEL(u32ModuleIdx)]);
1457         }
1458 
1459         /* Convert mask bit number to mask */
1460         switch(MODULE_CLKSEL_Msk(u32ModuleIdx))
1461         {
1462         case 1:
1463             u32mask = 0x1;
1464             break;
1465         case 2:
1466             u32mask = 0x3;
1467             break;
1468         case 3:
1469             u32mask = 0x7;
1470             break;
1471         case 4:
1472             u32mask = 0xF;
1473             break;
1474         case 8:
1475             u32mask = 0xFF;
1476             break;
1477         default:
1478             u32mask = 0;
1479             break;
1480         }
1481 
1482         /* Get clock source selection setting */
1483         return ((M32(u32sel) & (u32mask << MODULE_CLKSEL_Pos(u32ModuleIdx))) >> MODULE_CLKSEL_Pos(u32ModuleIdx));
1484     }
1485     else
1486         return 0;
1487 }
1488 
1489 /**
1490   * @brief      Get selected module clock divider number
1491   * @param[in]  u32ModuleIdx is module index.
1492   *             - \ref CANFD0_MODULE
1493   *             - \ref CANFD1_MODULE
1494   *             - \ref EADC0_MODULE
1495   *             - \ref HCLK1_MODULE
1496   *             - \ref LPADC0_MODULE
1497   *             - \ref LPUART0_MODULE
1498   *             - \ref UART0_MODULE
1499   *             - \ref UART1_MODULE
1500   *             - \ref UART2_MODULE
1501   *             - \ref UART3_MODULE
1502   *             - \ref UART4_MODULE
1503   *             - \ref UART5_MODULE
1504   *             - \ref UART6_MODULE
1505   *             - \ref UART7_MODULE
1506   *             - \ref USBD_MODULE
1507   *             - \ref USBH_MODULE
1508   * @return     Selected module clock divider number setting
1509   * @details    This function get selected module clock divider number.
1510   */
CLK_GetModuleClockDivider(uint32_t u32ModuleIdx)1511 uint32_t CLK_GetModuleClockDivider(uint32_t u32ModuleIdx)
1512 {
1513     uint32_t u32div = 0;
1514     uint32_t u32DivTbl[4] = {0x0, 0x10, 0x1C, 0x0};             /* CLKDIV offset on MODULE index, 0x0:CLKDIV0, 0x1:CLKDIV4, 0x2:CLKDIV5, 0x3:LPSCC_CLKDIV0 */
1515     uint32_t u32mask;
1516 
1517     if(MODULE_CLKDIV_Msk(u32ModuleIdx) != MODULE_NoMsk)
1518     {
1519         /* Get clock divider control register address */
1520         if (MODULE_CLKDIV(u32ModuleIdx) == 3)
1521         {
1522             u32div = (uint32_t)&LPSCC->CLKDIV0;
1523         }
1524         else
1525         {
1526             u32div = (uint32_t)&CLK->CLKDIV0 + (u32DivTbl[MODULE_CLKDIV(u32ModuleIdx)]);
1527         }
1528 
1529         /* Convert mask bit number to mask */
1530         switch(MODULE_CLKDIV_Msk(u32ModuleIdx))
1531         {
1532         case 1:
1533             u32mask = 0x1;
1534             break;
1535         case 2:
1536             u32mask = 0x3;
1537             break;
1538         case 3:
1539             u32mask = 0x7;
1540             break;
1541         case 4:
1542             u32mask = 0xF;
1543             break;
1544         case 8:
1545             u32mask = 0xFF;
1546             break;
1547         default:
1548             u32mask = 0;
1549             break;
1550         }
1551 
1552         /* Get clock divider number setting */
1553         return ((M32(u32div) & (u32mask << MODULE_CLKDIV_Pos(u32ModuleIdx))) >> MODULE_CLKDIV_Pos(u32ModuleIdx));
1554     }
1555     else
1556         return 0;
1557 }
1558 
1559 /**
1560   * @brief      Get internal multiple speed RC oscillator (MIRC) clock frequency
1561   * @param      None
1562   * @return     Internal multiple speed RC oscillator (MIRC) clock frequency
1563   * @details    This function get internal multiple speed RC oscillator (MIRC) clock frequency. The frequency unit is Hz.
1564   */
CLK_GetMIRCFreq(void)1565 uint32_t CLK_GetMIRCFreq(void)
1566 {
1567     uint32_t u32Freq = 0UL;
1568 
1569     if((CLK->PWRCTL & CLK_PWRCTL_MIRCEN_Msk) == CLK_PWRCTL_MIRCEN_Msk)
1570     {
1571         switch (CLK->PWRCTL & CLK_PWRCTL_MIRCFSEL_Msk)
1572         {
1573         case CLK_PWRCTL_MIRCFSEL_1M:
1574             u32Freq = FREQ_1MHZ;
1575             break;
1576         case CLK_PWRCTL_MIRCFSEL_2M:
1577             u32Freq = FREQ_2MHZ;
1578             break;
1579         case CLK_PWRCTL_MIRCFSEL_4M:
1580             u32Freq = FREQ_4MHZ;
1581             break;
1582         case CLK_PWRCTL_MIRCFSEL_8M:
1583             u32Freq = FREQ_8MHZ;
1584             break;
1585         default:
1586             u32Freq = __MIRC;
1587             break;
1588         }
1589     }
1590     else
1591     {
1592         u32Freq = 0UL;
1593     }
1594 
1595     return u32Freq;
1596 }
1597 
1598 /**
1599   * @brief      Disable MIRC
1600   * @param      None
1601   * @return     None
1602   * @details    This function disable MIRC clock. \n
1603   *             The register write-protection function should be disabled before using this function.
1604   */
CLK_DisableMIRC(void)1605 void CLK_DisableMIRC(void)
1606 {
1607     CLK->PWRCTL &= ~CLK_PWRCTL_MIRCEN_Msk;
1608 }
1609 
1610 /**
1611   * @brief      Set MIRC frequency
1612   * @param[in]  u32MircFreq is MIRC clock frequency. Including :
1613   *             - \ref CLK_PWRCTL_MIRCFSEL_1M
1614   *             - \ref CLK_PWRCTL_MIRCFSEL_2M
1615   *             - \ref CLK_PWRCTL_MIRCFSEL_4M
1616   *             - \ref CLK_PWRCTL_MIRCFSEL_8M
1617   * @return     MIRC frequency
1618   * @details    This function is used to configure PWRCTL register to set specified MIRC frequency. \n
1619   *             The register write-protection function should be disabled before using this function.
1620   */
CLK_EnableMIRC(uint32_t u32MircFreq)1621 uint32_t CLK_EnableMIRC(uint32_t u32MircFreq)
1622 {
1623     /* Disable MIRC first to avoid unstable when setting MIRC */
1624     CLK_DisableMIRC();
1625 
1626     /* Enable and apply new MIRC setting. */
1627     CLK->PWRCTL = (CLK->PWRCTL & ~(CLK_PWRCTL_MIRCFSEL_Msk)) | (u32MircFreq | CLK_PWRCTL_MIRCEN_Msk);
1628 
1629     /* Wait for MIRC clock stable */
1630     CLK_WaitClockReady(CLK_STATUS_MIRCSTB_Msk);
1631 
1632     /* Return actual MIRC output clock frequency */
1633     return CLK_GetMIRCFreq();
1634 }
1635 
1636 
1637 /*@}*/ /* end of group CLK_EXPORTED_FUNCTIONS */
1638 
1639 /*@}*/ /* end of group CLK_Driver */
1640 
1641 /*@}*/ /* end of group Standard_Driver */
1642 
1643 /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/
1644