refactor: LoRaBoard trait with full associated types + BoardParts

- LoRaBoard trait now has associated types: RadioParts, CommParts, DisplayParts, DisplayDriver
- into_parts() is on the trait (enforced by compiler, not implicit convention)
- BoardParts<R, C, D> struct replaces tuple return from into_parts()
- mac_address() stays on trait, MAC also in BoardParts for convenience
- Removed mac field from DisplayParts (display task calls Board::mac_address())
- DisplayDriver associated type requires DrawTarget<Color = BinaryColor>
This commit is contained in:
swaits committed 2026-04-07 09:50:50 -06:00
1 parent 7a54c4dff3
commit ecc451affe
8 files changed
+134 -98

No files matched your search

+32 -25
View File
@@ -9,7 +9,7 @@ use embassy_time::Delay;
use lora_phy::iv::GenericSx126xInterfaceVariant;
use lora_phy::sx126x::{self, Sx1262, Sx126x};
use super::traits::LoRaBoard;
use super::traits::{BoardParts, LoRaBoard};
use crate::hal::nrf52840 as mcu;
// ── Concrete peripheral types ───────────────────────────────────────
@@ -27,6 +27,23 @@ pub type DisplayDriver = ssd1306::Ssd1306Async<
ssd1306::mode::BufferedGraphicsModeAsync<ssd1306::size::DisplaySize128x64>,
>;
// ── Peripheral bundles ──────────────────────────────────────────────
pub struct RadioParts {
pub driver: RadioDriver,
pub delay: Delay,
}
pub struct UsbParts {
pub driver: UsbDriver,
}
pub struct DisplayParts {
pub i2c: DisplayI2c,
}
// ── Display init ────────────────────────────────────────────────────
pub async fn create_display(i2c: DisplayI2c) -> Option<DisplayDriver> {
use ssd1306::mode::DisplayConfigAsync;
use ssd1306::prelude::{Brightness, DisplayRotation};
@@ -46,22 +63,6 @@ pub async fn create_display(i2c: DisplayI2c) -> Option<DisplayDriver> {
Some(display)
}
// ── Peripheral bundles ──────────────────────────────────────────────
pub struct RadioParts {
pub driver: RadioDriver,
pub delay: Delay,
}
pub struct UsbParts {
pub driver: UsbDriver,
}
pub struct DisplayParts {
pub i2c: DisplayI2c,
pub mac: [u8; 6],
}
// ── Board init ──────────────────────────────────────────────────────
pub struct Board {
@@ -72,6 +73,11 @@ impl LoRaBoard for Board {
const NAME: &'static str = "RAK WisBlock 4631";
const TX_POWER_RANGE: (i8, i8) = (-9, 22);
type RadioParts = RadioParts;
type CommParts = UsbParts;
type DisplayParts = DisplayParts;
type DisplayDriver = DisplayDriver;
fn init() -> Self {
let p = embassy_nrf::init(Default::default());
Self { p }
@@ -80,10 +86,8 @@ impl LoRaBoard for Board {
fn mac_address() -> [u8; 6] {
mcu::mac_address()
}
}
impl Board {
pub fn into_parts(self) -> (RadioParts, UsbParts, Option<DisplayParts>) {
fn into_parts(self) -> BoardParts<RadioParts, UsbParts, DisplayParts> {
let p = self.p;
// ── SPI bus for SX1262 ──────────────────────────────────
@@ -95,7 +99,6 @@ impl Board {
let nss = Output::new(p.P1_10, Level::High, OutputDrive::Standard);
let spi_device = SpiDevice::new(spi_bus, nss);
// ── SX1262 control pins ─────────────────────────────────
let reset = Output::new(p.P1_06, Level::High, OutputDrive::Standard);
let dio1 = Input::new(p.P1_15, Pull::Down);
let busy = Input::new(p.P1_14, Pull::Down);
@@ -117,7 +120,7 @@ impl Board {
// ── USB ─────────────────────────────────────────────────
let vbus = mcu::alloc_vbus_detect(true, false);
let usb = UsbParts {
let host = UsbParts {
driver: Driver::new(p.USBD, mcu::Irqs, vbus),
};
@@ -126,9 +129,13 @@ impl Board {
let i2c = embassy_nrf::twim::Twim::new(
p.TWISPI0, mcu::Irqs, p.P0_13, p.P0_14, twim::Config::default(), twim_buf,
);
let mac = Self::mac_address();
let display = Some(DisplayParts { i2c, mac });
let display = Some(DisplayParts { i2c });
(radio, usb, display)
BoardParts {
radio,
host,
display,
mac: Self::mac_address(),
}
}
}