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;
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 {
122  return SystemCoreClock;
123 }
124 
125 
131 uint32_t CLK_GetCPUFreq(void)
132 {
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  {
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 
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;
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 
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)
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 
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 
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 
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 
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:599
#define MODULE_NoMsk
Definition: clk.h:280
void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
Enable System Tick counter.
Definition: clk.c:580
uint32_t CLK_GetLXTFreq(void)
This function get external low frequency crystal frequency. The frequency unit is Hz.
Definition: clk.c:106
#define CLK_CLKSEL0_HCLK_S_PLL
Definition: clk.h:103
#define CLK_PLLCTL_PLL_SRC_HIRC
Definition: clk.h:206
void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
This function enable module clock.
Definition: clk.c:436
void CLK_SysTickDelay(uint32_t us)
This function execute delay function.
Definition: clk.c:559
void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
This function disable module clock.
Definition: clk.c:478
#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:119
uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
This function set PLL frequency.
Definition: clk.c:491
#define MODULE_APBCLK(x)
Definition: clk.h:272
void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
This function set HCLK clock source and HCLK clock divider.
Definition: clk.c:223
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_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 ~ 42 MHz.
Definition: clk.c:177
uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
This function check selected clock source status.
Definition: clk.c:618
#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:142
#define CLK_PWRCTL_LXT_EN_Msk
#define CLK_PLLCTL_PLL_SRC_HXT
Definition: clk.h:207
#define CLK_PLLCTL_PD_Msk
#define CLK_CLKSTATUS_LIRC_STB_Msk
#define FREQ_42MHZ
Definition: clk.h:37
#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:394
#define CLK_CLKSTATUS_HXT_STB_Msk
#define __HIRC12M
#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:83
#define CLK_PLLCTL_IN_DV_Msk
#define CLK_HCLK_CLK_DIVIDER(x)
Definition: clk.h:188
#define CLK_PWRCTL_HXT_EN
Definition: clk.h:43
#define __HXT
#define CLK_PLLCTL_OUT_DV
Definition: clk.h:204
#define CLK_CLKSEL0_HCLK_S_HIRC
Definition: clk.h:105
#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:131
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:546
void CLK_EnableXtalRC(uint32_t u32ClkMask)
This function enable clock source.
Definition: clk.c:369
void CLK_PowerDown(void)
This function let system enter to Power-down mode.
Definition: clk.c:72
#define CLK_PWRCTL_LXT_EN
Definition: clk.h:44
#define MODULE_CLKSEL_Pos(x)
Definition: clk.h:275
#define MODULE_CLKDIV_Pos(x)
Definition: clk.h:278
void CLK_DisableCKO(void)
This function disable frequency output function.
Definition: clk.c:32
#define MODULE_CLKSEL_Msk(x)
Definition: clk.h:274
#define CLK_CLKSEL2_FRQDIV_S_Msk
#define MODULE_IP_EN_Pos(x)
Definition: clk.h:279
#define MODULE_CLKSEL(x)
Definition: clk.h:273
#define CLK_CLKSTATUS_HIRC_STB_Msk
#define MODULE_CLKDIV(x)
Definition: clk.h:276
#define CLK_PLLCTL_PD
Definition: clk.h:205
#define MODULE_CLKDIV_Msk(x)
Definition: clk.h:277
#define CLK_CLKSEL0_STCLKSEL_HCLK
Definition: clk.h:200
#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:339
#define CLK_PLLCTL_PLL_SRC_Pos