Pārlūkot izejas kodu

[bsp/hc32]添加timerA的pwm驱动

梁生 2 gadi atpakaļ
vecāks
revīzija
c7ce44ab3a

+ 19 - 0
bsp/hc32/ev_hc32f460_lqfp100_v2/board/Kconfig

@@ -144,6 +144,25 @@ menu "On-chip Peripheral Drivers"
                 default 49
         endif 
 		
+    menuconfig BSP_USING_PWM_TMRA
+        bool "Enable timerA output PWM"
+        depends on (!BSP_USING_UART3)
+        default n
+        select RT_USING_PWM
+        if BSP_USING_PWM_TMRA
+        menuconfig BSP_USING_PWM_TMRA_4
+            bool "Enable timerA-4 output PWM"
+            default n
+            if BSP_USING_PWM_TMRA_4
+                config BSP_USING_PWM_TMRA_4_CH7
+                    bool "Enable timerA-4 channel7"
+                    default n
+                config BSP_USING_PWM_TMRA_4_CH8
+                    bool "Enable timerA-4 channel8"
+                    default n
+            endif
+        endif
+        
 endmenu
 
 menu "Board extended module Drivers"

+ 185 - 0
bsp/hc32/ev_hc32f460_lqfp100_v2/board/board_config.c

@@ -7,6 +7,8 @@
  * Change Logs:
  * Date           Author       Notes
  * 2022-04-28     CDT          first version
+ * 2022-06-16     lianghongquan     use macro definition config adc pin.
+ * 2022-06-28     lianghongquan     add function rt_hw_board_pwm_tmra_init().
  */
 
 #include <rtdevice.h>
@@ -121,3 +123,186 @@ rt_err_t rt_hw_board_adc_init(CM_ADC_TypeDef *ADCx)
     return result;
 }
 #endif
