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