Browse Source

[bsp][bluetrum] add pwm support

greedyhao 4 years ago
parent
commit
801aa4747b

+ 2 - 13
bsp/bluetrum/ab32vg1-ab-prougen/.config

@@ -107,13 +107,7 @@ CONFIG_FINSH_ARG_MAX=10
 #
 #
 # Device virtual file system
 # Device virtual file system
 #
 #
-CONFIG_RT_USING_DFS=y
-CONFIG_DFS_USING_WORKDIR=y
-CONFIG_DFS_FILESYSTEMS_MAX=2
-CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
-CONFIG_DFS_FD_MAX=16
-# CONFIG_RT_USING_DFS_MNTTABLE is not set
-# CONFIG_RT_USING_DFS_ELMFAT is not set
+# CONFIG_RT_USING_DFS is not set
 # CONFIG_RT_DFS_ELM_USE_LFN_0 is not set
 # CONFIG_RT_DFS_ELM_USE_LFN_0 is not set
 # CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
 # CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
 # CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
 # CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
@@ -122,11 +116,6 @@ CONFIG_DFS_FD_MAX=16
 # CONFIG_RT_DFS_ELM_LFN_UNICODE_1 is not set
 # CONFIG_RT_DFS_ELM_LFN_UNICODE_1 is not set
 # CONFIG_RT_DFS_ELM_LFN_UNICODE_2 is not set
 # CONFIG_RT_DFS_ELM_LFN_UNICODE_2 is not set
 # CONFIG_RT_DFS_ELM_LFN_UNICODE_3 is not set
 # CONFIG_RT_DFS_ELM_LFN_UNICODE_3 is not set
-# CONFIG_RT_USING_DFS_DEVFS is not set
-# CONFIG_RT_USING_DFS_ROMFS is not set
-# CONFIG_RT_USING_DFS_RAMFS is not set
-# CONFIG_RT_USING_DFS_UFFS is not set
-# CONFIG_RT_USING_DFS_JFFS2 is not set
 
 
 #
 #
 # Device Drivers
 # Device Drivers
@@ -172,7 +161,6 @@ CONFIG_RT_USING_PIN=y
 #
 #
 CONFIG_RT_USING_LIBC=y
 CONFIG_RT_USING_LIBC=y
 # CONFIG_RT_USING_PTHREADS is not set
 # CONFIG_RT_USING_PTHREADS is not set
-# CONFIG_RT_USING_POSIX is not set
 # CONFIG_RT_USING_MODULE is not set
 # CONFIG_RT_USING_MODULE is not set
 
 
 #
 #
@@ -525,6 +513,7 @@ CONFIG_BSP_USING_USB_TO_USART=y
 CONFIG_BSP_USING_UART0=y
 CONFIG_BSP_USING_UART0=y
 # CONFIG_BSP_USING_SDIO is not set
 # CONFIG_BSP_USING_SDIO is not set
 # CONFIG_BSP_USING_I2C1 is not set
 # CONFIG_BSP_USING_I2C1 is not set
+# CONFIG_BSP_USING_PWM is not set
 # CONFIG_BSP_USING_WDT is not set
 # CONFIG_BSP_USING_WDT is not set
 # CONFIG_BSP_USING_TIM is not set
 # CONFIG_BSP_USING_TIM is not set
 
 

+ 20 - 20
bsp/bluetrum/ab32vg1-ab-prougen/README.md

@@ -30,26 +30,26 @@ ab32vg1-prougen 是 中科蓝讯(Bluetrum) 推出的一款基于 RISC-V 内核
 
 
 本 BSP 目前对外设的支持情况如下:
 本 BSP 目前对外设的支持情况如下:
 
 
