diff --git a/bsp/wch/ch32v003/driver/mr_board.h b/bsp/wch/ch32v003/driver/mr_board.h index 15b5e81..b72a407 100644 --- a/bsp/wch/ch32v003/driver/mr_board.h +++ b/bsp/wch/ch32v003/driver/mr_board.h @@ -15,6 +15,8 @@ extern "C" { #include "ch32v00x.h" +#define MR_USING_CH32V00X + #define DRV_ADC_CHANNEL_CONFIG \ { \ {ADC_Channel_0, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_2}, \ diff --git a/bsp/wch/ch32v203/driver/Kconfig b/bsp/wch/ch32v203/driver/Kconfig index 25dd328..81fe579 100644 --- a/bsp/wch/ch32v203/driver/Kconfig +++ b/bsp/wch/ch32v203/driver/Kconfig @@ -1,9 +1,5 @@ menu "Driver configure" - config MR_USING_CH32V20X - bool "Enable CH32V20X driver" - default y - menu "ADC" config MR_USING_ADC1 bool "Enable ADC1 driver" @@ -42,6 +38,73 @@ menu "Driver configure" endmenu endmenu + menu "PWM" + config MR_USING_PWM1 + bool "Enable PWM1 driver" + default n + + menu "PWM1 driver configure" + depends on MR_USING_PWM1 + + config MR_CFG_PWM1_GROUP + int "PWM1 Group" + default 1 + range 1 1 + endmenu + + config MR_USING_PWM2 + bool "Enable PWM2 driver" + default n + + menu "PWM2 driver configure" + depends on MR_USING_PWM2 + + config MR_CFG_PWM2_GROUP + int "PWM2 Group" + default 1 + range 1 4 + endmenu + + config MR_USING_PWM3 + bool "Enable PWM3 driver" + default n + + menu "PWM3 driver configure" + depends on MR_USING_PWM3 + + config MR_CFG_PWM3_GROUP + int "PWM3 Group" + default 1 + range 1 3 + endmenu + + config MR_USING_PWM4 + bool "Enable PWM4 driver" + default n + + menu "PWM4 driver configure" + depends on MR_USING_PWM4 + + config MR_CFG_PWM4_GROUP + int "PWM4 Group" + default 1 + range 1 1 + endmenu + + config MR_USING_PWM5 + bool "Enable PWM5 driver" + default n + + menu "PWM5 driver configure" + depends on MR_USING_PWM5 + + config MR_CFG_PWM5_GROUP + int "PWM5 Group" + default 1 + range 1 1 + endmenu + endmenu + menu "UART" config MR_USING_UART1 bool "Enable UART1 driver" diff --git a/bsp/wch/ch32v203/driver/mr_board.h b/bsp/wch/ch32v203/driver/mr_board.h index ab9bcd9..73bed54 100644 --- a/bsp/wch/ch32v203/driver/mr_board.h +++ b/bsp/wch/ch32v203/driver/mr_board.h @@ -15,6 +15,8 @@ extern "C" { #include "ch32v20x.h" +#define MR_USING_CH32V20X + #define DRV_ADC_CHANNEL_CONFIG \ { \ {ADC_Channel_0, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_0}, \ @@ -97,6 +99,54 @@ extern "C" { GPIO_Pin_15, \ } +#if (MR_CFG_PWM1_GROUP == 1) +#define DRV_PWM1_CONFIG \ + {TIM1, RCC_APB2Periph_TIM1, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_8, GPIOA, GPIO_Pin_9, GPIOA, GPIO_Pin_10, GPIOA, GPIO_Pin_11, 0} +#endif /* MR_CFG_PWM1_GROUP */ +#if (MR_CFG_PWM2_GROUP == 1) +#define DRV_PWM2_CONFIG \ + {TIM2, RCC_APB1Periph_TIM2, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_0, GPIOA, GPIO_Pin_1, GPIOA, GPIO_Pin_2, GPIOA, GPIO_Pin_3, 0} +#elif (MR_CFG_PWM2_GROUP == 2) +#define DRV_PWM2_CONFIG \ + {TIM2, RCC_APB1Periph_TIM2, RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, GPIOA, GPIO_Pin_15, GPIOB, GPIO_Pin_3, GPIOA, GPIO_Pin_2, GPIOA, GPIO_Pin_3, GPIO_PartialRemap1_TIM2} +#elif (MR_CFG_PWM2_GROUP == 3) +#define DRV_PWM2_CONFIG \ + {TIM2, RCC_APB1Periph_TIM2, RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, GPIOA, GPIO_Pin_0, GPIOA, GPIO_Pin_1, GPIOB, GPIO_Pin_10, GPIOA, GPIO_Pin_3, GPIO_PartialRemap2_TIM2} +#elif (MR_CFG_PWM2_GROUP == 4) +#define DRV_PWM2_CONFIG \ + {TIM2, RCC_APB1Periph_TIM2, RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, GPIOA, GPIO_Pin_15, GPIOB, GPIO_Pin_3, GPIOB, GPIO_Pin_10, GPIOB, GPIO_Pin_11, GPIO_FullRemap_TIM2} +#endif /* MR_CFG_PWM2_GROUP */ +#if (MR_CFG_PWM3_GROUP == 1) +#define DRV_PWM3_CONFIG \ + {TIM3, RCC_APB1Periph_TIM3, RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, GPIOA, GPIO_Pin_6, GPIOA, GPIO_Pin_7, GPIOB, GPIO_Pin_0, GPIOB, GPIO_Pin_1, 0} +#elif (MR_CFG_PWM3_GROUP == 2) +#define DRV_PWM3_CONFIG \ + {TIM3, RCC_APB1Periph_TIM3, RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_4, GPIOB, GPIO_Pin_5, GPIOB, GPIO_Pin_0, GPIOB, GPIO_Pin_1, GPIO_PartialRemap_TIM3} +#elif (MR_CFG_PWM3_GROUP == 3) +#define DRV_PWM3_CONFIG \ + {TIM3, RCC_APB1Periph_TIM3, RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_6, GPIOC, GPIO_Pin_7, GPIOC, GPIO_Pin_8, GPIOC, GPIO_Pin_9, GPIO_FullRemap_TIM3} +#endif /* MR_CFG_PWM3_GROUP */ +#if (MR_CFG_PWM4_GROUP == 1) +#define DRV_PWM4_CONFIG \ + {TIM4, RCC_APB1Periph_TIM4, RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_6, GPIOB, GPIO_Pin_7, GPIOB, GPIO_Pin_8, GPIOB, GPIO_Pin_9, 0} +#endif /* MR_CFG_PWM4_GROUP */ +#if (MR_CFG_PWM5_GROUP == 1) +#define DRV_PWM5_CONFIG \ + {TIM5, RCC_APB1Periph_TIM5, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_0, GPIOA, GPIO_Pin_1, GPIOA, GPIO_Pin_2, GPIOA, GPIO_Pin_3, 0} +#endif /* MR_CFG_PWM5_GROUP */ + +#define DRV_PWM1_INFO_CONFIG \ + {0, UINT16_MAX, UINT16_MAX} +#define DRV_PWM2_INFO_CONFIG \ + {0, UINT16_MAX, UINT16_MAX} +#define DRV_PWM3_INFO_CONFIG \ + {0, UINT16_MAX, UINT16_MAX} +#define DRV_PWM4_INFO_CONFIG \ + {0, UINT16_MAX, UINT16_MAX} +#define DRV_PWM5_INFO_CONFIG \ + {0, UINT16_MAX, UINT16_MAX} + + #if (MR_CFG_UART1_GROUP == 1) #define DRV_UART1_CONFIG \ {USART1, RCC_APB2Periph_USART1, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_10, GPIOA, GPIO_Pin_9, USART1_IRQn, 0} diff --git a/bsp/wch/ch32v307/driver/Kconfig b/bsp/wch/ch32v307/driver/Kconfig index 723fb9e..1f11bcf 100644 --- a/bsp/wch/ch32v307/driver/Kconfig +++ b/bsp/wch/ch32v307/driver/Kconfig @@ -1,9 +1,5 @@ menu "Driver configure" - config MR_USING_CH32V30X - bool "Enable CH32V30X driver" - default y - menu "ADC" config MR_USING_ADC1 bool "Enable ADC1 driver" @@ -48,6 +44,112 @@ menu "Driver configure" endmenu endmenu + menu "PWM" + config MR_USING_PWM1 + bool "Enable PWM1 driver" + default n + + menu "PWM1 driver configure" + depends on MR_USING_PWM1 + + config MR_CFG_PWM1_GROUP + int "PWM1 Group" + default 1 + range 1 3 + endmenu + + config MR_USING_PWM2 + bool "Enable PWM2 driver" + default n + + menu "PWM2 driver configure" + depends on MR_USING_PWM2 + + config MR_CFG_PWM2_GROUP + int "PWM2 Group" + default 1 + range 1 4 + endmenu + + config MR_USING_PWM3 + bool "Enable PWM3 driver" + default n + + menu "PWM3 driver configure" + depends on MR_USING_PWM3 + + config MR_CFG_PWM3_GROUP + int "PWM3 Group" + default 1 + range 1 3 + endmenu + + config MR_USING_PWM4 + bool "Enable PWM4 driver" + default n + + menu "PWM4 driver configure" + depends on MR_USING_PWM4 + + config MR_CFG_PWM4_GROUP + int "PWM4 Group" + default 1 + range 1 2 + endmenu + + config MR_USING_PWM5 + bool "Enable PWM5 driver" + default n + + menu "PWM5 driver configure" + depends on MR_USING_PWM5 + + config MR_CFG_PWM5_GROUP + int "PWM5 Group" + default 1 + range 1 1 + endmenu + + config MR_USING_PWM8 + bool "Enable PWM8 driver" + default n + + menu "PWM8 driver configure" + depends on MR_USING_PWM8 + + config MR_CFG_PWM8_GROUP + int "PWM8 Group" + default 1 + range 1 2 + endmenu + + config MR_USING_PWM9 + bool "Enable PWM9 driver" + default n + + menu "PWM9 driver configure" + depends on MR_USING_PWM9 + + config MR_CFG_PWM9_GROUP + int "PWM9 Group" + default 1 + range 1 3 + endmenu + + config MR_USING_PWM10 + bool "Enable PWM10 driver" + default n + + menu "PWM10 driver configure" + depends on MR_USING_PWM10 + + config MR_CFG_PWM10_GROUP + int "PWM10 Group" + default 1 + range 1 3 + endmenu + endmenu + menu "UART" config MR_USING_UART1 bool "Enable UART1 driver" diff --git a/bsp/wch/ch32v307/driver/mr_board.h b/bsp/wch/ch32v307/driver/mr_board.h index 3ead43c..a30253b 100644 --- a/bsp/wch/ch32v307/driver/mr_board.h +++ b/bsp/wch/ch32v307/driver/mr_board.h @@ -15,6 +15,8 @@ extern "C" { #include "ch32v30x.h" +#define MR_USING_CH32V30X + #define DRV_ADC_CHANNEL_CONFIG \ { \ {ADC_Channel_0, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_0}, \ @@ -49,7 +51,7 @@ extern "C" { {I2C1, RCC_APB1Periph_I2C1, RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_6, GPIOB, GPIO_Pin_7, I2C1_EV_IRQn, 0} #elif (MR_CFG_I2C1_GROUP == 2) #define DRV_I2C1_CONFIG \ - {I2C1, RCC_APB1Periph_I2C1, RCC_APB2Periph_GPIOD, GPIOB, GPIO_Pin_8, GPIOB, GPIO_Pin_9, I2C1_EV_IRQn, GPIO_Remap_I2C1} + {I2C1, RCC_APB1Periph_I2C1, RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_8, GPIOB, GPIO_Pin_9, I2C1_EV_IRQn, GPIO_Remap_I2C1} #endif /* MR_CFG_I2C1_GROUP */ #if (MR_CFG_I2C2_GROUP == 1) #define DRV_I2C2_CONFIG \ @@ -105,6 +107,95 @@ extern "C" { GPIO_Pin_15, \ } +#if (MR_CFG_PWM1_GROUP == 1) +#define DRV_PWM1_CONFIG \ + {TIM1, RCC_APB2Periph_TIM1, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_8, GPIOA, GPIO_Pin_9, GPIOA, GPIO_Pin_10, GPIOA, GPIO_Pin_11, 0} +#elif (MR_CFG_PWM1_GROUP == 2) +#define DRV_PWM1_CONFIG \ + {TIM1, RCC_APB2Periph_TIM1, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_8, GPIOA, GPIO_Pin_9, GPIOA, GPIO_Pin_10, GPIOA, GPIO_Pin_11, GPIO_PartialRemap_TIM1} +#elif (MR_CFG_PWM1_GROUP == 3) +#define DRV_PWM1_CONFIG \ + {TIM1, RCC_APB2Periph_TIM1, RCC_APB2Periph_GPIOE, GPIOE, GPIO_Pin_9, GPIOE, GPIO_Pin_11, GPIOE, GPIO_Pin_13, GPIOE, GPIO_Pin_14, GPIO_FullRemap_TIM1} +#endif /* MR_CFG_PWM1_GROUP */ +#if (MR_CFG_PWM2_GROUP == 1) +#define DRV_PWM2_CONFIG \ + {TIM2, RCC_APB1Periph_TIM2, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_0, GPIOA, GPIO_Pin_1, GPIOA, GPIO_Pin_2, GPIOA, GPIO_Pin_3, 0} +#elif (MR_CFG_PWM2_GROUP == 2) +#define DRV_PWM2_CONFIG \ + {TIM2, RCC_APB1Periph_TIM2, RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, GPIOA, GPIO_Pin_15, GPIOB, GPIO_Pin_3, GPIOA, GPIO_Pin_2, GPIOA, GPIO_Pin_3, GPIO_PartialRemap1_TIM2} +#elif (MR_CFG_PWM2_GROUP == 3) +#define DRV_PWM2_CONFIG \ + {TIM2, RCC_APB1Periph_TIM2, RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, GPIOA, GPIO_Pin_0, GPIOA, GPIO_Pin_1, GPIOB, GPIO_Pin_10, GPIOA, GPIO_Pin_3, GPIO_PartialRemap2_TIM2} +#elif (MR_CFG_PWM2_GROUP == 4) +#define DRV_PWM2_CONFIG \ + {TIM2, RCC_APB1Periph_TIM2, RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, GPIOA, GPIO_Pin_15, GPIOB, GPIO_Pin_3, GPIOB, GPIO_Pin_10, GPIOB, GPIO_Pin_11, GPIO_FullRemap_TIM2} +#endif /* MR_CFG_PWM2_GROUP */ +#if (MR_CFG_PWM3_GROUP == 1) +#define DRV_PWM3_CONFIG \ + {TIM3, RCC_APB1Periph_TIM3, RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, GPIOA, GPIO_Pin_6, GPIOA, GPIO_Pin_7, GPIOB, GPIO_Pin_0, GPIOB, GPIO_Pin_1, 0} +#elif (MR_CFG_PWM3_GROUP == 2) +#define DRV_PWM3_CONFIG \ + {TIM3, RCC_APB1Periph_TIM3, RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_4, GPIOB, GPIO_Pin_5, GPIOB, GPIO_Pin_0, GPIOB, GPIO_Pin_1, GPIO_PartialRemap_TIM3} +#elif (MR_CFG_PWM3_GROUP == 3) +#define DRV_PWM3_CONFIG \ + {TIM3, RCC_APB1Periph_TIM3, RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_6, GPIOC, GPIO_Pin_7, GPIOC, GPIO_Pin_8, GPIOC, GPIO_Pin_9, GPIO_FullRemap_TIM3} +#endif /* MR_CFG_PWM3_GROUP */ +#if (MR_CFG_PWM4_GROUP == 1) +#define DRV_PWM4_CONFIG \ + {TIM4, RCC_APB1Periph_TIM4, RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_6, GPIOB, GPIO_Pin_7, GPIOB, GPIO_Pin_8, GPIOB, GPIO_Pin_9, 0} +#elif (MR_CFG_PWM4_GROUP == 2) +#define DRV_PWM4_CONFIG \ + {TIM4, RCC_APB1Periph_TIM4, RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_12, GPIOD, GPIO_Pin_13, GPIOD, GPIO_Pin_14, GPIOD, GPIO_Pin_15, GPIO_Remap_TIM4} +#endif /* MR_CFG_PWM4_GROUP */ +#if (MR_CFG_PWM5_GROUP == 1) +#define DRV_PWM5_CONFIG \ + {TIM5, RCC_APB1Periph_TIM5, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_0, GPIOA, GPIO_Pin_1, GPIOA, GPIO_Pin_2, GPIOA, GPIO_Pin_3, 0} +#endif /* MR_CFG_PWM5_GROUP */ +#if (MR_CFG_PWM8_GROUP == 1) +#define DRV_PWM8_CONFIG \ + {TIM8, RCC_APB2Periph_TIM8, RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_6, GPIOC, GPIO_Pin_7, GPIOC, GPIO_Pin_8, GPIOC, GPIO_Pin_9, 0} +#elif (MR_CFG_PWM8_GROUP == 2) +#defined DRV_PWM8_CONFIG \ + {TIM8, RCC_APB2Periph_TIM8, RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, GPIOB, GPIO_Pin_6, GPIOB, GPIO_Pin_7, GPIOB, GPIO_Pin_8, GPIOC, GPIO_Pin_13, GPIO_Remap_TIM8} +#endif /* MR_CFG_PWM8_GROUP */ +#if (MR_CFG_PWM9_GROUP == 1) +#define DRV_PWM9_CONFIG \ + {TIM9, RCC_APB2Periph_TIM9, RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, GPIOA, GPIO_Pin_2, GPIOA, GPIO_Pin_3, GPIOA, GPIO_Pin_4, GPIOC, GPIO_Pin_4, 0} +#elif (MR_CFG_PWM9_GROUP == 2) +#define DRV_PWM9_CONFIG \ + {TIM9, RCC_APB2Periph_TIM9, RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, GPIOA, GPIO_Pin_2, GPIOA, GPIO_Pin_3, GPIOA, GPIO_Pin_4, GPIOC, GPIO_Pin_14, GPIO_PartialRemap_TIM9} +#elif (MR_CFG_PWM9_GROUP == 3) +#define DRV_PWM9_CONFIG \ + {TIM9, RCC_APB2Periph_TIM9, RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_9, GPIOD, GPIO_Pin_11, GPIOD, GPIO_Pin_13, GPIOD, GPIO_Pin_15, GPIO_FullRemap_TIM9} +#endif /* MR_CFG_PWM9_GROUP */ +#if (MR_CFG_PWM10_GROUP == 1) +#define DRV_PWM10_CONFIG \ + {TIM10, RCC_APB2Periph_TIM10, RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, GPIOB, GPIO_Pin_8, GPIOB, GPIO_Pin_9, GPIOC, GPIO_Pin_3, GPIOC, GPIO_Pin_11, 0} +#elif (MR_CFG_PWM10_GROUP == 2) +#define DRV_PWM10_CONFIG \ + {TIM10, RCC_APB2Periph_TIM10, RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, GPIOB, GPIO_Pin_3, GPIOB, GPIO_Pin_4, GPIOB, GPIO_Pin_5, GPIOC, GPIO_Pin_15, GPIO_PartialRemap_TIM10} +#elif (MR_CFG_PWM10_GROUP == 3) +#define DRV_PWM10_CONFIG \ + {TIM10, RCC_APB2Periph_TIM10, RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_1, GPIOD, GPIO_Pin_3, GPIOD, GPIO_Pin_5, GPIOD, GPIO_Pin_7, GPIO_FullRemap_TIM10} +#endif /* MR_CFG_PWM10_GROUP */ + +#define DRV_PWM1_INFO_CONFIG \ + {0, UINT16_MAX, UINT16_MAX} +#define DRV_PWM2_INFO_CONFIG \ + {0, UINT16_MAX, UINT16_MAX} +#define DRV_PWM3_INFO_CONFIG \ + {0, UINT16_MAX, UINT16_MAX} +#define DRV_PWM4_INFO_CONFIG \ + {0, UINT16_MAX, UINT16_MAX} +#define DRV_PWM5_INFO_CONFIG \ + {0, UINT16_MAX, UINT16_MAX} +#define DRV_PWM8_INFO_CONFIG \ + {0, UINT16_MAX, UINT16_MAX} +#define DRV_PWM9_INFO_CONFIG \ + {0, UINT16_MAX, UINT16_MAX} +#define DRV_PWM10_INFO_CONFIG \ + {0, UINT16_MAX, UINT16_MAX} + #if (MR_CFG_UART1_GROUP == 1) #define DRV_UART1_CONFIG \ {USART1, RCC_APB2Periph_USART1, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_10, GPIOA, GPIO_Pin_9, USART1_IRQn, 0} @@ -150,7 +241,7 @@ extern "C" { #endif /* MR_CFG_UART4_GROUP */ #if (MR_CFG_UART5_GROUP == 1) #define DRV_UART5_CONFIG \ - {UART5, RCC_APB1Periph_UART5, RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_13, GPIOC, GPIO_Pin_12, UART5_IRQn, 0} + {UART5, RCC_APB1Periph_UART5, RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_2, GPIOC, GPIO_Pin_12, UART5_IRQn, 0} #elif (MR_CFG_UART5_GROUP == 2) #define DRV_UART5_CONFIG \ {UART5, RCC_APB1Periph_UART5, RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_5, GPIOB, GPIO_Pin_4, UART5_IRQn, GPIO_PartialRemap_USART5} diff --git a/bsp/wch/driver/drv_pwm.c b/bsp/wch/driver/drv_pwm.c new file mode 100644 index 0000000..2a91e59 --- /dev/null +++ b/bsp/wch/driver/drv_pwm.c @@ -0,0 +1,384 @@ +/* + * @copyright (c) 2023-2024, MR Development Team + * + * @license SPDX-License-Identifier: Apache-2.0 + * + * @date 2024-01-01 MacRsh First version + */ + +#include "drv_pwm.h" + +#ifdef MR_USING_PWM + +enum drv_pwm_index +{ +#ifdef MR_USING_PWM1 + DRV_INDEX_PWM1, +#endif /* MR_USING_PWM1 */ +#ifdef MR_USING_PWM2 + DRV_INDEX_PWM2, +#endif /* MR_USING_PWM2 */ +#ifdef MR_USING_PWM3 + DRV_INDEX_PWM3, +#endif /* MR_USING_PWM3 */ +#ifdef MR_USING_PWM4 + DRV_INDEX_PWM4, +#endif /* MR_USING_PWM4 */ +#ifdef MR_USING_PWM5 + DRV_INDEX_PWM5, +#endif /* MR_USING_PWM5 */ +#ifdef MR_USING_PWM8 + DRV_INDEX_PWM8, +#endif /* MR_USING_PWM8 */ +#ifdef MR_USING_PWM9 + DRV_INDEX_PWM9, +#endif /* MR_USING_PWM9 */ +#ifdef MR_USING_PWM10 + DRV_INDEX_PWM10, +#endif /* MR_USING_PWM10 */ + DRV_INDEX_PWM_MAX +}; + +static const char *pwm_name[] = + { +#ifdef MR_USING_PWM1 + "pwm1", +#endif /* MR_USING_PWM1 */ +#ifdef MR_USING_PWM2 + "pwm2", +#endif /* MR_USING_PWM2 */ +#ifdef MR_USING_PWM3 + "pwm3", +#endif /* MR_USING_PWM3 */ +#ifdef MR_USING_PWM4 + "pwm4", +#endif /* MR_USING_PWM4 */ +#ifdef MR_USING_PWM5 + "pwm5", +#endif /* MR_USING_PWM5 */ +#ifdef MR_USING_PWM8 + "pwm8", +#endif /* MR_USING_PWM8 */ +#ifdef MR_USING_PWM9 + "pwm9", +#endif /* MR_USING_PWM9 */ +#ifdef MR_USING_PWM10 + "pwm10", +#endif /* MR_USING_PWM10 */ + }; + +static struct drv_pwm_data pwm_drv_data[] = + { +#ifdef MR_USING_PWM1 + DRV_PWM1_CONFIG, +#endif /* MR_USING_PWM1 */ +#ifdef MR_USING_PWM2 + DRV_PWM2_CONFIG, +#endif /* MR_USING_PWM2 */ +#ifdef MR_USING_PWM3 + DRV_PWM3_CONFIG, +#endif /* MR_USING_PWM3 */ +#ifdef MR_USING_PWM4 + DRV_PWM4_CONFIG, +#endif /* MR_USING_PWM4 */ +#ifdef MR_USING_PWM5 + DRV_PWM5_CONFIG, +#endif /* MR_USING_PWM5 */ +#ifdef MR_USING_PWM8 + DRV_PWM8_CONFIG, +#endif /* MR_USING_PWM8 */ +#ifdef MR_USING_PWM9 + DRV_PWM9_CONFIG, +#endif /* MR_USING_PWM9 */ +#ifdef MR_USING_PWM10 + DRV_PWM10_CONFIG, +#endif /* MR_USING_PWM10 */ + }; + +static struct mr_pwm pwm_dev[MR_ARRAY_NUM(pwm_drv_data)]; + +static struct mr_pwm_info pwm_info[] = + { +#ifdef MR_USING_PWM1 + DRV_PWM1_INFO_CONFIG, +#endif /* MR_USING_PWM1 */ +#ifdef MR_USING_PWM2 + DRV_PWM2_INFO_CONFIG, +#endif /* MR_USING_PWM2 */ +#ifdef MR_USING_PWM3 + DRV_PWM3_INFO_CONFIG, +#endif /* MR_USING_PWM3 */ +#ifdef MR_USING_PWM4 + DRV_PWM4_INFO_CONFIG, +#endif /* MR_USING_PWM4 */ +#ifdef MR_USING_PWM5 + DRV_PWM5_INFO_CONFIG, +#endif /* MR_USING_PWM5 */ +#ifdef MR_USING_PWM8 + DRV_PWM8_INFO_CONFIG, +#endif /* MR_USING_PWM8 */ +#ifdef MR_USING_PWM9 + DRV_PWM9_INFO_CONFIG, +#endif /* MR_USING_PWM9 */ +#ifdef MR_USING_PWM10 + DRV_PWM10_INFO_CONFIG, +#endif /* MR_USING_PWM10 */ + }; + +static int drv_pwm_configure(struct mr_pwm *pwm, int state) +{ + struct drv_pwm_data *pwm_data = (struct drv_pwm_data *)pwm->dev.drv->data; + TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0}; + RCC_ClocksTypeDef RCC_ClockStructure = {0}; + uint32_t pclk = 0; + + /* Configure clock */ + RCC_GetClocksFreq(&RCC_ClockStructure); + if ((uint32_t)pwm_data->instance > APB2PERIPH_BASE) + { + RCC_APB2PeriphClockCmd(pwm_data->clock, state); + pclk = RCC_ClockStructure.PCLK2_Frequency; + } else + { + RCC_APB1PeriphClockCmd(pwm_data->clock, state); + pclk = RCC_ClockStructure.PCLK1_Frequency; + } + + /* Update pwm clock(MHz) */ + pwm->info->clk = pclk / 1000000; + + /* Configure remap */ + if (pwm_data->remap != 0) + { + RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); + GPIO_PinRemapConfig(pwm_data->remap, state); + } + + /* Configure pwm */ + TIM_TimeBaseInitStructure.TIM_Period = 0; + TIM_TimeBaseInitStructure.TIM_Prescaler = 0; + TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; + TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; + TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInit(pwm_data->instance, &TIM_TimeBaseInitStructure); + if (state == DISABLE) + { + TIM_Cmd(pwm_data->instance, DISABLE); + } + return MR_EOK; +} + +static int drv_pwm_channel_configure(struct mr_pwm *pwm, int channel, int state, int polarity) +{ + struct drv_pwm_data *pwm_data = (struct drv_pwm_data *)pwm->dev.drv->data; + TIM_OCInitTypeDef TIM_OCInitStructure = {0}; + GPIO_InitTypeDef GPIO_InitStructure = {0}; + + RCC_APB2PeriphClockCmd(pwm_data->gpio_clock, ENABLE); + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = (state == MR_ENABLE) ? GPIO_Mode_AF_PP : GPIO_Mode_IN_FLOATING; + + TIM_OCInitStructure.TIM_Pulse = 0; + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; + TIM_OCInitStructure.TIM_OutputState = (state == MR_ENABLE) ? TIM_OutputState_Enable : TIM_OutputState_Disable; + TIM_OCInitStructure.TIM_OCPolarity = (polarity == MR_PWM_POLARITY_NORMAL) + ? TIM_OCPolarity_High + : TIM_OCPolarity_Low; + switch (channel) + { + case 1: + { + GPIO_InitStructure.GPIO_Pin = pwm_data->ch1_pin; + GPIO_Init(pwm_data->ch1_port, &GPIO_InitStructure); + TIM_OC1Init(pwm_data->instance, &TIM_OCInitStructure); + TIM_OC1PreloadConfig(pwm_data->instance, state ? TIM_OCPreload_Enable : TIM_OCPreload_Disable); + return MR_EOK; + } + case 2: + { + GPIO_InitStructure.GPIO_Pin = pwm_data->ch2_pin; + GPIO_Init(pwm_data->ch2_port, &GPIO_InitStructure); + TIM_OC2Init(pwm_data->instance, &TIM_OCInitStructure); + TIM_OC2PreloadConfig(pwm_data->instance, state ? TIM_OCPreload_Enable : TIM_OCPreload_Disable); + return MR_EOK; + } + case 3: + { + GPIO_InitStructure.GPIO_Pin = pwm_data->ch3_pin; + GPIO_Init(pwm_data->ch3_port, &GPIO_InitStructure); + TIM_OC3Init(pwm_data->instance, &TIM_OCInitStructure); + TIM_OC3PreloadConfig(pwm_data->instance, state ? TIM_OCPreload_Enable : TIM_OCPreload_Disable); + return MR_EOK; + } + case 4: + { + GPIO_InitStructure.GPIO_Pin = pwm_data->ch4_pin; + GPIO_Init(pwm_data->ch4_port, &GPIO_InitStructure); + TIM_OC4Init(pwm_data->instance, &TIM_OCInitStructure); + TIM_OC4PreloadConfig(pwm_data->instance, state ? TIM_OCPreload_Enable : TIM_OCPreload_Disable); + return MR_EOK; + } + + default: + { + return MR_EINVAL; + } + } + return MR_EOK; +} + +static void drv_pwm_start(struct mr_pwm *pwm, uint32_t prescaler, uint32_t period) +{ + struct drv_pwm_data *pwm_data = (struct drv_pwm_data *)pwm->dev.drv->data; + + /* Set the PSC and ARR, and enable the timer */ + TIM_SetCounter(pwm_data->instance, 0); + TIM_SetAutoreload(pwm_data->instance, period - 1); + TIM_PrescalerConfig(pwm_data->instance, prescaler - 1, TIM_PSCReloadMode_Update); + TIM_CtrlPWMOutputs(pwm_data->instance, ENABLE); + TIM_Cmd(pwm_data->instance, ENABLE); +} + +static void drv_pwm_write(struct mr_pwm *pwm, int channel, uint32_t compare_value) +{ + struct drv_pwm_data *pwm_data = (struct drv_pwm_data *)pwm->dev.drv->data; + + switch (channel) + { + case 1: + { + TIM_SetCompare1(pwm_data->instance, compare_value); + return; + } + case 2: + { + TIM_SetCompare2(pwm_data->instance, compare_value); + return; + } + case 3: + { + TIM_SetCompare3(pwm_data->instance, compare_value); + return; + } + case 4: + { + TIM_SetCompare4(pwm_data->instance, compare_value); + return; + } + default: + { + return; + } + } +} + +static uint32_t drv_pwm_read(struct mr_pwm *pwm, int channel) +{ + struct drv_pwm_data *pwm_data = (struct drv_pwm_data *)pwm->dev.drv->data; + + switch (channel) + { + case 1: + { + return TIM_GetCapture1(pwm_data->instance); + } + case 2: + { + return TIM_GetCapture2(pwm_data->instance); + } + case 3: + { + return TIM_GetCapture3(pwm_data->instance); + } + case 4: + { + return TIM_GetCapture4(pwm_data->instance); + } + default: + { + return 0; + } + } +} + +static struct mr_pwm_ops pwm_drv_ops = + { + drv_pwm_configure, + drv_pwm_channel_configure, + drv_pwm_start, + drv_pwm_write, + drv_pwm_read + }; + +static struct mr_drv pwm_drv[] = + { +#ifdef MR_USING_PWM1 + { + Mr_Drv_Type_PWM, + &pwm_drv_ops, + &pwm_drv_data[DRV_INDEX_PWM1] + }, +#endif /* MR_USING_PWM1 */ +#ifdef MR_USING_PWM2 + { + Mr_Drv_Type_PWM, + &pwm_drv_ops, + &pwm_drv_data[DRV_INDEX_PWM2] + }, +#endif /* MR_USING_PWM2 */ +#ifdef MR_USING_PWM3 + { + Mr_Drv_Type_PWM, + &pwm_drv_ops, + &pwm_drv_data[DRV_INDEX_PWM3] + }, +#endif /* MR_USING_PWM3 */ +#ifdef MR_USING_PWM4 + { + Mr_Drv_Type_PWM, + &pwm_drv_ops, + &pwm_drv_data[DRV_INDEX_PWM4] + }, +#endif /* MR_USING_PWM4 */ +#ifdef MR_USING_PWM5 + { + Mr_Drv_Type_PWM, + &pwm_drv_ops, + &pwm_drv_data[DRV_INDEX_PWM5] + }, +#endif /* MR_USING_PWM5 */ +#ifdef MR_USING_PWM8 + { + Mr_Drv_Type_PWM, + &pwm_drv_ops, + &pwm_drv_data[DRV_INDEX_PWM8] + }, +#endif /* MR_USING_PWM8 */ +#ifdef MR_USING_PWM9 + { + Mr_Drv_Type_PWM, + &pwm_drv_ops, + &pwm_drv_data[DRV_INDEX_PWM9] + }, +#endif /* MR_USING_PWM9 */ +#ifdef MR_USING_PWM10 + { + Mr_Drv_Type_PWM, + &pwm_drv_ops, + &pwm_drv_data[DRV_INDEX_PWM10] + }, +#endif /* MR_USING_PWM10 */ + }; + +static int drv_pwm_init(void) +{ + for (size_t i = 0; i < MR_ARRAY_NUM(pwm_dev); i++) + { + mr_pwm_register(&pwm_dev[i], pwm_name[i], &pwm_drv[i], &pwm_info[i]); + } + return MR_EOK; +} +MR_INIT_DRV_EXPORT(drv_pwm_init); + +#endif /* MR_USING_PWM */ diff --git a/bsp/wch/driver/drv_pwm.h b/bsp/wch/driver/drv_pwm.h new file mode 100644 index 0000000..4c855e2 --- /dev/null +++ b/bsp/wch/driver/drv_pwm.h @@ -0,0 +1,43 @@ +/* + * @copyright (c) 2023-2024, MR Development Team + * + * @license SPDX-License-Identifier: Apache-2.0 + * + * @date 2024-01-01 MacRsh First version + */ + +#ifndef _DRV_PWM_H_ +#define _DRV_PWM_H_ + +#include "include/device/mr_pwm.h" +#include "mr_board.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef MR_USING_PWM + +struct drv_pwm_data +{ + TIM_TypeDef *instance; + uint32_t clock; + uint32_t gpio_clock; + GPIO_TypeDef *ch1_port; + uint32_t ch1_pin; + GPIO_TypeDef *ch2_port; + uint32_t ch2_pin; + GPIO_TypeDef *ch3_port; + uint32_t ch3_pin; + GPIO_TypeDef *ch4_port; + uint32_t ch4_pin; + uint32_t remap; +}; + +#endif /* MR_USING_PWM */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DRV_PWM_H_ */