NUC472_NUC442_BSP V3.03.004
The Board Support Package for NUC472/NUC442
clk.c
Go to the documentation of this file.
1/**************************************************************************/
13#include "NUC472_442.h"
22int32_t g_CLK_i32ErrCode = 0;
35{
36 /* Disable CKO clock source */
37 CLK->APBCLK0 &= (~CLK_APBCLK0_CLKOCKEN_Msk);
38}
39
58void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv, uint32_t u32ClkDivBy1En)
59{
60 /* CKO = clock source / 2^(u32ClkDiv + 1) */
61 CLK->CLKOCTL = CLK_CLKOCTL_CLKOEN_Msk | u32ClkDiv | u32ClkDivBy1En<<CLK_CLKOCTL_DIV1EN_Pos;
62
63 /* Enable CKO clock source */
64 CLK->APBCLK0 |= CLK_APBCLK0_CLKOCKEN_Msk;
65
66 /* Select CKO clock source */
67 CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_CLKOSEL_Msk)) | u32ClkSrc;
68}
69
75void CLK_PowerDown(void)
76{
77 SCB->SCR = SCB_SCR_SLEEPDEEP_Msk;
79 __WFI();
80}
81
87void CLK_Idle(void)
88{
89 /* Set the processor uses sleep as its low power mode */
90 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
91
92 /* Set chip in idle mode because of WFI command */
93 CLK->PWRCTL &= ~(CLK_PWRCTL_PDEN_Msk );
94
95 /* Chip enter idle mode after CPU run WFI instruction */
96 __WFI();
97}
98
99
104uint32_t CLK_GetPCLKFreq(void)
105{
107 if(CLK->CLKSEL0 & CLK_CLKSEL0_PCLKSEL_Msk)
108 return SystemCoreClock/2;
109 else
110 return SystemCoreClock;
111}
112
118uint32_t CLK_GetHXTFreq(void)
119{
120 if(CLK->PWRCTL & CLK_PWRCTL_HXTEN_Msk )
121 return __HXT;
122 else
123 return 0;
124}
125
131uint32_t CLK_GetLXTFreq(void)
132{
133 if(CLK->PWRCTL & CLK_PWRCTL_LXTEN_Msk )
134 return __LXT;
135 else
136 return 0;
137}
138
139
145uint32_t CLK_GetHCLKFreq(void)
146{
148 return SystemCoreClock;
149}
150
156uint32_t CLK_GetCPUFreq(void)
157{
159 return SystemCoreClock;
160}
161
167{
168 uint32_t u32Freq =0, u32PLLSrc;
169 uint32_t u32NO,u32NF,u32NR,u32PllReg;
170
171 u32PllReg = CLK->PLLCTL;
172
173 if(u32PllReg & (CLK_PLLCTL_PD_Msk | CLK_PLLCTL_OE_Msk))
174 return 0; /* PLL is in power down mode or fix low */
175
176 if(u32PllReg & CLK_PLLCTL_PLLSRC_Msk)
177 u32PLLSrc = __HIRC;
178 else
179 u32PLLSrc = __HXT;
180
181 u32NO=(u32PllReg & CLK_PLLCTL_OUTDV_Msk)>>CLK_PLLCTL_OUTDV_Pos;
182 switch(u32NO)
183 {
184 case 0:
185 u32NO=1;
186 break;
187 case 1:
188 case 2:
189 u32NO=2;
190 break;
191 case 3:
192 u32NO=4;
193 break;
194 }
195
196 u32NF = (u32PllReg & CLK_PLLCTL_FBDIV_Msk) + 2;
197 u32NR = ( (u32PllReg & CLK_PLLCTL_INDIV_Msk)>>CLK_PLLCTL_INDIV_Pos ) + 2;
198
199 /* u32PLLSrc is shifted 2 bits to avoid overflow */
200 u32Freq = (((u32PLLSrc >> 2) * u32NF) / (u32NR * u32NO) << 2);
201 return u32Freq;
202}
203
210uint32_t CLK_SetCoreClock(uint32_t u32Hclk)
211{
212 uint32_t u32ClkSrc,u32NR, u32NF,u32Register;
213 u32ClkSrc = CLK->CLKSEL0 & CLK_CLKSEL0_HCLKSEL_Msk;
214
215 if(u32Hclk < FREQ_24MHZ)
216 u32Hclk =FREQ_24MHZ;
217
218 if(CLK->PWRCTL & CLK_PWRCTL_HXTEN_Msk)
219 {
220 u32Register = 0<<CLK_PLLCTL_PLLSRC_Pos;
221 u32ClkSrc = __HXT;
222 }
223 else
224 {
225 u32Register = 1<<CLK_PLLCTL_PLLSRC_Pos;
226 u32ClkSrc = __HIRC;
227 }
228
229 if(u32Hclk<FREQ_50MHZ)
230 {
231 u32Hclk <<=2;
232 u32Register |= (0x3<<CLK_PLLCTL_OUTDV_Pos);
233 }
234 else
235 {
236 u32Hclk <<=1;
237 u32Register |= (0x1<<CLK_PLLCTL_OUTDV_Pos);
238 }
239 u32NF = u32Hclk / 1000000;
240 u32NR = u32ClkSrc / 1000000;
241 while( u32NR>(0xF+2) || u32NF>(0xFF+2) )
242 {
243 u32NR = u32NR>>1;
244 u32NF = u32NF>>1;
245 }
246 CLK->PLLCTL = u32Register | ((u32NR - 2)<<9) | (u32NF - 2) ;
248
250
251 /* Update System Core Clock */
253
254 return SystemCoreClock;
255}
256
269void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
270{
271 CLK->CLKDIV0 = (CLK->CLKDIV0 & ~CLK_CLKDIV0_HCLKDIV_Msk) | u32ClkDiv;
272 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_HCLKSEL_Msk) | u32ClkSrc;
274}
275
456void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv)
457{
458 uint32_t u32tmp=0,u32sel=0,u32div=0;
459
460 if(MODULE_CLKDIV_Msk(u32ModuleIdx)!=MODULE_NoMsk)
461 {
462 u32div =(uint32_t)&CLK->CLKDIV0+((MODULE_CLKDIV(u32ModuleIdx))*4);
463 u32tmp = *(volatile uint32_t *)(u32div);
464 u32tmp = ( u32tmp & ~(MODULE_CLKDIV_Msk(u32ModuleIdx)<<MODULE_CLKDIV_Pos(u32ModuleIdx)) ) | u32ClkDiv;
465 *(volatile uint32_t *)(u32div) = u32tmp;
466 }
467
468 if(MODULE_CLKSEL_Msk(u32ModuleIdx)!=MODULE_NoMsk)
469 {
470 u32sel = (uint32_t)&CLK->CLKSEL0+((MODULE_CLKSEL(u32ModuleIdx))*4);
471 u32tmp = *(volatile uint32_t *)(u32sel);
472 u32tmp = ( u32tmp & ~(MODULE_CLKSEL_Msk(u32ModuleIdx)<<MODULE_CLKSEL_Pos(u32ModuleIdx)) ) | u32ClkSrc;
473 *(volatile uint32_t *)(u32sel) = u32tmp;
474 }
475}
476
486void CLK_EnableXtalRC(uint32_t u32ClkMask)
487{
488 CLK->PWRCTL |= u32ClkMask;
489}
490
500void CLK_DisableXtalRC(uint32_t u32ClkMask)
501{
502 CLK->PWRCTL &= ~u32ClkMask;
503}
504
571void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
572{
573 *(volatile uint32_t *)((uint32_t)&CLK->AHBCLK+(MODULE_APBCLK(u32ModuleIdx)*4)) |= 1<<MODULE_IP_EN_Pos(u32ModuleIdx);
574}
575
642void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
643{
644 *(volatile uint32_t *)((uint32_t)&CLK->AHBCLK+(MODULE_APBCLK(u32ModuleIdx)*4)) &= ~(1<<MODULE_IP_EN_Pos(u32ModuleIdx));
645}
646
655uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
656{
657 uint32_t u32PllSrcClk, u32NR, u32NF, u32NO, u32CLK_SRC;
658 uint32_t u32Tmp, u32Tmp2, u32Tmp3, u32Min, u32MinNF, u32MinNR;
659
660 /* Disable PLL first to avoid unstable when setting PLL */
662
663 /* PLL source clock is from HXT */
664 if(u32PllClkSrc == CLK_PLLCTL_PLLSRC_HXT)
665 {
666 /* Enable HXT clock */
667 CLK->PWRCTL |= CLK_PWRCTL_HXTEN_Msk;
668
669 /* Wait for HXT clock ready */
671
672 /* Select PLL source clock from HXT */
673 u32CLK_SRC = CLK_PLLCTL_PLLSRC_HXT;
674 u32PllSrcClk = __HXT;
675
676 /* u32NR start from 2 */
677 u32NR = 2;
678 }
679
680 /* PLL source clock is from HIRC */
681 else
682 {
683 /* Enable HIRC clock */
684 CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
685
686 /* Wait for HIRC clock ready */
688
689 /* Select PLL source clock from HIRC */
690 u32CLK_SRC = CLK_PLLCTL_PLLSRC_HIRC;
691 u32PllSrcClk = __HIRC;
692
693 /* u32NR start from 4 when FIN = 22.1184MHz to avoid calculation overflow */
694 u32NR = 4;
695 }
696
697 /* Select "NO" according to request frequency */
698 if((u32PllFreq <= FREQ_500MHZ) && (u32PllFreq > FREQ_250MHZ))
699 {
700 u32NO = 0;
701 }
702 else if((u32PllFreq <= FREQ_250MHZ) && (u32PllFreq > FREQ_125MHZ))
703 {
704 u32NO = 1;
705 u32PllFreq = u32PllFreq << 1;
706 }
707 else if((u32PllFreq <= FREQ_125MHZ) && (u32PllFreq >= FREQ_50MHZ))
708 {
709 u32NO = 3;
710 u32PllFreq = u32PllFreq << 2;
711 }
712 else
713 {
714 /* Wrong frequency request. Just return default setting. */
715 goto lexit;
716 }
717
718 /* Find best solution */
719 u32Min = (uint32_t) - 1;
720 u32MinNR = 0;
721 u32MinNF = 0;
722 for(; u32NR <= 33; u32NR++)
723 {
724 u32Tmp = u32PllSrcClk / u32NR;
725 if((u32Tmp > 1600000) && (u32Tmp < 16000000))
726 {
727 for(u32NF = 2; u32NF <= 513; u32NF++)
728 {
729 u32Tmp2 = u32Tmp * u32NF;
730 if((u32Tmp2 >= 200000000) && (u32Tmp2 <= 500000000))
731 {
732 u32Tmp3 = (u32Tmp2 > u32PllFreq) ? u32Tmp2 - u32PllFreq : u32PllFreq - u32Tmp2;
733 if(u32Tmp3 < u32Min)
734 {
735 u32Min = u32Tmp3;
736 u32MinNR = u32NR;
737 u32MinNF = u32NF;
738
739 /* Break when get good results */
740 if(u32Min == 0)
741 break;
742 }
743 }
744 }
745 }
746 }
747
748 /* Enable and apply new PLL setting. */
749 CLK->PLLCTL = u32CLK_SRC | (u32NO << 14) | ((u32MinNR - 2) << 9) | (u32MinNF - 2);
750
751 /* Wait for PLL clock stable */
753
754 /* Return actual PLL output clock frequency */
755 return u32PllSrcClk / ((u32NO + 1) * u32MinNR) * u32MinNF;
756
757lexit:
758
759 /* Apply default PLL setting and return */
760 if(u32PllClkSrc == CLK_PLLCTL_PLLSRC_HXT)
761 CLK->PLLCTL = CLK_PLLCTL_84MHz_HXT; /* 84MHz */
762 else
763 CLK->PLLCTL = CLK_PLLCTL_50MHz_HIRC; /* 50MHz */
764
765 /* Wait for PLL clock stable */
767
768 return CLK_GetPLLClockFreq();
769}
770
776{
777 CLK->PLLCTL |= CLK_PLLCTL_PD_Msk;
778}
779
790void CLK_SetSysTickClockSrc(uint32_t u32ClkSrc)
791{
792 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc ;
793}
804int32_t CLK_SysTickDelay(uint32_t us)
805{
806 /* The u32TimeOutCnt value must be greater than the max delay time of 1398ms if HCLK=12MHz */
807 uint32_t u32TimeOutCnt = SystemCoreClock * 2;
808
809 SysTick->LOAD = us * CyclesPerUs;
810 SysTick->VAL = (0x00);
811 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
812
813 /* Waiting for down-count to zero */
814 while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0)
815 {
816 if(--u32TimeOutCnt == 0)
817 {
818 break;
819 }
820 }
821
822 /* Disable SysTick counter */
823 SysTick->CTRL = 0;
824
825 if(u32TimeOutCnt == 0)
826 return CLK_TIMEOUT_ERR;
827 else
828 return 0;
829}
830
847uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
848{
849 uint32_t u32TimeOutCnt = SystemCoreClock / 2;
850 uint32_t u32Ret = 1U;
851
853
854 while((CLK->STATUS & u32ClkMask) != u32ClkMask)
855 {
856 if(--u32TimeOutCnt == 0)
857 {
858 u32Ret = 0U;
859 break;
860 }
861 }
862
863 if(u32TimeOutCnt == 0)
865
866 return u32Ret;
867}
868
883void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
884{
885 /* Set System Tick counter disabled */
886 SysTick->CTRL = 0;
887
888 /* Set System Tick clock source */
889 if( u32ClkSrc == CLK_CLKSEL0_STCLKSEL_HCLK )
890 SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
891 else
892 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc;
893
894 /* Set System Tick reload value */
895 SysTick->LOAD = u32Count;
896
897 /* Clear System Tick current value and counter flag */
898 SysTick->VAL = 0;
899
900 /* Set System Tick interrupt enabled and counter enabled */
901 SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
902}
903
911{
912 /* Set System Tick counter disabled */
913 SysTick->CTRL = 0;
914}
915 /* end of group NUC472_442_CLK_EXPORTED_FUNCTIONS */
917 /* end of group NUC472_442_CLK_Driver */
919 /* end of group NUC472_442_Device_Driver */
921
922/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
923
NUC472/NUC442 peripheral access layer header file. This file contains all the peripheral register's d...
#define CLK_PWRCTL_LXTEN_Msk
Definition: NUC472_442.h:3551
#define CLK_PLLCTL_INDIV_Pos
Definition: NUC472_442.h:3904
#define CLK_PLLCTL_FBDIV_Msk
Definition: NUC472_442.h:3902
#define CLK_PLLCTL_PLLSRC_Msk
Definition: NUC472_442.h:3920
#define CLK_STATUS_PLLSTB_Msk
Definition: NUC472_442.h:3938
#define CLK_PWRCTL_PDEN_Msk
Definition: NUC472_442.h:3569
#define CLK_CLKOCTL_CLKOEN_Msk
Definition: NUC472_442.h:3956
#define CLK_PLLCTL_INDIV_Msk
Definition: NUC472_442.h:3905
#define CLK_APBCLK0_CLKOCKEN_Msk
Definition: NUC472_442.h:3629
#define CLK_CLKSEL0_HCLKSEL_Msk
Definition: NUC472_442.h:3761
#define CLK_PLLCTL_PD_Msk
Definition: NUC472_442.h:3911
#define CLK_PWRCTL_HIRCEN_Msk
Definition: NUC472_442.h:3554
#define CLK_PLLCTL_PLLSRC_Pos
Definition: NUC472_442.h:3919
#define CLK_PWRCTL_PDWKDLY_Msk
Definition: NUC472_442.h:3560
#define CLK_PLLCTL_OUTDV_Pos
Definition: NUC472_442.h:3907
#define CLK_CLKSEL0_PCLKSEL_Msk
Definition: NUC472_442.h:3767
#define CLK_PWRCTL_HXTEN_Msk
Definition: NUC472_442.h:3548
#define CLK_PLLCTL_OUTDV_Msk
Definition: NUC472_442.h:3908
#define CLK_STATUS_HXTSTB_Msk
Definition: NUC472_442.h:3932
#define CLK_PLLCTL_OE_Msk
Definition: NUC472_442.h:3917
#define CLK_STATUS_HIRCSTB_Msk
Definition: NUC472_442.h:3944
#define CLK_CLKOCTL_DIV1EN_Pos
Definition: NUC472_442.h:3958
int32_t g_CLK_i32ErrCode
Definition: clk.c:22
#define CLK_CLKSEL0_STCLKSEL_HCLK
Definition: clk.h:97
#define CLK_PLLCTL_PLLSRC_HXT
Definition: clk.h:50
#define FREQ_250MHZ
Definition: clk.h:35
#define CLK_PLLCTL_50MHz_HIRC
Definition: clk.h:71
#define MODULE_NoMsk
Definition: clk.h:315
#define MODULE_CLKSEL_Msk(x)
Definition: clk.h:309
#define CLK_CLKDIV0_HCLK(x)
Definition: clk.h:276
#define CLK_CLKSEL0_HCLKSEL_PLL
Definition: clk.h:87
#define FREQ_125MHZ
Definition: clk.h:37
#define CLK_PLLCTL_PLLSRC_HIRC
Definition: clk.h:49
#define FREQ_24MHZ
Definition: clk.h:41
#define MODULE_CLKSEL_Pos(x)
Definition: clk.h:310
#define FREQ_50MHZ
Definition: clk.h:39
#define MODULE_CLKDIV_Pos(x)
Definition: clk.h:313
#define MODULE_IP_EN_Pos(x)
Definition: clk.h:314
#define MODULE_CLKDIV_Msk(x)
Definition: clk.h:312
#define MODULE_CLKDIV(x)
Definition: clk.h:311
#define MODULE_APBCLK(x)
Definition: clk.h:307
#define CLK_TIMEOUT_ERR
Definition: clk.h:394
#define FREQ_500MHZ
Definition: clk.h:34
#define MODULE_CLKSEL(x)
Definition: clk.h:308
void CLK_Idle(void)
Enter to Idle mode.
Definition: clk.c:87
uint32_t CLK_GetPCLKFreq(void)
This function get PCLK frequency. The frequency unit is Hz.
Definition: clk.c:104
void CLK_SetSysTickClockSrc(uint32_t u32ClkSrc)
This function set SysTick clock source.
Definition: clk.c:790
uint32_t CLK_GetHCLKFreq(void)
Get HCLK frequency.
Definition: clk.c:145
uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
This function set PLL frequency.
Definition: clk.c:655
void CLK_DisableCKO(void)
Disable frequency output function.
Definition: clk.c:34
void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
This function enable module clock.
Definition: clk.c:571
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:58
void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
This function disable module clock.
Definition: clk.c:642
uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
This function check selected clock source status.
Definition: clk.c:847
uint32_t CLK_GetLXTFreq(void)
Get external low speed crystal clock frequency.
Definition: clk.c:131
void CLK_PowerDown(void)
Enter to Power-down mode.
Definition: clk.c:75
void CLK_DisablePLL(void)
This function disable PLL.
Definition: clk.c:775
uint32_t CLK_GetCPUFreq(void)
Get CPU frequency.
Definition: clk.c:156
int32_t CLK_SysTickDelay(uint32_t us)
This function execute delay function.
Definition: clk.c:804
void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
This function set HCLK clock source and HCLK clock divider.
Definition: clk.c:269
void CLK_DisableXtalRC(uint32_t u32ClkMask)
This function disable clock source.
Definition: clk.c:500
void CLK_DisableSysTick(void)
Disable System Tick counter.
Definition: clk.c:910
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:456
void CLK_EnableXtalRC(uint32_t u32ClkMask)
This function enable clock source.
Definition: clk.c:486
void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
Enable System Tick counter.
Definition: clk.c:883
uint32_t CLK_SetCoreClock(uint32_t u32Hclk)
Set HCLK frequency.
Definition: clk.c:210
uint32_t CLK_GetPLLClockFreq(void)
This function get PLL frequency. The frequency unit is Hz.
Definition: clk.c:166
uint32_t CLK_GetHXTFreq(void)
Get external high speed crystal clock frequency.
Definition: clk.c:118
#define CLK
Definition: NUC472_442.h:28798
#define __HIRC
#define __HXT
uint32_t CyclesPerUs
uint32_t SystemCoreClock
#define __LXT
void SystemCoreClockUpdate(void)
Updates the SystemCoreClock with current core Clock retrieved from CPU registers.