-| **板载外设** | **支持情况** | **备注**    |
-| :----------- | :----------: | :---------- |
-| USB 转串口   |     支持     |             |
-| SD卡         |     支持     |             |
-| IRDA         |   即将支持   |             |
-| 音频接口     |     支持     |             |
-| **片上外设** | **支持情况** | **备注**    |
-| GPIO         |     支持     | PA PB PE PF |
-| UART         |     支持     | UART0/1/2   |
-| SDIO         |     支持     |             |
-| ADC          |   即将支持   |             |
-| SPI          |   即将支持   | 软件 SPI    |
-| I2C          |     支持     | 软件 I2C    |
-| RTC          |   即将支持   |             |
-| WDT          |     支持     |             |
-| FLASH        |   即将支持   |             |
-| TIMER        |     支持     |             |
-| PWM          |   即将支持   |             |
-| USB Device   |   暂不支持   |             |
-| USB Host     |   暂不支持   |             |
+| **板载外设** | **支持情况** | **备注**                                  |
+| :----------- | :----------: | :---------------------------------------- |
+| USB 转串口   |     支持     |                                           |
+| SD卡         |     支持     |                                           |
+| IRDA         |   即将支持   |                                           |
+| 音频接口     |     支持     |                                           |
+| **片上外设** | **支持情况** | **备注**                                  |
+| GPIO         |     支持     | PA PB PE PF                               |
+| UART         |     支持     | UART0/1/2                                 |
+| SDIO         |     支持     |                                           |
+| ADC          |   即将支持   |                                           |
+| SPI          |   即将支持   | 软件 SPI                                  |
+| I2C          |     支持     | 软件 I2C                                  |
+| RTC          |   即将支持   |                                           |
+| WDT          |     支持     |                                           |
+| FLASH        |   即将支持   |                                           |
+| TIMER        |     支持     |                                           |
+| PWM          |     支持     | LPWM 的 G1 G2 G3 之间是互斥的,只能三选一 |
+| USB Device   |   暂不支持   |                                           |
+| USB Host     |   暂不支持   |                                           |
 
 
 ## 使用说明
 ## 使用说明
 
 

+ 66 - 0
bsp/bluetrum/ab32vg1-ab-prougen/board/Kconfig

@@ -65,6 +65,72 @@ menu "On-chip Peripheral Drivers"
                 default 15
                 default 15
         endif
         endif
 
 
+    menuconfig BSP_USING_PWM
+        bool "Enable PWM"
+        default n
+        select RT_USING_PWM
+        if BSP_USING_PWM
+        menuconfig BSP_USING_T3_PWM
+            bool "Enable Timer3 PWM"
+            default n
+            if BSP_USING_T3_PWM
+                config BSP_USING_T3_PWM0
+                    bool "Enable Timer3 PWM0 (PB0)(Confict with SD card)"
+                    default n
+            endif
+
+        menuconfig BSP_USING_T4_PWM
+            bool "Enable Timer4 PWM"
+            default n
+            if BSP_USING_T4_PWM
+                config BSP_USING_T4_PWM1
+                    bool "Enable Timer4 PWM1 (PA6)(Confit with uart0 rx)"
+                    default n
+            endif
+
+        menuconfig BSP_USING_T5_PWM
+            bool "Enable Timer5 PWM"
+            default n
+            if BSP_USING_T5_PWM
+                config BSP_USING_T5_PWM0
+                    bool "Enable Timer5 PWM2 (PE1)"
+                    default n
+            endif
+
+        menuconfig BSP_USING_LPWM0
+            bool "Enable LPWM0"
+            default n
+            if BSP_USING_LPWM0
+                comment "G1, G2 and G3 are mutually exclusive"
+                config BSP_USING_LPWM0_G1
+                    bool "Enable LPWM0 G1 (PE4)"
+                    default n
+            endif
+
+        menuconfig BSP_USING_LPWM1
+            bool "Enable LPWM1"
+            default n
+            if BSP_USING_LPWM1
+                comment "G1, G2 and G3 are mutually exclusive"
+                config BSP_USING_LPWM1_G3
+                    bool "Enable LPWM1 G3 (PA1)"
+                    default n
+            endif
+
+        menuconfig BSP_USING_LPWM2
+            bool "Enable LPWM2"
+            default n
+            if BSP_USING_LPWM2
+                comment "G1, G2 and G3 are mutually exclusive"
+                config BSP_USING_LPWM2_G2
+                    bool "Enable LPWM2 G2 (PE0)"
+                    default n
+                config BSP_USING_LPWM2_G3
+                    bool "Enable LPWM2 G3 (PA2)"
+                    default n
+            endif
+        endif
+
     config BSP_USING_WDT
     config BSP_USING_WDT
         bool "Enable Watchdog Timer"
         bool "Enable Watchdog Timer"
         select RT_USING_WDT
         select RT_USING_WDT

+ 59 - 1
bsp/bluetrum/ab32vg1-ab-prougen/board/ab32vg1_hal_msp.c

