M480 BSP V3.05.006
The Board Support Package for M480 Series
timer.c
Go to the documentation of this file.
1/**************************************************************************/
8#include "NuMicro.h"
9
10
41uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq)
42{
43 uint32_t u32Clk = TIMER_GetModuleClock(timer);
44 uint32_t u32Cmpr = 0UL, u32Prescale = 0UL;
45
46 /* Fastest possible timer working freq is (u32Clk / 2). While cmpr = 2, prescaler = 0. */
47 if(u32Freq > (u32Clk / 2UL))
48 {
49 u32Cmpr = 2UL;
50 }
51 else
52 {
53 u32Cmpr = u32Clk / u32Freq;
54 u32Prescale = (u32Cmpr >> 24); /* for 24 bits CMPDAT */
55 if (u32Prescale > 0UL)
56 u32Cmpr = u32Cmpr / (u32Prescale + 1UL);
57 }
58
59 timer->CTL = u32Mode | u32Prescale;
60 timer->CMP = u32Cmpr;
61
62 return(u32Clk / (u32Cmpr * (u32Prescale + 1UL)));
63}
64
74void TIMER_Close(TIMER_T *timer)
75{
76 timer->CTL = 0UL;
77 timer->EXTCTL = 0UL;
78}
79
94int32_t TIMER_Delay(TIMER_T *timer, uint32_t u32Usec)
95{
96 uint32_t u32Clk = TIMER_GetModuleClock(timer);
97 uint32_t u32Prescale = 0UL, u32Delay;
98 uint32_t u32Cmpr, u32Cntr, u32NsecPerTick, i = 0UL;
99
100 /* Clear current timer configuration */
101 timer->CTL = 0UL;
102 timer->EXTCTL = 0UL;
103
104 if(u32Clk <= 1000000UL) /* min delay is 1000 us if timer clock source is <= 1 MHz */
105 {
106 if(u32Usec < 1000UL)
107 {
108 u32Usec = 1000UL;
109 }
110 if(u32Usec > 1000000UL)
111 {
112 u32Usec = 1000000UL;
113 }
114 }
115 else
116 {
117 if(u32Usec < 100UL)
118 {
119 u32Usec = 100UL;
120 }
121 if(u32Usec > 1000000UL)
122 {
123 u32Usec = 1000000UL;
124 }
125 }
126
127 if(u32Clk <= 1000000UL)
128 {
129 u32Prescale = 0UL;
130 u32NsecPerTick = 1000000000UL / u32Clk;
131 u32Cmpr = (u32Usec * 1000UL) / u32NsecPerTick;
132 }
133 else
134 {
135 u32Cmpr = u32Usec * (u32Clk / 1000000UL);
136 u32Prescale = (u32Cmpr >> 24); /* for 24 bits CMPDAT */
137 if (u32Prescale > 0UL)
138 u32Cmpr = u32Cmpr / (u32Prescale + 1UL);
139 }
140
141 timer->CMP = u32Cmpr;
142 timer->CTL = TIMER_CTL_CNTEN_Msk | TIMER_ONESHOT_MODE | u32Prescale;
143
144 /* When system clock is faster than timer clock, it is possible timer active bit cannot set
145 in time while we check it. And the while loop below return immediately, so put a tiny
146 delay larger than 1 ECLK here allowing timer start counting and raise active flag. */
147 for(u32Delay = (SystemCoreClock / u32Clk) + 1UL; u32Delay > 0UL; u32Delay--)
148 {
149 __NOP();
150 }
151
152 /* Add a bail out counter here in case timer clock source is disabled accidentally.
153 Prescale counter reset every ECLK * (prescale value + 1).
154 The u32Delay here is to make sure timer counter value changed when prescale counter reset */
155 u32Delay = (SystemCoreClock / TIMER_GetModuleClock(timer)) * (u32Prescale + 1);
156 u32Cntr = timer->CNT;
157 while(timer->CTL & TIMER_CTL_ACTSTS_Msk)
158 {
159 /* Bailed out if timer stop counting e.g. Some interrupt handler close timer clock source. */
160 if(u32Cntr == timer->CNT)
161 {
162 if(i++ > u32Delay)
163 {
164 return TIMER_TIMEOUT_ERR;
165 }
166 }
167 else
168 {
169 i = 0;
170 u32Cntr = timer->CNT;
171 }
172 }
173 return 0;
174}
175
195void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
196{
198 u32CapMode | u32Edge | TIMER_EXTCTL_CAPEN_Msk;
199}
200
211{
212 timer->EXTCTL &= ~TIMER_EXTCTL_CAPEN_Msk;
213}
214
229void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge)
230{
231 timer->EXTCTL = (timer->EXTCTL & ~TIMER_EXTCTL_CNTPHASE_Msk) | u32Edge;
232 timer->CTL |= TIMER_CTL_EXTCNTEN_Msk;
233}
234
245{
246 timer->CTL &= ~TIMER_CTL_EXTCNTEN_Msk;
247}
248
260{
261 uint32_t u32Src, u32Clk;
262 const uint32_t au32Clk[] = {__HXT, __LXT, 0UL, 0UL, 0UL, __LIRC, 0UL, __HIRC};
263
264 if(timer == TIMER0)
265 {
266 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0SEL_Msk) >> CLK_CLKSEL1_TMR0SEL_Pos;
267 }
268 else if(timer == TIMER1)
269 {
270 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1SEL_Msk) >> CLK_CLKSEL1_TMR1SEL_Pos;
271 }
272 else if(timer == TIMER2)
273 {
274 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR2SEL_Msk) >> CLK_CLKSEL1_TMR2SEL_Pos;
275 }
276 else /* Timer 3 */
277 {
278 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR3SEL_Msk) >> CLK_CLKSEL1_TMR3SEL_Pos;
279 }
280
281 if(u32Src == 2UL)
282 {
283 if((timer == TIMER0) || (timer == TIMER1))
284 {
285 u32Clk = CLK_GetPCLK0Freq();
286 }
287 else
288 {
289 u32Clk = CLK_GetPCLK1Freq();
290 }
291 }
292 else
293 {
294 u32Clk = au32Clk[u32Src];
295 }
296
297 return u32Clk;
298}
299
300
301
316 uint32_t u32DropCount,
317 uint32_t u32Timeout,
318 uint32_t u32EnableInt)
319{
320 TIMER_T *t; /* store the timer base to configure compare value */
321
322 t = (timer == TIMER0) ? TIMER1 : TIMER3;
323
324 t->CMP = 0xFFFFFFUL;
325 t->EXTCTL = u32EnableInt ? TIMER_EXTCTL_CAPIEN_Msk : 0UL;
327
328 return;
329}
336{
337 timer->CTL &= ~TIMER_CTL_INTRGEN_Msk;
338}
339
340
349void TIMER_SetTriggerSource(TIMER_T *timer, uint32_t u32Src)
350{
351 timer->TRGCTL = (timer->TRGCTL & ~TIMER_TRGCTL_TRGSSEL_Msk) | u32Src;
352}
353
364void TIMER_SetTriggerTarget(TIMER_T *timer, uint32_t u32Mask)
365{
367}
368
381{
382 uint32_t u32Delay;
383
384 timer->CNT = 0UL;
385 /* Takes 2~3 ECLKs to reset timer counter */
386 u32Delay = (SystemCoreClock / TIMER_GetModuleClock(timer)) * 3;
387 while(((timer->CNT&TIMER_CNT_RSTACT_Msk) == TIMER_CNT_RSTACT_Msk) && (--u32Delay))
388 {
389 __NOP();
390 }
391 return u32Delay > 0 ? 0 : TIMER_TIMEOUT_ERR;
392}
393 /* end of group TIMER_EXPORTED_FUNCTIONS */
395 /* end of group TIMER_Driver */
397 /* end of group Standard_Driver */
NuMicro peripheral access layer header file.
uint32_t CLK_GetPCLK1Freq(void)
Get PCLK1 frequency.
Definition: clk.c:206
uint32_t CLK_GetPCLK0Freq(void)
Get PCLK0 frequency.
Definition: clk.c:166
#define CLK
Definition: M480.h:368
#define TIMER1
Definition: M480.h:412
#define TIMER3
Definition: M480.h:414
#define TIMER2
Definition: M480.h:413
#define TIMER0
Definition: M480.h:411
#define CLK_CLKSEL1_TMR1SEL_Msk
Definition: clk_reg.h:2532
#define TIMER_TRGCTL_TRGEADC_Msk
Definition: timer_reg.h:1746
#define CLK_CLKSEL1_TMR0SEL_Msk
Definition: clk_reg.h:2529
#define TIMER_TRGCTL_TRGPDMA_Msk
Definition: timer_reg.h:1752
#define TIMER_EXTCTL_CAPFUNCS_Msk
Definition: timer_reg.h:1713
#define CLK_CLKSEL1_TMR2SEL_Pos
Definition: clk_reg.h:2534
#define TIMER_EXTCTL_CAPEDGE_Msk
Definition: timer_reg.h:1728
#define CLK_CLKSEL1_TMR1SEL_Pos
Definition: clk_reg.h:2531
#define TIMER_TRGCTL_TRGEPWM_Msk
Definition: timer_reg.h:1743
#define TIMER_CTL_EXTCNTEN_Msk
Definition: timer_reg.h:1671
#define TIMER_EXTCTL_CAPIEN_Msk
Definition: timer_reg.h:1716
#define TIMER_TRGCTL_TRGDAC_Msk
Definition: timer_reg.h:1749
#define TIMER_CTL_INTRGEN_Msk
Definition: timer_reg.h:1656
#define CLK_CLKSEL1_TMR3SEL_Msk
Definition: clk_reg.h:2538
#define TIMER_CTL_ACTSTS_Msk
Definition: timer_reg.h:1674
#define TIMER_CTL_CNTEN_Msk
Definition: timer_reg.h:1683
#define CLK_CLKSEL1_TMR3SEL_Pos
Definition: clk_reg.h:2537
#define TIMER_EXTCTL_CAPEN_Msk
Definition: timer_reg.h:1710
#define CLK_CLKSEL1_TMR0SEL_Pos
Definition: clk_reg.h:2528
#define TIMER_CNT_RSTACT_Msk
Definition: timer_reg.h:1701
#define CLK_CLKSEL1_TMR2SEL_Msk
Definition: clk_reg.h:2535
#define TIMER_ONESHOT_MODE
Definition: timer.h:32
#define TIMER_TIMEOUT_ERR
Definition: timer.h:58
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:349
void TIMER_DisableCapture(TIMER_T *timer)
Disable Timer Capture Function.
Definition: timer.c:210
uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq)
Open Timer with Operate Mode and Frequency.
Definition: timer.c:41
void TIMER_DisableEventCounter(TIMER_T *timer)
Disable Timer Counter Function.
Definition: timer.c:244
uint32_t TIMER_GetModuleClock(TIMER_T *timer)
Get Timer Clock Frequency.
Definition: timer.c:259
int32_t TIMER_ResetCounter(TIMER_T *timer)
Reset Counter.
Definition: timer.c:380
void TIMER_DisableFreqCounter(TIMER_T *timer)
This function is used to disable the Timer frequency counter function.
Definition: timer.c:335
void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge)
Enable Timer Counter Function.
Definition: timer.c:229
void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
Enable Timer Capture Function.
Definition: timer.c:195
void TIMER_Close(TIMER_T *timer)
Stop Timer Counting.
Definition: timer.c:74
void TIMER_SetTriggerTarget(TIMER_T *timer, uint32_t u32Mask)
This function is used to set modules trigger by timer interrupt.
Definition: timer.c:364
int32_t TIMER_Delay(TIMER_T *timer, uint32_t u32Usec)
Create a specify Delay Time.
Definition: timer.c:94
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:315
__IO uint32_t CNT
Definition: timer_reg.h:1609
__IO uint32_t TRGCTL
Definition: timer_reg.h:1613
__IO uint32_t CMP
Definition: timer_reg.h:1607
__IO uint32_t CTL
Definition: timer_reg.h:1606
__IO uint32_t EXTCTL
Definition: timer_reg.h:1611
#define __HIRC
Definition: system_M480.h:36
#define __HXT
Definition: system_M480.h:29
#define __LIRC
Definition: system_M480.h:37
uint32_t SystemCoreClock
Definition: system_M480.c:21
#define __LXT
Definition: system_M480.h:33