summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhg0720 <[email protected]>2022-10-17 08:14:08 +0800
committerGitHub <[email protected]>2022-10-16 20:14:08 -0400
commitfddc522d9cabf73c2ed9666e00c031b0d761e629 (patch)
tree7c0f9d009a98bcfeb0496a71fa824f88b9115569
parent1d77744a37d4870d4b20275a97f52d7b2720b138 (diff)
[bsp][ch32v307]添加了pwm驱动 (#6519)
* [bsp][ch32v307]添加了 pwm 驱动
-rw-r--r--bsp/wch/risc-v/Libraries/ch32_drivers/SConscript3
-rw-r--r--bsp/wch/risc-v/Libraries/ch32_drivers/drv_pwm.c628
-rw-r--r--bsp/wch/risc-v/ch32v307v-r1/board/Kconfig169
3 files changed, 796 insertions, 4 deletions
diff --git a/bsp/wch/risc-v/Libraries/ch32_drivers/SConscript b/bsp/wch/risc-v/Libraries/ch32_drivers/SConscript
index 3f3fb70c03..e81428c58b 100644
--- a/bsp/wch/risc-v/Libraries/ch32_drivers/SConscript
+++ b/bsp/wch/risc-v/Libraries/ch32_drivers/SConscript
@@ -30,6 +30,9 @@ if GetDepend('SOC_RISCV_FAMILY_CH32'):
if GetDepend('BSP_USING_CAN'):
src += ['drv_can.c']
+ if GetDepend('BSP_USING_PWM'):
+ src += ['drv_pwm.c']
+
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
Return('group')
diff --git a/bsp/wch/risc-v/Libraries/ch32_drivers/drv_pwm.c b/bsp/wch/risc-v/Libraries/ch32_drivers/drv_pwm.c
new file mode 100644
index 0000000000..e4a81b9852
--- /dev/null
+++ b/bsp/wch/risc-v/Libraries/ch32_drivers/drv_pwm.c
@@ -0,0 +1,628 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-09-23 charlown first version
+ * 2022-10-14 hg0720 the first version which add from wch
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <drivers/rt_drv_pwm.h>
+#include <drivers/hwtimer.h>
+#include <board.h>
+
+#ifdef BSP_USING_PWM
+
+#define LOG_TAG "drv.pwm"
+#include <drv_log.h>
+
+#ifndef ITEM_NUM
+#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
+#endif
+
+#define MAX_COUNTER 65535
+#define MIN_COUNTER 2
+#define MIN_PULSE 2
+
+struct rtdevice_pwm_device
+{
+ struct rt_device_pwm parent;
+ TIM_TypeDef* periph;
+ rt_uint8_t channel[4];
+ char* name;
+};
+
+void ch32_tim_clock_init(TIM_TypeDef* timx)
+{
+ if (timx == TIM1)
+ {
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
+ }
+ if (timx == TIM2)
+ {
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
+ }
+ if (timx == TIM3)
+ {
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
+ }
+ if (timx == TIM4)
+ {
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
+ }
+}
+
+rt_uint32_t ch32_tim_clock_get(TIM_TypeDef* timx)
+{
+ RCC_ClocksTypeDef RCC_Clocks;
+ RCC_GetClocksFreq(&RCC_Clocks);
+
+ /*tim1~4 all in HCLK*/
+ return RCC_Clocks.HCLK_Frequency;
+}
+
+struct rt_hwtimer_info hwtimer_info1 =
+{
+ .maxfreq = 1000000,
+ .minfreq = 2000,
+ .maxcnt = 0xFFFF,
+ .cntmode = HWTIMER_CNTMODE_UP,
+};
+
+struct rt_hwtimer_info hwtimer_info2 =
+{
+ .maxfreq = 1000000,
+ .minfreq = 2000,
+ .maxcnt = 0xFFFF,
+ .cntmode = HWTIMER_CNTMODE_UP,
+
+};
+
+struct rt_hwtimer_info hwtimer_info3 =
+{
+ .maxfreq = 1000000,
+ .minfreq = 2000,
+ .maxcnt = 0xFFFF,
+ .cntmode = HWTIMER_CNTMODE_UP,
+
+};
+
+struct rt_hwtimer_info hwtimer_info4 =
+{
+ .maxfreq = 1000000,
+ .minfreq = 2000,
+ .maxcnt = 0xFFFF,
+ .cntmode = HWTIMER_CNTMODE_UP,
+
+};
+
+struct rt_hwtimer_info* ch32_hwtimer_info_config_get(TIM_TypeDef* timx)
+{
+ struct rt_hwtimer_info* info = RT_NULL;
+
+ if (timx == TIM1)
+ {
+ info = &hwtimer_info1;
+ }
+ else if (timx == TIM2)
+ {
+ info = &hwtimer_info2;
+ }
+ else if (timx == TIM3)
+ {
+ info = &hwtimer_info3;
+ }
+ else if (timx == TIM4)
+ {
+ info = &hwtimer_info4;
+ }
+
+ return info;
+}
+
+void ch32_pwm_io_init(TIM_TypeDef* timx, rt_uint8_t channel)
+{
+ GPIO_InitTypeDef GPIO_InitStructure;
+
+ if (timx == TIM1)
+ {
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
+
+ if (channel == TIM_Channel_1)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ }
+ if (channel == TIM_Channel_2)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ }
+ if (channel == TIM_Channel_3)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ }
+ if (channel == TIM_Channel_4)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ }
+ }
+
+ if (timx == TIM2)
+ {
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
+
+ if (channel == TIM_Channel_1)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ }
+ if (channel == TIM_Channel_2)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ }
+ if (channel == TIM_Channel_3)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ }
+ if (channel == TIM_Channel_4)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ }
+ }
+
+ if (timx == TIM3)
+ {
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
+
+ if (channel == TIM_Channel_1)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ }
+ if (channel == TIM_Channel_2)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ }
+ if (channel == TIM_Channel_3)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
+ }
+ if (channel == TIM_Channel_4)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
+ }
+ }
+
+ if (timx == TIM4)
+ {
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
+
+ if (channel == TIM_Channel_1)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
+ }
+ if (channel == TIM_Channel_2)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
+ }
+ if (channel == TIM_Channel_3)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
+ }
+ if (channel == TIM_Channel_4)
+ {
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
+ }
+ }
+}
+
+/*
+ * channel = 0xFF: the channel is not use.
+ */
+struct rtdevice_pwm_device pwm_device_list[] =
+{
+#ifdef BSP_USING_TIM1_PWM
+ {
+ .periph = TIM1,
+ .name = "pwm1",
+#ifdef BSP_USING_TIM1_PWM_CH1
+ .channel[0] = TIM_Channel_1,
+#else
+ .channel[0] = 0xFF,
+#endif
+
+#ifdef BSP_USING_TIM1_PWM_CH2
+ .channel[1] = TIM_Channel_2,
+#else
+ .channel[1] = 0xFF,
+#endif
+
+#ifdef BSP_USING_TIM1_PWM_CH3
+ .channel[2] = TIM_Channel_3,
+#else
+ .channel[2] = 0xFF,
+#endif
+
+#ifdef BSP_USING_TIM1_PWM_CH4
+ .channel[3] = TIM_Channel_4,
+#else
+ .channel[3] = 0xFF,
+#endif
+ },
+#endif /* BSP_USING_TIM1_PWM */
+
+#ifdef BSP_USING_TIM2_PWM
+ {
+ .periph = TIM2,
+ .name = "pwm2",
+#ifdef BSP_USING_TIM2_PWM_CH1
+ .channel[0] = TIM_Channel_1,
+#else
+ .channel[0] = 0xFF,
+#endif
+
+#ifdef BSP_USING_TIM2_PWM_CH2
+ .channel[1] = TIM_Channel_2,
+#else
+ .channel[1] = 0xFF,
+#endif
+
+#ifdef BSP_USING_TIM2_PWM_CH3
+ .channel[2] = TIM_Channel_3,
+#else
+ .channel[2] = 0xFF,
+#endif
+
+#ifdef BSP_USING_TIM2_PWM_CH4
+ .channel[3] = TIM_Channel_4,
+#else
+ .channel[3] = 0xFF,
+#endif
+ },
+#endif /* BSP_USING_TIM2_PWM */
+
+#ifdef BSP_USING_TIM3_PWM
+ {
+ .periph = TIM3,
+ .name = "pwm3",
+#ifdef BSP_USING_TIM3_PWM_CH1
+ .channel[0] = TIM_Channel_1,
+#else
+ .channel[0] = 0xFF,
+#endif
+
+#ifdef BSP_USING_TIM3_PWM_CH2
+ .channel[1] = TIM_Channel_2,
+#else
+ .channel[1] = 0xFF,
+#endif
+
+#ifdef BSP_USING_TIM3_PWM_CH3
+ .channel[2] = TIM_Channel_3,
+#else
+ .channel[2] = 0xFF,
+#endif
+
+#ifdef BSP_USING_TIM3_PWM_CH4
+ .channel[3] = TIM_Channel_4,
+#else
+ .channel[3] = 0xFF,
+#endif
+ },
+#endif /* BSP_USING_TIM3_PWM */
+
+#ifdef BSP_USING_TIM4_PWM
+ {
+ .periph = TIM4,
+ .name = "pwm4",
+#ifdef BSP_USING_TIM4_PWM_CH1
+ .channel[0] = TIM_Channel_1,
+#else
+ .channel[0] = 0xFF,
+#endif
+
+#ifdef BSP_USING_TIM4_PWM_CH2
+ .channel[1] = TIM_Channel_2,
+#else
+ .channel[1] = 0xFF,
+#endif
+
+#ifdef BSP_USING_TIM4_PWM_CH3
+ .channel[2] = TIM_Channel_3,
+#else
+ .channel[2] = 0xFF,
+#endif
+
+#ifdef BSP_USING_TIM4_PWM_CH4
+ .channel[3] = TIM_Channel_4,
+#else
+ .channel[3] = 0xFF,
+#endif
+ },
+#endif /* BSP_USING_TIM4_PWM */
+};
+
+static rt_err_t ch32_pwm_device_enable(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration, rt_bool_t enable)
+{
+ struct rtdevice_pwm_device* pwm_device;
+ rt_uint32_t channel_index;
+ rt_uint16_t ccx_state;
+
+ pwm_device = (struct rtdevice_pwm_device*)device;
+ channel_index = configuration->channel;
+
+ if (enable == RT_TRUE)
+ {
+ ccx_state = TIM_CCx_Enable;
+ }
+ else
+ {
+ ccx_state = TIM_CCx_Disable;
+ }
+
+ if (channel_index <= 4 && channel_index > 0)
+ {
+ if (pwm_device->channel[channel_index - 1] == 0xFF)
+ {
+ return RT_EINVAL;
+ }
+ TIM_CCxCmd(pwm_device->periph, pwm_device->channel[channel_index - 1], ccx_state);
+ }
+ else
+ {
+ return RT_EINVAL;
+ }
+
+ TIM_Cmd(pwm_device->periph, ENABLE);
+
+ return RT_EOK;
+}
+
+static rt_err_t ch32_pwm_device_get(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration)
+{
+ struct rtdevice_pwm_device* pwm_device;
+ rt_uint32_t arr_counter, ccr_counter, prescaler, sample_freq;
+ rt_uint32_t channel_index;
+ rt_uint32_t tim_clock;
+
+ pwm_device = (struct rtdevice_pwm_device*)device;
+ tim_clock = ch32_tim_clock_get(pwm_device->periph);
+ channel_index = configuration->channel;
+ arr_counter = pwm_device->periph->ATRLR + 1;
+ prescaler = pwm_device->periph->PSC + 1;
+ sample_freq = (tim_clock / prescaler) / arr_counter;
+
+ /* unit:ns */
+ configuration->period = 1000000000 / sample_freq;
+
+ if (channel_index == 1)
+ {
+ ccr_counter = pwm_device->periph->CH1CVR + 1;
+ configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
+ }
+ else if (channel_index == 2)
+ {
+ ccr_counter = pwm_device->periph->CH2CVR + 1;
+ configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
+ }
+ else if (channel_index == 3)
+ {
+ ccr_counter = pwm_device->periph->CH3CVR + 1;
+ configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
+ }
+ else if (channel_index == 4)
+ {
+ ccr_counter = pwm_device->periph->CH4CVR + 1;
+ configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
+ }
+ else
+ {
+ return RT_EINVAL;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t ch32_pwm_device_set(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration)
+{
+ struct rtdevice_pwm_device* pwm_device;
+ rt_uint32_t arr_counter, ccr_counter, prescaler, sample_freq;
+ rt_uint32_t channel_index;
+ rt_uint32_t tim_clock;
+ TIM_TimeBaseInitTypeDef TIM_TimeBaseInitType;
+ TIM_OCInitTypeDef TIM_OCInitType;
+
+ pwm_device = (struct rtdevice_pwm_device*)device;
+ tim_clock = ch32_tim_clock_get(pwm_device->periph);
+ channel_index = configuration->channel;
+
+ /* change to freq, unit:Hz */
+ sample_freq = 1000000000 / configuration->period;
+
+ /* counter = (tim_clk / prescaler) / sample_freq */
+ /* normally, tim_clk is not need div, if arr_counter over 65536, need div. */
+ prescaler = 1;
+ arr_counter = (tim_clock / prescaler) / sample_freq;
+
+ if (arr_counter > MAX_COUNTER)
+ {
+ /* need div tim_clock
+ * and round up the prescaler value.
+ * (tim_clock >> 16) = tim_clock / 65536
+ */
+ if ((tim_clock >> 16) % sample_freq == 0)
+ prescaler = (tim_clock >> 16) / sample_freq;
+ else
+ prescaler = (tim_clock >> 16) / sample_freq + 1;
+
+ /* counter = (tim_clk / prescaler) / sample_freq */
+ arr_counter = (tim_clock / prescaler) / sample_freq;
+ }
+ /* ccr_counter = duty cycle * arr_counter */
+ ccr_counter = (configuration->pulse * 100 / configuration->period) * arr_counter / 100;
+
+ /* check arr_counter > 1, cxx_counter > 1 */
+ if (arr_counter < MIN_COUNTER)
+ {
+ arr_counter = MIN_COUNTER;
+ }
+ if (ccr_counter < MIN_PULSE)
+ {
+ ccr_counter = MIN_PULSE;
+ }
+
+ /* TMRe base configuration */
+ TIM_TimeBaseStructInit(&TIM_TimeBaseInitType);
+ TIM_TimeBaseInitType.TIM_Period = arr_counter - 1;
+ TIM_TimeBaseInitType.TIM_Prescaler = prescaler - 1;
+ TIM_TimeBaseInitType.TIM_ClockDivision = TIM_CKD_DIV1;
+ TIM_TimeBaseInitType.TIM_CounterMode = TIM_CounterMode_Up;
+ TIM_TimeBaseInit(pwm_device->periph, &TIM_TimeBaseInitType);
+
+ TIM_OCStructInit(&TIM_OCInitType);
+ TIM_OCInitType.TIM_OCMode = TIM_OCMode_PWM1;
+ TIM_OCInitType.TIM_OutputState = TIM_OutputState_Enable;
+ TIM_OCInitType.TIM_Pulse = ccr_counter - 1;
+ TIM_OCInitType.TIM_OCPolarity = TIM_OCPolarity_High;
+
+ if (channel_index == 1)
+ {
+ TIM_OC1Init(pwm_device->periph, &TIM_OCInitType);
+ TIM_OC1PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
+ }
+ else if (channel_index == 2)
+ {
+ TIM_OC2Init(pwm_device->periph, &TIM_OCInitType);
+ TIM_OC2PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
+ }
+ else if (channel_index == 3)
+ {
+ TIM_OC3Init(pwm_device->periph, &TIM_OCInitType);
+ TIM_OC3PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
+ }
+ else if (channel_index == 4)
+ {
+ TIM_OC4Init(pwm_device->periph, &TIM_OCInitType);
+ TIM_OC4PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
+ }
+ else
+ {
+ return RT_EINVAL;
+ }
+
+ TIM_ARRPreloadConfig(pwm_device->periph, ENABLE);
+ TIM_CtrlPWMOutputs(pwm_device->periph, ENABLE);
+
+ return RT_EOK;
+}
+
+static rt_err_t drv_pwm_control(struct rt_device_pwm* device, int cmd, void* arg)
+{
+ struct rt_pwm_configuration* configuration;
+
+ configuration = (struct rt_pwm_configuration*)arg;
+
+ switch (cmd)
+ {
+ case PWM_CMD_ENABLE:
+ return ch32_pwm_device_enable(device, configuration, RT_TRUE);
+ case PWM_CMD_DISABLE:
+ return ch32_pwm_device_enable(device, configuration, RT_FALSE);
+ case PWM_CMD_SET:
+ return ch32_pwm_device_set(device, configuration);
+ case PWM_CMD_GET:
+ return ch32_pwm_device_get(device, configuration);
+ default:
+ return RT_EINVAL;
+ }
+}
+
+static struct rt_pwm_ops pwm_ops =
+{
+ .control = drv_pwm_control
+};
+
+static int rt_hw_pwm_init(void)
+{
+ int result = RT_EOK;
+ int index = 0;
+ int channel_index;
+
+ for (index = 0; index < ITEM_NUM(pwm_device_list); index++)
+ {
+ ch32_tim_clock_init(pwm_device_list[index].periph);
+ for (channel_index = 0; channel_index < sizeof(pwm_device_list[index].channel); channel_index++)
+ {
+ if (pwm_device_list[index].channel[channel_index] != 0xFF)
+ {
+ ch32_pwm_io_init(pwm_device_list[index].periph, pwm_device_list[index].channel[channel_index]);
+ }
+ }
+
+ if (rt_device_pwm_register(&pwm_device_list[index].parent, pwm_device_list[index].name, &pwm_ops, RT_NULL) == RT_EOK)
+ {
+ LOG_D("%s register success", pwm_device_list[index].name);
+ }
+ else
+ {
+ LOG_D("%s register failed", pwm_device_list[index].name);
+ result = -RT_ERROR;
+ }
+ }
+
+ return result;
+}
+
+INIT_BOARD_EXPORT(rt_hw_pwm_init);
+
+#endif /* BSP_USING_PWM */
diff --git a/bsp/wch/risc-v/ch32v307v-r1/board/Kconfig b/bsp/wch/risc-v/ch32v307v-r1/board/Kconfig
index b1134365e0..69b6b9467c 100644
--- a/bsp/wch/risc-v/ch32v307v-r1/board/Kconfig
+++ b/bsp/wch/risc-v/ch32v307v-r1/board/Kconfig
@@ -137,10 +137,10 @@ menu "On-chip Peripheral Drivers"
default n
if BSP_USING_RTC
- config BSP_USING_RTC_LSI
- bool "using LSI clock for rtc, if not, LSE default"
- select LSI_VALUE
- default n
+ config BSP_USING_RTC_LSI
+ bool "using LSI clock for rtc, if not, LSE default"
+ select LSI_VALUE
+ default n
endif
config LSI_VALUE
@@ -165,6 +165,167 @@ menu "On-chip Peripheral Drivers"
bool "using CAN2"
default n
endif
+
+ config BSP_USING_TIM
+ bool "using TIMx"
+ default n
+
+ if BSP_USING_TIM
+ config BSP_USING_HWTIMER
+ bool
+ select RT_USING_HWTIMER
+ default n
+
+ config BSP_USING_PWM
+ bool
+ select RT_USING_PWM
+ default n
+
+ config BSP_USING_TIM1
+ bool "using TIM1"
+ default n
+
+ if BSP_USING_TIM1
+ choice
+ prompt "using TIM1 as hwtimer or PWM mode"
+ default BSP_USING_TIM1_HWTIMER
+
+ config BSP_USING_TIM1_HWTIMER
+ bool "using TIM1 as hwtimer mode"
+ select BSP_USING_HWTIMER
+
+ config BSP_USING_TIM1_PWM
+ bool "using TIM1 as PWM mode"
+ select BSP_USING_PWM
+ endchoice
+
+ if BSP_USING_TIM1_PWM
+ config BSP_USING_TIM1_PWM_CH1
+ bool "using TIM1 channel 1"
+ default n
+
+ config BSP_USING_TIM1_PWM_CH2
+ bool "using TIM1 channel 2"
+ default n
+
+ config BSP_USING_TIM1_PWM_CH3
+ bool "using TIM1 channel 3"
+
+ config BSP_USING_TIM1_PWM_CH4
+ bool "using TIM1 channel 4"
+ endif
+
+ endif
+
+ config BSP_USING_TIM2
+ bool "using TIM2"
+ default n
+
+ if BSP_USING_TIM2
+ choice
+ prompt "using TIM2 as hwtimer or PWM mode"
+ default BSP_USING_TIM2_HWTIMER
+
+ config BSP_USING_TIM2_HWTIMER
+ bool "using TIM2 as hwtimer mode"
+ select BSP_USING_HWTIMER
+
+ config BSP_USING_TIM2_PWM
+ bool "using TIM2 as PWM mode"
+ select BSP_USING_PWM
+ endchoice
+
+ if BSP_USING_TIM2_PWM
+ config BSP_USING_TIM2_PWM_CH1
+ bool "using TIM2 channel 1"
+ default n
+
+ config BSP_USING_TIM2_PWM_CH2
+ bool "using TIM2 channel 2"
+ default n
+
+ config BSP_USING_TIM2_PWM_CH3
+ bool "using TIM2 channel 3"
+
+ config BSP_USING_TIM2_PWM_CH4
+ bool "using TIM2 channel 4"
+ endif
+
+ endif
+
+ config BSP_USING_TIM3
+ bool "using TIM3"
+ default n
+
+ if BSP_USING_TIM3
+ choice
+ prompt "using TIM3 as hwtimer or PWM mode"
+ default BSP_USING_TIM3_HWTIMER
+
+ config BSP_USING_TIM3_HWTIMER
+ bool "using TIM3 as hwtimer mode"
+ select BSP_USING_HWTIMER
+
+ config BSP_USING_TIM3_PWM
+ bool "using TIM3 as PWM mode"
+ select BSP_USING_PWM
+ endchoice
+
+ if BSP_USING_TIM3_PWM
+ config BSP_USING_TIM3_PWM_CH1
+ bool "using TIM3 channel 1"
+ default n
+
+ config BSP_USING_TIM3_PWM_CH2
+ bool "using TIM3 channel 2"
+ default n
+
+ config BSP_USING_TIM3_PWM_CH3
+ bool "using TIM3 channel 3"
+
+ config BSP_USING_TIM3_PWM_CH4
+ bool "using TIM3 channel 4"
+ endif
+
+ endif
+
+ config BSP_USING_TIM4
+ bool "using TIM4"
+ default n
+
+ if BSP_USING_TIM4
+ choice
+ prompt "using TIM4 as hwtimer or PWM mode"
+ default BSP_USING_TIM4_HWTIMER
+
+ config BSP_USING_TIM4_HWTIMER
+ bool "using TIM4 as hwtimer mode"
+ select BSP_USING_HWTIMER
+
+ config BSP_USING_TIM4_PWM
+ bool "using TIM4 as PWM mode"
+ select BSP_USING_PWM
+ endchoice
+
+ if BSP_USING_TIM4_PWM
+ config BSP_USING_TIM4_PWM_CH1
+ bool "using TIM4 channel 1"
+ default n
+
+ config BSP_USING_TIM4_PWM_CH2
+ bool "using TIM4 channel 2"
+ default n
+
+ config BSP_USING_TIM4_PWM_CH3
+ bool "using TIM4 channel 3"
+
+ config BSP_USING_TIM4_PWM_CH4
+ bool "using TIM4 channel 4"
+ endif
+
+ endif
+
+ endif
endmenu