Files
drivers/ws2812/ws2812_rp2_pio.go
deadprogram dc6edbb694 ws2812: fix PIO TX FIFO overflow on rp2040/rp2350 dropping LEDs
PutRGB calls TxPut which is non-blocking and silently discards data
when the TX FIFO is full.

Wait for FIFO space before each PutRGB using runtime.Gosched() to
yield cooperatively, matching the pattern used by piolib.WriteRaw.

Signed-off-by: deadprogram <ron@hybridgroup.com>
2026-07-06 20:21:35 +02:00

40 lines
960 B
Go

//go:build rp2040 || rp2350
package ws2812
import (
"image/color"
"machine"
"runtime"
pio "github.com/tinygo-org/pio/rp2-pio"
"github.com/tinygo-org/pio/rp2-pio/piolib"
)
// newWS2812Device creates a WS2812 device using PIO for hardware-timed control.
// If PIO initialization fails, it falls back to the bit-bang driver.
func newWS2812Device(pin machine.Pin) Device {
sm, err := pio.PIO0.ClaimStateMachine()
if err != nil {
return Device{Pin: pin, brightness: 255, writeColorFunc: writeColorsRGB}
}
ws, err := piolib.NewWS2812B(sm, pin)
if err != nil {
return Device{Pin: pin, brightness: 255, writeColorFunc: writeColorsRGB}
}
return Device{
Pin: pin,
brightness: 255,
writeColorFunc: func(_ Device, buf []color.RGBA, brightness uint8) error {
for _, c := range buf {
r, g, b := applyBrightness(c, brightness)
for ws.IsQueueFull() {
runtime.Gosched()
}
ws.PutRGB(r, g, b)
}
return nil
},
}
}