Nano103 BSP  V3.01.002
The Board Support Package for Nano103 Series
timer.c
Go to the documentation of this file.
1 /**************************************************************************/
12 #include "Nano103.h"
13 
42 uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq)
43 {
44  uint32_t u32Clk = TIMER_GetModuleClock(timer);
45  uint32_t u32Cmpr = 0, u32Prescale = 0;
46 
47  // Fastest possible timer working freq is u32Clk / 2. While cmpr = 2, pre-scale = 0
48  if(u32Freq > (u32Clk / 2))
49  {
50  u32Cmpr = 2;
51  }
52  else
53  {
54  if(u32Clk > 0xFFFFFF) // For Nano103, only needs to consider 36MHz at most
55  {
56  u32Prescale = 1;
57  u32Clk >>= 1;
58  }
59  u32Cmpr = u32Clk / u32Freq;
60  }
61  timer->CMP = u32Cmpr;
62  timer->PRECNT = u32Prescale;
63  timer->CTL = u32Mode;
64 
65 
66  return(u32Clk / (u32Cmpr * (u32Prescale + 1)));
67 }
68 
74 void TIMER_Close(TIMER_T *timer)
75 {
76  timer->CTL = 0;
77  timer->INTEN = 0;
78 }
79 
88 void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec)
89 {
90  uint32_t u32Clk = TIMER_GetModuleClock(timer);
91  uint32_t u32Prescale = 0, delay = SystemCoreClock / u32Clk;
92  long long u64Cmpr;
93 
94  // Clear current timer configuration
95  timer->CTL = 0;
96 
97  if(u32Clk == 10000) // min delay is 100us if timer clock source is LIRC 10k
98  {
99  u32Usec = ((u32Usec + 99) / 100) * 100;
100  }
101  else // 10 usec every step
102  {
103  u32Usec = ((u32Usec + 9) / 10) * 10;
104  }
105 
106  if(u32Clk > 0xFFFFFF) // For Nano103, only needs to consider 32MHz at most
107  {
108  u32Prescale = 1;
109  u32Clk >>= 1;
110  }
111 
112  // u32Usec * u32Clk might overflow if using uint32_t
113  u64Cmpr = (long long)u32Usec * (long long)u32Clk / (long long)1000000;
114 
115  timer->CMP = (uint32_t)u64Cmpr;
116  timer->PRECNT = u32Prescale;
117  timer->CTL = TIMER_CTL_CNTEN_Msk; // one shot mode
118 
119  // When system clock is faster than timer clock, it is possible timer active bit cannot set in time while we check it.
120  // And the while loop below return immediately, so put a tiny delay here allowing timer start counting and raise active flag.
121  for(; delay > 0; delay--)
122  {
123  __NOP();
124  }
125 
126  while(timer->CTL & TIMER_CTL_ACTSTS_Msk);
127 
128 }
129 
145 void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
146 {
147 
148  timer->CTL = (timer->CTL & ~(TIMER_CTL_CAPFUNCS_Msk |
151  u32CapMode | u32Edge | TIMER_CTL_CAPEN_Msk;
152 }
153 
160 {
161  timer->CTL &= ~TIMER_CTL_CAPEN_Msk;
162 
163 }
164 
174 void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge)
175 {
176  timer->CTL = (timer->CTL & ~TIMER_CTL_CNTPHASE_Msk) | u32Edge;
177  timer->CTL |= TIMER_CTL_EXTCNTEN_Msk;
178 }
179 
186 {
187  timer->CTL &= ~TIMER_CTL_EXTCNTEN_Msk;
188 }
189 
197 {
198  uint32_t u32Src, u32Div;
199  const uint32_t au32Clk[] = {__HXT, __LXT, __LIRC, 0}; // we don't know actual clock if external pin is clock source, set to 0 here
200 
201  if(timer == TIMER0)
202  {
203  u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0SEL_Msk) >> CLK_CLKSEL1_TMR0SEL_Pos;
204  u32Div = (CLK->CLKDIV1 & CLK_CLKDIV1_TMR0DIV_Msk) >> CLK_CLKDIV1_TMR0DIV_Pos;
205  }
206  else if(timer == TIMER1)
207  {
208  u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1SEL_Msk) >> CLK_CLKSEL1_TMR1SEL_Pos;
209  u32Div = (CLK->CLKDIV1 & CLK_CLKDIV1_TMR1DIV_Msk) >> CLK_CLKDIV1_TMR1DIV_Pos;
210  }
211  else if(timer == TIMER2)
212  {
213  u32Src = (CLK->CLKSEL2 & CLK_CLKSEL2_TMR2SEL_Msk) >> CLK_CLKSEL2_TMR2SEL_Pos;
214  u32Div = (CLK->CLKDIV1 & CLK_CLKDIV1_TMR2DIV_Msk) >> CLK_CLKDIV1_TMR2DIV_Pos;
215  }
216  else // Timer 3
217  {
218  u32Src = (CLK->CLKSEL2 & CLK_CLKSEL2_TMR3SEL_Msk) >> CLK_CLKSEL2_TMR3SEL_Pos;
219  u32Div = (CLK->CLKDIV1 & CLK_CLKDIV1_TMR3DIV_Msk) >> CLK_CLKDIV1_TMR3DIV_Pos;
220  }
221  u32Div++;
222  if(u32Src < 4)
223  return au32Clk[u32Src] / u32Div;
224  else if(u32Src == 4)
225  {
226  /* HIRC Source Selection */
227  if(CLK->CLKSEL0 & CLK_CLKSEL0_HIRCSEL_Msk)
228  {
229  /* Clock source from HIRC1 (36MHz) */
230  return __HIRC36M / u32Div;
231  }
232  else
233  {
234  /* Clock source from HIRC0 (12MHz) */
235  if(CLK->PWRCTL & CLK_PWRCTL_HIRC0FSEL_Msk)
236  return __HIRC16M / u32Div;
237  else
238  return __HIRC12M / u32Div;
239  }
240 
241  }
242  else if(u32Src == 5) // MIRC
243  {
244  return __MIRC / u32Div;
245 
246  }
247  else // HCLK
248  return CLK_GetHCLKFreq() / u32Div;
249 
250 }
251 
258 {
259  // A write with any value to TIMER CNT register will trigger timer counter reset
260  timer->CNT = 0;
261 }
262 
281  uint32_t u32DropCount,
282  uint32_t u32Timeout,
283  uint32_t u32EnableInt)
284 {
285  uint32_t mode = TIMER_CTL_INTRTGEN_Msk;
286  TIMER_T *t; // store the timer base to configure compare value
287 
288  if(u32DropCount != 0 || u32Timeout >= 2)
289  mode |= TIMER_CTL_INTRTGMD_Msk;
290  if(u32Timeout < 2)
291  u32Timeout = 0xFFFFFF;
292 
293  timer->ECTL = u32DropCount << TIMER_ECTL_EVNTDPCNT_Pos;
294  t = (timer == TIMER0) ? TIMER1 : TIMER3;
295 
296  t->CMP = u32Timeout;
297  t->INTEN = u32EnableInt ? TIMER_INTEN_CAPIEN_Msk : 0;
298  timer->CTL = mode | TIMER_CTL_CNTEN_Msk;
299 
300  return;
301 }
308 {
310 }
311 
320 void TIMER_SetTriggerSource(TIMER_T *timer, uint32_t u32Src)
321 {
322  timer->CTL = (timer->CTL & ~TIMER_CTL_TRGSSEL_Msk) | u32Src;
323 }
324 
334 void TIMER_SetTriggerTarget(TIMER_T *timer, uint32_t u32Mask)
335 {
336  timer->CTL = (timer->CTL & ~(TIMER_CTL_TRGPWM_Msk | TIMER_CTL_TRGPDMA_Msk | TIMER_CTL_TRGADC_Msk)) | u32Mask;
337 }
338  /* end of group NANO103_TIMER_EXPORTED_FUNCTIONS */
340  /* end of group NANO103_TIMER_Driver */
342  /* end of group NANO103_Device_Driver */
344 
345 /*** (C) COPYRIGHT 2015 Nuvoton Technology Corp. ***/
#define CLK_CLKSEL2_TMR3SEL_Pos
Definition: Nano103.h:5112
#define TIMER2
Pointer to TIMER2 register structure.
Definition: Nano103.h:24866
#define TIMER_CTL_INTRTGMD_Msk
Definition: Nano103.h:14303
__IO uint32_t CTL
Definition: Nano103.h:14227
#define TIMER_INTEN_CAPIEN_Msk
Definition: Nano103.h:14318
#define TIMER_CTL_TRGSSEL_Msk
Definition: Nano103.h:14270
#define CLK_PWRCTL_HIRC0FSEL_Msk
Definition: Nano103.h:4957
void TIMER_Close(TIMER_T *timer)
This API stops Timer counting and disable the Timer interrupt function.
Definition: timer.c:74
#define __HXT
void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge)
This function is used to enable the Timer counter function with specify detection edge.
Definition: timer.c:174
#define CLK_CLKSEL1_TMR0SEL_Msk
Definition: Nano103.h:5083
#define TIMER_CTL_EXTCNTEN_Msk
Definition: Nano103.h:14273
uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq)
This API is used to configure timer to operate in specified mode and frequency. If timer cannot work ...
Definition: timer.c:42
#define CLK_CLKSEL1_TMR1SEL_Pos
Definition: Nano103.h:5085
void TIMER_EnableFreqCounter(TIMER_T *timer, uint32_t u32DropCount, uint32_t u32Timeout, uint32_t u32EnableInt)
This function is used to enable the Timer frequency counter function.
Definition: timer.c:280
#define CLK_CLKDIV1_TMR0DIV_Pos
Definition: Nano103.h:5145
#define TIMER_CTL_CNTEN_Msk
Definition: Nano103.h:14246
#define CLK_CLKDIV1_TMR2DIV_Msk
Definition: Nano103.h:5152
void TIMER_DisableEventCounter(TIMER_T *timer)
This API is used to disable the Timer event counter function.
Definition: timer.c:185
#define TIMER_CTL_CAPEN_Msk
Definition: Nano103.h:14282
#define __HIRC16M
uint32_t SystemCoreClock
#define TIMER_CTL_CAPEDGE_Msk
Definition: Nano103.h:14288
#define __LXT
#define TIMER1
Pointer to TIMER1 register structure.
Definition: Nano103.h:24865
void TIMER_ResetCounter(TIMER_T *timer)
This function is used to reset the Timer counter value.
Definition: timer.c:257
__IO uint32_t PRECNT
Definition: Nano103.h:14228
#define TIMER_CTL_INTRTGEN_Msk
Definition: Nano103.h:14300
#define CLK_CLKDIV1_TMR1DIV_Pos
Definition: Nano103.h:5148
#define TIMER_CTL_TRGPWM_Msk
Definition: Nano103.h:14306
void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
This API is used to enable timer capture function with specified mode and capture edge.
Definition: timer.c:145
#define TIMER_ECTL_EVNTDPCNT_Pos
Definition: Nano103.h:14344
#define CLK_CLKDIV1_TMR3DIV_Pos
Definition: Nano103.h:5154
#define CLK_CLKSEL1_TMR0SEL_Pos
Definition: Nano103.h:5082
#define CLK_CLKDIV1_TMR2DIV_Pos
Definition: Nano103.h:5151
__IO uint32_t CMP
Definition: Nano103.h:14229
#define TIMER_CTL_TRGPDMA_Msk
Definition: Nano103.h:14267
#define TIMER_CTL_CAPCNTMD_Msk
Definition: Nano103.h:14291
#define TIMER_CTL_ACTSTS_Msk
Definition: Nano103.h:14261
#define CLK_CLKSEL2_TMR2SEL_Pos
Definition: Nano103.h:5109
#define __LIRC
uint32_t TIMER_GetModuleClock(TIMER_T *timer)
This API is used to get the clock frequency of Timer.
Definition: timer.c:196
#define TIMER_CTL_CNTPHASE_Msk
Definition: Nano103.h:14276
void TIMER_SetTriggerTarget(TIMER_T *timer, uint32_t u32Mask)
This function is used to set modules trigger by timer interrupt.
Definition: timer.c:334
#define __MIRC
uint32_t CLK_GetHCLKFreq(void)
This function get HCLK frequency. The frequency unit is Hz.
Definition: clk.c:126
#define CLK_CLKSEL2_TMR2SEL_Msk
Definition: Nano103.h:5110
#define TIMER3
Pointer to TIMER3 register structure.
Definition: Nano103.h:24867
void TIMER_DisableCapture(TIMER_T *timer)
This API is used to disable the Timer capture function.
Definition: timer.c:159
NANO103 peripheral access layer header file. This file contains all the peripheral register's definit...
#define TIMER_CTL_CAPFUNCS_Msk
Definition: Nano103.h:14285
__IO uint32_t CNT
Definition: Nano103.h:14232
#define __HIRC36M
#define CLK_CLKSEL0_HIRCSEL_Msk
Definition: Nano103.h:5071
#define CLK_CLKSEL1_TMR1SEL_Msk
Definition: Nano103.h:5086
void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec)
This API is used to create a delay loop for u32usec micro seconds.
Definition: timer.c:88
__IO uint32_t INTEN
Definition: Nano103.h:14230
#define CLK_CLKSEL2_TMR3SEL_Msk
Definition: Nano103.h:5113
#define CLK_CLKDIV1_TMR1DIV_Msk
Definition: Nano103.h:5149
#define __HIRC12M
#define CLK
Pointer to CLK register structure.
Definition: Nano103.h:24884
void TIMER_DisableFreqCounter(TIMER_T *timer)
This function is used to disable the Timer frequency counter function.
Definition: timer.c:307
#define TIMER0
Pointer to TIMER0 register structure.
Definition: Nano103.h:24864
#define CLK_CLKDIV1_TMR0DIV_Msk
Definition: Nano103.h:5146
#define TIMER_CTL_TRGADC_Msk
Definition: Nano103.h:14264
void TIMER_SetTriggerSource(TIMER_T *timer, uint32_t u32Src)
This function is used to select the interrupt source used to trigger other modules.
Definition: timer.c:320
__IO uint32_t ECTL
Definition: Nano103.h:14237
#define CLK_CLKDIV1_TMR3DIV_Msk
Definition: Nano103.h:5155