+
+#if defined(RT_USING_PWM)
+rt_err_t rt_hw_board_pwm_tmra_init(CM_TMRA_TypeDef *TMRAx)
+{
+    rt_err_t result = RT_EOK;
+    switch ((rt_uint32_t)TMRAx)
+    {
+#if defined(BSP_USING_PWM_TMRA_1)
+    case (rt_uint32_t)CM_TMRA_1:
+    #ifdef BSP_USING_PWM_TMRA_1_CH1
+        GPIO_SetFunc(PWM_TMRA_1_CH1_PORT, PWM_TMRA_1_CH1_PIN, PWM_TMRA_1_CH1_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_1_CH2
+        GPIO_SetFunc(PWM_TMRA_1_CH2_PORT, PWM_TMRA_1_CH2_PIN, PWM_TMRA_1_CH2_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_1_CH3
+        GPIO_SetFunc(PWM_TMRA_1_CH3_PORT, PWM_TMRA_1_CH3_PIN, PWM_TMRA_1_CH3_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_1_CH4
+        GPIO_SetFunc(PWM_TMRA_1_CH4_PORT, PWM_TMRA_1_CH4_PIN, PWM_TMRA_1_CH4_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_1_CH5
+        GPIO_SetFunc(PWM_TMRA_1_CH5_PORT, PWM_TMRA_1_CH5_PIN, PWM_TMRA_1_CH5_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_1_CH6
+        GPIO_SetFunc(PWM_TMRA_1_CH6_PORT, PWM_TMRA_1_CH6_PIN, PWM_TMRA_1_CH6_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_1_CH7
+        GPIO_SetFunc(PWM_TMRA_1_CH7_PORT, PWM_TMRA_1_CH7_PIN, PWM_TMRA_1_CH7_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_1_CH8
+        GPIO_SetFunc(PWM_TMRA_1_CH8_PORT, PWM_TMRA_1_CH8_PIN, PWM_TMRA_1_CH8_PIN_FUNC);
+    #endif
+        break;
+#endif
+#if defined(BSP_USING_PWM_TMRA_2)
+    case (rt_uint32_t)CM_TMRA_2:
+    #ifdef BSP_USING_PWM_TMRA_2_CH1
+        GPIO_SetFunc(PWM_TMRA_2_CH1_PORT, PWM_TMRA_2_CH1_PIN, PWM_TMRA_2_CH1_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_2_CH2
+        GPIO_SetFunc(PWM_TMRA_2_CH2_PORT, PWM_TMRA_2_CH2_PIN, PWM_TMRA_2_CH2_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_2_CH3
+        GPIO_SetFunc(PWM_TMRA_2_CH3_PORT, PWM_TMRA_2_CH3_PIN, PWM_TMRA_2_CH3_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_2_CH4
+        GPIO_SetFunc(PWM_TMRA_2_CH4_PORT, PWM_TMRA_2_CH4_PIN, PWM_TMRA_2_CH4_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_2_CH5
+        GPIO_SetFunc(PWM_TMRA_2_CH5_PORT, PWM_TMRA_2_CH5_PIN, PWM_TMRA_2_CH5_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_2_CH6
+        GPIO_SetFunc(PWM_TMRA_2_CH6_PORT, PWM_TMRA_2_CH6_PIN, PWM_TMRA_2_CH6_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_2_CH7
+        GPIO_SetFunc(PWM_TMRA_2_CH7_PORT, PWM_TMRA_2_CH7_PIN, PWM_TMRA_2_CH7_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_2_CH8
+        GPIO_SetFunc(PWM_TMRA_2_CH8_PORT, PWM_TMRA_2_CH8_PIN, PWM_TMRA_2_CH8_PIN_FUNC);
+    #endif
+        break;
+#endif
+#if defined(BSP_USING_PWM_TMRA_3)
+    case (rt_uint32_t)CM_TMRA_3:
+    #ifdef BSP_USING_PWM_TMRA_3_CH1
+        GPIO_SetFunc(PWM_TMRA_3_CH1_PORT, PWM_TMRA_3_CH1_PIN, PWM_TMRA_3_CH1_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_3_CH2
+        GPIO_SetFunc(PWM_TMRA_3_CH2_PORT, PWM_TMRA_3_CH2_PIN, PWM_TMRA_3_CH2_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_3_CH3
+        GPIO_SetFunc(PWM_TMRA_3_CH3_PORT, PWM_TMRA_3_CH3_PIN, PWM_TMRA_3_CH3_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_3_CH4
+        GPIO_SetFunc(PWM_TMRA_3_CH4_PORT, PWM_TMRA_3_CH4_PIN, PWM_TMRA_3_CH4_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_3_CH5
+        GPIO_SetFunc(PWM_TMRA_3_CH5_PORT, PWM_TMRA_3_CH5_PIN, PWM_TMRA_3_CH5_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_3_CH6
+        GPIO_SetFunc(PWM_TMRA_3_CH6_PORT, PWM_TMRA_3_CH6_PIN, PWM_TMRA_3_CH6_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_3_CH7
+        GPIO_SetFunc(PWM_TMRA_3_CH7_PORT, PWM_TMRA_3_CH7_PIN, PWM_TMRA_3_CH7_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_3_CH8
+        GPIO_SetFunc(PWM_TMRA_3_CH8_PORT, PWM_TMRA_3_CH8_PIN, PWM_TMRA_3_CH8_PIN_FUNC);
+    #endif
+        break;
+#endif
+#if defined(BSP_USING_PWM_TMRA_4)
+    case (rt_uint32_t)CM_TMRA_4:
+    #ifdef BSP_USING_PWM_TMRA_4_CH1
+        GPIO_SetFunc(PWM_TMRA_4_CH1_PORT, PWM_TMRA_4_CH1_PIN, PWM_TMRA_4_CH1_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_4_CH2
+        GPIO_SetFunc(PWM_TMRA_4_CH2_PORT, PWM_TMRA_4_CH2_PIN, PWM_TMRA_4_CH2_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_4_CH3
+        GPIO_SetFunc(PWM_TMRA_4_CH3_PORT, PWM_TMRA_4_CH3_PIN, PWM_TMRA_4_CH3_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_4_CH4
+        GPIO_SetFunc(PWM_TMRA_4_CH4_PORT, PWM_TMRA_4_CH4_PIN, PWM_TMRA_4_CH4_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_4_CH5
+        GPIO_SetFunc(PWM_TMRA_4_CH5_PORT, PWM_TMRA_4_CH5_PIN, PWM_TMRA_4_CH5_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_4_CH6
+        GPIO_SetFunc(PWM_TMRA_4_CH6_PORT, PWM_TMRA_4_CH6_PIN, PWM_TMRA_4_CH6_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_4_CH7
+        GPIO_SetFunc(PWM_TMRA_4_CH7_PORT, PWM_TMRA_4_CH7_PIN, PWM_TMRA_4_CH7_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_4_CH8
+        GPIO_SetFunc(PWM_TMRA_4_CH8_PORT, PWM_TMRA_4_CH8_PIN, PWM_TMRA_4_CH8_PIN_FUNC);
+    #endif
+        break;
+#endif
+#if defined(BSP_USING_PWM_TMRA_5)
+    case (rt_uint32_t)CM_TMRA_5:
+    #ifdef BSP_USING_PWM_TMRA_5_CH1
+        GPIO_SetFunc(PWM_TMRA_5_CH1_PORT, PWM_TMRA_5_CH1_PIN, PWM_TMRA_5_CH1_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_5_CH2
+        GPIO_SetFunc(PWM_TMRA_5_CH2_PORT, PWM_TMRA_5_CH2_PIN, PWM_TMRA_5_CH2_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_5_CH3
+        GPIO_SetFunc(PWM_TMRA_5_CH3_PORT, PWM_TMRA_5_CH3_PIN, PWM_TMRA_5_CH3_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_5_CH4
+        GPIO_SetFunc(PWM_TMRA_5_CH4_PORT, PWM_TMRA_5_CH4_PIN, PWM_TMRA_5_CH4_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_5_CH5
+        GPIO_SetFunc(PWM_TMRA_5_CH5_PORT, PWM_TMRA_5_CH5_PIN, PWM_TMRA_5_CH5_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_5_CH6
+        GPIO_SetFunc(PWM_TMRA_5_CH6_PORT, PWM_TMRA_5_CH6_PIN, PWM_TMRA_5_CH6_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_5_CH7
+        GPIO_SetFunc(PWM_TMRA_5_CH7_PORT, PWM_TMRA_5_CH7_PIN, PWM_TMRA_5_CH7_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_5_CH8
+        GPIO_SetFunc(PWM_TMRA_5_CH8_PORT, PWM_TMRA_5_CH8_PIN, PWM_TMRA_5_CH8_PIN_FUNC);
+    #endif
+        break;
+#endif
+#if defined(BSP_USING_PWM_TMRA_6)
+    case (rt_uint32_t)CM_TMRA_6:
+    #ifdef BSP_USING_PWM_TMRA_6_CH1
+        GPIO_SetFunc(PWM_TMRA_6_CH1_PORT, PWM_TMRA_6_CH1_PIN, PWM_TMRA_6_CH1_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_6_CH2
+        GPIO_SetFunc(PWM_TMRA_6_CH2_PORT, PWM_TMRA_6_CH2_PIN, PWM_TMRA_6_CH2_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_6_CH3
+        GPIO_SetFunc(PWM_TMRA_6_CH3_PORT, PWM_TMRA_6_CH3_PIN, PWM_TMRA_6_CH3_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_6_CH4
+        GPIO_SetFunc(PWM_TMRA_6_CH4_PORT, PWM_TMRA_6_CH4_PIN, PWM_TMRA_6_CH4_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_6_CH5
+        GPIO_SetFunc(PWM_TMRA_6_CH5_PORT, PWM_TMRA_6_CH5_PIN, PWM_TMRA_6_CH5_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_6_CH6
+        GPIO_SetFunc(PWM_TMRA_6_CH6_PORT, PWM_TMRA_6_CH6_PIN, PWM_TMRA_6_CH6_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_6_CH7
+        GPIO_SetFunc(PWM_TMRA_6_CH7_PORT, PWM_TMRA_6_CH7_PIN, PWM_TMRA_6_CH7_PIN_FUNC);
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_6_CH8
+        GPIO_SetFunc(PWM_TMRA_6_CH8_PORT, PWM_TMRA_6_CH8_PIN, PWM_TMRA_6_CH8_PIN_FUNC);
+    #endif
+        break;
+#endif
+    default:
+        result = -RT_ERROR;
+        break;
+    }
+
+    return result;
+}
+#endif

+ 13 - 0
bsp/hc32/ev_hc32f460_lqfp100_v2/board/board_config.h

@@ -7,6 +7,8 @@
  * Change Logs:
  * Date           Author       Notes
  * 2022-04-28     CDT          first version
+ * 2022-06-16     lianghongquan     use macro definition config adc pin.
+ * 2022-06-28     lianghongquan     add PWM_TMRA pin define.
  */
 
 
@@ -84,4 +86,15 @@
     #define ADC2_CH7_PIN                      (GPIO_PIN_01)
 #endif
 
+/***********  PWM_TMRA configure *********/
+#if defined(BSP_USING_PWM_TMRA_4)
+    #define PWM_TMRA_4_CH7_PORT             (GPIO_PORT_H)
+    #define PWM_TMRA_4_CH7_PIN              (GPIO_PIN_02)
+    #define PWM_TMRA_4_CH7_PIN_FUNC         (GPIO_FUNC_4)
+
+    #define PWM_TMRA_4_CH8_PORT             (GPIO_PORT_C)
+    #define PWM_TMRA_4_CH8_PIN              (GPIO_PIN_13)
+    #define PWM_TMRA_4_CH8_PIN_FUNC         (GPIO_FUNC_4)
+#endif
+
 #endif

+ 205 - 0
bsp/hc32/ev_hc32f460_lqfp100_v2/board/config/pwm_tmra_config.h

@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2022-06-27     lianghongquan     first version
+ */
+
+#ifndef __PWM_TMRA_CONFIG_H__
+#define __PWM_TMRA_CONFIG_H__
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef BSP_USING_PWM_TMRA_1
+#ifndef PWM_TMRA_1_CONFIG
+#define PWM_TMRA_1_CONFIG                                       \
+    {                                                           \
+        .name                           = "pwm_a1",             \
+        .instance                       = CM_TMRA_1,            \
+        .channel                        = 0,                    \
+        .stcTmraInit =                                          \
+        {                                                       \
+            .u8CountSrc                 = TMRA_CNT_SRC_SW,      \
+            .u32PeriodValue             = 0xFFFF,               \
+            .sw_count =                                         \
+            {                                                   \
+                .u16ClockDiv            = TMRA_CLK_DIV1,        \
+                .u16CountMode           = TMRA_MD_SAWTOOTH,     \
+                .u16CountDir            = TMRA_DIR_DOWN,        \
+            },                                                  \
+        },                                                      \
+        .stcPwmInit =                                           \
+        {                                                       \
+            .u32CompareValue            = 0x0000,               \
+            .u16StartPolarity           = TMRA_PWM_LOW,         \
+            .u16StopPolarity            = TMRA_PWM_LOW,         \
+            .u16CompareMatchPolarity    = TMRA_PWM_HIGH,        \
+            .u16PeriodMatchPolarity     = TMRA_PWM_LOW,         \
+        },                                                      \
+    }
+#endif /* PWM_TMRA_1_CONFIG */
+#endif /* BSP_USING_PWM_TMRA_1 */
+
+#ifdef BSP_USING_PWM_TMRA_2
+#ifndef PWM_TMRA_2_CONFIG
+#define PWM_TMRA_2_CONFIG                                       \
+    {                                                           \
+        .name                           = "pwm_a2",             \
+        .instance                       = CM_TMRA_2,            \
+        .channel                        = 0,                    \
+        .stcTmraInit =                                          \
+        {                                                       \
+            .u8CountSrc                 = TMRA_CNT_SRC_SW,      \
+            .u32PeriodValue             = 0xFFFF,               \
+            .sw_count =                                         \
+            {                                                   \
+                .u16ClockDiv            = TMRA_CLK_DIV1,        \
+                .u16CountMode           = TMRA_MD_SAWTOOTH,     \
+                .u16CountDir            = TMRA_DIR_DOWN,        \
+            },                                                  \
+        },                                                      \
+        .stcPwmInit =                                           \
+        {                                                       \
+            .u32CompareValue            = 0x0000,               \
+            .u16StartPolarity           = TMRA_PWM_LOW,         \
+            .u16StopPolarity            = TMRA_PWM_LOW,         \
+            .u16CompareMatchPolarity    = TMRA_PWM_HIGH,        \
+            .u16PeriodMatchPolarity     = TMRA_PWM_LOW,         \
+        },                                                      \
+    }
+#endif /* PWM_TMRA_2_CONFIG */
+#endif /* BSP_USING_PWM_TMRA_2 */
+
+#ifdef BSP_USING_PWM_TMRA_3
+#ifndef PWM_TMRA_3_CONFIG
+#define PWM_TMRA_3_CONFIG                                       \
+    {                                                           \
+        .name                           = "pwm_a3",             \
+        .instance                       = CM_TMRA_3,            \
+        .channel                        = 0,                    \
+        .stcTmraInit =                                          \
+        {                                                       \
+            .u8CountSrc                 = TMRA_CNT_SRC_SW,      \
+            .u32PeriodValue             = 0xFFFF,               \
+            .sw_count =                                         \
+            {                                                   \
+                .u16ClockDiv            = TMRA_CLK_DIV1,        \
+                .u16CountMode           = TMRA_MD_SAWTOOTH,     \
+                .u16CountDir            = TMRA_DIR_DOWN,        \
+            },                                                  \
+        },                                                      \
+        .stcPwmInit =                                           \
+        {                                                       \
+            .u32CompareValue            = 0x0000,               \
+            .u16StartPolarity           = TMRA_PWM_LOW,         \
+            .u16StopPolarity            = TMRA_PWM_LOW,         \
+            .u16CompareMatchPolarity    = TMRA_PWM_HIGH,        \
+            .u16PeriodMatchPolarity     = TMRA_PWM_LOW,         \
+        },                                                      \
+    }
+#endif /* PWM_TMRA_3_CONFIG */
+#endif /* BSP_USING_PWM_TMRA_3 */
+
+#ifdef BSP_USING_PWM_TMRA_4
+#ifndef PWM_TMRA_4_CONFIG
+#define PWM_TMRA_4_CONFIG                                       \
+    {                                                           \
+        .name                           = "pwm_a4",             \
+        .instance                       = CM_TMRA_4,            \
+        .channel                        = 0,                    \
+        .stcTmraInit =                                          \
+        {                                                       \
+            .u8CountSrc                 = TMRA_CNT_SRC_SW,      \
+            .u32PeriodValue             = 0xFFFF,               \
+            .sw_count =                                         \
+            {                                                   \
+                .u16ClockDiv            = TMRA_CLK_DIV1,        \
+                .u16CountMode           = TMRA_MD_SAWTOOTH,     \
+                .u16CountDir            = TMRA_DIR_DOWN,        \
+            },                                                  \
+        },                                                      \
+        .stcPwmInit =                                           \
+        {                                                       \
+            .u32CompareValue            = 0x0000,               \
+            .u16StartPolarity           = TMRA_PWM_LOW,         \
+            .u16StopPolarity            = TMRA_PWM_LOW,         \
+            .u16CompareMatchPolarity    = TMRA_PWM_HIGH,        \
+            .u16PeriodMatchPolarity     = TMRA_PWM_LOW,         \
+        },                                                      \
+    }
+#endif /* PWM_TMRA_4_CONFIG */
+#endif /* BSP_USING_PWM_TMRA_4 */
+
+#ifdef BSP_USING_PWM_TMRA_5
+#ifndef PWM_TMRA_5_CONFIG
+#define PWM_TMRA_5_CONFIG                                       \
+    {                                                           \
+        .name                           = "pwm_a5",             \
+        .instance                       = CM_TMRA_5,            \
+        .channel                        = 0,                    \
+        .stcTmraInit =                                          \
+        {                                                       \
+            .u8CountSrc                 = TMRA_CNT_SRC_SW,      \
+            .u32PeriodValue             = 0xFFFF,               \
+            .sw_count =                                         \
+            {                                                   \
+                .u16ClockDiv            = TMRA_CLK_DIV1,        \
+                .u16CountMode           = TMRA_MD_SAWTOOTH,     \
+                .u16CountDir            = TMRA_DIR_DOWN,        \
+            },                                                  \
+        },                                                      \
+        .stcPwmInit =                                           \
+        {                                                       \
+            .u32CompareValue            = 0x0000,               \
+            .u16StartPolarity           = TMRA_PWM_LOW,         \
+            .u16StopPolarity            = TMRA_PWM_LOW,         \
+            .u16CompareMatchPolarity    = TMRA_PWM_HIGH,        \
+            .u16PeriodMatchPolarity     = TMRA_PWM_LOW,         \
+        },                                                      \
+    }
+#endif /* PWM_TMRA_5_CONFIG */
+#endif /* BSP_USING_PWM_TMRA_5 */
+
+#ifdef BSP_USING_PWM_TMRA_6
+#ifndef PWM_TMRA_6_CONFIG
+#define PWM_TMRA_6_CONFIG                                       \
+    {                                                           \
+        .name                           = "pwm_a6",             \
+        .instance                       = CM_TMRA_6,            \
+        .channel                        = 0,                    \
+        .stcTmraInit =                                          \
+        {                                                       \
+            .u8CountSrc                 = TMRA_CNT_SRC_SW,      \
+            .u32PeriodValue             = 0xFFFF,               \
+            .sw_count =                                         \
+            {                                                   \
+                .u16ClockDiv            = TMRA_CLK_DIV1,        \
+                .u16CountMode           = TMRA_MD_SAWTOOTH,     \
+                .u16CountDir            = TMRA_DIR_DOWN,        \
+            },                                                  \
+        },                                                      \
+        .stcPwmInit =                                           \
+        {                                                       \
+            .u32CompareValue            = 0x0000,               \
+            .u16StartPolarity           = TMRA_PWM_LOW,         \
+            .u16StopPolarity            = TMRA_PWM_LOW,         \
+            .u16CompareMatchPolarity    = TMRA_PWM_HIGH,        \
+            .u16PeriodMatchPolarity     = TMRA_PWM_LOW,         \
+        },                                                      \
+    }
+#endif /* PWM_TMRA_6_CONFIG */
+#endif /* BSP_USING_PWM_TMRA_6 */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PWM_TMRA_CONFIG_H__ */

+ 1 - 0
bsp/hc32/ev_hc32f460_lqfp100_v2/board/drv_config.h

@@ -32,6 +32,7 @@ extern "C" {
 #include "gpio_config.h"
 #include "can_config.h"
 #include "adc_config.h"
+#include "pwm_tmra_config.h"
 
 #ifdef __cplusplus
 }

+ 3 - 0
bsp/hc32/libraries/hc32_drivers/SConscript

@@ -33,6 +33,9 @@ if GetDepend(['RT_USING_CAN']):
 if GetDepend(['RT_USING_RTC']):
     src += ['drv_rtc.c']
 
+if GetDepend(['RT_USING_PWM', 'BSP_USING_PWM_TMRA']):
+    src += ['drv_pwm_tmra.c']
+
 path = [cwd]
 
 group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)

+ 437 - 0
bsp/hc32/libraries/hc32_drivers/drv_pwm_tmra.c

@@ -0,0 +1,437 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2022-06-27     lianghongquan     first version
+ */
+
+#include <board.h>
+
+#if (defined RT_USING_PWM) && (defined BSP_USING_PWM_TMRA)
+#include "drv_config.h"
+#include <drivers/rt_drv_pwm.h>
+
+//#define DRV_DEBUG
+#define LOG_TAG             "drv.pwm.tmra"
+#include <drv_log.h>
+
+#if (!(defined(BSP_USING_PWM_TMRA_1) || defined(BSP_USING_PWM_TMRA_2) || \
+       defined(BSP_USING_PWM_TMRA_3) || defined(BSP_USING_PWM_TMRA_4) || \
+       defined(BSP_USING_PWM_TMRA_5) || defined(BSP_USING_PWM_TMRA_6)))
+    #error "Please define at least one BSP_USING_PWM_TMRA_x"
+#endif
+
+enum
+{
+#ifdef BSP_USING_PWM_TMRA_1
+    PWM_TMRA_1_INDEX,
+#endif
+#ifdef BSP_USING_PWM_TMRA_2
+    PWM_TMRA_2_INDEX,
+#endif
+#ifdef BSP_USING_PWM_TMRA_3
+    PWM_TMRA_3_INDEX,
+#endif
+#ifdef BSP_USING_PWM_TMRA_4
+    PWM_TMRA_4_INDEX,
+#endif
+#ifdef BSP_USING_PWM_TMRA_5
+    PWM_TMRA_5_INDEX,
+#endif
+#ifdef BSP_USING_PWM_TMRA_6
+    PWM_TMRA_6_INDEX,
+#endif
+};
+
+struct hc32_pwm_tmra
+{
+    struct rt_device_pwm pwm_device;
+    CM_TMRA_TypeDef *instance;
+    stc_tmra_init_t stcTmraInit;
+    stc_tmra_pwm_init_t stcPwmInit;
+    rt_uint8_t channel;
+    char *name;
+};
+
+static struct hc32_pwm_tmra g_pwm_dev_array[] =
+{
+#ifdef BSP_USING_PWM_TMRA_1
+    PWM_TMRA_1_CONFIG,
+#endif
+#ifdef BSP_USING_PWM_TMRA_2
+    PWM_TMRA_2_CONFIG,
+#endif
+#ifdef BSP_USING_PWM_TMRA_3
+    PWM_TMRA_3_CONFIG,
+#endif
+#ifdef BSP_USING_PWM_TMRA_4
+    PWM_TMRA_4_CONFIG,
+#endif
+#ifdef BSP_USING_PWM_TMRA_5
+    PWM_TMRA_5_CONFIG,
+#endif
+#ifdef BSP_USING_PWM_TMRA_6
+    PWM_TMRA_6_CONFIG,
+#endif
+};
+
+static rt_uint32_t get_tmra_clk_freq_not_div(CM_TMRA_TypeDef *TMRAx)
+{
+    stc_clock_freq_t stcClockFreq;
+    CLK_GetClockFreq(&stcClockFreq);
+    return stcClockFreq.u32Pclk1Freq;
+}
+
+static rt_uint32_t get_tmra_clk_freq(CM_TMRA_TypeDef *TMRAx)
+{
+    rt_uint32_t u32clkFreq;
+    uint16_t u16Div;
+    //
+    u32clkFreq = get_tmra_clk_freq_not_div(TMRAx);
+    u16Div = READ_REG16(TMRAx->BCSTR) & TMRA_BCSTR_CKDIV;
+    switch (u16Div)
+    {
+        case (TMRA_CLK_DIV2):
+            u32clkFreq /= 2;
+            break;
+        case (TMRA_CLK_DIV4):
+            u32clkFreq /= 4;
+            break;
+        case (TMRA_CLK_DIV8):
+            u32clkFreq /= 8;
+            break;
+        case (TMRA_CLK_DIV16):
+            u32clkFreq /= 16;
+            break;
+        case (TMRA_CLK_DIV32):
+            u32clkFreq /= 32;
+            break;
+        case (TMRA_CLK_DIV64):
+            u32clkFreq /= 64;
+            break;
+        case (TMRA_CLK_DIV128):
+            u32clkFreq /= 128;
+            break;
+        case (TMRA_CLK_DIV256):
+            u32clkFreq /= 256;
+            break;
+        case (TMRA_CLK_DIV512):
+            u32clkFreq /= 512;
+            break;
+        case (TMRA_CLK_DIV1024):
+            u32clkFreq /= 1024;
+            break;
+        case (TMRA_CLK_DIV1):
+        default:
+            break;
+    }
+    return u32clkFreq;
+}
+
+static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg);
+static struct rt_pwm_ops drv_ops =
+{
+    drv_pwm_control
+};
+
+static rt_err_t drv_pwm_enable(CM_TMRA_TypeDef *TMRAx, struct rt_pwm_configuration *configuration, rt_bool_t enable)
+{
+    if (RT_TRUE == enable) {TMRA_PWM_OutputCmd(TMRAx, configuration->channel, ENABLE);}
+    else {TMRA_PWM_OutputCmd(TMRAx, configuration->channel, DISABLE);}
+    return RT_EOK;
+}
+
+static rt_err_t drv_pwm_get(CM_TMRA_TypeDef *TMRAx, struct rt_pwm_configuration *configuration)
+{
+    rt_uint32_t u32clkFreq;
+    rt_uint64_t u64clk_ns;
+    u32clkFreq = get_tmra_clk_freq(TMRAx);
+    u64clk_ns = (rt_uint64_t)1000000000ul / u32clkFreq;
+    configuration->period = u64clk_ns * TMRA_GetPeriodValue(TMRAx);
+    configuration->pulse = u64clk_ns * TMRA_GetCompareValue(TMRAx, configuration->channel);
+    return RT_EOK;
+}
+
+static rt_err_t drv_pwm_set(CM_TMRA_TypeDef *TMRAx, struct rt_pwm_configuration *configuration)
+{
+    rt_uint32_t u32clkFreq;
+    rt_uint64_t u64clk_ns;
+    rt_uint64_t u64val;
+    //
+    u32clkFreq = get_tmra_clk_freq(TMRAx);
+    u64clk_ns = (rt_uint64_t)1000000000ul / u32clkFreq;
+    u64val = (rt_uint64_t)configuration->period / u64clk_ns;
+    if ((configuration->period <= u64clk_ns) || (u64val > 0xFFFF))
+    {
+        // clk not match, need change div
+        uint32_t div_bit;
+        u32clkFreq = get_tmra_clk_freq_not_div(TMRAx);
+        u64clk_ns = (rt_uint64_t)1000000000ul / u32clkFreq;
+        u64val = (rt_uint64_t)configuration->period / u64clk_ns;
+        for (div_bit=0; div_bit<= 10; div_bit++)
+        {
+            if (u64val < 0xFFFF) break;
+            u64val /= 2;
+        }
+        if (div_bit > 10) return RT_ERROR;
+        //
+        TMRA_SetClockDiv(TMRAx, div_bit << TMRA_BCSTR_CKDIV_POS);
+        u32clkFreq = get_tmra_clk_freq(TMRAx);
+        u64clk_ns = (rt_uint64_t)1000000000ul / u32clkFreq;
+    }
+    TMRA_SetPeriodValue(TMRAx, configuration->period / u64clk_ns);
+    TMRA_SetCompareValue(TMRAx, configuration->channel, configuration->pulse / u64clk_ns);
+    return RT_EOK;
+}
+
+static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
+{
+    struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
+    struct hc32_pwm_tmra *pwm;
+    pwm = rt_container_of(device, struct hc32_pwm_tmra, pwm_device);
+    CM_TMRA_TypeDef *TMRAx = pwm->instance;
+
+    switch (cmd)
+    {
+    case PWMN_CMD_ENABLE:
+        configuration->complementary = RT_TRUE;
+    case PWM_CMD_ENABLE:
+        return drv_pwm_enable(TMRAx, configuration, RT_TRUE);
+    case PWMN_CMD_DISABLE:
+        configuration->complementary = RT_FALSE;
+    case PWM_CMD_DISABLE:
+        return drv_pwm_enable(TMRAx, configuration, RT_FALSE);
+    case PWM_CMD_SET:
+        return drv_pwm_set(TMRAx, configuration);
+    case PWM_CMD_GET:
+        return drv_pwm_get(TMRAx, configuration);
+    default:
+        return RT_EINVAL;
+    }
+}
+
+static rt_err_t _pwm_tmra_init(struct hc32_pwm_tmra *device)
+{
+    CM_TMRA_TypeDef *TMRAx;
+    uint32_t i;
+    //
+    RT_ASSERT(device != RT_NULL);
+    TMRAx = device->instance;
+    TMRA_Init(TMRAx, &device->stcTmraInit);
+    for (i=0; i<8; i++)
+    {
+        if ((device->channel >> i) & 0x01)
+        {
+            TMRA_PWM_Init(TMRAx, i, &device->stcPwmInit);
+        }
+    }
+    TMRA_Start(TMRAx);
+    return RT_EOK;
+}
+
+static void pwm_get_channel(void)
+{
+#ifdef BSP_USING_PWM_TMRA_1
+    #ifdef BSP_USING_PWM_TMRA_1_CH1
+        g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 0;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_1_CH2
+        g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 1;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_1_CH3
+        g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 2;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_1_CH4
+        g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 3;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_1_CH5
+        g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 4;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_1_CH6
+        g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 5;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_1_CH7
+        g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 6;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_1_CH8
+        g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 7;
+    #endif
+#endif
+#ifdef BSP_USING_PWM_TMRA_2
+    #ifdef BSP_USING_PWM_TMRA_2_CH1
+        g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 0;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_2_CH2
+        g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 1;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_2_CH3
+        g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 2;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_2_CH4
+        g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 3;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_2_CH5
+        g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 4;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_2_CH6
+        g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 5;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_2_CH7
+        g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 6;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_2_CH8
+        g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 7;
+    #endif
+#endif
+#ifdef BSP_USING_PWM_TMRA_3
+    #ifdef BSP_USING_PWM_TMRA_3_CH1
+        g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 0;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_3_CH2
+        g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 1;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_3_CH3
+        g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 2;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_3_CH4
+        g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 3;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_3_CH5
+        g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 4;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_3_CH6
+        g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 5;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_3_CH7
+        g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 6;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_3_CH8
+        g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 7;
+    #endif
+#endif
+#ifdef BSP_USING_PWM_TMRA_4
+    #ifdef BSP_USING_PWM_TMRA_4_CH1
+        g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 0;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_4_CH2
+        g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 1;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_4_CH3
+        g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 2;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_4_CH4
+        g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 3;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_4_CH5
+        g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 4;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_4_CH6
+        g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 5;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_4_CH7
+        g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 6;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_4_CH8
+        g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 7;
+    #endif
+#endif
+#ifdef BSP_USING_PWM_TMRA_5
+    #ifdef BSP_USING_PWM_TMRA_5_CH1
+        g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 0;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_5_CH2
+        g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 1;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_5_CH3
+        g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 2;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_5_CH4
+        g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 3;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_5_CH5
+        g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 4;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_5_CH6
+        g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 5;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_5_CH7
+        g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 6;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_5_CH8
+        g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 7;
+    #endif
+#endif
+#ifdef BSP_USING_PWM_TMRA_6
+    #ifdef BSP_USING_PWM_TMRA_6_CH1
+        g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 0;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_6_CH2
+        g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 1;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_6_CH3
+        g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 2;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_6_CH4
+        g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 3;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_6_CH5
+        g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 4;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_6_CH6
+        g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 5;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_6_CH7
+        g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 6;
+    #endif
+    #ifdef BSP_USING_PWM_TMRA_6_CH8
+        g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 7;
+    #endif
+#endif
+}
+
+static void _enable_periph_clk(void)
+{
+#ifdef BSP_USING_PWM_TMRA_1
+    FCG_Fcg2PeriphClockCmd(FCG2_PERIPH_TMRA_1, ENABLE);
+#endif
+#ifdef BSP_USING_PWM_TMRA_2
+    FCG_Fcg2PeriphClockCmd(FCG2_PERIPH_TMRA_2, ENABLE);
+#endif
+#ifdef BSP_USING_PWM_TMRA_3
+    FCG_Fcg2PeriphClockCmd(FCG2_PERIPH_TMRA_3, ENABLE);
+#endif
+#ifdef BSP_USING_PWM_TMRA_4
+    FCG_Fcg2PeriphClockCmd(FCG2_PERIPH_TMRA_4, ENABLE);
+#endif
+#ifdef BSP_USING_PWM_TMRA_5
+    FCG_Fcg2PeriphClockCmd(FCG2_PERIPH_TMRA_5, ENABLE);
+#endif
+#ifdef BSP_USING_PWM_TMRA_6
+    FCG_Fcg2PeriphClockCmd(FCG2_PERIPH_TMRA_6, ENABLE);
+#endif
+}
+
+extern rt_err_t rt_hw_board_pwm_tmra_init(CM_TMRA_TypeDef *TMRAx);
+static int rt_hw_pwm_tmra_init(void)
+{
+    int i = 0;
+    rt_err_t result = RT_EOK;
+
+    pwm_get_channel();
+    _enable_periph_clk();
+    for (i = 0; i < sizeof(g_pwm_dev_array) / sizeof(g_pwm_dev_array[0]); i++)
+    {
+        /* pwm init */
+        _pwm_tmra_init(&g_pwm_dev_array[i]);
+        rt_hw_board_pwm_tmra_init(g_pwm_dev_array[i].instance);
+        /* register UART device */
+        result = rt_device_pwm_register(&g_pwm_dev_array[i].pwm_device, g_pwm_dev_array[i].name, &drv_ops, &g_pwm_dev_array[i].instance);
+        RT_ASSERT(result == RT_EOK);
+    }
+    return result;
+}
+INIT_DEVICE_EXPORT(rt_hw_pwm_tmra_init);
+#endif /* RT_USING_PWM */

+ 1 - 1
bsp/hc32/libraries/hc32f460_ddl/SConscript

@@ -59,7 +59,7 @@ if GetDepend(['RT_USING_SDIO']):
 if GetDepend(['RT_USING_ON_CHIP_FLASH']):
     src += ['drivers/hc32_ll_driver/src/hc32_ll_efm.c']
 
-if GetDepend(['RT_USING_HWTIMER']) or GetDepend(['RT_USING_PWM'] or GetDepend(['RT_USING_PULSE_ENCODER'])):
+if GetDepend(['RT_USING_HWTIMER']) or GetDepend(['RT_USING_PWM'] or GetDepend(['RT_USING_PULSE_ENCODER']) or GetDepend(['BSP_USING_PWM_TMRA'])):
     src += ['drivers/hc32_ll_driver/src/hc32_ll_tmra.c']
     
 path = [