1 /*
2  * Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-07-01     lik          first version
9  */
10 
11 #include "drv_hwtimer.h"
12 
13 #ifdef RT_USING_HWTIMER
14 #ifdef BSP_USING_TIM
15 
16 //#define DRV_DEBUG
17 #define LOG_TAG "drv.hwtimer"
18 #include <drv_log.h>
19 
20 #if !defined(BSP_USING_TIM0) && !defined(BSP_USING_TIM1) && !defined(BSP_USING_TIM2) && !defined(BSP_USING_TIM3)     \
21 && !defined(BSP_USING_TIM4) && !defined(BSP_USING_BTIM0) && !defined(BSP_USING_BTIM1) && !defined(BSP_USING_BTIM2)   \
22 && !defined(BSP_USING_BTIM3) && !defined(BSP_USING_BTIM4) && !defined(BSP_USING_BTIM5) && !defined(BSP_USING_BTIM6)  \
23 && !defined(BSP_USING_BTIM7) && !defined(BSP_USING_BTIM8) && !defined(BSP_USING_BTIM9) && !defined(BSP_USING_BTIM10) \
24 && !defined(BSP_USING_BTIM11)
25 #error "Please define at least one BSP_USING_TIMx or BSP_USING_BTIMx"
26 /* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
27 #endif
28 
29 #ifndef TIM_DEV_INFO_CONFIG
30 #define TIM_DEV_INFO_CONFIG            \
31     {                                  \
32         .maxfreq = 1000000,            \
33         .minfreq = 1000000,            \
34         .maxcnt = 0xFFFFFFFF,          \
35         .cntmode = HWTIMER_CNTMODE_DW, \
36     }
37 #endif /* TIM_DEV_INFO_CONFIG */
38 
39 #ifdef BSP_USING_TIM0
40 #ifndef TIM0_CFG
41 #define TIM0_CFG          \
42     {                     \
43         .name = "timer0", \
44         .TIMRx = TIMR0,   \
45     }
46 #endif /* TIM0_CFG */
47 #endif /* BSP_USING_TIM0 */
48 
49 #ifdef BSP_USING_TIM1
50 #ifndef TIM1_CFG
51 #define TIM1_CFG          \
52     {                     \
53         .name = "timer1", \
54         .TIMRx = TIMR1,   \
55     }
56 #endif /* TIM1_CFG */
57 #endif /* BSP_USING_TIM1 */
58 
59 #ifdef BSP_USING_TIM2
60 #ifndef TIM2_CFG
61 #define TIM2_CFG          \
62     {                     \
63         .name = "timer2", \
64         .TIMRx = TIMR2,   \
65     }
66 #endif /* TIM2_CFG */
67 #endif /* BSP_USING_TIM2 */
68 
69 #ifdef BSP_USING_TIM3
70 #ifndef TIM3_CFG
71 #define TIM3_CFG          \
72     {                     \
73         .name = "timer3", \
74         .TIMRx = TIMR3,   \
75     }
76 #endif /* TIM3_CFG */
77 #endif /* BSP_USING_TIM3 */
78 
79 #ifdef BSP_USING_TIM4
80 #ifndef TIM4_CFG
81 #define TIM4_CFG          \
82     {                     \
83         .name = "timer4", \
84         .TIMRx = TIMR4,   \
85     }
86 #endif /* TIM4_CFG */
87 #endif /* BSP_USING_TIM4 */
88 
89 #ifdef BSP_USING_BTIM0
90 #ifndef BTIM0_CFG
91 #define BTIM0_CFG          \
92     {                      \
93         .name = "btimer0", \
94         .TIMRx = BTIMR0,   \
95     }
96 #endif /* BTIM0_CFG */
97 #endif /* BSP_USING_BTIM0 */
98 
99 #ifdef BSP_USING_BTIM1
100 #ifndef BTIM1_CFG
101 #define BTIM1_CFG          \
102     {                      \
103         .name = "btimer1", \
104         .TIMRx = BTIMR1,   \
105     }
106 #endif /* BTIM1_CFG */
107 #endif /* BSP_USING_BTIM1 */
108 
109 #ifdef BSP_USING_BTIM2
110 #ifndef BTIM2_CFG
111 #define BTIM2_CFG          \
112     {                      \
113         .name = "btimer2", \
114         .TIMRx = BTIMR2,   \
115     }
116 #endif /* BTIM2_CFG */
117 #endif /* BSP_USING_BTIM2 */
118 
119 #ifdef BSP_USING_BTIM3
120 #ifndef BTIM3_CFG
121 #define BTIM3_CFG          \
122     {                      \
123         .name = "btimer3", \
124         .TIMRx = BTIMR3,   \
125     }
126 #endif /* BTIM3_CFG */
127 #endif /* BSP_USING_BTIM3 */
128 
129 #ifdef BSP_USING_BTIM4
130 #ifndef BTIM4_CFG
131 #define BTIM4_CFG          \
132     {                      \
133         .name = "btimer4", \
134         .TIMRx = BTIMR4,   \
135     }
136 #endif /* BTIM4_CFG */
137 #endif /* BSP_USING_BTIM4 */
138 
139 #ifdef BSP_USING_BTIM5
140 #ifndef BTIM5_CFG
141 #define BTIM5_CFG          \
142     {                      \
143         .name = "btimer5", \
144         .TIMRx = BTIMR5,   \
145     }
146 #endif /* BTIM5_CFG */
147 #endif /* BSP_USING_BTIM5 */
148 
149 #ifdef BSP_USING_BTIM6
150 #ifndef BTIM6_CFG
151 #define BTIM6_CFG          \
152     {                      \
153         .name = "btimer6", \
154         .TIMRx = BTIMR6,   \
155     }
156 #endif /* BTIM6_CFG */
157 #endif /* BSP_USING_BTIM6 */
158 
159 #ifdef BSP_USING_BTIM7
160 #ifndef BTIM7_CFG
161 #define BTIM7_CFG          \
162     {                      \
163         .name = "btimer7", \
164         .TIMRx = BTIMR7,   \
165     }
166 #endif /* BTIM7_CFG */
167 #endif /* BSP_USING_BTIM7 */
168 
169 #ifdef BSP_USING_BTIM8
170 #ifndef BTIM8_CFG
171 #define BTIM8_CFG          \
172     {                      \
173         .name = "btimer8", \
174         .TIMRx = BTIMR8,   \
175     }
176 #endif /* BTIM8_CFG */
177 #endif /* BSP_USING_BTIM8 */
178 
179 #ifdef BSP_USING_BTIM9
180 #ifndef BTIM9_CFG
181 #define BTIM9_CFG          \
182     {                      \
183         .name = "btimer9", \
184         .TIMRx = BTIMR9,   \
185     }
186 #endif /* BTIM9_CFG */
187 #endif /* BSP_USING_BTIM9 */
188 
189 #ifdef BSP_USING_BTIM10
190 #ifndef BTIM10_CFG
191 #define BTIM10_CFG          \
192     {                       \
193         .name = "btimer10", \
194         .TIMRx = BTIMR10,   \
195     }
196 #endif /* BTIM10_CFG */
197 #endif /* BSP_USING_BTIM10 */
198 
199 #ifdef BSP_USING_BTIM11
200 #ifndef BTIM11_CFG
201 #define BTIM11_CFG          \
202     {                       \
203         .name = "btimer11", \
204         .TIMRx = BTIMR11,   \
205     }
206 #endif /* BTIM11_CFG */
207 #endif /* BSP_USING_BTIM11 */
208 
209 struct swm_hwtimer_cfg
210 {
211     char *name;
212     TIMR_TypeDef *TIMRx;
213 };
214 
215 struct swm_hwtimer_device
216 {
217     struct swm_hwtimer_cfg *hwtimer_cfg;
218     rt_hwtimer_t time_device;
219 };
220 
221 enum
222 {
223 #ifdef BSP_USING_TIM0
224     TIM0_INDEX,
225 #endif
226 #ifdef BSP_USING_TIM1
227     TIM1_INDEX,
228 #endif
229 #ifdef BSP_USING_TIM2
230     TIM2_INDEX,
231 #endif
232 #ifdef BSP_USING_TIM3
233     TIM3_INDEX,
234 #endif
235 #ifdef BSP_USING_TIM4
236     TIM4_INDEX,
237 #endif
238 #ifdef BSP_USING_BTIM0
239     BTIM0_INDEX,
240 #endif
241 #ifdef BSP_USING_BTIM1
242     BTIM1_INDEX,
243 #endif
244 #ifdef BSP_USING_BTIM2
245     BTIM2_INDEX,
246 #endif
247 #ifdef BSP_USING_BTIM3
248     BTIM3_INDEX,
249 #endif
250 #ifdef BSP_USING_BTIM4
251     BTIM4_INDEX,
252 #endif
253 #ifdef BSP_USING_BTIM5
254     BTIM5_INDEX,
255 #endif
256 #ifdef BSP_USING_BTIM6
257     BTIM6_INDEX,
258 #endif
259 #ifdef BSP_USING_BTIM7
260     BTIM7_INDEX,
261 #endif
262 #ifdef BSP_USING_BTIM8
263     BTIM8_INDEX,
264 #endif
265 #ifdef BSP_USING_BTIM9
266     BTIM9_INDEX,
267 #endif
268 #ifdef BSP_USING_BTIM10
269     BTIM10_INDEX,
270 #endif
271 #ifdef BSP_USING_BTIM11
272     BTIM11_INDEX,
273 #endif
274 };
275 
276 static struct swm_hwtimer_cfg swm_hwtimer_cfg[] =
277     {
278 #ifdef BSP_USING_TIM0
279         TIM0_CFG,
280 #endif
281 #ifdef BSP_USING_TIM1
282         TIM1_CFG,
283 #endif
284 #ifdef BSP_USING_TIM2
285         TIM2_CFG,
286 #endif
287 #ifdef BSP_USING_TIM3
288         TIM3_CFG,
289 #endif
290 #ifdef BSP_USING_TIM4
291         TIM4_CFG,
292 #endif
293 #ifdef BSP_USING_BTIM0
294         BTIM0_CFG,
295 #endif
296 #ifdef BSP_USING_BTIM1
297         BTIM1_CFG,
298 #endif
299 #ifdef BSP_USING_BTIM2
300         BTIM2_CFG,
301 #endif
302 #ifdef BSP_USING_BTIM3
303         BTIM3_CFG,
304 #endif
305 #ifdef BSP_USING_BTIM4
306         BTIM4_CFG,
307 #endif
308 #ifdef BSP_USING_BTIM5
309         BTIM5_CFG,
310 #endif
311 #ifdef BSP_USING_BTIM6
312         BTIM6_CFG,
313 #endif
314 #ifdef BSP_USING_BTIM7
315         BTIM7_CFG,
316 #endif
317 #ifdef BSP_USING_BTIM8
318         BTIM8_CFG,
319 #endif
320 #ifdef BSP_USING_BTIM9
321         BTIM9_CFG,
322 #endif
323 #ifdef BSP_USING_BTIM10
324         BTIM10_CFG,
325 #endif
326 #ifdef BSP_USING_BTIM11
327         BTIM11_CFG,
328 #endif
329 };
330 
331 static struct swm_hwtimer_device hwtimer_obj[sizeof(swm_hwtimer_cfg) / sizeof(swm_hwtimer_cfg[0])] = {0};
332 
swm_timer_configure(struct rt_hwtimer_device * timer_device,rt_uint32_t state)333 static void swm_timer_configure(struct rt_hwtimer_device *timer_device, rt_uint32_t state)
334 {
335     struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
336     RT_ASSERT(timer_device != RT_NULL);
337 
338     if (state)
339     {
340         hwtimer_cfg = timer_device->parent.user_data;
341         TIMR_Init(hwtimer_cfg->TIMRx, TIMR_MODE_TIMER, CyclesPerUs, 1000000, 1);
342         timer_device->freq = 1000000;
343     }
344 }
345 
swm_timer_start(rt_hwtimer_t * timer_device,rt_uint32_t cnt,rt_hwtimer_mode_t opmode)346 static rt_err_t swm_timer_start(rt_hwtimer_t *timer_device, rt_uint32_t cnt, rt_hwtimer_mode_t opmode)
347 {
348     rt_err_t result = RT_EOK;
349     struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
350     RT_ASSERT(timer_device != RT_NULL);
351     hwtimer_cfg = timer_device->parent.user_data;
352 
353     if (opmode == HWTIMER_MODE_ONESHOT)
354     {
355         /* set timer to single mode */
356         timer_device->mode = HWTIMER_MODE_ONESHOT;
357     }
358     else
359     {
360         timer_device->mode = HWTIMER_MODE_PERIOD;
361     }
362     hwtimer_cfg->TIMRx->LOAD = cnt - 1;
363     TIMR_Stop(hwtimer_cfg->TIMRx);
364     TIMR_Start(hwtimer_cfg->TIMRx);
365 
366     return result;
367 }
368 
swm_timer_stop(rt_hwtimer_t * timer_device)369 static void swm_timer_stop(rt_hwtimer_t *timer_device)
370 {
371     struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
372     RT_ASSERT(timer_device != RT_NULL);
373     hwtimer_cfg = timer_device->parent.user_data;
374 
375     /* stop timer */
376     TIMR_Stop(hwtimer_cfg->TIMRx);
377 }
378 
swm_timer_count_get(rt_hwtimer_t * timer_device)379 static rt_uint32_t swm_timer_count_get(rt_hwtimer_t *timer_device)
380 {
381     struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
382     RT_ASSERT(timer_device != RT_NULL);
383     hwtimer_cfg = timer_device->parent.user_data;
384 
385     return TIMR_GetCurValue(hwtimer_cfg->TIMRx);
386 }
387 
swm_timer_control(rt_hwtimer_t * timer_device,rt_uint32_t cmd,void * args)388 static rt_err_t swm_timer_control(rt_hwtimer_t *timer_device, rt_uint32_t cmd, void *args)
389 {
390     struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
391     rt_err_t result = RT_EOK;
392     RT_ASSERT(timer_device != RT_NULL);
393     RT_ASSERT(args != RT_NULL);
394     hwtimer_cfg = timer_device->parent.user_data;
395 
396     switch (cmd)
397     {
398     case HWTIMER_CTRL_FREQ_SET:
399     {
400         rt_uint32_t freq;
401         freq = *(rt_uint32_t *)args;
402 
403         TIMR_Init(hwtimer_cfg->TIMRx, TIMR_MODE_TIMER, CyclesPerUs, freq, 1);
404     }
405     break;
406     default:
407     {
408         result = -RT_ENOSYS;
409     }
410     break;
411     }
412 
413     return result;
414 }
415 
416 static const struct rt_hwtimer_info _info = TIM_DEV_INFO_CONFIG;
417 
418 static const struct rt_hwtimer_ops swm_timer_ops =
419     {
420         .init = swm_timer_configure,
421         .start = swm_timer_start,
422         .stop = swm_timer_stop,
423         .count_get = swm_timer_count_get,
424         .control = swm_timer_control};
425 
swm_timer_isr(rt_hwtimer_t * timer_device)426 void swm_timer_isr(rt_hwtimer_t *timer_device)
427 {
428     struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
429     RT_ASSERT(timer_device != RT_NULL);
430     hwtimer_cfg = timer_device->parent.user_data;
431 
432     TIMR_INTClr(hwtimer_cfg->TIMRx);
433     rt_device_hwtimer_isr(timer_device);
434 }
435 
436 #ifdef BSP_USING_TIM0
TIMR0_Handler(void)437 void TIMR0_Handler(void)
438 {
439     rt_interrupt_enter();
440     swm_timer_isr(&(hwtimer_obj[TIM0_INDEX].time_device));
441     rt_interrupt_leave();
442 }
443 #endif // BSP_USING_TIM0
444 
445 #ifdef BSP_USING_TIM1
TIMR1_Handler(void)446 void TIMR1_Handler(void)
447 {
448     rt_interrupt_enter();
449     swm_timer_isr(&(hwtimer_obj[TIM1_INDEX].time_device));
450     rt_interrupt_leave();
451 }
452 #endif // BSP_USING_TIM1
453 
454 #ifdef BSP_USING_TIM2
TIMR2_Handler(void)455 void TIMR2_Handler(void)
456 {
457     rt_interrupt_enter();
458     swm_timer_isr(&(hwtimer_obj[TIM2_INDEX].time_device));
459     rt_interrupt_leave();
460 }
461 #endif // BSP_USING_TIM2
462 
463 #ifdef BSP_USING_TIM3
TIMR3_Handler(void)464 void TIMR3_Handler(void)
465 {
466     rt_interrupt_enter();
467     swm_timer_isr(&(hwtimer_obj[TIM3_INDEX].time_device));
468     rt_interrupt_leave();
469 }
470 #endif // BSP_USING_TIM3
471 
472 #ifdef BSP_USING_TIM4
TIMR4_Handler(void)473 void TIMR4_Handler(void)
474 {
475     rt_interrupt_enter();
476     swm_timer_isr(&(hwtimer_obj[TIM4_INDEX].time_device));
477     rt_interrupt_leave();
478 }
479 #endif // BSP_USING_TIM4
480 
481 #ifdef BSP_USING_BTIM0
BTIMR0_Handler(void)482 void BTIMR0_Handler(void)
483 {
484     rt_interrupt_enter();
485     swm_timer_isr(&(hwtimer_obj[BTIM0_INDEX].time_device));
486     rt_interrupt_leave();
487 }
488 #endif // BSP_USING_BTIM0
489 
490 #ifdef BSP_USING_BTIM1
BTIMR1_Handler(void)491 void BTIMR1_Handler(void)
492 {
493     rt_interrupt_enter();
494     swm_timer_isr(&(hwtimer_obj[BTIM1_INDEX].time_device));
495     rt_interrupt_leave();
496 }
497 #endif // BSP_USING_BTIM1
498 
499 #ifdef BSP_USING_BTIM2
BTIMR2_Handler(void)500 void BTIMR2_Handler(void)
501 {
502     rt_interrupt_enter();
503     swm_timer_isr(&(hwtimer_obj[BTIM2_INDEX].time_device));
504     rt_interrupt_leave();
505 }
506 #endif // BSP_USING_BTIM2
507 
508 #ifdef BSP_USING_BTIM3
BTIMR3_Handler(void)509 void BTIMR3_Handler(void)
510 {
511     rt_interrupt_enter();
512     swm_timer_isr(&(hwtimer_obj[BTIM3_INDEX].time_device));
513     rt_interrupt_leave();
514 }
515 #endif // BSP_USING_BTIM3
516 
517 #ifdef BSP_USING_BTIM4
BTIMR4_Handler(void)518 void BTIMR4_Handler(void)
519 {
520     rt_interrupt_enter();
521     swm_timer_isr(&(hwtimer_obj[BTIM4_INDEX].time_device));
522     rt_interrupt_leave();
523 }
524 #endif // BSP_USING_BTIM4
525 
526 #ifdef BSP_USING_BTIM5
BTIMR5_Handler(void)527 void BTIMR5_Handler(void)
528 {
529     rt_interrupt_enter();
530     swm_timer_isr(&(hwtimer_obj[BTIM5_INDEX].time_device));
531     rt_interrupt_leave();
532 }
533 #endif // BSP_USING_BTIM5
534 
535 #ifdef BSP_USING_BTIM6
BTIMR6_Handler(void)536 void BTIMR6_Handler(void)
537 {
538     rt_interrupt_enter();
539     swm_timer_isr(&(hwtimer_obj[BTIM6_INDEX].time_device));
540     rt_interrupt_leave();
541 }
542 #endif // BSP_USING_BTIM6
543 
544 #ifdef BSP_USING_BTIM7
BTIMR7_Handler(void)545 void BTIMR7_Handler(void)
546 {
547     rt_interrupt_enter();
548     swm_timer_isr(&(hwtimer_obj[BTIM7_INDEX].time_device));
549     rt_interrupt_leave();
550 }
551 #endif // BSP_USING_BTIM7
552 
553 #ifdef BSP_USING_BTIM8
BTIMR8_Handler(void)554 void BTIMR8_Handler(void)
555 {
556     rt_interrupt_enter();
557     swm_timer_isr(&(hwtimer_obj[BTIM8_INDEX].time_device));
558     rt_interrupt_leave();
559 }
560 #endif // BSP_USING_BTIM8
561 
562 #ifdef BSP_USING_BTIM9
BTIMR9_Handler(void)563 void BTIMR9_Handler(void)
564 {
565     rt_interrupt_enter();
566     swm_timer_isr(&(hwtimer_obj[BTIM9_INDEX].time_device));
567     rt_interrupt_leave();
568 }
569 #endif // BSP_USING_BTIM9
570 
571 #ifdef BSP_USING_BTIM10
BTIMR10_Handler(void)572 void BTIMR10_Handler(void)
573 {
574     rt_interrupt_enter();
575     swm_timer_isr(&(hwtimer_obj[BTIM10_INDEX].time_device));
576     rt_interrupt_leave();
577 }
578 #endif // BSP_USING_BTIM10
579 
580 #ifdef BSP_USING_BTIM11
BTIMR11_Handler(void)581 void BTIMR11_Handler(void)
582 {
583     rt_interrupt_enter();
584     swm_timer_isr(&(hwtimer_obj[BTIM11_INDEX].time_device));
585     rt_interrupt_leave();
586 }
587 #endif // BSP_USING_BTIM11
588 
swm_timer_init(void)589 int swm_timer_init(void)
590 {
591     int i = 0;
592     int result = RT_EOK;
593 
594     for (i = 0; i < sizeof(swm_hwtimer_cfg) / sizeof(swm_hwtimer_cfg[0]); i++)
595     {
596         hwtimer_obj[i].hwtimer_cfg = &swm_hwtimer_cfg[i];
597         hwtimer_obj[i].time_device.info = &_info;
598         hwtimer_obj[i].time_device.ops = &swm_timer_ops;
599         result = rt_device_hwtimer_register(&hwtimer_obj[i].time_device, hwtimer_obj[i].hwtimer_cfg->name, hwtimer_obj[i].hwtimer_cfg);
600         if (result != RT_EOK)
601         {
602             LOG_E("%s register fail.", hwtimer_obj[i].hwtimer_cfg->name);
603         }
604         else
605         {
606             LOG_D("%s register success.", hwtimer_obj[i].hwtimer_cfg->name);
607         }
608     }
609 
610     return result;
611 }
612 INIT_BOARD_EXPORT(swm_timer_init);
613 
614 #endif /* BSP_USING_TIM */
615 #endif /* RT_USING_HWTIMER */
616