From 16074235b98a80105cdee391bff9451d7df7b624 Mon Sep 17 00:00:00 2001 From: greedyhao Date: Tue, 26 Jan 2021 16:09:35 +0800 Subject: [PATCH] [bsp][bluetrum] add hwtimer support --- bsp/bluetrum/libraries/hal_drivers/SConscript | 4 + .../libraries/hal_drivers/config/tim_config.h | 89 ++++++ .../libraries/hal_drivers/drv_hwtimer.c | 281 ++++++++++++++++++ .../ab32vg1_hal/include/ab32vg1_hal_conf.h | 5 + .../ab32vg1_hal/include/ab32vg1_hal_tim.h | 31 ++ 5 files changed, 410 insertions(+) create mode 100644 bsp/bluetrum/libraries/hal_drivers/config/tim_config.h create mode 100644 bsp/bluetrum/libraries/hal_drivers/drv_hwtimer.c create mode 100644 bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_tim.h diff --git a/bsp/bluetrum/libraries/hal_drivers/SConscript b/bsp/bluetrum/libraries/hal_drivers/SConscript index aed71ef9b1..83ceaa1ba1 100644 --- a/bsp/bluetrum/libraries/hal_drivers/SConscript +++ b/bsp/bluetrum/libraries/hal_drivers/SConscript @@ -21,6 +21,10 @@ if GetDepend('RT_USING_I2C'): if GetDepend('RT_USING_WDT'): src += ['drv_wdt.c'] + +if GetDepend('RT_USING_HWTIMER'): + src += ['drv_hwtimer.c'] + group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path) objs = [group] diff --git a/bsp/bluetrum/libraries/hal_drivers/config/tim_config.h b/bsp/bluetrum/libraries/hal_drivers/config/tim_config.h new file mode 100644 index 0000000000..c9f192a9de --- /dev/null +++ b/bsp/bluetrum/libraries/hal_drivers/config/tim_config.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020-2021, Bluetrum Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-01-22 greedyhao first version + */ + +#ifndef __TIM_CONFIG_H__ +#define __TIM_CONFIG_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef TIM_DEV_INFO_CONFIG +#define TIM_DEV_INFO_CONFIG \ + { \ + .maxfreq = 1000000, \ + .minfreq = 3000, \ + .maxcnt = 0xFFFFFFFF, \ + .cntmode = HWTIMER_CNTMODE_UP, \ + } +#endif /* TIM_DEV_INFO_CONFIG */ + +#ifdef BSP_USING_TIM1 +#ifndef TIM1_CONFIG +#define TIM1_CONFIG \ + { \ + .tim_handle = TIM1_BASE, \ + .tim_irqn = IRQ_TMR1_VECTOR, \ + .name = "timer1", \ + } +#endif /* TIM1_CONFIG */ +#endif /* BSP_USING_TIM1 */ + +#ifdef BSP_USING_TIM2 +#ifndef TIM2_CONFIG +#define TIM2_CONFIG \ + { \ + .tim_handle = TIM2_BASE, \ + .tim_irqn = IRQ_TMR2_4_5_VECTOR, \ + .name = "timer2", \ + } +#endif /* TIM1_CONFIG */ +#endif /* BSP_USING_TIM2 */ + +#ifdef BSP_USING_TIM3 +#ifndef TIM3_CONFIG +#define TIM3_CONFIG \ + { \ + .tim_handle = TIM3_BASE, \ + .tim_irqn = IRQ_IRRX_VECTOR, \ + .name = "timer3", \ + } +#endif /* TIM1_CONFIG */ +#endif /* BSP_USING_TIM3 */ + +#ifdef BSP_USING_TIM4 +#ifndef TIM4_CONFIG +#define TIM4_CONFIG \ + { \ + .tim_handle = TIM4_BASE, \ + .tim_irqn = IRQ_TMR2_4_5_VECTOR, \ + .name = "timer4", \ + } +#endif /* TIM1_CONFIG */ +#endif /* BSP_USING_TIM4 */ + +#ifdef BSP_USING_TIM5 +#ifndef TIM5_CONFIG +#define TIM5_CONFIG \ + { \ + .tim_handle = TIM5_BASE, \ + .tim_irqn = IRQ_TMR2_4_5_VECTOR, \ + .name = "timer5", \ + } +#endif /* TIM1_CONFIG */ +#endif /* BSP_USING_TIM5 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIM_CONFIG_H__ */ diff --git a/bsp/bluetrum/libraries/hal_drivers/drv_hwtimer.c b/bsp/bluetrum/libraries/hal_drivers/drv_hwtimer.c new file mode 100644 index 0000000000..bd4f463bd1 --- /dev/null +++ b/bsp/bluetrum/libraries/hal_drivers/drv_hwtimer.c @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2020-2021, Bluetrum Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-01-22 greedyhao first version + */ + +#include "board.h" +#ifdef BSP_USING_TIM +#include "tim_config.h" + +//#define DRV_DEBUG +#define LOG_TAG "drv.hwtimer" +#include + +#ifdef RT_USING_HWTIMER + +#define TIM_ENABLE BIT(0) +#define TIM_CAPTURE_ENABLE +#define TIM_INCREASE_CLOCK_SELECT +#define TIM_CAPTURE_EDGE_SELECT +#define TIM_INCREASE_SOURCE_SELECT +#define TIM_OVERFLOW_INTERRUPT_ENABLE +#define TIM_CAPTURE_INTERRUPT_ENABLE +#define TIM_PWM0_ENABLE +#define TIM_PWM1_ENABLE +#define TIM_PWM2_ENABLE +#define TIM_OVERFLOW_PEND +#define TIM_CAPTURE_PEND + +enum +{ +#ifdef BSP_USING_TIM1 + TIM1_INDEX, +#endif +#ifdef BSP_USING_TIM2 + TIM2_INDEX, +#endif +#ifdef BSP_USING_TIM3 + TIM3_INDEX, +#endif +#ifdef BSP_USING_TIM4 + TIM4_INDEX, +#endif +#ifdef BSP_USING_TIM5 + TIM5_INDEX, +#endif +}; + +struct ab32_hwtimer +{ + rt_hwtimer_t time_device; + hal_sfr_t tim_handle; + char *name; + irq_type tim_irqn; +}; + +static struct ab32_hwtimer ab32_hwtimer_obj[] = +{ +#ifdef BSP_USING_TIM1 + TIM1_CONFIG, +#endif + +#ifdef BSP_USING_TIM2 + TIM2_CONFIG, +#endif + +#ifdef BSP_USING_TIM3 + TIM3_CONFIG, +#endif + +#ifdef BSP_USING_TIM4 + TIM4_CONFIG, +#endif + +#ifdef BSP_USING_TIM5 + TIM5_CONFIG, +#endif +}; + +static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state) +{ + uint32_t prescaler_value = 0; + hal_sfr_t tim = RT_NULL; + struct ab32_hwtimer *tim_device = RT_NULL; + + RT_ASSERT(timer != RT_NULL); + tim = (hal_sfr_t)timer->parent.user_data; + + if (state) + { + tim_device = (struct ab32_hwtimer *)timer; + + if (timer->info->cntmode != HWTIMER_CNTMODE_UP) + { + LOG_E("Only support HWTIMER_CNTMODE_UP!"); + } + + /* set tim int */ + tim[TMRxCON] = BIT(7); + + LOG_D("%s init success", tim_device->name); + } else { + /* stop timer */ + tim[TMRxCON] = 0; + } +} + +static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode) +{ + rt_err_t result = RT_EOK; + hal_sfr_t tim = RT_NULL; + + RT_ASSERT(timer != RT_NULL); + + tim = (hal_sfr_t)timer->parent.user_data; + + /* set tim cnt */ + tim[TMRxCNT] = 0; + tim[TMRxPR] = t * (get_sysclk_nhz() / timer->freq) - 1; + + if (opmode != HWTIMER_MODE_PERIOD) + { + LOG_E("Opmode only support HWTIMER_MODE_PERIOD!"); + return -RT_EINVAL; + } + + /* start timer */ + tim[TMRxCON] |= BIT(0); + + return result; +} + +static void timer_stop(rt_hwtimer_t *timer) +{ + hal_sfr_t tim = RT_NULL; + + RT_ASSERT(timer != RT_NULL); + + tim = (hal_sfr_t)timer->parent.user_data; + + /* stop timer */ + tim[TMRxCON] &= ~BIT(0); + + /* set tim cnt */ + tim[TMRxCNT] = 0; +} + +static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg) +{ + hal_sfr_t tim = RT_NULL; + rt_err_t result = RT_EOK; + + RT_ASSERT(timer != RT_NULL); + RT_ASSERT(arg != RT_NULL); + + tim = (hal_sfr_t)timer->parent.user_data; + + switch (cmd) + { + case HWTIMER_CTRL_FREQ_SET: + { + } + break; + default: + { + result = -RT_ENOSYS; + } + break; + } + + return result; +} + +static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer) +{ + hal_sfr_t tim = RT_NULL; + + RT_ASSERT(timer != RT_NULL); + + tim = (hal_sfr_t)timer->parent.user_data; + + return tim[TMRxCNT] / (get_sysclk_nhz() / timer->freq); +} + +static const struct rt_hwtimer_info _info = TIM_DEV_INFO_CONFIG; + +static const struct rt_hwtimer_ops _ops = +{ + .init = timer_init, + .start = timer_start, + .stop = timer_stop, + .count_get = timer_counter_get, + .control = timer_ctrl, +}; + +#if defined(BSP_USING_TIM2) || defined(BSP_USING_TIM4) || defined(BSP_USING_TIM5) +void timer2_4_5_isr(int vector, void *param) +{ + rt_interrupt_enter(); +#ifdef BSP_USING_TIM2 + if (ab32_hwtimer_obj[TIM2_INDEX].tim_handle[TMRxCON] != 0) { + ab32_hwtimer_obj[TIM2_INDEX].tim_handle[TMRxCPND] = BIT(9); + rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM2_INDEX].time_device); + } +#endif +#ifdef BSP_USING_TIM4 + if (ab32_hwtimer_obj[TIM4_INDEX].tim_handle[TMRxCON] != 0) { + ab32_hwtimer_obj[TIM4_INDEX].tim_handle[TMRxCPND] = BIT(9); + rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM4_INDEX].time_device); + } +#endif +#ifdef BSP_USING_TIM5 + if (ab32_hwtimer_obj[TIM5_INDEX].tim_handle[TMRxCON] != 0) { + ab32_hwtimer_obj[TIM5_INDEX].tim_handle[TMRxCPND] = BIT(9); + rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM5_INDEX].time_device); + } +#endif + rt_interrupt_leave(); +} +#endif + +#ifdef BSP_USING_TIM3 +void timer3_isr(int vector, void *param) +{ + rt_interrupt_enter(); + ab32_hwtimer_obj[TIM3_INDEX].tim_handle[TMRxCPND] = BIT(9); + rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM3_INDEX].time_device); + rt_interrupt_leave(); +} +#endif + +#ifdef BSP_USING_TIM1 +void timer1_isr(int vector, void *param) +{ + rt_interrupt_enter(); + ab32_hwtimer_obj[TIM1_INDEX].tim_handle[TMRxCPND] = BIT(9); + rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM1_INDEX].time_device); + rt_interrupt_leave(); +} +#endif + +static int ab32_hwtimer_init(void) +{ + int i = 0; + int result = RT_EOK; + + for (i = 0; i < sizeof(ab32_hwtimer_obj) / sizeof(ab32_hwtimer_obj[0]); i++) + { + ab32_hwtimer_obj[i].time_device.info = &_info; + ab32_hwtimer_obj[i].time_device.ops = &_ops; + if (rt_device_hwtimer_register(&ab32_hwtimer_obj[i].time_device, ab32_hwtimer_obj[i].name, (void *)ab32_hwtimer_obj[i].tim_handle) == RT_EOK) + { + LOG_D("%s register success", ab32_hwtimer_obj[i].name); + } + else + { + LOG_E("%s register failed", ab32_hwtimer_obj[i].name); + result = -RT_ERROR; + } + } + +#ifdef BSP_USING_TIM1 + rt_hw_interrupt_install(IRQ_TMR1_VECTOR, timer1_isr, RT_NULL, "t1_isr"); +#endif +#if defined(BSP_USING_TIM2) || defined(BSP_USING_TIM4) || defined(BSP_USING_TIM5) + rt_hw_interrupt_install(IRQ_TMR2_4_5_VECTOR, timer2_4_5_isr, RT_NULL, "t245_isr"); +#endif +#ifdef BSP_USING_TIM3 + rt_hw_interrupt_install(IRQ_IRRX_VECTOR, timer3_isr, RT_NULL, "t3_isr"); +#endif + + return result; +} +INIT_BOARD_EXPORT(ab32_hwtimer_init); + +#endif /* RT_USING_HWTIMER */ +#endif /* BSP_USING_TIM */ diff --git a/bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_conf.h b/bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_conf.h index a26714cc28..cf1a7cb763 100644 --- a/bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_conf.h +++ b/bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_conf.h @@ -14,6 +14,7 @@ #define HAL_WDT_MODULE_ENABLED // #define HAL_DAC_MODULE_ENABLED #define HAL_SD_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED /* Includes */ #ifdef HAL_GPIO_MODULE_ENABLED @@ -40,6 +41,10 @@ #include "ab32vg1_hal_sd.h" #endif +#ifdef HAL_TIM_MODULE_ENABLED +#include "ab32vg1_hal_tim.h" +#endif + #include #endif diff --git a/bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_tim.h b/bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_tim.h new file mode 100644 index 0000000000..e53017fa89 --- /dev/null +++ b/bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_tim.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020-2020, BLUETRUM Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef AB32VG1_HAL_TIM_H__ +#define AB32VG1_HAL_TIM_H__ + +#include "ab32vg1_hal_def.h" + +enum +{ + TMRxCON, + TMRxCPND, + TMRxCNT, + TMRxPR, + TMRxCPT, + TMRxDUTY0, + TMRxDUTY1, + TMRxDUTY2 +}; + +#define TIM0_BASE ((hal_sfr_t)&TMR0CON) +#define TIM1_BASE ((hal_sfr_t)&TMR1CON) +#define TIM2_BASE ((hal_sfr_t)&TMR2CON) +#define TIM3_BASE ((hal_sfr_t)&TMR3CON) +#define TIM4_BASE ((hal_sfr_t)&TMR4CON) +#define TIM5_BASE ((hal_sfr_t)&TMR5CON) + +#endif