@@ -1,9 +1,10 @@
 /*
 /*
- * Copyright (c) 2020-2020, BLUETRUM Development Team
+ * Copyright (c) 2020-2021, BLUETRUM Development Team
  *
  *
  * SPDX-License-Identifier: Apache-2.0
  * SPDX-License-Identifier: Apache-2.0
  */
  */
 
 
+#include <rtthread.h>
 #include "ab32vg1_hal.h"
 #include "ab32vg1_hal.h"
 
 
 void hal_uart_mspinit(struct uart_handle *huart)
 void hal_uart_mspinit(struct uart_handle *huart)
@@ -63,3 +64,60 @@ void hal_sd_mspinit(sd_handle_t hsd)
     hal_gpio_init(GPIOB_BASE, &gpio_init);
     hal_gpio_init(GPIOB_BASE, &gpio_init);
 }
 }
 #endif
 #endif
+
+void hal_pwm_mspinit(void)
+{
+    struct gpio_init gpio_init = {0};
+
+    gpio_init.dir       = GPIO_DIR_OUTPUT;
+    gpio_init.de        = GPIO_DIGITAL;
+
+#ifdef BSP_USING_T3_PWM0
+    gpio_init.pin       = GPIO_PIN_0;
+    gpio_init.alternate = GPIO_AF_MAP_Gx(TMR3MAP_AF, GPIO_AF_G1);
+    gpio_init.af_con    = GPIO_AFEN | GPIO_AFCON2;
+    hal_gpio_init(GPIOB_BASE, &gpio_init);
+#endif
+
+#ifdef BSP_USING_T4_PWM1
+    gpio_init.pin       = GPIO_PIN_6;
+    gpio_init.alternate = GPIO_AF_MAP_Gx(TMR4MAP_AF, GPIO_AF_G1);
+    gpio_init.af_con    = GPIO_AFEN | GPIO_AFCON2;
+    hal_gpio_init(GPIOA_BASE, &gpio_init);
+#endif
+
+#ifdef BSP_USING_T5_PWM0
+    gpio_init.pin       = GPIO_PIN_1;
+    gpio_init.alternate = GPIO_AF_MAP_Gx(TMR5MAP_AF, GPIO_AF_G1);
+    gpio_init.af_con    = GPIO_AFEN | GPIO_AFCON2;
+    hal_gpio_init(GPIOE_BASE, &gpio_init);
+#endif
+
+#ifdef BSP_USING_LPWM0_G1
+    gpio_init.pin       = GPIO_PIN_4;
+    gpio_init.alternate = GPIO_AF_MAP_Gx(LPWM0MAP_AF, GPIO_AF_G1);
+    gpio_init.af_con    = GPIO_AFEN | GPIO_AFCON1;
+    hal_gpio_init(GPIOE_BASE, &gpio_init);
+#endif
+
+#ifdef BSP_USING_LPWM1_G3
+    gpio_init.pin       = GPIO_PIN_1;
+    gpio_init.alternate = GPIO_AF_MAP_Gx(LPWM1MAP_AF, GPIO_AF_G3);
+    gpio_init.af_con    = GPIO_AFEN | GPIO_AFCON1;
+    hal_gpio_init(GPIOA_BASE, &gpio_init);
+#endif
+
+#ifdef BSP_USING_LPWM2_G2
+    gpio_init.pin       = GPIO_PIN_0;
+    gpio_init.alternate = GPIO_AF_MAP_Gx(LPWM2MAP_AF, GPIO_AF_G2);
+    gpio_init.af_con    = GPIO_AFEN | GPIO_AFCON1;
+    hal_gpio_init(GPIOE_BASE, &gpio_init);
+#endif
+
+#ifdef BSP_USING_LPWM2_G3
+    gpio_init.pin       = GPIO_PIN_2;
+    gpio_init.alternate = GPIO_AF_MAP_Gx(LPWM2MAP_AF, GPIO_AF_G3);
+    gpio_init.af_con    = GPIO_AFEN | GPIO_AFCON1;
+    hal_gpio_init(GPIOA_BASE, &gpio_init);
+#endif
+}

+ 2 - 2
bsp/bluetrum/ab32vg1-ab-prougen/board/board.c

