Nano100AN Series BSP  V3.02.002
The Board Support Package for Nano100AN Series
timer.c
Go to the documentation of this file.
1 /**************************************************************************/
12 #include "Nano100Series.h"
13 
41 uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq)
42 {
43  uint32_t u32Clk = TIMER_GetModuleClock(timer);
44  uint32_t u32Cmpr = 0, u32Prescale = 0;
45 
46  // Fastest possible timer working freq is u32Clk / 2. While cmpr = 2, pre-scale = 0
47  if(u32Freq > (u32Clk / 2))
48  {
49  u32Cmpr = 2;
50  }
51  else
52  {
53  if(u32Clk > 0xFFFFFF) // For Nano100, only needs to consider 32MHz at most
54  {
55  u32Prescale = 1;
56  u32Clk >>= 1;
57  }
58  u32Cmpr = u32Clk / u32Freq;
59  }
60  timer->CMPR = u32Cmpr;
61  timer->PRECNT = u32Prescale;
62  timer->CTL = u32Mode;
63 
64 
65  return(u32Clk / (u32Cmpr * (u32Prescale + 1)));
66 }
67 
73 void TIMER_Close(TIMER_T *timer)
74 {
75  timer->CTL = 0;
76  timer->IER = 0;
77 }
78 
87 void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec)
88 {
89  uint32_t u32Clk = TIMER_GetModuleClock(timer);
90  uint32_t u32Prescale = 0, delay = SystemCoreClock / u32Clk;
91  float fCmpr;
92 
93  // Clear current timer configuration
94  timer->CTL = 0;
95 
96  if(u32Clk == 10000) // min delay is 100us if timer clock source is LIRC 10k
97  {
98  u32Usec = ((u32Usec + 99) / 100) * 100;
99  }
100  else // 10 usec every step
101  {
102  u32Usec = ((u32Usec + 9) / 10) * 10;
103  }
104 
105  if(u32Clk > 0xFFFFFF) // For Nano100, only needs to consider 32MHz at most
106  {
107  u32Prescale = 1;
108  u32Clk >>= 1;
109  }
110 
111  // u32Usec * u32Clk might overflow if using uint32_t
112  fCmpr = ((float)u32Usec * (float)u32Clk) / 1000000.0;
113 
114  timer->CMPR = (uint32_t)fCmpr;
115  timer->PRECNT = u32Prescale;
116  timer->CTL = TIMER_CTL_TMR_EN_Msk; // one shot mode
117 
118  // When system clock is faster than timer clock, it is possible timer active bit cannot set in time while we check it.
119  // And the while loop below return immediately, so put a tiny delay here allowing timer start counting and raise active flag.
120  for(; delay > 0; delay--)
121  {
122  __NOP();
123  }
124 
125  while(timer->CTL & TIMER_CTL_TMR_ACT_Msk);
126 
127 }
128 
144 void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
145 {
146 
147  timer->CTL = (timer->CTL & ~(TIMER_CTL_TCAP_MODE_Msk |
150  u32CapMode | u32Edge | TIMER_CTL_TCAP_EN_Msk;
151 }
152 
159 {
160  timer->CTL &= ~TIMER_CTL_TCAP_EN_Msk;
161 
162 }
163 
173 void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge)
174 {
175  timer->CTL = (timer->CTL & ~TIMER_CTL_EVENT_EDGE_Msk) | u32Edge;
176  timer->CTL |= TIMER_CTL_EVENT_EN_Msk;
177 }
178 
185 {
186  timer->CTL &= ~TIMER_CTL_EVENT_EN_Msk;
187 }
188 
196 {
197  uint32_t u32Src;
198  const uint32_t au32Clk[] = {__HXT, __LXT, __LIRC, 0}; // we don't know actual clock if external pin is clock source, set to 0 here
199 
200  if(timer == TIMER0)
201  u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0_S_Msk) >> CLK_CLKSEL1_TMR0_S_Pos;
202  else if(timer == TIMER1)
203  u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1_S_Msk) >> CLK_CLKSEL1_TMR1_S_Pos;
204  else if(timer == TIMER2)
205  u32Src = (CLK->CLKSEL2 & CLK_CLKSEL2_TMR2_S_Msk) >> CLK_CLKSEL2_TMR2_S_Pos;
206  else // Timer 3
207  u32Src = (CLK->CLKSEL2 & CLK_CLKSEL2_TMR3_S_Msk) >> CLK_CLKSEL2_TMR3_S_Pos;
208 
209  if(u32Src < 4)
210  return au32Clk[u32Src];
211  else
212  return __HIRC;
213 
214 }
215 
230  uint32_t u32DropCount,
231  uint32_t u32Timeout,
232  uint32_t u32EnableInt)
233 {
234  TIMER_T *t; // store the timer base to configure compare value
235 
236  t = (timer == TIMER0) ? TIMER1 : TIMER3;
237 
238  t->CMPR = 0xFFFFFF;
239  t->IER = u32EnableInt ? TIMER_IER_TCAP_IE_Msk : 0;
241 
242  return;
243 }
250 {
251  timer->CTL &= ~TIMER_CTL_INTR_TRG_EN_Msk;
252 }
253 
262 void TIMER_SetTriggerSource(TIMER_T *timer, uint32_t u32Src)
263 {
264  timer->CTL = (timer->CTL & ~TIMER_CTL_CAP_TRG_EN_Msk) | u32Src;
265 }
266 
275 void TIMER_SetTriggerTarget(TIMER_T *timer, uint32_t u32Mask)
276 {
277  timer->CTL = (timer->CTL & ~(TIMER_CTL_PDMA_TEEN_Msk | TIMER_CTL_ADC_TEEN_Msk)) | u32Mask;
278 }
279  /* end of group NANO100_TIMER_EXPORTED_FUNCTIONS */
281  /* end of group NANO100_TIMER_Driver */
283  /* end of group NANO100_Device_Driver */
285 
286 /*** (C) COPYRIGHT 2015 Nuvoton Technology Corp. ***/
uint32_t SystemCoreClock
void TIMER_DisableEventCounter(TIMER_T *timer)
This function is used to disable the Timer event counter function.
Definition: timer.c:184
#define TIMER_CTL_PDMA_TEEN_Msk
#define CLK_CLKSEL2_TMR2_S_Msk
#define CLK_CLKSEL1_TMR0_S_Pos
#define CLK
Pointer to CLK register structure.
#define TIMER_CTL_TCAP_EN_Msk
#define TIMER_CTL_TMR_EN_Msk
#define TIMER2
Pointer to TIMER2 register structure.
Nano100 series peripheral access layer header file. This file contains all the peripheral register's ...
#define CLK_CLKSEL1_TMR0_S_Msk
#define TIMER_CTL_EVENT_EDGE_Msk
__IO uint32_t IER
#define CLK_CLKSEL2_TMR3_S_Msk
void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
This function is used to enable timer capture function with specified mode and capture edge.
Definition: timer.c:144
#define CLK_CLKSEL1_TMR1_S_Pos
#define CLK_CLKSEL1_TMR1_S_Msk
#define TIMER_CTL_EVENT_EN_Msk
#define TIMER_CTL_CAP_TRG_EN_Msk
#define TIMER_CTL_TMR_ACT_Msk
#define TIMER_CTL_TCAP_CNT_MODE_Msk
#define __HIRC
void TIMER_DisableCapture(TIMER_T *timer)
This function is used to disable the Timer capture function.
Definition: timer.c:158
#define TIMER_IER_TCAP_IE_Msk
uint32_t TIMER_GetModuleClock(TIMER_T *timer)
This function is used to get the clock frequency of Timer.
Definition: timer.c:195
#define TIMER3
Pointer to TIMER3 register structure.
#define TIMER1
Pointer to TIMER1 register structure.
#define __HXT
#define TIMER0
Pointer to TIMER0 register structure.
#define __LXT
#define TIMER_CTL_TCAP_EDGE_Msk
void TIMER_Close(TIMER_T *timer)
This function stops Timer counting and disable the Timer interrupt function.
Definition: timer.c:73
void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec)
This function is used to create a delay loop for u32usec micro seconds.
Definition: timer.c:87
#define CLK_CLKSEL2_TMR2_S_Pos
#define CLK_CLKSEL2_TMR3_S_Pos
__IO uint32_t CMPR
__IO uint32_t PRECNT
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:229
#define TIMER_CTL_ADC_TEEN_Msk
void TIMER_SetTriggerTarget(TIMER_T *timer, uint32_t u32Mask)
This function is used to set modules trigger by timer interrupt.
Definition: timer.c:275
#define TIMER_CTL_TCAP_MODE_Msk
__IO uint32_t CTL
void TIMER_DisableFreqCounter(TIMER_T *timer)
This function is used to disable the Timer frequency counter function.
Definition: timer.c:249
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:262
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:173
uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq)
This function is used to configure timer to operate in specified mode and frequency....
Definition: timer.c:41
#define __LIRC
#define TIMER_CTL_INTR_TRG_EN_Msk