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:
17624 files changed
+4564928
-38
No files matched your search
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
fn main() {
|
||||
defmt::info!("hello");
|
||||
}
|
||||
|
||||
#[defmt::global_logger]
|
||||
struct Logger;
|
||||
|
||||
unsafe impl defmt::Logger for Logger {
|
||||
fn acquire() {}
|
||||
unsafe fn flush() {}
|
||||
unsafe fn release() {}
|
||||
unsafe fn write(_bytes: &[u8]) {}
|
||||
}
|
||||
|
||||
defmt::timestamp!("{=u32}", 0);
|
||||
Vendored
+36
@@ -0,0 +1,36 @@
|
||||
extern crate defmt as defmt2;
|
||||
|
||||
fn main() {
|
||||
let baz: Baz<Qux> = Default::default();
|
||||
defmt::info!("{}", baz);
|
||||
}
|
||||
|
||||
trait Foo {
|
||||
type Bar;
|
||||
}
|
||||
#[derive(defmt::Format, Default)]
|
||||
struct Baz<T: Foo> {
|
||||
field: T::Bar,
|
||||
field2: Quux<T>,
|
||||
}
|
||||
#[derive(defmt::Format, Default)]
|
||||
struct Qux;
|
||||
impl Foo for Qux {
|
||||
type Bar = Qux;
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
#[derive(defmt::Format, Default)]
|
||||
enum Quux<T: Foo> {
|
||||
#[default]
|
||||
None,
|
||||
Variant1(T),
|
||||
Variant2 {
|
||||
f: T::Bar,
|
||||
},
|
||||
Variant3(T::Bar),
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(defmt::Format)]
|
||||
#[defmt(crate = defmt2)]
|
||||
struct Quz;
|
||||
Vendored
+1011
File diff suppressed because it is too large.
Load diff
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
#[test]
|
||||
fn ui() {
|
||||
// only test error messages on the stable channel (nightly may change too often)
|
||||
if rustc_version::version_meta()
|
||||
.map(|meta| meta.channel == rustc_version::Channel::Stable)
|
||||
.unwrap_or(false)
|
||||
&& std::env::var_os("SKIP_UI_TESTS").is_none()
|
||||
{
|
||||
let t = trybuild::TestCases::new();
|
||||
t.compile_fail("tests/ui/*.rs");
|
||||
|
||||
t.pass("tests/basic_usage.rs");
|
||||
t.pass("tests/derive-bounds.rs");
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
#[derive(defmt::Format)]
|
||||
struct S {
|
||||
#[defmt()]
|
||||
f: bool,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: expected 1 attribute argument
|
||||
--> $DIR/derive-empty-attr.rs:3:7
|
||||
|
|
||||
3 | #[defmt()]
|
||||
| ^^^^^^^
|
||||
@@ -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)]
|
||||
| ^^^^^^
|
||||
@@ -0,0 +1,7 @@
|
||||
#[derive(defmt::Format)]
|
||||
struct S {
|
||||
#[defmt(FooBar)]
|
||||
f: bool,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: expected `Debug2Format` or `Display2Format`
|
||||
--> $DIR/derive-invalid-attr-arg.rs:3:13
|
||||
|
|
||||
3 | #[defmt(FooBar)]
|
||||
| ^^^^^^
|
||||
@@ -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
@@ -0,0 +1,8 @@
|
||||
#[derive(defmt::Format)]
|
||||
struct S {
|
||||
#[defmt(Debug2Format)]
|
||||
#[defmt()]
|
||||
f: bool,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -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
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
defmt::info!("{=u8:dunno}", 42)
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: unknown display hint: "dunno"
|
||||
--> $DIR/log-invalid-hint.rs:2:18
|
||||
|
|
||||
2 | defmt::info!("{=u8:dunno}", 42)
|
||||
| ^^^^^^^^^^^^^
|
||||
@@ -0,0 +1,5 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
#[defmt::panic_handler]
|
||||
fn foo(x: bool) -> ! { info!("{:?}", x); loop {} }
|
||||
@@ -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 {} }
|
||||
| ^^^
|
||||
@@ -0,0 +1,5 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
#[defmt::panic_handler]
|
||||
fn foo() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: function must have signature `fn() -> !`
|
||||
--> $DIR/panic-handler-empty.rs:5:4
|
||||
|
|
||||
5 | fn foo() {}
|
||||
| ^^^
|
||||
@@ -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"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -0,0 +1,8 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
#[defmt::panic_handler]
|
||||
#[no_mangle]
|
||||
fn panic() -> ! {
|
||||
loop {}
|
||||
}
|
||||
@@ -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
@@ -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() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: unknown display hint: "dunno"
|
||||
--> $DIR/write-invalid-hint.rs:5:26
|
||||
|
|
||||
5 | defmt::write!(f, "{=u8:dunno}", 42)
|
||||
| ^^^^^^^^^^^^^
|
||||
Reference in new issue
Block a user