@@ -1,6 +1,6 @@
 /*
 /*
- * Copyright (c) 2006-2020, RT-Thread Development Team
- *
+ * Copyright (c) 2020-2021, Bluetrum Development Team
+ * 
  * SPDX-License-Identifier: Apache-2.0
  * SPDX-License-Identifier: Apache-2.0
  *
  *
  * Change Logs:
  * Change Logs:

+ 2 - 2
bsp/bluetrum/ab32vg1-ab-prougen/board/board.h

@@ -1,6 +1,6 @@
 /*
 /*
- * Copyright (c) 2006-2020, RT-Thread Development Team
- *
+ * Copyright (c) 2020-2021, Bluetrum Development Team
+ * 
  * SPDX-License-Identifier: Apache-2.0
  * SPDX-License-Identifier: Apache-2.0
  *
  *
  * Change Logs:
  * Change Logs:

+ 1 - 1
bsp/bluetrum/ab32vg1-ab-prougen/board/ports/audio/drv_sound.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2020-2020, Bluetrum Development Team
+ * Copyright (c) 2020-2021, Bluetrum Development Team
  * 
  * 
  * SPDX-License-Identifier: Apache-2.0
  * SPDX-License-Identifier: Apache-2.0
  *
  *

+ 0 - 1
bsp/bluetrum/ab32vg1-ab-prougen/link.lds

@@ -61,7 +61,6 @@ SECTIONS
         *components.o (.text*)
         *components.o (.text*)
         *idle.o (.text*)
         *idle.o (.text*)
         *object.o (.text*)
         *object.o (.text*)
-        *scheduler.o (.text*)
     } > ram1 AT > flash
     } > ram1 AT > flash
 
 
     .comm __comm_vma : {
     .comm __comm_vma : {

+ 0 - 5
bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.h

@@ -72,11 +72,6 @@
 
 
 /* Device virtual file system */
 /* Device virtual file system */
 
 
-#define RT_USING_DFS
-#define DFS_USING_WORKDIR
-#define DFS_FILESYSTEMS_MAX 2
-#define DFS_FILESYSTEM_TYPES_MAX 2
-#define DFS_FD_MAX 16
 
 
 /* Device Drivers */
 /* Device Drivers */
 
 

+ 3 - 0
bsp/bluetrum/libraries/hal_drivers/SConscript

@@ -25,6 +25,9 @@ if GetDepend('RT_USING_WDT'):
 if GetDepend('RT_USING_HWTIMER'):
 if GetDepend('RT_USING_HWTIMER'):
     src += ['drv_hwtimer.c']
     src += ['drv_hwtimer.c']
 
 
+if GetDepend('RT_USING_PWM'):
+    src += ['drv_pwm.c']
+
 group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
 group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
 
 
 objs = [group]
 objs = [group]

+ 106 - 2
bsp/bluetrum/libraries/hal_drivers/config/pwm_config.h

@@ -4,6 +4,110 @@
  * SPDX-License-Identifier: Apache-2.0
  * SPDX-License-Identifier: Apache-2.0
  *
  *
  * Change Logs:
  * Change Logs:
- * Date           Author       Notes
- * 2021/01/18     greedyhao    The first version
+ * Date           Author            Notes
+ * 2021-01-28     greedyhao         first version
  */
  */
