瀏覽代碼

Merge pull request #5095 from charlown/master

support ch32f10x pwm driver.
Bernard Xiong 3 年之前
父節點
當前提交
4a9ecd8d0d

+ 3 - 0
bsp/wch/arm/Libraries/ch32_drivers/SConscript

@@ -32,6 +32,9 @@ if  GetDepend('SOC_ARM_SERIES_CH32F103'):
     if GetDepend(['RT_USING_HWTIMER', 'BSP_USING_HWTIMER']):
         src += ['drv_hwtimer_ch32f10x.c']
 
+    if GetDepend(['RT_USING_PWM', 'BSP_USING_PWM']):
+        src += ['drv_pwm_ch32f10x.c']
+
 src += ['drv_common.c']
 
 path =  [cwd]

+ 6 - 10
bsp/wch/arm/Libraries/ch32_drivers/drv_hwtimer_ch32f10x.c

@@ -73,17 +73,16 @@ static void ch32f1_hwtimer_init(struct rt_hwtimer_device *device, rt_uint32_t st
 
     if (state)
     {
-        ch32f1_hwtimer_clock_init(hwtimer_dev->periph);
+        ch32f1_tim_clock_init(hwtimer_dev->periph);
 
         hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_dev->periph);
 
-        clk = ch32f1_hwtimer_clock_get(hwtimer_dev->periph);
+        clk = ch32f1_tim_clock_get(hwtimer_dev->periph);
 
         prescaler_value = (rt_uint16_t)(clk / hwtimer_info->minfreq) - 1;
 
         /*
-        * set interrupt callback one or each time need total time =
-        *  (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
+        * (1 / freq) = (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
         */
 
         TIM_TimeBaseInitType.TIM_Period = hwtimer_info->maxcnt - 1;
@@ -132,8 +131,7 @@ static rt_err_t ch32f1_hwtimer_start(struct rt_hwtimer_device *device, rt_uint32
     hwtimer_dev = (struct hwtimer_device *)device;
 
     /*
-    * interrupt callback one or each time need total time =
-    *  (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
+    * (1 / freq) = (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
     */
 
     TIM_SetCounter(hwtimer_dev->periph, 0);
@@ -197,15 +195,14 @@ static rt_err_t ch32f1_hwtimer_control(struct rt_hwtimer_device *device, rt_uint
         rt_uint16_t prescaler_value = 0;
 
         /*
-        *set interrupt callback one or each time need total time =
-        *  (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
+        * (1 / freq) = (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
         */
         if (arg != RT_NULL)
         {
 
             freq = *((rt_uint32_t *)arg);
 
-            clk = ch32f1_hwtimer_clock_get(hwtimer_dev->periph);
+            clk = ch32f1_tim_clock_get(hwtimer_dev->periph);
 
             prescaler_value = (rt_uint16_t)(clk / freq) - 1;
 
@@ -369,4 +366,3 @@ void TIM4_IRQHandler(void)
 #endif
 
 #endif /* BSP_USING_HWTIMER */
-

+ 400 - 0
bsp/wch/arm/Libraries/ch32_drivers/drv_pwm_ch32f10x.c

@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2021-09-23     charlown           first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.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;
+};
+
+/*
+* 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
+
+#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
+
+#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
+
+#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
+};
+
+static rt_err_t ch32f1_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 ch32f1_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 = ch32f1_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 ch32f1_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 = ch32f1_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 ch32f1_pwm_device_enable(device, configuration, RT_TRUE);
+  case PWM_CMD_DISABLE:
+    return ch32f1_pwm_device_enable(device, configuration, RT_FALSE);
+  case PWM_CMD_SET:
+    return ch32f1_pwm_device_set(device, configuration);
+  case PWM_CMD_GET:
+    return ch32f1_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++)
+  {
+    ch32f1_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)
+      {
+        ch32f1_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 */

+ 16 - 16
bsp/wch/arm/ch32f103c8-core/board/Kconfig

@@ -116,18 +116,18 @@ config BSP_USING_TIM
 
                         if BSP_USING_TIM1_PWM
                                 config BSP_USING_TIM1_PWM_CH1
-                                        bool "using TIM1 channel 1 as pwm"
+                                        bool "using TIM1 channel 1"
                                         default n
 
                                 config BSP_USING_TIM1_PWM_CH2
-                                        bool "using TIM1 channel 2 as pwm"
+                                        bool "using TIM1 channel 2"
                                         default n
 
                                 config BSP_USING_TIM1_PWM_CH3
-                                        bool "using TIM1 channel 3 as pwm"
+                                        bool "using TIM1 channel 3"
 
                                 config BSP_USING_TIM1_PWM_CH4
-                                        bool "using TIM1 channel 4 as pwm"
+                                        bool "using TIM1 channel 4"
 
                         endif
 
@@ -154,18 +154,18 @@ config BSP_USING_TIM
 
                         if BSP_USING_TIM2_PWM
                                 config BSP_USING_TIM2_PWM_CH1
-                                        bool "using TIM2 channel 1 as pwm"
+                                        bool "using TIM2 channel 1"
                                         default n
 
                                 config BSP_USING_TIM2_PWM_CH2
-                                        bool "using TIM2 channel 2 as pwm"
+                                        bool "using TIM2 channel 2"
                                         default n
 
                                 config BSP_USING_TIM2_PWM_CH3
-                                        bool "using TIM2 channel 3 as pwm"
+                                        bool "using TIM2 channel 3"
 
                                 config BSP_USING_TIM2_PWM_CH4
-                                        bool "using TIM2 channel 4 as pwm"
+                                        bool "using TIM2 channel 4"
 
                         endif
 
@@ -192,18 +192,18 @@ config BSP_USING_TIM
 
                         if BSP_USING_TIM3_PWM
                                 config BSP_USING_TIM3_PWM_CH1
-                                        bool "using TIM3 channel 1 as pwm"
+                                        bool "using TIM3 channel 1"
                                         default n
 
                                 config BSP_USING_TIM3_PWM_CH2
-                                        bool "using TIM3 channel 2 as pwm"
+                                        bool "using TIM3 channel 2"
                                         default n
 
                                 config BSP_USING_TIM3_PWM_CH3
-                                        bool "using TIM3 channel 3 as pwm"
+                                        bool "using TIM3 channel 3"
 
                                 config BSP_USING_TIM3_PWM_CH4
-                                        bool "using TIM3 channel 4 as pwm"
+                                        bool "using TIM3 channel 4"
 
                         endif
 
@@ -230,18 +230,18 @@ config BSP_USING_TIM
 
                         if BSP_USING_TIM4_PWM
                                 config BSP_USING_TIM4_PWM_CH1
-                                        bool "using TIM4 channel 1 as pwm"
+                                        bool "using TIM4 channel 1"
                                         default n
 
                                 config BSP_USING_TIM4_PWM_CH2
-                                        bool "using TIM4 channel 2 as pwm"
+                                        bool "using TIM4 channel 2"
                                         default n
 
                                 config BSP_USING_TIM4_PWM_CH3
-                                        bool "using TIM4 channel 3 as pwm"
+                                        bool "using TIM4 channel 3"
 
                                 config BSP_USING_TIM4_PWM_CH4
-                                        bool "using TIM4 channel 4 as pwm"
+                                        bool "using TIM4 channel 4"
 
                         endif
 

+ 144 - 2
bsp/wch/arm/ch32f103c8-core/board/board.c

@@ -200,7 +200,7 @@ void ch32f1_i2c_config(I2C_TypeDef *i2cx)
     }
 }
 
-void ch32f1_hwtimer_clock_init(TIM_TypeDef *timx)
+void ch32f1_tim_clock_init(TIM_TypeDef *timx)
 {
     if (timx == TIM1)
     {
@@ -223,7 +223,7 @@ void ch32f1_hwtimer_clock_init(TIM_TypeDef *timx)
     }
 }
 
-rt_uint32_t ch32f1_hwtimer_clock_get(TIM_TypeDef *timx)
+rt_uint32_t ch32f1_tim_clock_get(TIM_TypeDef *timx)
 {
     RCC_ClocksTypeDef RCC_Clocks;
 
@@ -292,3 +292,145 @@ struct rt_hwtimer_info *ch32f1_hwtimer_info_config_get(TIM_TypeDef *timx)
 
     return info;
 }
+
+void ch32f1_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);
+        }
+    }
+}

+ 3 - 3
bsp/wch/arm/ch32f103c8-core/board/board.h

@@ -50,10 +50,10 @@ void ch32f1_spi_clock_and_io_init(SPI_TypeDef* spix);
 rt_uint32_t ch32f1_spi_clock_get(SPI_TypeDef* spix);
 void ch32f1_i2c_clock_and_io_init(I2C_TypeDef* i2cx);
 void ch32f1_i2c_config(I2C_TypeDef* i2cx);
-void ch32f1_hwtimer_clock_init(TIM_TypeDef *timx);
-rt_uint32_t ch32f1_hwtimer_clock_get(TIM_TypeDef *timx);
+void ch32f1_tim_clock_init(TIM_TypeDef *timx);
+rt_uint32_t ch32f1_tim_clock_get(TIM_TypeDef *timx);
 struct rt_hwtimer_info* ch32f1_hwtimer_info_config_get(TIM_TypeDef *timx);
-
+void ch32f1_pwm_io_init(TIM_TypeDef *timx, rt_uint8_t channel);