fix: eliminate panics, validate config, handle all errors in radio/USB tasks

Radio task:
- Remove all .unwrap() — start_rx/rx_once now take &RadioConfig directly
- Validate RadioConfig on SetConfig and Transmit (freq, SF, CR, power)
- Notify host when RX restart fails (was silently going Idle)
- Clamp payload length with warning instead of silent truncation
- Extract modulation_params() helper, eliminating 3x duplication
- Name all magic numbers (PREAMBLE_LEN, CRC_ON, etc.)
- Add comprehensive module documentation

USB task:
- Log serialization and write failures instead of silently dropping
- Break chunk loop on write error
- Add compile-time buffer size assertion

Protocol:
- Add RadioConfig::validate() with SX1262 hardware limits
- Document all field ranges
This commit is contained in:
swaits committed 2026-03-29 20:42:57 -06:00
1 parent ece7cbc8ab
commit a60c18a8bf
3 files changed
+212 -77

No files matched your search

+20 -3
View File
@@ -1,3 +1,4 @@
use defmt::warn;
use embassy_executor::task;
use embassy_futures::join::join;
use embassy_usb::class::cdc_acm::{CdcAcmClass, Receiver, Sender, State};
@@ -14,6 +15,14 @@ use crate::protocol::{Command, ErrorCode, Response};
const MAX_FRAME: usize = 512;
const MAX_PACKET: usize = 64;
// Ensure MAX_FRAME can hold the largest possible COBS-encoded response.
// Worst case: RxPacket with MAX_PAYLOAD bytes. Postcard overhead ~8 bytes,
// COBS adds ceil(n/254)+1 bytes. 256+8+3 = 267. 512 is comfortably sufficient.
const _: () = assert!(
MAX_FRAME >= crate::protocol::MAX_PAYLOAD + 64,
"MAX_FRAME too small for max payload + COBS overhead"
);
#[task]
pub async fn usb_task(
parts: UsbParts,
@@ -117,9 +126,17 @@ async fn protocol_loop<'d, D: embassy_usb_driver::Driver<'d>>(
}
}
Either3::Second(response) => {
if let Ok(buf) = postcard::to_slice_cobs(&response, &mut write_buf) {
for chunk in buf.chunks(MAX_PACKET) {
let _ = sender.write_packet(chunk).await;
match postcard::to_slice_cobs(&response, &mut write_buf) {
Ok(buf) => {
for chunk in buf.chunks(MAX_PACKET) {
if sender.write_packet(chunk).await.is_err() {
warn!("USB write failed, response dropped");
break;
}
}
}
Err(_) => {
warn!("response serialization failed");
}
}
}