NANO100_BSP V3.04.002
The Board Support Package for Nano100BN Series
timer.c
Go to the documentation of this file.
1/**************************************************************************/
12#include "Nano100Series.h"
13
42uint32_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 >= 0x2000000)
55 {
56 u32Prescale = 3; // real prescaler value is 4
57 u32Clk >>= 2;
58 }
59 else if(u32Clk >= 0x1000000)
60 {
61 u32Prescale = 1; // real prescaler value is 2
62 u32Clk >>= 1;
63 }
64 u32Cmpr = u32Clk / u32Freq;
65 }
66 timer->CMPR = u32Cmpr;
67 timer->PRECNT = u32Prescale;
68 timer->CTL = u32Mode;
69
70
71 return(u32Clk / (u32Cmpr * (u32Prescale + 1)));
72}
73
79void TIMER_Close(TIMER_T *timer)
80{
81 timer->CTL = 0;
82 timer->IER = 0;
83}
84
93void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec)
94{
95 uint32_t u32Clk = TIMER_GetModuleClock(timer);
96 uint32_t u32Prescale = 0, delay = SystemCoreClock / u32Clk;
97 long long u64Cmpr;
98
99 // Clear current timer configuration
100 timer->CTL = 0;
101
102 if(u32Clk == 10000) // min delay is 100us if timer clock source is LIRC 10k
103 {
104 u32Usec = ((u32Usec + 99) / 100) * 100;
105 }
106 else // 10 usec every step
107 {
108 u32Usec = ((u32Usec + 9) / 10) * 10;
109 }
110
111 if(u32Clk >= 0x2000000)
112 {
113 u32Prescale = 3; // real prescaler value is 4
114 u32Clk >>= 2;
115 }
116 else if(u32Clk >= 0x1000000)
117 {
118 u32Prescale = 1; // real prescaler value is 2
119 u32Clk >>= 1;
120 }
121
122 // u32Usec * u32Clk might overflow if using uint32_t
123 u64Cmpr = ((long long)u32Usec * (long long)u32Clk) / (long long)1000000;
124
125 timer->CMPR = (uint32_t)u64Cmpr;
126 timer->PRECNT = u32Prescale;
127 timer->CTL = TIMER_CTL_TMR_EN_Msk; // one shot mode
128
129 // When system clock is faster than timer clock, it is possible timer active bit cannot set in time while we check it.
130 // And the while loop below return immediately, so put a tiny delay here allowing timer start counting and raise active flag.
131 for(; delay > 0; delay--)
132 {
133 __NOP();
134 }
135
136 delay = (SystemCoreClock / 1000000) * u32Usec * 10;
137
138 while ((timer->CTL & TIMER_CTL_TMR_ACT_Msk) && (delay-- > 0));
139}
140
156void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
157{
158
159 timer->CTL = (timer->CTL & ~(TIMER_CTL_TCAP_MODE_Msk |
162 u32CapMode | u32Edge | TIMER_CTL_TCAP_EN_Msk;
163}
164
171{
172 timer->CTL &= ~TIMER_CTL_TCAP_EN_Msk;
173
174}
175
185void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge)
186{
187 timer->CTL = (timer->CTL & ~TIMER_CTL_EVENT_EDGE_Msk) | u32Edge;
188 timer->CTL |= TIMER_CTL_EVENT_EN_Msk;
189}
190
197{
198 timer->CTL &= ~TIMER_CTL_EVENT_EN_Msk;
199}
200
208{
209 uint32_t u32Src;
210 const uint32_t au32Clk[] = {__HXT, __LXT, __LIRC, 0}; // we don't know actual clock if external pin is clock source, set to 0 here
211
212 if(timer == TIMER0)
213 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0_S_Msk) >> CLK_CLKSEL1_TMR0_S_Pos;
214 else if(timer == TIMER1)
215 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1_S_Msk) >> CLK_CLKSEL1_TMR1_S_Pos;
216 else if(timer == TIMER2)
217 u32Src = (CLK->CLKSEL2 & CLK_CLKSEL2_TMR2_S_Msk) >> CLK_CLKSEL2_TMR2_S_Pos;
218 else // Timer 3
219 u32Src = (CLK->CLKSEL2 & CLK_CLKSEL2_TMR3_S_Msk) >> CLK_CLKSEL2_TMR3_S_Pos;
220
221 if(u32Src < 4)
222 return au32Clk[u32Src];
223 else
224 return __HIRC;
225
226}
227
242 uint32_t u32DropCount,
243 uint32_t u32Timeout,
244 uint32_t u32EnableInt)
245{
246 TIMER_T *t; // store the timer base to configure compare value
247
248 t = (timer == TIMER0) ? TIMER1 : TIMER3;
249
250 t->CMPR = 0xFFFFFF;
251 t->IER = u32EnableInt ? TIMER_IER_TCAP_IE_Msk : 0;
253
254 return;
255}
262{
263 timer->CTL &= ~TIMER_CTL_INTR_TRG_EN_Msk;
264}
265
274void TIMER_SetTriggerSource(TIMER_T *timer, uint32_t u32Src)
275{
276 timer->CTL = (timer->CTL & ~TIMER_CTL_CAP_TRG_EN_Msk) | u32Src;
277}
278
288void TIMER_SetTriggerTarget(TIMER_T *timer, uint32_t u32Mask)
289{
291}
292 /* end of group NANO100_TIMER_EXPORTED_FUNCTIONS */
294 /* end of group NANO100_TIMER_Driver */
296 /* end of group NANO100_Device_Driver */
298
299/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/
Nano100 series peripheral access layer header file. This file contains all the peripheral register's ...
#define TIMER_CTL_TCAP_MODE_Msk
#define TIMER_CTL_TCAP_CNT_MODE_Msk
#define TIMER_CTL_INTR_TRG_EN_Msk
#define TIMER_CTL_EVENT_EN_Msk
#define TIMER_CTL_TMR_EN_Msk
#define TIMER_IER_TCAP_IE_Msk
#define TIMER_CTL_PDMA_TEEN_Msk
#define TIMER_CTL_TMR_ACT_Msk
#define TIMER_CTL_DAC_TEEN_Msk
#define TIMER_CTL_ADC_TEEN_Msk
#define TIMER_CTL_TCAP_EN_Msk
#define TIMER_CTL_TCAP_EDGE_Msk
#define CLK_CLKSEL2_TMR2_S_Pos
#define CLK_CLKSEL2_TMR3_S_Pos
#define CLK_CLKSEL2_TMR2_S_Msk
#define CLK_CLKSEL2_TMR3_S_Msk
#define CLK_CLKSEL1_TMR1_S_Msk
#define CLK_CLKSEL1_TMR0_S_Pos
#define CLK_CLKSEL1_TMR0_S_Msk
#define CLK_CLKSEL1_TMR1_S_Pos
#define CLK
Pointer to CLK register structure.
#define TIMER1
Pointer to TIMER1 register structure.
#define TIMER3
Pointer to TIMER3 register structure.
#define TIMER2
Pointer to TIMER2 register structure.
#define TIMER0
Pointer to TIMER0 register structure.
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:274
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:93
void TIMER_DisableCapture(TIMER_T *timer)
This API is used to disable the Timer capture function.
Definition: timer.c:170
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
void TIMER_DisableEventCounter(TIMER_T *timer)
This API is used to disable the Timer event counter function.
Definition: timer.c:196
uint32_t TIMER_GetModuleClock(TIMER_T *timer)
This API is used to get the clock frequency of Timer.
Definition: timer.c:207
void TIMER_DisableFreqCounter(TIMER_T *timer)
This function is used to disable the Timer frequency counter function.
Definition: timer.c:261
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:185
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:156
void TIMER_Close(TIMER_T *timer)
This API stops Timer counting and disable the Timer interrupt function.
Definition: timer.c:79
void TIMER_SetTriggerTarget(TIMER_T *timer, uint32_t u32Mask)
This function is used to set modules trigger by timer interrupt.
Definition: timer.c:288
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:241
__IO uint32_t IER
__IO uint32_t PRECNT
__IO uint32_t CMPR
__IO uint32_t CTL
#define __HIRC
#define __HXT
#define __LIRC
uint32_t SystemCoreClock
#define __LXT