Pull Request #303: fix(hwled): support explicit 32-bit WS2812 transfers

New Pull Request: fix(hwled): support explicit 32-bit WS2812 transfers
virtmedia/BusPirate5-firmwareDangerousPrototypes/BusPirate5-firmware

Summary

Add support for explicit 32-bit WS2812-compatible LED transfers, enabling direct use with RGBW devices such as SK6812 RGBW.

When .32 is specified, LED mode now:

  • configures the PIO autopull threshold for 32 bits,
  • transmits the complete uint32_t value without the existing 8-bit shift.

The existing behavior is preserved for default and explicit .24 transfers.

Examples

[ 0xff0000
[ 0xff0000.24

Both continue to transmit a 24-bit RGB value.

[ 0x01020304.32

Now transmits all four bytes instead of dropping the most significant byte.

Implementation

The WS2812 PIO state machine is reconfigured between 24-bit RGB and 32-bit RGBW operation when the requested transfer width changes. The code waits for the current transfer to finish before reinitializing the state machine.

APA102 and onboard LED handling are unchanged.

Testing

  • Bus Pirate 5 rev10 firmware build with Pico SDK 2.1.1
  • Tested on physical Bus Pirate 5 hardware
  • Verified 24-bit operation remains functional
  • Verified explicit 32-bit RGBW transmission
  • SPSC Queue host tests: 11/11 passed
  • VT100 keys host tests: 81/81 passed

Fixes #302

Created by: virtmedia

Thank you for this update. I am going to add this feature, but I am also going to add it as a command line/menu option.

HiZ> m led -d ws2812 -f rgbw


Mode: LED
LED-(WS2812)> m led -h


options:
  -d, --device <ws2812|apa102|onboard>
  -f, --format [rgb|rgbw]
  -h, --help      Get additional help

LED-(WS2812)> m led -d ws2812


Mode: LED

Not quite there yet, but here is the current prototype.

Comment by: DangerousPrototypes

HiZ> m led -d ws2812 -f rgbw

Love having it parameterized. :two_hearts:

Some feedback that I understand you might not take:

  • -d/--device – change to -t / --type, as it indicates which pixel type
  • -f/--format – Allowing rgbw and rgb is OK, but what this is really doing is changing how many bits are processed by the script by default from each 32-bit value. Maybe make the options: <rgb|rgbw|24bpp|32bpp> to reflect bit per pixel, which happens to be a perfect explanation of what’s changing?
  • For type=APA102, add parameters --data and --clock? (using BPIO pin #s … and restricting to pins that are consecutive, if needed by the .PIO program?)
  • For type=WS2812, add parameter --data, and allow special pin of “Internal” to control internal WS2812 pixels.
  • Use the terms “Pixel” and “LED”; Each pixel typically has 3-4 LEDs embedded in it. As a contributed to FastLED, WLED, and others, the clarity this brings in the long run is (imho) worthwhile.

Comment by: henrygab

Henry beat me to it, but this is my current hang up. RGB isn’t actually giving RGB ordered access to the pixels, it is 24 bits/pixel. 24bpp and 32bpp seem like good choices.

Another route is to allow an arbitrary number of bits per pixel. 1-32?

That’s an interesting idea.

Of course, for WS2812, the protocol is just a stream of all the bits. At the same time, all significant options in market are multiples of one byte. More importantly, the PIO program only supports 24bpp and 32bpp.

It’s important to remember that the “bpp” setting’s only use is to make it easier to send data using the 32-bit chunks that the PIO requires… and then really only for 24bpp, by reformatting the data to fit what the PIO program needs.

Maybe it’d be possible to add 8bpp or 16bpp, but that would also need PIO changes.

For APA102, I am not aware of any devices not covered by either 24bpp or 32bpp.

In conclusion, I think only 24bpp and 32bpp are reasonable and testable at this time.

1 Like