refactor: extract hal/ and driver/ modules
- Created hal/esp32s3.rs with MCU primitives (SPI, I2C, USB, UART, timer, MAC) - Created hal/nrf52840.rs with shared nRF boilerplate (interrupts, bus wrapping, VBUS, MAC) - Moved SH1106 OLED driver from display/ to driver/ (clear separation from app code) - Board esp32s3.rs now delegates MCU init to hal, keeps only peripheral wiring (RadioParts) - nRF board files use hal for shared StaticCell patterns, mac_address, interrupt bindings - Board files still own pin assignments and peripheral construction
This commit is contained in:
1 parent
8bdaa72bc3
commit
fb334118fd
13 files changed
+300
-252
No files matched your search
+23
-59
@@ -1,40 +1,27 @@
|
||||
use embassy_embedded_hal::shared_bus::asynch::spi::SpiDevice;
|
||||
use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
|
||||
use embassy_nrf::spim::{self, Spim};
|
||||
use embassy_nrf::twim::{self, Twim};
|
||||
use embassy_nrf::twim;
|
||||
use embassy_nrf::usb::Driver;
|
||||
use embassy_nrf::{bind_interrupts, Peripherals};
|
||||
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
|
||||
use embassy_time::Delay;
|
||||
use static_cell::StaticCell;
|
||||
|
||||
use lora_phy::iv::GenericSx126xInterfaceVariant;
|
||||
use lora_phy::sx126x::{self, Sx1262, Sx126x};
|
||||
|
||||
use super::traits::LoRaBoard;
|
||||
use crate::hal::nrf52840 as mcu;
|
||||
|
||||
bind_interrupts!(struct Irqs {
|
||||
USBD => embassy_nrf::usb::InterruptHandler<embassy_nrf::peripherals::USBD>;
|
||||
SPIM3 => embassy_nrf::spim::InterruptHandler<embassy_nrf::peripherals::SPI3>;
|
||||
TWISPI0 => embassy_nrf::twim::InterruptHandler<embassy_nrf::peripherals::TWISPI0>;
|
||||
});
|
||||
// ── Concrete peripheral types ───────────────────────────────────────
|
||||
|
||||
// ── Concrete peripheral types ────────────────────────────────────────
|
||||
|
||||
type SpiBus = Spim<'static>;
|
||||
type Nss = Output<'static>;
|
||||
type Iv = GenericSx126xInterfaceVariant<Output<'static>, Input<'static>>;
|
||||
type RadioSpiDevice = SpiDevice<'static, NoopRawMutex, SpiBus, Nss>;
|
||||
/// SX126x driver (pre-LoRa construction — LoRa::new is async).
|
||||
type RadioSpiDevice = SpiDevice<'static, NoopRawMutex, mcu::SpiBus, Nss>;
|
||||
pub type RadioDriver = Sx126x<RadioSpiDevice, Iv, Sx1262>;
|
||||
pub type UsbDriver = mcu::UsbNrfDriver;
|
||||
pub type DisplayI2c = mcu::I2cBus;
|
||||
|
||||
/// USB driver for CDC-ACM.
|
||||
pub type UsbDriver = Driver<'static, &'static embassy_nrf::usb::vbus_detect::SoftwareVbusDetect>;
|
||||
|
||||
/// I2C bus for SH1106 OLED.
|
||||
pub type DisplayI2c = Twim<'static>;
|
||||
|
||||
// ── Peripheral bundles ───────────────────────────────────────────────
|
||||
// ── Peripheral bundles ──────────────────────────────────────────────
|
||||
|
||||
pub struct RadioParts {
|
||||
pub driver: RadioDriver,
|
||||
@@ -50,13 +37,13 @@ pub struct DisplayParts {
|
||||
pub mac: [u8; 6],
|
||||
}
|
||||
|
||||
// ── Board init ───────────────────────────────────────────────────────
|
||||
// ── Board init ──────────────────────────────────────────────────────
|
||||
|
||||
pub struct Board {
|
||||
p: Peripherals,
|
||||
p: embassy_nrf::Peripherals,
|
||||
}
|
||||
|
||||
impl super::traits::LoRaBoard for Board {
|
||||
impl LoRaBoard for Board {
|
||||
const NAME: &'static str = "Wio Tracker L1";
|
||||
const TX_POWER_RANGE: (i8, i8) = (-9, 22);
|
||||
|
||||
@@ -69,23 +56,7 @@ impl super::traits::LoRaBoard for Board {
|
||||
}
|
||||
|
||||
fn mac_address() -> [u8; 6] {
|
||||
// SAFETY: 0x10000000 is the nRF52840 FICR (Factory Information Configuration
|
||||
// Registers) base address. Offsets 0x0A4 and 0x0A8 are the DEVICEADDR[0] and
|
||||
// DEVICEADDR[1] registers containing the factory-programmed device address.
|
||||
// read_volatile is correct for memory-mapped hardware registers.
|
||||
unsafe {
|
||||
let ficr = 0x10000000 as *const u32;
|
||||
let addr0 = core::ptr::read_volatile(ficr.byte_add(0x0A4));
|
||||
let addr1 = core::ptr::read_volatile(ficr.byte_add(0x0A8));
|
||||
[
|
||||
addr0 as u8,
|
||||
(addr0 >> 8) as u8,
|
||||
(addr0 >> 16) as u8,
|
||||
(addr0 >> 24) as u8,
|
||||
addr1 as u8,
|
||||
(addr1 >> 8) as u8,
|
||||
]
|
||||
}
|
||||
mcu::mac_address()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,19 +64,16 @@ impl Board {
|
||||
pub fn into_parts(self) -> (RadioParts, UsbParts, Option<DisplayParts>) {
|
||||
let p = self.p;
|
||||
|
||||
// ── SPI bus for SX1262 ───────────────────────────────────
|
||||
// ── SPI bus for SX1262 ──────────────────────────────────
|
||||
let mut spi_cfg = spim::Config::default();
|
||||
spi_cfg.frequency = spim::Frequency::M1;
|
||||
let spi = Spim::new(p.SPI3, Irqs, p.P0_30, p.P0_03, p.P0_28, spi_cfg);
|
||||
|
||||
static SPI_BUS: StaticCell<embassy_sync::mutex::Mutex<NoopRawMutex, SpiBus>> =
|
||||
StaticCell::new();
|
||||
let spi_bus = SPI_BUS.init(embassy_sync::mutex::Mutex::new(spi));
|
||||
let spi = Spim::new(p.SPI3, mcu::Irqs, p.P0_30, p.P0_03, p.P0_28, spi_cfg);
|
||||
let spi_bus = mcu::share_spi_bus(spi);
|
||||
|
||||
let nss = Output::new(p.P1_14, Level::High, OutputDrive::Standard);
|
||||
let spi_device = SpiDevice::new(spi_bus, nss);
|
||||
|
||||
// ── SX1262 control pins ──────────────────────────────────
|
||||
// ── SX1262 control pins ─────────────────────────────────
|
||||
let reset = Output::new(p.P1_07, Level::High, OutputDrive::Standard);
|
||||
let dio1 = Input::new(p.P0_07, Pull::Down);
|
||||
let busy = Input::new(p.P1_10, Pull::Down);
|
||||
@@ -127,25 +95,21 @@ impl Board {
|
||||
delay: Delay,
|
||||
};
|
||||
|
||||
// ── USB ──────────────────────────────────────────────────
|
||||
static VBUS: StaticCell<embassy_nrf::usb::vbus_detect::SoftwareVbusDetect> =
|
||||
StaticCell::new();
|
||||
let vbus = VBUS.init(embassy_nrf::usb::vbus_detect::SoftwareVbusDetect::new(
|
||||
true, true,
|
||||
));
|
||||
// ── USB ─────────────────────────────────────────────────
|
||||
let vbus = mcu::alloc_vbus_detect(true, true);
|
||||
let usb = UsbParts {
|
||||
driver: Driver::new(p.USBD, Irqs, vbus),
|
||||
driver: Driver::new(p.USBD, mcu::Irqs, vbus),
|
||||
};
|
||||
|
||||
// ── BAT_CTL: P0.04, active HIGH — enables power to OLED and battery sense
|
||||
let bat_ctl = Output::new(p.P0_04, Level::High, OutputDrive::Standard);
|
||||
core::mem::forget(bat_ctl);
|
||||
|
||||
// ── Display (SH1106 OLED on I2C) ─────────────────────────
|
||||
static TWIM_BUF: StaticCell<[u8; 256]> = StaticCell::new();
|
||||
let twim_buf = TWIM_BUF.init([0u8; 256]);
|
||||
let i2c_cfg = twim::Config::default();
|
||||
let i2c = Twim::new(p.TWISPI0, Irqs, p.P0_06, p.P0_05, i2c_cfg, twim_buf);
|
||||
// ── Display (SH1106 OLED on I2C) ────────────────────────
|
||||
let twim_buf = mcu::alloc_i2c_buffer();
|
||||
let i2c = embassy_nrf::twim::Twim::new(
|
||||
p.TWISPI0, mcu::Irqs, p.P0_06, p.P0_05, twim::Config::default(), twim_buf,
|
||||
);
|
||||
let mac = Self::mac_address();
|
||||
let display = Some(DisplayParts { i2c, mac });
|
||||
|
||||
|
||||
Reference in new issue
Block a user