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  * 2018-12-10    Zohar_Lee    first version
9  * 2020-07-10    lik          format file
10  */
11 
12 #include "drv_hwtimer.h"
13 
14 #ifdef RT_USING_HWTIMER
15 #ifdef BSP_USING_TIM
16 
17 //#define DRV_DEBUG
18 #define LOG_TAG "drv.hwtimer"
19 #include <drv_log.h>
20 
21 #if !defined(BSP_USING_TIM0) && !defined(BSP_USING_TIM1) && !defined(BSP_USING_TIM2) && !defined(BSP_USING_TIM3)     \
22 && !defined(BSP_USING_TIM4) && !defined(BSP_USING_TIM5)
23 #error "Please define at least one BSP_USING_TIMx"
24 /* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
25 #endif
26 
27 #ifndef TIM_DEV_INFO_CONFIG
28 #define TIM_DEV_INFO_CONFIG            \
29     {                                  \
30         .maxfreq = 120000000,          \
31         .minfreq = 120000000,          \
32         .maxcnt = 0xFFFFFFFF,          \
33         .cntmode = HWTIMER_CNTMODE_DW, \
34     }
35 #endif /* TIM_DEV_INFO_CONFIG */
36 
37 #ifdef BSP_USING_TIM0
38 #ifndef TIM0_CFG
39 #define TIM0_CFG          \
40     {                     \
41         .name = "timer0", \
42         .TIMRx = TIMR0,   \
43     }
44 #endif /* TIM0_CFG */
45 #endif /* BSP_USING_TIM0 */
46 
47 #ifdef BSP_USING_TIM1
48 #ifndef TIM1_CFG
49 #define TIM1_CFG          \
50     {                     \
51         .name = "timer1", \
52         .TIMRx = TIMR1,   \
53     }
54 #endif /* TIM1_CFG */
55 #endif /* BSP_USING_TIM1 */
56 
57 #ifdef BSP_USING_TIM2
58 #ifndef TIM2_CFG
59 #define TIM2_CFG          \
60     {                     \
61         .name = "timer2", \
62         .TIMRx = TIMR2,   \
63     }
64 #endif /* TIM2_CFG */
65 #endif /* BSP_USING_TIM2 */
66 
67 #ifdef BSP_USING_TIM3
68 #ifndef TIM3_CFG
69 #define TIM3_CFG          \
70     {                     \
71         .name = "timer3", \
72         .TIMRx = TIMR3,   \
73     }
74 #endif /* TIM3_CFG */
75 #endif /* BSP_USING_TIM3 */
76 
77 #ifdef BSP_USING_TIM4
78 #ifndef TIM4_CFG
79 #define TIM4_CFG          \
80     {                     \
81         .name = "timer4", \
82         .TIMRx = TIMR4,   \
83     }
84 #endif /* TIM4_CFG */
85 #endif /* BSP_USING_TIM4 */
86 
87 #ifdef BSP_USING_TIM5
88 #ifndef TIM5_CFG
89 #define TIM5_CFG          \
90     {                     \
91         .name = "timer5", \
92         .TIMRx = TIMR5,   \
93     }
94 #endif /* TIM5_CFG */
95 #endif /* BSP_USING_TIM5 */
96 
97 struct swm_hwtimer_cfg
98 {
99     char *name;
100     TIMR_TypeDef *TIMRx;
101 };
102 
103 struct swm_hwtimer_device
104 {
105     struct swm_hwtimer_cfg *hwtimer_cfg;
106     rt_hwtimer_t time_device;
107 };
108 
109 enum
110 {
111 #ifdef BSP_USING_TIM0
112     TIM0_INDEX,
113 #endif
114 #ifdef BSP_USING_TIM1
115     TIM1_INDEX,
116 #endif
117 #ifdef BSP_USING_TIM2
118     TIM2_INDEX,
119 #endif
120 #ifdef BSP_USING_TIM3
121     TIM3_INDEX,
122 #endif
123 #ifdef BSP_USING_TIM4
124     TIM4_INDEX,
125 #endif
126 #ifdef BSP_USING_TIM5
127     TIM5_INDEX,
128 #endif
129 };
130 
131 static struct swm_hwtimer_cfg swm_hwtimer_cfg[] =
132     {
133 #ifdef BSP_USING_TIM0
134         TIM0_CFG,
135 #endif
136 #ifdef BSP_USING_TIM1
137         TIM1_CFG,
138 #endif
139 #ifdef BSP_USING_TIM2
140         TIM2_CFG,
141 #endif
142 #ifdef BSP_USING_TIM3
143         TIM3_CFG,
144 #endif
145 #ifdef BSP_USING_TIM4
146         TIM4_CFG,
147 #endif
148 #ifdef BSP_USING_TIM5
149         TIM5_CFG,
150 #endif
151 };
152 
153 static struct swm_hwtimer_device hwtimer_obj[sizeof(swm_hwtimer_cfg) / sizeof(swm_hwtimer_cfg[0])] = {0};
154 
swm_timer_configure(struct rt_hwtimer_device * timer_device,rt_uint32_t state)155 static void swm_timer_configure(struct rt_hwtimer_device *timer_device, rt_uint32_t state)
156 {
157     struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
158     RT_ASSERT(timer_device != RT_NULL);
159 
160     if (state)
161     {
162         hwtimer_cfg = timer_device->parent.user_data;
163         TIMR_Init(hwtimer_cfg->TIMRx, TIMR_MODE_TIMER, SystemCoreClock, 1);
164         timer_device->freq = SystemCoreClock;
165     }
166 }
167 
swm_timer_start(rt_hwtimer_t * timer_device,rt_uint32_t cnt,rt_hwtimer_mode_t opmode)168 static rt_err_t swm_timer_start(rt_hwtimer_t *timer_device, rt_uint32_t cnt, rt_hwtimer_mode_t opmode)
169 {
170     rt_err_t result = RT_EOK;
171     struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
172     RT_ASSERT(timer_device != RT_NULL);
173     hwtimer_cfg = timer_device->parent.user_data;
174 
175     if (opmode == HWTIMER_MODE_ONESHOT)
176     {
177         /* set timer to single mode */
178         timer_device->mode = HWTIMER_MODE_ONESHOT;
179     }
180     else
181     {
182         timer_device->mode = HWTIMER_MODE_PERIOD;
183     }
184     TIMR_SetPeriod(hwtimer_cfg->TIMRx, cnt);
185     TIMR_Stop(hwtimer_cfg->TIMRx);
186     TIMR_Start(hwtimer_cfg->TIMRx);
187 
188     return result;
189 }
190 
swm_timer_stop(rt_hwtimer_t * timer_device)191 static void swm_timer_stop(rt_hwtimer_t *timer_device)
192 {
193     struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
194     RT_ASSERT(timer_device != RT_NULL);
195     hwtimer_cfg = timer_device->parent.user_data;
196 
197     /* stop timer */
198     TIMR_Stop(hwtimer_cfg->TIMRx);
199 }
200 
swm_timer_count_get(rt_hwtimer_t * timer_device)201 static rt_uint32_t swm_timer_count_get(rt_hwtimer_t *timer_device)
202 {
203     struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
204     RT_ASSERT(timer_device != RT_NULL);
205     hwtimer_cfg = timer_device->parent.user_data;
206 
207     return TIMR_GetCurValue(hwtimer_cfg->TIMRx);
208 }
209 
swm_timer_control(rt_hwtimer_t * timer_device,rt_uint32_t cmd,void * args)210 static rt_err_t swm_timer_control(rt_hwtimer_t *timer_device, rt_uint32_t cmd, void *args)
211 {
212     struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
213     rt_err_t result = RT_EOK;
214     RT_ASSERT(timer_device != RT_NULL);
215     RT_ASSERT(args != RT_NULL);
216     hwtimer_cfg = timer_device->parent.user_data;
217 
218     switch (cmd)
219     {
220     case HWTIMER_CTRL_FREQ_SET:
221     {
222         rt_uint32_t freq;
223         freq = *(rt_uint32_t *)args;
224 
225         TIMR_Init(hwtimer_cfg->TIMRx, TIMR_MODE_TIMER, SystemCoreClock / freq, 1);
226     }
227     break;
228     default:
229     {
230         result = -RT_ENOSYS;
231     }
232     break;
233     }
234 
235     return result;
236 }
237 
238 static const struct rt_hwtimer_info _info = TIM_DEV_INFO_CONFIG;
239 
240 static const struct rt_hwtimer_ops swm_timer_ops =
241     {
242         .init = swm_timer_configure,
243         .start = swm_timer_start,
244         .stop = swm_timer_stop,
245         .count_get = swm_timer_count_get,
246         .control = swm_timer_control};
247 
swm_timer_isr(rt_hwtimer_t * timer_device)248 void swm_timer_isr(rt_hwtimer_t *timer_device)
249 {
250     struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
251     RT_ASSERT(timer_device != RT_NULL);
252     hwtimer_cfg = timer_device->parent.user_data;
253 
254     TIMR_INTClr(hwtimer_cfg->TIMRx);
255     rt_device_hwtimer_isr(timer_device);
256 }
257 
258 #ifdef BSP_USING_TIM0
TIMR0_Handler(void)259 void TIMR0_Handler(void)
260 {
261     /* enter interrupt */
262     rt_interrupt_enter();
263     swm_timer_isr(&(hwtimer_obj[TIM0_INDEX].time_device));
264     /* leave interrupt */
265     rt_interrupt_leave();
266 }
267 #endif //BSP_USING_TIM0
268 
269 #ifdef BSP_USING_TIM1
TIMR1_Handler(void)270 void TIMR1_Handler(void)
271 {
272     /* enter interrupt */
273     rt_interrupt_enter();
274     swm_timer_isr(&(hwtimer_obj[TIM1_INDEX].time_device));
275     /* leave interrupt */
276     rt_interrupt_leave();
277 }
278 #endif //BSP_USING_TIM1
279 
280 #ifdef BSP_USING_TIM2
TIMR2_Handler(void)281 void TIMR2_Handler(void)
282 {
283     /* enter interrupt */
284     rt_interrupt_enter();
285     swm_timer_isr(&(hwtimer_obj[TIM2_INDEX].time_device));
286     /* leave interrupt */
287     rt_interrupt_leave();
288 }
289 #endif //BSP_USING_TIM2
290 
291 #ifdef BSP_USING_TIM3
TIMR3_Handler(void)292 void TIMR3_Handler(void)
293 {
294     /* enter interrupt */
295     rt_interrupt_enter();
296     swm_timer_isr(&(hwtimer_obj[TIM3_INDEX].time_device));
297     /* leave interrupt */
298     rt_interrupt_leave();
299 }
300 #endif //BSP_USING_TIM3
301 
302 #ifdef BSP_USING_TIM4
TIMR4_Handler(void)303 void TIMR4_Handler(void)
304 {
305     /* enter interrupt */
306     rt_interrupt_enter();
307     swm_timer_isr(&(hwtimer_obj[TIM4_INDEX].time_device));
308     /* leave interrupt */
309     rt_interrupt_leave();
310 }
311 #endif //BSP_USING_TIM4
312 
313 #ifdef BSP_USING_TIM5
TIMR5_Handler(void)314 void TIMR5_Handler(void)
315 {
316     /* enter interrupt */
317     rt_interrupt_enter();
318     swm_timer_isr(&(hwtimer_obj[TIM5_INDEX].time_device));
319     /* leave interrupt */
320     rt_interrupt_leave();
321 }
322 #endif //BSP_USING_TIM5
323 
swm_timer_init(void)324 static int swm_timer_init(void)
325 {
326     int i = 0;
327     int result = RT_EOK;
328 
329     for (i = 0; i < sizeof(swm_hwtimer_cfg) / sizeof(swm_hwtimer_cfg[0]); i++)
330     {
331         hwtimer_obj[i].hwtimer_cfg = &swm_hwtimer_cfg[i];
332         hwtimer_obj[i].time_device.info = &_info;
333         hwtimer_obj[i].time_device.ops = &swm_timer_ops;
334         result = rt_device_hwtimer_register(&hwtimer_obj[i].time_device, hwtimer_obj[i].hwtimer_cfg->name, hwtimer_obj[i].hwtimer_cfg);
335         if (result != RT_EOK)
336         {
337             LOG_E("%s register fail.", hwtimer_obj[i].hwtimer_cfg->name);
338         }
339         else
340         {
341             LOG_D("%s register success.", hwtimer_obj[i].hwtimer_cfg->name);
342         }
343     }
344 
345     return result;
346 }
347 INIT_BOARD_EXPORT(swm_timer_init);
348 
349 #endif /* BSP_USING_TIM */
350 #endif /* RT_USING_HWTIMER */
351