summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Hinnebusch <joshhinnebusch@gmail.com>2020-12-06 01:15:48 -0500
committerDrashna Jael're <drashna@live.com>2021-01-12 22:46:07 -0800
commit99d80b2acb71cf23e957bad9c25017befa6d8537 (patch)
treec085711123cc82cb5972e4fe4640a66f8b1c9544
parentdc57b14a0a39a0169cb63bd00d5af1228458ca7a (diff)
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--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
4 files changed, 74 insertions, 4 deletions
diff --git a/drivers/chibios/ws2812.c b/drivers/chibios/ws2812.c
index c2bec3fdc9..b5b02fdacd 100644
--- a/drivers/chibios/ws2812.c
+++ b/drivers/chibios/ws2812.c
@@ -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
diff --git a/drivers/chibios/ws2812_pwm.c b/drivers/chibios/ws2812_pwm.c
index bfb44ce4a4..14be0a9edc 100644
--- a/drivers/chibios/ws2812_pwm.c
+++ b/drivers/chibios/ws2812_pwm.c
@@ -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
*
@@ -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
@@ -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
@@ -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 ---------------------------------------------------- */
diff --git a/drivers/chibios/ws2812_spi.c b/drivers/chibios/ws2812_spi.c
index 7a1d2f05da..1dec1f5167 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) {
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) {
diff --git a/quantum/color.h b/quantum/color.h
index 44caa552fa..590fc75841 100644
--- a/quantum/color.h
+++ b/quantum/color.h
@@ -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;