Skip to content

Commit

Permalink
add definition WS2812_BYTE_ORDER to fix RGB LED issues (qmk#10184)
Browse files Browse the repository at this point in the history
* add define for WS2812B-2020 to fix RGB issues

* update driver doc

* add WS2812_BYTE_ORDER definition to correct RGB byte issues

* add definition variable thing

* update per PR request

* update per PR reqs

* update per PR request

* inital changes

* move defines to color.h and add rgbw incase

* Update docs/ws2812_driver.md

Co-authored-by: Ryan <fauxpark@gmail.com>

Co-authored-by: hineybush <hineybushkeyboards@gmail.com>
Co-authored-by: Xelus22 <preyas22@gmail.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
  • Loading branch information
4 people authored and drashna committed Jan 13, 2021
1 parent dc57b14 commit 99d80b2
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 4 deletions.
7 changes: 7 additions & 0 deletions drivers/chibios/ws2812.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,16 @@ void ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) {

for (uint8_t i = 0; i < leds; i++) {
// WS2812 protocol dictates grb order
#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
sendByte(ledarray[i].g);
sendByte(ledarray[i].r);
sendByte(ledarray[i].b);
#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
sendByte(ledarray[i].r);
sendByte(ledarray[i].g);
sendByte(ledarray[i].b);
#endif

#ifdef RGBW
sendByte(ledarray[i].w);
#endif
Expand Down
45 changes: 42 additions & 3 deletions drivers/chibios/ws2812_pwm.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
*/
#define WS2812_BIT(led, byte, bit) (24 * (led) + 8 * (byte) + (7 - (bit)))

#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
/**
* @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given red bit
*
Expand All @@ -117,7 +118,7 @@
*
* @return The bit index
*/
#define WS2812_RED_BIT(led, bit) WS2812_BIT((led), 1, (bit))
# define WS2812_RED_BIT(led, bit) WS2812_BIT((led), 1, (bit))

/**
* @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given green bit
Expand All @@ -129,7 +130,7 @@
*
* @return The bit index
*/
#define WS2812_GREEN_BIT(led, bit) WS2812_BIT((led), 0, (bit))
# define WS2812_GREEN_BIT(led, bit) WS2812_BIT((led), 0, (bit))

/**
* @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given blue bit
Expand All @@ -141,7 +142,45 @@
*
* @return The bit index
*/
#define WS2812_BLUE_BIT(led, bit) WS2812_BIT((led), 2, (bit))
# define WS2812_BLUE_BIT(led, bit) WS2812_BIT((led), 2, (bit))

#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
/**
* @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), 0, (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), 2, (bit))
#endif

/* --- PRIVATE VARIABLES ---------------------------------------------------- */

Expand Down
6 changes: 6 additions & 0 deletions drivers/chibios/ws2812_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,15 @@ static uint8_t get_protocol_eq(uint8_t data, int pos) {
static void set_led_color_rgb(LED_TYPE color, int pos) {
uint8_t* tx_start = &txbuf[PREAMBLE_SIZE];

#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.g, j);
for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.r, 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_RGB)
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);
#endif
}

void ws2812_init(void) {
Expand Down
20 changes: 19 additions & 1 deletion quantum/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,38 @@
# define LED_TYPE RGB
#endif

// WS2812 specific layout
#define WS2812_BYTE_ORDER_RGB 0
#define WS2812_BYTE_ORDER_GRB 1

#ifndef WS2812_BYTE_ORDER
# define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_GRB
#endif

typedef struct PACKED {
#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
uint8_t g;
uint8_t r;
uint8_t b;
#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
uint8_t r;
uint8_t g;
uint8_t b;
#endif
} cRGB;

typedef cRGB RGB;

// WS2812 specific layout
typedef struct PACKED {
#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
uint8_t g;
uint8_t r;
uint8_t b;
#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
uint8_t r;
uint8_t g;
uint8_t b;
#endif
uint8_t w;
} cRGBW;

Expand Down

0 comments on commit 99d80b2

Please sign in to comment.