From 3d70766327422bcd918b6940298f7557ab10d248 Mon Sep 17 00:00:00 2001 From: kb-elmo Date: Fri, 15 Jan 2021 22:42:30 +0100 Subject: [PATCH] Add BGR byte order for WS2812 drivers (#11562) * add byte order bgr for ws2812 * update docs for driver change * Update ws2812_driver.md * Update docs/ws2812_driver.md Co-authored-by: Ryan Co-authored-by: Ryan --- docs/ws2812_driver.md | 9 +++++---- drivers/chibios/ws2812.c | 4 ++++ drivers/chibios/ws2812_pwm.c | 37 ++++++++++++++++++++++++++++++++++++ drivers/chibios/ws2812_spi.c | 4 ++++ quantum/color.h | 9 +++++++++ 5 files changed, 59 insertions(+), 4 deletions(-) diff --git a/docs/ws2812_driver.md b/docs/ws2812_driver.md index da5db01dbde6f023c467946199e38432b4daa797..cca6827ec8d590a2ba0e8f4bc11c6073b7812756 100644 --- a/docs/ws2812_driver.md +++ b/docs/ws2812_driver.md @@ -33,10 +33,11 @@ The default setting is 280 µs, which should work for most cases, but this can b Some variants of the WS2812 may have their color components in a different physical or logical order. For example, the WS2812B-2020 has physically swapped red and green LEDs, which causes the wrong color to be displayed, because the default order of the bytes sent over the wire is defined as GRB. In this case, you can change the byte order by defining `WS2812_BYTE_ORDER` as one of the following values: -| Byte order | Known devices | -|-----------------------------------|-------------------------------| -| `WS2812_BYTE_ORDER_GRB` (default) | Most WS2812's, SK6812, SK6805 | -| `WS2812_BYTE_ORDER_RGB` | WS2812B-2020 | +|Byte order |Known devices | +|---------------------------------|-----------------------------| +|`WS2812_BYTE_ORDER_GRB` (default)|Most WS2812's, SK6812, SK6805| +|`WS2812_BYTE_ORDER_RGB` |WS2812B-2020 | +|`WS2812_BYTE_ORDER_BGR` |TM1812 | ### Bitbang diff --git a/drivers/chibios/ws2812.c b/drivers/chibios/ws2812.c index 59ed90374a6c9f66fce3422fd59f1bbbdfc2cee0..0d12e2fb79aba83075ebd4d1dcf0328731151f33 100644 --- a/drivers/chibios/ws2812.c +++ b/drivers/chibios/ws2812.c @@ -97,6 +97,10 @@ void ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) { sendByte(ledarray[i].r); sendByte(ledarray[i].g); sendByte(ledarray[i].b); +#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR) + sendByte(ledarray[i].b); + sendByte(ledarray[i].g); + sendByte(ledarray[i].r); #endif #ifdef RGBW diff --git a/drivers/chibios/ws2812_pwm.c b/drivers/chibios/ws2812_pwm.c index 3af922c063ce9705d72aae7f608ba8ae60d67daa..140120d488de5981de145192ece400696eb82efd 100644 --- a/drivers/chibios/ws2812_pwm.c +++ b/drivers/chibios/ws2812_pwm.c @@ -180,6 +180,43 @@ * @return The bit index */ # define WS2812_BLUE_BIT(led, bit) WS2812_BIT((led), 2, (bit)) + +#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR) +/** + * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given red bit + * + * @note The red byte is the middle byte in the color packet + * + * @param[in] led: The led index [0, @ref RGBLED_NUM) + * @param[in] bit: The bit number [0, 7] + * + * @return The bit index + */ +# define WS2812_RED_BIT(led, bit) WS2812_BIT((led), 2, (bit)) + +/** + * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given green bit + * + * @note The red byte is the first byte in the color packet + * + * @param[in] led: The led index [0, @ref RGBLED_NUM) + * @param[in] bit: The bit number [0, 7] + * + * @return The bit index + */ +# define WS2812_GREEN_BIT(led, bit) WS2812_BIT((led), 1, (bit)) + +/** + * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given blue bit + * + * @note The red byte is the last byte in the color packet + * + * @param[in] led: The led index [0, @ref RGBLED_NUM) + * @param[in] bit: The bit index [0, 7] + * + * @return The bit index + */ +# define WS2812_BLUE_BIT(led, bit) WS2812_BIT((led), 0, (bit)) #endif /* --- PRIVATE VARIABLES ---------------------------------------------------- */ diff --git a/drivers/chibios/ws2812_spi.c b/drivers/chibios/ws2812_spi.c index a9334243620255552ade832a333c10bf17508d8e..89df2987b548a5c1ab50099fdfddf2ad8f70bc73 100644 --- a/drivers/chibios/ws2812_spi.c +++ b/drivers/chibios/ws2812_spi.c @@ -70,6 +70,10 @@ static void set_led_color_rgb(LED_TYPE color, int pos) { for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.r, j); for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.g, j); for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE * 2 + j] = get_protocol_eq(color.b, j); +#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR) + for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.b, j); + for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.g, j); + for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE * 2 + j] = get_protocol_eq(color.r, j); #endif } diff --git a/quantum/color.h b/quantum/color.h index 7448168b3ad024c4f5c76a9ee6cf54b7cf2dc77a..4783f6839c2333e9581cd3be3482bb74cd473bd4 100644 --- a/quantum/color.h +++ b/quantum/color.h @@ -37,6 +37,7 @@ #define WS2812_BYTE_ORDER_RGB 0 #define WS2812_BYTE_ORDER_GRB 1 +#define WS2812_BYTE_ORDER_BGR 2 #ifndef WS2812_BYTE_ORDER # define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_GRB @@ -51,6 +52,10 @@ typedef struct PACKED { uint8_t r; uint8_t g; uint8_t b; +#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR) + uint8_t b; + uint8_t g; + uint8_t r; #endif } cRGB; @@ -66,6 +71,10 @@ typedef struct PACKED { uint8_t r; uint8_t g; uint8_t b; +#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR) + uint8_t b; + uint8_t g; + uint8_t r; #endif uint8_t w; } cRGBW;