From d3e1f6b0ccc265a3b233becded31b508ea5c5792 Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Tue, 23 Feb 2021 15:36:12 +0300 Subject: [PATCH 1/2] Add support for complementary outputs to the WS2812 PWM driver Advanced-control timers (TIM1, TIM8, TIM20) on STM32 support complementary outputs (TIMx_CHyN) that actually have configurable polarity and can work exactly like normal outputs. Add support for these outputs to the WS2812 PWM driver. Using a complementary output requires adding #define WS2812_PWM_COMPLEMENTARY_OUTPUT to the usual set of PWM driver configuration options. In addition, the STM32_PWM_USE_ADVANCED option in mcuconf.h must be set to TRUE (otherwise the flags to configure complementary outputs are silently ignored by the ChibiOS low-level PWM driver). Note that complementary outputs of general-purpose timers (e.g., TIM15/TIM16/TIM17 on STM32F303) are still not supported, because the current version of the ChibiOS low-level PWM driver does not have the code to control those outputs. --- drivers/chibios/ws2812_pwm.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/chibios/ws2812_pwm.c b/drivers/chibios/ws2812_pwm.c index 140120d488de..e6af55b6b361 100644 --- a/drivers/chibios/ws2812_pwm.c +++ b/drivers/chibios/ws2812_pwm.c @@ -27,6 +27,15 @@ # error "please consult your MCU's datasheet and specify in your config.h: #define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM?_UP" #endif +#ifndef WS2812_PWM_COMPLEMENTARY_OUTPUT +# define WS2812_PWM_OUTPUT_MODE PWM_OUTPUT_ACTIVE_HIGH +#else +# if !STM32_PWM_USE_ADVANCED +# error "WS2812_PWM_COMPLEMENTARY_OUTPUT requires STM32_PWM_USE_ADVANCED == TRUE" +# endif +# define WS2812_PWM_OUTPUT_MODE PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH +#endif + // Push Pull or Open Drain Configuration // Default Push Pull #ifndef WS2812_EXTERNAL_PULLUP @@ -247,7 +256,7 @@ void ws2812_init(void) { .channels = { [0 ... 3] = {.mode = PWM_OUTPUT_DISABLED, .callback = NULL}, // Channels default to disabled - [WS2812_PWM_CHANNEL - 1] = {.mode = PWM_OUTPUT_ACTIVE_HIGH, .callback = NULL}, // Turn on the channel we care about + [WS2812_PWM_CHANNEL - 1] = {.mode = WS2812_PWM_OUTPUT_MODE, .callback = NULL}, // Turn on the channel we care about }, .cr2 = 0, .dier = TIM_DIER_UDE, // DMA on update event for next period From 01f7e92322e5fdb7b97e41c1aeef36a7124d8fb9 Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Tue, 23 Feb 2021 16:17:15 +0300 Subject: [PATCH 2/2] Document support for complementary outputs in the WS2812 PWM driver --- docs/ws2812_driver.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/ws2812_driver.md b/docs/ws2812_driver.md index cca6827ec8d5..fa14f02fdbc0 100644 --- a/docs/ws2812_driver.md +++ b/docs/ws2812_driver.md @@ -102,11 +102,14 @@ Configure the hardware via your config.h: #define WS2812_PWM_DRIVER PWMD2 // default: PWMD2 #define WS2812_PWM_CHANNEL 2 // default: 2 #define WS2812_PWM_PAL_MODE 2 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 2 +//#define WS2812_PWM_COMPLEMENTARY_OUTPUT // Define for a complementary timer output (TIMx_CHyN); omit for a normal timer output (TIMx_CHy). #define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA Stream for TIMx_UP, see the respective reference manual for the appropriate values for your MCU. #define WS2812_DMA_CHANNEL 2 // DMA Channel for TIMx_UP, see the respective reference manual for the appropriate values for your MCU. #define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM2_UP // DMAMUX configuration for TIMx_UP -- only required if your MCU has a DMAMUX peripheral, see the respective reference manual for the appropriate values for your MCU. ``` +Note that using a complementary timer output (TIMx_CHyN) is possible only for advanced-control timers (TIM1, TIM8, TIM20 on STM32), and the `STM32_PWM_USE_ADVANCED` option in mcuconf.h must be set to `TRUE`. Complementary outputs of general-purpose timers are not supported due to ChibiOS limitations. + You must also turn on the PWM feature in your halconf.h and mcuconf.h #### Testing Notes