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

+10
View File
@@ -0,0 +1,10 @@
use test_crate::*;
abort_from!(one, two);
abort_to_string!(one, two);
abort_format!(one, two);
direct_abort!(one, two);
abort_notes!(one, two);
abort_call_site_test!(one, two);
fn main() {}
+48
View File
@@ -0,0 +1,48 @@
error: abort!(span, from) test
--> tests/ui/abort.rs:3:13
|
3 | abort_from!(one, two);
| ^^^
error: abort!(span, single_expr) test
--> tests/ui/abort.rs:4:18
|
4 | abort_to_string!(one, two);
| ^^^
error: abort!(span, expr1, expr2) test
--> tests/ui/abort.rs:5:15
|
5 | abort_format!(one, two);
| ^^^
error: Diagnostic::abort() test
--> tests/ui/abort.rs:6:15
|
6 | direct_abort!(one, two);
| ^^^
error: This is an error
= note: simple note
= help: simple help
= help: simple hint
= note: simple yay
= note: format note
= note: Some note
= note: spanned simple note
= note: spanned format note
= note: Some note
--> tests/ui/abort.rs:7:14
|
7 | abort_notes!(one, two);
| ^^^
error: abort_call_site! test
--> tests/ui/abort.rs:8:1
|
8 | abort_call_site_test!(one, two);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `abort_call_site_test` (in Nightly builds, run with -Z macro-backtrace for more info)
+12
View File
@@ -0,0 +1,12 @@
use test_crate::*;
enum NeedDefault {
A,
B,
}
append_dummy!(need_default);
fn main() {
let _ = NeedDefault::default();
}
+5
View File
@@ -0,0 +1,5 @@
error: append_dummy test
--> tests/ui/append_dummy.rs:8:15
|
8 | append_dummy!(need_default);
| ^^^^^^^^^^^^
@@ -0,0 +1,5 @@
use test_crate::*;
children_messages!(one, two, three, four);
fn main() {}
@@ -0,0 +1,23 @@
error: main macro message
--> tests/ui/children_messages.rs:3:20
|
3 | children_messages!(one, two, three, four);
| ^^^
error: child message
--> tests/ui/children_messages.rs:3:25
|
3 | children_messages!(one, two, three, four);
| ^^^
error: main syn::Error
--> tests/ui/children_messages.rs:3:30
|
3 | children_messages!(one, two, three, four);
| ^^^^^
error: child syn::Error
--> tests/ui/children_messages.rs:3:37
|
3 | children_messages!(one, two, three, four);
| ^^^^
+12
View File
@@ -0,0 +1,12 @@
use test_crate::*;
enum NeedDefault {
A,
B,
}
dummy!(need_default);
fn main() {
let _ = NeedDefault::default();
}
+5
View File
@@ -0,0 +1,5 @@
error: set_dummy test
--> tests/ui/dummy.rs:8:8
|
8 | dummy!(need_default);
| ^^^^^^^^^^^^
+6
View File
@@ -0,0 +1,6 @@
use test_crate::*;
emit!(one, two, three, four, five);
emit_notes!(one, two);
fn main() {}
+48
View File
@@ -0,0 +1,48 @@
error: emit!(span, from) test
--> tests/ui/emit.rs:3:7
|
3 | emit!(one, two, three, four, five);
| ^^^
error: emit!(span, expr1, expr2) test
--> tests/ui/emit.rs:3:12
|
3 | emit!(one, two, three, four, five);
| ^^^
error: emit!(span, single_expr) test
--> tests/ui/emit.rs:3:17
|
3 | emit!(one, two, three, four, five);
| ^^^^^
error: Diagnostic::emit() test
--> tests/ui/emit.rs:3:24
|
3 | emit!(one, two, three, four, five);
| ^^^^
error: emit_call_site_error!(expr) test
--> tests/ui/emit.rs:3:1
|
3 | emit!(one, two, three, four, five);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `emit` (in Nightly builds, run with -Z macro-backtrace for more info)
error: This is an error
= note: simple note
= help: simple help
= help: simple hint
= note: simple yay
= note: format note
= note: Some note
= note: spanned simple note
= note: spanned format note
= note: Some note
--> tests/ui/emit.rs:4:13
|
4 | emit_notes!(one, two);
| ^^^
@@ -0,0 +1,5 @@
use test_crate::*;
explicit_span_range!(one, two, three, four);
fn main() {}
@@ -0,0 +1,5 @@
error: explicit SpanRange
--> tests/ui/explicit_span_range.rs:3:22
|
3 | explicit_span_range!(one, two, three, four);
| ^^^^^^^^^^^^^^^
+10
View File
@@ -0,0 +1,10 @@
use proc_macro_error2::abort;
struct Foo;
#[allow(unused)]
fn foo() {
abort!(Foo, "BOOM");
}
fn main() {}
+24
View File
@@ -0,0 +1,24 @@
error[E0599]: the method `FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange` exists for reference `&Foo`, but its trait bounds were not satisfied
--> tests/ui/misuse.rs:7:5
|
3 | struct Foo;
| ---------- doesn't satisfy `Foo: quote::to_tokens::ToTokens`
...
7 | abort!(Foo, "BOOM");
| ^^^^^^^^^^^^^^^^^^^ method cannot be called on `&Foo` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`Foo: quote::to_tokens::ToTokens`
which is required by `&Foo: ToTokensAsSpanRange`
note: the trait `quote::to_tokens::ToTokens` must be implemented
--> $CARGO/quote-1.0.37/src/to_tokens.rs
|
| pub trait ToTokens {
| ^^^^^^^^^^^^^^^^^^
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following traits define an item `FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange`, perhaps you need to implement one of them:
candidate #1: `Span2AsSpanRange`
candidate #2: `SpanAsSpanRange`
candidate #3: `SpanRangeAsSpanRange`
candidate #4: `ToTokensAsSpanRange`
= note: this error originates in the macro `$crate::diagnostic` which comes from the expansion of the macro `abort` (in Nightly builds, run with -Z macro-backtrace for more info)
+4
View File
@@ -0,0 +1,4 @@
#[test_crate::multiple_tokens]
type T = ();
fn main() {}
@@ -0,0 +1,5 @@
error: ...
--> tests/ui/multiple_tokens.rs:2:1
|
2 | type T = ();
| ^^^^^^^^^^^^
+4
View File
@@ -0,0 +1,4 @@
use proc_macro_error2::proc_macro_error;
#[proc_macro_error]
fn main() {}
@@ -0,0 +1,9 @@
error: #[proc_macro_error] attribute can be used only with procedural macros
= hint: if you are really sure that #[proc_macro_error] should be applied to this exact function, use #[proc_macro_error(allow_not_macro)]
--> tests/ui/not_proc_macro.rs:3:1
|
3 | #[proc_macro_error]
| ^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the attribute macro `proc_macro_error` (in Nightly builds, run with -Z macro-backtrace for more info)
+5
View File
@@ -0,0 +1,5 @@
use test_crate::*;
option_ext!(one, two);
fn main() {}
+7
View File
@@ -0,0 +1,7 @@
error: Option::expect_or_abort() test
--> tests/ui/option_ext.rs:3:1
|
3 | option_ext!(one, two);
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `option_ext` (in Nightly builds, run with -Z macro-backtrace for more info)
+6
View File
@@ -0,0 +1,6 @@
use test_crate::*;
result_unwrap_or_abort!(one, two);
result_expect_or_abort!(one, two);
fn main() {}
+11
View File
@@ -0,0 +1,11 @@
error: Result::unwrap_or_abort() test
--> tests/ui/result_ext.rs:3:25
|
3 | result_unwrap_or_abort!(one, two);
| ^^^
error: BOOM: Result::expect_or_abort() test
--> tests/ui/result_ext.rs:4:25
|
4 | result_expect_or_abort!(one, two);
| ^^^
+5
View File
@@ -0,0 +1,5 @@
use test_crate::*;
to_tokens_span!(std::option::Option);
fn main() {}
+11
View File
@@ -0,0 +1,11 @@
error: whole type
--> tests/ui/to_tokens_span.rs:3:17
|
3 | to_tokens_span!(std::option::Option);
| ^^^^^^^^^^^^^^^^^^^
error: explicit .span()
--> tests/ui/to_tokens_span.rs:3:17
|
3 | to_tokens_span!(std::option::Option);
| ^^^
+4
View File
@@ -0,0 +1,4 @@
use proc_macro_error2::proc_macro_error;
#[proc_macro_error(allow_not_macro, assert_unwind_safe, trololo)]
fn main() {}
@@ -0,0 +1,5 @@
error: unknown setting `trololo`, expected one of `assert_unwind_safe`, `allow_not_macro`, `proc_macro_hack`
--> tests/ui/unknown_setting.rs:3:57
|
3 | #[proc_macro_error(allow_not_macro, assert_unwind_safe, trololo)]
| ^^^^^^^
+5
View File
@@ -0,0 +1,5 @@
use test_crate::*;
unrelated_panic!();
fn main() {}
@@ -0,0 +1,7 @@
error: proc macro panicked
--> tests/ui/unrelated_panic.rs:3:1
|
3 | unrelated_panic!();
| ^^^^^^^^^^^^^^^^^^
|
= help: message: unrelated panic test