Skip to content

Commit 8411176

Browse files
committed
[bsp/wch/arm/Libraries/ch32_drivers]: support ch32f10x hwtimer.
[bsp/wch/arm/ch32f103c8-core]: add hwtimer1~4.
1 parent 7aa4dfe commit 8411176

File tree

5 files changed

+637
-0
lines changed

5 files changed

+637
-0
lines changed

bsp/wch/arm/Libraries/ch32_drivers/SConscript

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ if GetDepend('SOC_ARM_SERIES_CH32F103'):
2929
if GetDepend(['RT_USING_WDT', 'BSP_USING_IWDT']):
3030
src += ['drv_iwdt_ch32f10x.c']
3131

32+
if GetDepend(['RT_USING_HWTIMER', 'BSP_USING_HWTIMER']):
33+
src += ['drv_hwtimer_ch32f10x.c']
34+
3235
src += ['drv_common.c']
3336

3437
path = [cwd]
Lines changed: 372 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,372 @@
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+
* 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+
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_hwtimer_clock_init(hwtimer_dev->periph);
77+
78+
hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_dev->periph);
79+
80+
clk = ch32f1_hwtimer_clock_get(hwtimer_dev->periph);
81+
82+
prescaler_value = (rt_uint16_t)(clk / hwtimer_info->minfreq) - 1;
83+
84+
/*
85+
* set interrupt callback one or each time need total time =
86+
* (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
87+
*/
88+
89+
TIM_TimeBaseInitType.TIM_Period = hwtimer_info->maxcnt - 1;
90+
TIM_TimeBaseInitType.TIM_Prescaler = prescaler_value;
91+
TIM_TimeBaseInitType.TIM_ClockDivision = TIM_CKD_DIV1;
92+
TIM_TimeBaseInitType.TIM_RepetitionCounter = 0;
93+
94+
if (hwtimer_info == RT_NULL)
95+
{
96+
TIM_TimeBaseInitType.TIM_CounterMode = TIM_CounterMode_Up;
97+
}
98+
else
99+
{
100+
if (hwtimer_info->cntmode == HWTIMER_CNTMODE_UP)
101+
{
102+
TIM_TimeBaseInitType.TIM_CounterMode = TIM_CounterMode_Up;
103+
}
104+
else
105+
{
106+
TIM_TimeBaseInitType.TIM_CounterMode = TIM_CounterMode_Down;
107+
}
108+
}
109+
110+
TIM_TimeBaseInit(hwtimer_dev->periph, &TIM_TimeBaseInitType);
111+
112+
NVIC_InitStructure.NVIC_IRQChannel = hwtimer_dev->irqn;
113+
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
114+
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
115+
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
116+
NVIC_Init(&NVIC_InitStructure);
117+
118+
TIM_ITConfig(hwtimer_dev->periph, TIM_IT_Update, ENABLE);
119+
TIM_ClearITPendingBit(hwtimer_dev->periph, TIM_IT_Update);
120+
121+
LOG_D("%s init success", hwtimer_dev->name);
122+
}
123+
}
124+
125+
static rt_err_t ch32f1_hwtimer_start(struct rt_hwtimer_device *device, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
126+
{
127+
128+
struct hwtimer_device *hwtimer_dev;
129+
130+
RT_ASSERT(device != RT_NULL);
131+
132+
hwtimer_dev = (struct hwtimer_device *)device;
133+
134+
/*
135+
* interrupt callback one or each time need total time =
136+
* (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
137+
*/
138+
139+
TIM_SetCounter(hwtimer_dev->periph, 0);
140+
TIM_SetAutoreload(hwtimer_dev->periph, cnt - 1);
141+
142+
if (mode == HWTIMER_MODE_ONESHOT)
143+
{
144+
TIM_SelectOnePulseMode(hwtimer_dev->periph, TIM_OPMode_Single);
145+
}
146+
else
147+
{
148+
TIM_SelectOnePulseMode(hwtimer_dev->periph, TIM_OPMode_Repetitive);
149+
}
150+
151+
TIM_Cmd(hwtimer_dev->periph, ENABLE);
152+
153+
LOG_D("%s start, cnt = %d", hwtimer_dev->name, cnt);
154+
155+
return RT_EOK;
156+
}
157+
158+
static void ch32f1_hwtimer_stop(struct rt_hwtimer_device *device)
159+
{
160+
struct hwtimer_device *hwtimer_dev;
161+
162+
RT_ASSERT(device != RT_NULL);
163+
164+
hwtimer_dev = (struct hwtimer_device *)device;
165+
166+
TIM_Cmd(hwtimer_dev->periph, DISABLE);
167+
168+
TIM_SetCounter(hwtimer_dev->periph, 0);
169+
}
170+
171+
static rt_uint32_t ch32f1_hwtimer_counter_get(struct rt_hwtimer_device *device)
172+
{
173+
struct hwtimer_device *hwtimer_dev;
174+
175+
RT_ASSERT(device != RT_NULL);
176+
177+
hwtimer_dev = (struct hwtimer_device *)device;
178+
179+
return hwtimer_dev->periph->CNT;
180+
}
181+
182+
static rt_err_t ch32f1_hwtimer_control(struct rt_hwtimer_device *device, rt_uint32_t cmd, void *arg)
183+
{
184+
struct hwtimer_device *hwtimer_dev;
185+
rt_err_t result = RT_EOK;
186+
187+
RT_ASSERT(device != RT_NULL);
188+
189+
hwtimer_dev = (struct hwtimer_device *)device;
190+
191+
switch (cmd)
192+
{
193+
case HWTIMER_CTRL_FREQ_SET:
194+
{
195+
rt_uint32_t freq = 0;
196+
rt_uint32_t clk = 0;
197+
rt_uint16_t prescaler_value = 0;
198+
199+
/*
200+
*set interrupt callback one or each time need total time =
201+
* (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
202+
*/
203+
if (arg != RT_NULL)
204+
{
205+
206+
freq = *((rt_uint32_t *)arg);
207+
208+
clk = ch32f1_hwtimer_clock_get(hwtimer_dev->periph);
209+
210+
prescaler_value = (rt_uint16_t)(clk / freq) - 1;
211+
212+
TIM_PrescalerConfig(hwtimer_dev->periph, prescaler_value, TIM_PSCReloadMode_Immediate);
213+
}
214+
else
215+
{
216+
result = RT_EINVAL;
217+
}
218+
}
219+
break;
220+
221+
default:
222+
result = RT_ENOSYS;
223+
break;
224+
}
225+
226+
return result;
227+
}
228+
229+
static const struct rt_hwtimer_ops hwtimer_ops =
230+
{
231+
.init = ch32f1_hwtimer_init,
232+
.start = ch32f1_hwtimer_start,
233+
.stop = ch32f1_hwtimer_stop,
234+
.count_get = ch32f1_hwtimer_counter_get,
235+
.control = ch32f1_hwtimer_control,
236+
};
237+
238+
static int rt_hw_hwtimer_init(void)
239+
{
240+
rt_err_t ret;
241+
struct rt_hwtimer_info *hwtimer_info;
242+
243+
#ifdef BSP_USING_TIM1_HWTIMER
244+
hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_device1.periph);
245+
hwtimer_device1.parent.info = hwtimer_info;
246+
hwtimer_device1.parent.ops = &hwtimer_ops;
247+
ret = rt_device_hwtimer_register(&hwtimer_device1.parent, hwtimer_device1.name, RT_NULL);
248+
if (ret == RT_EOK)
249+
{
250+
LOG_D("hwtimer: %s register success.", hwtimer_device1.name);
251+
}
252+
else
253+
{
254+
LOG_D("hwtimer: %s register failed.", hwtimer_device1.name);
255+
}
256+
#endif
257+
258+
#ifdef BSP_USING_TIM2_HWTIMER
259+
hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_device2.periph);
260+
hwtimer_device2.parent.info = hwtimer_info;
261+
hwtimer_device2.parent.ops = &hwtimer_ops;
262+
ret = rt_device_hwtimer_register(&hwtimer_device2.parent, hwtimer_device2.name, RT_NULL);
263+
if (ret == RT_EOK)
264+
{
265+
LOG_D("hwtimer: %s register success.", hwtimer_device2.name);
266+
}
267+
else
268+
{
269+
LOG_D("hwtimer: %s register failed.", hwtimer_device2.name);
270+
}
271+
#endif
272+
273+
#ifdef BSP_USING_TIM3_HWTIMER
274+
hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_device3.periph);
275+
hwtimer_device3.parent.info = hwtimer_info;
276+
hwtimer_device3.parent.ops = &hwtimer_ops;
277+
ret = rt_device_hwtimer_register(&hwtimer_device3.parent, hwtimer_device3.name, RT_NULL);
278+
if (ret == RT_EOK)
279+
{
280+
LOG_D("hwtimer: %s register success.", hwtimer_device3.name);
281+
}
282+
else
283+
{
284+
LOG_D("hwtimer: %s register failed.", hwtimer_device3.name);
285+
}
286+
#endif
287+
288+
#ifdef BSP_USING_TIM4_HWTIMER
289+
hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_device4.periph);
290+
hwtimer_device4.parent.info = hwtimer_info;
291+
hwtimer_device4.parent.ops = &hwtimer_ops;
292+
ret = rt_device_hwtimer_register(&hwtimer_device4.parent, hwtimer_device4.name, RT_NULL);
293+
if (ret == RT_EOK)
294+
{
295+
LOG_D("hwtimer: %s register success.", hwtimer_device4.name);
296+
}
297+
else
298+
{
299+
LOG_D("hwtimer: %s register failed.", hwtimer_device4.name);
300+
}
301+
#endif
302+
303+
return RT_EOK;
304+
}
305+
INIT_DEVICE_EXPORT(rt_hw_hwtimer_init);
306+
307+
#ifdef BSP_USING_TIM1_HWTIMER
308+
void TIM1_UP_IRQHandler(void)
309+
{
310+
/* enter interrupt */
311+
rt_interrupt_enter();
312+
313+
if (TIM_GetITStatus(hwtimer_device1.periph, TIM_IT_Update) == SET)
314+
{
315+
TIM_ClearITPendingBit(hwtimer_device1.periph, TIM_IT_Update);
316+
rt_device_hwtimer_isr(&hwtimer_device1.parent);
317+
}
318+
/* leave interrupt */
319+
rt_interrupt_leave();
320+
}
321+
#endif
322+
323+
#ifdef BSP_USING_TIM2_HWTIMER
324+
void TIM2_IRQHandler(void)
325+
{
326+
/* enter interrupt */
327+
rt_interrupt_enter();
328+
329+
if (TIM_GetITStatus(hwtimer_device2.periph, TIM_IT_Update) == SET)
330+
{
331+
TIM_ClearITPendingBit(hwtimer_device2.periph, TIM_IT_Update);
332+
rt_device_hwtimer_isr(&hwtimer_device2.parent);
333+
}
334+
/* leave interrupt */
335+
rt_interrupt_leave();
336+
}
337+
#endif
338+
339+
#ifdef BSP_USING_TIM3_HWTIMER
340+
void TIM3_IRQHandler(void)
341+
{
342+
/* enter interrupt */
343+
rt_interrupt_enter();
344+
345+
if (TIM_GetITStatus(hwtimer_device3.periph, TIM_IT_Update) == SET)
346+
{
347+
TIM_ClearITPendingBit(hwtimer_device3.periph, TIM_IT_Update);
348+
rt_device_hwtimer_isr(&hwtimer_device3.parent);
349+
}
350+
/* leave interrupt */
351+
rt_interrupt_leave();
352+
}
353+
#endif
354+
355+
#ifdef BSP_USING_TIM4_HWTIMER
356+
void TIM4_IRQHandler(void)
357+
{
358+
/* enter interrupt */
359+
rt_interrupt_enter();
360+
361+
if (TIM_GetITStatus(hwtimer_device4.periph, TIM_IT_Update) == SET)
362+
{
363+
TIM_ClearITPendingBit(hwtimer_device4.periph, TIM_IT_Update);
364+
rt_device_hwtimer_isr(&hwtimer_device4.parent);
365+
}
366+
/* leave interrupt */
367+
rt_interrupt_leave();
368+
}
369+
#endif
370+
371+
#endif /* BSP_USING_HWTIMER */
372+

0 commit comments

Comments
 (0)