From c76feb620087d86f44f58badd3614cc5015ac75e Mon Sep 17 00:00:00 2001 From: Lorenz Wellmer Date: Fri, 15 Jan 2021 16:55:28 +0100 Subject: [PATCH 1/4] add byte order bgr for ws2812 --- drivers/chibios/ws2812.c | 4 ++++ drivers/chibios/ws2812_pwm.c | 37 ++++++++++++++++++++++++++++++++++++ drivers/chibios/ws2812_spi.c | 4 ++++ quantum/color.h | 9 +++++++++ 4 files changed, 54 insertions(+) diff --git a/drivers/chibios/ws2812.c b/drivers/chibios/ws2812.c index 59ed90374a6c..0d12e2fb79ab 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 3af922c063ce..140120d488de 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 a93342436202..89df2987b548 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 7448168b3ad0..4783f6839c23 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; From cad6286c29ca5d07ca50bb3ab90bacad1ded5b82 Mon Sep 17 00:00:00 2001 From: Lorenz Wellmer Date: Fri, 15 Jan 2021 17:01:54 +0100 Subject: [PATCH 2/4] update docs for driver change --- docs/ws2812_driver.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/ws2812_driver.md b/docs/ws2812_driver.md index da5db01dbde6..f00eb975adc9 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` | some custom keyboard PCBs (MatrixLabs)| ### Bitbang From 281f9a17105cb29db712f69e15f50942d04bcfc8 Mon Sep 17 00:00:00 2001 From: Lorenz Wellmer Date: Fri, 15 Jan 2021 17:44:23 +0100 Subject: [PATCH 3/4] Update ws2812_driver.md --- docs/ws2812_driver.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ws2812_driver.md b/docs/ws2812_driver.md index f00eb975adc9..db10aa2c2180 100644 --- a/docs/ws2812_driver.md +++ b/docs/ws2812_driver.md @@ -37,7 +37,7 @@ In this case, you can change the byte order by defining `WS2812_BYTE_ORDER` as o |-----------------------------------|---------------------------------------| | `WS2812_BYTE_ORDER_GRB` (default) | Most WS2812's, SK6812, SK6805 | | `WS2812_BYTE_ORDER_RGB` | WS2812B-2020 | -| `WS2812_BYTE_ORDER_BGR` | some custom keyboard PCBs (MatrixLabs)| +| `WS2812_BYTE_ORDER_BGR` | TM1812 and similar | ### Bitbang From e53bc6df6b72331dfd3f58fd7e494efc4f27f4b3 Mon Sep 17 00:00:00 2001 From: kb-elmo Date: Fri, 15 Jan 2021 18:16:21 +0100 Subject: [PATCH 4/4] Update docs/ws2812_driver.md Co-authored-by: Ryan --- docs/ws2812_driver.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/ws2812_driver.md b/docs/ws2812_driver.md index db10aa2c2180..cca6827ec8d5 100644 --- a/docs/ws2812_driver.md +++ b/docs/ws2812_driver.md @@ -33,11 +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 | -| `WS2812_BYTE_ORDER_BGR` | TM1812 and similar | +|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