+
+#ifndef __PWM_CONFIG_H__
+#define __PWM_CONFIG_H__
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum
+{
+    PWMxCON,
+    PWMxPR,
+    PWMxxDUT,
+    PWMyyDUT,
+    PWMxCYCNUM,
+    PWMxSTEP,
+};
+
+#define PWM_BASE    ((hal_sfr_t)&PWMCON)
+
+#ifdef BSP_USING_T3_PWM
+#ifndef T3_PWM_CONFIG
+#define T3_PWM_CONFIG                         \
+    {                                       \
+       .pwm_handle          = TIM3_BASE,    \
+       .name                = "t3pwm",       \
+       .channel             = 0             \
+    }
+#endif /* T3_PWM_CONFIG */
+#endif /* BSP_USING_T3_PWM */
+
+#ifdef BSP_USING_T4_PWM
+#ifndef T4_PWM_CONFIG
+#define T4_PWM_CONFIG                         \
+    {                                       \
+       .pwm_handle          = TIM4_BASE,    \
+       .name                = "t4pwm",       \
+       .channel             = 0             \
+    }
+#endif /* T4_PWM_CONFIG */
+#endif /* BSP_USING_T4_PWM */
+
+#ifdef BSP_USING_T5_PWM
+#ifndef T5_PWM_CONFIG
+#define T5_PWM_CONFIG                         \
+    {                                       \
+       .pwm_handle          = TIM5_BASE,    \
+       .name                = "t5pwm",       \
+       .channel             = 0             \
+    }
+#endif /* T5_PWM_CONFIG */
+#endif /* BSP_USING_T5_PWM */
+
+#ifdef BSP_USING_LPWM0
+#ifndef LPWM0_CONFIG
+#define LPWM0_CONFIG                        \
+    {                                       \
+       .pwm_handle          = PWM_BASE,     \
+       .name                = "lpwm0",      \
+       .channel             = 0             \
+    }
+#endif /* LPWM0_CONFIG */
+#endif /* BSP_USING_LPWM0 */
+
+#ifdef BSP_USING_LPWM1
+#ifndef LPWM1_CONFIG
+#define LPWM1_CONFIG                        \
+    {                                       \
+       .pwm_handle          = PWM_BASE,     \
+       .name                = "lpwm1",      \
+       .channel             = 0             \
+    }
+#endif /* LPWM1_CONFIG */
+#endif /* BSP_USING_LPWM1 */
+
+#ifdef BSP_USING_LPWM2
+#ifndef LPWM2_CONFIG
+#define LPWM2_CONFIG                        \
+    {                                       \
+       .pwm_handle          = PWM_BASE,     \
+       .name                = "lpwm2",      \
+       .channel             = 0             \
+    }
+#endif /* LPWM2_CONFIG */
+#endif /* BSP_USING_LPWM2 */
+
+#ifdef BSP_USING_LPWM3
+#ifndef LPWM3_CONFIG
+#define LPWM3_CONFIG                        \
+    {                                       \
+       .pwm_handle          = PWM_BASE,     \
+       .name                = "lpwm3",      \
+       .channel             = 0             \
+    }
+#endif /* LPWM3_CONFIG */
+#endif /* BSP_USING_LPWM3 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PWM_CONFIG_H__ */

+ 334 - 0
bsp/bluetrum/libraries/hal_drivers/drv_pwm.c

