refactor: board-owned display init, zero cfg in application code
- Each board now exports DisplayDriver type and create_display() async fn - ESP32-S3 boards share SSD1306 create_display in board/esp32s3.rs - RAK WisBlock has its own SSD1306 create_display (different I2C type) - Wio Tracker has SH1106 create_display (different display IC) - Removed all cfg_if from display.rs — calls board::create_display() - Removed display init retry logic (single attempt, return None on failure) - ZERO board-specific #[cfg(feature)] outside board/, host/mod.rs, and hal/
This commit is contained in:
6 files changed
+78
-47
No files matched your search
@@ -47,6 +47,34 @@ pub struct DisplayParts {
|
|||||||
pub mac: [u8; 6],
|
pub mac: [u8; 6],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── 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 ──────────────────────────────────
|
// ── Shared peripheral init helpers ──────────────────────────────────
|
||||||
|
|
||||||
/// Construct SX1262 radio from an initialized SPI bus.
|
/// Construct SX1262 radio from an initialized SPI bus.
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ use super::traits::LoRaBoard;
|
|||||||
use crate::hal::esp32s3 as mcu;
|
use crate::hal::esp32s3 as mcu;
|
||||||
|
|
||||||
#[allow(unused_imports)] // Re-exported for other modules (display, radio, uart tasks)
|
#[allow(unused_imports)] // Re-exported for other modules (display, radio, uart tasks)
|
||||||
pub use super::esp32s3::{DisplayI2c, DisplayParts, RadioDriver, RadioParts, UartDriver, UartParts};
|
pub use super::esp32s3::{
|
||||||
|
create_display, DisplayDriver, DisplayI2c, DisplayParts, RadioDriver, RadioParts, UartDriver,
|
||||||
|
UartParts,
|
||||||
|
};
|
||||||
|
|
||||||
// ── Board init ──────────────────────────────────────────────────────
|
// ── Board init ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ use super::traits::LoRaBoard;
|
|||||||
use crate::hal::esp32s3 as mcu;
|
use crate::hal::esp32s3 as mcu;
|
||||||
|
|
||||||
#[allow(unused_imports)] // Re-exported for other modules (display, radio, usb tasks)
|
#[allow(unused_imports)] // Re-exported for other modules (display, radio, usb tasks)
|
||||||
pub use super::esp32s3::{DisplayI2c, DisplayParts, RadioDriver, RadioParts, UsbDriver, UsbParts};
|
pub use super::esp32s3::{
|
||||||
|
create_display, DisplayDriver, DisplayI2c, DisplayParts, RadioDriver, RadioParts, UsbDriver,
|
||||||
|
UsbParts,
|
||||||
|
};
|
||||||
|
|
||||||
// ── Board implementation ────────────────────────────────────────────
|
// ── Board implementation ────────────────────────────────────────────
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,31 @@ pub type RadioDriver = Sx126x<RadioSpiDevice, Iv, Sx1262>;
|
|||||||
pub type UsbDriver = mcu::UsbNrfDriver;
|
pub type UsbDriver = mcu::UsbNrfDriver;
|
||||||
pub type DisplayI2c = mcu::I2cBus;
|
pub type DisplayI2c = mcu::I2cBus;
|
||||||
|
|
||||||
|
pub type DisplayDriver = ssd1306::Ssd1306Async<
|
||||||
|
ssd1306::prelude::I2CInterface<DisplayI2c>,
|
||||||
|
ssd1306::size::DisplaySize128x64,
|
||||||
|
ssd1306::mode::BufferedGraphicsModeAsync<ssd1306::size::DisplaySize128x64>,
|
||||||
|
>;
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
// ── Peripheral bundles ──────────────────────────────────────────────
|
// ── Peripheral bundles ──────────────────────────────────────────────
|
||||||
|
|
||||||
pub struct RadioParts {
|
pub struct RadioParts {
|
||||||
|
|||||||
@@ -21,6 +21,20 @@ pub type RadioDriver = Sx126x<RadioSpiDevice, Iv, Sx1262>;
|
|||||||
pub type UsbDriver = mcu::UsbNrfDriver;
|
pub type UsbDriver = mcu::UsbNrfDriver;
|
||||||
pub type DisplayI2c = mcu::I2cBus;
|
pub type DisplayI2c = mcu::I2cBus;
|
||||||
|
|
||||||
|
pub type DisplayDriver = crate::driver::sh1106::Sh1106<DisplayI2c>;
|
||||||
|
|
||||||
|
pub async fn create_display(i2c: DisplayI2c) -> Option<DisplayDriver> {
|
||||||
|
let mut display = crate::driver::sh1106::Sh1106::new(i2c, 0x3D);
|
||||||
|
|
||||||
|
embassy_time::Timer::after_millis(100).await;
|
||||||
|
if display.init().await.is_err() {
|
||||||
|
defmt::error!("SH1106 display init failed");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let _ = display.set_brightness(0xFF).await;
|
||||||
|
Some(display)
|
||||||
|
}
|
||||||
|
|
||||||
// ── Peripheral bundles ──────────────────────────────────────────────
|
// ── Peripheral bundles ──────────────────────────────────────────────
|
||||||
|
|
||||||
pub struct RadioParts {
|
pub struct RadioParts {
|
||||||
|
|||||||
+3
-45
@@ -123,52 +123,10 @@ pub async fn display_task(
|
|||||||
mac: &mac_str,
|
mac: &mac_str,
|
||||||
};
|
};
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
let Some(mut display) = crate::board::create_display(parts.i2c).await else {
|
||||||
if #[cfg(feature = "wio_tracker_l1")] {
|
defmt::error!("display init failed, giving up");
|
||||||
let mut display = crate::driver::sh1106::Sh1106::new(parts.i2c, 0x3D);
|
|
||||||
|
|
||||||
Timer::after_millis(100).await;
|
|
||||||
|
|
||||||
if display.init().await.is_err() {
|
|
||||||
defmt::error!("SH1106 init failed — retrying");
|
|
||||||
Timer::after_millis(500).await;
|
|
||||||
if display.init().await.is_err() {
|
|
||||||
defmt::error!("SH1106 init failed twice, giving up");
|
|
||||||
return;
|
return;
|
||||||
}
|
};
|
||||||
}
|
|
||||||
if display.set_brightness(0xFF).await.is_err() {
|
|
||||||
defmt::warn!("display brightness set failed");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
use ssd1306::mode::DisplayConfigAsync;
|
|
||||||
use ssd1306::prelude::DisplayRotation;
|
|
||||||
use ssd1306::size::DisplaySize128x64;
|
|
||||||
use ssd1306::{I2CDisplayInterface, Ssd1306Async};
|
|
||||||
|
|
||||||
let interface = I2CDisplayInterface::new(parts.i2c);
|
|
||||||
let mut display = Ssd1306Async::new(interface, DisplaySize128x64, DisplayRotation::Rotate0)
|
|
||||||
.into_buffered_graphics_mode();
|
|
||||||
|
|
||||||
Timer::after_millis(100).await;
|
|
||||||
|
|
||||||
if display.init().await.is_err() {
|
|
||||||
defmt::error!("SSD1306 init failed — retrying");
|
|
||||||
Timer::after_millis(500).await;
|
|
||||||
if display.init().await.is_err() {
|
|
||||||
defmt::error!("SSD1306 init failed twice, giving up");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if display
|
|
||||||
.set_brightness(ssd1306::prelude::Brightness::BRIGHTEST)
|
|
||||||
.await
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
defmt::warn!("display brightness set failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut state = DisplayState::new();
|
let mut state = DisplayState::new();
|
||||||
let Some(mut receiver) = status.receiver() else {
|
let Some(mut receiver) = status.receiver() else {
|
||||||
|
|||||||
Reference in new issue
Block a user