jgarff / rpi_ws281x

Userspace Raspberry Pi PWM library for WS281X LEDs
BSD 2-Clause "Simplified" License
1.76k stars 615 forks source link

[FEATURE REQUEST] Custom color order for SK6812 compatible strips #540

Open pawelsky opened 1 month ago

pawelsky commented 1 month ago

I recently came across a WS2814/SK6812 compatible strip with (unusual?) WRGB color order, which I unfortunately cannot configure properly to use with this great library. The closest I can get is SK6812_STRIP_BRGW but the Blue and White are swapped.

The problem I'm facing is that currently the library assumes that W is always last, and and detects presence of W by checking only the highest nibble of the strip type

// If our shift mask includes the highest nibble, then we have 4 LEDs, RBGW.
if (channel->strip_type & SK6812_SHIFT_WMASK)
{
    array_size = 4;
}

where SK6812_SHIFT_WMASK is defined as

#define SK6812_SHIFT_WMASK 0xf0000000

The way I've temporarily solved it for myself is to check the highest bit of each byte of the strip type with the mask defined as follows:

#define SK6812_SHIFT_WMASK 0x80808080

and modified the strip types to the highest bit of the W byte enabled here

// 4 color R, G, B and W ordering
#define SK6812_STRIP_RGBW                        0x98100800
#define SK6812_STRIP_RBGW                        0x98100008
#define SK6812_STRIP_GRBW                        0x98081000
#define SK6812_STRIP_GBRW                        0x98080010
#define SK6812_STRIP_BRGW                        0x98001008
#define SK6812_STRIP_BGRW                        0x98000810

In addition to that I've modified setting the color shift values here and here to

channel->wshift = (channel->strip_type >> 24) & 0x7f;
channel->rshift = (channel->strip_type >> 16) & 0x7f;
channel->gshift = (channel->strip_type >> 8)  & 0x7f;
channel->bshift = (channel->strip_type >> 0)  & 0x7f;

Do you think such modification could be added to the library?

P.S. Not sure how popular my type of the strip is, but just in case you would find it worth adding it, here is the strip type #define for it

#define SK6812_STRIP_WRGB 0x00981008