Nano103 BSP  V3.01.002
The Board Support Package for Nano103 Series
clk.c
Go to the documentation of this file.
1 /**************************************************************************/
13 #include "Nano103.h"
32 void CLK_DisableCKO(void)
33 {
34  /* Disable CKO clock source */
35  CLK->APBCLK &= (~CLK_APBCLK_CLKOCKEN_Msk);
36 }
37 
57 void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv, uint32_t u32ClkDivBy1En)
58 {
59  /* Select CKO clock source */
60  CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_CLKOSEL_Msk)) | u32ClkSrc;
61 
62  /* CKO = clock source / 2^(u32ClkDiv + 1) */
63  CLK->CLKOCTL = CLK_CLKOCTL_CLKOEN_Msk | u32ClkDiv | (u32ClkDivBy1En<<CLK_CLKOCTL_DIV1EN_Pos);
64 
65  /* Enable CKO clock source */
66  CLK->APBCLK |= CLK_APBCLK_CLKOCKEN_Msk;
67 }
68 
69 
75 void CLK_PowerDown(void)
76 {
77 
78  SCB->SCR = SCB_SCR_SLEEPDEEP_Msk;
80  __WFI();
81 
82 }
83 
89 void CLK_Idle(void)
90 {
91  CLK->PWRCTL &= ~(CLK_PWRCTL_PDEN_Msk);
92  __WFI();
93 }
94 
100 uint32_t CLK_GetHXTFreq(void)
101 {
102  if(CLK->PWRCTL & CLK_PWRCTL_HXT_EN )
103  return __HXT;
104  else
105  return 0;
106 }
107 
113 uint32_t CLK_GetLXTFreq(void)
114 {
115  if(CLK->PWRCTL & CLK_PWRCTL_LXT_EN )
116  return __LXT;
117  else
118  return 0;
119 }
120 
126 uint32_t CLK_GetHCLKFreq(void)
127 {
129  return SystemCoreClock;
130 }
131 
137 uint32_t CLK_GetPCLK0Freq(void)
138 {
139  uint32_t Div[]= {1,2,4,8,16,1,1,1};
140  uint32_t PCLK_Div;
141  PCLK_Div = CLK->APBDIV & CLK_APBDIV_APB0DIV_Msk;
143  return SystemCoreClock/Div[PCLK_Div];
144 }
145 
151 uint32_t CLK_GetPCLK1Freq(void)
152 {
153  uint32_t Div[]= {1,2,4,8,16,1,1,1};
154  uint32_t PCLK_Div;
155  PCLK_Div = CLK->APBDIV & CLK_APBDIV_APB1DIV_Msk;
157  return SystemCoreClock/Div[PCLK_Div];
158 }
159 
165 uint32_t CLK_GetCPUFreq(void)
166 {
168  return SystemCoreClock;
169 }
170 
176 uint32_t CLK_GetPLLClockFreq(void)
177 {
178  uint32_t u32Freq =0, u32PLLSrc;
179  uint32_t u32SRC_N,u32PLL_M,u32PllReg;
180 
181  u32PllReg = CLK->PLLCTL;
182 
183  if (u32PllReg & CLK_PLLCTL_PD)
184  return 0; /* PLL is in power down mode */
185 
186  if((u32PllReg & CLK_PLLCTL_PLLSRC_Msk) == CLK_PLLCTL_PLL_SRC_HXT)
187  {
188  /* PLL source clock from HXT */
189  u32PLLSrc = __HXT;
190  }
191  else if((u32PllReg & CLK_PLLCTL_PLLSRC_Msk) == CLK_PLLCTL_PLL_SRC_HIRC)
192  {
193  /* HIRC Source Selection */
194  if(CLK->CLKSEL0 & CLK_CLKSEL0_HIRCSEL_Msk)
195  {
196  /* Clock source from HIRC1 (36MHz) */
197  u32PLLSrc =__HIRC36M;
198  }
199  else
200  {
201  /* Clock source from HIRC0 (12MHz) */
202  if(CLK->PWRCTL & CLK_PWRCTL_HIRC0FSEL_Msk)
203  u32PLLSrc =__HIRC16M;
204  else
205  u32PLLSrc =__HIRC12M;
206  }
207  }
208  else
209  {
210  /* PLL source clock from MIRC (4MHz) */
211  u32PLLSrc =__MIRC;
212  }
213 
214  u32SRC_N = (u32PllReg & CLK_PLLCTL_INDIV_Msk) >> CLK_PLLCTL_INDIV_Pos;
215  u32PLL_M = (u32PllReg & CLK_PLLCTL_PLLMLP_Msk) >> CLK_PLLCTL_PLLMLP_Pos;
216 
217  u32Freq = u32PLLSrc * u32PLL_M / (u32SRC_N+1);
218 
219  return u32Freq;
220 }
221 
227 uint32_t CLK_SetCoreClock(uint32_t u32Hclk)
228 {
229  if(CLK->PWRCTL & CLK_PWRCTL_HXT_EN)
231  else if(CLK->PWRCTL & (CLK_PWRCTL_HIRC0_EN | CLK_PWRCTL_HIRC1_EN))
233  else
235 
238  return SystemCoreClock;
239 }
240 
256 void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
257 {
258  CLK->CLKDIV0 = (CLK->CLKDIV0 & ~CLK_CLKDIV0_HCLKDIV_Msk) | u32ClkDiv;
259  CLK->CLKSEL0 = (CLK->CLKSEL0 & ~(CLK_CLKSEL0_HIRCSEL_Msk | CLK_CLKSEL0_HCLKSEL_Msk)) | u32ClkSrc;
261 }
262 
273 void CLK_SetPCLK0(uint32_t u32ClkDiv)
274 {
275  CLK->APBDIV = (CLK->APBDIV & ~CLK_APBDIV_APB0DIV_Msk) | u32ClkDiv;
276 }
277 
288 void CLK_SetPCLK1(uint32_t u32ClkDiv)
289 {
290  CLK->APBDIV = (CLK->APBDIV & ~CLK_APBDIV_APB1DIV_Msk) | u32ClkDiv;
291 }
292 
380 void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv)
381 {
382  uint32_t u32tmp=0,u32sel=0,u32div=0;
383 
384  if(MODULE_CLKDIV_Msk(u32ModuleIdx)!=MODULE_NoMsk)
385  {
386  u32div =(uint32_t)&CLK->CLKDIV0+((MODULE_CLKDIV(u32ModuleIdx))*4);
387  u32tmp = *(volatile uint32_t *)(u32div);
388  u32tmp = ( u32tmp & ~(MODULE_CLKDIV_Msk(u32ModuleIdx)<<MODULE_CLKDIV_Pos(u32ModuleIdx)) ) | u32ClkDiv;
389  *(volatile uint32_t *)(u32div) = u32tmp;
390  }
391 
392  if(MODULE_CLKSEL_Msk(u32ModuleIdx)!=MODULE_NoMsk)
393  {
394  u32sel = (uint32_t)&CLK->CLKSEL0+((MODULE_CLKSEL(u32ModuleIdx))*4);
395  u32tmp = *(volatile uint32_t *)(u32sel);
396  u32tmp = ( u32tmp & ~(MODULE_CLKSEL_Msk(u32ModuleIdx)<<MODULE_CLKSEL_Pos(u32ModuleIdx)) ) | u32ClkSrc;
397  *(volatile uint32_t *)(u32sel) = u32tmp;
398  }
399 }
400 
412 void CLK_EnableXtalRC(uint32_t u32ClkMask)
413 {
414  CLK->PWRCTL |= u32ClkMask;
415 }
416 
428 void CLK_DisableXtalRC(uint32_t u32ClkMask)
429 {
430  CLK->PWRCTL &= ~u32ClkMask;
431 }
432 
464 void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
465 {
466  *(volatile uint32_t *)((uint32_t)&CLK->AHBCLK+(MODULE_APBCLK(u32ModuleIdx)*4)) |= 1<<MODULE_IP_EN_Pos(u32ModuleIdx);
467 }
468 
500 void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
501 {
502  *(volatile uint32_t *)((uint32_t)&CLK->AHBCLK+(MODULE_APBCLK(u32ModuleIdx)*4)) &= ~(1<<MODULE_IP_EN_Pos(u32ModuleIdx));
503 }
504 
514 uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
515 {
516  uint32_t u32PllCr,u32PLL_N,u32PLL_M,u32PLLReg;
517  if ( u32PllFreq < FREQ_16MHZ)
518  u32PllFreq=FREQ_16MHZ;
519  else if(u32PllFreq > FREQ_36MHZ)
520  u32PllFreq=FREQ_36MHZ;
521 
522  if(u32PllClkSrc == CLK_PLLCTL_PLL_SRC_HXT)
523  {
524  /* PLL source clock from HXT */
525  CLK->PLLCTL = (CLK->PLLCTL & ~CLK_PLLCTL_PLL_SRC_HIRC);
526  u32PllCr = __HXT;
527  }
528  else if(u32PllClkSrc == CLK_PLLCTL_PLL_SRC_HIRC)
529  {
530  /* PLL source clock from HIRC */
531  CLK->PLLCTL = (CLK->PLLCTL & ~CLK_PLLCTL_PLL_SRC_HIRC) | (CLK_PLLCTL_PLL_SRC_HIRC);
532 
533  /* HIRC Source Selection */
534  if(CLK->CLKSEL0 & CLK_CLKSEL0_HIRCSEL_Msk)
535  {
536  /* Clock source from HIRC1 (36MHz) */
537  u32PllCr =__HIRC36M;
538  }
539  else
540  {
541  /* Clock source from HIRC0 (12MHz) */
542  if(CLK->PWRCTL & CLK_PWRCTL_HIRC0FSEL_Msk)
543  u32PllCr =__HIRC16M;
544  else
545  u32PllCr =__HIRC12M;
546  }
547  }
548  else
549  {
550  /* PLL source clock from MIRC (4MHz) */
551  CLK->PLLCTL = (CLK->PLLCTL & ~CLK_PLLCTL_PLL_SRC_MIRC) | (CLK_PLLCTL_PLL_SRC_MIRC);
552  u32PllCr =__MIRC;
553  }
554 
555  u32PLL_N=u32PllCr/1000000;
556  u32PLL_M=u32PllFreq/1000000;
557  while(1)
558  {
559  if(u32PLL_M<=48 && u32PLL_N<=36 ) break;
560  u32PLL_M >>=1;
561  u32PLL_N >>=1;
562  }
563  u32PLLReg = (u32PLL_M<<CLK_PLLCTL_PLLMLP_Pos) | ((u32PLL_N-1)<<CLK_PLLCTL_INDIV_Pos);
564  CLK->PLLCTL = ( CLK->PLLCTL & ~(CLK_PLLCTL_PLLMLP_Msk | CLK_PLLCTL_INDIV_Msk ) )| u32PLLReg;
565 
566  if(u32PllClkSrc==CLK_PLLCTL_PLL_SRC_HIRC)
567  CLK->PLLCTL = (CLK->PLLCTL & ~CLK_PLLCTL_PLLSRC_Msk) | (CLK_PLLCTL_PLL_SRC_HIRC);
568  else if(u32PllClkSrc==CLK_PLLCTL_PLL_SRC_HXT)
569  CLK->PLLCTL = (CLK->PLLCTL & ~CLK_PLLCTL_PLLSRC_Msk) | (CLK_PLLCTL_PLL_SRC_HXT);
570  else
571  CLK->PLLCTL = (CLK->PLLCTL & ~CLK_PLLCTL_PLLSRC_Msk) | (CLK_PLLCTL_PLL_SRC_MIRC);
572 
573  CLK->PLLCTL &= ~CLK_PLLCTL_PD_Msk;
574  return CLK_GetPLLClockFreq();
575 }
576 
582 void CLK_DisablePLL(void)
583 {
584  CLK->PLLCTL |= CLK_PLLCTL_PD_Msk;
585 }
586 
595 void CLK_SysTickDelay(uint32_t us)
596 {
597  SysTick->LOAD = us * CyclesPerUs;
598  SysTick->VAL = (0x00);
599  SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
600 
601  /* Waiting for down-count to zero */
602  while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
603  SysTick->CTRL = 0;
604 }
605 
616 void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
617 {
618  SysTick->CTRL=0;
619  if( u32ClkSrc== CLK_CLKSEL0_STCLKSEL_HCLK ) /* Set System Tick clock source */
620  SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
621  else
622  {
623  SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk;
624  }
625  SysTick->LOAD = u32Count; /* Set System Tick reload value */
626  SysTick->VAL = 0; /* Clear System Tick current value and counter flag */
627  SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; /* Set System Tick counter enabled */
628 }
629 
636 {
637  SysTick->CTRL = 0; /* Set System Tick counter disabled */
638 }
639 
656 uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
657 {
658  int32_t i32TimeOutCnt=2160000;
659 
660  while((CLK->STATUS & u32ClkMask) != u32ClkMask)
661  {
662  if(i32TimeOutCnt-- <= 0)
663  return 0;
664  }
665  return 1;
666 }
667 
668  /* end of group NANO103_CLK_EXPORTED_FUNCTIONS */
670  /* end of group NANO103_CLK_Driver */
672  /* end of group NANO103_Device_Driver */
674 
675 /*** (C) COPYRIGHT 2015 Nuvoton Technology Corp. ***/
676 
#define CLK_PLLCTL_PLLMLP_Msk
Definition: Nano103.h:5158
#define CLK_APBCLK_CLKOCKEN_Msk
Definition: Nano103.h:5002
#define CLK_PLLCTL_PLL_SRC_MIRC
Definition: clk.h:102
uint32_t CLK_GetLXTFreq(void)
This function get external low frequency crystal frequency. The frequency unit is Hz.
Definition: clk.c:113
#define CLK_PWRCTL_HXT_EN
Definition: clk.h:38
uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
This function set PLL frequency.
Definition: clk.c:514
#define CLK_PWRCTL_HIRC0FSEL_Msk
Definition: Nano103.h:4957
#define __HXT
#define CLK_CLKSEL0_HCLKSEL_PLL
Definition: clk.h:140
#define CLK_APBDIV_APB1DIV_Msk
Definition: Nano103.h:5188
#define CLK_PLLCTL_PLL_SRC_HIRC
Definition: clk.h:101
#define FREQ_16MHZ
Definition: clk.h:35
#define MODULE_CLKSEL_Pos(x)
Definition: clk.h:274
#define CLK_CLKOCTL_CLKOEN_Msk
Definition: Nano103.h:5176
#define CLK_PWRCTL_LXT_EN
Definition: clk.h:39
#define MODULE_APBCLK(x)
Definition: clk.h:271
void CLK_DisableCKO(void)
This function disable frequency output function.
Definition: clk.c:32
uint32_t CLK_GetPCLK0Freq(void)
This function get PCLK0 frequency. The frequency unit is Hz.
Definition: clk.c:137
void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv, uint32_t u32ClkDivBy1En)
This function enable frequency divider module clock, enable frequency divider clock function and conf...
Definition: clk.c:57
#define __HIRC16M
uint32_t SystemCoreClock
#define CLK_PLLCTL_PLL_SRC_HXT
Definition: clk.h:100
#define __LXT
void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
Enable System Tick counter.
Definition: clk.c:616
#define CLK_CLKOCTL_DIV1EN_Pos
Definition: Nano103.h:5178
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:380
#define MODULE_NoMsk
Definition: clk.h:279
#define MODULE_IP_EN_Pos(x)
Definition: clk.h:278
void CLK_DisableSysTick(void)
Disable System Tick counter.
Definition: clk.c:635
#define CLK_PLLCTL_PD
Definition: clk.h:99
#define MODULE_CLKSEL_Msk(x)
Definition: clk.h:273
uint32_t CLK_GetPCLK1Freq(void)
This function get PCLK1 frequency. The frequency unit is Hz.
Definition: clk.c:151
uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
This function check selected clock source status.
Definition: clk.c:656
uint32_t CLK_GetPLLClockFreq(void)
This function get PLL frequency. The frequency unit is Hz.
Definition: clk.c:176
void CLK_PowerDown(void)
This function let system enter to fractal fx-2-down mode.
Definition: clk.c:75
#define MODULE_CLKDIV(x)
Definition: clk.h:275
#define CLK_CLKSEL0_HCLKSEL_Msk
Definition: Nano103.h:5068
#define CLK_CLKSEL0_STCLKSEL_HCLK
Definition: clk.h:258
#define CLK_PWRCTL_HIRC0_EN
Definition: clk.h:40
#define CLK_PWRCTL_PDEN_Msk
Definition: Nano103.h:4948
void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
This function disable module clock.
Definition: clk.c:500
#define CLK_PWRCTL_HIRC1_EN
Definition: clk.h:46
#define CLK_PWRCTL_PDWKDLY_Msk
Definition: Nano103.h:4942
uint32_t CLK_GetCPUFreq(void)
This function get CPU frequency. The frequency unit is Hz.
Definition: clk.c:165
#define FREQ_36MHZ
Definition: clk.h:34
#define CLK_PLLCTL_INDIV_Pos
Definition: Nano103.h:5160
void CLK_SetPCLK1(uint32_t u32ClkDiv)
This function set APB PCLK1 clock divider.
Definition: clk.c:288
#define __MIRC
uint32_t CLK_GetHCLKFreq(void)
This function get HCLK frequency. The frequency unit is Hz.
Definition: clk.c:126
#define MODULE_CLKSEL(x)
Definition: clk.h:272
#define CLK_CLKDIV0_HCLKDIV_Msk
Definition: Nano103.h:5128
void CLK_EnableXtalRC(uint32_t u32ClkMask)
This function enable clock source.
Definition: clk.c:412
#define CLK_PLLCTL_PLLSRC_Msk
Definition: Nano103.h:5170
void CLK_SysTickDelay(uint32_t us)
This function execute delay function.
Definition: clk.c:595
NANO103 peripheral access layer header file. This file contains all the peripheral register's definit...
void SystemCoreClockUpdate(void)
Updates the SystemCoreClock with current core Clock retrieved from CPU registers.
#define __HIRC36M
#define CLK_CLKSEL0_HIRCSEL_Msk
Definition: Nano103.h:5071
#define MODULE_CLKDIV_Pos(x)
Definition: clk.h:277
#define CLK_HCLK_CLK_DIVIDER(x)
Definition: clk.h:246
uint32_t CLK_GetHXTFreq(void)
This function get external high frequency crystal frequency. The frequency unit is Hz.
Definition: clk.c:100
#define __HIRC12M
uint32_t CLK_SetCoreClock(uint32_t u32Hclk)
This function set HCLK frequency. The frequency unit is Hz. The range of u32Hclk is 16 ~ 48 MHz.
Definition: clk.c:227
void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
This function set HCLK clock source and HCLK clock divider.
Definition: clk.c:256
void CLK_DisableXtalRC(uint32_t u32ClkMask)
This function disable clock source.
Definition: clk.c:428
#define CLK
Pointer to CLK register structure.
Definition: Nano103.h:24884
void CLK_SetPCLK0(uint32_t u32ClkDiv)
This function set APB PCLK0 clock divider.
Definition: clk.c:273
#define CLK_APBDIV_APB0DIV_Msk
Definition: Nano103.h:5185
void CLK_DisablePLL(void)
This function disable PLL.
Definition: clk.c:582
uint32_t CyclesPerUs
void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
This function enable module clock.
Definition: clk.c:464
#define CLK_PLLCTL_INDIV_Msk
Definition: Nano103.h:5161
void CLK_Idle(void)
This function let system enter to Idle mode.
Definition: clk.c:89
#define CLK_CLKSEL2_CLKOSEL_Msk
Definition: Nano103.h:5107
#define CLK_PLLCTL_PD_Msk
Definition: Nano103.h:5167
#define MODULE_CLKDIV_Msk(x)
Definition: clk.h:276
#define CLK_PLLCTL_PLLMLP_Pos
Definition: Nano103.h:5157
#define CLK_STATUS_PLLSTB_Msk
Definition: Nano103.h:5050