diff --git a/src/board/heltec_v4.rs b/src/board/heltec_v4.rs index d63f71d..cbfd85e 100644 --- a/src/board/heltec_v4.rs +++ b/src/board/heltec_v4.rs @@ -1,11 +1,9 @@ use esp_hal::gpio::{Level, Output, OutputConfig}; -use esp_hal::rmt::{Rmt, TxChannelConfig, TxChannelCreator}; -use esp_hal::time::Rate; use static_cell::StaticCell; use super::esp32s3; use super::traits::{BoardParts, LoRaBoard}; -use crate::driver::ws2812::Ws2812; +use crate::driver::simple_led::SimpleLed; use crate::hal::esp32s3 as mcu; pub use super::esp32s3::{ @@ -14,7 +12,7 @@ pub use super::esp32s3::{ pub type UsbDriver = esp_hal::otg_fs::asynch::Driver<'static>; -pub type LedDriver = Ws2812; +pub type LedDriver = SimpleLed; pub struct UsbParts { pub driver: UsbDriver, @@ -32,7 +30,7 @@ impl LoRaBoard for Board { type CommParts = UsbParts; type DisplayParts = DisplayParts; type DisplayDriver = DisplayDriver; - type LedDriver = Ws2812; + type LedDriver = LedDriver; fn init() -> Self { let p = esp_hal::init(esp_hal::Config::default()); @@ -43,7 +41,7 @@ impl LoRaBoard for Board { mcu::mac_address() } - fn into_parts(self) -> BoardParts { + fn into_parts(self) -> BoardParts { let p = self.p; mcu::start_timer(p.TIMG0); @@ -77,18 +75,9 @@ 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 (blocking, ~31µs per update) - let rmt = Rmt::new(p.RMT, Rate::from_mhz(80)).expect("RMT init"); - let led_channel = rmt - .channel0 - .configure_tx( - p.GPIO38, - TxChannelConfig::default() - .with_clk_divider(1) - .with_idle_output(true), - ) - .expect("RMT TX channel init"); - let led = Some(Ws2812::new(led_channel)); + // Orange LED on GPIO35 + let led_pin = Output::new(p.GPIO35, Level::Low, OutputConfig::default()); + let led = Some(SimpleLed::new(led_pin)); BoardParts { radio, diff --git a/src/driver/mod.rs b/src/driver/mod.rs index 1e7b497..39e3ec1 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -1,8 +1,5 @@ #[cfg(feature = "wio_tracker_l1")] pub mod sh1106; -#[cfg(any(feature = "heltec_v3", feature = "heltec_v3_uart"))] +#[cfg(any(feature = "heltec_v3", feature = "heltec_v3_uart", feature = "heltec_v4"))] pub mod simple_led; - -#[cfg(feature = "heltec_v4")] -pub mod ws2812; diff --git a/src/driver/ws2812.rs b/src/driver/ws2812.rs deleted file mode 100644 index d86e7dc..0000000 --- a/src/driver/ws2812.rs +++ /dev/null @@ -1,64 +0,0 @@ -//! WS2812B single-LED driver using the ESP32-S3 RMT peripheral. -//! -//! Encodes RGB values as GRB PulseCodes and transmits via RMT. -//! At 80 MHz with divider=1, each tick is 12.5 ns. -//! Uses blocking transmit (~31µs per LED update). - -use esp_hal::gpio::Level; -use esp_hal::rmt::{Channel, PulseCode, Tx}; - -use crate::board::RgbLed; - -/// WS2812 0-bit: High 400ns (32 ticks), Low 850ns (68 ticks). -const BIT_0: PulseCode = PulseCode::new(Level::High, 32, Level::Low, 68); - -/// WS2812 1-bit: High 800ns (64 ticks), Low 450ns (36 ticks). -const BIT_1: PulseCode = PulseCode::new(Level::High, 64, Level::Low, 36); - -/// WS2812B single-LED driver over RMT (blocking). -pub struct Ws2812 { - channel: Option>, -} - -impl Ws2812 { - pub fn new(channel: Channel<'static, esp_hal::Blocking, Tx>) -> Self { - Self { - channel: Some(channel), - } - } - - /// Encode 3 bytes (GRB order) + end marker into PulseCodes. - fn encode(r: u8, g: u8, b: u8) -> [PulseCode; 25] { - let mut data = [PulseCode::end_marker(); 25]; - let bytes = [g, r, b]; // WS2812 expects GRB order - let mut idx = 0; - for byte in bytes { - for bit in (0..8).rev() { - data[idx] = if byte & (1 << bit) != 0 { BIT_1 } else { BIT_0 }; - idx += 1; - } - } - data - } -} - -impl RgbLed for Ws2812 { - async fn set_rgb(&mut self, r: u8, g: u8, b: u8) { - let data = Self::encode(r, g, b); - if let Some(ch) = self.channel.take() { - match ch.transmit(&data) { - Ok(tx) => match tx.wait() { - Ok(ch) => self.channel = Some(ch), - Err((e, ch)) => { - defmt::warn!("WS2812 wait error: {}", e); - self.channel = Some(ch); - } - }, - Err(e) => { - defmt::warn!("WS2812 transmit error: {}", e); - // Channel consumed on transmit error — LED is lost - } - } - } - } -}