1 /*
2 * Copyright (c) 2006-2022, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2021-02-25 iysheng first version
9 */
10
11 #include <board.h>
12 #include <rtdevice.h>
13 #include <drivers/hwtimer.h>
14
15 #ifdef BSP_USING_HWTIMER
16
17 typedef struct {
18 uint32_t reg_base;
19 IRQn_Type irqn;
20 rcu_periph_enum rcu;
21 } gd32_hwtimer_data;
22
23 typedef struct {
24 char dev_name[RT_NAME_MAX];
25 const gd32_hwtimer_data hw_data;
26 rt_hwtimer_t hwtimer_dev;
27 const struct rt_hwtimer_info hwtimer_info;
28 } gd32_hwtimer_device;
29
30 enum timer_index_E {
31 #ifdef BSP_USING_HWTIMER0
32 TIM0_INDEX,
33 #endif
34 #ifdef BSP_USING_HWTIMER1
35 TIM1_INDEX,
36 #endif
37 #ifdef BSP_USING_HWTIMER2
38 TIM2_INDEX,
39 #endif
40 #ifdef BSP_USING_HWTIMER3
41 TIM3_INDEX,
42 #endif
43 #ifdef BSP_USING_HWTIMER4
44 TIM4_INDEX,
45 #endif
46 #ifdef BSP_USING_HWTIMER5
47 TIM5_INDEX,
48 #endif
49 #ifdef BSP_USING_HWTIMER6
50 TIM6_INDEX,
51 #endif
52 #ifdef BSP_USING_HWTIMER7
53 TIM7_INDEX,
54 #endif
55 #ifdef BSP_USING_HWTIMER8
56 TIM8_INDEX,
57 #endif
58 #ifdef BSP_USING_HWTIMER9
59 TIM9_INDEX,
60 #endif
61 #ifdef BSP_USING_HWTIMER10
62 TIM10_INDEX,
63 #endif
64 #ifdef BSP_USING_HWTIMER11
65 TIM11_INDEX,
66 #endif
67 #ifdef BSP_USING_HWTIMER12
68 TIM12_INDEX,
69 #endif
70 #ifdef BSP_USING_HWTIMER13
71 TIM13_INDEX,
72 #endif
73 };
74
75 /*
76 * static void __set_timerx_freq
77 * Set freq with timerx
78 *
79 * @param timerx the pointer of TIMER_TypeDef
80 * @param freq of the timer clock
81 * @retval None
82 */
__set_timerx_freq(uint32_t timerx,uint32_t freq)83 static void __set_timerx_freq(uint32_t timerx, uint32_t freq)
84 {
85 uint32_t ap1freq, ap2freq;
86 uint16_t prescaler;
87 uint32_t temp;
88
89 if (timerx == TIMER0 || timerx == TIMER7 || timerx == TIMER8 \
90 || timerx == TIMER9 || timerx == TIMER10)
91 {
92 ap2freq = rcu_clock_freq_get(CK_APB2);
93 temp = RCU_CFG0 & RCU_CFG0_APB2PSC;
94 temp >>= 11;
95 /* whether should frequency doubling */
96 temp = (temp < 4) ? 0 : 1;
97
98 prescaler = (ap2freq << temp) / freq - 1;
99 }
100 else
101 {
102 ap1freq = rcu_clock_freq_get(CK_APB1);
103 temp = RCU_CFG0 & RCU_CFG0_APB1PSC;
104 temp >>= 8;
105 /* whether should frequency doubling */
106 temp = (temp < 4) ? 0 : 1;
107
108 prescaler = (ap1freq << temp) / freq - 1;
109 }
110
111 timer_prescaler_config(timerx, prescaler, TIMER_PSC_RELOAD_NOW);
112 }
113
gd32_hwtimer_init(struct rt_hwtimer_device * timer,rt_uint32_t state)114 static void gd32_hwtimer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
115 {
116 uint32_t timer_base = (uint32_t)timer->parent.user_data;
117 timer_parameter_struct initpara;
118
119 if (state)
120 {
121 timer_internal_clock_config(timer_base);
122 timer_struct_para_init(&initpara);
123 initpara.period = timer->info->maxcnt;
124 timer_init(timer_base, &initpara);
125 __set_timerx_freq(timer_base, timer->info->maxfreq);
126 }
127 }
128
gd32_hwtimer_start(struct rt_hwtimer_device * timer,rt_uint32_t cnt,rt_hwtimer_mode_t mode)129 static rt_err_t gd32_hwtimer_start(struct rt_hwtimer_device *timer, \
130 rt_uint32_t cnt, rt_hwtimer_mode_t mode)
131 {
132 uint32_t timer_base = (uint32_t)timer->parent.user_data;
133
134 if (mode == HWTIMER_MODE_ONESHOT)
135 {
136 timer_single_pulse_mode_config(timer_base, TIMER_SP_MODE_SINGLE);
137 }
138 else if (mode == HWTIMER_MODE_PERIOD)
139 {
140 timer_single_pulse_mode_config(timer_base, TIMER_SP_MODE_REPETITIVE);
141 }
142
143 timer_counter_value_config(timer_base, 0);
144 timer_autoreload_value_config(timer_base, cnt - 1);
145 timer_enable(timer_base);
146
147 return 0;
148 }
149
gd32_hwtimer_stop(struct rt_hwtimer_device * timer)150 static void gd32_hwtimer_stop(struct rt_hwtimer_device *timer)
151 {
152 uint32_t timer_base = (uint32_t)timer->parent.user_data;
153
154 timer_disable(timer_base);
155 }
156
gd32_hwtimer_count_get(struct rt_hwtimer_device * timer)157 static rt_uint32_t gd32_hwtimer_count_get(struct rt_hwtimer_device *timer)
158 {
159 uint32_t timer_base = (uint32_t)timer->parent.user_data;
160 rt_uint32_t count;
161
162 count = timer_counter_read(timer_base);
163
164 return count;
165 }
166
gd32_hwtimer_control(struct rt_hwtimer_device * timer,rt_uint32_t cmd,void * args)167 static rt_err_t gd32_hwtimer_control(struct rt_hwtimer_device *timer, rt_uint32_t cmd, \
168 void *args)
169 {
170 int ret = RT_EOK;
171 rt_int32_t freq;
172 rt_hwtimer_mode_t mode;
173
174 switch (cmd)
175 {
176 case HWTIMER_CTRL_FREQ_SET:
177 freq = *(rt_uint32_t *)args;
178 __set_timerx_freq((uint32_t)timer->parent.user_data, freq);
179 break;
180 default:
181 rt_kprintf("invalid cmd:%x\n", cmd);
182 ret = -RT_EINVAL;
183 break;
184 }
185
186 return ret;
187 }
188
189 static const struct rt_hwtimer_ops g_gd32_hwtimer_ops = {
190 gd32_hwtimer_init,
191 gd32_hwtimer_start,
192 gd32_hwtimer_stop,
193 gd32_hwtimer_count_get,
194 gd32_hwtimer_control,
195 };
196
197 static gd32_hwtimer_device g_gd32_hwtimer[] = {
198 #ifdef BSP_USING_HWTIMER0
199 {
200 "timer0",
201 {
202 TIMER0,
203 TIMER0_UP_IRQn,
204 RCU_TIMER0,
205 },
206 {0},
207 {
208 1000000,
209 1000,
210 0xffff,
211 0, /* count up mode */
212 }
213 },
214 #endif
215 #ifdef BSP_USING_HWTIMER1
216 {
217 "timer1",
218 {
219 TIMER1,
220 TIMER1_IRQn,
221 RCU_TIMER1,
222 },
223 {0},
224 {
225 1000000,
226 1000,
227 0xffff,
228 0, /* count up mode */
229 }
230 },
231 #endif
232 #ifdef BSP_USING_HWTIMER2
233 {
234 "timer2",
235 {
236 TIMER2,
237 TIMER2_IRQn,
238 RCU_TIMER2,
239 },
240 {0},
241 {
242 1000000,
243 1000,
244 0xffff,
245 0, /* count up mode */
246 }
247 },
248 #endif
249 #ifdef BSP_USING_HWTIMER3
250 {
251 "timer3",
252 {
253 TIMER3,
254 TIMER3_IRQn,
255 RCU_TIMER3,
256 },
257 {0},
258 {
259 1000000,
260 1000,
261 0xffff,
262 0, /* count up mode */
263 }
264 },
265 #endif
266 #ifdef BSP_USING_HWTIMER4
267 {
268 "timer4",
269 {
270 TIMER4,
271 TIMER4_IRQn,
272 RCU_TIMER4,
273 },
274 {0},
275 {
276 1000000,
277 1000,
278 0xffff,
279 0, /* count up mode */
280 }
281 },
282 #endif
283 #ifdef BSP_USING_HWTIMER5
284 {
285 "timer5",
286 {
287 TIMER5,
288 TIMER5_IRQn,
289 RCU_TIMER5,
290 },
291 {0},
292 {
293 1000000,
294 1000,
295 0xffff,
296 0, /* count up mode */
297 }
298 },
299 #endif
300 #ifdef BSP_USING_HWTIMER6
301 {
302 "timer6",
303 {
304 TIMER6,
305 TIMER6_IRQn,
306 RCU_TIMER6,
307 },
308 {0},
309 {
310 1000000,
311 1000,
312 0xffff,
313 0, /* count up mode */
314 }
315 },
316 #endif
317 #ifdef BSP_USING_HWTIMER7
318 {
319 "timer7",
320 {
321 TIMER7,
322 TIMER7_UP_IRQn,
323 RCU_TIMER7,
324 },
325 {0},
326 {
327 1000000,
328 1000,
329 0xffff,
330 0, /* count up mode */
331 }
332 },
333 #endif
334 #ifdef BSP_USING_HWTIMER8
335 {
336 "timer8",
337 {
338 TIMER8,
339 TIMER8_IRQn,
340 RCU_TIMER8,
341 },
342 {0},
343 {
344 1000000,
345 1000,
346 0xffff,
347 0, /* count up mode */
348 }
349 },
350 #endif
351 #ifdef BSP_USING_HWTIMER9
352 {
353 "timer9",
354 {
355 TIMER9,
356 TIMER9_IRQn,
357 RCU_TIMER9,
358 },
359 {0},
360 {
361 1000000,
362 1000,
363 0xffff,
364 0, /* count up mode */
365 }
366 },
367 #endif
368 #ifdef BSP_USING_HWTIMER10
369 {
370 "timer10",
371 {
372 TIMER10,
373 TIMER10_IRQn,
374 RCU_TIMER10,
375 },
376 {0},
377 {
378 1000000,
379 1000,
380 0xffff,
381 0, /* count up mode */
382 }
383 },
384 #endif
385 #ifdef BSP_USING_HWTIMER11
386 {
387 "timer11",
388 {
389 TIMER11,
390 TIMER11_IRQn,
391 RCU_TIMER11,
392 },
393 {0},
394 {
395 1000000,
396 1000,
397 0xffff,
398 0, /* count up mode */
399 }
400 },
401 #endif
402 #ifdef BSP_USING_HWTIMER12
403 {
404 "timer12",
405 {
406 TIMER12,
407 TIMER12_IRQn,
408 RCU_TIMER12,
409 },
410 {0},
411 {
412 1000000,
413 1000,
414 0xffff,
415 0, /* count up mode */
416 }
417 },
418 #endif
419 #ifdef BSP_USING_HWTIMER13
420 {
421 "timer13",
422 {
423 TIMER13,
424 TIMER13_IRQn,
425 RCU_TIMER13,
426 },
427 {0},
428 {
429 1000000,
430 1000,
431 0xffff,
432 0, /* count up mode */
433 }
434 },
435 #endif
436 };
437
438 #ifdef BSP_USING_HWTIMER0
TIMER0_UP_IRQHandler(void)439 void TIMER0_UP_IRQHandler(void)
440 {
441 rt_interrupt_enter();
442 rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM0_INDEX].hwtimer_dev);
443 timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM0_INDEX].hwtimer_dev.parent.user_data, \
444 TIMER_INT_UP);
445 rt_interrupt_leave();
446 }
447 #endif
448
449 #ifdef BSP_USING_HWTIMER1
TIMER1_IRQHandler(void)450 void TIMER1_IRQHandler(void)
451 {
452 rt_interrupt_enter();
453 rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM1_INDEX].hwtimer_dev);
454 timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM1_INDEX].hwtimer_dev.parent.user_data, \
455 TIMER_INT_UP);
456 rt_interrupt_leave();
457 }
458 #endif
459
460 #ifdef BSP_USING_HWTIMER2
TIMER2_IRQHandler(void)461 void TIMER2_IRQHandler(void)
462 {
463 rt_interrupt_enter();
464 rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM2_INDEX].hwtimer_dev);
465 timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM2_INDEX].hwtimer_dev.parent.user_data, \
466 TIMER_INT_UP);
467 rt_interrupt_leave();
468 }
469 #endif
470
471 #ifdef BSP_USING_HWTIMER3
TIMER3_IRQHandler(void)472 void TIMER3_IRQHandler(void)
473 {
474 rt_interrupt_enter();
475 rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM3_INDEX].hwtimer_dev);
476 timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM3_INDEX].hwtimer_dev.parent.user_data, \
477 TIMER_INT_UP);
478 rt_interrupt_leave();
479 }
480 #endif
481
482 #ifdef BSP_USING_HWTIMER4
TIMER4_IRQHandler(void)483 void TIMER4_IRQHandler(void)
484 {
485 rt_interrupt_enter();
486 rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM4_INDEX].hwtimer_dev);
487 timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM4_INDEX].hwtimer_dev.parent.user_data, \
488 TIMER_INT_UP);
489 rt_interrupt_leave();
490 }
491 #endif
492
493 #ifdef BSP_USING_HWTIMER5
TIMER5_IRQHandler(void)494 void TIMER5_IRQHandler(void)
495 {
496 rt_interrupt_enter();
497 rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM5_INDEX].hwtimer_dev);
498 timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM5_INDEX].hwtimer_dev.parent.user_data, \
499 TIMER_INT_UP);
500 rt_interrupt_leave();
501 }
502 #endif
503
504 #ifdef BSP_USING_HWTIMER6
TIMER6_IRQHandler(void)505 void TIMER6_IRQHandler(void)
506 {
507 rt_interrupt_enter();
508 rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM6_INDEX].hwtimer_dev);
509 timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM6_INDEX].hwtimer_dev.parent.user_data, \
510 TIMER_INT_UP);
511 rt_interrupt_leave();
512 }
513 #endif
514
515 #ifdef BSP_USING_HWTIMER7
TIMER7_UP_IRQHandler(void)516 void TIMER7_UP_IRQHandler(void)
517 {
518 rt_interrupt_enter();
519 rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM7_INDEX].hwtimer_dev);
520 timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM7_INDEX].hwtimer_dev.parent.user_data, \
521 TIMER_INT_UP);
522 rt_interrupt_leave();
523 }
524 #endif
525
rt_hwtimer_init(void)526 static int rt_hwtimer_init(void)
527 {
528 int ret = 0, i = 0;
529
530 for (; i < sizeof(g_gd32_hwtimer) / sizeof(g_gd32_hwtimer[0]); i++)
531 {
532 g_gd32_hwtimer[i].hwtimer_dev.ops = &g_gd32_hwtimer_ops;
533 g_gd32_hwtimer[i].hwtimer_dev.info = &g_gd32_hwtimer[i].hwtimer_info;
534
535 rcu_periph_clock_enable(g_gd32_hwtimer[i].hw_data.rcu);
536 NVIC_SetPriority(g_gd32_hwtimer[i].hw_data.irqn, 0);
537 NVIC_EnableIRQ(g_gd32_hwtimer[i].hw_data.irqn);
538 timer_interrupt_enable(g_gd32_hwtimer[i].hw_data.reg_base, TIMER_INT_UP);
539 ret = rt_device_hwtimer_register(&g_gd32_hwtimer[i].hwtimer_dev, \
540 g_gd32_hwtimer[i].dev_name, (void *)g_gd32_hwtimer[i].hw_data.reg_base);
541 if (RT_EOK != ret)
542 {
543 rt_kprintf("failed register %s, err=%d\n", g_gd32_hwtimer[i].dev_name, \
544 ret);
545 break;
546 }
547 }
548
549 return ret;
550 }
551 INIT_BOARD_EXPORT(rt_hwtimer_init);
552 #endif
553