From 0559d3c15db0c2289349f9028ae75ad72ce97ed2 Mon Sep 17 00:00:00 2001 From: daylily Date: Sat, 10 Jan 2026 11:47:24 +0800 Subject: [PATCH] Misc firmware improvements --- firmware/Cargo.toml | 2 +- firmware/src/app.rs | 47 ++++++++++++++++++++++++++++---------------- firmware/src/midi.rs | 2 +- firmware/src/uid.rs | 6 +++--- 4 files changed, 35 insertions(+), 22 deletions(-) diff --git a/firmware/Cargo.toml b/firmware/Cargo.toml index 6f26520..fbf25a1 100644 --- a/firmware/Cargo.toml +++ b/firmware/Cargo.toml @@ -39,7 +39,7 @@ embedded-hal-bus = { version = "0.3.0", features = ["async"] } epd-waveshare = "0.6.0" panic-abort = "0.3.2" panic-probe = { version = "1.0.0", features = ["print-defmt"] } -postcard = { version = "1.1.3", features = ["defmt"] } +postcard = { version = "1.1.3", features = ["use-defmt"] } serde = { version = "1.0.228", default-features = false, features = ["derive"] } static_cell = "2.1.1" diff --git a/firmware/src/app.rs b/firmware/src/app.rs index 0eeef35..4ae586c 100644 --- a/firmware/src/app.rs +++ b/firmware/src/app.rs @@ -140,19 +140,22 @@ impl App { async fn handle_get_identification(&mut self) { self.write_response(Response::GetIdentification { - serial: uid_base64().await, + serial: uid_base64(), model: DeviceType::BWRev1, }) .await; } - async fn write_response<'a>(&mut self, resp: Response<'a>) -> bool { + async fn write_response<'a>(&mut self, resp: Response<'a>) { const RESP_N: usize = 1024; let mut resp_buffer = [0u8; RESP_N]; - let Ok(payload_slice) = postcard::to_slice(&resp, &mut resp_buffer) else { - error!("write_response: postcard encoding overflows the buffer"); - return false; + let payload_slice = match postcard::to_slice(&resp, &mut resp_buffer) { + Ok(slice) => slice, + Err(err) => { + error!("write_response: postcard encoding returns {}", err); + return; + } }; let mut encode_buffer = [0u8; RESP_N]; @@ -160,23 +163,31 @@ impl App { let Some(encoded_len) = encode_7in8(payload_slice, &mut encode_buffer[MAGIC_NUMBER_LEN..]) else { error!("write_response: 7-in-8 encoding overflows the buffer"); - return false; + return; }; - let mut sysex_encoder = SysExEncoder::<1024>::new(); + let mut sysex_encoder = SysExEncoder::::new(); let Some(encoded) = sysex_encoder.encode(&encode_buffer[..MAGIC_NUMBER_LEN + encoded_len]) else { error!("write_response: USB MIDI encoding overflows the buffer"); - return false; + return; }; for chunk in encoded.chunks(64) { - let Ok(_) = self.midi.write_packet(chunk).await else { - error!("write_response: failed to write response"); - return false; + match self.midi.write_packet(chunk).await { + Ok(_) => {} + Err(EndpointError::BufferOverflow) => { + error!("write_response: EP buffer overflowed"); + return; + } + Err(EndpointError::Disabled) => { + warn!( + "write_response: EP disabled when writing a response. Remainder will be discarded" + ); + return; + } }; } - true } pub async fn run(&mut self) { @@ -225,13 +236,15 @@ impl App { continue; } - let Ok(parsed) = postcard::from_bytes::(decode_7in8( + match postcard::from_bytes::(decode_7in8( &mut sysex[MAGIC_NUMBER_LEN..], - )) else { - warn!("App: cannot parse payload. dropping."); - continue; + )) { + Ok(parsed) => self.handle_request(parsed).await, + Err(err) => { + warn!("App: cannot parse payload ({}). dropping.", err); + continue; + } }; - self.handle_request(parsed).await; } } } diff --git a/firmware/src/midi.rs b/firmware/src/midi.rs index b22237c..362dc26 100644 --- a/firmware/src/midi.rs +++ b/firmware/src/midi.rs @@ -25,7 +25,7 @@ pub async fn make_usb_builder( let mut config = embassy_usb::Config::new(0x1209, 0xc9c9); config.manufacturer = Some("Project Daylily"); config.product = Some("Inkclip BW"); - config.serial_number = Some(uid::uid_base64().await); + config.serial_number = Some(uid::uid_base64()); config.bcd_usb = UsbVersion::Two; let usb_driver = usb::Driver::new_fs(peri, Irqs, dp, dm, ep_out_buffer, usb::Config::default()); diff --git a/firmware/src/uid.rs b/firmware/src/uid.rs index 5c541a0..74337f4 100644 --- a/firmware/src/uid.rs +++ b/firmware/src/uid.rs @@ -2,11 +2,11 @@ use base64::prelude::*; use embassy_stm32::uid::uid; use embassy_sync::once_lock::OnceLock; -pub async fn uid_base64() -> &'static str { - unsafe { core::str::from_utf8_unchecked(uid_base64_bytes().await) } +pub fn uid_base64() -> &'static str { + unsafe { core::str::from_utf8_unchecked(uid_base64_bytes()) } } -pub async fn uid_base64_bytes() -> &'static [u8; 16] { +pub fn uid_base64_bytes() -> &'static [u8; 16] { static UID_BASE64: OnceLock<[u8; 16]> = OnceLock::new(); UID_BASE64.get_or_init(|| { let mut b64 = [0u8; 16];