fix: prevent RMT peripheral drop on V4, log WS2812 errors

The Rmt struct was being dropped after extracting channel0, which
likely disabled the RMT peripheral. Use ManuallyDrop to keep it alive.
Also log WS2812 transmit errors instead of silently discarding them.
This commit is contained in:
swaits committed 2026-04-07 11:48:34 -06:00
1 parent 6558350aee
commit 239e72d0a8
2 files changed
+15 -6

No files matched your search

+12 -5
View File
@@ -77,11 +77,18 @@ impl LoRaBoard for Board {
let i2c = mcu::init_i2c(p.I2C0, p.GPIO17, p.GPIO18);
let display = Some(DisplayParts { i2c });
// WS2812B RGB LED on GPIO38 via RMT channel 0
let rmt = Rmt::new(p.RMT, Rate::from_mhz(80))
.expect("RMT init")
.into_async();
let led_channel = rmt.channel0
// WS2812B RGB LED on GPIO38 via RMT channel 0.
// Wrap in ManuallyDrop so the Rmt peripheral isn't disabled when
// the struct is dropped after we take channel0.
let rmt = core::mem::ManuallyDrop::new(
Rmt::new(p.RMT, Rate::from_mhz(80))
.expect("RMT init")
.into_async(),
);
// SAFETY: we're reading channel0 out of the ManuallyDrop wrapper.
// The Rmt won't be dropped, so the peripheral stays enabled.
let channel0 = unsafe { core::ptr::read(&raw const rmt.channel0) };
let led_channel = channel0
.configure_tx(
p.GPIO38,
TxChannelConfig::default()
+3 -1
View File
@@ -43,6 +43,8 @@ impl Ws2812 {
impl RgbLed for Ws2812 {
async fn set_rgb(&mut self, r: u8, g: u8, b: u8) {
let data = Self::encode(r, g, b);
let _ = self.channel.transmit(&data).await;
if let Err(e) = self.channel.transmit(&data).await {
defmt::warn!("WS2812 transmit error: {}", e);
}
}
}