feat: add display UI with splash screen, dashboard, and RSSI sparkline

Implement full SSD1306 OLED display support:
- Splash screen on boot (1.5s) with project name, version, board
- Dashboard showing radio state, config, counters, RSSI/SNR
- RSSI history sparkline (64-sample ring buffer, 2px-wide bars)
- DisplayOn/DisplayOff host commands routed via dedicated channel
- Pure render functions against generic DrawTarget (no hardware coupling)
- Display on/off control bypasses radio task entirely

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
swaitsandClaude Opus 4.6 committed 2026-03-29 20:42:54 -06:00
1 parent 7064110293
commit 3102fc747a
17624 files changed
+4564928 -38

No files matched your search

+47
View File
@@ -0,0 +1,47 @@
use proc_macro::TokenStream;
use syn::{parse::Error, spanned::Spanned, AttrStyle, Attribute};
pub(crate) enum WhiteListCaller {
Interrupt,
}
pub(crate) fn check_attr_whitelist(
attrs: &[Attribute],
caller: WhiteListCaller,
) -> Result<(), TokenStream> {
let whitelist = &[
"doc",
"link_section",
"cfg",
"allow",
"warn",
"deny",
"forbid",
"cold",
"ram",
"inline",
];
'o: for attr in attrs {
for val in whitelist {
if eq(attr, val) {
continue 'o;
}
}
let err_str = match caller {
WhiteListCaller::Interrupt => {
"this attribute is not allowed on an interrupt handler controlled by esp-hal"
}
};
return Err(Error::new(attr.span(), err_str).to_compile_error().into());
}
Ok(())
}
/// Returns `true` if `attr.path` matches `name`
fn eq(attr: &Attribute, name: &str) -> bool {
attr.style == AttrStyle::Outer && attr.path().is_ident(name)
}