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;
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 {
124  return SystemCoreClock;
125 }
126 
127 
133 uint32_t CLK_GetCPUFreq(void)
134 {
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  {
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)
200 
201  /* Configure PLL setting if HXT clock is not enabled */
202  else
203  {
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  */
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;
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;
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)
385 
386  if(u32ClkMask & CLK_PWRCTL_LXT_EN_Msk)
388 
389  if(u32ClkMask & CLK_PWRCTL_HIRC_EN_Msk)
391 
392  if(u32ClkMask & CLK_PWRCTL_LIRC_EN_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 
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 
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 
uint32_t SystemCoreClock
#define CLK_PWRCTL_WK_DLY_Msk
#define CLK_PWRCTL_HXT_EN_Msk
void CLK_DisableSysTick(void)
Disable System Tick counter.
Definition: clk.c:604
#define MODULE_NoMsk
Definition: clk.h:205
void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
Enable System Tick counter.
Definition: clk.c:585
uint32_t CLK_GetLXTFreq(void)
This function get external low frequency crystal frequency. The frequency unit is Hz.
Definition: clk.c:108
#define CLK_CLKSEL0_HCLK_S_PLL
Definition: clk.h:87
#define CLK_PLLCTL_PLL_SRC_HIRC
Definition: clk.h:191
void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
This function enable module clock.
Definition: clk.c:444
void CLK_SysTickDelay(uint32_t us)
This function execute delay function.
Definition: clk.c:564
void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
This function disable module clock.
Definition: clk.c:483
#define CLK
Pointer to CLK register structure.
uint32_t CLK_GetHCLKFreq(void)
This function get HCLK frequency. The frequency unit is Hz.
Definition: clk.c:121
uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
This function set PLL frequency.
Definition: clk.c:496
#define MODULE_APBCLK(x)
Definition: clk.h:197
void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
This function set HCLK clock source and HCLK clock divider.
Definition: clk.c:235
uint32_t CLK_GetHXTFreq(void)
This function get external high frequency crystal frequency. The frequency unit is Hz.
Definition: clk.c:95
#define CLK_CLKSTATUS_LXT_STB_Msk
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
uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
This function check selected clock source status.
Definition: clk.c:623
#define CLK_PWRCTL_PD_EN_Msk
#define __HSI
#define CLK_CLKSTATUS_PLL_STB_Msk
Nano100 series peripheral access layer header file. This file contains all the peripheral register's ...
uint32_t CLK_GetPLLClockFreq(void)
This function get PLL frequency. The frequency unit is Hz.
Definition: clk.c:144
#define CLK_PWRCTL_LXT_EN_Msk
#define CLK_PLLCTL_PLL_SRC_HXT
Definition: clk.h:192
#define CLK_PLLCTL_PD_Msk
#define CLK_CLKSTATUS_LIRC_STB_Msk
#define CLK_APBCLK_FDIV_EN_Msk
#define CLK_CLKDIV0_HCLK_N_Msk
void CLK_DisableXtalRC(uint32_t u32ClkMask)
This function disable clock source.
Definition: clk.c:405
#define CLK_CLKSTATUS_HXT_STB_Msk
#define __HIRC12M
#define CLK_PLLCTL_OUT_DV_Msk
#define CLK_PWRCTL_HIRC_EN_Msk
uint32_t CyclesPerUs
#define FREQ_48MHZ
Definition: clk.h:36
#define CLK_CLKSEL0_HCLK_S_Msk
void CLK_Idle(void)
This function let system enter to Idle mode.
Definition: clk.c:84
#define CLK_PLLCTL_IN_DV_Msk
#define CLK_HCLK_CLK_DIVIDER(x)
Definition: clk.h:162
#define __HXT
#define CLK_CLKSEL0_HCLK_S_HIRC
Definition: clk.h:89
#define CLK_PLLCTL_FB_DV_Msk
#define __LXT
uint32_t CLK_GetCPUFreq(void)
This function get CPU frequency. The frequency unit is Hz.
Definition: clk.c:133
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
#define FREQ_120MHZ
Definition: clk.h:35
#define CLK_PWRCTL_LIRC_EN_Msk
#define CLK_PLLCTL_PLL_SRC_Msk
#define FREQ_24MHZ
Definition: clk.h:39
void CLK_DisablePLL(void)
This function disable PLL.
Definition: clk.c:551
void CLK_EnableXtalRC(uint32_t u32ClkMask)
This function enable clock source.
Definition: clk.c:380
void CLK_PowerDown(void)
This function let system enter to Power-down mode.
Definition: clk.c:72
#define MODULE_CLKSEL_Pos(x)
Definition: clk.h:200
#define MODULE_CLKDIV_Pos(x)
Definition: clk.h:203
void CLK_DisableCKO(void)
This function disable frequency output function.
Definition: clk.c:32
#define MODULE_CLKSEL_Msk(x)
Definition: clk.h:199
#define FREQ_32MHZ
Definition: clk.h:38
#define CLK_CLKSEL2_FRQDIV_S_Msk
#define MODULE_IP_EN_Pos(x)
Definition: clk.h:204
#define MODULE_CLKSEL(x)
Definition: clk.h:198
#define CLK_CLKSTATUS_HIRC_STB_Msk
#define MODULE_CLKDIV(x)
Definition: clk.h:201
#define MODULE_CLKDIV_Msk(x)
Definition: clk.h:202
#define CLK_CLKSEL0_STCLKSEL_HCLK
Definition: clk.h:174
#define CLK_FRQDIV_FDIV_EN_Msk
void SystemCoreClockUpdate(void)
Updates the SystemCoreClock with current core Clock retrieved from CPU registers.
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
#define CLK_PLLCTL_PLL_SRC_Pos