From ded4945457689963f5e7f9d5ec401e487a560651 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Fri, 13 Oct 2023 13:32:11 +0200 Subject: [PATCH 1/4] Adding basic USB implementation --- Cargo.lock | 39 ++++++++++++++++++ Cargo.toml | 5 ++- src/bin/dual-iir.rs | 13 ++++++ src/hardware/mod.rs | 3 ++ src/hardware/serial_terminal.rs | 71 ++++++++++++++++++++++++++++++++ src/hardware/setup.rs | 73 +++++++++++++++++++++++++++++++-- 6 files changed, 200 insertions(+), 4 deletions(-) create mode 100644 src/hardware/serial_terminal.rs diff --git a/Cargo.lock b/Cargo.lock index 3a2832ef8..8fd778b34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,6 +72,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" +[[package]] +name = "bbqueue" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3baa8859d1a4c7411039a75c0599a4640ef1c9a8fc811e4325b00e6cfe0a55" + [[package]] name = "bit_field" version = "0.10.2" @@ -890,6 +896,7 @@ name = "stabilizer" version = "0.8.1" dependencies = [ "ad9959", + "bbqueue", "cortex-m 0.7.7", "cortex-m-rt", "cortex-m-rtic", @@ -918,6 +925,8 @@ dependencies = [ "spin", "stm32h7xx-hal", "systick-monotonic", + "usb-device", + "usbd-serial", ] [[package]] @@ -954,6 +963,7 @@ dependencies = [ "paste", "smoltcp", "stm32h7", + "synopsys-usb-otg", "void", ] @@ -979,6 +989,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synopsys-usb-otg" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678f3707a7b1fd4863023292c42f73c6bab0e9b0096f41ae612d1af0ff221b45" +dependencies = [ + "cortex-m 0.7.7", + "embedded-hal", + "usb-device", + "vcell", +] + [[package]] name = "systick-monotonic" version = "1.0.1" @@ -1008,6 +1030,23 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +[[package]] +name = "usb-device" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f6cc3adc849b5292b4075fc0d5fdcf2f24866e88e336dd27a8943090a520508" + +[[package]] +name = "usbd-serial" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db75519b86287f12dcf0d171c7cf4ecc839149fe9f3b720ac4cfce52959e1dfe" +dependencies = [ + "embedded-hal", + "nb 0.1.3", + "usb-device", +] + [[package]] name = "varint-rs" version = "2.2.0" diff --git a/Cargo.toml b/Cargo.toml index 8a484c784..adb694c63 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,13 +60,16 @@ enum-iterator = "1.4.1" rand_xorshift = "0.3.0" rand_core = "0.6.4" minimq = { git = "https://github.com/quartiq/minimq" } # "0.8" +usb-device = "0.2.9" +usbd-serial = "0.1.1" # Keep this synced with the miniconf version in py/setup.py miniconf = { git = "https://github.com/quartiq/miniconf.git" } # "0.9" smoltcp-nal = { version = "0.4.1", features = ["shared-stack"]} +bbqueue = "0.5" [dependencies.stm32h7xx-hal] git = "https://github.com/stm32-rs/stm32h7xx-hal" -features = ["stm32h743v", "rt", "ethernet", "xspi"] +features = ["stm32h743v", "rt", "ethernet", "xspi", "usb_hs"] [features] nightly = [ ] diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index 8a6918acc..afb2e262e 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -40,6 +40,7 @@ use idsp::iir; use stabilizer::{ hardware::{ self, + serial_terminal::SerialTerminal, adc::{Adc0Input, Adc1Input, AdcCode}, afe::Gain, dac::{Dac0Output, Dac1Output, DacCode}, @@ -191,6 +192,7 @@ mod app { #[local] struct Local { + usb_terminal: SerialTerminal, sampling_timer: SamplingTimer, digital_inputs: (DigitalInput0, DigitalInput1), afes: (AFE0, AFE1), @@ -246,6 +248,7 @@ mod app { }; let mut local = Local { + usb_terminal: stabilizer.usb_serial, sampling_timer: stabilizer.adc_dac_timer, digital_inputs: stabilizer.digital_inputs, afes: stabilizer.afes, @@ -266,6 +269,7 @@ mod app { settings_update::spawn().unwrap(); telemetry::spawn().unwrap(); ethernet_link::spawn().unwrap(); + usb::spawn().unwrap(); start::spawn_after(100.millis()).unwrap(); (shared, local, init::Monotonics(stabilizer.systick)) @@ -452,6 +456,15 @@ mod app { .unwrap(); } + #[task(priority = 1, local=[usb_terminal])] + fn usb(c: usb::Context) { + // Handle the USB serial terminal. + c.local.usb_terminal.process(); + + // Schedule to run this task every 10ms. + usb::spawn_after(10u64.millis()).unwrap(); + } + #[task(priority = 1, shared=[network])] fn ethernet_link(mut c: ethernet_link::Context) { c.shared.network.lock(|net| net.processor.handle_link()); diff --git a/src/hardware/mod.rs b/src/hardware/mod.rs index a2745208a..3f58bb8e5 100644 --- a/src/hardware/mod.rs +++ b/src/hardware/mod.rs @@ -11,6 +11,7 @@ pub mod delay; pub mod design_parameters; pub mod input_stamper; pub mod pounder; +pub mod serial_terminal; pub mod setup; pub mod shared_adc; pub mod signal_generator; @@ -30,6 +31,8 @@ pub type AFE1 = afe::ProgrammableGainAmplifier< hal::gpio::gpiod::PD15>, >; +pub type UsbBus = stm32h7xx_hal::usb_hs::UsbBus; + // Type alias for digital input 0 (DI0). pub type DigitalInput0 = hal::gpio::gpiog::PG9; diff --git a/src/hardware/serial_terminal.rs b/src/hardware/serial_terminal.rs new file mode 100644 index 000000000..b7c7aa26a --- /dev/null +++ b/src/hardware/serial_terminal.rs @@ -0,0 +1,71 @@ +use super::UsbBus; + +static OUTPUT_BUFFER: bbqueue::BBBuffer<1024> = bbqueue::BBBuffer::new(); + +pub struct SerialTerminal { + usb_device: usb_device::device::UsbDevice<'static, UsbBus>, + usb_serial: usbd_serial::SerialPort<'static, UsbBus>, + output: bbqueue::Consumer<'static, 1024>, +} + +impl SerialTerminal { + pub fn new( + usb_device: usb_device::device::UsbDevice<'static, UsbBus>, + usb_serial: usbd_serial::SerialPort<'static, UsbBus>, + ) -> Self { + let (_producer, consumer) = OUTPUT_BUFFER.try_split().unwrap(); + + Self { + usb_device, + usb_serial, + output: consumer, + } + } + + fn flush(&mut self) { + let read = match self.output.read() { + Ok(grant) => grant, + Err(bbqueue::Error::InsufficientSize) => return, + err => err.unwrap(), + }; + + match self.usb_serial.write(read.buf()) { + Ok(count) => read.release(count), + Err(usbd_serial::UsbError::WouldBlock) => read.release(0), + Err(_) => { + let len = read.buf().len(); + read.release(len); + } + } + } + + pub fn process(&mut self) { + self.flush(); + + if !self.usb_device.poll(&mut [&mut self.usb_serial]) { + return; + } + + let mut buffer = [0u8; 64]; + match self.usb_serial.read(&mut buffer) { + Ok(count) => { + for &value in &buffer[..count] { + // Currently, just echo it back. + self.usb_serial.write(&[value]).ok(); + } + } + + Err(usbd_serial::UsbError::WouldBlock) => {} + Err(_) => { + // Flush the output buffer if USB is not connected. + self.output + .read() + .map(|grant| { + let len = grant.buf().len(); + grant.release(len); + }) + .ok(); + } + } + } +} diff --git a/src/hardware/setup.rs b/src/hardware/setup.rs index a8b52e7ad..186bf03c6 100644 --- a/src/hardware/setup.rs +++ b/src/hardware/setup.rs @@ -2,7 +2,7 @@ //! //! This file contains all of the hardware-specific configuration of Stabilizer. use core::sync::atomic::{self, AtomicBool, Ordering}; -use core::{ptr, slice}; +use core::{fmt::Write, ptr, slice}; use stm32h7xx_hal::{ self as hal, ethernet::{self, PHY}, @@ -18,7 +18,7 @@ use super::{ pounder::dds_output::DdsOutput, shared_adc::SharedAdc, timers, DigitalInput0, DigitalInput1, EemDigitalInput0, EemDigitalInput1, EemDigitalOutput0, EemDigitalOutput1, EthernetPhy, NetworkStack, - SystemTimer, Systick, AFE0, AFE1, + SystemTimer, Systick, UsbBus, AFE0, AFE1, serial_terminal::SerialTerminal, }; const NUM_TCP_SOCKETS: usize = 4; @@ -117,6 +117,7 @@ pub struct StabilizerDevices { pub net: NetworkDevices, pub digital_inputs: (DigitalInput0, DigitalInput1), pub eem_gpio: EemGpioDevices, + pub usb_serial: SerialTerminal, } /// The available Pounder-specific hardware interfaces. @@ -266,7 +267,7 @@ pub fn setup( device.RCC.d3ccipr.modify(|_, w| w.adcsel().per()); let rcc = device.RCC.constrain(); - let ccdr = rcc + let mut ccdr = rcc .use_hse(8.MHz()) .sysclk(design_parameters::SYSCLK.convert()) .hclk(200.MHz()) @@ -275,6 +276,11 @@ pub fn setup( .pll2_q_ck(100.MHz()) .freeze(vos, &device.SYSCFG); + // Set up USB clocks. + ccdr.clocks.hsi48_ck().unwrap(); + ccdr.peripheral + .kernel_usb_clk_mux(stm32h7xx_hal::rcc::rec::UsbClkSel::Hsi48); + // Before being able to call any code in ITCM, load that code from flash. load_itcm(); @@ -1003,6 +1009,66 @@ pub fn setup( lvds7: gpiod.pd4.into_push_pull_output(), }; + let (usb_device, usb_serial) = { + let usb_bus = cortex_m::singleton!(: Option> = None).unwrap(); + let endpoint_memory = + cortex_m::singleton!(: [u32; 1024] = [0; 1024]).unwrap(); + + //let usb_id = gpioa.pa10.into_alternate::<8>(); + let usb_n = gpioa.pa11.into_alternate(); + let usb_p = gpioa.pa12.into_alternate(); + + let usb = stm32h7xx_hal::usb_hs::USB2::new( + device.OTG2_HS_GLOBAL, + device.OTG2_HS_DEVICE, + device.OTG2_HS_PWRCLK, + usb_n, + usb_p, + ccdr.peripheral.USB2OTG, + &ccdr.clocks, + ); + + // Generate a device serial number from the MAC address. + let serial_number = + cortex_m::singleton!(: Option> = None) + .unwrap(); + { + let mut serial_string: heapless::String<64> = heapless::String::new(); + let octets = mac_addr.0; + + write!( + serial_string, + "{:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}", + octets[0], + octets[1], + octets[2], + octets[3], + octets[4], + octets[5] + ) + .unwrap(); + serial_number.replace(serial_string); + } + + usb_bus.replace(stm32h7xx_hal::usb_hs::UsbBus::new( + usb, + &mut endpoint_memory[..], + )); + + let serial = usbd_serial::SerialPort::new(usb_bus.as_ref().unwrap()); + let usb_device = usb_device::device::UsbDeviceBuilder::new( + usb_bus.as_ref().unwrap(), + usb_device::device::UsbVidPid(0x1209, 0x392F), + ) + .manufacturer("ARTIQ/Sinara") + .product("Stabilizer") + .serial_number(serial_number.as_ref().unwrap()) + .device_class(usbd_serial::USB_CLASS_CDC) + .build(); + + (usb_device, serial) + }; + let stabilizer = StabilizerDevices { systick, afes, @@ -1017,6 +1083,7 @@ pub fn setup( timestamp_timer, digital_inputs, eem_gpio, + usb_serial: SerialTerminal::new(usb_device, usb_serial), }; // info!("Version {} {}", build_info::PKG_VERSION, build_info::GIT_VERSION.unwrap()); From 8e0445279827535239e4fab41fb506a73d384441 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Fri, 13 Oct 2023 17:18:22 +0200 Subject: [PATCH 2/4] Fixing USB support --- Cargo.lock | 3 +-- Cargo.toml | 4 ++++ src/bin/dual-iir.rs | 26 +++++++++++++++++--------- src/bin/lockin.rs | 24 ++++++++++++++++++++++-- src/hardware/serial_terminal.rs | 6 ++++++ src/hardware/setup.rs | 11 ++++++----- 6 files changed, 56 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8fd778b34..65a95d45a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1033,8 +1033,7 @@ checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "usb-device" version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f6cc3adc849b5292b4075fc0d5fdcf2f24866e88e336dd27a8943090a520508" +source = "git+https://github.com/ryan-summers/usb-device?branch=rs/issue-128-v0.2.9#59a02aaedd385d29d896f07fe977bff1f8963eb2" [[package]] name = "usbd-serial" diff --git a/Cargo.toml b/Cargo.toml index adb694c63..6c9c67961 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,6 +71,10 @@ bbqueue = "0.5" git = "https://github.com/stm32-rs/stm32h7xx-hal" features = ["stm32h743v", "rt", "ethernet", "xspi", "usb_hs"] +[patch.crates-io.usb-device] +git = "https://github.com/ryan-summers/usb-device" +branch = "rs/issue-128-v0.2.9" + [features] nightly = [ ] pounder_v1_0 = [ ] diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index afb2e262e..5c27e50d4 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -40,11 +40,11 @@ use idsp::iir; use stabilizer::{ hardware::{ self, - serial_terminal::SerialTerminal, adc::{Adc0Input, Adc1Input, AdcCode}, afe::Gain, dac::{Dac0Output, Dac1Output, DacCode}, hal, + serial_terminal::SerialTerminal, signal_generator::{self, SignalGenerator}, timers::SamplingTimer, DigitalInput0, DigitalInput1, SystemTimer, Systick, AFE0, AFE1, @@ -183,6 +183,7 @@ mod app { #[shared] struct Shared { + usb_terminal: SerialTerminal, network: NetworkUsers, settings: Settings, @@ -192,7 +193,6 @@ mod app { #[local] struct Local { - usb_terminal: SerialTerminal, sampling_timer: SamplingTimer, digital_inputs: (DigitalInput0, DigitalInput1), afes: (AFE0, AFE1), @@ -230,6 +230,7 @@ mod app { let settings = Settings::default(); let shared = Shared { + usb_terminal: stabilizer.usb_serial, network, settings, telemetry: TelemetryBuffer::default(), @@ -248,7 +249,6 @@ mod app { }; let mut local = Local { - usb_terminal: stabilizer.usb_serial, sampling_timer: stabilizer.adc_dac_timer, digital_inputs: stabilizer.digital_inputs, afes: stabilizer.afes, @@ -392,7 +392,7 @@ mod app { ); } - #[idle(shared=[network])] + #[idle(shared=[network, usb_terminal])] fn idle(mut c: idle::Context) -> ! { loop { match c.shared.network.lock(|net| net.update()) { @@ -400,7 +400,15 @@ mod app { settings_update::spawn().unwrap() } NetworkState::Updated => {} - NetworkState::NoChange => cortex_m::asm::wfi(), + NetworkState::NoChange => { + // We can't sleep if USB is not in suspend. + if c.shared + .usb_terminal + .lock(|terminal| terminal.usb_is_suspended()) + { + cortex_m::asm::wfi(); + } + } } } } @@ -456,12 +464,12 @@ mod app { .unwrap(); } - #[task(priority = 1, local=[usb_terminal])] - fn usb(c: usb::Context) { + #[task(priority = 1, shared=[usb_terminal])] + fn usb(mut c: usb::Context) { // Handle the USB serial terminal. - c.local.usb_terminal.process(); + c.shared.usb_terminal.lock(|usb| usb.process()); - // Schedule to run this task every 10ms. + // Schedule to run this task every 10 milliseconds. usb::spawn_after(10u64.millis()).unwrap(); } diff --git a/src/bin/lockin.rs b/src/bin/lockin.rs index f44872228..a116b4da1 100644 --- a/src/bin/lockin.rs +++ b/src/bin/lockin.rs @@ -47,6 +47,7 @@ use stabilizer::{ dac::{Dac0Output, Dac1Output, DacCode}, hal, input_stamper::InputStamper, + serial_terminal::SerialTerminal, signal_generator, timers::SamplingTimer, DigitalInput0, DigitalInput1, SystemTimer, Systick, AFE0, AFE1, @@ -221,6 +222,7 @@ mod app { #[shared] struct Shared { + usb_terminal: SerialTerminal, network: NetworkUsers, settings: Settings, telemetry: TelemetryBuffer, @@ -267,6 +269,7 @@ mod app { let shared = Shared { network, + usb_terminal: stabilizer.usb_serial, telemetry: TelemetryBuffer::default(), settings: Settings::default(), }; @@ -451,7 +454,7 @@ mod app { }); } - #[idle(shared=[network])] + #[idle(shared=[network, usb_terminal])] fn idle(mut c: idle::Context) -> ! { loop { match c.shared.network.lock(|net| net.update()) { @@ -459,7 +462,15 @@ mod app { settings_update::spawn().unwrap() } NetworkState::Updated => {} - NetworkState::NoChange => cortex_m::asm::wfi(), + NetworkState::NoChange => { + // We can't sleep if USB is not in suspend. + if c.shared + .usb_terminal + .lock(|terminal| terminal.usb_is_suspended()) + { + cortex_m::asm::wfi(); + } + } } } } @@ -504,6 +515,15 @@ mod app { .unwrap(); } + #[task(priority = 1, shared=[usb_terminal])] + fn usb(mut c: usb::Context) { + // Handle the USB serial terminal. + c.shared.usb_terminal.lock(|usb| usb.process()); + + // Schedule to run this task every 10 milliseconds. + usb::spawn_after(10u64.millis()).unwrap(); + } + #[task(priority = 1, shared=[network])] fn ethernet_link(mut c: ethernet_link::Context) { c.shared.network.lock(|net| net.processor.handle_link()); diff --git a/src/hardware/serial_terminal.rs b/src/hardware/serial_terminal.rs index b7c7aa26a..bc82a00c0 100644 --- a/src/hardware/serial_terminal.rs +++ b/src/hardware/serial_terminal.rs @@ -39,6 +39,10 @@ impl SerialTerminal { } } + pub fn usb_is_suspended(&self) -> bool { + self.usb_device.state() == usb_device::device::UsbDeviceState::Suspend + } + pub fn process(&mut self) { self.flush(); @@ -51,7 +55,9 @@ impl SerialTerminal { Ok(count) => { for &value in &buffer[..count] { // Currently, just echo it back. + self.usb_serial.write(b"echo: ").ok(); self.usb_serial.write(&[value]).ok(); + self.usb_serial.write(b"\n\r").ok(); } } diff --git a/src/hardware/setup.rs b/src/hardware/setup.rs index 186bf03c6..02f0c694b 100644 --- a/src/hardware/setup.rs +++ b/src/hardware/setup.rs @@ -15,10 +15,10 @@ use smoltcp_nal::smoltcp; use super::{ adc, afe, cpu_temp_sensor::CpuTempSensor, dac, delay, design_parameters, eeprom, input_stamper::InputStamper, pounder, - pounder::dds_output::DdsOutput, shared_adc::SharedAdc, timers, - DigitalInput0, DigitalInput1, EemDigitalInput0, EemDigitalInput1, - EemDigitalOutput0, EemDigitalOutput1, EthernetPhy, NetworkStack, - SystemTimer, Systick, UsbBus, AFE0, AFE1, serial_terminal::SerialTerminal, + pounder::dds_output::DdsOutput, serial_terminal::SerialTerminal, + shared_adc::SharedAdc, timers, DigitalInput0, DigitalInput1, + EemDigitalInput0, EemDigitalInput1, EemDigitalOutput0, EemDigitalOutput1, + EthernetPhy, NetworkStack, SystemTimer, Systick, UsbBus, AFE0, AFE1, }; const NUM_TCP_SOCKETS: usize = 4; @@ -1033,7 +1033,8 @@ pub fn setup( cortex_m::singleton!(: Option> = None) .unwrap(); { - let mut serial_string: heapless::String<64> = heapless::String::new(); + let mut serial_string: heapless::String<64> = + heapless::String::new(); let octets = mac_addr.0; write!( From 2bd057c35fc9230293f612668f01fc5aff581371 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Mon, 16 Oct 2023 11:33:22 +0200 Subject: [PATCH 3/4] Updating serial after review --- src/hardware/serial_terminal.rs | 48 ++++++++++++++++++++++----------- src/hardware/setup.rs | 4 +-- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/hardware/serial_terminal.rs b/src/hardware/serial_terminal.rs index bc82a00c0..a9b8b5139 100644 --- a/src/hardware/serial_terminal.rs +++ b/src/hardware/serial_terminal.rs @@ -1,11 +1,34 @@ use super::UsbBus; +use core::fmt::Write; -static OUTPUT_BUFFER: bbqueue::BBBuffer<1024> = bbqueue::BBBuffer::new(); +static OUTPUT_BUFFER: bbqueue::BBBuffer<512> = bbqueue::BBBuffer::new(); + +pub struct OutputBuffer { + producer: bbqueue::Producer<'static, 512>, +} + +impl Write for OutputBuffer { + fn write_str(&mut self, s: &str) -> core::fmt::Result { + let data = s.as_bytes(); + + // Write as much data as possible to the output buffer. + let Ok(mut grant) = self.producer.grant_max_remaining(data.len()) else { + // Output buffer is full, silently drop the data. + return Ok(()); + }; + + let len = grant.buf().len(); + grant.buf().copy_from_slice(&data[..len]); + grant.commit(len); + Ok(()) + } +} pub struct SerialTerminal { usb_device: usb_device::device::UsbDevice<'static, UsbBus>, usb_serial: usbd_serial::SerialPort<'static, UsbBus>, - output: bbqueue::Consumer<'static, 1024>, + output: bbqueue::Consumer<'static, 512>, + buffer: OutputBuffer, } impl SerialTerminal { @@ -13,9 +36,10 @@ impl SerialTerminal { usb_device: usb_device::device::UsbDevice<'static, UsbBus>, usb_serial: usbd_serial::SerialPort<'static, UsbBus>, ) -> Self { - let (_producer, consumer) = OUTPUT_BUFFER.try_split().unwrap(); + let (producer, consumer) = OUTPUT_BUFFER.try_split().unwrap(); Self { + buffer: OutputBuffer { producer }, usb_device, usb_serial, output: consumer, @@ -54,23 +78,17 @@ impl SerialTerminal { match self.usb_serial.read(&mut buffer) { Ok(count) => { for &value in &buffer[..count] { - // Currently, just echo it back. - self.usb_serial.write(b"echo: ").ok(); - self.usb_serial.write(&[value]).ok(); - self.usb_serial.write(b"\n\r").ok(); + writeln!(self.buffer, "echo: {}", value as char).unwrap(); } } Err(usbd_serial::UsbError::WouldBlock) => {} Err(_) => { - // Flush the output buffer if USB is not connected. - self.output - .read() - .map(|grant| { - let len = grant.buf().len(); - grant.release(len); - }) - .ok(); + // Clear the output buffer if USB is not connected. + while let Ok(grant) = self.output.read() { + let len = grant.buf().len(); + grant.release(len); + } } } } diff --git a/src/hardware/setup.rs b/src/hardware/setup.rs index 02f0c694b..0873aca43 100644 --- a/src/hardware/setup.rs +++ b/src/hardware/setup.rs @@ -1030,10 +1030,10 @@ pub fn setup( // Generate a device serial number from the MAC address. let serial_number = - cortex_m::singleton!(: Option> = None) + cortex_m::singleton!(: Option> = None) .unwrap(); { - let mut serial_string: heapless::String<64> = + let mut serial_string: heapless::String<17> = heapless::String::new(); let octets = mac_addr.0; From 1a50dbdc7ad073158aa5a0214816b904bbf26a60 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Mon, 16 Oct 2023 11:44:20 +0200 Subject: [PATCH 4/4] Fixing format --- src/hardware/serial_terminal.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/serial_terminal.rs b/src/hardware/serial_terminal.rs index a9b8b5139..649ad2836 100644 --- a/src/hardware/serial_terminal.rs +++ b/src/hardware/serial_terminal.rs @@ -12,7 +12,8 @@ impl Write for OutputBuffer { let data = s.as_bytes(); // Write as much data as possible to the output buffer. - let Ok(mut grant) = self.producer.grant_max_remaining(data.len()) else { + let Ok(mut grant) = self.producer.grant_max_remaining(data.len()) + else { // Output buffer is full, silently drop the data. return Ok(()); };