fix: resolve display stuck after disconnect and radio task deadlock

- Set disconnected flag on DisplayCommand::Reset to block stale radio
  status updates from re-rendering dashboard over splash screen
- Send StopRx to radio when USB DTR drops so radio stops generating
  packets after host disconnects
- Use try_send for unsolicited responses (RxPacket, error recovery,
  StopRx Ok) to prevent radio task deadlock on full response channel
- Fall back to LED-only event loop when display init fails instead of
  returning early and orphaning the LED

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
swaitsandClaude Opus 4.6 committed 2026-04-07 19:49:15 -06:00
1 parent 0c9094dcbd
commit de38278d7b
6 files changed
+114 -12

No files matched your search

+6 -2
View File
@@ -8,6 +8,7 @@ use embassy_usb::Builder;
use static_cell::StaticCell;
use crate::channel::{CommandChannel, DisplayCommand, DisplayCommandChannel, ResponseChannel};
use crate::protocol::Command;
use super::framing::{self, CobsDecoder, MAX_FRAME};
const MAX_PACKET: usize = 64;
@@ -126,8 +127,11 @@ async fn protocol_loop<'d, D: embassy_usb_driver::Driver<'d>>(
}
let connected = receiver.dtr();
if was_connected && !connected && has_display {
display_commands.send(DisplayCommand::Reset).await;
if was_connected && !connected {
let _ = commands.try_send(Command::StopRx);
if has_display {
display_commands.send(DisplayCommand::Reset).await;
}
}
if !was_connected && connected && has_display {
display_commands.send(DisplayCommand::On).await;