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