| Nano100BN Series BSP V3.03.002 The Board Support Package for Nano100BN 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
83 void CLK_Idle(void)
84 {
85 CLK->PWRCTL &= ~(CLK_PWRCTL_PD_EN_Msk );
86 __WFI();
87 }
88
94 uint32_t CLK_GetHXTFreq(void)
95 {
96 if(CLK->PWRCTL & CLK_PWRCTL_HXT_EN )
97 return __HXT;
98 else
99 return 0;
100 }
101
106 uint32_t CLK_GetLXTFreq(void)
107 {
108 if(CLK->PWRCTL & CLK_PWRCTL_LXT_EN )
109 return __LXT;
110 else
111 return 0;
112 }
113
119 uint32_t CLK_GetHCLKFreq(void)
120 {
121 SystemCoreClockUpdate();
122 return SystemCoreClock;
123 }
124
125
131 uint32_t CLK_GetCPUFreq(void)
132 {
133 SystemCoreClockUpdate();
134 return SystemCoreClock;
135 }
136
142 uint32_t CLK_GetPLLClockFreq(void)
143 {
144 uint32_t u32Freq =0, u32PLLSrc;
145 uint32_t u32NO, u32NR, u32IN_DV, u32PllReg;
146
147 u32PllReg = CLK->PLLCTL;
148
149 if (u32PllReg & CLK_PLLCTL_PD)
150 return 0; /* PLL is in power down mode */
151
152 if (u32PllReg & CLK_PLLCTL_PLL_SRC_Msk)
153 u32PLLSrc = __HIRC12M;
154 else
155 u32PLLSrc = __HXT;
156
157 u32NO = (u32PllReg & CLK_PLLCTL_OUT_DV) ? 2: 1;
158
159 u32IN_DV = (u32PllReg & CLK_PLLCTL_IN_DV_Msk) >> 8;
160 if (u32IN_DV == 0)
161 u32NR = 2;
162 else if (u32IN_DV == 1)
163 u32NR = 4;
164 else if (u32IN_DV == 2)
165 u32NR = 8;
166 else
167 u32NR = 16;
168 u32Freq = u32PLLSrc * ((u32PllReg & CLK_PLLCTL_FB_DV_Msk) +32) / u32NR / u32NO;
169 return u32Freq;
170 }
171
177 uint32_t CLK_SetCoreClock(uint32_t u32Hclk)
178 {
179 uint32_t u32HIRCSTB;
180 /* Read HIRC clock source stable flag */
181 u32HIRCSTB = CLK->CLKSTATUS & CLK_CLKSTATUS_HIRC_STB_Msk;
182
183 if(u32Hclk==__HIRC12M)
184 {
185 CLK_EnableXtalRC(CLK_PWRCTL_HIRC_EN_Msk);
186 CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC,CLK_HCLK_CLK_DIVIDER(1));
187 return SystemCoreClock;
188 }
189
190 if(u32Hclk<FREQ_24MHZ) u32Hclk=FREQ_24MHZ;
191 if(u32Hclk>FREQ_42MHZ) u32Hclk=FREQ_42MHZ;
192
193 if(CLK->PWRCTL & CLK_PWRCTL_HXT_EN)
194 CLK_EnablePLL(CLK_PLLCTL_PLL_SRC_HXT,u32Hclk*2);
195 else
196 {
197 CLK_EnablePLL(CLK_PLLCTL_PLL_SRC_HIRC,u32Hclk*2);
198
199 /* Read HIRC clock source stable flag */
200 u32HIRCSTB = CLK->CLKSTATUS & CLK_CLKSTATUS_HIRC_STB_Msk;
201 }
202 CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_PLL,CLK_HCLK_CLK_DIVIDER(2));
203
204 /* Disable HIRC if HIRC is disabled before setting core clock */
205 if(u32HIRCSTB == 0)
206 CLK->PWRCTL &= ~CLK_PWRCTL_HIRC_EN_Msk;
207
208 return SystemCoreClock;
209 }
210
223 void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
224 {
225 uint32_t u32HIRCSTB;
226
227 /* Read HIRC clock source stable flag */
228 u32HIRCSTB = CLK->CLKSTATUS & CLK_CLKSTATUS_HIRC_STB_Msk;
229
230 /* Switch to HIRC for Safe. Avoid HCLK too high when applying new divider. */
231 CLK->PWRCTL |= CLK_PWRCTL_HIRC_EN_Msk;
232 CLK_WaitClockReady(CLK_CLKSTATUS_HIRC_STB_Msk);
233 CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLK_S_Msk)) | CLK_CLKSEL0_HCLK_S_HIRC;
234
235 CLK->CLKDIV0 = (CLK->CLKDIV0 & ~CLK_CLKDIV0_HCLK_N_Msk) | u32ClkDiv;
236 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_HCLK_S_Msk) | u32ClkSrc;
237 SystemCoreClockUpdate();
238
239 /* Disable HIRC if HIRC is disabled before switching HCLK source */
240 if(u32HIRCSTB == 0)
241 CLK->PWRCTL &= ~CLK_CLKSTATUS_HIRC_STB_Msk;
242 }
243
339 void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv)
340 {
341 uint32_t u32tmp=0,u32sel=0,u32div=0;
342
343 if(MODULE_CLKDIV_Msk(u32ModuleIdx)!=MODULE_NoMsk)
344 {
345 u32div =(uint32_t)&CLK->CLKDIV0+((MODULE_CLKDIV(u32ModuleIdx))*4);
346 u32tmp = *(volatile uint32_t *)(u32div);
347 u32tmp = ( u32tmp & ~(MODULE_CLKDIV_Msk(u32ModuleIdx)<<MODULE_CLKDIV_Pos(u32ModuleIdx)) ) | u32ClkDiv;
348 *(volatile uint32_t *)(u32div) = u32tmp;
349 }
350
351 if(MODULE_CLKSEL_Msk(u32ModuleIdx)!=MODULE_NoMsk)
352 {
353 u32sel = (uint32_t)&CLK->CLKSEL0+((MODULE_CLKSEL(u32ModuleIdx))*4);
354 u32tmp = *(volatile uint32_t *)(u32sel);
355 u32tmp = ( u32tmp & ~(MODULE_CLKSEL_Msk(u32ModuleIdx)<<MODULE_CLKSEL_Pos(u32ModuleIdx)) ) | u32ClkSrc;
356 *(volatile uint32_t *)(u32sel) = u32tmp;
357 }
358 }
359
369 void CLK_EnableXtalRC(uint32_t u32ClkMask)
370 {
371 CLK->PWRCTL |= u32ClkMask;
372 if(u32ClkMask & CLK_PWRCTL_HXT_EN_Msk)
373 CLK_WaitClockReady(CLK_CLKSTATUS_HXT_STB_Msk);
374
375 if(u32ClkMask & CLK_PWRCTL_LXT_EN_Msk)
376 CLK_WaitClockReady(CLK_CLKSTATUS_LXT_STB_Msk);
377
378 if(u32ClkMask & CLK_PWRCTL_HIRC_EN_Msk)
379 CLK_WaitClockReady(CLK_CLKSTATUS_HIRC_STB_Msk);
380
381 if(u32ClkMask & CLK_PWRCTL_LIRC_EN_Msk)
382 CLK_WaitClockReady(CLK_CLKSTATUS_LIRC_STB_Msk);
383 }
384
394 void CLK_DisableXtalRC(uint32_t u32ClkMask)
395 {
396 CLK->PWRCTL &= ~u32ClkMask;
397 }
398
436 void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
437 {
438 *(volatile uint32_t *)((uint32_t)&CLK->AHBCLK+(MODULE_APBCLK(u32ModuleIdx)*4)) |= 1<<MODULE_IP_EN_Pos(u32ModuleIdx);
439 }
440
478 void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
479 {
480 *(volatile uint32_t *)((uint32_t)&CLK->AHBCLK+(MODULE_APBCLK(u32ModuleIdx)*4)) &= ~(1<<MODULE_IP_EN_Pos(u32ModuleIdx));
481 }
482
491 uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
492 {
493 uint32_t u32ClkSrc,u32NR, u32NF,u32Register;
494 uint32_t u32NRTable[4]= {2,4,8,16};
495 int32_t i32NRVal;
496 if ( u32PllFreq < FREQ_48MHZ)
497 u32PllFreq=FREQ_48MHZ;
498 else if(u32PllFreq > FREQ_120MHZ)
499 u32PllFreq=FREQ_120MHZ;
500
501 if(u32PllClkSrc!=CLK_PLLCTL_PLL_SRC_HIRC)
502 {
503 /* PLL source clock from HXT */
504 u32Register = (0x0UL<<CLK_PLLCTL_PLL_SRC_Pos);
505 u32ClkSrc = __HXT;
506 }
507 else
508 {
509 /* PLL source clock from HIRC */
510 u32Register = (0x1UL<<CLK_PLLCTL_PLL_SRC_Pos);
511 u32ClkSrc =__HIRC12M;
512 }
513
514 u32NF = u32PllFreq / 1000000;
515 u32NR = u32ClkSrc / 1000000;
516 if(u32ClkSrc%12==0)
517 {
518 u32NF=(u32NF/3)*4;
519 u32NR=(u32NR/3)*4;
520 }
521
522 while( u32NR>16 || u32NF>(0x3F+32) )
523 {
524 u32NR = u32NR>>1;
525 u32NF = u32NF>>1;
526 }
527
528 for(i32NRVal=3; i32NRVal>=0; i32NRVal--)
529 if(u32NR==u32NRTable[i32NRVal]) break;
530
531 CLK->PLLCTL = u32Register | (i32NRVal<<8) | (u32NF - 32) ;
532
533 CLK->PLLCTL &= ~CLK_PLLCTL_PD_Msk;
534
535 CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk);
536
537 return CLK_GetPLLClockFreq();
538
539 }
540
546 void CLK_DisablePLL(void)
547 {
548 CLK->PLLCTL |= CLK_PLLCTL_PD_Msk;
549 }
550
559 void CLK_SysTickDelay(uint32_t us)
560 {
561 SysTick->LOAD = us * CyclesPerUs;
562 SysTick->VAL = (0x00);
563 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
564
565 /* Waiting for down-count to zero */
566 while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
567 SysTick->CTRL = 0;
568 }
569
580 void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
581 {
582 SysTick->CTRL=0;
583 if( u32ClkSrc== CLK_CLKSEL0_STCLKSEL_HCLK ) /* Set System Tick clock source */
584 SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
585 else
586 {
587 SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk;
588 }
589 SysTick->LOAD = u32Count; /* Set System Tick reload value */
590 SysTick->VAL = 0; /* Clear System Tick current value and counter flag */
591 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; /* Set System Tick counter enabled */
592 }
593
599 void CLK_DisableSysTick(void)
600 {
601 SysTick->CTRL = 0; /* Set System Tick counter disabled */
602 }
603
618 uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
619 {
620 int32_t i32TimeOutCnt;
621
622 i32TimeOutCnt = __HSI / 20;
623
624 while((CLK->CLKSTATUS & u32ClkMask) != u32ClkMask)
625 {
626 if(i32TimeOutCnt-- <= 0)
627 return 0;
628 }
629 return 1;
630 }
631
632 /* end of group NANO100_CLK_EXPORTED_FUNCTIONS */
634 /* end of group NANO100_CLK_Driver */
636 /* end of group NANO100_Device_Driver */
638
639 /*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
640
SystemCoreClock
uint32_t SystemCoreClock
Definition: system_Nano100Series.c:20
CLK_PWRCTL_WK_DLY_Msk
#define CLK_PWRCTL_WK_DLY_Msk
Definition: Nano100Series.h:1225
CLK_PWRCTL_HXT_EN_Msk
#define CLK_PWRCTL_HXT_EN_Msk
Definition: Nano100Series.h:1213
CLK_DisableSysTick
void CLK_DisableSysTick(void)
Disable System Tick counter.
Definition: clk.c:599
MODULE_NoMsk
#define MODULE_NoMsk
Definition: clk.h:280
CLK_EnableSysTick
void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
Enable System Tick counter.
Definition: clk.c:580
CLK_GetLXTFreq
uint32_t CLK_GetLXTFreq(void)
This function get external low frequency crystal frequency. The frequency unit is Hz.
Definition: clk.c:106
CLK_CLKSEL0_HCLK_S_PLL
#define CLK_CLKSEL0_HCLK_S_PLL
Definition: clk.h:103
CLK_PLLCTL_PLL_SRC_HIRC
#define CLK_PLLCTL_PLL_SRC_HIRC
Definition: clk.h:206
CLK_EnableModuleClock
void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
This function enable module clock.
Definition: clk.c:436
CLK_SysTickDelay
void CLK_SysTickDelay(uint32_t us)
This function execute delay function.
Definition: clk.c:559
CLK_DisableModuleClock
void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
This function disable module clock.
Definition: clk.c:478
CLK
#define CLK
Pointer to CLK register structure.
Definition: Nano100Series.h:11693
CLK_GetHCLKFreq
uint32_t CLK_GetHCLKFreq(void)
This function get HCLK frequency. The frequency unit is Hz.
Definition: clk.c:119
CLK_EnablePLL
uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
This function set PLL frequency.
Definition: clk.c:491
MODULE_APBCLK
#define MODULE_APBCLK(x)
Definition: clk.h:272
CLK_SetHCLK
void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
This function set HCLK clock source and HCLK clock divider.
Definition: clk.c:223
CLK_GetHXTFreq
uint32_t CLK_GetHXTFreq(void)
This function get external high frequency crystal frequency. The frequency unit is Hz.
Definition: clk.c:94
CLK_CLKSTATUS_LXT_STB_Msk
#define CLK_CLKSTATUS_LXT_STB_Msk
Definition: Nano100Series.h:1345
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 ~ 42 MHz.
Definition: clk.c:177
CLK_WaitClockReady
uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
This function check selected clock source status.
Definition: clk.c:618
CLK_PWRCTL_PD_EN_Msk
#define CLK_PWRCTL_PD_EN_Msk
Definition: Nano100Series.h:1231
__HSI
#define __HSI
Definition: system_Nano100Series.h:31
CLK_CLKSTATUS_PLL_STB_Msk
#define CLK_CLKSTATUS_PLL_STB_Msk
Definition: Nano100Series.h:1348
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:142
CLK_PWRCTL_LXT_EN_Msk
#define CLK_PWRCTL_LXT_EN_Msk
Definition: Nano100Series.h:1216
CLK_PLLCTL_PLL_SRC_HXT
#define CLK_PLLCTL_PLL_SRC_HXT
Definition: clk.h:207
CLK_PLLCTL_PD_Msk
#define CLK_PLLCTL_PD_Msk
Definition: Nano100Series.h:1447
CLK_CLKSTATUS_LIRC_STB_Msk
#define CLK_CLKSTATUS_LIRC_STB_Msk
Definition: Nano100Series.h:1351
FREQ_42MHZ
#define FREQ_42MHZ
Definition: clk.h:37
CLK_APBCLK_FDIV_EN_Msk
#define CLK_APBCLK_FDIV_EN_Msk
Definition: Nano100Series.h:1282
CLK_CLKDIV0_HCLK_N_Msk
#define CLK_CLKDIV0_HCLK_N_Msk
Definition: Nano100Series.h:1414
CLK_DisableXtalRC
void CLK_DisableXtalRC(uint32_t u32ClkMask)
This function disable clock source.
Definition: clk.c:394
CLK_CLKSTATUS_HXT_STB_Msk
#define CLK_CLKSTATUS_HXT_STB_Msk
Definition: Nano100Series.h:1342
__HIRC12M
#define __HIRC12M
Definition: system_Nano100Series.h:28
CLK_PWRCTL_HIRC_EN_Msk
#define CLK_PWRCTL_HIRC_EN_Msk
Definition: Nano100Series.h:1219
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:1360
CLK_Idle
void CLK_Idle(void)
This function let system enter to Idle mode.
Definition: clk.c:83
CLK_PLLCTL_IN_DV_Msk
#define CLK_PLLCTL_IN_DV_Msk
Definition: Nano100Series.h:1441
CLK_HCLK_CLK_DIVIDER
#define CLK_HCLK_CLK_DIVIDER(x)
Definition: clk.h:188
CLK_PWRCTL_HXT_EN
#define CLK_PWRCTL_HXT_EN
Definition: clk.h:43
__HXT
#define __HXT
Definition: system_Nano100Series.h:26
CLK_PLLCTL_OUT_DV
#define CLK_PLLCTL_OUT_DV
Definition: clk.h:204
CLK_CLKSEL0_HCLK_S_HIRC
#define CLK_CLKSEL0_HCLK_S_HIRC
Definition: clk.h:105
CLK_PLLCTL_FB_DV_Msk
#define CLK_PLLCTL_FB_DV_Msk
Definition: Nano100Series.h:1438
__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:131
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:1222
CLK_PLLCTL_PLL_SRC_Msk
#define CLK_PLLCTL_PLL_SRC_Msk
Definition: Nano100Series.h:1450
FREQ_24MHZ
#define FREQ_24MHZ
Definition: clk.h:39
CLK_DisablePLL
void CLK_DisablePLL(void)
This function disable PLL.
Definition: clk.c:546
CLK_EnableXtalRC
void CLK_EnableXtalRC(uint32_t u32ClkMask)
This function enable clock source.
Definition: clk.c:369
CLK_PowerDown
void CLK_PowerDown(void)
This function let system enter to Power-down mode.
Definition: clk.c:72
CLK_PWRCTL_LXT_EN
#define CLK_PWRCTL_LXT_EN
Definition: clk.h:44
MODULE_CLKSEL_Pos
#define MODULE_CLKSEL_Pos(x)
Definition: clk.h:275
MODULE_CLKDIV_Pos
#define MODULE_CLKDIV_Pos(x)
Definition: clk.h:278
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:274
CLK_CLKSEL2_FRQDIV_S_Msk
#define CLK_CLKSEL2_FRQDIV_S_Msk
Definition: Nano100Series.h:1384
MODULE_IP_EN_Pos
#define MODULE_IP_EN_Pos(x)
Definition: clk.h:279
MODULE_CLKSEL
#define MODULE_CLKSEL(x)
Definition: clk.h:273
CLK_CLKSTATUS_HIRC_STB_Msk
#define CLK_CLKSTATUS_HIRC_STB_Msk
Definition: Nano100Series.h:1354
MODULE_CLKDIV
#define MODULE_CLKDIV(x)
Definition: clk.h:276
CLK_PLLCTL_PD
#define CLK_PLLCTL_PD
Definition: clk.h:205
MODULE_CLKDIV_Msk
#define MODULE_CLKDIV_Msk(x)
Definition: clk.h:277
CLK_CLKSEL0_STCLKSEL_HCLK
#define CLK_CLKSEL0_STCLKSEL_HCLK
Definition: clk.h:200
CLK_FRQDIV_FDIV_EN_Msk
#define CLK_FRQDIV_FDIV_EN_Msk
Definition: Nano100Series.h:1456
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:339
CLK_PLLCTL_PLL_SRC_Pos
#define CLK_PLLCTL_PLL_SRC_Pos
Definition: Nano100Series.h:1449