MINI58_BSP V3.01.005
The Board Support Package for Mini58 Series MCU
timer.c
Go to the documentation of this file.
1/**************************************************************************/
12#include "Mini58Series.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
78void TIMER_Close(TIMER_T *timer)
79{
80 timer->CTL = 0;
81 timer->EXTCTL = 0;
82
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 float fCmpr;
98
99 // Clear current timer configuration
100 timer->CTL = 0;
101 timer->EXTCTL = 0;
102
103 if(u32Clk == 10000) // min delay is 100us if timer clock source is LIRC 10k
104 {
105 u32Usec = ((u32Usec + 99) / 100) * 100;
106 }
107 else // 10 usec every step
108 {
109 u32Usec = ((u32Usec + 9) / 10) * 10;
110 }
111
112 if(u32Clk >= 0x2000000)
113 {
114 u32Prescale = 3; // real prescaler value is 4
115 u32Clk >>= 2;
116 }
117 else if(u32Clk >= 0x1000000)
118 {
119 u32Prescale = 1; // real prescaler value is 2
120 u32Clk >>= 1;
121 }
122
123 // u32Usec * u32Clk might overflow if using uint32_t
124 fCmpr = ((float)u32Usec * (float)u32Clk) / 1000000.0;
125
126 timer->CMP = (uint32_t)fCmpr;
127 timer->CTL = TIMER_CTL_CNTEN_Msk | u32Prescale; // 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_ACTSTS_Msk) && (delay-- > 0));
139}
140
156void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
157{
158
159 timer->EXTCTL = (timer->EXTCTL & ~(TIMER_EXTCTL_CAPSEL_Msk |
162 u32CapMode | u32Edge | TIMER_EXTCTL_CAPEN_Msk;
163}
164
171{
172 timer->EXTCTL &= ~TIMER_EXTCTL_CAPEN_Msk;
173
174}
175
185void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge)
186{
187 timer->EXTCTL = (timer->EXTCTL & ~TIMER_EXTCTL_CNTPHASE_Msk) | u32Edge;
188 timer->CTL |= TIMER_CTL_EXTCNTEN_Msk;
189}
190
197{
198 timer->CTL &= ~TIMER_CTL_EXTCNTEN_Msk;
199}
200
208{
209 uint32_t u32Src;
210 if(timer == TIMER0)
211 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0SEL_Msk) >> CLK_CLKSEL1_TMR0SEL_Pos;
212 else
213 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1SEL_Msk) >> CLK_CLKSEL1_TMR1SEL_Pos;
214
215 if(u32Src == 0)
216 return((CLK->PWRCTL & CLK_PWRCTL_XTLEN_Msk) == 1 ? __XTAL12M : __XTAL32K);
217 else if(u32Src == 1)
218 return __IRC10K;
219 else if(u32Src == 2)
220 return SystemCoreClock;
221 else
222 return __HSI;
223
224}
225 /* end of group Mini58_TIMER_EXPORTED_FUNCTIONS */
227 /* end of group Mini58_TIMER_Driver */
229 /* end of group Mini58_Device_Driver */
231
232/*** (C) COPYRIGHT 2022 Nuvoton Technology Corp. ***/
Mini58 series peripheral access layer header file. This file contains all the peripheral register's d...
#define TIMER_EXTCTL_CAPSEL_Msk
#define TIMER_EXTCTL_CAPFUNCS_Msk
#define TIMER_EXTCTL_CAPEDGE_Msk
#define TIMER_CTL_EXTCNTEN_Msk
#define TIMER_CTL_ACTSTS_Msk
#define TIMER_CTL_CNTEN_Msk
#define TIMER_EXTCTL_CAPEN_Msk
#define CLK_CLKSEL1_TMR1SEL_Msk
#define CLK_CLKSEL1_TMR0SEL_Msk
#define CLK_CLKSEL1_TMR1SEL_Pos
#define CLK_PWRCTL_XTLEN_Msk
#define CLK_CLKSEL1_TMR0SEL_Pos
#define CLK
Pointer to CLK register structure.
#define TIMER0
Pointer to Timer 0 register structure.
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_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:78
__IO uint32_t CMP
__IO uint32_t CTL
__IO uint32_t EXTCTL
#define __IRC10K
uint32_t __HSI
#define __XTAL32K
#define __XTAL12M
uint32_t SystemCoreClock