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

+7
View File
@@ -0,0 +1,7 @@
#[derive(defmt::Format)]
struct S {
#[defmt()]
f: bool,
}
fn main() {}
+5
View File
@@ -0,0 +1,5 @@
error: expected 1 attribute argument
--> $DIR/derive-empty-attr.rs:3:7
|
3 | #[defmt()]
| ^^^^^^^
+7
View File
@@ -0,0 +1,7 @@
#[derive(defmt::Format)]
#[defmt(FooBar)]
struct S {
f: bool,
}
fn main() {}
@@ -0,0 +1,5 @@
error: unknown defmt attribute `FooBar`
--> tests/ui/derive-invalid-attr-arg-item.rs:2:9
|
2 | #[defmt(FooBar)]
| ^^^^^^
+7
View File
@@ -0,0 +1,7 @@
#[derive(defmt::Format)]
struct S {
#[defmt(FooBar)]
f: bool,
}
fn main() {}
+5
View File
@@ -0,0 +1,5 @@
error: expected `Debug2Format` or `Display2Format`
--> $DIR/derive-invalid-attr-arg.rs:3:13
|
3 | #[defmt(FooBar)]
| ^^^^^^
+13
View File
@@ -0,0 +1,13 @@
#[derive(defmt::Format)]
#[defmt(crate = unresolved)]
struct S {}
#[derive(defmt::Format)]
#[defmt(crate = "not a path")]
struct S2 {}
#[derive(defmt::Format)]
#[defmt(crate(defmt))]
struct S3 {}
fn main() {}
@@ -0,0 +1,25 @@
error: expected identifier
--> tests/ui/derive-invalid-crate-overwrite.rs:6:17
|
6 | #[defmt(crate = "not a path")]
| ^^^^^^^^^^^^
error: expected `=`
--> tests/ui/derive-invalid-crate-overwrite.rs:10:14
|
10 | #[defmt(crate(defmt))]
| ^
error[E0432]: unresolved import `unresolved`
--> tests/ui/derive-invalid-crate-overwrite.rs:1:10
|
1 | #[derive(defmt::Format)]
| ^^^^^^^^^^^^^ no external crate `unresolved`
|
= note: this error originates in the derive macro `defmt::Format` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0433]: failed to resolve: use of undeclared crate or module `unresolved`
--> tests/ui/derive-invalid-crate-overwrite.rs:2:17
|
2 | #[defmt(crate = unresolved)]
| ^^^^^^^^^^ use of undeclared crate or module `unresolved`
+8
View File
@@ -0,0 +1,8 @@
#[derive(defmt::Format)]
struct S {
#[defmt(Debug2Format)]
#[defmt()]
f: bool,
}
fn main() {}
+7
View File
@@ -0,0 +1,7 @@
error: multiple `defmt` attributes not supported
--> $DIR/derive-multi-attr.rs:3:5
|
3 | / #[defmt(Debug2Format)]
4 | | #[defmt()]
5 | | f: bool,
| |___________^
+3
View File
@@ -0,0 +1,3 @@
fn main() {
defmt::info!("{=u8:dunno}", 42)
}
+5
View File
@@ -0,0 +1,5 @@
error: unknown display hint: "dunno"
--> $DIR/log-invalid-hint.rs:2:18
|
2 | defmt::info!("{=u8:dunno}", 42)
| ^^^^^^^^^^^^^
+5
View File
@@ -0,0 +1,5 @@
#![no_main]
#![no_std]
#[defmt::panic_handler]
fn foo(x: bool) -> ! { info!("{:?}", x); loop {} }
+5
View File
@@ -0,0 +1,5 @@
error: function must have signature `fn() -> !`
--> $DIR/panic-handler-argument.rs:5:4
|
5 | fn foo(x: bool) -> ! { info!("{:?}", x); loop {} }
| ^^^
+5
View File
@@ -0,0 +1,5 @@
#![no_main]
#![no_std]
#[defmt::panic_handler]
fn foo() {}
+5
View File
@@ -0,0 +1,5 @@
error: function must have signature `fn() -> !`
--> $DIR/panic-handler-empty.rs:5:4
|
5 | fn foo() {}
| ^^^
+8
View File
@@ -0,0 +1,8 @@
#![no_main]
#![no_std]
#[defmt::panic_handler]
#[export_name = "hello"]
fn foo() -> ! {
loop {}
}
@@ -0,0 +1,5 @@
error: `#[panic_handler]` attribute cannot be used together with `#[export_name]`
--> $DIR/panic-handler-export-name.rs:5:1
|
5 | #[export_name = "hello"]
| ^^^^^^^^^^^^^^^^^^^^^^^^
+8
View File
@@ -0,0 +1,8 @@
#![no_main]
#![no_std]
#[defmt::panic_handler]
#[no_mangle]
fn panic() -> ! {
loop {}
}
+5
View File
@@ -0,0 +1,5 @@
error: `#[panic_handler]` attribute cannot be used together with `#[no_mangle]`
--> $DIR/panic-handler-no-mangle.rs:5:1
|
5 | #[no_mangle]
| ^^^^^^^^^^^^
+9
View File
@@ -0,0 +1,9 @@
struct S;
impl defmt::Format for S {
fn format(&self, f: defmt::Formatter) {
defmt::write!(f, "{=u8:dunno}", 42)
}
}
fn main() {}
+5
View File
@@ -0,0 +1,5 @@
error: unknown display hint: "dunno"
--> $DIR/write-invalid-hint.rs:5:26
|
5 | defmt::write!(f, "{=u8:dunno}", 42)
| ^^^^^^^^^^^^^