From 4c30b09c08646c731e9099e9b408f743c09e032f Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Wed, 14 Aug 2024 02:03:06 +0200 Subject: [PATCH] feat: add color formats to WS2812 driver (#5428) --- radio/src/boards/generic_stm32/rgb_leds.h | 2 -- .../common/arm/stm32/stm32_pulse_driver.cpp | 4 ++++ .../targets/common/arm/stm32/stm32_ws2812.cpp | 16 ++++++++++++---- .../src/targets/common/arm/stm32/stm32_ws2812.h | 16 +++++++++++++--- radio/src/targets/pl18/board.cpp | 2 +- radio/src/targets/taranis/board.cpp | 2 +- 6 files changed, 31 insertions(+), 11 deletions(-) diff --git a/radio/src/boards/generic_stm32/rgb_leds.h b/radio/src/boards/generic_stm32/rgb_leds.h index 535d1c556..7dc76ae1b 100644 --- a/radio/src/boards/generic_stm32/rgb_leds.h +++ b/radio/src/boards/generic_stm32/rgb_leds.h @@ -25,5 +25,3 @@ void rgbLedStart(); void rgbLedStop(); void rgbSetLedColor(unsigned char, unsigned char, unsigned char, unsigned char); void rgbLedColorApply(); - -// void boardInitRGBLed(); diff --git a/radio/src/targets/common/arm/stm32/stm32_pulse_driver.cpp b/radio/src/targets/common/arm/stm32/stm32_pulse_driver.cpp index 744e9e08e..83e64d9db 100644 --- a/radio/src/targets/common/arm/stm32/stm32_pulse_driver.cpp +++ b/radio/src/targets/common/arm/stm32/stm32_pulse_driver.cpp @@ -64,7 +64,11 @@ static void init_dma_arr_mode(const stm32_pulse_timer_t* tim) dmaInit.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_HALFWORD; } +#if defined(STM32H7) + dmaInit.PeriphRequest = tim->DMA_Channel; +#else dmaInit.Channel = tim->DMA_Channel; +#endif dmaInit.Priority = LL_DMA_PRIORITY_VERYHIGH; stm32_dma_enable_clock(tim->DMAx); diff --git a/radio/src/targets/common/arm/stm32/stm32_ws2812.cpp b/radio/src/targets/common/arm/stm32/stm32_ws2812.cpp index 21c08ee49..51c8212b5 100644 --- a/radio/src/targets/common/arm/stm32/stm32_ws2812.cpp +++ b/radio/src/targets/common/arm/stm32/stm32_ws2812.cpp @@ -40,6 +40,10 @@ static uint8_t _led_colors[WS2812_BYTES_PER_LED * WS2812_MAX_LEDS]; // LED strip length static uint8_t _led_strip_len; +static uint8_t _r_offset; +static uint8_t _g_offset; +static uint8_t _b_offset; + // DMA buffer contains data for 2 LEDs and is filled // half by half on DMA HT and TC IRQs #define WS2821_DMA_BUFFER_HALF_LEN (WS2812_BYTES_PER_LED * 8) @@ -195,7 +199,7 @@ static void _init_timer(const stm32_pulse_timer_t* tim) NVIC_SetPriority(tim->DMA_IRQn, WS2812_DMA_IRQ_PRIO); } -void ws2812_init(const stm32_pulse_timer_t* timer, uint8_t strip_len) +void ws2812_init(const stm32_pulse_timer_t* timer, uint8_t strip_len, uint8_t type) { WS2812_DBG_INIT; @@ -208,6 +212,10 @@ void ws2812_init(const stm32_pulse_timer_t* timer, uint8_t strip_len) _led_strip_len = WS2812_MAX_LEDS; } + _r_offset = (type >> 4) & 0b11; + _g_offset = (type >> 2) & 0b11; + _b_offset = type & 0b11; + _init_timer(timer); } @@ -216,9 +224,9 @@ void ws2812_set_color(uint8_t led, uint8_t r, uint8_t g, uint8_t b) if (led >= _led_strip_len) return; uint8_t* pixel = &_led_colors[led * WS2812_BYTES_PER_LED]; - pixel[0] = g; - pixel[1] = r; - pixel[2] = b; + pixel[_r_offset] = r; + pixel[_g_offset] = g; + pixel[_b_offset] = b; } void ws2812_update(const stm32_pulse_timer_t* tim) diff --git a/radio/src/targets/common/arm/stm32/stm32_ws2812.h b/radio/src/targets/common/arm/stm32/stm32_ws2812.h index cc3323038..c2dd69d48 100644 --- a/radio/src/targets/common/arm/stm32/stm32_ws2812.h +++ b/radio/src/targets/common/arm/stm32/stm32_ws2812.h @@ -23,14 +23,24 @@ #include "stm32_pulse_driver.h" +// Offset: R G B +#define WS2812_RGB ((0 << 4) | (1 << 2) | (2)) +#define WS2812_GRB ((1 << 4) | (0 << 2) | (2)) + // RGB #define WS2812_BYTES_PER_LED 3 -#define WS2812_MAX_LEDS 8 + +// Maximum number of supported LEDs +#if !defined(WS2812_MAX_LEDS) +# define WS2812_MAX_LEDS 8 +#endif // Number of LED periods used for trailing reset -#define WS2812_TRAILING_RESET 10 +#if !defined(WS2812_TRAILING_RESET) +# define WS2812_TRAILING_RESET 10 +#endif -void ws2812_init(const stm32_pulse_timer_t* timer, uint8_t strip_len); +void ws2812_init(const stm32_pulse_timer_t* timer, uint8_t strip_len, uint8_t type); void ws2812_update(const stm32_pulse_timer_t* timer); void ws2812_dma_isr(const stm32_pulse_timer_t* timer); diff --git a/radio/src/targets/pl18/board.cpp b/radio/src/targets/pl18/board.cpp index b834dca20..5013da46f 100644 --- a/radio/src/targets/pl18/board.cpp +++ b/radio/src/targets/pl18/board.cpp @@ -119,7 +119,7 @@ void boardInit() touchPanelInit(); usbInit(); - ws2812_init(&_led_timer, LED_STRIP_LENGTH); + ws2812_init(&_led_timer, LED_STRIP_LENGTH, WS2812_GRB); ledStripOff(); uint32_t press_start = 0; diff --git a/radio/src/targets/taranis/board.cpp b/radio/src/targets/taranis/board.cpp index d264e8dbd..baf333ea4 100644 --- a/radio/src/targets/taranis/board.cpp +++ b/radio/src/targets/taranis/board.cpp @@ -184,7 +184,7 @@ void boardInit() #if defined(LED_STRIP_GPIO) extern const stm32_pulse_timer_t _led_timer; - ws2812_init(&_led_timer, LED_STRIP_LENGTH); + ws2812_init(&_led_timer, LED_STRIP_LENGTH, WS2812_GRB); for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) { ws2812_set_color(i, 0, 0, 50); }