@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2020-2021, Bluetrum Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2021-01-28     greedyhao         first version
+ */
+
+#include <board.h>
+
+#ifdef RT_USING_PWM
+#include "pwm_config.h"
+
+//#define DRV_DEBUG
+#define LOG_TAG             "drv.pwm"
+#include <drv_log.h>
+
+#define MAX_PERIOD 65535
+#define MIN_PERIOD 3
+#define MIN_PULSE 2
+
+void hal_pwm_mspinit(void);
+
+enum
+{
+#ifdef BSP_USING_T3_PWM
+    T3_PWM_INDEX,
+#endif
+#ifdef BSP_USING_T4_PWM
+    T4_PWM_INDEX,
+#endif
+#ifdef BSP_USING_T5_PWM
+    T5_PWM_INDEX,
+#endif
+#ifdef BSP_USING_LPWM0
+    LPWM0_INDEX,
+#endif
+#ifdef BSP_USING_LPWM1
+    LPWM1_INDEX,
+#endif
+#ifdef BSP_USING_LPWM2
+    LPWM2_INDEX,
+#endif
+#ifdef BSP_USING_LPWM3
+    LPWM3_INDEX,
+#endif
+};
+
+struct ab32_pwm
+{
+    struct rt_device_pwm pwm_device;
+    hal_sfr_t   pwm_handle;
+    char *name;
+    rt_uint8_t  channel;
+    rt_uint32_t period;
+    rt_uint32_t pulse;
+};
+
+static struct ab32_pwm ab32_pwm_obj[] =
+{
+#ifdef BSP_USING_T3_PWM
+    T3_PWM_CONFIG,
+#endif
+#ifdef BSP_USING_T4_PWM
+    T4_PWM_CONFIG,
+#endif
+#ifdef BSP_USING_T5_PWM
+    T5_PWM_CONFIG,
+#endif
+#ifdef BSP_USING_LPWM0
+    LPWM0_CONFIG,
+#endif
+#ifdef BSP_USING_LPWM1
+    LPWM1_CONFIG,
+#endif
+#ifdef BSP_USING_LPWM2
+    LPWM2_CONFIG,
+#endif
+#ifdef BSP_USING_LPWM3
+    LPWM3_CONFIG,
+#endif
+};
+
+static rt_err_t drv_pwm_enable(hal_sfr_t pwm, char *name, struct rt_pwm_configuration *configuration, rt_bool_t enable)
+{
+    rt_uint8_t channel = configuration->channel;
+    rt_uint8_t pwm_num = 0;
+
+    if (!configuration->complementary) {
+        if (name[0] == 'l') {
+            pwm[PWMxCON] &= ~BIT(5);
+        }
+    } else {
+        if (name[0] == 'l') {
+            pwm[PWMxCON] |= BIT(5);
+        } else {
+            LOG_W("Timer no support complementary PWM output!");
+        }
+    }
+
+    if (!enable) {
+        if (name[0] == 'l') {
+            pwm_num = name[4] - '0';
+            pwm[PWMxCON] &= ~(1 << (pwm_num));
+        } else {
+            if (channel & 0x1) { /* pwm0 */
+                pwm[TMRxCON] &= ~(1 << (9 + 0));
+            }
+            if (channel & 0x2) { /* pwm1 */
+                pwm[TMRxCON] &= ~(1 << (9 + 1));
+            }
+            if (channel & 0x4) { /* pwm2 */
+                pwm[TMRxCON] &= ~(1 << (9 + 2));
+            }
+        }
+    } else {
+        if (name[0] == 'l') {
+            pwm_num = name[4] - '0';
+            pwm[PWMxCON] |= 1 << (pwm_num);
+        } else {
+            if (channel & 0x1) { /* pwm0 */
+                pwm[TMRxCON] |= (1 << (9 + 0));
+            }
+            if (channel & 0x2) { /* pwm1 */
+                pwm[TMRxCON] |= (1 << (9 + 1));
+            }
+            if (channel & 0x4) { /* pwm2 */
+                pwm[TMRxCON] |= (1 << (9 + 2));
+            }
+        }
+    }
+
+    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 ab32_pwm *pwm_obj = (struct ab32_pwm *)device->parent.user_data;
+    hal_sfr_t pwm = pwm_obj->pwm_handle;
+    char *name = pwm_obj->name;
+    rt_uint8_t channel = configuration->channel;
+    rt_uint32_t period, pulse;
+    rt_uint64_t tim_clock, psc;
+
+    if (name[0] == 'l') {
+        tim_clock = 6500; /* lpwm clock is 6.5MHz */
+    } else {
+        tim_clock = get_sysclk_nhz() / 1000ul;
+    }
+
+    switch (cmd)
+    {
+    case PWMN_CMD_ENABLE:
+        configuration->complementary = RT_TRUE;
+    case PWM_CMD_ENABLE:
+        return drv_pwm_enable(pwm, name, configuration, RT_TRUE);
+    case PWMN_CMD_DISABLE:
+        configuration->complementary = RT_FALSE;
+    case PWM_CMD_DISABLE:
+        return drv_pwm_enable(pwm, name, configuration, RT_FALSE);
+    case PWM_CMD_SET:
+        pwm_obj->pulse = configuration->pulse;
+        pwm_obj->period = configuration->period;
+
+        period = pwm_obj->period * tim_clock / 1000000ul;
+        psc = period / MAX_PERIOD + 1;
+        period = period / psc;
+
+        if (period < MIN_PERIOD)
+        {
+            period = MIN_PERIOD;
+        }
+
+        pulse = pwm_obj->pulse * tim_clock / psc / 1000000ul;
+        if (pulse < MIN_PULSE)
+        {
+            pulse = MIN_PULSE;
+        }
+        else if (pulse > period)
+        {
+            pulse = period;
+        }
+
+        if (name[0] == 'l') {
+            pwm[PWMxPR] = period - 1;
+            switch (name[4] - '0')
+            {
+            case 0: /* lpwm0 */
+                pwm[PWMxxDUT] = pulse - 1;
+                break;
+            case 1: /* lpwm1 */
+                pwm[PWMxxDUT] = (pulse - 1) << 16;
+                break;
+            case 2: /* lpwm2 */
+                pwm[PWMyyDUT] = pulse - 1;
+                break;
+            case 3: /* lpwm3 */
+                pwm[PWMyyDUT] = (pulse - 1) << 16;
+                break;
+            default:
+                break;
+            }
+        } else {
+            pwm[TMRxPR] = period - 1;
+            if (channel & 0x1) { /* pwm0 */
+                pwm[TMRxDUTY0] = pulse - 1;
+            }
+            if (channel & 0x2) { /* pwm1 */
+                pwm[TMRxDUTY1] = pulse - 1;
+            }
+            if (channel & 0x4) { /* pwm2 */
+                pwm[TMRxDUTY2] = pulse - 1;
+            }
+        }
+        return RT_EOK;
+    case PWM_CMD_GET:
+        configuration->pulse = pwm_obj->pulse;
+        configuration->period = pwm_obj->period;
+        return RT_EOK;
+    default:
+        return -RT_EINVAL;
+    }
+}
+
+static rt_err_t ab32_hw_pwm_init(struct ab32_pwm *device)
+{
+    rt_err_t result = RT_EOK;
+    hal_sfr_t pwm = RT_NULL;
+    char *name = RT_NULL;
+
+    RT_ASSERT(device != RT_NULL);
+
+    pwm = (hal_sfr_t)device->pwm_handle;
+    name = device->name;
+
+    if (name[0] == 'l') {
+        pwm[PWMxCON] = 0;
+    } else {
+        pwm[TMRxCON] &= ~(7 << 9);
+    }
+
+    return result;
+}
+
+static void pwm_get_channel(void)
+{
+#ifdef BSP_USING_T3_PWM0
+    ab32_pwm_obj[T3_PWM_INDEX].channel |= 1 << 0;
+#endif
+#ifdef BSP_USING_T3_PWM1
+    ab32_pwm_obj[T3_PWM_INDEX].channel |= 1 << 1;
+#endif
+#ifdef BSP_USING_T3_PWM2
+    ab32_pwm_obj[T3_PWM_INDEX].channel |= 1 << 2;
+#endif
+#ifdef BSP_USING_T4_PWM0
+    ab32_pwm_obj[T4_PWM_INDEX].channel |= 1 << 0;
+#endif
+#ifdef BSP_USING_T4_PWM1
+    ab32_pwm_obj[T4_PWM_INDEX].channel |= 1 << 1;
+#endif
+#ifdef BSP_USING_T4_PWM2
+    ab32_pwm_obj[T4_PWM_INDEX].channel |= 1 << 2;
+#endif
+#ifdef BSP_USING_T5_PWM0
+    ab32_pwm_obj[T5_PWM_INDEX].channel |= 1 << 0;
+#endif
+#ifdef BSP_USING_T5_PWM1
+    ab32_pwm_obj[T5_PWM_INDEX].channel |= 1 << 1;
+#endif
+#ifdef BSP_USING_T5_PWM2
+    ab32_pwm_obj[T5_PWM_INDEX].channel |= 1 << 2;
+#endif
+#ifdef BSP_USING_LPWM0
+    ab32_pwm_obj[LPWM0_INDEX].channel |= 1 << 0;
+#endif
+#ifdef BSP_USING_LPWM1
+    ab32_pwm_obj[LPWM1_INDEX].channel |= 1 << 0;
+#endif
+#ifdef BSP_USING_LPWM2
+    ab32_pwm_obj[LPWM2_INDEX].channel |= 1 << 0;
+#endif
+#ifdef BSP_USING_LPWM3
+    ab32_pwm_obj[LPWM3_INDEX].channel |= 1 << 0;
+#endif
+}
+
+static struct rt_pwm_ops drv_ops =
+{
+    drv_pwm_control
+};
+
+static int ab32_pwm_init(void)
+{
+    int i = 0;
+    int result = RT_EOK;
+
+    pwm_get_channel();
+    hal_pwm_mspinit();
+
+    for (i = 0; i < sizeof(ab32_pwm_obj) / sizeof(ab32_pwm_obj[0]); i++)
+    {
+        /* pwm init */
+        if (ab32_hw_pwm_init(&ab32_pwm_obj[i]) != RT_EOK)
+        {
+            LOG_E("%s init failed", ab32_pwm_obj[i].name);
+            result = -RT_ERROR;
+            goto __exit;
+        }
+        else
+        {
+            LOG_D("%s init success", ab32_pwm_obj[i].name);
+
+            /* register pwm device */
+            if (rt_device_pwm_register(&ab32_pwm_obj[i].pwm_device, ab32_pwm_obj[i].name, &drv_ops, (void *)&ab32_pwm_obj[i]) == RT_EOK)
+            {
+                LOG_D("%s register success", ab32_pwm_obj[i].name);
+            }
+            else
+            {
+                LOG_E("%s register failed", ab32_pwm_obj[i].name);
+                result = -RT_ERROR;
+            }
+        }
+    }
+
+__exit:
+    return result;
+}
+INIT_DEVICE_EXPORT(ab32_pwm_init);
+#endif /* RT_USING_PWM */

