Skip to content

Commit 38154c4

Browse files
authored
add hwtimer device (#6230)
1 parent 77067f8 commit 38154c4

File tree

5 files changed

+429
-0
lines changed

5 files changed

+429
-0
lines changed

bsp/cypress/libraries/HAL_Drivers/SConscript

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ if GetDepend('BSP_USING_ON_CHIP_FLASH'):
4646

4747
if GetDepend(['RT_USING_WDT']):
4848
src += ['drv_wdt.c']
49+
50+
if GetDepend(['BSP_USING_TIM']):
51+
src += ['drv_hwtimer.c']
4952

5053
path = [cwd]
5154
path += [cwd + '/config']
Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
/*
2+
* Copyright (c) 2006-2022, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2022-07-29 rtthread qiu first version
9+
*/
10+
#include "drv_common.h"
11+
#include "drv_hwtimer.h"
12+
13+
#include <board.h>
14+
#ifdef BSP_USING_TIM
15+
16+
//#define DRV_DEBUG
17+
#define LOG_TAG "drv.hwtimer"
18+
#include <drv_log.h>
19+
static void isr_timer(void *callback_arg, cyhal_timer_event_t event);
20+
21+
#ifdef RT_USING_HWTIMER
22+
enum
23+
{
24+
#ifdef BSP_USING_TIM1
25+
TIM1_INDEX,
26+
#endif
27+
#ifdef BSP_USING_TIM2
28+
TIM2_INDEX,
29+
#endif
30+
};
31+
32+
struct cyp_hwtimer
33+
{
34+
rt_hwtimer_t time_device;
35+
cyhal_timer_t tim_handle;
36+
IRQn_Type tim_irqn;
37+
char *name;
38+
};
39+
40+
static struct cyp_hwtimer cyp_hwtimer_obj[] =
41+
{
42+
#ifdef BSP_USING_TIM1
43+
TIM1_CONFIG,
44+
#endif
45+
#ifdef BSP_USING_TIM2
46+
TIM2_CONFIG,
47+
#endif
48+
};
49+
50+
static void timer_init(rt_hwtimer_t *timer, rt_uint32_t state)
51+
{
52+
RT_ASSERT(timer != RT_NULL);
53+
54+
cy_rslt_t result = RT_EOK;
55+
56+
cyhal_timer_t *tim = RT_NULL;
57+
58+
tim = (cyhal_timer_t *)timer->parent.user_data;
59+
60+
const cyhal_timer_cfg_t init_timer_cfg =
61+
{
62+
.compare_value = 0, /* Timer compare value, not used */
63+
.period = 9999, /* Defines the timer period */
64+
.direction = CYHAL_TIMER_DIR_UP, /* Timer counts up */
65+
.is_compare = false, /* Don't use compare mode */
66+
.is_continuous = true, /* Run timer indefinitely */
67+
.value = 0 /* Initial value of counter */
68+
};
69+
70+
if (state)
71+
{
72+
/* Initialize the timer object. Does not use input pin ('pin' is NC) and
73+
* does not use a pre-configured clock source ('clk' is NULL). */
74+
result = cyhal_timer_init(tim, NC, NULL);
75+
76+
if (result != CY_RSLT_SUCCESS)
77+
{
78+
LOG_E("timer init error \r\n");
79+
return;
80+
}
81+
else
82+
{
83+
/* Configure timer period and operation mode such as count direction,
84+
duration */
85+
cyhal_timer_configure(tim, &init_timer_cfg);
86+
87+
/* Set the frequency of timer's clock source */
88+
cyhal_timer_set_frequency(tim, 10000);
89+
90+
cyhal_timer_start(tim);
91+
}
92+
}
93+
else
94+
{
95+
cyhal_timer_free(tim);
96+
LOG_E("free time \r\n");
97+
}
98+
}
99+
100+
static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
101+
{
102+
RT_ASSERT(timer != RT_NULL);
103+
RT_ASSERT(opmode != RT_NULL);
104+
105+
cy_rslt_t result = RT_EOK;
106+
107+
cyhal_timer_t *tim = RT_NULL;
108+
109+
tim = (cyhal_timer_t *)timer->parent.user_data;
110+
111+
const cyhal_timer_cfg_t init_timer_cfg =
112+
{
113+
.compare_value = 0, /* Timer compare value, not used */
114+
.period = t - 1, /* Defines the timer period */
115+
.direction = CYHAL_TIMER_DIR_UP, /* Timer counts up */
116+
.is_compare = false, /* Don't use compare mode */
117+
.is_continuous = true, /* Run timer indefinitely */
118+
.value = 0 /* Initial value of counter */
119+
};
120+
/* Configure timer period and operation mode such as count direction,
121+
duration */
122+
cyhal_timer_configure(tim, &init_timer_cfg);
123+
124+
if (opmode == HWTIMER_MODE_ONESHOT)
125+
{
126+
/* set timer to single mode */
127+
cyhal_timer_stop(tim);
128+
}
129+
else
130+
{
131+
cyhal_timer_reset(tim);
132+
}
133+
134+
result = cyhal_timer_start(tim);
135+
if (result != CY_RSLT_SUCCESS)
136+
{
137+
LOG_E("time start error\r\n");
138+
cyhal_timer_free(tim);
139+
}
140+
141+
/* Assign the ISR to execute on timer interrupt */
142+
cyhal_timer_register_callback(tim, isr_timer, NULL);
143+
/* Set the event on which timer interrupt occurs and enable it */
144+
cyhal_timer_enable_event(tim, CYHAL_TIMER_IRQ_TERMINAL_COUNT, 1, true);
145+
146+
return result;
147+
}
148+
149+
static void timer_stop(rt_hwtimer_t *timer)
150+
{
151+
152+
RT_ASSERT(timer != RT_NULL);
153+
154+
cyhal_timer_t *tim = RT_NULL;
155+
156+
tim = (cyhal_timer_t *)timer->parent.user_data;
157+
158+
cyhal_timer_stop(tim);
159+
}
160+
161+
static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer)
162+
{
163+
cyhal_timer_t *tim = RT_NULL;
164+
165+
rt_uint32_t count;
166+
167+
RT_ASSERT(timer != RT_NULL);
168+
169+
tim = (cyhal_timer_t *)timer->parent.user_data;
170+
171+
count = cyhal_timer_read(tim);
172+
173+
return count;
174+
}
175+
176+
static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
177+
{
178+
RT_ASSERT(timer != RT_NULL);
179+
RT_ASSERT(arg != RT_NULL);
180+
181+
cyhal_timer_t *tim = RT_NULL;
182+
183+
rt_err_t result = -RT_ERROR;
184+
185+
tim = (cyhal_timer_t *)timer->parent.user_data;
186+
187+
switch (cmd)
188+
{
189+
case HWTIMER_CTRL_FREQ_SET:
190+
{
191+
rt_uint32_t freq;
192+
rt_uint16_t val;
193+
194+
freq = *((rt_uint32_t *)arg);
195+
196+
result = cyhal_timer_set_frequency(tim, freq);
197+
198+
if (result != CY_RSLT_SUCCESS)
199+
{
200+
LOG_E("cyhal_timer_set_frequency error\r\n");
201+
return RT_ERROR;
202+
}
203+
}
204+
break;
205+
default:
206+
{
207+
result = -RT_EINVAL;
208+
}
209+
break;
210+
}
211+
return result;
212+
}
213+
214+
static const struct rt_hwtimer_info _info = TIM_DEV_INFO_CONFIG;
215+
216+
static const struct rt_hwtimer_ops _ops =
217+
{
218+
.init = timer_init,
219+
.start = timer_start,
220+
.stop = timer_stop,
221+
.count_get = timer_counter_get,
222+
.control = timer_ctrl,
223+
};
224+
225+
#ifdef BSP_USING_TIM1
226+
static void isr_timer(void *callback_arg, cyhal_timer_event_t event)
227+
{
228+
/* enter interrupt */
229+
rt_interrupt_enter();
230+
231+
(void)callback_arg;
232+
(void)event;
233+
234+
rt_device_hwtimer_isr(&cyp_hwtimer_obj[TIM1_INDEX].time_device);
235+
236+
/* leave interrupt */
237+
rt_interrupt_leave();
238+
}
239+
#endif
240+
#ifdef BSP_USING_TIM2
241+
static void isr_timer(void *callback_arg, cyhal_timer_event_t event)
242+
{
243+
/* enter interrupt */
244+
rt_interrupt_enter();
245+
246+
(void)callback_arg;
247+
(void)event;
248+
249+
rt_device_hwtimer_isr(&cyp_hwtimer_obj[TIM2_INDEX].time_device);
250+
251+
/* leave interrupt */
252+
rt_interrupt_leave();
253+
}
254+
#endif
255+
256+
int cyp_hwtimer_init(void)
257+
{
258+
int i = 0;
259+
int result = RT_EOK;
260+
261+
for (i = 0; i < sizeof(cyp_hwtimer_obj) / sizeof(cyp_hwtimer_obj[0]); i++)
262+
{
263+
cyp_hwtimer_obj[i].time_device.info = &_info;
264+
cyp_hwtimer_obj[i].time_device.ops = &_ops;
265+
if (rt_device_hwtimer_register(&cyp_hwtimer_obj[i].time_device, cyp_hwtimer_obj[i].name, &cyp_hwtimer_obj[i].tim_handle) != RT_EOK)
266+
{
267+
LOG_E("%s register failed", cyp_hwtimer_obj[i].name);
268+
result = -RT_ERROR;
269+
}
270+
}
271+
return result;
272+
}
273+
INIT_BOARD_EXPORT(cyp_hwtimer_init);
274+
275+
#endif /*RT_USING_HWTIMER*/
276+
#endif /*BSP_USING_TIM*/
277+
278+
/* this is a hwtimer test demo*/
279+
#include <rtthread.h>
280+
#include <rtdevice.h>
281+
282+
#define HWTIMER_DEV_NAME "time2" /* device name */
283+
284+
static rt_err_t timeout_cb(rt_device_t dev, rt_size_t size)
285+
{
286+
rt_kprintf("this is hwtimer timeout callback fucntion!\n");
287+
rt_kprintf("tick is :%d !\n", rt_tick_get());
288+
289+
return 0;
290+
}
291+
292+
int hwtimer_sample()
293+
{
294+
rt_err_t ret = RT_EOK;
295+
rt_hwtimerval_t timeout_s;
296+
rt_device_t hw_dev = RT_NULL;
297+
rt_hwtimer_mode_t mode;
298+
rt_uint32_t freq = 10000;
299+
300+
hw_dev = rt_device_find(HWTIMER_DEV_NAME);
301+
if (hw_dev == RT_NULL)
302+
{
303+
rt_kprintf("hwtimer sample run failed! can't find %s device!\n", HWTIMER_DEV_NAME);
304+
return RT_ERROR;
305+
}
306+
307+
ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR);
308+
if (ret != RT_EOK)
309+
{
310+
rt_kprintf("open %s device failed!\n", HWTIMER_DEV_NAME);
311+
return ret;
312+
}
313+
314+
rt_device_set_rx_indicate(hw_dev, timeout_cb);
315+
316+
rt_device_control(hw_dev, HWTIMER_CTRL_FREQ_SET, &freq);
317+
318+
mode = HWTIMER_MODE_PERIOD;
319+
ret = rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, &mode);
320+
if (ret != RT_EOK)
321+
{
322+
rt_kprintf("set mode failed! ret is :%d\n", ret);
323+
return ret;
324+
}
325+
326+
/* Example Set the timeout period of the timer */
327+
timeout_s.sec = 3; /* secend */
328+
timeout_s.usec = 0; /* microsecend */
329+
if (rt_device_write(hw_dev, 0, &timeout_s, sizeof(timeout_s)) != sizeof(timeout_s))
330+
{
331+
rt_kprintf("set timeout value failed\n");
332+
return RT_ERROR;
333+
}
334+
335+
while (1)
336+
{
337+
rt_thread_mdelay(1500);
338+
339+
rt_device_read(hw_dev, 0, &timeout_s, sizeof(timeout_s));
340+
rt_kprintf("Read: Sec = %d, Usec = %d\n", timeout_s.sec, timeout_s.usec);
341+
}
342+
return ret;
343+
}
344+
MSH_CMD_EXPORT(hwtimer_sample, hwtimer sample);

0 commit comments

Comments
 (0)