summaryrefslogtreecommitdiff
path: root/bsp/bluetrum/libraries
diff options
context:
space:
mode:
authorBernard Xiong <[email protected]>2021-02-03 10:53:16 +0800
committerGitHub <[email protected]>2021-02-03 10:53:16 +0800
commite210bc7cb6e00876718239dd0ffdedf83002cc95 (patch)
tree37e2c0ef87e5d6d26584d72a344b28633481aa13 /bsp/bluetrum/libraries
parent58c3b2f523e662704f744ebd1da399b606d9907c (diff)
parent801aa4747baebee4674a4937d2409c244c661297 (diff)
Merge pull request #4273 from greedyhao/bluetrum
[bsp][bluetrum] add pwm support
Diffstat (limited to 'bsp/bluetrum/libraries')
-rw-r--r--bsp/bluetrum/libraries/hal_drivers/SConscript3
-rw-r--r--bsp/bluetrum/libraries/hal_drivers/config/pwm_config.h108
-rw-r--r--bsp/bluetrum/libraries/hal_drivers/drv_pwm.c334
-rw-r--r--bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_gpio_ex.h79
4 files changed, 492 insertions, 32 deletions
diff --git a/bsp/bluetrum/libraries/hal_drivers/SConscript b/bsp/bluetrum/libraries/hal_drivers/SConscript
index 83ceaa1ba1..7ec2f48a81 100644
--- a/bsp/bluetrum/libraries/hal_drivers/SConscript
+++ b/bsp/bluetrum/libraries/hal_drivers/SConscript
@@ -25,6 +25,9 @@ if GetDepend('RT_USING_WDT'):
if GetDepend('RT_USING_HWTIMER'):
src += ['drv_hwtimer.c']
+if GetDepend('RT_USING_PWM'):
+ src += ['drv_pwm.c']
+
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
objs = [group]
diff --git a/bsp/bluetrum/libraries/hal_drivers/config/pwm_config.h b/bsp/bluetrum/libraries/hal_drivers/config/pwm_config.h
index 24d705f342..b5e2403976 100644
--- a/bsp/bluetrum/libraries/hal_drivers/config/pwm_config.h
+++ b/bsp/bluetrum/libraries/hal_drivers/config/pwm_config.h
@@ -4,6 +4,110 @@
* SPDX-License-Identifier: Apache-2.0
*
* 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__ */
diff --git a/bsp/bluetrum/libraries/hal_drivers/drv_pwm.c b/bsp/bluetrum/libraries/hal_drivers/drv_pwm.c
new file mode 100644
index 0000000000..df40562ad8
--- /dev/null
+++ b/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 */
diff --git a/bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_gpio_ex.h b/bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_gpio_ex.h
index 9745242870..f2a94d65ac 100644
--- a/bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_gpio_ex.h
+++ b/bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_gpio_ex.h
@@ -8,6 +8,17 @@
#define AB32VG1_HAL_GPIO_EX_H__
/* 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:
* G1: tx:PA7 rx:PA6
@@ -23,16 +34,6 @@
* G2: tx:PA4 rx:PA3
* 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 UT1TXMAP_AF (24u)
@@ -46,26 +47,44 @@
#define UT1RXMAP_TX ((uint32_t)(0x3u << (UT1RXMAP_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