+ 49 - 30
bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_gpio_ex.h

@@ -8,6 +8,17 @@
 #define AB32VG1_HAL_GPIO_EX_H__
 #define AB32VG1_HAL_GPIO_EX_H__
 
 
 /* Alternate function */
 /* Alternate function */
+#define GPIO_AF_MAP_Gx(AF, Gx)  ((uint32_t)((Gx) << (AF)))
+#define GPIO_AF_MAP_CLR(AF)     ((uint32_t)(0xfu << (AF)))
+
+#define GPIO_AF_G1              (1u)
+#define GPIO_AF_G2              (2u)
+#define GPIO_AF_G3              (3u)
+#define GPIO_AF_G4              (4u)
+#define GPIO_AF_G5              (5u)
+#define GPIO_AF_G6              (6u)
+#define GPIO_AF_G7              (7u)
+
 /**
 /**
  * UART0:
  * UART0:
  * G1: tx:PA7 rx:PA6
  * G1: tx:PA7 rx:PA6
@@ -23,16 +34,6 @@
  * G2: tx:PA4 rx:PA3
  * G2: tx:PA4 rx:PA3
  * G3: tx:PF2 rx:map to tx
  * G3: tx:PF2 rx:map to tx
  */
  */
-#define GPIO_AF_MAP_Gx(AF, Gx)  ((uint32_t)((Gx) << (AF)))
-#define GPIO_AF_MAP_CLR(AF)     ((uint32_t)(0xfu << (AF)))
-
-#define GPIO_AF_G1              (1u)
-#define GPIO_AF_G2              (2u)
-#define GPIO_AF_G3              (3u)
-#define GPIO_AF_G4              (4u)
-#define GPIO_AF_G5              (5u)
-#define GPIO_AF_G6              (6u)
-#define GPIO_AF_G7              (7u)
 
 
 #define UT1RXMAP_AF             (28u)
 #define UT1RXMAP_AF             (28u)
 #define UT1TXMAP_AF             (24u)
 #define UT1TXMAP_AF             (24u)
