ws2812: add PIO support for RP2040/RP2350

Integrate PIO support directly into the existing Device.
NewWS2812() now uses PIO for hardware-timed control
on RP2040/RP2350 and falls back to bit-banging on other platforms.

No changes to the exported API surface.
This commit is contained in:
Carlos Henrique Guardão Gandarez
2026-03-31 19:26:58 -03:00
committed by Ron Evans
parent a514169c37
commit 4071028e85
5 changed files with 53 additions and 9 deletions
+1 -2
View File
@@ -1,17 +1,16 @@
module tinygo.org/x/drivers
go 1.22.1
toolchain go1.23.1
require (
github.com/eclipse/paho.mqtt.golang v1.2.0
github.com/frankban/quicktest v1.10.2
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/orsinium-labs/tinymath v1.1.0
github.com/soypat/natiu-mqtt v0.5.1
github.com/tinygo-org/pio v0.3.0
golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d
golang.org/x/net v0.33.0
tinygo.org/x/tinyfont v0.3.0
+2
View File
@@ -17,6 +17,8 @@ github.com/orsinium-labs/tinymath v1.1.0 h1:KomdsyLHB7vE3f1nRAJF2dyf1m/gnM2HxfTe
github.com/orsinium-labs/tinymath v1.1.0/go.mod h1:WPXX6ei3KSXG7JfA03a+ekCYaY9SWN4I+JRl2p6ck+A=
github.com/soypat/natiu-mqtt v0.5.1 h1:rwaDmlvjzD2+3MCOjMZc4QEkDkNwDzbct2TJbpz+TPc=
github.com/soypat/natiu-mqtt v0.5.1/go.mod h1:xEta+cwop9izVCW7xOx2W+ct9PRMqr0gNVkvBPnQTc4=
github.com/tinygo-org/pio v0.3.0 h1:opEnOtw58KGB4RJD3/n/Rd0/djYGX3DeJiXLI6y/yDI=
github.com/tinygo-org/pio v0.3.0/go.mod h1:wf6c6lKZp+pQOzKKcpzchmRuhiMc27ABRuo7KVnaMFU=
github.com/valyala/fastjson v1.6.3/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d h1:0olWaB5pg3+oychR51GUVCEsGkeCU/2JxjBgIo4f3M0=
golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
+7 -7
View File
@@ -1,4 +1,7 @@
// Package ws2812 implements a driver for WS2812 and SK6812 RGB LED strips.
//
// On most platforms NewWS2812 uses bit-banging.
// On RP2040/RP2350 it uses PIO for hardware-timed control.
package ws2812 // import "tinygo.org/x/drivers/ws2812"
//go:generate go run gen-ws2812.go -arch=cortexm 16 48 64 120 125 150 168 200
@@ -24,14 +27,11 @@ func New(pin machine.Pin) Device {
return NewWS2812(pin)
}
// New returns a new WS2812(RGB) driver.
// It does not touch the pin object: you have
// to configure it as an output pin before calling New.
// NewWS2812 returns a new WS2812(RGB) driver.
// On RP2040/RP2350, it uses PIO for hardware-timed control.
// On other platforms, you must configure the pin as output before calling this.
func NewWS2812(pin machine.Pin) Device {
return Device{
Pin: pin,
writeColorFunc: writeColorsRGB,
}
return newWS2812Device(pin)
}
// New returns a new SK6812(RGBA) driver.
+10
View File
@@ -0,0 +1,10 @@
//go:build !rp2040 && !rp2350
package ws2812
import "machine"
// newWS2812Device creates a WS2812 device using the bit-bang driver.
func newWS2812Device(pin machine.Pin) Device {
return Device{Pin: pin, writeColorFunc: writeColorsRGB}
}
+33
View File
@@ -0,0 +1,33 @@
//go:build rp2040 || rp2350
package ws2812
import (
"image/color"
"machine"
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, writeColorFunc: writeColorsRGB}
}
ws, err := piolib.NewWS2812B(sm, pin)
if err != nil {
return Device{Pin: pin, writeColorFunc: writeColorsRGB}
}
return Device{
Pin: pin,
writeColorFunc: func(_ Device, buf []color.RGBA) error {
for _, c := range buf {
ws.PutRGB(c.R, c.G, c.B)
}
return nil
},
}
}