Per the Wio Tracker L1 schematic, it has a green LED on P1.01. Moved SimpleLed from driver/ to board layer (esp32s3.rs and wio_tracker_l1.rs) since the impl needs HAL-specific Output types. Removed driver/simple_led.rs — each board layer defines its own. RAK WisBlock remains LedDriver=() (no user LED on the core module).
113 lines
4.3 KiB
Rust
113 lines
4.3 KiB
Rust
//! Shared types and peripheral wiring for ESP32-S3 boards.
|
|
//!
|
|
//! Delegates MCU-level init to `hal::esp32s3` and defines peripheral-level
|
|
//! types (RadioDriver, display) used by ESP32-S3 board files.
|
|
//! Each board defines its own comm types (UsbParts/UartParts) directly.
|
|
|
|
use embassy_embedded_hal::shared_bus::asynch::spi::SpiDevice;
|
|
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
|
|
use embassy_time::Delay;
|
|
use esp_hal::gpio::{Input, InputConfig, Level, Output, OutputConfig, Pull};
|
|
|
|
use lora_phy::iv::GenericSx126xInterfaceVariant;
|
|
use lora_phy::sx126x::{self, Sx1262, Sx126x};
|
|
|
|
use crate::hal::esp32s3 as mcu;
|
|
|
|
// ── Re-export MCU types ─────────────────────────────────────────────
|
|
|
|
pub use mcu::{I2cBus as DisplayI2c, SpiBus};
|
|
|
|
// ── LED driver ──────────────────────────────────────────────────────
|
|
|
|
pub struct SimpleLed(pub Output<'static>);
|
|
|
|
impl super::traits::RgbLed for SimpleLed {
|
|
async fn set_rgb(&mut self, r: u8, g: u8, b: u8) {
|
|
if r > 0 || g > 0 || b > 0 {
|
|
self.0.set_high();
|
|
} else {
|
|
self.0.set_low();
|
|
}
|
|
}
|
|
}
|
|
|
|
// ── Concrete peripheral types ───────────────────────────────────────
|
|
|
|
type Nss = Output<'static>;
|
|
type Iv = GenericSx126xInterfaceVariant<Output<'static>, Input<'static>>;
|
|
type RadioSpiDevice = SpiDevice<'static, NoopRawMutex, SpiBus, Nss>;
|
|
pub type RadioDriver = Sx126x<RadioSpiDevice, Iv, Sx1262>;
|
|
|
|
// ── Peripheral bundles ──────────────────────────────────────────────
|
|
|
|
pub struct RadioParts {
|
|
pub driver: RadioDriver,
|
|
pub delay: Delay,
|
|
}
|
|
|
|
pub struct DisplayParts {
|
|
pub i2c: DisplayI2c,
|
|
}
|
|
|
|
// ── Display driver ──────────────────────────────────────────────────
|
|
|
|
pub type DisplayDriver = ssd1306::Ssd1306Async<
|
|
ssd1306::prelude::I2CInterface<DisplayI2c>,
|
|
ssd1306::size::DisplaySize128x64,
|
|
ssd1306::mode::BufferedGraphicsModeAsync<ssd1306::size::DisplaySize128x64>,
|
|
>;
|
|
|
|
/// Construct and initialize an SSD1306 display from raw I2C.
|
|
pub async fn create_display(i2c: DisplayI2c) -> Option<DisplayDriver> {
|
|
use ssd1306::mode::DisplayConfigAsync;
|
|
use ssd1306::prelude::{Brightness, DisplayRotation};
|
|
use ssd1306::size::DisplaySize128x64;
|
|
use ssd1306::{I2CDisplayInterface, Ssd1306Async};
|
|
|
|
let interface = I2CDisplayInterface::new(i2c);
|
|
let mut display = Ssd1306Async::new(interface, DisplaySize128x64, DisplayRotation::Rotate0)
|
|
.into_buffered_graphics_mode();
|
|
|
|
embassy_time::Timer::after_millis(100).await;
|
|
if display.init().await.is_err() {
|
|
defmt::error!("SSD1306 display init failed");
|
|
return None;
|
|
}
|
|
let _ = display.set_brightness(Brightness::BRIGHTEST).await;
|
|
Some(display)
|
|
}
|
|
|
|
// ── Shared peripheral init helpers ──────────────────────────────────
|
|
|
|
/// Construct SX1262 radio from an initialized SPI bus.
|
|
pub fn init_radio(
|
|
spi_bus: &'static embassy_sync::mutex::Mutex<NoopRawMutex, SpiBus>,
|
|
nss_pin: esp_hal::peripherals::GPIO8<'static>,
|
|
reset_pin: esp_hal::peripherals::GPIO12<'static>,
|
|
dio1_pin: esp_hal::peripherals::GPIO14<'static>,
|
|
busy_pin: esp_hal::peripherals::GPIO13<'static>,
|
|
) -> RadioParts {
|
|
let nss = Output::new(nss_pin, Level::High, OutputConfig::default());
|
|
let spi_device = SpiDevice::new(spi_bus, nss);
|
|
|
|
let reset = Output::new(reset_pin, Level::High, OutputConfig::default());
|
|
let dio1 = Input::new(dio1_pin, InputConfig::default().with_pull(Pull::Down));
|
|
let busy = Input::new(busy_pin, InputConfig::default().with_pull(Pull::Down));
|
|
|
|
let iv = GenericSx126xInterfaceVariant::new(reset, dio1, busy, None, None)
|
|
.expect("SX1262 interface init");
|
|
|
|
let sx_config = sx126x::Config {
|
|
chip: Sx1262,
|
|
tcxo_ctrl: Some(sx126x::TcxoCtrlVoltage::Ctrl1V8),
|
|
use_dcdc: true,
|
|
rx_boost: false,
|
|
};
|
|
|
|
RadioParts {
|
|
driver: Sx126x::new(spi_device, iv, sx_config),
|
|
delay: Delay,
|
|
}
|
|
}
|