1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2022-05-16     shelton      first version
9  */
10 
11 #include "board.h"
12 #include "drv_hwtimer.h"
13 
14 //#define DRV_DEBUG
15 #define LOG_TAG             "drv.hwtimer"
16 #include <drv_log.h>
17 
18 #ifdef BSP_USING_HWTIMER
19 
20 enum
21 {
22 #ifdef BSP_USING_HWTMR1
23     TMR1_INDEX,
24 #endif
25 
26 #ifdef BSP_USING_HWTMR2
27     TMR2_INDEX,
28 #endif
29 
30 #ifdef BSP_USING_HWTMR3
31     TMR3_INDEX,
32 #endif
33 
34 #ifdef BSP_USING_HWTMR4
35     TMR4_INDEX,
36 #endif
37 
38 #ifdef BSP_USING_HWTMR5
39     TMR5_INDEX,
40 #endif
41 
42 #ifdef BSP_USING_HWTMR6
43     TMR6_INDEX,
44 #endif
45 
46 #ifdef BSP_USING_HWTMR7
47     TMR7_INDEX,
48 #endif
49 
50 #ifdef BSP_USING_HW_TMR8
51     TMR8_INDEX,
52 #endif
53 
54 #ifdef BSP_USING_HWTMR9
55     TMR9_INDEX,
56 #endif
57 
58 #ifdef BSP_USING_HWTMR10
59     TMR10_INDEX,
60 #endif
61 
62 #ifdef BSP_USING_HWTMR11
63     TMR11_INDEX,
64 #endif
65 
66 #ifdef BSP_USING_HWTMR12
67     TMR12_INDEX,
68 #endif
69 
70 #ifdef BSP_USING_HWTMR13
71     TMR13_INDEX,
72 #endif
73 
74 #ifdef BSP_USING_HWTMR14
75     TMR14_INDEX,
76 #endif
77 
78 #ifdef BSP_USING_HWTMR15
79     TMR15_INDEX,
80 #endif
81 };
82 
83 struct at32_hwtimer
84 {
85     rt_hwtimer_t  tmr_device;
86     tmr_type*     tmr_x;
87     IRQn_Type     tmr_irqn;
88     char          *name;
89 };
90 
91 static struct at32_hwtimer at32_hwtimer_obj[] =
92 {
93 #ifdef BSP_USING_HWTMR1
94     TMR1_CONFIG,
95 #endif
96 
97 #ifdef BSP_USING_HWTMR2
98     TMR2_CONFIG,
99 #endif
100 
101 #ifdef BSP_USING_HWTMR3
102     TMR3_CONFIG,
103 #endif
104 
105 #ifdef BSP_USING_HWTMR4
106     TMR4_CONFIG,
107 #endif
108 
109 #ifdef BSP_USING_HWTMR5
110     TMR5_CONFIG,
111 #endif
112 
113 #ifdef BSP_USING_HWTMR6
114     TMR6_CONFIG,
115 #endif
116 
117 #ifdef BSP_USING_HWTMR7
118     TMR7_CONFIG,
119 #endif
120 
121 #ifdef BSP_USING_HWTMR8
122     TMR8_CONFIG,
123 #endif
124 
125 #ifdef BSP_USING_HWTMR9
126     TMR9_CONFIG,
127 #endif
128 
129 #ifdef BSP_USING_HWTMR10
130     TMR10_CONFIG,
131 #endif
132 
133 #ifdef BSP_USING_HWTMR11
134     TMR11_CONFIG,
135 #endif
136 
137 #ifdef BSP_USING_HWTMR12
138     TMR12_CONFIG,
139 #endif
140 
141 #ifdef BSP_USING_HWTMR13
142     TMR13_CONFIG,
143 #endif
144 
145 #ifdef BSP_USING_HWTMR14
146     TMR14_CONFIG,
147 #endif
148 
149 #ifdef BSP_USING_HWTMR15
150     TMR15_CONFIG,
151 #endif
152 };
153 
tmr_pclk_get(rt_uint32_t * pclk1_doubler,rt_uint32_t * pclk2_doubler)154 static void tmr_pclk_get(rt_uint32_t *pclk1_doubler, rt_uint32_t *pclk2_doubler)
155 {
156     crm_clocks_freq_type  clocks_struct;
157 
158     *pclk1_doubler = 1;
159     *pclk2_doubler = 1;
160 
161     crm_clocks_freq_get(&clocks_struct);
162 
163     if(clocks_struct.ahb_freq != clocks_struct.apb1_freq)
164     {
165         *pclk1_doubler = 2;
166     }
167 
168     if(clocks_struct.ahb_freq != clocks_struct.apb2_freq)
169     {
170         *pclk2_doubler = 2;
171     }
172 }
173 
at32_timer_init(struct rt_hwtimer_device * timer,rt_uint32_t state)174 static void at32_timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
175 {
176     crm_clocks_freq_type clocks_struct;
177     rt_uint32_t pclk1_doubler = 0, pclk2_doubler = 0;
178     rt_uint32_t prescaler_value = 0, tmr_clock = 0;
179     tmr_type *tmr_x = RT_NULL;
180     struct at32_hwtimer *tmr_device = RT_NULL;
181 
182     RT_ASSERT(timer != RT_NULL);
183     if (state)
184     {
185         tmr_x = (tmr_type *)timer->parent.user_data;
186         tmr_device = (struct at32_hwtimer *)timer;
187 
188         /* timer clock enable */
189         at32_msp_hwtmr_init(tmr_x);
190 
191         /* get timer clock */
192         tmr_pclk_get(&pclk1_doubler, &pclk2_doubler);
193         crm_clocks_freq_get(&clocks_struct);
194 
195         if(
196 #if defined (TMR1)
197         (tmr_x == TMR1)
198 #endif
199 #if defined (TMR8)
200         || (tmr_x == TMR8)
201 #endif
202 #if defined (TMR9)
203         || (tmr_x == TMR9)
204 #endif
205 #if defined (TMR10)
206         || (tmr_x == TMR10)
207 #endif
208 #if defined (TMR11)
209         || (tmr_x == TMR11)
210 #endif
211         )
212         {
213             tmr_clock = clocks_struct.apb2_freq * pclk2_doubler;
214         }
215         else
216         {
217             tmr_clock = clocks_struct.apb1_freq * pclk1_doubler;
218         }
219         /* set timer clock is 1mhz */
220         prescaler_value = (uint32_t)(tmr_clock / 10000) - 1;
221         tmr_base_init(tmr_x, 10000 - 1, prescaler_value);
222         tmr_clock_source_div_set(tmr_x, TMR_CLOCK_DIV1);
223         tmr_repetition_counter_set(tmr_x, 0);
224 
225         if (timer->info->cntmode == HWTIMER_CNTMODE_UP)
226         {
227             tmr_cnt_dir_set(tmr_x, TMR_COUNT_UP);
228         }
229         else
230         {
231             tmr_cnt_dir_set(tmr_x, TMR_COUNT_DOWN);
232         }
233 
234         /* enable the timer global interrupt and clear flag */
235         nvic_irq_enable(tmr_device->tmr_irqn, 2, 0);
236 
237         tmr_interrupt_enable(tmr_x, TMR_OVF_INT, TRUE);
238         tmr_flag_clear(tmr_x, TMR_OVF_INT);
239 
240         LOG_D("%s init success", tmr_device->name);
241     }
242 }
243 
at32_timer_start(rt_hwtimer_t * timer,rt_uint32_t pr,rt_hwtimer_mode_t opmode)244 static rt_err_t at32_timer_start(rt_hwtimer_t *timer, rt_uint32_t pr, rt_hwtimer_mode_t opmode)
245 {
246     rt_err_t result = RT_EOK;
247     tmr_type *tmr_x = RT_NULL;
248 
249     RT_ASSERT(timer != RT_NULL);
250     tmr_x = (tmr_type *)timer->parent.user_data;
251 
252     /* set tmr_x count */
253     tmr_counter_value_set(tmr_x, 0);
254     /* set tmr_x period register */
255     tmr_period_value_set(tmr_x, pr - 1);
256 
257     if (opmode == HWTIMER_MODE_ONESHOT)
258     {
259         /* set timer to one cycle mode */
260         tmr_one_cycle_mode_enable(tmr_x, TRUE);
261     }
262     else
263     {
264         /* set timer to period mode */
265         tmr_one_cycle_mode_enable(tmr_x, FALSE);
266     }
267 
268     /* start timer */
269     tmr_counter_enable(tmr_x, TRUE);
270 
271     return result;
272 }
273 
at32_timer_stop(rt_hwtimer_t * timer)274 static void at32_timer_stop(rt_hwtimer_t *timer)
275 {
276     tmr_type *tmr_x = RT_NULL;
277 
278     RT_ASSERT(timer != RT_NULL);
279     tmr_x = (tmr_type *)timer->parent.user_data;
280 
281     /* stop timer */
282     tmr_counter_enable(tmr_x, FALSE);
283 
284     /* set tmr_x count */
285     tmr_counter_value_set(tmr_x, 0);
286 }
287 
at32_timer_counter_get(rt_hwtimer_t * timer)288 static rt_uint32_t at32_timer_counter_get(rt_hwtimer_t *timer)
289 {
290     tmr_type *tmr_x = RT_NULL;
291 
292     RT_ASSERT(timer != RT_NULL);
293 
294     tmr_x = (tmr_type *)timer->parent.user_data;
295 
296     return tmr_counter_value_get(tmr_x);
297 }
298 
at32_timer_ctrl(rt_hwtimer_t * timer,rt_uint32_t cmd,void * arg)299 static rt_err_t at32_timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
300 {
301     crm_clocks_freq_type clocks_struct;
302     tmr_type *tmr_x = RT_NULL;
303     rt_err_t result = RT_EOK;
304     rt_uint32_t pclk1_doubler = 0, pclk2_doubler = 0, tmr_clock = 0;
305 
306     RT_ASSERT(timer != RT_NULL);
307     RT_ASSERT(arg != RT_NULL);
308 
309     tmr_x = (tmr_type *)timer->parent.user_data;
310 
311     switch(cmd)
312     {
313         case HWTIMER_CTRL_FREQ_SET:
314         {
315             rt_uint32_t freq;
316             rt_uint16_t val;
317 
318             /* get timer frequence */
319             freq = *((rt_uint32_t *)arg);
320 
321             /* get timer clock */
322             tmr_pclk_get(&pclk1_doubler, &pclk2_doubler);
323             crm_clocks_freq_get(&clocks_struct);
324             if(
325 #if defined (TMR1)
326             (tmr_x == TMR1)
327 #endif
328 #if defined (TMR8)
329             || (tmr_x == TMR8)
330 #endif
331 #if defined (TMR9)
332             || (tmr_x == TMR9)
333 #endif
334 #if defined (TMR10)
335             || (tmr_x == TMR10)
336 #endif
337 #if defined (TMR11)
338             || (tmr_x == TMR11)
339 #endif
340             )
341             {
342                 tmr_clock = clocks_struct.apb2_freq * pclk2_doubler;
343             }
344             else
345             {
346                 tmr_clock = clocks_struct.apb1_freq * pclk1_doubler;
347             }
348             /* set div value */
349             val = tmr_clock / freq;
350 
351             tmr_div_value_set(tmr_x, val - 1);
352             tmr_event_sw_trigger(tmr_x, TMR_OVERFLOW_SWTRIG);
353         }
354         break;
355         default:
356         {
357             result = -RT_ENOSYS;
358         }
359         break;
360     }
361 
362     return result;
363 }
364 
365 static const struct rt_hwtimer_info _info = TMR_DEV_INFO_CONFIG;
366 static const struct rt_hwtimer_ops _ops =
367 {
368     .init      = at32_timer_init,
369     .start     = at32_timer_start,
370     .stop      = at32_timer_stop,
371     .count_get = at32_timer_counter_get,
372     .control   = at32_timer_ctrl,
373 };
374 
375 #ifdef BSP_USING_HWTMR2
TMR2_GLOBAL_IRQHandler(void)376 void TMR2_GLOBAL_IRQHandler(void)
377 {
378     /* enter interrupt */
379     rt_interrupt_enter();
380 
381     if(tmr_flag_get(TMR2, TMR_OVF_FLAG) == SET)
382     {
383         rt_device_hwtimer_isr(&at32_hwtimer_obj[TMR2_INDEX].tmr_device);
384         tmr_flag_clear(TMR2, TMR_OVF_FLAG);
385     }
386     /* leave interrupt */
387     rt_interrupt_leave();
388 }
389 #endif
390 
391 #ifdef BSP_USING_HWTMR3
TMR3_GLOBAL_IRQHandler(void)392 void TMR3_GLOBAL_IRQHandler(void)
393 {
394     /* enter interrupt */
395     rt_interrupt_enter();
396 
397     if(tmr_flag_get(TMR3, TMR_OVF_FLAG) == SET)
398     {
399         rt_device_hwtimer_isr(&at32_hwtimer_obj[TMR3_INDEX].tmr_device);
400         tmr_flag_clear(TMR3, TMR_OVF_FLAG);
401     }
402     /* leave interrupt */
403     rt_interrupt_leave();
404 }
405 #endif
406 
407 #ifdef BSP_USING_HWTMR4
TMR4_GLOBAL_IRQHandler(void)408 void TMR4_GLOBAL_IRQHandler(void)
409 {
410     /* enter interrupt */
411     rt_interrupt_enter();
412 
413     if(tmr_flag_get(TMR4, TMR_OVF_FLAG) == SET)
414     {
415         rt_device_hwtimer_isr(&at32_hwtimer_obj[TMR4_INDEX].tmr_device);
416         tmr_flag_clear(TMR4, TMR_OVF_FLAG);
417     }
418     /* leave interrupt */
419     rt_interrupt_leave();
420 }
421 #endif
422 
423 #ifdef BSP_USING_HWTMR5
TMR5_GLOBAL_IRQHandler(void)424 void TMR5_GLOBAL_IRQHandler(void)
425 {
426     /* enter interrupt */
427     rt_interrupt_enter();
428 
429     if(tmr_flag_get(TMR5, TMR_OVF_FLAG) == SET)
430     {
431         rt_device_hwtimer_isr(&at32_hwtimer_obj[TMR5_INDEX].tmr_device);
432         tmr_flag_clear(TMR5, TMR_OVF_FLAG);
433     }
434     /* leave interrupt */
435     rt_interrupt_leave();
436 }
437 #endif
438 
rt_hw_hwtimer_init(void)439 static int rt_hw_hwtimer_init(void)
440 {
441     int i = 0;
442     int result = RT_EOK;
443 
444     for (i = 0; i < sizeof(at32_hwtimer_obj) / sizeof(at32_hwtimer_obj[0]); i++)
445     {
446         at32_hwtimer_obj[i].tmr_device.info = &_info;
447         at32_hwtimer_obj[i].tmr_device.ops  = &_ops;
448         if (rt_device_hwtimer_register(&at32_hwtimer_obj[i].tmr_device, at32_hwtimer_obj[i].name, at32_hwtimer_obj[i].tmr_x) == RT_EOK)
449         {
450             LOG_D("%s register success", at32_hwtimer_obj[i].name);
451         }
452         else
453         {
454             LOG_E("%s register failed", at32_hwtimer_obj[i].name);
455             result = -RT_ERROR;
456         }
457     }
458 
459     return result;
460 }
461 
462 INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
463 
464 #endif /* BSP_USING_HWTIMER */
465