@@ -46,26 +47,44 @@
 #define UT1RXMAP_TX             ((uint32_t)(0x3u << (UT1RXMAP_AF)))
 #define UT1RXMAP_TX             ((uint32_t)(0x3u << (UT1RXMAP_AF)))
 #define UT0RXMAP_TX             ((uint32_t)(0x7u << (UT0RXMAP_AF)))
 #define UT0RXMAP_TX             ((uint32_t)(0x7u << (UT0RXMAP_AF)))
 
 
-#define GPIO_HSUART_G1
-#define GPIO_HSUART_G2
-#define GPIO_HSUART_G3
-#define GPIO_HSUART_G4
-#define GPIO_HSUART_G5
-#define GPIO_HSUART_G6
-#define GPIO_HSUART_G7
-#define GPIO_HSUART_G8
-#define GPIO_HSUART_G9
-#define GPIO_HSUART_G10
-
-#define GPIO_SPI0_G1
-#define GPIO_SPI0_G2
-#define GPIO_SPI0_G3
+/**
+ * LPWM3:
+ * G1: PE7
+ * G2: PF2
+ * G3: PA3
+ * 
+ * LPWM2:
+ * G1: PE6
+ * G2: PE0
+ * G3: PA2
+ * 
+ * LPWM1:
+ * G1: PE5
+ * G2: PB4
+ * G3: PA1
+ * 
+ * LPWM0:
+ * G1: PE4
+ * G2: PB3
+ * G3: PA0
+ */
+#define LPWM3MAP_AF             (28u)
+#define LPWM2MAP_AF             (24u)
+#define LPWM1MAP_AF             (20u)
+#define LPWM0MAP_AF             (16u)
 
 
-#define GPIO_SD0_G1
-#define GPIO_SD0_G2
-#define GPIO_SD0_G3
-#define GPIO_SD0_G4
-#define GPIO_SD0_G5
-#define GPIO_SD0_G6
+/**
+ * TMR5:
+ * G1: PE1 PE2 PE3
+ * 
+ * TMR4:
+ * G1: PA5 PA6 PA7
+ * 
+ * TMR3:
+ * G1: PB0 PB1 PB2
+ */
+#define TMR5MAP_AF              (16u)
+#define TMR4MAP_AF              (12u)
+#define TMR3MAP_AF              ( 8u)
 
 
 #endif
 #endif