From cd2a738b9d3183cbcd48fd2de555def6b3779a7f Mon Sep 17 00:00:00 2001 From: Tero Marttila Date: Mon, 2 Jun 2025 23:00:59 +0300 Subject: [PATCH 1/4] leds: add LEDS_FORMAT_{RGB,BGR,GRB}XI --- components/leds/format.c | 70 ++++++++++++++++++++++++++++++++++ components/leds/include/leds.h | 2 + main/leds_config.c | 2 + 3 files changed, 74 insertions(+) diff --git a/components/leds/format.c b/components/leds/format.c index b947d938..fef639d9 100644 --- a/components/leds/format.c +++ b/components/leds/format.c @@ -19,6 +19,8 @@ unsigned leds_format_count(size_t len, enum leds_format format, unsigned group) return len / (4 * group) * group; case LEDS_FORMAT_RGBXI: + case LEDS_FORMAT_BGRXI: + case LEDS_FORMAT_GRBXI: return len / (3 + group) * group; case LEDS_FORMAT_RGBWXI: @@ -156,6 +158,66 @@ void leds_set_format_rgbxi(struct leds *leds, const uint8_t *data, size_t len, s } } +void leds_set_format_bgrxi(struct leds *leds, const uint8_t *data, size_t len, struct leds_format_params params) +{ + enum leds_parameter_type parameter_type = leds_parameter_type(leds); + uint8_t parameter_default = leds_parameter_default(leds); + + LOG_DEBUG("len=%u offset=%u count=%u segment=%u group=%u", len, params.offset, params.count, params.segment, params.group); + + size_t off = 0; + + for (unsigned g = 0; g * params.group < params.count && len >= off + 3 + params.group; g++) { + struct leds_color group_color = {}; + + group_color.b = data[off++]; + group_color.g = data[off++]; + group_color.r = data[off++]; + group_color.parameter = parameter_default; + + LOG_DEBUG("\tg=%u off=%u rgb=%02x%02x%02x", g, off, group_color.r, group_color.g, group_color.b); + + for (unsigned i = 0; i < params.group && g * params.group + i < params.count; i++) { + uint8_t intensity = data[off++]; + struct leds_color pixel_color = leds_color_intensity(group_color, parameter_type, intensity); + + for (unsigned j = 0; j < params.segment; j++) { + leds->pixels[params.offset + (g * params.group + i) * params.segment + j] = pixel_color; + } + } + } +} + +void leds_set_format_grbxi(struct leds *leds, const uint8_t *data, size_t len, struct leds_format_params params) +{ + enum leds_parameter_type parameter_type = leds_parameter_type(leds); + uint8_t parameter_default = leds_parameter_default(leds); + + LOG_DEBUG("len=%u offset=%u count=%u segment=%u group=%u", len, params.offset, params.count, params.segment, params.group); + + size_t off = 0; + + for (unsigned g = 0; g * params.group < params.count && len >= off + 3 + params.group; g++) { + struct leds_color group_color = {}; + + group_color.g = data[off++]; + group_color.r = data[off++]; + group_color.b = data[off++]; + group_color.parameter = parameter_default; + + LOG_DEBUG("\tg=%u off=%u rgb=%02x%02x%02x", g, off, group_color.r, group_color.g, group_color.b); + + for (unsigned i = 0; i < params.group && g * params.group + i < params.count; i++) { + uint8_t intensity = data[off++]; + struct leds_color pixel_color = leds_color_intensity(group_color, parameter_type, intensity); + + for (unsigned j = 0; j < params.segment; j++) { + leds->pixels[params.offset + (g * params.group + i) * params.segment + j] = pixel_color; + } + } + } +} + void leds_set_format_rgbwxi(struct leds *leds, const uint8_t *data, size_t len, struct leds_format_params params) { enum leds_parameter_type parameter_type = leds_parameter_type(leds); @@ -234,6 +296,14 @@ int leds_set_format(struct leds *leds, enum leds_format format, const void *data leds_set_format_rgbxi(leds, data, len, params); return 0; + case LEDS_FORMAT_BGRXI: + leds_set_format_bgrxi(leds, data, len, params); + return 0; + + case LEDS_FORMAT_GRBXI: + leds_set_format_grbxi(leds, data, len, params); + return 0; + case LEDS_FORMAT_RGBWXI: leds_set_format_rgbwxi(leds, data, len, params); return 0; diff --git a/components/leds/include/leds.h b/components/leds/include/leds.h index 88e6794e..a6cdefa9 100644 --- a/components/leds/include/leds.h +++ b/components/leds/include/leds.h @@ -98,6 +98,8 @@ enum leds_format { LEDS_FORMAT_RGBW, LEDS_FORMAT_RGBXI, // grouped RGB + intensity + LEDS_FORMAT_BGRXI, // grouped BGR + intensity + LEDS_FORMAT_GRBXI, // grouped GRB + intensity LEDS_FORMAT_RGBWXI, // grouped RGBW + intensity }; diff --git a/main/leds_config.c b/main/leds_config.c index 819707b9..595e25c2 100644 --- a/main/leds_config.c +++ b/main/leds_config.c @@ -101,6 +101,8 @@ const struct config_enum leds_format_enum[] = { { "RGBA", .value = LEDS_FORMAT_RGBA }, { "RGBW", .value = LEDS_FORMAT_RGBW }, { "RGBxI", .value = LEDS_FORMAT_RGBXI }, + { "BGRxI", .value = LEDS_FORMAT_BGRXI }, + { "GRBxI", .value = LEDS_FORMAT_GRBXI }, { "RGBWxI", .value = LEDS_FORMAT_RGBWXI }, {} }; From 299ac03e96465864d9cfb020f7e74d19e942584e Mon Sep 17 00:00:00 2001 From: Tero Marttila Date: Mon, 2 Jun 2025 23:19:03 +0300 Subject: [PATCH 2/4] leds: refactor leds_pixel_{rgb,grb} --- components/leds/pixel.h | 40 ++++++++++++++++++++++++ components/leds/protocols/ws2811.h | 18 ----------- components/leds/protocols/ws2811_i2s.c | 3 +- components/leds/protocols/ws2811_uart.c | 3 +- components/leds/protocols/ws2812b.h | 18 ----------- components/leds/protocols/ws2812b_i2s.c | 3 +- components/leds/protocols/ws2812b_uart.c | 3 +- 7 files changed, 48 insertions(+), 40 deletions(-) create mode 100644 components/leds/pixel.h diff --git a/components/leds/pixel.h b/components/leds/pixel.h new file mode 100644 index 00000000..b606baee --- /dev/null +++ b/components/leds/pixel.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include "limit.h" + +union leds_pixel_rgb { + struct { + uint8_t b, g, r; + }; + + // aligned with 0xXXRRGGBB on little-endian architectures + uint32_t _rgb; +}; + +static inline union leds_pixel_rgb leds_pixel_rgb(struct leds_color color, unsigned index, const struct leds_limit *limit) +{ + return (union leds_pixel_rgb) { + .b = leds_limit_uint8(limit, index, color.b), + .g = leds_limit_uint8(limit, index, color.g), + .r = leds_limit_uint8(limit, index, color.r), + }; +} + +union leds_pixel_grb { + struct { + uint8_t b, r, g; + }; + + // aligned with 0xXXGGRRBB on little-endian architectures + uint32_t _grb; +}; + +static inline union leds_pixel_grb leds_pixel_grb(struct leds_color color, unsigned index, const struct leds_limit *limit) +{ + return (union leds_pixel_grb) { + .b = leds_limit_uint8(limit, index, color.b), + .r = leds_limit_uint8(limit, index, color.r), + .g = leds_limit_uint8(limit, index, color.g), + }; +} diff --git a/components/leds/protocols/ws2811.h b/components/leds/protocols/ws2811.h index 7283a738..d558165c 100644 --- a/components/leds/protocols/ws2811.h +++ b/components/leds/protocols/ws2811.h @@ -3,24 +3,6 @@ #include #include "../protocol.h" -union ws2811_pixel { - struct { - uint8_t b, g, r; - }; - - // aligned with 0xXXRRGGBB on little-endian architectures - uint32_t _rgb; -}; - -static inline union ws2811_pixel ws2811_pixel(struct leds_color color, unsigned index, const struct leds_limit *limit) -{ - return (union ws2811_pixel) { - .b = leds_limit_uint8(limit, index, color.b), - .g = leds_limit_uint8(limit, index, color.g), - .r = leds_limit_uint8(limit, index, color.r), - }; -} - extern struct leds_protocol_type leds_protocol_ws2811; #if CONFIG_LEDS_I2S_ENABLED diff --git a/components/leds/protocols/ws2811_i2s.c b/components/leds/protocols/ws2811_i2s.c index 0558b417..fe5add8c 100644 --- a/components/leds/protocols/ws2811_i2s.c +++ b/components/leds/protocols/ws2811_i2s.c @@ -1,5 +1,6 @@ #include "ws2811.h" #include "../leds.h" +#include "../pixel.h" #include "../interfaces/i2s.h" #include @@ -38,7 +39,7 @@ void leds_protocol_ws2811_i2s_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) { - union ws2811_pixel pixel = ws2811_pixel(pixels[index], index, limit); + union leds_pixel_rgb pixel = leds_pixel_rgb(pixels[index], index, limit); // 16-bit little-endian buf[0] = ws2811_lut[(pixel._rgb >> 20) & 0xf]; diff --git a/components/leds/protocols/ws2811_uart.c b/components/leds/protocols/ws2811_uart.c index 2bab27d1..ef1fcc34 100644 --- a/components/leds/protocols/ws2811_uart.c +++ b/components/leds/protocols/ws2811_uart.c @@ -1,5 +1,6 @@ #include "ws2811.h" #include "../leds.h" +#include "../pixel.h" #include "../interfaces/uart.h" #include @@ -63,7 +64,7 @@ void leds_protocol_ws2811_uart_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) { - union ws2811_pixel pixel = ws2811_pixel(pixels[index], index, limit); + union leds_pixel_rgb pixel = leds_pixel_rgb(pixels[index], index, limit); // 16-bit little-endian buf[0] = ws2811_lut[(pixel._rgb >> 20) & 0xf]; diff --git a/components/leds/protocols/ws2812b.h b/components/leds/protocols/ws2812b.h index 4aecc74d..c5759ee6 100644 --- a/components/leds/protocols/ws2812b.h +++ b/components/leds/protocols/ws2812b.h @@ -3,24 +3,6 @@ #include #include "../protocol.h" -union ws2812b_pixel { - struct { - uint8_t b, r, g; - }; - - // aligned with 0xXXGGRRBB on little-endian architectures - uint32_t _grb; -}; - -static inline union ws2812b_pixel ws2812b_pixel(struct leds_color color, unsigned index, const struct leds_limit *limit) -{ - return (union ws2812b_pixel) { - .b = leds_limit_uint8(limit, index, color.b), - .r = leds_limit_uint8(limit, index, color.r), - .g = leds_limit_uint8(limit, index, color.g), - }; -} - extern struct leds_protocol_type leds_protocol_ws2812b; #if CONFIG_LEDS_I2S_ENABLED diff --git a/components/leds/protocols/ws2812b_i2s.c b/components/leds/protocols/ws2812b_i2s.c index 2bd839ca..9a90546c 100644 --- a/components/leds/protocols/ws2812b_i2s.c +++ b/components/leds/protocols/ws2812b_i2s.c @@ -1,5 +1,6 @@ #include "ws2812b.h" #include "../leds.h" +#include "../pixel.h" #include "../interfaces/i2s.h" #include @@ -38,7 +39,7 @@ void leds_protocol_ws2812b_i2s_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) { - union ws2812b_pixel pixel = ws2812b_pixel(pixels[index], index, limit); + union leds_pixel_grb pixel = leds_pixel_grb(pixels[index], index, limit); // 16-bit little-endian buf[0] = ws2812b_lut[(pixel._grb >> 20) & 0xf]; diff --git a/components/leds/protocols/ws2812b_uart.c b/components/leds/protocols/ws2812b_uart.c index fec4b2f9..c19c5667 100644 --- a/components/leds/protocols/ws2812b_uart.c +++ b/components/leds/protocols/ws2812b_uart.c @@ -1,5 +1,6 @@ #include "ws2812b.h" #include "../leds.h" +#include "../pixel.h" #include "../interfaces/uart.h" #include @@ -116,7 +117,7 @@ void leds_protocol_ws2812b_uart_out(uint16_t buf[4], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) { - union ws2812b_pixel pixel = ws2812b_pixel(pixels[index], index, limit); + union leds_pixel_grb pixel = leds_pixel_grb(pixels[index], index, limit); // 16-bit little-endian buf[0] = ws2812b_lut[(pixel._grb >> 18) & 0x3f]; From d7364d23e3efabf494f83020808b499e6830d92e Mon Sep 17 00:00:00 2001 From: Tero Marttila Date: Mon, 2 Jun 2025 23:20:38 +0300 Subject: [PATCH 3/4] leds: refactor leds_pixel_{rgb,grb,grbw} --- components/leds/pixel.h | 19 +++++++++++++++++++ components/leds/protocols/sk6812grbw.h | 19 ------------------- components/leds/protocols/sk6812grbw_i2s.c | 3 ++- components/leds/protocols/sk6812grbw_uart.c | 3 ++- components/leds/protocols/sm16703.h | 18 ------------------ components/leds/protocols/sm16703_i2s.c | 3 ++- 6 files changed, 25 insertions(+), 40 deletions(-) diff --git a/components/leds/pixel.h b/components/leds/pixel.h index b606baee..9d825f7e 100644 --- a/components/leds/pixel.h +++ b/components/leds/pixel.h @@ -38,3 +38,22 @@ static inline union leds_pixel_grb leds_pixel_grb(struct leds_color color, unsig .g = leds_limit_uint8(limit, index, color.g), }; } + +union leds_pixel_grbw { + struct { + uint8_t w, b, r, g; + }; + + // aligned with 0xGGRRBBWW on little-endian architectures + uint32_t grbw; +}; + +static inline union leds_pixel_grbw leds_pixel_grbw(struct leds_color color, unsigned index, const struct leds_limit *limit) +{ + return (union leds_pixel_grbw) { + .w = leds_limit_uint8(limit, index, color.white), + .b = leds_limit_uint8(limit, index, color.b), + .r = leds_limit_uint8(limit, index, color.r), + .g = leds_limit_uint8(limit, index, color.g), + }; +} diff --git a/components/leds/protocols/sk6812grbw.h b/components/leds/protocols/sk6812grbw.h index 2c24c09c..ae6d042c 100644 --- a/components/leds/protocols/sk6812grbw.h +++ b/components/leds/protocols/sk6812grbw.h @@ -3,25 +3,6 @@ #include #include "../protocol.h" -union sk6812grbw_pixel { - struct { - uint8_t w, b, r, g; - }; - - // aligned with 0xGGRRBBWW on little-endian architectures - uint32_t grbw; -}; - -static inline union sk6812grbw_pixel sk6812grbw_pixel(struct leds_color color, unsigned index, const struct leds_limit *limit) -{ - return (union sk6812grbw_pixel) { - .w = leds_limit_uint8(limit, index, color.white), - .b = leds_limit_uint8(limit, index, color.b), - .r = leds_limit_uint8(limit, index, color.r), - .g = leds_limit_uint8(limit, index, color.g), - }; -} - extern struct leds_protocol_type leds_protocol_sk6812grbw; #if CONFIG_LEDS_I2S_ENABLED diff --git a/components/leds/protocols/sk6812grbw_i2s.c b/components/leds/protocols/sk6812grbw_i2s.c index 0126ee07..112ef57c 100644 --- a/components/leds/protocols/sk6812grbw_i2s.c +++ b/components/leds/protocols/sk6812grbw_i2s.c @@ -1,5 +1,6 @@ #include "sk6812grbw.h" #include "../leds.h" +#include "../pixel.h" #include "../interfaces/i2s.h" #include @@ -40,7 +41,7 @@ void leds_protocol_sk6812grbw_i2s_out(uint16_t buf[8], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) { - union sk6812grbw_pixel pixel = sk6812grbw_pixel(pixels[index], index, limit); + union leds_pixel_grbw pixel = leds_pixel_grbw(pixels[index], index, limit); // 16-bit little-endian buf[0] = sk6812_i2s_lut[(pixel.grbw >> 28) & 0xf]; diff --git a/components/leds/protocols/sk6812grbw_uart.c b/components/leds/protocols/sk6812grbw_uart.c index a3f0a637..c6b52498 100644 --- a/components/leds/protocols/sk6812grbw_uart.c +++ b/components/leds/protocols/sk6812grbw_uart.c @@ -1,5 +1,6 @@ #include "sk6812grbw.h" #include "../leds.h" +#include "../pixel.h" #include "../interfaces/uart.h" #include @@ -68,7 +69,7 @@ void leds_protocol_sk6812grbw_uart_out(uint16_t buf[8], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) { - union sk6812grbw_pixel pixel = sk6812grbw_pixel(pixels[index], index, limit); + union leds_pixel_grbw pixel = leds_pixel_grbw(pixels[index], index, limit); // 16-bit little-endian buf[0] = sk6812_lut[(pixel.grbw >> 28) & 0xf]; diff --git a/components/leds/protocols/sm16703.h b/components/leds/protocols/sm16703.h index c7684ce3..87e2b829 100644 --- a/components/leds/protocols/sm16703.h +++ b/components/leds/protocols/sm16703.h @@ -3,24 +3,6 @@ #include #include "../protocol.h" -union sm16703_pixel { - struct { - uint8_t b, g, r; - }; - - // aligned with 0xXXRRGGBB on little-endian architectures - uint32_t _rgb; -}; - -static inline union sm16703_pixel sm16703_pixel(struct leds_color color, unsigned index, const struct leds_limit *limit) -{ - return (union sm16703_pixel) { - .b = leds_limit_uint8(limit, index, color.b), - .g = leds_limit_uint8(limit, index, color.g), - .r = leds_limit_uint8(limit, index, color.r), - }; -} - extern struct leds_protocol_type leds_protocol_sm16703; #if CONFIG_LEDS_I2S_ENABLED diff --git a/components/leds/protocols/sm16703_i2s.c b/components/leds/protocols/sm16703_i2s.c index a65eaed4..27d01624 100644 --- a/components/leds/protocols/sm16703_i2s.c +++ b/components/leds/protocols/sm16703_i2s.c @@ -1,5 +1,6 @@ #include "sm16703.h" #include "../leds.h" +#include "../pixel.h" #include "../interfaces/i2s.h" #include @@ -38,7 +39,7 @@ void leds_protocol_sm16703_i2s_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) { - union sm16703_pixel pixel = sm16703_pixel(pixels[index], index, limit); + union leds_pixel_rgb pixel = leds_pixel_rgb(pixels[index], index, limit); // 16-bit little-endian buf[0] = sm16703_lut[(pixel._rgb >> 20) & 0xf]; From 83096bfbaa432e382ae47a401cd4b6535d1fec14 Mon Sep 17 00:00:00 2001 From: Tero Marttila Date: Mon, 2 Jun 2025 23:30:24 +0300 Subject: [PATCH 4/4] leds: split LEDS_PROTOCOL_{WS2811,WS2812B}_{RGB,GRB} --- components/leds/include/leds.h | 10 ++++++++-- components/leds/protocol.c | 6 ++++-- components/leds/protocols/ws2811.c | 15 ++++++++++++--- components/leds/protocols/ws2811.h | 8 +++++--- components/leds/protocols/ws2811_i2s.c | 15 ++++++++++++++- components/leds/protocols/ws2811_uart.c | 2 +- components/leds/protocols/ws2812b.c | 15 ++++++++++++--- components/leds/protocols/ws2812b.h | 8 +++++--- components/leds/protocols/ws2812b_i2s.c | 15 ++++++++++++++- components/leds/protocols/ws2812b_uart.c | 2 +- main/leds_config.c | 6 ++++-- 11 files changed, 80 insertions(+), 22 deletions(-) diff --git a/components/leds/include/leds.h b/components/leds/include/leds.h index a6cdefa9..759864f2 100644 --- a/components/leds/include/leds.h +++ b/components/leds/include/leds.h @@ -81,13 +81,19 @@ enum leds_protocol { LEDS_PROTOCOL_APA102, LEDS_PROTOCOL_P9813, - LEDS_PROTOCOL_WS2812B, + LEDS_PROTOCOL_WS2812B_GRB, + LEDS_PROTOCOL_WS2812B_RGB, LEDS_PROTOCOL_SK6812_GRBW, - LEDS_PROTOCOL_WS2811, + LEDS_PROTOCOL_WS2811_RGB, + LEDS_PROTOCOL_WS2811_GRB, LEDS_PROTOCOL_SK9822, LEDS_PROTOCOL_SM16703, LEDS_PROTOCOLS_COUNT, + + // compat + LEDS_PROTOCOL_WS2812B = LEDS_PROTOCOL_WS2812B_GRB, + LEDS_PROTOCOL_WS2811 = LEDS_PROTOCOL_WS2811_RGB, }; enum leds_format { diff --git a/components/leds/protocol.c b/components/leds/protocol.c index 1249561e..d06d6eb6 100644 --- a/components/leds/protocol.c +++ b/components/leds/protocol.c @@ -13,9 +13,11 @@ const struct leds_protocol_type *leds_protocol_types[LEDS_PROTOCOLS_COUNT] = { [LEDS_PROTOCOL_APA102] = &leds_protocol_apa102, [LEDS_PROTOCOL_P9813] = &leds_protocol_p9813, - [LEDS_PROTOCOL_WS2812B] = &leds_protocol_ws2812b, + [LEDS_PROTOCOL_WS2812B_GRB] = &leds_protocol_ws2812b_grb, + [LEDS_PROTOCOL_WS2812B_RGB] = &leds_protocol_ws2812b_rgb, [LEDS_PROTOCOL_SK6812_GRBW] = &leds_protocol_sk6812grbw, - [LEDS_PROTOCOL_WS2811] = &leds_protocol_ws2811, + [LEDS_PROTOCOL_WS2811_RGB] = &leds_protocol_ws2811_rgb, + [LEDS_PROTOCOL_WS2811_GRB] = &leds_protocol_ws2811_grb, [LEDS_PROTOCOL_SK9822] = &leds_protocol_sk9822, [LEDS_PROTOCOL_SM16703] = &leds_protocol_sm16703, }; diff --git a/components/leds/protocols/ws2811.c b/components/leds/protocols/ws2811.c index c9105316..426bfd8e 100644 --- a/components/leds/protocols/ws2811.c +++ b/components/leds/protocols/ws2811.c @@ -3,14 +3,23 @@ #include "../interfaces/i2s.h" #include "../interfaces/uart.h" -struct leds_protocol_type leds_protocol_ws2811 = { +struct leds_protocol_type leds_protocol_ws2811_rgb = { #if CONFIG_LEDS_I2S_ENABLED .i2s_interface_mode = LEDS_INTERFACE_I2S_MODE_24BIT_1U250_4X4_80UL, - .i2s_interface_func = LEDS_INTERFACE_I2S_FUNC(i2s_mode_24bit_4x4, leds_protocol_ws2811_i2s_out), + .i2s_interface_func = LEDS_INTERFACE_I2S_FUNC(i2s_mode_24bit_4x4, leds_protocol_ws2811_i2s_rgb_out), #endif #if CONFIG_LEDS_UART_ENABLED .uart_interface_mode = LEDS_INTERFACE_UART_MODE_24B2I8_0U25_50U, - .uart_interface_func = LEDS_INTERFACE_UART_FUNC(uart_mode_24B2I8, leds_protocol_ws2811_uart_out), + .uart_interface_func = LEDS_INTERFACE_UART_FUNC(uart_mode_24B2I8, leds_protocol_ws2811_uart_rgb_out), +#endif + .parameter_type = LEDS_PARAMETER_NONE, + .power_mode = LEDS_POWER_RGB, +}; + +struct leds_protocol_type leds_protocol_ws2811_grb = { +#if CONFIG_LEDS_I2S_ENABLED + .i2s_interface_mode = LEDS_INTERFACE_I2S_MODE_24BIT_1U250_4X4_80UL, + .i2s_interface_func = LEDS_INTERFACE_I2S_FUNC(i2s_mode_24bit_4x4, leds_protocol_ws2811_i2s_grb_out), #endif .parameter_type = LEDS_PARAMETER_NONE, .power_mode = LEDS_POWER_RGB, diff --git a/components/leds/protocols/ws2811.h b/components/leds/protocols/ws2811.h index d558165c..19f026d1 100644 --- a/components/leds/protocols/ws2811.h +++ b/components/leds/protocols/ws2811.h @@ -3,16 +3,18 @@ #include #include "../protocol.h" -extern struct leds_protocol_type leds_protocol_ws2811; +extern struct leds_protocol_type leds_protocol_ws2811_rgb; +extern struct leds_protocol_type leds_protocol_ws2811_grb; #if CONFIG_LEDS_I2S_ENABLED #include "../interfaces/i2s.h" - void leds_protocol_ws2811_i2s_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit); + void leds_protocol_ws2811_i2s_rgb_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit); + void leds_protocol_ws2811_i2s_grb_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit); #endif #if CONFIG_LEDS_UART_ENABLED #include "../interfaces/uart.h" - void leds_protocol_ws2811_uart_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit); + void leds_protocol_ws2811_uart_rgb_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit); #endif diff --git a/components/leds/protocols/ws2811_i2s.c b/components/leds/protocols/ws2811_i2s.c index fe5add8c..0fc15cce 100644 --- a/components/leds/protocols/ws2811_i2s.c +++ b/components/leds/protocols/ws2811_i2s.c @@ -37,7 +37,7 @@ [0b1111] = WS2811_LUT(0b1111), }; - void leds_protocol_ws2811_i2s_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) + void leds_protocol_ws2811_i2s_rgb_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) { union leds_pixel_rgb pixel = leds_pixel_rgb(pixels[index], index, limit); @@ -50,4 +50,17 @@ buf[5] = ws2811_lut[(pixel._rgb >> 0) & 0xf]; } + void leds_protocol_ws2811_i2s_grb_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) + { + union leds_pixel_grb pixel = leds_pixel_grb(pixels[index], index, limit); + + // 16-bit little-endian + buf[0] = ws2811_lut[(pixel._grb >> 20) & 0xf]; + buf[1] = ws2811_lut[(pixel._grb >> 16) & 0xf]; + buf[2] = ws2811_lut[(pixel._grb >> 12) & 0xf]; + buf[3] = ws2811_lut[(pixel._grb >> 8) & 0xf]; + buf[4] = ws2811_lut[(pixel._grb >> 4) & 0xf]; + buf[5] = ws2811_lut[(pixel._grb >> 0) & 0xf]; + } + #endif diff --git a/components/leds/protocols/ws2811_uart.c b/components/leds/protocols/ws2811_uart.c index ef1fcc34..42f5108b 100644 --- a/components/leds/protocols/ws2811_uart.c +++ b/components/leds/protocols/ws2811_uart.c @@ -62,7 +62,7 @@ [0b1111] = WS2811_LUT(0b1111), }; - void leds_protocol_ws2811_uart_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) + void leds_protocol_ws2811_uart_rgb_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) { union leds_pixel_rgb pixel = leds_pixel_rgb(pixels[index], index, limit); diff --git a/components/leds/protocols/ws2812b.c b/components/leds/protocols/ws2812b.c index 8d1f2cf5..43bf2fbc 100644 --- a/components/leds/protocols/ws2812b.c +++ b/components/leds/protocols/ws2812b.c @@ -3,14 +3,23 @@ #include "../interfaces/i2s.h" #include "../interfaces/uart.h" -struct leds_protocol_type leds_protocol_ws2812b = { +struct leds_protocol_type leds_protocol_ws2812b_grb = { #if CONFIG_LEDS_I2S_ENABLED .i2s_interface_mode = LEDS_INTERFACE_I2S_MODE_24BIT_1U250_4X4_80UL, - .i2s_interface_func = LEDS_INTERFACE_I2S_FUNC(i2s_mode_24bit_4x4, leds_protocol_ws2812b_i2s_out), + .i2s_interface_func = LEDS_INTERFACE_I2S_FUNC(i2s_mode_24bit_4x4, leds_protocol_ws2812b_i2s_grb_out), #endif #if CONFIG_LEDS_UART_ENABLED .uart_interface_mode = LEDS_INTERFACE_UART_MODE_24B3I7_0U4_80U, - .uart_interface_func = LEDS_INTERFACE_UART_FUNC(uart_mode_24B3I7, leds_protocol_ws2812b_uart_out), + .uart_interface_func = LEDS_INTERFACE_UART_FUNC(uart_mode_24B3I7, leds_protocol_ws2812b_uart_grb_out), +#endif + .parameter_type = LEDS_PARAMETER_NONE, + .power_mode = LEDS_POWER_RGB, +}; + +struct leds_protocol_type leds_protocol_ws2812b_rgb = { +#if CONFIG_LEDS_I2S_ENABLED + .i2s_interface_mode = LEDS_INTERFACE_I2S_MODE_24BIT_1U250_4X4_80UL, + .i2s_interface_func = LEDS_INTERFACE_I2S_FUNC(i2s_mode_24bit_4x4, leds_protocol_ws2812b_i2s_rgb_out), #endif .parameter_type = LEDS_PARAMETER_NONE, .power_mode = LEDS_POWER_RGB, diff --git a/components/leds/protocols/ws2812b.h b/components/leds/protocols/ws2812b.h index c5759ee6..df6eba01 100644 --- a/components/leds/protocols/ws2812b.h +++ b/components/leds/protocols/ws2812b.h @@ -3,16 +3,18 @@ #include #include "../protocol.h" -extern struct leds_protocol_type leds_protocol_ws2812b; +extern struct leds_protocol_type leds_protocol_ws2812b_grb; +extern struct leds_protocol_type leds_protocol_ws2812b_rgb; #if CONFIG_LEDS_I2S_ENABLED #include "../interfaces/i2s.h" - void leds_protocol_ws2812b_i2s_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit); + void leds_protocol_ws2812b_i2s_grb_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit); + void leds_protocol_ws2812b_i2s_rgb_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit); #endif #if CONFIG_LEDS_UART_ENABLED #include "../interfaces/uart.h" - void leds_protocol_ws2812b_uart_out(uint16_t buf[4], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit); + void leds_protocol_ws2812b_uart_grb_out(uint16_t buf[4], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit); #endif diff --git a/components/leds/protocols/ws2812b_i2s.c b/components/leds/protocols/ws2812b_i2s.c index 9a90546c..83d5c39b 100644 --- a/components/leds/protocols/ws2812b_i2s.c +++ b/components/leds/protocols/ws2812b_i2s.c @@ -37,7 +37,7 @@ [0b1111] = WS2812B_LUT(0b1111), }; - void leds_protocol_ws2812b_i2s_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) + void leds_protocol_ws2812b_i2s_grb_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) { union leds_pixel_grb pixel = leds_pixel_grb(pixels[index], index, limit); @@ -49,4 +49,17 @@ buf[4] = ws2812b_lut[(pixel._grb >> 4) & 0xf]; buf[5] = ws2812b_lut[(pixel._grb >> 0) & 0xf]; } + + void leds_protocol_ws2812b_i2s_rgb_out(uint16_t buf[6], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) + { + union leds_pixel_rgb pixel = leds_pixel_rgb(pixels[index], index, limit); + + // 16-bit little-endian + buf[0] = ws2812b_lut[(pixel._rgb >> 20) & 0xf]; + buf[1] = ws2812b_lut[(pixel._rgb >> 16) & 0xf]; + buf[2] = ws2812b_lut[(pixel._rgb >> 12) & 0xf]; + buf[3] = ws2812b_lut[(pixel._rgb >> 8) & 0xf]; + buf[4] = ws2812b_lut[(pixel._rgb >> 4) & 0xf]; + buf[5] = ws2812b_lut[(pixel._rgb >> 0) & 0xf]; + } #endif diff --git a/components/leds/protocols/ws2812b_uart.c b/components/leds/protocols/ws2812b_uart.c index c19c5667..5ee39093 100644 --- a/components/leds/protocols/ws2812b_uart.c +++ b/components/leds/protocols/ws2812b_uart.c @@ -115,7 +115,7 @@ [0b111111] = WS2812B_LUT(0b111111), }; - void leds_protocol_ws2812b_uart_out(uint16_t buf[4], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) + void leds_protocol_ws2812b_uart_grb_out(uint16_t buf[4], const struct leds_color *pixels, unsigned index, const struct leds_limit *limit) { union leds_pixel_grb pixel = leds_pixel_grb(pixels[index], index, limit); diff --git a/main/leds_config.c b/main/leds_config.c index 595e25c2..afa120c4 100644 --- a/main/leds_config.c +++ b/main/leds_config.c @@ -33,9 +33,11 @@ const struct config_enum leds_protocol_enum[] = { { "NONE", .value = LEDS_PROTOCOL_NONE }, { "APA102", .value = LEDS_PROTOCOL_APA102 }, { "P9813", .value = LEDS_PROTOCOL_P9813 }, - { "WS2812B", .value = LEDS_PROTOCOL_WS2812B }, + { "WS2812B_GRB", .value = LEDS_PROTOCOL_WS2812B_GRB, .alias = "WS2812B" }, + { "WS2812B_RGB", .value = LEDS_PROTOCOL_WS2812B_RGB }, { "SK6812_GRBW", .value = LEDS_PROTOCOL_SK6812_GRBW }, - { "WS2811", .value = LEDS_PROTOCOL_WS2811 }, + { "WS2811_RGB", .value = LEDS_PROTOCOL_WS2811_RGB, .alias = "WS2811" }, + { "WS2811_GRB", .value = LEDS_PROTOCOL_WS2811_GRB }, { "SK9822", .value = LEDS_PROTOCOL_SK9822 }, { "SM16703", .value = LEDS_PROTOCOL_SM16703 }, {}