NANO100_BSP V3.04.002
The Board Support Package for Nano100BN Series
clk.c
Go to the documentation of this file.
1/**************************************************************************/
13#include "Nano100Series.h"
33{
34 /* Disable CKO0 clock source */
35 CLK->APBCLK &= (~CLK_APBCLK_FDIV_EN_Msk);
36}
37
55void 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
72void CLK_PowerDown(void)
73{
74 SCB->SCR = SCB_SCR_SLEEPDEEP_Msk;
76 __WFI();
77}
78
83void CLK_Idle(void)
84{
85 CLK->PWRCTL &= ~(CLK_PWRCTL_PD_EN_Msk );
86 __WFI();
87}
88
94uint32_t CLK_GetHXTFreq(void)
95{
96 if(CLK->PWRCTL & CLK_PWRCTL_HXT_EN )
97 return __HXT;
98 else
99 return 0;
100}
101
106uint32_t CLK_GetLXTFreq(void)
107{
108 if(CLK->PWRCTL & CLK_PWRCTL_LXT_EN )
109 return __LXT;
110 else
111 return 0;
112}
113
119uint32_t CLK_GetHCLKFreq(void)
120{
122 return SystemCoreClock;
123}
124
125
131uint32_t CLK_GetCPUFreq(void)
132{
134 return SystemCoreClock;
135}
136
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
177uint32_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 {
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)
195 else
196 {
198
199 /* Read HIRC clock source stable flag */
200 u32HIRCSTB = CLK->CLKSTATUS & CLK_CLKSTATUS_HIRC_STB_Msk;
201 }
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
223void 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;
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;
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
339void 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
369void CLK_EnableXtalRC(uint32_t u32ClkMask)
370{
371 CLK->PWRCTL |= u32ClkMask;
372 if(u32ClkMask & CLK_PWRCTL_HXT_EN_Msk)
374
375 if(u32ClkMask & CLK_PWRCTL_LXT_EN_Msk)
377
378 if(u32ClkMask & CLK_PWRCTL_HIRC_EN_Msk)
380
381 if(u32ClkMask & CLK_PWRCTL_LIRC_EN_Msk)
383}
384
394void CLK_DisableXtalRC(uint32_t u32ClkMask)
395{
396 CLK->PWRCTL &= ~u32ClkMask;
397}
398
436void 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
478void 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
491uint32_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
536
537 return CLK_GetPLLClockFreq();
538
539}
540
547{
548 CLK->PLLCTL |= CLK_PLLCTL_PD_Msk;
549}
550
560int32_t CLK_SysTickDelay(uint32_t us)
561{
562 int32_t tout = SystemCoreClock * ((us / 1000000) + 1) + (SystemCoreClock / 2);
563
564 SysTick->LOAD = us * CyclesPerUs;
565 SysTick->VAL = (0x00);
566 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
567
568 /* Waiting for down-count to zero */
569 while (((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) &&
570 (tout-- > 0));
571 if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0)
572 return -1; /* time out */
573 SysTick->CTRL = 0;
574 return 0;
575}
576
587void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
588{
589 SysTick->CTRL=0;
590 if( u32ClkSrc== CLK_CLKSEL0_STCLKSEL_HCLK ) /* Set System Tick clock source */
591 SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
592 else
593 {
594 SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk;
595 }
596 SysTick->LOAD = u32Count; /* Set System Tick reload value */
597 SysTick->VAL = 0; /* Clear System Tick current value and counter flag */
598 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; /* Set System Tick counter enabled */
599}
600
607{
608 SysTick->CTRL = 0; /* Set System Tick counter disabled */
609}
610
625uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
626{
627 int32_t i32TimeOutCnt;
628
629 i32TimeOutCnt = __HSI / 20;
630
631 while((CLK->CLKSTATUS & u32ClkMask) != u32ClkMask)
632 {
633 if(i32TimeOutCnt-- <= 0)
634 return 0;
635 }
636 return 1;
637}
638
639 /* end of group NANO100_CLK_EXPORTED_FUNCTIONS */
641 /* end of group NANO100_CLK_Driver */
643 /* end of group NANO100_Device_Driver */
645
646/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
647
Nano100 series peripheral access layer header file. This file contains all the peripheral register's ...
#define CLK_CLKSEL0_STCLKSEL_HCLK
Definition: clk.h:200
#define CLK_PLLCTL_PLL_SRC_HXT
Definition: clk.h:207
#define CLK_PWRCTL_HXT_EN
Definition: clk.h:43
#define MODULE_NoMsk
Definition: clk.h:280
#define MODULE_CLKSEL_Msk(x)
Definition: clk.h:274
#define FREQ_120MHZ
Definition: clk.h:35
#define CLK_PLLCTL_OUT_DV
Definition: clk.h:204
#define CLK_PLLCTL_PLL_SRC_HIRC
Definition: clk.h:206
#define FREQ_24MHZ
Definition: clk.h:39
#define MODULE_CLKSEL_Pos(x)
Definition: clk.h:275
#define CLK_PLLCTL_PD
Definition: clk.h:205
#define CLK_HCLK_CLK_DIVIDER(x)
Definition: clk.h:188
#define CLK_CLKSEL0_HCLK_S_PLL
Definition: clk.h:103
#define MODULE_CLKDIV_Pos(x)
Definition: clk.h:278
#define MODULE_IP_EN_Pos(x)
Definition: clk.h:279
#define MODULE_CLKDIV_Msk(x)
Definition: clk.h:277
#define FREQ_48MHZ
Definition: clk.h:36
#define CLK_PWRCTL_LXT_EN
Definition: clk.h:44
#define FREQ_42MHZ
Definition: clk.h:37
#define MODULE_CLKDIV(x)
Definition: clk.h:276
#define MODULE_APBCLK(x)
Definition: clk.h:272
#define CLK_CLKSEL0_HCLK_S_HIRC
Definition: clk.h:105
#define MODULE_CLKSEL(x)
Definition: clk.h:273
void CLK_Idle(void)
This function let system enter to Idle mode.
Definition: clk.c:83
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
uint32_t CLK_GetHCLKFreq(void)
This function get HCLK frequency. The frequency unit is Hz.
Definition: clk.c:119
uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
This function set PLL frequency.
Definition: clk.c:491
void CLK_DisableCKO(void)
This function disable frequency output function.
Definition: clk.c:32
void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
This function enable module clock.
Definition: clk.c:436
void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
This function disable module clock.
Definition: clk.c:478
uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
This function check selected clock source status.
Definition: clk.c:625
uint32_t CLK_GetLXTFreq(void)
This function get external low frequency crystal frequency. The frequency unit is Hz.
Definition: clk.c:106
void CLK_PowerDown(void)
This function let system enter to Power-down mode.
Definition: clk.c:72
void CLK_DisablePLL(void)
This function disable PLL.
Definition: clk.c:546
uint32_t CLK_GetCPUFreq(void)
This function get CPU frequency. The frequency unit is Hz.
Definition: clk.c:131
int32_t CLK_SysTickDelay(uint32_t us)
This function execute delay function.
Definition: clk.c:560
void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
This function set HCLK clock source and HCLK clock divider.
Definition: clk.c:223
void CLK_DisableXtalRC(uint32_t u32ClkMask)
This function disable clock source.
Definition: clk.c:394
void CLK_DisableSysTick(void)
Disable System Tick counter.
Definition: clk.c:606
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
void CLK_EnableXtalRC(uint32_t u32ClkMask)
This function enable clock source.
Definition: clk.c:369
void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
Enable System Tick counter.
Definition: clk.c:587
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
uint32_t CLK_GetPLLClockFreq(void)
This function get PLL frequency. The frequency unit is Hz.
Definition: clk.c:142
uint32_t CLK_GetHXTFreq(void)
This function get external high frequency crystal frequency. The frequency unit is Hz.
Definition: clk.c:94
#define CLK_CLKSTATUS_LIRC_STB_Msk
#define CLK_PWRCTL_LXT_EN_Msk
#define CLK_PWRCTL_WK_DLY_Msk
#define CLK_CLKSTATUS_LXT_STB_Msk
#define CLK_CLKSTATUS_HIRC_STB_Msk
#define CLK_CLKSTATUS_PLL_STB_Msk
#define CLK_PWRCTL_HIRC_EN_Msk
#define CLK_PLLCTL_PD_Msk
#define CLK_PLLCTL_IN_DV_Msk
#define CLK_PLLCTL_FB_DV_Msk
#define CLK_PWRCTL_HXT_EN_Msk
#define CLK_PLLCTL_PLL_SRC_Msk
#define CLK_APBCLK_FDIV_EN_Msk
#define CLK_PWRCTL_PD_EN_Msk
#define CLK_FRQDIV_FDIV_EN_Msk
#define CLK_PWRCTL_LIRC_EN_Msk
#define CLK_CLKSTATUS_HXT_STB_Msk
#define CLK_PLLCTL_PLL_SRC_Pos
#define CLK
Pointer to CLK register structure.
#define __HXT
uint32_t CyclesPerUs
uint32_t SystemCoreClock
#define __LXT
#define __HSI
#define __HIRC12M
void SystemCoreClockUpdate(void)
Updates the SystemCoreClock with current core Clock retrieved from CPU registers.