M471M/R1/S BSP V3.01.000
The Board Support Package for M4521
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 = 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 u32Cmpr = u32Clk / u32Freq;
54 u32Prescale = (u32Cmpr >> 24); /* for 24 bits CMPDAT */
55 if (u32Prescale > 0)
56 u32Cmpr = u32Cmpr / (u32Prescale + 1);
57 }
58
59 timer->CTL = u32Mode | u32Prescale;
60 timer->CMP = u32Cmpr;
61
62 return(u32Clk / (u32Cmpr * (u32Prescale + 1)));
63}
64
74void TIMER_Close(TIMER_T *timer)
75{
76 timer->CTL = 0;
77 timer->EXTCTL = 0;
78}
79
92int32_t TIMER_Delay(TIMER_T *timer, uint32_t u32Usec)
93{
94 uint32_t u32Clk = TIMER_GetModuleClock(timer);
95 uint32_t u32Prescale = 0UL, u32Delay;
96 uint32_t u32Cmpr, u32Cntr, u32NsecPerTick, i = 0UL;
97
98 /* Clear current timer configuration */
99 timer->CTL = 0UL;
100 timer->EXTCTL = 0UL;
101
102 if(u32Clk <= 1000000UL) /* min delay is 1000 us if timer clock source is <= 1 MHz */
103 {
104 if(u32Usec < 1000UL)
105 {
106 u32Usec = 1000UL;
107 }
108 if(u32Usec > 1000000UL)
109 {
110 u32Usec = 1000000UL;
111 }
112 }
113 else
114 {
115 if(u32Usec < 100UL)
116 {
117 u32Usec = 100UL;
118 }
119 if(u32Usec > 1000000UL)
120 {
121 u32Usec = 1000000UL;
122 }
123 }
124
125 if(u32Clk <= 1000000UL)
126 {
127 u32Prescale = 0UL;
128 u32NsecPerTick = 1000000000UL / u32Clk;
129 u32Cmpr = (u32Usec * 1000UL) / u32NsecPerTick;
130 }
131 else
132 {
133 u32Cmpr = u32Usec * (u32Clk / 1000000UL);
134 u32Prescale = (u32Cmpr >> 24); /* for 24 bits CMPDAT */
135 if (u32Prescale > 0UL)
136 u32Cmpr = u32Cmpr / (u32Prescale + 1UL);
137 }
138
139 timer->CMP = u32Cmpr;
140 timer->CTL = TIMER_CTL_CNTEN_Msk | TIMER_ONESHOT_MODE | u32Prescale;
141
142 /* When system clock is faster than timer clock, it is possible timer active bit cannot set
143 in time while we check it. And the while loop below return immediately, so put a tiny
144 delay larger than 1 ECLK here allowing timer start counting and raise active flag. */
145 for(u32Delay = (SystemCoreClock / u32Clk) + 1UL; u32Delay > 0UL; u32Delay--)
146 {
147 __NOP();
148 }
149
150 /* Add a bail out counter here in case timer clock source is disabled accidentally.
151 Prescale counter reset every ECLK * (prescale value + 1).
152 The u32Delay here is to make sure timer counter value changed when prescale counter reset */
153 u32Delay = (SystemCoreClock / TIMER_GetModuleClock(timer)) * (u32Prescale + 1);
154 u32Cntr = timer->CNT;
155 i = 0;
156 while(timer->CTL & TIMER_CTL_ACTSTS_Msk)
157 {
158 /* Bailed out if timer stop counting e.g. Some interrupt handler close timer clock source. */
159 if(u32Cntr == timer->CNT)
160 {
161 if(i++ > u32Delay)
162 {
163 return TIMER_TIMEOUT_ERR;
164 }
165 }
166 else
167 {
168 i = 0;
169 u32Cntr = timer->CNT;
170 }
171 }
172 return 0;
173}
174
193void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
194{
195
197 u32CapMode | u32Edge | TIMER_EXTCTL_CAPEN_Msk;
198}
199
210{
211 timer->EXTCTL &= ~TIMER_EXTCTL_CAPEN_Msk;
212}
213
228void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge)
229{
230 timer->EXTCTL = (timer->EXTCTL & ~TIMER_EXTCTL_CNTPHASE_Msk) | u32Edge;
231 timer->CTL |= TIMER_CTL_EXTCNTEN_Msk;
232}
233
244{
245 timer->CTL &= ~TIMER_CTL_EXTCNTEN_Msk;
246}
247
259{
260 uint32_t u32Src;
261 const uint32_t au32Clk[] = {__HXT, __LXT, 0, 0, 0, __LIRC, 0, __HIRC};
262
263 if(timer == TIMER0)
264 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0SEL_Msk) >> CLK_CLKSEL1_TMR0SEL_Pos;
265 else if(timer == TIMER1)
266 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1SEL_Msk) >> CLK_CLKSEL1_TMR1SEL_Pos;
267 else if(timer == TIMER2)
268 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR2SEL_Msk) >> CLK_CLKSEL1_TMR2SEL_Pos;
269 else // Timer 3
270 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR3SEL_Msk) >> CLK_CLKSEL1_TMR3SEL_Pos;
271
272 if(u32Src == 2)
273 {
274 return (SystemCoreClock);
275 }
276
277 return (au32Clk[u32Src]);
278}
279 /* end of group TIMER_EXPORTED_FUNCTIONS */
281 /* end of group TIMER_Driver */
283 /* end of group Standard_Driver */
285
#define TIMER_EXTCTL_CAPFUNCS_Msk
Definition: M471M_R1_S.h:11336
#define TIMER_EXTCTL_CAPEDGE_Msk
Definition: M471M_R1_S.h:11330
#define TIMER_CTL_EXTCNTEN_Msk
Definition: M471M_R1_S.h:11291
#define TIMER_CTL_ACTSTS_Msk
Definition: M471M_R1_S.h:11294
#define TIMER_CTL_CNTEN_Msk
Definition: M471M_R1_S.h:11306
#define TIMER_EXTCTL_CAPEN_Msk
Definition: M471M_R1_S.h:11333
NuMicro peripheral access layer header file.
#define CLK_CLKSEL1_TMR1SEL_Msk
Definition: M471M_R1_S.h:1583
#define CLK_CLKSEL1_TMR0SEL_Msk
Definition: M471M_R1_S.h:1580
#define CLK_CLKSEL1_TMR2SEL_Pos
Definition: M471M_R1_S.h:1585
#define CLK_CLKSEL1_TMR1SEL_Pos
Definition: M471M_R1_S.h:1582
#define CLK_CLKSEL1_TMR3SEL_Msk
Definition: M471M_R1_S.h:1589
#define CLK_CLKSEL1_TMR3SEL_Pos
Definition: M471M_R1_S.h:1588
#define CLK_CLKSEL1_TMR0SEL_Pos
Definition: M471M_R1_S.h:1579
#define CLK_CLKSEL1_TMR2SEL_Msk
Definition: M471M_R1_S.h:1586
__I uint32_t CNT
Definition: M471M_R1_S.h:11255
#define CLK
Definition: M471M_R1_S.h:13818
#define TIMER1
Definition: M471M_R1_S.h:13839
__IO uint32_t CMP
Definition: M471M_R1_S.h:11253
__IO uint32_t CTL
Definition: M471M_R1_S.h:11252
__IO uint32_t EXTCTL
Definition: M471M_R1_S.h:11257
#define TIMER2
Definition: M471M_R1_S.h:13840
#define TIMER0
Definition: M471M_R1_S.h:13838
#define TIMER_ONESHOT_MODE
Definition: timer.h:31
#define TIMER_TIMEOUT_ERR
Definition: timer.h:45
void TIMER_DisableCapture(TIMER_T *timer)
Disable Timer Capture Function.
Definition: timer.c:209
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:243
uint32_t TIMER_GetModuleClock(TIMER_T *timer)
Get Timer Clock Frequency.
Definition: timer.c:258
void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge)
Enable Timer Counter Function.
Definition: timer.c:228
void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
Enable Timer Capture Function.
Definition: timer.c:193
void TIMER_Close(TIMER_T *timer)
Stop Timer Counting.
Definition: timer.c:74
int32_t TIMER_Delay(TIMER_T *timer, uint32_t u32Usec)
Create a specify Delay Time.
Definition: timer.c:92
#define __HIRC
#define __HXT
#define __LIRC
uint32_t SystemCoreClock
#define __LXT