1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2021-08-10 charlown first version
9 */
10
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include <board.h>
14
15 #ifdef BSP_USING_HWTIMER
16
17 #define LOG_TAG "drv.hwtimer"
18 #include <drv_log.h>
19
20 struct hwtimer_device
21 {
22 struct rt_hwtimer_device parent;
23 TIM_TypeDef *periph;
24 IRQn_Type irqn;
25 char *name;
26 };
27
28 #ifdef BSP_USING_TIM1_HWTIMER
29 struct hwtimer_device hwtimer_device1 =
30 {
31 .periph = TIM1,
32 .irqn = TIM1_UP_IRQn,
33 .name = "timer1"};
34 #endif
35
36 #ifdef BSP_USING_TIM2_HWTIMER
37 struct hwtimer_device hwtimer_device2 =
38 {
39 .periph = TIM2,
40 .irqn = TIM2_IRQn,
41 .name = "timer2"};
42 #endif
43
44 #ifdef BSP_USING_TIM3_HWTIMER
45 struct hwtimer_device hwtimer_device3 =
46 {
47 .periph = TIM3,
48 .irqn = TIM3_IRQn,
49 .name = "timer3"};
50 #endif
51
52 #ifdef BSP_USING_TIM4_HWTIMER
53 struct hwtimer_device hwtimer_device4 =
54 {
55 .periph = TIM4,
56 .irqn = TIM4_IRQn,
57 .name = "timer4"};
58 #endif
59
ch32f1_hwtimer_init(struct rt_hwtimer_device * device,rt_uint32_t state)60 static void ch32f1_hwtimer_init(struct rt_hwtimer_device *device, rt_uint32_t state)
61 {
62 struct hwtimer_device *hwtimer_dev;
63 struct rt_hwtimer_info *hwtimer_info;
64 rt_uint32_t clk = 0;
65 rt_uint16_t prescaler_value = 0;
66
67 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitType;
68 NVIC_InitTypeDef NVIC_InitStructure;
69
70 RT_ASSERT(device != RT_NULL);
71
72 hwtimer_dev = (struct hwtimer_device *)device;
73
74 if (state)
75 {
76 ch32f1_tim_clock_init(hwtimer_dev->periph);
77
78 hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_dev->periph);
79
80 clk = ch32f1_tim_clock_get(hwtimer_dev->periph);
81
82 prescaler_value = (rt_uint16_t)(clk / hwtimer_info->minfreq) - 1;
83
84 /*
85 * (1 / freq) = (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
86 */
87
88 TIM_TimeBaseInitType.TIM_Period = hwtimer_info->maxcnt - 1;
89 TIM_TimeBaseInitType.TIM_Prescaler = prescaler_value;
90 TIM_TimeBaseInitType.TIM_ClockDivision = TIM_CKD_DIV1;
91 TIM_TimeBaseInitType.TIM_RepetitionCounter = 0;
92
93 if (hwtimer_info == RT_NULL)
94 {
95 TIM_TimeBaseInitType.TIM_CounterMode = TIM_CounterMode_Up;
96 }
97 else
98 {
99 if (hwtimer_info->cntmode == HWTIMER_CNTMODE_UP)
100 {
101 TIM_TimeBaseInitType.TIM_CounterMode = TIM_CounterMode_Up;
102 }
103 else
104 {
105 TIM_TimeBaseInitType.TIM_CounterMode = TIM_CounterMode_Down;
106 }
107 }
108
109 TIM_TimeBaseInit(hwtimer_dev->periph, &TIM_TimeBaseInitType);
110
111 NVIC_InitStructure.NVIC_IRQChannel = hwtimer_dev->irqn;
112 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
113 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
114 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
115 NVIC_Init(&NVIC_InitStructure);
116
117 TIM_ITConfig(hwtimer_dev->periph, TIM_IT_Update, ENABLE);
118 TIM_ClearITPendingBit(hwtimer_dev->periph, TIM_IT_Update);
119
120 LOG_D("%s init success", hwtimer_dev->name);
121 }
122 }
123
ch32f1_hwtimer_start(struct rt_hwtimer_device * device,rt_uint32_t cnt,rt_hwtimer_mode_t mode)124 static rt_err_t ch32f1_hwtimer_start(struct rt_hwtimer_device *device, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
125 {
126
127 struct hwtimer_device *hwtimer_dev;
128
129 RT_ASSERT(device != RT_NULL);
130
131 hwtimer_dev = (struct hwtimer_device *)device;
132
133 /*
134 * (1 / freq) = (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
135 */
136
137 TIM_SetCounter(hwtimer_dev->periph, 0);
138 TIM_SetAutoreload(hwtimer_dev->periph, cnt - 1);
139
140 if (mode == HWTIMER_MODE_ONESHOT)
141 {
142 TIM_SelectOnePulseMode(hwtimer_dev->periph, TIM_OPMode_Single);
143 }
144 else
145 {
146 TIM_SelectOnePulseMode(hwtimer_dev->periph, TIM_OPMode_Repetitive);
147 }
148
149 TIM_Cmd(hwtimer_dev->periph, ENABLE);
150
151 LOG_D("%s start, cnt = %d", hwtimer_dev->name, cnt);
152
153 return RT_EOK;
154 }
155
ch32f1_hwtimer_stop(struct rt_hwtimer_device * device)156 static void ch32f1_hwtimer_stop(struct rt_hwtimer_device *device)
157 {
158 struct hwtimer_device *hwtimer_dev;
159
160 RT_ASSERT(device != RT_NULL);
161
162 hwtimer_dev = (struct hwtimer_device *)device;
163
164 TIM_Cmd(hwtimer_dev->periph, DISABLE);
165
166 TIM_SetCounter(hwtimer_dev->periph, 0);
167 }
168
ch32f1_hwtimer_counter_get(struct rt_hwtimer_device * device)169 static rt_uint32_t ch32f1_hwtimer_counter_get(struct rt_hwtimer_device *device)
170 {
171 struct hwtimer_device *hwtimer_dev;
172
173 RT_ASSERT(device != RT_NULL);
174
175 hwtimer_dev = (struct hwtimer_device *)device;
176
177 return hwtimer_dev->periph->CNT;
178 }
179
ch32f1_hwtimer_control(struct rt_hwtimer_device * device,rt_uint32_t cmd,void * arg)180 static rt_err_t ch32f1_hwtimer_control(struct rt_hwtimer_device *device, rt_uint32_t cmd, void *arg)
181 {
182 struct hwtimer_device *hwtimer_dev;
183 rt_err_t result = RT_EOK;
184
185 RT_ASSERT(device != RT_NULL);
186
187 hwtimer_dev = (struct hwtimer_device *)device;
188
189 switch (cmd)
190 {
191 case HWTIMER_CTRL_FREQ_SET:
192 {
193 rt_uint32_t freq = 0;
194 rt_uint32_t clk = 0;
195 rt_uint16_t prescaler_value = 0;
196
197 /*
198 * (1 / freq) = (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
199 */
200 if (arg != RT_NULL)
201 {
202
203 freq = *((rt_uint32_t *)arg);
204
205 clk = ch32f1_tim_clock_get(hwtimer_dev->periph);
206
207 prescaler_value = (rt_uint16_t)(clk / freq) - 1;
208
209 TIM_PrescalerConfig(hwtimer_dev->periph, prescaler_value, TIM_PSCReloadMode_Immediate);
210 }
211 else
212 {
213 result = -RT_EINVAL;
214 }
215 }
216 break;
217
218 default:
219 result = -RT_ENOSYS;
220 break;
221 }
222
223 return result;
224 }
225
226 static const struct rt_hwtimer_ops hwtimer_ops =
227 {
228 .init = ch32f1_hwtimer_init,
229 .start = ch32f1_hwtimer_start,
230 .stop = ch32f1_hwtimer_stop,
231 .count_get = ch32f1_hwtimer_counter_get,
232 .control = ch32f1_hwtimer_control,
233 };
234
rt_hw_hwtimer_init(void)235 static int rt_hw_hwtimer_init(void)
236 {
237 rt_err_t ret;
238 struct rt_hwtimer_info *hwtimer_info;
239
240 #ifdef BSP_USING_TIM1_HWTIMER
241 hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_device1.periph);
242 hwtimer_device1.parent.info = hwtimer_info;
243 hwtimer_device1.parent.ops = &hwtimer_ops;
244 ret = rt_device_hwtimer_register(&hwtimer_device1.parent, hwtimer_device1.name, RT_NULL);
245 if (ret == RT_EOK)
246 {
247 LOG_D("hwtimer: %s register success.", hwtimer_device1.name);
248 }
249 else
250 {
251 LOG_D("hwtimer: %s register failed.", hwtimer_device1.name);
252 }
253 #endif
254
255 #ifdef BSP_USING_TIM2_HWTIMER
256 hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_device2.periph);
257 hwtimer_device2.parent.info = hwtimer_info;
258 hwtimer_device2.parent.ops = &hwtimer_ops;
259 ret = rt_device_hwtimer_register(&hwtimer_device2.parent, hwtimer_device2.name, RT_NULL);
260 if (ret == RT_EOK)
261 {
262 LOG_D("hwtimer: %s register success.", hwtimer_device2.name);
263 }
264 else
265 {
266 LOG_D("hwtimer: %s register failed.", hwtimer_device2.name);
267 }
268 #endif
269
270 #ifdef BSP_USING_TIM3_HWTIMER
271 hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_device3.periph);
272 hwtimer_device3.parent.info = hwtimer_info;
273 hwtimer_device3.parent.ops = &hwtimer_ops;
274 ret = rt_device_hwtimer_register(&hwtimer_device3.parent, hwtimer_device3.name, RT_NULL);
275 if (ret == RT_EOK)
276 {
277 LOG_D("hwtimer: %s register success.", hwtimer_device3.name);
278 }
279 else
280 {
281 LOG_D("hwtimer: %s register failed.", hwtimer_device3.name);
282 }
283 #endif
284
285 #ifdef BSP_USING_TIM4_HWTIMER
286 hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_device4.periph);
287 hwtimer_device4.parent.info = hwtimer_info;
288 hwtimer_device4.parent.ops = &hwtimer_ops;
289 ret = rt_device_hwtimer_register(&hwtimer_device4.parent, hwtimer_device4.name, RT_NULL);
290 if (ret == RT_EOK)
291 {
292 LOG_D("hwtimer: %s register success.", hwtimer_device4.name);
293 }
294 else
295 {
296 LOG_D("hwtimer: %s register failed.", hwtimer_device4.name);
297 }
298 #endif
299
300 return RT_EOK;
301 }
302 INIT_DEVICE_EXPORT(rt_hw_hwtimer_init);
303
304 #ifdef BSP_USING_TIM1_HWTIMER
TIM1_UP_IRQHandler(void)305 void TIM1_UP_IRQHandler(void)
306 {
307 /* enter interrupt */
308 rt_interrupt_enter();
309
310 if (TIM_GetITStatus(hwtimer_device1.periph, TIM_IT_Update) == SET)
311 {
312 TIM_ClearITPendingBit(hwtimer_device1.periph, TIM_IT_Update);
313 rt_device_hwtimer_isr(&hwtimer_device1.parent);
314 }
315 /* leave interrupt */
316 rt_interrupt_leave();
317 }
318 #endif
319
320 #ifdef BSP_USING_TIM2_HWTIMER
TIM2_IRQHandler(void)321 void TIM2_IRQHandler(void)
322 {
323 /* enter interrupt */
324 rt_interrupt_enter();
325
326 if (TIM_GetITStatus(hwtimer_device2.periph, TIM_IT_Update) == SET)
327 {
328 TIM_ClearITPendingBit(hwtimer_device2.periph, TIM_IT_Update);
329 rt_device_hwtimer_isr(&hwtimer_device2.parent);
330 }
331 /* leave interrupt */
332 rt_interrupt_leave();
333 }
334 #endif
335
336 #ifdef BSP_USING_TIM3_HWTIMER
TIM3_IRQHandler(void)337 void TIM3_IRQHandler(void)
338 {
339 /* enter interrupt */
340 rt_interrupt_enter();
341
342 if (TIM_GetITStatus(hwtimer_device3.periph, TIM_IT_Update) == SET)
343 {
344 TIM_ClearITPendingBit(hwtimer_device3.periph, TIM_IT_Update);
345 rt_device_hwtimer_isr(&hwtimer_device3.parent);
346 }
347 /* leave interrupt */
348 rt_interrupt_leave();
349 }
350 #endif
351
352 #ifdef BSP_USING_TIM4_HWTIMER
TIM4_IRQHandler(void)353 void TIM4_IRQHandler(void)
354 {
355 /* enter interrupt */
356 rt_interrupt_enter();
357
358 if (TIM_GetITStatus(hwtimer_device4.periph, TIM_IT_Update) == SET)
359 {
360 TIM_ClearITPendingBit(hwtimer_device4.periph, TIM_IT_Update);
361 rt_device_hwtimer_isr(&hwtimer_device4.parent);
362 }
363 /* leave interrupt */
364 rt_interrupt_leave();
365 }
366 #endif
367
368 #endif /* BSP_USING_HWTIMER */
369