M4521_BSP V3.02.000
The Board Support Package for M4521
timer.c
Go to the documentation of this file.
1/**************************************************************************/
12#include "M4521.h"
13
14
28
47uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq)
48{
49 uint32_t u32Clk = TIMER_GetModuleClock(timer);
50 uint32_t u32Cmpr = 0, u32Prescale = 0;
51
52 // Fastest possible timer working freq is (u32Clk / 2). While cmpr = 2, pre-scale = 0.
53 if(u32Freq > (u32Clk / 2))
54 {
55 u32Cmpr = 2;
56 }
57 else
58 {
59 u32Cmpr = u32Clk / u32Freq;
60 u32Prescale = (u32Cmpr >> 24); /* for 24 bits CMPDAT */
61 if (u32Prescale > 0)
62 u32Cmpr = u32Cmpr / (u32Prescale + 1);
63 }
64
65 timer->CTL = u32Mode | u32Prescale;
66 timer->CMP = u32Cmpr;
67
68 return(u32Clk / (u32Cmpr * (u32Prescale + 1)));
69}
70
80void TIMER_Close(TIMER_T *timer)
81{
82 timer->CTL = 0;
83 timer->EXTCTL = 0;
84}
85
100void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec)
101{
102 uint32_t u32Clk = TIMER_GetModuleClock(timer);
103 uint32_t u32Prescale = 0, delay = (SystemCoreClock / u32Clk) + 1;
104 uint32_t u32Cmpr, u32NsecPerTick;
105 uint32_t u32Timeout;
106
107 // Clear current timer configuration/
108 timer->CTL = 0;
109 timer->EXTCTL = 0;
110
111 if(u32Clk <= 1000000) // min delay is 1000 us if timer clock source is <= 1 MHz
112 {
113 if(u32Usec < 1000)
114 u32Usec = 1000;
115 if(u32Usec > 1000000)
116 u32Usec = 1000000;
117 }
118 else
119 {
120 if(u32Usec < 100)
121 u32Usec = 100;
122 if(u32Usec > 1000000)
123 u32Usec = 1000000;
124 }
125
126 if(u32Clk <= 1000000)
127 {
128 u32Prescale = 0;
129 u32NsecPerTick = 1000000000 / u32Clk;
130 u32Cmpr = (u32Usec * 1000) / u32NsecPerTick;
131 }
132 else
133 {
134 u32Cmpr = u32Usec * (u32Clk / 1000000);
135 u32Prescale = (u32Cmpr >> 24); /* for 24 bits CMPDAT */
136 if (u32Prescale > 0)
137 u32Cmpr = u32Cmpr / (u32Prescale + 1);
138 }
139
140 timer->CMP = u32Cmpr;
141 timer->CTL = TIMER_CTL_CNTEN_Msk | TIMER_ONESHOT_MODE | u32Prescale;
142
143 // When system clock is faster than timer clock, it is possible timer active bit cannot set in time while we check it.
144 // And the while loop below return immediately, so put a tiny delay here allowing timer start counting and raise active flag.
145 for(; delay > 0; delay--)
146 {
147 __NOP();
148 }
149
151 u32Timeout = (SystemCoreClock / 1000000) * u32Usec * 2;
152 while ((timer->CTL & TIMER_CTL_ACTSTS_Msk) && (u32Timeout-- > 0));
153
154 if (timer->CTL & TIMER_CTL_ACTSTS_Msk)
156}
157
176void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
177{
178
180 u32CapMode | u32Edge | TIMER_EXTCTL_CAPEN_Msk;
181}
182
193{
194 timer->EXTCTL &= ~TIMER_EXTCTL_CAPEN_Msk;
195}
196
211void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge)
212{
213 timer->EXTCTL = (timer->EXTCTL & ~TIMER_EXTCTL_CNTPHASE_Msk) | u32Edge;
214 timer->CTL |= TIMER_CTL_EXTCNTEN_Msk;
215}
216
227{
228 timer->CTL &= ~TIMER_CTL_EXTCNTEN_Msk;
229}
230
242{
243 uint32_t u32Src;
244 const uint32_t au32Clk[] = {__HXT, __LXT, 0, 0, 0, __LIRC, 0, __HIRC};
245
246 if(timer == TIMER0)
247 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0SEL_Msk) >> CLK_CLKSEL1_TMR0SEL_Pos;
248 else if(timer == TIMER1)
249 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1SEL_Msk) >> CLK_CLKSEL1_TMR1SEL_Pos;
250 else if(timer == TIMER2)
251 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR2SEL_Msk) >> CLK_CLKSEL1_TMR2SEL_Pos;
252 else // Timer 3
253 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR3SEL_Msk) >> CLK_CLKSEL1_TMR3SEL_Pos;
254
255 if(u32Src == 2)
256 {
257 return (SystemCoreClock);
258 }
259
260 return (au32Clk[u32Src]);
261}
262 /* end of group TIMER_EXPORTED_FUNCTIONS */
264 /* end of group TIMER_Driver */
266 /* end of group Standard_Driver */
268
269/*** (C) COPYRIGHT 2022 Nuvoton Technology Corp. ***/
#define TIMER_EXTCTL_CAPFUNCS_Msk
Definition: M4521.h:11340
#define TIMER_EXTCTL_CAPEDGE_Msk
Definition: M4521.h:11334
#define TIMER_CTL_EXTCNTEN_Msk
Definition: M4521.h:11295
#define TIMER_CTL_ACTSTS_Msk
Definition: M4521.h:11298
#define TIMER_CTL_CNTEN_Msk
Definition: M4521.h:11310
#define TIMER_EXTCTL_CAPEN_Msk
Definition: M4521.h:11337
#define CLK_CLKSEL1_TMR1SEL_Msk
Definition: M4521.h:1587
#define CLK_CLKSEL1_TMR0SEL_Msk
Definition: M4521.h:1584
#define CLK_CLKSEL1_TMR2SEL_Pos
Definition: M4521.h:1589
#define CLK_CLKSEL1_TMR1SEL_Pos
Definition: M4521.h:1586
#define CLK_CLKSEL1_TMR3SEL_Msk
Definition: M4521.h:1593
#define CLK_CLKSEL1_TMR3SEL_Pos
Definition: M4521.h:1592
#define CLK_CLKSEL1_TMR0SEL_Pos
Definition: M4521.h:1583
#define CLK_CLKSEL1_TMR2SEL_Msk
Definition: M4521.h:1590
#define CLK
Definition: M4521.h:13822
#define TIMER1
Definition: M4521.h:13843
__IO uint32_t CMP
Definition: M4521.h:11257
__IO uint32_t CTL
Definition: M4521.h:11256
__IO uint32_t EXTCTL
Definition: M4521.h:11261
#define TIMER2
Definition: M4521.h:13844
#define TIMER0
Definition: M4521.h:13842
#define TIMER_ONESHOT_MODE
Definition: timer.h:35
void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec)
Create a specify Delay Time.
Definition: timer.c:100
void TIMER_DisableCapture(TIMER_T *timer)
Disable Timer Capture Function.
Definition: timer.c:192
uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq)
Open Timer with Operate Mode and Frequency.
Definition: timer.c:47
void TIMER_DisableEventCounter(TIMER_T *timer)
Disable Timer Counter Function.
Definition: timer.c:226
uint32_t TIMER_GetModuleClock(TIMER_T *timer)
Get Timer Clock Frequency.
Definition: timer.c:241
int32_t g_TIMER_i32ErrCode
Definition: timer.c:27
void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge)
Enable Timer Counter Function.
Definition: timer.c:211
void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
Enable Timer Capture Function.
Definition: timer.c:176
void TIMER_Close(TIMER_T *timer)
Stop Timer Counting.
Definition: timer.c:80
#define __HIRC
Definition: system_M4521.h:37
#define __HXT
Definition: system_M4521.h:35
#define __LIRC
Definition: system_M4521.h:38
uint32_t SystemCoreClock
Definition: system_M4521.c:24
#define __LXT
Definition: system_M4521.h:36