1 /**************************************************************************//**
2 *
3 * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Change Logs:
8 * Date            Author           Notes
9 * 2020-2-7        YCHuang12        First version
10 *
11 ******************************************************************************/
12 
13 #include <rtconfig.h>
14 
15 #if (defined(BSP_USING_TIMER) && defined(RT_USING_HWTIMER))
16 
17 #include <rtdevice.h>
18 #include "NuMicro.h"
19 
20 /* Private define ---------------------------------------------------------------*/
21 #define NU_TIMER_DEVICE(timer) (nu_timer_t *)(timer)
22 
23 /* Private typedef --------------------------------------------------------------*/
24 typedef struct nu_timer
25 {
26     rt_hwtimer_t parent;
27     TIMER_T *timer_periph;
28     IRQn_Type IRQn;
29 } nu_timer_t;
30 
31 /* Private functions ------------------------------------------------------------*/
32 static void nu_timer_init(rt_hwtimer_t *timer, rt_uint32_t state);
33 static rt_err_t nu_timer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t opmode);
34 static void nu_timer_stop(rt_hwtimer_t *timer);
35 static rt_uint32_t nu_timer_count_get(rt_hwtimer_t *timer);
36 static rt_err_t nu_timer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args);
37 
38 /* Public functions -------------------------------------------------------------*/
39 
40 
41 /* Private variables ------------------------------------------------------------*/
42 #ifdef BSP_USING_TIMER0
43     static nu_timer_t nu_timer0;
44 #endif
45 
46 #ifdef BSP_USING_TIMER1
47     static nu_timer_t nu_timer1;
48 #endif
49 
50 #ifdef BSP_USING_TIMER2
51     static nu_timer_t nu_timer2;
52 #endif
53 
54 #ifdef BSP_USING_TIMER3
55     static nu_timer_t nu_timer3;
56 #endif
57 
58 static struct rt_hwtimer_info nu_timer_info =
59 {
60     12000000, /* maximum count frequency */
61     46875,        /* minimum count frequency */
62     0xFFFFFF,          /* the maximum counter value */
63     HWTIMER_CNTMODE_UP,/* Increment or Decreasing count mode */
64 };
65 
66 static struct rt_hwtimer_ops nu_timer_ops =
67 {
68     nu_timer_init,
69     nu_timer_start,
70     nu_timer_stop,
71     nu_timer_count_get,
72     nu_timer_control
73 };
74 
75 /* Functions define ------------------------------------------------------------*/
nu_timer_init(rt_hwtimer_t * timer,rt_uint32_t state)76 static void nu_timer_init(rt_hwtimer_t *timer, rt_uint32_t state)
77 {
78     RT_ASSERT(timer != RT_NULL);
79 
80     nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
81     RT_ASSERT(nu_timer != RT_NULL);
82     RT_ASSERT(nu_timer->timer_periph != RT_NULL);
83 
84     if (1 == state)
85     {
86         uint32_t timer_clk;
87         struct rt_hwtimer_info *info = &nu_timer_info;
88 
89         timer_clk = TIMER_GetModuleClock(nu_timer->timer_periph);
90         info->maxfreq = timer_clk;
91         info->minfreq = timer_clk / 256;
92         TIMER_Open(nu_timer->timer_periph, TIMER_ONESHOT_MODE, 1);
93         TIMER_EnableInt(nu_timer->timer_periph);
94         NVIC_EnableIRQ(nu_timer->IRQn);
95     }
96     else
97     {
98         NVIC_DisableIRQ(nu_timer->IRQn);
99         TIMER_DisableInt(nu_timer->timer_periph);
100         TIMER_Close(nu_timer->timer_periph);
101     }
102 }
103 
nu_timer_start(rt_hwtimer_t * timer,rt_uint32_t cnt,rt_hwtimer_mode_t opmode)104 static rt_err_t nu_timer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t opmode)
105 {
106     rt_err_t err = RT_EOK;
107     RT_ASSERT(timer != RT_NULL);
108 
109     nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
110     RT_ASSERT(nu_timer != RT_NULL);
111     RT_ASSERT(nu_timer->timer_periph != RT_NULL);
112 
113     if (cnt > 1 && cnt <= 0xFFFFFF)
114     {
115         TIMER_SET_CMP_VALUE(nu_timer->timer_periph, cnt);
116     }
117     else
118     {
119         rt_kprintf("nu_timer_start set compared value failed\n");
120         err = -RT_ERROR;
121     }
122 
123     if (HWTIMER_MODE_PERIOD == opmode)
124     {
125         TIMER_SET_OPMODE(nu_timer->timer_periph, TIMER_PERIODIC_MODE);
126     }
127     else if (HWTIMER_MODE_ONESHOT == opmode)
128     {
129         TIMER_SET_OPMODE(nu_timer->timer_periph, TIMER_ONESHOT_MODE);
130     }
131     else
132     {
133         rt_kprintf("nu_timer_start set operation mode failed\n");
134         err = -RT_ERROR;
135     }
136 
137     TIMER_Start(nu_timer->timer_periph);
138 
139     return err;
140 }
141 
nu_timer_stop(rt_hwtimer_t * timer)142 static void nu_timer_stop(rt_hwtimer_t *timer)
143 {
144     RT_ASSERT(timer != RT_NULL);
145 
146     nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
147     RT_ASSERT(nu_timer != RT_NULL);
148     RT_ASSERT(nu_timer->timer_periph != RT_NULL);
149 
150     TIMER_Stop(nu_timer->timer_periph);
151 }
152 
nu_timer_count_get(rt_hwtimer_t * timer)153 static rt_uint32_t nu_timer_count_get(rt_hwtimer_t *timer)
154 {
155     RT_ASSERT(timer != RT_NULL);
156 
157     nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
158     RT_ASSERT(nu_timer != RT_NULL);
159     RT_ASSERT(nu_timer->timer_periph != RT_NULL);
160 
161     return TIMER_GetCounter(nu_timer->timer_periph);
162 }
163 
nu_timer_control(rt_hwtimer_t * timer,rt_uint32_t cmd,void * args)164 static rt_err_t nu_timer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args)
165 {
166     rt_err_t ret = RT_EOK;
167 
168     RT_ASSERT(timer != RT_NULL);
169 
170     nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
171     RT_ASSERT(nu_timer != RT_NULL);
172     RT_ASSERT(nu_timer->timer_periph != RT_NULL);
173 
174     switch (cmd)
175     {
176     case HWTIMER_CTRL_FREQ_SET:
177     {
178         uint32_t clk;
179         uint32_t pre;
180 
181         clk = TIMER_GetModuleClock(nu_timer->timer_periph);
182         pre = clk / *((uint32_t *)args) - 1;
183         TIMER_SET_PRESCALE_VALUE(nu_timer->timer_periph, pre);
184         *((uint32_t *)args) = clk / (pre + 1) ;
185     }
186     break;
187 
188     case HWTIMER_CTRL_STOP:
189         TIMER_Stop(nu_timer->timer_periph);
190         break;
191 
192     default:
193         ret = -RT_EINVAL;
194         break;
195     }
196 
197     return ret;
198 }
199 
rt_hw_timer_init(void)200 int rt_hw_timer_init(void)
201 {
202     rt_err_t ret = RT_EOK;
203 
204 #ifdef BSP_USING_TIMER0
205     nu_timer0.timer_periph = TIMER0;
206     nu_timer0.parent.info = &nu_timer_info;
207     nu_timer0.parent.ops = &nu_timer_ops;
208     nu_timer0.IRQn = TMR0_IRQn;
209     ret = rt_device_hwtimer_register(&nu_timer0.parent, "timer0", &nu_timer0);
210     if (ret != RT_EOK)
211     {
212         rt_kprintf("timer0 register failed\n");
213     }
214     SYS_ResetModule(TMR0_RST);
215     CLK_EnableModuleClock(TMR0_MODULE);
216 #endif
217 
218 #ifdef BSP_USING_TIMER1
219     nu_timer1.timer_periph = TIMER1;
220     nu_timer1.parent.info = &nu_timer_info;
221     nu_timer1.parent.ops = &nu_timer_ops;
222     nu_timer1.IRQn = TMR1_IRQn;
223     ret = rt_device_hwtimer_register(&nu_timer1.parent, "timer1", &nu_timer1);
224     if (ret != RT_EOK)
225     {
226         rt_kprintf("timer1 register failed\n");
227     }
228     SYS_ResetModule(TMR1_RST);
229     CLK_EnableModuleClock(TMR1_MODULE);
230 #endif
231 
232 #ifdef BSP_USING_TIMER2
233     nu_timer2.timer_periph = TIMER2;
234     nu_timer2.parent.info = &nu_timer_info;
235     nu_timer2.parent.ops = &nu_timer_ops;
236     nu_timer2.IRQn = TMR2_IRQn;
237     ret = rt_device_hwtimer_register(&nu_timer2.parent, "timer2", &nu_timer2);
238     if (ret != RT_EOK)
239     {
240         rt_kprintf("timer2 register failed\n");
241     }
242     SYS_ResetModule(TMR2_RST);
243     CLK_EnableModuleClock(TMR2_MODULE);
244 #endif
245 
246 #ifdef BSP_USING_TIMER3
247     nu_timer3.timer_periph = TIMER3;
248     nu_timer3.parent.info = &nu_timer_info;
249     nu_timer3.parent.ops = &nu_timer_ops;
250     nu_timer3.IRQn = TMR3_IRQn;
251     ret = rt_device_hwtimer_register(&nu_timer3.parent, "timer3", &nu_timer3);
252     if (ret != RT_EOK)
253     {
254         rt_kprintf("timer3 register failed\n");
255     }
256     SYS_ResetModule(TMR3_RST);
257     CLK_EnableModuleClock(TMR3_MODULE);
258 #endif
259 
260     return ret;
261 }
262 
263 INIT_BOARD_EXPORT(rt_hw_timer_init);
264 
265 #ifdef BSP_USING_TIMER0
TMR0_IRQHandler(void)266 void TMR0_IRQHandler(void)
267 {
268     rt_interrupt_enter();
269 
270     if (TIMER_GetIntFlag(TIMER0))
271     {
272         TIMER_ClearIntFlag(TIMER0);
273         rt_device_hwtimer_isr(&nu_timer0.parent);
274     }
275 
276     rt_interrupt_leave();
277 }
278 #endif
279 
280 #ifdef BSP_USING_TIMER1
TMR1_IRQHandler(void)281 void TMR1_IRQHandler(void)
282 {
283     rt_interrupt_enter();
284 
285     if (TIMER_GetIntFlag(TIMER1))
286     {
287         TIMER_ClearIntFlag(TIMER1);
288         rt_device_hwtimer_isr(&nu_timer1.parent);
289     }
290 
291     rt_interrupt_leave();
292 }
293 #endif
294 
295 #ifdef BSP_USING_TIMER2
TMR2_IRQHandler(void)296 void TMR2_IRQHandler(void)
297 {
298     rt_interrupt_enter();
299 
300     if (TIMER_GetIntFlag(TIMER2))
301     {
302         TIMER_ClearIntFlag(TIMER2);
303         rt_device_hwtimer_isr(&nu_timer2.parent);
304     }
305 
306     rt_interrupt_leave();
307 }
308 #endif
309 
310 #ifdef BSP_USING_TIMER3
TMR3_IRQHandler(void)311 void TMR3_IRQHandler(void)
312 {
313     rt_interrupt_enter();
314 
315     if (TIMER_GetIntFlag(TIMER3))
316     {
317         TIMER_ClearIntFlag(TIMER3);
318         rt_device_hwtimer_isr(&nu_timer3.parent);
319     }
320 
321     rt_interrupt_leave();
322 }
323 #endif
324 
325 #endif //#if (defined(BSP_USING_TIMER) && defined(RT_USING_HWTIMER))
326