feat: initial lora-dongle firmware scaffold
Transparent LoRa-over-USB dongle firmware supporting Heltec V3 (ESP32-S3) and RAK 4631 (nRF52840) boards. Actor-model architecture with typed channels between USB, radio, and display tasks. - Protocol: Command/Response enums with COBS+postcard framing design - Board abstraction: auto-discovered via build.rs Jinja2 codegen - Radio task: SX1262 state machine (Idle → Receiving ↔ Transmitting) - Display task: optional SSD1306 dashboard via StatusWatch - RAK 4631: fully wired SPI/USB/I2C peripherals, clippy-clean - Heltec V3: structure in place, awaits espup Xtensa toolchain
This commit is contained in:
20 files changed
+2599
No files matched your search
@@ -0,0 +1,3 @@
|
||||
mod render;
|
||||
mod task;
|
||||
pub use task::display_task;
|
||||
@@ -0,0 +1,25 @@
|
||||
use crate::channel::{RadioState, RadioStatus};
|
||||
|
||||
/// Render the status dashboard to a framebuffer.
|
||||
///
|
||||
/// Pure logic — no hardware dependency. Takes a status snapshot and produces
|
||||
/// draw calls that the display task flushes to the screen.
|
||||
pub fn dashboard(status: &RadioStatus) {
|
||||
// TODO: use embedded-graphics to render:
|
||||
// Line 1: board name + radio state
|
||||
// Line 2: freq / BW / SF
|
||||
// Line 3: TX power / coding rate
|
||||
// Line 4: RX count / TX count
|
||||
// Line 5: last RSSI / SNR
|
||||
let _ = status;
|
||||
}
|
||||
|
||||
/// Format radio state as a short display string.
|
||||
#[allow(dead_code)]
|
||||
pub fn state_label(state: RadioState) -> &'static str {
|
||||
match state {
|
||||
RadioState::Idle => "IDLE",
|
||||
RadioState::Receiving => "RX",
|
||||
RadioState::Transmitting => "TX",
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
use embassy_executor::task;
|
||||
|
||||
use crate::board::DisplayParts;
|
||||
use crate::channel::StatusWatch;
|
||||
|
||||
use super::render;
|
||||
|
||||
#[task]
|
||||
pub async fn display_task(parts: DisplayParts, status: &'static StatusWatch) {
|
||||
let _i2c = parts.i2c;
|
||||
|
||||
// TODO: init SSD1306 driver from I2C handle
|
||||
// TODO: initial render of empty dashboard
|
||||
|
||||
let mut receiver = status.receiver().unwrap();
|
||||
|
||||
loop {
|
||||
let state = receiver.changed().await;
|
||||
render::dashboard(&state);
|
||||
// TODO: flush framebuffer to display
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user