From c7ce44ab3ad7d633bd8bc6b1e76d300b42e6f6c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E7=94=9F?= Date: Wed, 29 Jun 2022 00:00:58 +0800 Subject: [PATCH] =?UTF-8?q?[bsp/hc32]=E6=B7=BB=E5=8A=A0timerA=E7=9A=84pwm?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/hc32/ev_hc32f460_lqfp100_v2/board/Kconfig | 19 + .../board/board_config.c | 185 ++++++++ .../board/board_config.h | 13 + .../board/config/pwm_tmra_config.h | 205 ++++++++ .../ev_hc32f460_lqfp100_v2/board/drv_config.h | 1 + bsp/hc32/libraries/hc32_drivers/SConscript | 3 + .../libraries/hc32_drivers/drv_pwm_tmra.c | 437 ++++++++++++++++++ bsp/hc32/libraries/hc32f460_ddl/SConscript | 2 +- 8 files changed, 864 insertions(+), 1 deletion(-) create mode 100644 bsp/hc32/ev_hc32f460_lqfp100_v2/board/config/pwm_tmra_config.h create mode 100644 bsp/hc32/libraries/hc32_drivers/drv_pwm_tmra.c diff --git a/bsp/hc32/ev_hc32f460_lqfp100_v2/board/Kconfig b/bsp/hc32/ev_hc32f460_lqfp100_v2/board/Kconfig index 39e62535a4..18029d3f2d 100644 --- a/bsp/hc32/ev_hc32f460_lqfp100_v2/board/Kconfig +++ b/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" diff --git a/bsp/hc32/ev_hc32f460_lqfp100_v2/board/board_config.c b/bsp/hc32/ev_hc32f460_lqfp100_v2/board/board_config.c index 4abae9c170..86d5e9ab25 100644 --- a/bsp/hc32/ev_hc32f460_lqfp100_v2/board/board_config.c +++ b/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 @@ -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 diff --git a/bsp/hc32/ev_hc32f460_lqfp100_v2/board/board_config.h b/bsp/hc32/ev_hc32f460_lqfp100_v2/board/board_config.h index a930a2219a..3fbc1c33c3 100644 --- a/bsp/hc32/ev_hc32f460_lqfp100_v2/board/board_config.h +++ b/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 diff --git a/bsp/hc32/ev_hc32f460_lqfp100_v2/board/config/pwm_tmra_config.h b/bsp/hc32/ev_hc32f460_lqfp100_v2/board/config/pwm_tmra_config.h new file mode 100644 index 0000000000..a8f6727ff1 --- /dev/null +++ b/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 + +#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__ */ diff --git a/bsp/hc32/ev_hc32f460_lqfp100_v2/board/drv_config.h b/bsp/hc32/ev_hc32f460_lqfp100_v2/board/drv_config.h index 952412e2d9..a73c788129 100644 --- a/bsp/hc32/ev_hc32f460_lqfp100_v2/board/drv_config.h +++ b/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 } diff --git a/bsp/hc32/libraries/hc32_drivers/SConscript b/bsp/hc32/libraries/hc32_drivers/SConscript index abe4243c76..95606c6f5d 100644 --- a/bsp/hc32/libraries/hc32_drivers/SConscript +++ b/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) diff --git a/bsp/hc32/libraries/hc32_drivers/drv_pwm_tmra.c b/bsp/hc32/libraries/hc32_drivers/drv_pwm_tmra.c new file mode 100644 index 0000000000..9f7fdaf76e --- /dev/null +++ b/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 + +#if (defined RT_USING_PWM) && (defined BSP_USING_PWM_TMRA) +#include "drv_config.h" +#include + +//#define DRV_DEBUG +#define LOG_TAG "drv.pwm.tmra" +#include + +#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 */ diff --git a/bsp/hc32/libraries/hc32f460_ddl/SConscript b/bsp/hc32/libraries/hc32f460_ddl/SConscript index f4a843cbbf..4437ec1652 100644 --- a/bsp/hc32/libraries/hc32f460_ddl/SConscript +++ b/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 = [