refactor: drive display via hsmc statechart
Replaces the ad-hoc display loop with a declarative hsmc statechart
(Off/On.{Splash.{LearnMore,Info}, Dashboard.{Listening,Transmitting}})
and swaps the Radio→Display channel from a RadioStatus watch to a
typed RadioEvent queue. The radio task now emits discrete mode and
packet events instead of publishing full status snapshots; the
display consumes them through the statechart, which also handles the
5 s splash alternation and 1 s sparkline tick via `on(after …)` /
`on(every …)` transitions.
Also:
- Add hsmc dep and embassy/tokio feature shims (hsmc proc macro
evaluates `cfg(feature = "embassy")` in this crate).
- Fix USB disconnect path in `host/usb.rs` so the DTR branch always
runs on read error (was early-continuing, starving display/radio
reset).
This commit is contained in:
7 files changed
+661
-347
No files matched your search
+5
-4
@@ -37,7 +37,7 @@ use embassy_executor::Spawner;
|
||||
#[cfg(not(test))]
|
||||
use crate::board::LoRaBoard;
|
||||
#[cfg(not(test))]
|
||||
use crate::channel::{CommandChannel, DisplayCommandChannel, ResponseChannel, StatusWatch};
|
||||
use crate::channel::{CommandChannel, DisplayCommandChannel, RadioEventChannel, ResponseChannel};
|
||||
|
||||
#[cfg(not(test))]
|
||||
cfg_if::cfg_if! {
|
||||
@@ -55,7 +55,7 @@ static COMMANDS: CommandChannel = CommandChannel::new();
|
||||
#[cfg(not(test))]
|
||||
static RESPONSES: ResponseChannel = ResponseChannel::new();
|
||||
#[cfg(not(test))]
|
||||
static STATUS: StatusWatch = StatusWatch::new();
|
||||
static RADIO_EVENTS: RadioEventChannel = RadioEventChannel::new();
|
||||
#[cfg(not(test))]
|
||||
static DISPLAY_COMMANDS: DisplayCommandChannel = DisplayCommandChannel::new();
|
||||
|
||||
@@ -80,7 +80,8 @@ async fn run(spawner: Spawner) {
|
||||
let parts = board.into_parts();
|
||||
|
||||
spawner.spawn(
|
||||
radio::radio_task(parts.radio, &COMMANDS, &RESPONSES, &STATUS).expect("spawn radio_task"),
|
||||
radio::radio_task(parts.radio, &COMMANDS, &RESPONSES, &RADIO_EVENTS)
|
||||
.expect("spawn radio_task"),
|
||||
);
|
||||
|
||||
spawner.spawn(
|
||||
@@ -98,7 +99,7 @@ async fn run(spawner: Spawner) {
|
||||
if let Some(dp) = parts.display {
|
||||
#[allow(clippy::unit_arg)] // LedDriver is () for boards without LEDs
|
||||
spawner.spawn(
|
||||
display::display_task(dp, parts.led, &STATUS, &DISPLAY_COMMANDS)
|
||||
display::display_task(dp, parts.led, &RADIO_EVENTS, &DISPLAY_COMMANDS)
|
||||
.expect("spawn display_task"),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user