| MINI55_BSP V3.02.004 The Board Support Package for Mini55 Series MCU

timer.c
Go to the documentation of this file.
1/**************************************************************************/
12#include "Mini55Series.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
67 timer->CTL = u32Mode | u32Prescale;
68 timer->CMP = u32Cmpr;
69
70 return(u32Clk / (u32Cmpr * (u32Prescale + 1)));
71}
72
78 void TIMER_Close(TIMER_T *timer)
79{
80 timer->CTL = 0;
81 timer->EXTCTL = 0;
82
83}
84
93int32_t 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 uint32_t u32Cntr, i = 0UL;
99
100 // Clear current timer configuration
101 timer->CTL = 0;
102 timer->EXTCTL = 0;
103
104 if(u32Clk == 10000) // min delay is 100us if timer clock source is LIRC 10k
105 {
106 u32Usec = ((u32Usec + 99) / 100) * 100;
107 }
108 else // 10 usec every step
109 {
110 u32Usec = ((u32Usec + 9) / 10) * 10;
111 }
112
113 if(u32Clk >= 0x2000000)
114 {
115 u32Prescale = 3; // real prescaler value is 4
116 u32Clk >>= 2;
117 }
118 else if(u32Clk >= 0x1000000)
119 {
120 u32Prescale = 1; // real prescaler value is 2
121 u32Clk >>= 1;
122 }
123
124 // u32Usec * u32Clk might overflow if using uint32_t
125 u64Cmpr = ((long long)u32Usec * (long long)u32Clk) / (long long)1000000;
126
127 timer->CMP = (uint32_t)u64Cmpr;
128 timer->CTL = TIMER_CTL_CNTEN_Msk | u32Prescale; // one shot mode
129
130 // When system clock is faster than timer clock, it is possible timer active bit cannot set in time while we check it.
131 // And the while loop below return immediately, so put a tiny delay here allowing timer start counting and raise active flag.
132 for(; delay > 0; delay--)
133 {
134 __NOP();
135 }
136
137 /* Add a bail out counter here in case timer clock source is disabled accidentally.
138 Prescale counter reset every ECLK * (prescale value + 1).
139 The u32Delay here is to make sure timer counter value changed when prescale counter reset */
140 delay = (SystemCoreClock / TIMER_GetModuleClock(timer)) * (u32Prescale + 1);
141 u32Cntr = timer->CNT;
142 while(timer->CTL & TIMER_CTL_ACTSTS_Msk)
143 {
144 /* Bailed out if timer stop counting e.g. Some interrupt handler close timer clock source. */
145 if(u32Cntr == timer->CNT)
146 {
147 if(i++ > delay)
148 {
149 return -1;
150 }
151 }
152 else
153 {
154 i = 0;
155 u32Cntr = timer->CNT;
156 }
157 }
158 return 0;
159
160}
161
177 void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
178{
179
180 timer->EXTCTL = (timer->EXTCTL & ~(TIMER_EXTCTL_CAPMODE_Msk |
181 TIMER_EXTCTL_CAPFUNCS_Msk |
182 TIMER_EXTCTL_CAPEDGE_Msk)) |
183 u32CapMode | u32Edge | TIMER_EXTCTL_CAPEN_Msk;
184}
185
191 void TIMER_DisableCapture(TIMER_T *timer)
192{
193 timer->EXTCTL &= ~TIMER_EXTCTL_CAPEN_Msk;
194
195}
196
206 void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge)
207{
208 timer->EXTCTL = (timer->EXTCTL & ~TIMER_EXTCTL_CNTPHASE_Msk) | u32Edge;
209 timer->CTL |= TIMER_CTL_EXTCNTEN_Msk;
210}
211
217 void TIMER_DisableEventCounter(TIMER_T *timer)
218{
219 timer->CTL &= ~TIMER_CTL_EXTCNTEN_Msk;
220}
221
228uint32_t TIMER_GetModuleClock(TIMER_T *timer)
229{
230 uint32_t u32Src;
231 if(timer == TIMER0)
232 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0SEL_Msk) >> CLK_CLKSEL1_TMR0SEL_Pos;
233 else
234 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1SEL_Msk) >> CLK_CLKSEL1_TMR1SEL_Pos;
235
236 if(u32Src == 0)
237 return((CLK->PWRCTL & CLK_PWRCTL_XTLEN_Msk) == 1 ? __XTAL12M : __XTAL32K);
238 else if(u32Src == 1)
239 return __IRC10K;
240 else if(u32Src == 2)
241 return SystemCoreClock;
242 else
243 return __HSI;
244
245}
246 /* end of group MINI55_TIMER_EXPORTED_FUNCTIONS */
248 /* end of group MINI55_TIMER_Driver */
250 /* end of group MINI55_Device_Driver */
252
253/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/
Mini55Series.h
Mini55 series peripheral access layer header file. This file contains all the peripheral register's d...
TIMER_EXTCTL_CAPFUNCS_Msk
#define TIMER_EXTCTL_CAPFUNCS_Msk
Definition: Mini55Series.h:6115
TIMER_EXTCTL_CAPMODE_Msk
#define TIMER_EXTCTL_CAPMODE_Msk
Definition: Mini55Series.h:6127
TIMER_EXTCTL_CAPEDGE_Msk
#define TIMER_EXTCTL_CAPEDGE_Msk
Definition: Mini55Series.h:6109
TIMER_CTL_EXTCNTEN_Msk
#define TIMER_CTL_EXTCNTEN_Msk
Definition: Mini55Series.h:6070
TIMER_CTL_ACTSTS_Msk
#define TIMER_CTL_ACTSTS_Msk
Definition: Mini55Series.h:6073
TIMER_CTL_CNTEN_Msk
#define TIMER_CTL_CNTEN_Msk
Definition: Mini55Series.h:6085
TIMER_EXTCTL_CAPEN_Msk
#define TIMER_EXTCTL_CAPEN_Msk
Definition: Mini55Series.h:6112
TIMER_DisableCapture
void TIMER_DisableCapture(TIMER_T *timer)
This API is used to disable the Timer capture function.
Definition: timer.c:191
TIMER_Open
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
TIMER_DisableEventCounter
void TIMER_DisableEventCounter(TIMER_T *timer)
This API is used to disable the Timer event counter function.
Definition: timer.c:217
TIMER_GetModuleClock
uint32_t TIMER_GetModuleClock(TIMER_T *timer)
This API is used to get the clock frequency of Timer.
Definition: timer.c:228
TIMER_EnableEventCounter
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:206
TIMER_EnableCapture
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:177
TIMER_Close
void TIMER_Close(TIMER_T *timer)
This API stops Timer counting and disable the Timer interrupt function.
Definition: timer.c:78
TIMER_Delay
int32_t 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
CLK_CLKSEL1_TMR1SEL_Msk
#define CLK_CLKSEL1_TMR1SEL_Msk
Definition: Mini55Series.h:1232
CLK_CLKSEL1_TMR0SEL_Msk
#define CLK_CLKSEL1_TMR0SEL_Msk
Definition: Mini55Series.h:1229
CLK_CLKSEL1_TMR1SEL_Pos
#define CLK_CLKSEL1_TMR1SEL_Pos
Definition: Mini55Series.h:1231
CLK_PWRCTL_XTLEN_Msk
#define CLK_PWRCTL_XTLEN_Msk
Definition: Mini55Series.h:1130
CLK_CLKSEL1_TMR0SEL_Pos
#define CLK_CLKSEL1_TMR0SEL_Pos
Definition: Mini55Series.h:1228
CLK
#define CLK
Pointer to CLK register structure.
Definition: Mini55Series.h:7010
TIMER0
#define TIMER0
Pointer to Timer 0 register structure.
Definition: Mini55Series.h:6995
TIMER_T::CMP
__IO uint32_t CMP
Definition: Mini55Series.h:5868
TIMER_T::CTL
__IO uint32_t CTL
Definition: Mini55Series.h:5851
TIMER_T::EXTCTL
__IO uint32_t EXTCTL
Definition: Mini55Series.h:5955
TIMER_T::CNT
__I uint32_t CNT
Definition: Mini55Series.h:5900
TIMER_T
Definition: Mini55Series.h:5779
__IRC10K
#define __IRC10K
Definition: system_Mini55Series.h:35
__HSI
uint32_t __HSI
Definition: system_Mini55Series.c:21
__XTAL32K
#define __XTAL32K
Definition: system_Mini55Series.h:30
__XTAL12M
#define __XTAL12M
Definition: system_Mini55Series.h:29
SystemCoreClock
uint32_t SystemCoreClock
Definition: system_Mini55Series.c:22