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