Browse Source

Add support for complementary outputs to the WS2812 PWM driver (#11988)

Sergey Vlasov 4 years ago
parent
commit
18a333ec6b
2 changed files with 13 additions and 1 deletions
  1. 3 0
      docs/ws2812_driver.md
  2. 10 1
      drivers/chibios/ws2812_pwm.c

+ 3 - 0
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

+ 10 - 1
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