simple picorom interface
This commit is contained in:
69
Cargo.lock
generated
69
Cargo.lock
generated
@@ -155,6 +155,15 @@ version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e"
|
||||
|
||||
[[package]]
|
||||
name = "defmt"
|
||||
version = "0.3.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad"
|
||||
dependencies = [
|
||||
"defmt 1.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt"
|
||||
version = "1.0.1"
|
||||
@@ -194,7 +203,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93d5a25c99d89c40f5676bec8cefe0614f17f0f40e916f98e345dae941807f9e"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
"defmt",
|
||||
"defmt 1.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -391,6 +400,16 @@ dependencies = [
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heapless"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2af2455f757db2b292a9b1768c4b70186d443bcb3b316252d6b540aec1cd89ed"
|
||||
dependencies = [
|
||||
"hash32",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.5.2"
|
||||
@@ -522,7 +541,17 @@ version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9"
|
||||
dependencies = [
|
||||
"num_enum_derive",
|
||||
"num_enum_derive 0.5.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c"
|
||||
dependencies = [
|
||||
"num_enum_derive 0.7.5",
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -536,6 +565,17 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.110",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "panic-probe"
|
||||
version = "1.0.0"
|
||||
@@ -543,7 +583,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd402d00b0fb94c5aee000029204a46884b1262e0c443f166d86d2c0747e1a1a"
|
||||
dependencies = [
|
||||
"cortex-m",
|
||||
"defmt",
|
||||
"defmt 1.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -600,13 +640,17 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"cortex-m",
|
||||
"cortex-m-rt",
|
||||
"defmt",
|
||||
"defmt 1.0.1",
|
||||
"defmt-rtt",
|
||||
"embedded-hal 1.0.0",
|
||||
"heapless 0.9.2",
|
||||
"num_enum 0.7.5",
|
||||
"panic-probe",
|
||||
"pio",
|
||||
"pio-proc",
|
||||
"rp-pico",
|
||||
"usb-device",
|
||||
"usbd-serial",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -616,7 +660,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76e09694b50f89f302ed531c1f2a7569f0be5867aee4ab4f8f729bbeec0078e3"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"num_enum",
|
||||
"num_enum 0.5.11",
|
||||
"paste",
|
||||
]
|
||||
|
||||
@@ -1042,10 +1086,23 @@ version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6"
|
||||
dependencies = [
|
||||
"heapless",
|
||||
"defmt 0.3.100",
|
||||
"heapless 0.8.0",
|
||||
"portable-atomic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "usbd-serial"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "065e4eaf93db81d5adac82d9cef8f8da314cb640fa7f89534b972383f1cf80fc"
|
||||
dependencies = [
|
||||
"embedded-hal 0.2.7",
|
||||
"embedded-io",
|
||||
"nb 1.1.0",
|
||||
"usb-device",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcell"
|
||||
version = "0.1.3"
|
||||
|
||||
41
Cargo.toml
41
Cargo.toml
@@ -9,13 +9,52 @@ test = false
|
||||
bench = false
|
||||
|
||||
[dependencies]
|
||||
cortex-m = "0.7"
|
||||
cortex-m = { version = "0.7", features = ["inline-asm"] }
|
||||
cortex-m-rt = "0.7"
|
||||
panic-probe = { version = "1.0", features = ["print-defmt", "defmt-error"] }
|
||||
rp-pico = "0.9"
|
||||
embedded-hal = "1.0"
|
||||
pio = "0.2"
|
||||
pio-proc = "0.2"
|
||||
usb-device = { version = "0.3", features = ["defmt"] }
|
||||
usbd-serial = "0.2"
|
||||
|
||||
defmt = "1.0"
|
||||
defmt-rtt = "1.1"
|
||||
|
||||
num_enum = { version = "0.7", default-features = false }
|
||||
heapless = "0.9"
|
||||
|
||||
# cargo build/run
|
||||
[profile.dev]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = true
|
||||
incremental = false
|
||||
opt-level = 3
|
||||
overflow-checks = true
|
||||
|
||||
# cargo build/run --release
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = false
|
||||
incremental = false
|
||||
lto = 'fat'
|
||||
opt-level = 3
|
||||
overflow-checks = false
|
||||
|
||||
# do not optimize proc-macro crates = faster builds from scratch
|
||||
[profile.dev.build-override]
|
||||
codegen-units = 8
|
||||
debug = false
|
||||
debug-assertions = false
|
||||
opt-level = 0
|
||||
overflow-checks = false
|
||||
|
||||
[profile.release.build-override]
|
||||
codegen-units = 8
|
||||
debug = false
|
||||
debug-assertions = false
|
||||
opt-level = 0
|
||||
overflow-checks = false
|
||||
|
||||
137
src/main.rs
137
src/main.rs
@@ -8,9 +8,14 @@
|
||||
//! GP26 => CE
|
||||
//! GP27 => OE
|
||||
|
||||
use core::cell::Cell;
|
||||
mod serial;
|
||||
|
||||
use cortex_m::{delay::Delay, interrupt::Mutex};
|
||||
use core::{
|
||||
cell::Cell,
|
||||
sync::atomic::{AtomicU8, Ordering},
|
||||
};
|
||||
|
||||
use cortex_m::{delay::Delay, interrupt::Mutex, singleton};
|
||||
use defmt_rtt as _;
|
||||
use embedded_hal::digital::OutputPin;
|
||||
use panic_probe as _;
|
||||
@@ -21,11 +26,16 @@ use rp_pico::{
|
||||
Sio, Watchdog,
|
||||
clocks::init_clocks_and_plls,
|
||||
gpio::{FunctionPio0, PullNone},
|
||||
pio::{PIO0SM0, PIO0SM3, PIOBuilder, PioIRQ, Rx, ShiftDirection, Tx},
|
||||
pio::{PIO0SM0, PIO0SM3, PIOBuilder, PioIRQ, Rx, Tx},
|
||||
prelude::*,
|
||||
usb::UsbBus,
|
||||
},
|
||||
pac::{self, CorePeripherals, Peripherals, interrupt},
|
||||
};
|
||||
use usb_device::{class_prelude::*, prelude::*};
|
||||
use usbd_serial::SerialPort;
|
||||
|
||||
use crate::serial::{Link, PacketBuilder};
|
||||
|
||||
const ADDRESS_BASE: u8 = 0;
|
||||
const ADDRESS_PINS: u8 = 15;
|
||||
@@ -35,13 +45,19 @@ const CE: u8 = 26;
|
||||
#[allow(unused)]
|
||||
const OE: u8 = 27;
|
||||
|
||||
const ROM_SIZE: usize = 1024 * 32;
|
||||
|
||||
static GLOBAL_ADDRESS_RX: Mutex<Cell<Option<Rx<PIO0SM3>>>> = Mutex::new(Cell::new(None));
|
||||
static GLOBAL_DATA_TX: Mutex<Cell<Option<Tx<PIO0SM0>>>> = Mutex::new(Cell::new(None));
|
||||
static ROM_DATA: [AtomicU8; ROM_SIZE] = [const { AtomicU8::new(0) }; ROM_SIZE];
|
||||
|
||||
static GLOBAL_USB_DEVICE: Mutex<Cell<Option<UsbDevice<UsbBus>>>> = Mutex::new(Cell::new(None));
|
||||
static GLOBAL_USB_SERIAL: Mutex<Cell<Option<SerialPort<UsbBus>>>> = Mutex::new(Cell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let mut pac = Peripherals::take().unwrap();
|
||||
let core = CorePeripherals::take().unwrap();
|
||||
let mut core = CorePeripherals::take().unwrap();
|
||||
|
||||
let mut watchdog = Watchdog::new(pac.WATCHDOG);
|
||||
|
||||
@@ -195,8 +211,37 @@ fn main() -> ! {
|
||||
address_rx.enable_rx_not_empty_interrupt(PioIRQ::Irq0);
|
||||
cortex_m::interrupt::free(|cs| GLOBAL_ADDRESS_RX.borrow(cs).set(Some(address_rx)));
|
||||
|
||||
let usbctrl_regs = pac.USBCTRL_REGS;
|
||||
let usbctrl_dpram = pac.USBCTRL_DPRAM;
|
||||
let resets = &mut pac.RESETS;
|
||||
let usb_bus = singleton!(: UsbBusAllocator<UsbBus> = UsbBusAllocator::new(UsbBus::new(
|
||||
usbctrl_regs,
|
||||
usbctrl_dpram,
|
||||
clocks.usb_clock,
|
||||
true,
|
||||
resets,
|
||||
)))
|
||||
.unwrap();
|
||||
let serial = SerialPort::new(usb_bus);
|
||||
cortex_m::interrupt::free(|cs| GLOBAL_USB_SERIAL.borrow(cs).set(Some(serial)));
|
||||
|
||||
let usb_dev = UsbDeviceBuilder::new(usb_bus, UsbVidPid(0x2e8a, 0x000a))
|
||||
.strings(&[StringDescriptors::default()
|
||||
.manufacturer("Max Känner")
|
||||
.product("PicoROM.rs")
|
||||
.serial_number("1")])
|
||||
.unwrap()
|
||||
.device_class(2)
|
||||
.build();
|
||||
cortex_m::interrupt::free(|cs| GLOBAL_USB_DEVICE.borrow(cs).set(Some(usb_dev)));
|
||||
|
||||
unsafe {
|
||||
// Highest priority for pio
|
||||
core.NVIC.set_priority(pac::interrupt::PIO0_IRQ_0, 0x00);
|
||||
// lowest priority for usb
|
||||
core.NVIC.set_priority(pac::interrupt::USBCTRL_IRQ, 0xFF);
|
||||
pac::NVIC::unmask(pac::interrupt::PIO0_IRQ_0);
|
||||
pac::NVIC::unmask(pac::interrupt::USBCTRL_IRQ);
|
||||
}
|
||||
|
||||
loop {
|
||||
@@ -220,12 +265,86 @@ fn PIO0_IRQ_0() {
|
||||
}
|
||||
|
||||
if let Some(address) = ADDRESS {
|
||||
while let Some(address) = address.read() {
|
||||
let address = (address & 0x7fff) as u16;
|
||||
if let Some(data) = DATA {
|
||||
defmt::trace!("replying with {:#04x} @ {:#06x}", address as u8, address);
|
||||
data.write(u32::from(address));
|
||||
while let Some(rx) = address.read() {
|
||||
let address = (rx & 0x7fff) as u16;
|
||||
if let Some(tx) = DATA {
|
||||
let data = ROM_DATA[usize::from(address)].load(Ordering::Relaxed);
|
||||
defmt::trace!("replying with {:#04x} @ {:#06x}", data, address);
|
||||
tx.write(u32::from(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn USBCTRL_IRQ() {
|
||||
static mut USB_DEVICE: Option<UsbDevice<UsbBus>> = None;
|
||||
static mut USB_SERIAL: Option<SerialPort<UsbBus>> = None;
|
||||
static mut DO_PREAMBLE: bool = true;
|
||||
static mut PACKET_BUILDER: PacketBuilder = PacketBuilder::new();
|
||||
static mut LINK: Link = Link::new();
|
||||
const PREAMBLE: &[u8] = b"PicoROM Hello";
|
||||
|
||||
if USB_DEVICE.is_none() {
|
||||
*USB_DEVICE = cortex_m::interrupt::free(|cs| GLOBAL_USB_DEVICE.borrow(cs).take());
|
||||
}
|
||||
|
||||
if USB_SERIAL.is_none() {
|
||||
*USB_SERIAL = cortex_m::interrupt::free(|cs| GLOBAL_USB_SERIAL.borrow(cs).take());
|
||||
}
|
||||
|
||||
let Some(usb_dev) = USB_DEVICE else { return };
|
||||
let Some(serial) = USB_SERIAL else { return };
|
||||
|
||||
if !serial.rts() {
|
||||
*DO_PREAMBLE = true;
|
||||
}
|
||||
if *DO_PREAMBLE && serial.rts() {
|
||||
match serial.write(PREAMBLE) {
|
||||
Ok(count) if count == PREAMBLE.len() => {
|
||||
*DO_PREAMBLE = false;
|
||||
defmt::info!("Send Preamble")
|
||||
}
|
||||
Ok(count) => {
|
||||
defmt::warn!(
|
||||
"Unable to write the whole preamble. Only wrote {} Bytes",
|
||||
count
|
||||
);
|
||||
}
|
||||
Err(UsbError::WouldBlock) => (),
|
||||
Err(e) => {
|
||||
defmt::error!("Unable to write preamble: {}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if usb_dev.poll(&mut [serial]) {
|
||||
let mut buf = [0u8; 64];
|
||||
match serial.read(&mut buf) {
|
||||
Ok(0) => {}
|
||||
Ok(count) => {
|
||||
for byte in buf.into_iter().take(count) {
|
||||
if let Some(packet) = PACKET_BUILDER.push(byte) {
|
||||
defmt::debug!("Got packet: {}", packet);
|
||||
if let Some(response) = LINK.handle_packet(&packet) {
|
||||
defmt::info!("Sending Response: {}", response);
|
||||
if let Err(e) = response.send(serial)
|
||||
&& e != UsbError::WouldBlock
|
||||
{
|
||||
defmt::error!("Unable to send response: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(UsbError::WouldBlock) => (),
|
||||
Err(e) => {
|
||||
defmt::error!("USB Error: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if usb_dev.state() == UsbDeviceState::Default {
|
||||
*DO_PREAMBLE = true;
|
||||
}
|
||||
}
|
||||
|
||||
280
src/serial.rs
Normal file
280
src/serial.rs
Normal file
@@ -0,0 +1,280 @@
|
||||
use core::{borrow::BorrowMut, sync::atomic::Ordering};
|
||||
|
||||
use defmt::Format;
|
||||
use heapless::{String, Vec};
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
use usb_device::{UsbError, bus::UsbBus};
|
||||
use usbd_serial::SerialPort;
|
||||
|
||||
use crate::ROM_DATA;
|
||||
|
||||
const MAX_PAYLOAD: u8 = 30;
|
||||
|
||||
#[derive(
|
||||
Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Format, TryFromPrimitive, IntoPrimitive,
|
||||
)]
|
||||
#[repr(u8)]
|
||||
pub enum Kind {
|
||||
PointerSet = 3,
|
||||
PointerGet = 4,
|
||||
PointerCur = 5,
|
||||
Write = 6,
|
||||
Read = 7,
|
||||
ReadData = 8,
|
||||
|
||||
CommitFlash = 12,
|
||||
CommitDone = 13,
|
||||
|
||||
ParameterSet = 20,
|
||||
ParameterGet = 21,
|
||||
Parameter = 22,
|
||||
ParameterError = 23,
|
||||
ParameterQuery = 24,
|
||||
|
||||
CommsStart = 80,
|
||||
CommsEnd = 81,
|
||||
CommsData = 82,
|
||||
|
||||
Identify = 0xf8,
|
||||
Bootsel = 0xf9,
|
||||
Error = 0xfe,
|
||||
Debug = 0xff,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct Packet {
|
||||
pub kind: Kind,
|
||||
pub payload: Vec<u8, { MAX_PAYLOAD as usize }>,
|
||||
}
|
||||
|
||||
impl Format for Packet {
|
||||
fn format(&self, fmt: defmt::Formatter) {
|
||||
defmt::write!(
|
||||
fmt,
|
||||
"Packet {{ kind: {}, payload: {:x}}}",
|
||||
self.kind,
|
||||
&self.payload[..]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl Packet {
|
||||
pub fn send(
|
||||
&self,
|
||||
serial: &mut SerialPort<impl UsbBus, impl BorrowMut<[u8]>, impl BorrowMut<[u8]>>,
|
||||
) -> Result<(), UsbError> {
|
||||
serial.write(&[
|
||||
self.kind.into(),
|
||||
u8::try_from(self.payload.len()).unwrap_or(MAX_PAYLOAD),
|
||||
])?;
|
||||
serial.write(&self.payload)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn error<const N: usize>(reason: &[u8; N]) -> Self {
|
||||
Self {
|
||||
kind: Kind::Error,
|
||||
payload: Vec::from_array(*reason),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum PacketBuilder {
|
||||
Idle,
|
||||
Kind {
|
||||
kind: Kind,
|
||||
},
|
||||
Payload {
|
||||
kind: Kind,
|
||||
target_size: u8,
|
||||
payload: Vec<u8, { MAX_PAYLOAD as usize }>,
|
||||
},
|
||||
}
|
||||
|
||||
impl PacketBuilder {
|
||||
pub const fn new() -> Self {
|
||||
Self::Idle
|
||||
}
|
||||
|
||||
pub fn push(&mut self, byte: u8) -> Option<Packet> {
|
||||
match self {
|
||||
Self::Idle => {
|
||||
let kind = Kind::try_from(byte).ok()?;
|
||||
*self = Self::Kind { kind };
|
||||
}
|
||||
Self::Kind { kind } => {
|
||||
let target_size = byte;
|
||||
let kind = *kind;
|
||||
match target_size {
|
||||
0 => {
|
||||
*self = Self::Idle;
|
||||
return Some(Packet {
|
||||
kind,
|
||||
payload: Vec::new(),
|
||||
});
|
||||
}
|
||||
1..=MAX_PAYLOAD => {
|
||||
*self = Self::Payload {
|
||||
kind,
|
||||
target_size,
|
||||
payload: Vec::new(),
|
||||
};
|
||||
}
|
||||
_ => {
|
||||
*self = Self::Idle;
|
||||
}
|
||||
}
|
||||
}
|
||||
Self::Payload {
|
||||
kind,
|
||||
target_size,
|
||||
payload,
|
||||
} => {
|
||||
payload.push(byte).unwrap();
|
||||
if payload.len() >= usize::from(*target_size) {
|
||||
let kind = *kind;
|
||||
let payload = payload.clone();
|
||||
*self = Self::Idle;
|
||||
return Some(Packet { kind, payload });
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Link {
|
||||
pointer: u32,
|
||||
name: String<{ MAX_PAYLOAD as usize }>,
|
||||
rom_name: String<{ MAX_PAYLOAD as usize }>,
|
||||
}
|
||||
|
||||
impl Link {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
pointer: 0,
|
||||
name: String::new(),
|
||||
rom_name: String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_packet(&mut self, packet: &Packet) -> Option<Packet> {
|
||||
if self.name.is_empty() {
|
||||
let _ = self.name.push_str("rom");
|
||||
}
|
||||
match packet.kind {
|
||||
Kind::PointerSet => {
|
||||
if packet.payload.len() != 4 {
|
||||
return Some(Packet::error(b"Invalid pointer length"));
|
||||
}
|
||||
self.pointer = u32::from_le_bytes(packet.payload[..].try_into().unwrap());
|
||||
defmt::info!("Set pointer to {:#010x}", self.pointer);
|
||||
None
|
||||
}
|
||||
Kind::PointerGet => Some(Packet {
|
||||
kind: Kind::PointerCur,
|
||||
payload: Vec::from_array(self.pointer.to_le_bytes()),
|
||||
}),
|
||||
Kind::Write => {
|
||||
for byte in &packet.payload {
|
||||
let Some(target) = ROM_DATA.get(self.pointer as usize) else {
|
||||
self.pointer += 1;
|
||||
// return Some(Packet::error(b"Write out of range"));
|
||||
continue;
|
||||
};
|
||||
target.store(*byte, Ordering::Relaxed);
|
||||
self.pointer += 1;
|
||||
}
|
||||
None
|
||||
}
|
||||
Kind::ParameterGet => match &packet.payload[..] {
|
||||
b"name\0" => Some(Packet {
|
||||
kind: Kind::Parameter,
|
||||
payload: self.name.clone().into_bytes(),
|
||||
}),
|
||||
b"addr_mask\0" => Some(Packet {
|
||||
kind: Kind::Parameter,
|
||||
payload: Vec::from_array(*b"0x7fff"),
|
||||
}),
|
||||
b"rom_name\0" => Some(Packet {
|
||||
kind: Kind::Parameter,
|
||||
payload: self.rom_name.clone().into_bytes(),
|
||||
}),
|
||||
payload => {
|
||||
if let Ok(name) = str::from_utf8(payload) {
|
||||
defmt::warn!("Got unknonwn parameter request: {}", name);
|
||||
} else {
|
||||
defmt::warn!("Got unknonw parameter request: {}", payload);
|
||||
}
|
||||
Some(Packet {
|
||||
kind: Kind::ParameterError,
|
||||
payload: Vec::new(),
|
||||
})
|
||||
}
|
||||
},
|
||||
Kind::ParameterSet => {
|
||||
let mut parts = packet.payload.split(|b| *b == b',');
|
||||
let Some(name) = parts.next() else {
|
||||
return Some(Packet {
|
||||
kind: Kind::ParameterError,
|
||||
payload: Vec::new(),
|
||||
});
|
||||
};
|
||||
let Some(value) = parts.next() else {
|
||||
return Some(Packet {
|
||||
kind: Kind::ParameterError,
|
||||
payload: Vec::new(),
|
||||
});
|
||||
};
|
||||
match name {
|
||||
b"name" => {
|
||||
let Ok(value) = str::from_utf8(value) else {
|
||||
return Some(Packet {
|
||||
kind: Kind::ParameterError,
|
||||
payload: Vec::new(),
|
||||
});
|
||||
};
|
||||
self.name.clear();
|
||||
let _ = self.name.push_str(value);
|
||||
Some(Packet {
|
||||
kind: Kind::Parameter,
|
||||
payload: self.name.clone().into_bytes(),
|
||||
})
|
||||
}
|
||||
b"addr_mask" => Some(Packet {
|
||||
kind: Kind::Parameter,
|
||||
payload: Vec::from_array(*b"0x7fff"),
|
||||
}),
|
||||
b"rom_name" => {
|
||||
let Ok(value) = str::from_utf8(value) else {
|
||||
return Some(Packet {
|
||||
kind: Kind::ParameterError,
|
||||
payload: Vec::new(),
|
||||
});
|
||||
};
|
||||
self.rom_name.clear();
|
||||
let _ = self.rom_name.push_str(value);
|
||||
Some(Packet {
|
||||
kind: Kind::Parameter,
|
||||
payload: self.rom_name.clone().into_bytes(),
|
||||
})
|
||||
}
|
||||
payload => {
|
||||
if let Ok(name) = str::from_utf8(payload) {
|
||||
defmt::warn!("Got unknonwn parameter request: {}", name);
|
||||
} else {
|
||||
defmt::warn!("Got unknonw parameter request: {}", payload);
|
||||
}
|
||||
Some(Packet {
|
||||
kind: Kind::ParameterError,
|
||||
payload: Vec::new(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => Some(Packet::error(b"Unrecognized packet")),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user