[bsp][pico] add hwtimer driver
This commit is contained in:
parent
7ace7d0a78
commit
a64ccaa295
|
@ -397,6 +397,28 @@ menu "On-chip Peripheral Drivers"
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
menuconfig BSP_USING_HWTIMER
|
||||||
|
bool "Enable HWTIMER"
|
||||||
|
default n
|
||||||
|
select RT_USING_HWTIMER
|
||||||
|
if BSP_USING_HWTIMER
|
||||||
|
config BSP_USING_TIMER0
|
||||||
|
bool "Enable HWTIMER0"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config BSP_USING_TIMER1
|
||||||
|
bool "Enable HWTIMER1"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config BSP_USING_TIMER2
|
||||||
|
bool "Enable HWTIMER2"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config BSP_USING_TIMER3
|
||||||
|
bool "Enable HWTIMER3"
|
||||||
|
default n
|
||||||
|
endif
|
||||||
|
|
||||||
menuconfig BSP_USING_I2C
|
menuconfig BSP_USING_I2C
|
||||||
bool "Enable I2C"
|
bool "Enable I2C"
|
||||||
select RT_USING_I2C
|
select RT_USING_I2C
|
||||||
|
|
|
@ -34,6 +34,9 @@ if GetDepend('BSP_USING_ON_CHIP_FLASH'):
|
||||||
if GetDepend('BSP_USING_PWM'):
|
if GetDepend('BSP_USING_PWM'):
|
||||||
src += ['drv_pwm.c']
|
src += ['drv_pwm.c']
|
||||||
|
|
||||||
|
if GetDepend('BSP_USING_HWTIMER'):
|
||||||
|
src += ['drv_hwtimer.c']
|
||||||
|
|
||||||
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
|
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
Return('group')
|
Return('group')
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2023-10-30 ChuShicheng first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "drv_hwtimer.h"
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER
|
||||||
|
|
||||||
|
#define DBG_LEVEL DBG_LOG
|
||||||
|
#include <rtdbg.h>
|
||||||
|
#define LOG_TAG "DRV.HWTIMER"
|
||||||
|
|
||||||
|
typedef struct _timer
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
struct repeating_timer repeat_timer;
|
||||||
|
alarm_id_t alarm_id;
|
||||||
|
rt_hwtimer_t timer;
|
||||||
|
}_timer_t;
|
||||||
|
|
||||||
|
static void _hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state);
|
||||||
|
static rt_err_t _hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode);
|
||||||
|
static void _hwtimer_stop(rt_hwtimer_t *timer);
|
||||||
|
static rt_uint32_t _hwtimer_count_get(rt_hwtimer_t *timer);
|
||||||
|
static rt_err_t _hwtimer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args);
|
||||||
|
static int64_t _hwtmr_isr(alarm_id_t id, void *user_data);
|
||||||
|
|
||||||
|
static const struct rt_hwtimer_ops _hwtimer_ops = {
|
||||||
|
.init = _hwtimer_init,
|
||||||
|
.start = _hwtimer_start,
|
||||||
|
.stop = _hwtimer_stop,
|
||||||
|
.count_get = _hwtimer_count_get,
|
||||||
|
.control = _hwtimer_control
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rt_hwtimer_info _hwtimer_info = {
|
||||||
|
.maxfreq = 1000000UL,
|
||||||
|
.minfreq = 1000000UL,
|
||||||
|
.maxcnt = 0xFFFF,
|
||||||
|
.cntmode = HWTIMER_MODE_PERIOD
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef BSP_USING_TIMER0
|
||||||
|
static _timer_t timer0 = {.name = "timer0"};
|
||||||
|
#endif /* BSP_USING_TIMER0 */
|
||||||
|
#ifdef BSP_USING_TIMER1
|
||||||
|
static _timer_t timer1 = {.name = "timer1" };
|
||||||
|
#endif /* BSP_USING_TIMER1 */
|
||||||
|
#ifdef BSP_USING_TIMER2
|
||||||
|
static _timer_t timer0 = {.name = "timer2"};
|
||||||
|
#endif /* BSP_USING_TIMER2 */
|
||||||
|
#ifdef BSP_USING_TIMER3
|
||||||
|
static _timer_t timer1 = {.name = "timer3" };
|
||||||
|
#endif /* BSP_USING_TIMER3 */
|
||||||
|
|
||||||
|
static _timer_t *_timer_obj[] = {
|
||||||
|
#ifdef BSP_USING_TIMER0
|
||||||
|
&timer0,
|
||||||
|
#endif /* BSP_USING_TIMER0 */
|
||||||
|
#ifdef BSP_USING_TIMER1
|
||||||
|
&timer1,
|
||||||
|
#endif /* BSP_USING_TIMER1 */
|
||||||
|
#ifdef BSP_USING_TIMER2
|
||||||
|
&timer2,
|
||||||
|
#endif /* BSP_USING_TIMER2 */
|
||||||
|
#ifdef BSP_USING_TIMER3
|
||||||
|
&timer3,
|
||||||
|
#endif /* BSP_USING_TIMER3 */
|
||||||
|
};
|
||||||
|
|
||||||
|
static int64_t _hwtmr_isr(alarm_id_t id, void *user_data)
|
||||||
|
{
|
||||||
|
_timer_t *_tmr = rt_container_of(id, _timer_t, alarm_id);
|
||||||
|
rt_device_hwtimer_isr(&_tmr->timer);
|
||||||
|
return RT_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _repeat_timer_isr(struct repeating_timer *t)
|
||||||
|
{
|
||||||
|
_timer_t *_tmr = rt_container_of(t, _timer_t, repeat_timer);
|
||||||
|
rt_device_hwtimer_isr(&_tmr->timer);
|
||||||
|
return RT_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t _hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
|
||||||
|
{
|
||||||
|
_timer_t *_tmr = rt_container_of(timer, _timer_t, timer);
|
||||||
|
|
||||||
|
if(mode == HWTIMER_MODE_ONESHOT)
|
||||||
|
_tmr->alarm_id = add_alarm_in_us(cnt, _hwtmr_isr, RT_NULL, RT_TRUE);
|
||||||
|
else
|
||||||
|
add_repeating_timer_us(cnt, _repeat_timer_isr, RT_NULL, &_tmr->repeat_timer);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _hwtimer_stop(rt_hwtimer_t *timer)
|
||||||
|
{
|
||||||
|
_timer_t *_tmr = rt_container_of(timer, _timer_t, timer);
|
||||||
|
if(timer->mode == HWTIMER_MODE_ONESHOT)
|
||||||
|
cancel_alarm(_tmr->alarm_id);
|
||||||
|
else
|
||||||
|
cancel_repeating_timer(&_tmr->repeat_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_uint32_t _hwtimer_count_get(rt_hwtimer_t *timer)
|
||||||
|
{
|
||||||
|
_timer_t *_tmr = rt_container_of(timer, _timer_t, timer);
|
||||||
|
|
||||||
|
return timer_hw->alarm[_tmr->alarm_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t _hwtimer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args)
|
||||||
|
{
|
||||||
|
rt_err_t err = RT_EOK;
|
||||||
|
_timer_t *_tmr = rt_container_of(timer, _timer_t, timer);
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case HWTIMER_CTRL_FREQ_SET:
|
||||||
|
err = -RT_ERROR;
|
||||||
|
break;
|
||||||
|
case HWTIMER_CTRL_INFO_GET:
|
||||||
|
*(rt_hwtimer_t*)args = _tmr->timer;
|
||||||
|
break;
|
||||||
|
case HWTIMER_CTRL_MODE_SET:
|
||||||
|
_tmr->timer.mode = *(rt_uint32_t*)args;
|
||||||
|
break;
|
||||||
|
case HWTIMER_CTRL_STOP:
|
||||||
|
_hwtimer_stop(timer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rt_hw_hwtimer_init(void)
|
||||||
|
{
|
||||||
|
int ret = RT_EOK;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < sizeof(_timer_obj) / sizeof(_timer_obj[0]); i++)
|
||||||
|
{
|
||||||
|
_timer_obj[i]->timer.info = &_hwtimer_info;
|
||||||
|
_timer_obj[i]->timer.ops = &_hwtimer_ops;
|
||||||
|
ret = rt_device_hwtimer_register(&_timer_obj[i]->timer, _timer_obj[i]->name, _timer_obj[i]);
|
||||||
|
if (ret != RT_EOK)
|
||||||
|
{
|
||||||
|
LOG_E("%s register failed", _timer_obj[i]->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIT_DEVICE_EXPORT(rt_hw_hwtimer_init);
|
||||||
|
#endif /* BSP_USING_HWTIMER */
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2023-10-30 ChuShicheng first version
|
||||||
|
*/
|
||||||
|
#ifndef DRV_HWTIMER_H
|
||||||
|
#define DRV_HWTIMER_H
|
||||||
|
|
||||||
|
#include <rtdevice.h>
|
||||||
|
|
||||||
|
int rt_hw_hwtimer_init(void);
|
||||||
|
|
||||||
|
#endif /* DRV_HWTIMER_H */
|
Loading…
Reference in New Issue