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