aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Hinnebusch <joshhinnebusch@gmail.com>2020-12-06 01:15:48 -0500
committerGitHub <noreply@github.com>2020-12-06 17:15:48 +1100
commitc59f87a5d73a2d8a2085663ae329c4d7c75c83e3 (patch)
treeb1778e21ae0dd43261e79cbca5d2779a35b96627
parent08bf9f9e740a741d674585b5920e4c3a107825b9 (diff)
downloadqmk_firmware-c59f87a5d73a2d8a2085663ae329c4d7c75c83e3.tar.gz
qmk_firmware-c59f87a5d73a2d8a2085663ae329c4d7c75c83e3.zip
add definition WS2812_BYTE_ORDER to fix RGB LED issues (#10184)
* 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>
-rw-r--r--docs/ws2812_driver.md11
-rw-r--r--drivers/chibios/ws2812.c7
-rw-r--r--drivers/chibios/ws2812_pwm.c45
-rw-r--r--drivers/chibios/ws2812_spi.c6
-rw-r--r--quantum/color.h20
5 files changed, 85 insertions, 4 deletions
diff --git a/docs/ws2812_driver.md b/docs/ws2812_driver.md
index c1b96329e..da5db01db 100644
--- a/docs/ws2812_driver.md
+++ b/docs/ws2812_driver.md
@@ -28,6 +28,17 @@ The default setting is 280 µs, which should work for most cases, but this can b
28#define WS2812_TRST_US 80 28#define WS2812_TRST_US 80
29``` 29```
30 30
31#### Byte Order
32
33Some 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.
34In this case, you can change the byte order by defining `WS2812_BYTE_ORDER` as one of the following values:
35
36| Byte order | Known devices |
37|-----------------------------------|-------------------------------|
38| `WS2812_BYTE_ORDER_GRB` (default) | Most WS2812's, SK6812, SK6805 |
39| `WS2812_BYTE_ORDER_RGB` | WS2812B-2020 |
40
41
31### Bitbang 42### Bitbang
32Default driver, the absence of configuration assumes this driver. To configure it, add this to your rules.mk: 43Default driver, the absence of configuration assumes this driver. To configure it, add this to your rules.mk:
33 44
diff --git a/drivers/chibios/ws2812.c b/drivers/chibios/ws2812.c
index 0440cac75..504fb4f07 100644
--- a/drivers/chibios/ws2812.c
+++ b/drivers/chibios/ws2812.c
@@ -89,9 +89,16 @@ void ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) {
89 89
90 for (uint8_t i = 0; i < leds; i++) { 90 for (uint8_t i = 0; i < leds; i++) {
91 // WS2812 protocol dictates grb order 91 // WS2812 protocol dictates grb order
92#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
92 sendByte(ledarray[i].g); 93 sendByte(ledarray[i].g);
93 sendByte(ledarray[i].r); 94 sendByte(ledarray[i].r);
94 sendByte(ledarray[i].b); 95 sendByte(ledarray[i].b);
96#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
97 sendByte(ledarray[i].r);
98 sendByte(ledarray[i].g);
99 sendByte(ledarray[i].b);
100#endif
101
95#ifdef RGBW 102#ifdef RGBW
96 sendByte(ledarray[i].w); 103 sendByte(ledarray[i].w);
97#endif 104#endif
diff --git a/drivers/chibios/ws2812_pwm.c b/drivers/chibios/ws2812_pwm.c
index bfb44ce4a..14be0a9ed 100644
--- a/drivers/chibios/ws2812_pwm.c
+++ b/drivers/chibios/ws2812_pwm.c
@@ -107,6 +107,7 @@
107 */ 107 */
108#define WS2812_BIT(led, byte, bit) (24 * (led) + 8 * (byte) + (7 - (bit))) 108#define WS2812_BIT(led, byte, bit) (24 * (led) + 8 * (byte) + (7 - (bit)))
109 109
110#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
110/** 111/**
111 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given red bit 112 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given red bit
112 * 113 *
@@ -117,7 +118,7 @@
117 * 118 *
118 * @return The bit index 119 * @return The bit index
119 */ 120 */
120#define WS2812_RED_BIT(led, bit) WS2812_BIT((led), 1, (bit)) 121# define WS2812_RED_BIT(led, bit) WS2812_BIT((led), 1, (bit))
121 122
122/** 123/**
123 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given green bit 124 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given green bit
@@ -129,7 +130,7 @@
129 * 130 *
130 * @return The bit index 131 * @return The bit index
131 */ 132 */
132#define WS2812_GREEN_BIT(led, bit) WS2812_BIT((led), 0, (bit)) 133# define WS2812_GREEN_BIT(led, bit) WS2812_BIT((led), 0, (bit))
133 134
134/** 135/**
135 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given blue bit 136 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given blue bit
@@ -141,7 +142,45 @@
141 * 142 *
142 * @return The bit index 143 * @return The bit index
143 */ 144 */
144#define WS2812_BLUE_BIT(led, bit) WS2812_BIT((led), 2, (bit)) 145# define WS2812_BLUE_BIT(led, bit) WS2812_BIT((led), 2, (bit))
146
147#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
148/**
149 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given red bit
150 *
151 * @note The red byte is the middle byte in the color packet
152 *
153 * @param[in] led: The led index [0, @ref RGBLED_NUM)
154 * @param[in] bit: The bit number [0, 7]
155 *
156 * @return The bit index
157 */
158# define WS2812_RED_BIT(led, bit) WS2812_BIT((led), 0, (bit))
159
160/**
161 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given green bit
162 *
163 * @note The red byte is the first byte in the color packet
164 *
165 * @param[in] led: The led index [0, @ref RGBLED_NUM)
166 * @param[in] bit: The bit number [0, 7]
167 *
168 * @return The bit index
169 */
170# define WS2812_GREEN_BIT(led, bit) WS2812_BIT((led), 1, (bit))
171
172/**
173 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given blue bit
174 *
175 * @note The red byte is the last byte in the color packet
176 *
177 * @param[in] led: The led index [0, @ref RGBLED_NUM)
178 * @param[in] bit: The bit index [0, 7]
179 *
180 * @return The bit index
181 */
182# define WS2812_BLUE_BIT(led, bit) WS2812_BIT((led), 2, (bit))
183#endif
145 184
146/* --- PRIVATE VARIABLES ---------------------------------------------------- */ 185/* --- PRIVATE VARIABLES ---------------------------------------------------- */
147 186
diff --git a/drivers/chibios/ws2812_spi.c b/drivers/chibios/ws2812_spi.c
index 7a1d2f05d..1dec1f516 100644
--- a/drivers/chibios/ws2812_spi.c
+++ b/drivers/chibios/ws2812_spi.c
@@ -62,9 +62,15 @@ static uint8_t get_protocol_eq(uint8_t data, int pos) {
62static void set_led_color_rgb(LED_TYPE color, int pos) { 62static void set_led_color_rgb(LED_TYPE color, int pos) {
63 uint8_t* tx_start = &txbuf[PREAMBLE_SIZE]; 63 uint8_t* tx_start = &txbuf[PREAMBLE_SIZE];
64 64
65#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
65 for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.g, j); 66 for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.g, j);
66 for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.r, j); 67 for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.r, j);
67 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); 68 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);
69#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
70 for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.r, j);
71 for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.g, j);
72 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);
73#endif
68} 74}
69 75
70void ws2812_init(void) { 76void ws2812_init(void) {
diff --git a/quantum/color.h b/quantum/color.h
index 5c5a0f0eb..f0ee78275 100644
--- a/quantum/color.h
+++ b/quantum/color.h
@@ -36,20 +36,38 @@
36# define LED_TYPE RGB 36# define LED_TYPE RGB
37#endif 37#endif
38 38
39// WS2812 specific layout 39#define WS2812_BYTE_ORDER_RGB 0
40#define WS2812_BYTE_ORDER_GRB 1
41
42#ifndef WS2812_BYTE_ORDER
43# define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_GRB
44#endif
45
40typedef struct PACKED { 46typedef struct PACKED {
47#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
41 uint8_t g; 48 uint8_t g;
42 uint8_t r; 49 uint8_t r;
43 uint8_t b; 50 uint8_t b;
51#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
52 uint8_t r;
53 uint8_t g;
54 uint8_t b;
55#endif
44} cRGB; 56} cRGB;
45 57
46typedef cRGB RGB; 58typedef cRGB RGB;
47 59
48// WS2812 specific layout 60// WS2812 specific layout
49typedef struct PACKED { 61typedef struct PACKED {
62#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
50 uint8_t g; 63 uint8_t g;
51 uint8_t r; 64 uint8_t r;
52 uint8_t b; 65 uint8_t b;
66#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
67 uint8_t r;
68 uint8_t g;
69 uint8_t b;
70#endif
53 uint8_t w; 71 uint8_t w;
54} cRGBW; 72} cRGBW;
55 73