| Nano100AN Series BSP V3.02.002 The Board Support Package for Nano100AN Series

clk.c
Go to the documentation of this file.
1 /**************************************************************************/
13 #include "Nano100Series.h"
32 void CLK_DisableCKO(void)
33 {
34 /* Disable CKO0 clock source */
35 CLK->APBCLK &= (~CLK_APBCLK_FDIV_EN_Msk);
36 }
37
55 void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
56 {
57 /* CKO = clock source / 2^(u32ClkDiv + 1) */
58 CLK->FRQDIV = CLK_FRQDIV_FDIV_EN_Msk | u32ClkDiv ;
59
60 /* Enable CKO clock source */
61 CLK->APBCLK |= CLK_APBCLK_FDIV_EN_Msk;
62
63 /* Select CKO clock source */
64 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_FRQDIV_S_Msk)) | u32ClkSrc;
65 }
66
72 void CLK_PowerDown(void)
73 {
74 SCB->SCR = SCB_SCR_SLEEPDEEP_Msk;
75 CLK->PWRCTL |= (CLK_PWRCTL_PD_EN_Msk | CLK_PWRCTL_WK_DLY_Msk );
76 __WFI();
77 }
78
84 void CLK_Idle(void)
85 {
86 CLK->PWRCTL &= ~(CLK_PWRCTL_PD_EN_Msk );
87 __WFI();
88 }
89
95 uint32_t CLK_GetHXTFreq(void)
96 {
97 if(CLK->PWRCTL & CLK_PWRCTL_HXT_EN_Msk )
98 return __HXT;
99 else
100 return 0;
101 }
102
108 uint32_t CLK_GetLXTFreq(void)
109 {
110 if(CLK->PWRCTL & CLK_PWRCTL_LXT_EN_Msk )
111 return __LXT;
112 else
113 return 0;
114 }
115
121 uint32_t CLK_GetHCLKFreq(void)
122 {
123 SystemCoreClockUpdate();
124 return SystemCoreClock;
125 }
126
127
133 uint32_t CLK_GetCPUFreq(void)
134 {
135 SystemCoreClockUpdate();
136 return SystemCoreClock;
137 }
138
144 uint32_t CLK_GetPLLClockFreq(void)
145 {
146 uint32_t u32Freq =0, u32PLLSrc;
147 uint32_t u32NO, u32NR, u32IN_DV, u32PllReg;
148
149 u32PllReg = CLK->PLLCTL;
150
151 if (u32PllReg & CLK_PLLCTL_PD_Msk)
152 return 0; /* PLL is in power down mode */
153
154 if (u32PllReg & CLK_PLLCTL_PLL_SRC_Msk)
155 u32PLLSrc = __HIRC12M;
156 else
157 u32PLLSrc = __HXT;
158
159 u32NO = (u32PllReg & CLK_PLLCTL_OUT_DV_Msk) ? 2: 1;
160
161 u32IN_DV = (u32PllReg & CLK_PLLCTL_IN_DV_Msk) >> 8;
162 if (u32IN_DV == 0)
163 u32NR = 2;
164 else if (u32IN_DV == 1)
165 u32NR = 4;
166 else if (u32IN_DV == 2)
167 u32NR = 8;
168 else
169 u32NR = 16;
170
171 u32Freq = u32PLLSrc * ((u32PllReg & CLK_PLLCTL_FB_DV_Msk) +32) / u32NR / u32NO;
172
173 return u32Freq;
174 }
175
181 uint32_t CLK_SetCoreClock(uint32_t u32Hclk)
182 {
183 uint32_t u32HIRCSTB;
184 /* Read HIRC clock source stable flag */
185 u32HIRCSTB = CLK->CLKSTATUS & CLK_CLKSTATUS_HIRC_STB_Msk;
186
187 if(u32Hclk==__HIRC12M)
188 {
189 CLK_EnableXtalRC(CLK_PWRCTL_HIRC_EN_Msk);
190 CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC,CLK_HCLK_CLK_DIVIDER(1));
191 return SystemCoreClock;
192 }
193
194 if(u32Hclk<FREQ_24MHZ) u32Hclk=FREQ_24MHZ;
195 if(u32Hclk>FREQ_32MHZ) u32Hclk=FREQ_32MHZ;
196
197 /* Configure PLL setting if HXT clock is enabled */
198 if(CLK->PWRCTL & CLK_PWRCTL_HXT_EN_Msk)
199 CLK_EnablePLL(CLK_PLLCTL_PLL_SRC_HXT,u32Hclk*3);
200
201 /* Configure PLL setting if HXT clock is not enabled */
202 else
203 {
204 CLK_EnablePLL(CLK_PLLCTL_PLL_SRC_HIRC,u32Hclk*3);
205
206 /* Read HIRC clock source stable flag */
207 u32HIRCSTB = CLK->CLKSTATUS & CLK_CLKSTATUS_HIRC_STB_Msk;
208 }
209
210 /* Select HCLK clock source to PLL,
211 Select HCLK clock source divider as 3
212 and update system core clock
213 */
214 CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_PLL,CLK_HCLK_CLK_DIVIDER(3));
215
216 /* Disable HIRC if HIRC is disabled before setting core clock */
217 if(u32HIRCSTB == 0)
218 CLK->PWRCTL &= ~CLK_PWRCTL_HIRC_EN_Msk;
219
220 return SystemCoreClock;
221 }
222
235 void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
236 {
237 uint32_t u32HIRCSTB;
238
239 /* Read HIRC clock source stable flag */
240 u32HIRCSTB = CLK->CLKSTATUS & CLK_CLKSTATUS_HIRC_STB_Msk;
241
242 /* Switch to HIRC for Safe. Avoid HCLK too high when applying new divider. */
243 CLK->PWRCTL |= CLK_PWRCTL_HIRC_EN_Msk;
244 CLK_WaitClockReady(CLK_CLKSTATUS_HIRC_STB_Msk);
245 CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLK_S_Msk)) | CLK_CLKSEL0_HCLK_S_HIRC;
246
247 /* Apply new Divider */
248 CLK->CLKDIV0 = (CLK->CLKDIV0 & ~CLK_CLKDIV0_HCLK_N_Msk) | u32ClkDiv;
249
250 /* Switch to new HCLK source */
251 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_HCLK_S_Msk) | u32ClkSrc;
252 SystemCoreClockUpdate();
253
254 /* Disable HIRC if HIRC is disabled before switching HCLK source */
255 if(u32HIRCSTB == 0)
256 CLK->PWRCTL &= ~CLK_CLKSTATUS_HIRC_STB_Msk;
257 }
258
350 void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv)
351 {
352 uint32_t u32tmp=0,u32sel=0,u32div=0;
353
354 if(MODULE_CLKDIV_Msk(u32ModuleIdx)!=MODULE_NoMsk)
355 {
356 u32div =(uint32_t)&CLK->CLKDIV0+((MODULE_CLKDIV(u32ModuleIdx))*4);
357 u32tmp = *(volatile uint32_t *)(u32div);
358 u32tmp = ( u32tmp & ~(MODULE_CLKDIV_Msk(u32ModuleIdx)<<MODULE_CLKDIV_Pos(u32ModuleIdx)) ) | u32ClkDiv;
359 *(volatile uint32_t *)(u32div) = u32tmp;
360 }
361
362 if(MODULE_CLKSEL_Msk(u32ModuleIdx)!=MODULE_NoMsk)
363 {
364 u32sel = (uint32_t)&CLK->CLKSEL0+((MODULE_CLKSEL(u32ModuleIdx))*4);
365 u32tmp = *(volatile uint32_t *)(u32sel);
366 u32tmp = ( u32tmp & ~(MODULE_CLKSEL_Msk(u32ModuleIdx)<<MODULE_CLKSEL_Pos(u32ModuleIdx)) ) | u32ClkSrc;
367 *(volatile uint32_t *)(u32sel) = u32tmp;
368 }
369 }
370
380 void CLK_EnableXtalRC(uint32_t u32ClkMask)
381 {
382 CLK->PWRCTL |= u32ClkMask;
383 if(u32ClkMask & CLK_PWRCTL_HXT_EN_Msk)
384 CLK_WaitClockReady(CLK_CLKSTATUS_HXT_STB_Msk);
385
386 if(u32ClkMask & CLK_PWRCTL_LXT_EN_Msk)
387 CLK_WaitClockReady(CLK_CLKSTATUS_LXT_STB_Msk);
388
389 if(u32ClkMask & CLK_PWRCTL_HIRC_EN_Msk)
390 CLK_WaitClockReady(CLK_CLKSTATUS_HIRC_STB_Msk);
391
392 if(u32ClkMask & CLK_PWRCTL_LIRC_EN_Msk)
393 CLK_WaitClockReady(CLK_CLKSTATUS_LIRC_STB_Msk);
394 }
395
405 void CLK_DisableXtalRC(uint32_t u32ClkMask)
406 {
407 CLK->PWRCTL &= ~u32ClkMask;
408 }
409
444 void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
445 {
446 *(volatile uint32_t *)((uint32_t)&CLK->AHBCLK+(MODULE_APBCLK(u32ModuleIdx)*4)) |= 1<<MODULE_IP_EN_Pos(u32ModuleIdx);
447 }
448
483 void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
484 {
485 *(volatile uint32_t *)((uint32_t)&CLK->AHBCLK+(MODULE_APBCLK(u32ModuleIdx)*4)) &= ~(1<<MODULE_IP_EN_Pos(u32ModuleIdx));
486 }
487
496 uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
497 {
498 uint32_t u32ClkSrc,u32NR, u32NF,u32Register;
499 uint32_t u32NRTable[4]= {2,4,8,16};
500 int32_t i32NRVal;
501 if ( u32PllFreq < FREQ_48MHZ)
502 u32PllFreq=FREQ_48MHZ;
503 else if(u32PllFreq > FREQ_120MHZ)
504 u32PllFreq=FREQ_120MHZ;
505
506 if(u32PllClkSrc!=CLK_PLLCTL_PLL_SRC_HIRC)
507 {
508 /* PLL source clock from HXT */
509 u32Register = (0x0UL<<CLK_PLLCTL_PLL_SRC_Pos);
510 u32ClkSrc = __HXT;
511 }
512 else
513 {
514 /* PLL source clock from HIRC */
515 u32Register = (0x1UL<<CLK_PLLCTL_PLL_SRC_Pos);
516 u32ClkSrc =__HIRC12M;
517 }
518
519 u32NF = u32PllFreq / 1000000;
520 u32NR = u32ClkSrc / 1000000;
521 if(u32ClkSrc%12==0)
522 {
523 u32NF=(u32NF/3)*4;
524 u32NR=(u32NR/3)*4;
525 }
526
527 while( u32NR>16 || u32NF>(0x3F+32) )
528 {
529 u32NR = u32NR>>1;
530 u32NF = u32NF>>1;
531 }
532
533 for(i32NRVal=3; i32NRVal>=0; i32NRVal--)
534 if(u32NR==u32NRTable[i32NRVal]) break;
535
536 CLK->PLLCTL = u32Register | (i32NRVal<<8) | (u32NF - 32) ;
537
538 CLK->PLLCTL &= ~CLK_PLLCTL_PD_Msk;
539
540 CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk);
541
542 return CLK_GetPLLClockFreq();
543
544 }
545
551 void CLK_DisablePLL(void)
552 {
553 CLK->PLLCTL |= CLK_PLLCTL_PD_Msk;
554 }
555
564 void CLK_SysTickDelay(uint32_t us)
565 {
566 SysTick->LOAD = us * CyclesPerUs;
567 SysTick->VAL = (0x00);
568 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
569
570 /* Waiting for down-count to zero */
571 while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
572 SysTick->CTRL = 0;
573 }
574
585 void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
586 {
587 SysTick->CTRL=0;
588 if( u32ClkSrc== CLK_CLKSEL0_STCLKSEL_HCLK ) /* Set System Tick clock source */
589 SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
590 else
591 {
592 SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk;
593 }
594 SysTick->LOAD = u32Count; /* Set System Tick reload value */
595 SysTick->VAL = 0; /* Clear System Tick current value and counter flag */
596 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; /* Set System Tick counter enabled */
597 }
598
604 void CLK_DisableSysTick(void)
605 {
606 SysTick->CTRL = 0; /* Set System Tick counter disabled */
607 }
608
623 uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
624 {
625 int32_t i32TimeOutCnt;
626
627 i32TimeOutCnt = __HSI / 200; /* About 5ms */
628
629 while((CLK->CLKSTATUS & u32ClkMask) != u32ClkMask)
630 {
631 if(i32TimeOutCnt-- <= 0)
632 return 0;
633 }
634 return 1;
635 }
636
637 /* end of group NANO100_CLK_EXPORTED_FUNCTIONS */
639 /* end of group NANO100_CLK_Driver */
641 /* end of group NANO100_Device_Driver */
643
644 /*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
645
SystemCoreClock
uint32_t SystemCoreClock
Definition: system_Nano100Series.c:20
CLK_PWRCTL_WK_DLY_Msk
#define CLK_PWRCTL_WK_DLY_Msk
Definition: Nano100Series.h:1051
CLK_PWRCTL_HXT_EN_Msk
#define CLK_PWRCTL_HXT_EN_Msk
Definition: Nano100Series.h:1039
CLK_DisableSysTick
void CLK_DisableSysTick(void)
Disable System Tick counter.
Definition: clk.c:604
MODULE_NoMsk
#define MODULE_NoMsk
Definition: clk.h:205
CLK_EnableSysTick
void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
Enable System Tick counter.
Definition: clk.c:585
CLK_GetLXTFreq
uint32_t CLK_GetLXTFreq(void)
This function get external low frequency crystal frequency. The frequency unit is Hz.
Definition: clk.c:108
CLK_CLKSEL0_HCLK_S_PLL
#define CLK_CLKSEL0_HCLK_S_PLL
Definition: clk.h:87
CLK_PLLCTL_PLL_SRC_HIRC
#define CLK_PLLCTL_PLL_SRC_HIRC
Definition: clk.h:191
CLK_EnableModuleClock
void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
This function enable module clock.
Definition: clk.c:444
CLK_SysTickDelay
void CLK_SysTickDelay(uint32_t us)
This function execute delay function.
Definition: clk.c:564
CLK_DisableModuleClock
void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
This function disable module clock.
Definition: clk.c:483
CLK
#define CLK
Pointer to CLK register structure.
Definition: Nano100Series.h:10121
CLK_GetHCLKFreq
uint32_t CLK_GetHCLKFreq(void)
This function get HCLK frequency. The frequency unit is Hz.
Definition: clk.c:121
CLK_EnablePLL
uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
This function set PLL frequency.
Definition: clk.c:496
MODULE_APBCLK
#define MODULE_APBCLK(x)
Definition: clk.h:197
CLK_SetHCLK
void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
This function set HCLK clock source and HCLK clock divider.
Definition: clk.c:235
CLK_GetHXTFreq
uint32_t CLK_GetHXTFreq(void)
This function get external high frequency crystal frequency. The frequency unit is Hz.
Definition: clk.c:95
CLK_CLKSTATUS_LXT_STB_Msk
#define CLK_CLKSTATUS_LXT_STB_Msk
Definition: Nano100Series.h:1159
CLK_SetCoreClock
uint32_t CLK_SetCoreClock(uint32_t u32Hclk)
This function set HCLK frequency. The frequency unit is Hz. The range of u32Hclk is 24 ~ 32 MHz.
Definition: clk.c:181
CLK_WaitClockReady
uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
This function check selected clock source status.
Definition: clk.c:623
CLK_PWRCTL_PD_EN_Msk
#define CLK_PWRCTL_PD_EN_Msk
Definition: Nano100Series.h:1057
__HSI
#define __HSI
Definition: system_Nano100Series.h:31
CLK_CLKSTATUS_PLL_STB_Msk
#define CLK_CLKSTATUS_PLL_STB_Msk
Definition: Nano100Series.h:1162
Nano100Series.h
Nano100 series peripheral access layer header file. This file contains all the peripheral register's ...
CLK_GetPLLClockFreq
uint32_t CLK_GetPLLClockFreq(void)
This function get PLL frequency. The frequency unit is Hz.
Definition: clk.c:144
CLK_PWRCTL_LXT_EN_Msk
#define CLK_PWRCTL_LXT_EN_Msk
Definition: Nano100Series.h:1042
CLK_PLLCTL_PLL_SRC_HXT
#define CLK_PLLCTL_PLL_SRC_HXT
Definition: clk.h:192
CLK_PLLCTL_PD_Msk
#define CLK_PLLCTL_PD_Msk
Definition: Nano100Series.h:1246
CLK_CLKSTATUS_LIRC_STB_Msk
#define CLK_CLKSTATUS_LIRC_STB_Msk
Definition: Nano100Series.h:1165
CLK_APBCLK_FDIV_EN_Msk
#define CLK_APBCLK_FDIV_EN_Msk
Definition: Nano100Series.h:1105
CLK_CLKDIV0_HCLK_N_Msk
#define CLK_CLKDIV0_HCLK_N_Msk
Definition: Nano100Series.h:1216
CLK_DisableXtalRC
void CLK_DisableXtalRC(uint32_t u32ClkMask)
This function disable clock source.
Definition: clk.c:405
CLK_CLKSTATUS_HXT_STB_Msk
#define CLK_CLKSTATUS_HXT_STB_Msk
Definition: Nano100Series.h:1156
__HIRC12M
#define __HIRC12M
Definition: system_Nano100Series.h:28
CLK_PLLCTL_OUT_DV_Msk
#define CLK_PLLCTL_OUT_DV_Msk
Definition: Nano100Series.h:1243
CLK_PWRCTL_HIRC_EN_Msk
#define CLK_PWRCTL_HIRC_EN_Msk
Definition: Nano100Series.h:1045
CyclesPerUs
uint32_t CyclesPerUs
Definition: system_Nano100Series.c:21
FREQ_48MHZ
#define FREQ_48MHZ
Definition: clk.h:36
CLK_CLKSEL0_HCLK_S_Msk
#define CLK_CLKSEL0_HCLK_S_Msk
Definition: Nano100Series.h:1174
CLK_Idle
void CLK_Idle(void)
This function let system enter to Idle mode.
Definition: clk.c:84
CLK_PLLCTL_IN_DV_Msk
#define CLK_PLLCTL_IN_DV_Msk
Definition: Nano100Series.h:1240
CLK_HCLK_CLK_DIVIDER
#define CLK_HCLK_CLK_DIVIDER(x)
Definition: clk.h:162
__HXT
#define __HXT
Definition: system_Nano100Series.h:26
CLK_CLKSEL0_HCLK_S_HIRC
#define CLK_CLKSEL0_HCLK_S_HIRC
Definition: clk.h:89
CLK_PLLCTL_FB_DV_Msk
#define CLK_PLLCTL_FB_DV_Msk
Definition: Nano100Series.h:1237
__LXT
#define __LXT
Definition: system_Nano100Series.h:27
CLK_GetCPUFreq
uint32_t CLK_GetCPUFreq(void)
This function get CPU frequency. The frequency unit is Hz.
Definition: clk.c:133
CLK_EnableCKO
void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
This function enable frequency divider module clock, enable frequency divider clock function and conf...
Definition: clk.c:55
FREQ_120MHZ
#define FREQ_120MHZ
Definition: clk.h:35
CLK_PWRCTL_LIRC_EN_Msk
#define CLK_PWRCTL_LIRC_EN_Msk
Definition: Nano100Series.h:1048
CLK_PLLCTL_PLL_SRC_Msk
#define CLK_PLLCTL_PLL_SRC_Msk
Definition: Nano100Series.h:1249
FREQ_24MHZ
#define FREQ_24MHZ
Definition: clk.h:39
CLK_DisablePLL
void CLK_DisablePLL(void)
This function disable PLL.
Definition: clk.c:551
CLK_EnableXtalRC
void CLK_EnableXtalRC(uint32_t u32ClkMask)
This function enable clock source.
Definition: clk.c:380
CLK_PowerDown
void CLK_PowerDown(void)
This function let system enter to Power-down mode.
Definition: clk.c:72
MODULE_CLKSEL_Pos
#define MODULE_CLKSEL_Pos(x)
Definition: clk.h:200
MODULE_CLKDIV_Pos
#define MODULE_CLKDIV_Pos(x)
Definition: clk.h:203
CLK_DisableCKO
void CLK_DisableCKO(void)
This function disable frequency output function.
Definition: clk.c:32
MODULE_CLKSEL_Msk
#define MODULE_CLKSEL_Msk(x)
Definition: clk.h:199
FREQ_32MHZ
#define FREQ_32MHZ
Definition: clk.h:38
CLK_CLKSEL2_FRQDIV_S_Msk
#define CLK_CLKSEL2_FRQDIV_S_Msk
Definition: Nano100Series.h:1195
MODULE_IP_EN_Pos
#define MODULE_IP_EN_Pos(x)
Definition: clk.h:204
MODULE_CLKSEL
#define MODULE_CLKSEL(x)
Definition: clk.h:198
CLK_CLKSTATUS_HIRC_STB_Msk
#define CLK_CLKSTATUS_HIRC_STB_Msk
Definition: Nano100Series.h:1168
MODULE_CLKDIV
#define MODULE_CLKDIV(x)
Definition: clk.h:201
MODULE_CLKDIV_Msk
#define MODULE_CLKDIV_Msk(x)
Definition: clk.h:202
CLK_CLKSEL0_STCLKSEL_HCLK
#define CLK_CLKSEL0_STCLKSEL_HCLK
Definition: clk.h:174
CLK_FRQDIV_FDIV_EN_Msk
#define CLK_FRQDIV_FDIV_EN_Msk
Definition: Nano100Series.h:1255
SystemCoreClockUpdate
void SystemCoreClockUpdate(void)
Updates the SystemCoreClock with current core Clock retrieved from CPU registers.
Definition: system_Nano100Series.c:106
CLK_SetModuleClock
void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv)
This function set selected module clock source and module clock divider.
Definition: clk.c:350
CLK_PLLCTL_PLL_SRC_Pos
#define CLK_PLLCTL_PLL_SRC_Pos
Definition: Nano100Series.h:1248