Files
Oliver Walter f2d06278af Replace the plain status LED with a WS2812B on PIO
The boards this targets carry an addressable LED on GPIO16 rather than a
plain LED, so the GPIO25 heartbeat had nothing to drive. Green means
running, blue flashes on each measurement, red means the sensor is
failing, with the most urgent condition winning. A healthy node reads as
dim green with a blue pip once a second, so a stalled or failing one is
obvious with no serial port attached.

Driven from PIO directly rather than via ws2812-pio, whose current
release pins rp2040-hal 0.11 against this project's 0.12. Those are
semver incompatible: cargo would build both HALs and the driver would not
accept our PIO, state machine or pin types. The alternative was pinning
the whole project back a HAL version, for four instructions of PIO.

Generating the waveform in the state machine matters beyond convenience.
The bus tasks preempt the LED task freely, and a CPU-timed WS2812 would
glitch the moment a frame arrived mid-update. The >50 us latch gap needs
no explicit delay either, since repaints are 25 ms apart.

Byte order is a named constant rather than two transposed shifts, because
it is a property of the part fitted and not of the protocol: many parts
sold as WS2812B, along with the WS2811 and SK6812 families, want red
first. These do. The unused ChannelOrder variant stays so the choice, and
the fix if a board differs, is legible.

The task derives everything from existing shared state — the reading's
own timestamp already says when the last measurement landed — so nothing
is published purely to drive an LED.

Colours confirmed on hardware after correcting the channel order; bus
suite still 15/15 and sensor counters clean, so PIO0 disturbs nothing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 21:26:14 +02:00

50 lines
1.6 KiB
TOML

[package]
name = "wiredsensor-fw"
description = "RP2040 firmware for an RS485 temperature/humidity slave with an SHT31"
version.workspace = true
edition.workspace = true
license.workspace = true
[[bin]]
name = "wiredsensor-fw"
test = false
bench = false
[dependencies]
wiredsensor-core = { workspace = true, features = ["defmt"] }
# Concurrency framework. `thumbv6-backend` selects the Cortex-M0+ critical
# section and priority implementation.
rtic = { version = "2.3", features = ["thumbv6-backend"] }
rtic-monotonics = { version = "2.2", features = ["rp2040"] }
rp2040-hal = { version = "0.12", features = ["rt", "critical-section-impl"] }
rp2040-boot2 = "0.3"
cortex-m = "0.7"
cortex-m-rt = "0.7"
# Cortex-M0+ has no atomic compare-exchange instruction, so the polyfill has to
# be told to emulate one with a critical section. RTIC's executor needs CAS, and
# without this the build fails with a bare "requires atomic CAS" error.
portable-atomic = { version = "1", features = ["critical-section"] }
embedded-hal = "1.0"
fugit = "0.3"
# WS2812 status indicator. Version must track rp2040-hal's own `pio` dependency
# so the assembled program type matches what its PIO driver accepts. The
# assembler proc macro comes along with it, so pio-proc needs no direct entry.
pio = "0.3"
defmt = { workspace = true }
defmt-rtt = "1.0"
panic-probe = { version = "1.0", features = ["print-defmt"] }
# USB CDC diagnostics. Lets the node be verified over a plain USB cable with no
# SWD probe attached. The usb-device version must track rp2040-hal's own so the
# UsbBus trait implementations line up.
usb-device = "0.3"
usbd-serial = "0.2"
heapless = "0.8"