diff options
| author | Bernard Xiong <[email protected]> | 2021-02-03 10:53:16 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-02-03 10:53:16 +0800 |
| commit | e210bc7cb6e00876718239dd0ffdedf83002cc95 (patch) | |
| tree | 37e2c0ef87e5d6d26584d72a344b28633481aa13 /bsp/bluetrum/libraries | |
| parent | 58c3b2f523e662704f744ebd1da399b606d9907c (diff) | |
| parent | 801aa4747baebee4674a4937d2409c244c661297 (diff) | |
Merge pull request #4273 from greedyhao/bluetrum
[bsp][bluetrum] add pwm support
Diffstat (limited to 'bsp/bluetrum/libraries')
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 |
