forked from mirrors/qmk_firmware
Merge remote-tracking branch 'origin/master' into develop
This commit is contained in:
commit
e199fb6190
5 changed files with 85 additions and 4 deletions
|
@ -28,6 +28,17 @@ The default setting is 280 µs, which should work for most cases, but this can b
|
|||
#define WS2812_TRST_US 80
|
||||
```
|
||||
|
||||
#### Byte Order
|
||||
|
||||
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 |
|
||||
|
||||
|
||||
### Bitbang
|
||||
Default driver, the absence of configuration assumes this driver. To configure it, add this to your rules.mk:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
@ -143,6 +144,44 @@
|
|||
*/
|
||||
# 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 ---------------------------------------------------- */
|
||||
|
||||
static uint32_t ws2812_frame_buffer[WS2812_BIT_N + 1]; /**< Buffer for a frame */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue