diff --git a/bsp/es32f0654/.config b/bsp/es32f0654/.config index 10825f5a19..f0af98f0ac 100644 --- a/bsp/es32f0654/.config +++ b/bsp/es32f0654/.config @@ -346,6 +346,14 @@ CONFIG_BSP_USING_UART2=y # CONFIG_BSP_USING_PWM2 is not set # CONFIG_BSP_USING_PWM3 is not set +# +# HWtimer Drivers +# +# CONFIG_BSP_USING_HWTIMER0 is not set +# CONFIG_BSP_USING_HWTIMER1 is not set +# CONFIG_BSP_USING_HWTIMER2 is not set +# CONFIG_BSP_USING_HWTIMER3 is not set + # # Onboard Peripheral Drivers # diff --git a/bsp/es32f0654/README.md b/bsp/es32f0654/README.md index c7cbfa2206..87eb82c118 100644 --- a/bsp/es32f0654/README.md +++ b/bsp/es32f0654/README.md @@ -35,14 +35,17 @@ ES-PDS-ES32F0654-V1.1 | **板载外设** | **支持情况** | **备注** | | :---------------- | :----------: | :------------------------------------| | SPI FLASH | 支持 | SPI0 | - | **片上外设** | **支持情况** | **备注** | -| :---------------- | :----------: | :------------------------------------| | GPIO | 支持 | 54 GPIOs | | UART | 支持 | UART0/1/2/3 | | SPI | 支持 | SPI0/1 | | I2C | 支持 | I2C0/1 | | PWM | 支持 | PWM0/1/2/3 | +| TIMER | 支持 | TIMER0/1/2/3 | + +### 1.2 注意事项 + +- 本BSP中,UART2和TIMER1不能同时使用,UART3和TIMER2不能同时使用 更多详细信息请咨询[上海东软载波微电子技术支持](http://www.essemi.com/) diff --git a/bsp/es32f0654/drivers/Kconfig b/bsp/es32f0654/drivers/Kconfig index 248e02dc14..d5af1bbd95 100644 --- a/bsp/es32f0654/drivers/Kconfig +++ b/bsp/es32f0654/drivers/Kconfig @@ -16,16 +16,18 @@ menu "Hardware Drivers Config" bool "Enable UART1 PC10/PC11(T/R)" select RT_USING_SERIAL default n - + config BSP_USING_UART2 bool "Enable UART2 PC12/PD02(T/R)" select RT_USING_SERIAL default y + depends on !BSP_USING_HWTIMER1 config BSP_USING_UART3 bool "Enable UART3 PC04/PC05(T/R)" select RT_USING_SERIAL default n + depends on !BSP_USING_HWTIMER2 endmenu menu "SPI Drivers" @@ -47,6 +49,7 @@ menu "Hardware Drivers Config" bool "Enable I2C0 BUS PB08/PB09(SCL/SDA)" select RT_USING_I2C default n + config BSP_USING_I2C1 bool "Enable I2C1 BUS PB10/PB11(SCL/SDA)" select RT_USING_I2C @@ -62,18 +65,43 @@ menu "Hardware Drivers Config" config BSP_USING_PWM1 bool "Using PWM1 PB06/PB07/PB08/PB09" select RT_USING_PWM - default n + default n config BSP_USING_PWM2 bool "Using PWM2 PA00/PA01" select RT_USING_PWM - default n + default n config BSP_USING_PWM3 bool "Using PWM3 PC06/PC07" select RT_USING_PWM - default n + default n endmenu + + menu "HWtimer Drivers" + config BSP_USING_HWTIMER0 + bool "Using timer0" + select RT_USING_HWTIMER + default n + + config BSP_USING_HWTIMER1 + bool "Using timer1" + select RT_USING_HWTIMER + default n + depends on !BSP_USING_UART2 + + config BSP_USING_HWTIMER2 + bool "Using timer2" + select RT_USING_HWTIMER + default n + depends on !BSP_USING_UART3 + + config BSP_USING_HWTIMER3 + bool "Using timer3" + select RT_USING_HWTIMER + default n + endmenu + endmenu menu "Onboard Peripheral Drivers" diff --git a/bsp/es32f0654/drivers/SConscript b/bsp/es32f0654/drivers/SConscript index 17484f3491..31f75af3b3 100644 --- a/bsp/es32f0654/drivers/SConscript +++ b/bsp/es32f0654/drivers/SConscript @@ -31,6 +31,10 @@ if GetDepend('BSP_USING_SPI_FLASH'): if GetDepend('BSP_USING_PWM0') or GetDepend('BSP_USING_PWM1') or GetDepend('BSP_USING_PWM2') or GetDepend('BSP_USING_PWM3'): src += ['drv_pwm.c'] +# add hwtimer driver code +if GetDepend('BSP_USING_HWTIMER0') or GetDepend('BSP_USING_HWTIMER1') or GetDepend('BSP_USING_HWTIMER2') or GetDepend('BSP_USING_HWTIMER3'): + src += ['drv_hwtimer.c'] + CPPPATH = [cwd] group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) diff --git a/bsp/es32f0654/drivers/drv_hwtimer.c b/bsp/es32f0654/drivers/drv_hwtimer.c new file mode 100644 index 0000000000..6eceab627b --- /dev/null +++ b/bsp/es32f0654/drivers/drv_hwtimer.c @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-3-19 wangyq the first version + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef RT_USING_HWTIMER + +struct es32f0_hwtimer_dev +{ + rt_hwtimer_t parent; + timer_handle_t *hwtimer_periph; + IRQn_Type IRQn; +}; + +#ifdef BSP_USING_HWTIMER0 +static struct es32f0_hwtimer_dev hwtimer0; + +void BS16T0_Handler(void) +{ + timer_clear_flag_status(hwtimer0.hwtimer_periph, TIMER_FLAG_UPDATE); + rt_device_hwtimer_isr(&hwtimer0.parent); + + if (HWTIMER_MODE_ONESHOT == hwtimer0.parent.mode) + { + timer_base_stop(hwtimer0.hwtimer_periph); + } +} +#endif + +#ifdef BSP_USING_HWTIMER1 +static struct es32f0_hwtimer_dev hwtimer1; +/* can not use when UART2 Handler is enabled */ +void BS16T1_UART2_Handler(void) +{ + /* if BS16T1 it */ + if (timer_get_it_status(hwtimer1.hwtimer_periph, TIMER_IT_UPDATE) && + timer_get_flag_status(hwtimer1.hwtimer_periph, TIMER_FLAG_UPDATE)) + { + timer_clear_flag_status(hwtimer1.hwtimer_periph, TIMER_FLAG_UPDATE); + rt_device_hwtimer_isr(&hwtimer1.parent); + + if (HWTIMER_MODE_ONESHOT == hwtimer1.parent.mode) + { + timer_base_stop(hwtimer1.hwtimer_periph); + } + } +} +#endif + +#ifdef BSP_USING_HWTIMER2 +static struct es32f0_hwtimer_dev hwtimer2; +/* can not use when UART3 Handler is enabled */ +void BS16T2_UART3_Handler(void) +{ + /* if BS16T2 it */ + if (timer_get_it_status(hwtimer2.hwtimer_periph, TIMER_IT_UPDATE) && + timer_get_flag_status(hwtimer2.hwtimer_periph, TIMER_FLAG_UPDATE)) + { + timer_clear_flag_status(hwtimer2.hwtimer_periph, TIMER_FLAG_UPDATE); + rt_device_hwtimer_isr(&hwtimer2.parent); + + if (HWTIMER_MODE_ONESHOT == hwtimer2.parent.mode) + { + timer_base_stop(hwtimer2.hwtimer_periph); + } + } +} +#endif + +#ifdef BSP_USING_HWTIMER3 +static struct es32f0_hwtimer_dev hwtimer3; +/* can not use when DAC0 Handler is enabled */ +void BS16T3_DAC0_Handler(void) +{ + /* if BS16T3 it */ + if (timer_get_it_status(hwtimer3.hwtimer_periph, TIMER_IT_UPDATE) && + timer_get_flag_status(hwtimer3.hwtimer_periph, TIMER_FLAG_UPDATE)) + { + timer_clear_flag_status(hwtimer3.hwtimer_periph, TIMER_FLAG_UPDATE); + rt_device_hwtimer_isr(&hwtimer3.parent); + + if (HWTIMER_MODE_ONESHOT == hwtimer3.parent.mode) + { + timer_base_stop(hwtimer3.hwtimer_periph); + } + } +} +#endif + +static struct rt_hwtimer_info es32f0_hwtimer_info = +{ + 48000000, /* maximum count frequency */ + 1, /* minimum count frequency */ + 65535, /* counter maximum value */ + HWTIMER_CNTMODE_UP +}; + +static void es32f0_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state) +{ + struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data; + + RT_ASSERT(hwtimer != RT_NULL); + + if (1 == state) + { + timer_base_init(hwtimer->hwtimer_periph); + timer_interrupt_config(hwtimer->hwtimer_periph, TIMER_IT_UPDATE, ENABLE); + NVIC_EnableIRQ(hwtimer->IRQn); + } + hwtimer->parent.freq = cmu_get_pclk1_clock(); + es32f0_hwtimer_info.maxfreq = cmu_get_pclk1_clock(); + es32f0_hwtimer_info.minfreq = cmu_get_pclk1_clock(); +} + +static rt_err_t es32f0_hwtimer_start(rt_hwtimer_t *timer, + rt_uint32_t cnt, + rt_hwtimer_mode_t mode) +{ + struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data; + + RT_ASSERT(hwtimer != RT_NULL); + + WRITE_REG(hwtimer->hwtimer_periph->perh->AR, cnt); + timer_base_start(hwtimer->hwtimer_periph); + + return RT_EOK; +} + +static void es32f0_hwtimer_stop(rt_hwtimer_t *timer) +{ + struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data; + + RT_ASSERT(hwtimer != RT_NULL); + + timer_base_stop(hwtimer->hwtimer_periph); +} + +static rt_uint32_t es32f0_hwtimer_count_get(rt_hwtimer_t *timer) +{ + struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data; + uint32_t hwtimer_count = 0; + + RT_ASSERT(hwtimer != RT_NULL); + + hwtimer_count = READ_REG(hwtimer->hwtimer_periph->perh->COUNT); + + return hwtimer_count; +} + +static rt_err_t es32f0_hwtimer_control(rt_hwtimer_t *timer, + rt_uint32_t cmd, + void *args) +{ + rt_err_t ret = RT_EOK; + rt_uint32_t freq = 0; + struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data; + + RT_ASSERT(hwtimer != RT_NULL); + + switch (cmd) + { + case HWTIMER_CTRL_FREQ_SET: + freq = *(rt_uint32_t *)args; + if (freq != cmu_get_pclk1_clock()) + { + ret = -RT_ERROR; + } + break; + + case HWTIMER_CTRL_STOP: + timer_base_stop(hwtimer->hwtimer_periph); + break; + + default: + ret = RT_EINVAL; + break; + } + + return ret; +} + +static struct rt_hwtimer_ops es32f0_hwtimer_ops = +{ + es32f0_hwtimer_init, + es32f0_hwtimer_start, + es32f0_hwtimer_stop, + es32f0_hwtimer_count_get, + es32f0_hwtimer_control +}; + +int rt_hw_hwtimer_init(void) +{ + rt_err_t ret = RT_EOK; + +#ifdef BSP_USING_HWTIMER0 + static timer_handle_t _hwtimer_periph0; + _hwtimer_periph0.perh = BS16T0; + hwtimer0.IRQn = BS16T0_IRQn; + hwtimer0.hwtimer_periph = &_hwtimer_periph0; + hwtimer0.parent.info = &es32f0_hwtimer_info; + hwtimer0.parent.ops = &es32f0_hwtimer_ops; + ret = rt_device_hwtimer_register(&hwtimer0.parent, "timer0", &hwtimer0); +#endif + +#ifdef BSP_USING_HWTIMER1 + static timer_handle_t _hwtimer_periph1; + _hwtimer_periph1.perh = BS16T1; + hwtimer1.IRQn = BS16T1_UART2_IRQn; + hwtimer1.hwtimer_periph = &_hwtimer_periph1; + hwtimer1.parent.info = &es32f0_hwtimer_info; + hwtimer1.parent.ops = &es32f0_hwtimer_ops; + ret = rt_device_hwtimer_register(&hwtimer1.parent, "timer1", &hwtimer1); +#endif + +#ifdef BSP_USING_HWTIMER2 + static timer_handle_t _hwtimer_periph2; + _hwtimer_periph2.perh = BS16T2; + hwtimer2.IRQn = BS16T2_UART3_IRQn; + hwtimer2.hwtimer_periph = &_hwtimer_periph2; + hwtimer2.parent.info = &es32f0_hwtimer_info; + hwtimer2.parent.ops = &es32f0_hwtimer_ops; + ret = rt_device_hwtimer_register(&hwtimer2.parent, "timer2", &hwtimer2); +#endif + +#ifdef BSP_USING_HWTIMER3 + static timer_handle_t _hwtimer_periph3; + _hwtimer_periph3.perh = BS16T3; + hwtimer3.IRQn = BS16T3_DAC0_IRQn; + hwtimer3.hwtimer_periph = &_hwtimer_periph3; + hwtimer3.parent.info = &es32f0_hwtimer_info; + hwtimer3.parent.ops = &es32f0_hwtimer_ops; + ret = rt_device_hwtimer_register(&hwtimer3.parent, "timer3", &hwtimer3); +#endif + + return ret; +} +INIT_BOARD_EXPORT(rt_hw_hwtimer_init); + +#endif diff --git a/bsp/es32f0654/drivers/drv_hwtimer.h b/bsp/es32f0654/drivers/drv_hwtimer.h new file mode 100644 index 0000000000..e18d580fbd --- /dev/null +++ b/bsp/es32f0654/drivers/drv_hwtimer.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-3-19 wangyq the first version + */ + +#ifndef DRV_HWTIMER_H__ +#define DRV_HWTIMER_H__ + +int rt_hw_hwtimer_init(void); + +#endif diff --git a/bsp/es32f0654/drivers/drv_pwm.c b/bsp/es32f0654/drivers/drv_pwm.c index a64ff5cbd1..4bb747654d 100644 --- a/bsp/es32f0654/drivers/drv_pwm.c +++ b/bsp/es32f0654/drivers/drv_pwm.c @@ -19,7 +19,7 @@ static void pwm_set_freq(timer_handle_t *timer_initstruct, uint32_t ns) { uint64_t _arr = (uint64_t)cmu_get_pclk1_clock() * ns / 1000000000 / - (timer_initstruct->init.prescaler + 1) - 1; + (timer_initstruct->init.prescaler + 1); WRITE_REG(timer_initstruct->perh->AR, (uint32_t)_arr); timer_initstruct->init.period = (uint32_t)_arr; @@ -28,7 +28,7 @@ static void pwm_set_freq(timer_handle_t *timer_initstruct, uint32_t ns) static void pwm_set_duty(timer_handle_t *timer_initstruct, timer_channel_t ch, uint32_t ns) { uint64_t tmp = (uint64_t)cmu_get_pclk1_clock() * ns / 1000000000 / - (timer_initstruct->init.prescaler + 1) - 1; + (timer_initstruct->init.prescaler + 1); if (ch == TIMER_CHANNEL_1) WRITE_REG(timer_initstruct->perh->CCVAL1, (uint32_t)tmp); @@ -38,10 +38,6 @@ static void pwm_set_duty(timer_handle_t *timer_initstruct, timer_channel_t ch, u WRITE_REG(timer_initstruct->perh->CCVAL3, (uint32_t)tmp); else if (ch == TIMER_CHANNEL_4) WRITE_REG(timer_initstruct->perh->CCVAL4, (uint32_t)tmp); - else - { - ;/* do nothing */ - } } static rt_err_t es32f0_pwm_control(struct rt_device_pwm *device, int cmd, void *arg) diff --git a/bsp/es32f0654/rtconfig.h b/bsp/es32f0654/rtconfig.h index 1e4d3edbfe..52cb4930e0 100644 --- a/bsp/es32f0654/rtconfig.h +++ b/bsp/es32f0654/rtconfig.h @@ -172,6 +172,9 @@ /* PWM Drivers */ +/* HWtimer Drivers */ + + /* Onboard Peripheral Drivers */