summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZ8MAN8 <[email protected]>2023-10-30 16:20:14 +0800
committerMeco Man <[email protected]>2023-10-31 08:58:09 -0400
commita64ccaa295373ddc8c506d1f37c90ad294f53fbe (patch)
treedac32f6b57606a463676c5e21ab3b5b0365c3cdb
parent7ace7d0a788f3799fecc913396b049ced9b10baf (diff)
[bsp][pico] add hwtimer driver
-rw-r--r--bsp/raspberry-pico/Kconfig22
-rw-r--r--bsp/raspberry-pico/drivers/SConscript3
-rw-r--r--bsp/raspberry-pico/drivers/drv_hwtimer.c167
-rw-r--r--bsp/raspberry-pico/drivers/drv_hwtimer.h17
4 files changed, 209 insertions, 0 deletions
diff --git a/bsp/raspberry-pico/Kconfig b/bsp/raspberry-pico/Kconfig
index 1e61d7ce03..2645d78f9f 100644
--- a/bsp/raspberry-pico/Kconfig
+++ b/bsp/raspberry-pico/Kconfig
@@ -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
diff --git a/bsp/raspberry-pico/drivers/SConscript b/bsp/raspberry-pico/drivers/SConscript
index a05cd2aed2..2b92315914 100644
--- a/bsp/raspberry-pico/drivers/SConscript
+++ b/bsp/raspberry-pico/drivers/SConscript
@@ -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')
diff --git a/bsp/raspberry-pico/drivers/drv_hwtimer.c b/bsp/raspberry-pico/drivers/drv_hwtimer.c
new file mode 100644
index 0000000000..b431f163a8
--- /dev/null
+++ b/bsp/raspberry-pico/drivers/drv_hwtimer.c
@@ -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 */
diff --git a/bsp/raspberry-pico/drivers/drv_hwtimer.h b/bsp/raspberry-pico/drivers/drv_hwtimer.h
new file mode 100644
index 0000000000..e84eb568cf
--- /dev/null
+++ b/bsp/raspberry-pico/drivers/drv_hwtimer.h
@@ -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 */