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
+75
@@ -0,0 +1,75 @@
|
||||
#[macro_use]
|
||||
extern crate bitfield;
|
||||
|
||||
use bitfield::BitMut;
|
||||
use bitfield::BitRangeMut;
|
||||
|
||||
bitfield! {
|
||||
struct BitsLocations([u8]);
|
||||
}
|
||||
|
||||
bitfield! {
|
||||
struct BitsLocationsMsb0(MSB0 [u8]);
|
||||
}
|
||||
|
||||
fn println_slice_bits(slice: &[u8]) {
|
||||
if slice.is_empty() {
|
||||
println!("[]");
|
||||
} else {
|
||||
print!("[{:08b}", slice[0]);
|
||||
|
||||
for byte in &slice[1..] {
|
||||
print!(", {:08b}", byte);
|
||||
}
|
||||
|
||||
println!("]");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut bits_locations = BitsLocations([0; 3]);
|
||||
let mut bits_locations_msb0 = BitsLocationsMsb0([0; 3]);
|
||||
|
||||
println!("Default version:");
|
||||
for i in 0..(3 * 8) {
|
||||
bits_locations.set_bit(i, true);
|
||||
print!("{:2}: ", i);
|
||||
println_slice_bits(&bits_locations.0);
|
||||
bits_locations.set_bit(i, false);
|
||||
}
|
||||
|
||||
for i in 0..(3 * 8 - 3) {
|
||||
let msb = i + 3;
|
||||
let lsb = i;
|
||||
for value in &[0b1111u8, 0b0001, 0b1000] {
|
||||
bits_locations.set_bit_range(msb, lsb, *value);
|
||||
print!("{:2} - {:2} ({:04b}): ", msb, lsb, value);
|
||||
println_slice_bits(&bits_locations.0);
|
||||
}
|
||||
println!();
|
||||
bits_locations.set_bit_range(msb, lsb, 0u8);
|
||||
}
|
||||
|
||||
println!("MSB0 version:");
|
||||
|
||||
for i in 0..(3 * 8) {
|
||||
bits_locations_msb0.set_bit(i, true);
|
||||
print!("{:2}: ", i);
|
||||
println_slice_bits(&bits_locations_msb0.0);
|
||||
|
||||
bits_locations_msb0.set_bit(i, false);
|
||||
}
|
||||
|
||||
for i in 0..(3 * 8 - 3) {
|
||||
let msb = i + 3;
|
||||
let lsb = i;
|
||||
for value in &[0b1111u8, 0b0001, 0b1000] {
|
||||
bits_locations_msb0.set_bit_range(msb, lsb, *value);
|
||||
print!("{:2} - {:2} ({:04b}): ", msb, lsb, value);
|
||||
println_slice_bits(&bits_locations_msb0.0);
|
||||
}
|
||||
println!();
|
||||
|
||||
bits_locations_msb0.set_bit_range(msb, lsb, 0u8);
|
||||
}
|
||||
}
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate bitfield;
|
||||
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
bitfield! {
|
||||
struct IpV4Header(MSB0 [u8]);
|
||||
impl Debug;
|
||||
u32;
|
||||
get_version, _: 3, 0;
|
||||
get_ihl, _: 7, 4;
|
||||
get_dscp, _: 13, 8;
|
||||
get_ecn, _: 15, 14;
|
||||
get_total_length, _: 31, 16;
|
||||
get_identification, _: 47, 32;
|
||||
get_df, _: 49;
|
||||
get_mf, _: 50;
|
||||
get_fragment_offset, _: 63, 51;
|
||||
get_time_to_live, _: 71, 64;
|
||||
get_protocol, _: 79, 72;
|
||||
get_header_checksum, _: 95, 80;
|
||||
u8, get_source_address, _: 103, 96, 4;
|
||||
u32, into Ipv4Addr, get_destination_address, _: 159, 128;
|
||||
}
|
||||
|
||||
impl<T: AsRef<[u8]>> IpV4Header<T> {
|
||||
fn get_source_as_ip_addr(&self) -> Ipv4Addr {
|
||||
let mut src = [0; 4];
|
||||
for (i, src) in src.iter_mut().enumerate() {
|
||||
*src = self.get_source_address(i);
|
||||
}
|
||||
src.into()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let data = [
|
||||
0x45, 0x00, 0x00, 0x40, 0x69, 0x27, 0x40, 0x00, 0x40, 0x11, 0x4d, 0x0d, 0xc0, 0xa8, 0x01,
|
||||
0x2a, 0xc0, 0xa8, 0x01, 0xfe,
|
||||
];
|
||||
|
||||
let header = IpV4Header(data);
|
||||
|
||||
assert_eq!(header.get_version(), 4);
|
||||
assert_eq!(header.get_total_length(), 64);
|
||||
assert_eq!(header.get_identification(), 0x6927);
|
||||
assert!(header.get_df());
|
||||
assert!(!header.get_mf());
|
||||
assert_eq!(header.get_fragment_offset(), 0);
|
||||
assert_eq!(header.get_protocol(), 0x11);
|
||||
println!(
|
||||
"from {} to {}",
|
||||
header.get_source_as_ip_addr(),
|
||||
header.get_destination_address()
|
||||
);
|
||||
|
||||
println!("{:#?}", header);
|
||||
}
|
||||
Reference in new issue
Block a user