Skip to content

Commit

Permalink
[bsp][pico] add hwtimer driver
Browse files Browse the repository at this point in the history
  • Loading branch information
Z8MAN8 committed Oct 30, 2023
1 parent 1554888 commit eb766c1
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 0 deletions.
22 changes: 22 additions & 0 deletions bsp/raspberry-pico/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,28 @@ menu "On-chip Peripheral Drivers"
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
bool "Enable I2C"
select RT_USING_I2C
Expand Down
3 changes: 3 additions & 0 deletions bsp/raspberry-pico/drivers/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ if GetDepend('BSP_USING_ON_CHIP_FLASH'):
if GetDepend('BSP_USING_PWM'):
src += ['drv_pwm.c']

if GetDepend('BSP_USING_HWTIMER'):
src += ['drv_hwtimer.c']

group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)

Return('group')
167 changes: 167 additions & 0 deletions bsp/raspberry-pico/drivers/drv_hwtimer.c
Original file line number Diff line number Diff line change
@@ -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 */
17 changes: 17 additions & 0 deletions bsp/raspberry-pico/drivers/drv_hwtimer.h
Original file line number Diff line number Diff line change
@@ -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 */

0 comments on commit eb766c1

Please sign in to comment.