From 81723e2bbd849f89dc96d3b0612c75295126c376 Mon Sep 17 00:00:00 2001 From: Jonathan Herbst Date: Fri, 4 Oct 2024 13:38:01 -0400 Subject: [PATCH 01/13] starting uart, doesn't work --- Cargo.toml | 2 +- src/bin/app.rs | 20 ++++++++++++++++++++ src/lib.rs | 1 + src/setup.rs | 15 +++++++++++---- src/uart.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/usb.rs | 41 +++++++++++++++++++++++++++++++---------- 6 files changed, 108 insertions(+), 15 deletions(-) create mode 100644 src/uart.rs diff --git a/Cargo.toml b/Cargo.toml index d17c792..dc899c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ rp2040-boot2 = "0.2.1" defmt-brtt = { version = "0.1.0", default-features = false } # We don't need bbqueue directly, but we need to activate the # thumbv6 feature on it so it will compile. -bbqueue = { version = "0.5", features = ["thumbv6"], optional = true } +bbqueue = { version = "0.5", features = ["thumbv6"] } [features] default = [ "defmt-brtt/rtt", "gnddetect" ] diff --git a/src/bin/app.rs b/src/bin/app.rs index ae27dd7..5304d21 100644 --- a/src/bin/app.rs +++ b/src/bin/app.rs @@ -10,6 +10,7 @@ mod app { use pico_probe::{ leds::{LedManager, Vtarget}, setup::*, + uart::Config as UartConfig, }; use rp2040_hal::usb::UsbBus; use usb_device::class_prelude::*; @@ -23,6 +24,7 @@ mod app { #[local] struct Local { + uart: Uart, dap_handler: DapHandler, target_vcc: TargetVccReader, translator_power: TranslatorPower, @@ -38,6 +40,7 @@ mod app { let ( leds, probe_usb, + mut uart, dap_handler, target_vcc, translator_power, @@ -45,6 +48,8 @@ mod app { target_physically_connected, ) = setup(cx.device, cx.core, cx.local.usb_bus, cx.local.delay); + uart.configure(UartConfig::default()); + voltage_translator_control::spawn().ok(); #[cfg(feature = "defmt-bbq")] @@ -55,6 +60,7 @@ mod app { ( Shared { probe_usb }, Local { + uart, dap_handler, target_vcc, translator_power, @@ -148,4 +154,18 @@ mod app { } }); } + + #[task(binds = UART1_IRQ, priority = 2, shared = [probe_usb], local = [uart])] + fn on_uart_rx(ctx: on_uart_rx::Context) { + let mut probe_usb = ctx.shared.probe_usb; + let uart = ctx.local.uart; + + let mut uart_buf = [0u8; 32]; + let read_size = uart.read(&mut uart_buf); + if read_size > 0 { + probe_usb.lock(|probe_usb| { + probe_usb.serial_write(&uart_buf[..read_size]); + }); + } + } } diff --git a/src/lib.rs b/src/lib.rs index a9ff11f..b82e5af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,6 +13,7 @@ pub mod leds; pub mod pio; pub mod setup; pub mod systick_delay; +pub mod uart; pub mod usb; defmt::timestamp! {"{=u64:us}", { diff --git a/src/setup.rs b/src/setup.rs index e18091b..d347dce 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -33,6 +33,9 @@ pub type DapHandler = dap_rs::dap::Dap<'static, Context, HostStatusToken, Wait, #[used] pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; +type UartPins = (Pin, Pin); +pub type Uart = crate::uart::Uart; + #[inline(always)] pub fn setup( pac: pac::Peripherals, @@ -42,6 +45,7 @@ pub fn setup( ) -> ( LedManager, ProbeUsb, + Uart, DapHandler, TargetVccReader, TranslatorPower, @@ -95,6 +99,10 @@ pub fn setup( let sio = Sio::new(pac.SIO); let pins = Pins::new(pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut resets); + let uart = Uart::new(pac.UART1, (pins.gpio20.into_mode(), pins.gpio21.into_mode()), clocks.peripheral_clock.freq(), &mut resets); + let _dir_vcp_rx = pins.gpio25.into_push_pull_output_in_state(false.into()); + let _dir_vcp_tx = pins.gpio24.into_push_pull_output_in_state(true.into()); + let mut led_green = pins.gpio27.into_push_pull_output(); led_green.set_high().ok(); let mut led_red = pins.gpio28.into_push_pull_output(); @@ -158,10 +166,8 @@ pub fn setup( let _tdi = pins.gpio17; let _dir_tdi = pins.gpio23; - let _vcp_rx = pins.gpio21; - let _vcp_tx = pins.gpio20; - let _dir_vcp_rx = pins.gpio25; - let _dir_vcp_tx = pins.gpio24; + // let _vcp_rx = pins.gpio21; + // let _vcp_tx = pins.gpio20; // High speed IO io.set_drive_strength(OutputDriveStrength::TwelveMilliAmps); @@ -199,6 +205,7 @@ pub fn setup( ( led_manager, probe_usb, + uart, dap_hander, adc, translator_power, diff --git a/src/uart.rs b/src/uart.rs new file mode 100644 index 0000000..e8c58a5 --- /dev/null +++ b/src/uart.rs @@ -0,0 +1,44 @@ +use rp2040_hal::uart; +use rtic_monotonics::rp2040::fugit::HertzU32; + +enum Device> { + Disabled(uart::UartPeripheral), + Enabled(uart::UartPeripheral) +} + +pub use uart::UartConfig as Config; + +pub struct Uart> { + device: Option>, + peripheral_freq: HertzU32, +} + +impl> Uart { + pub fn new(device: D, pinout: P, peripheral_freq: HertzU32, resets: &mut rp2040_hal::pac::RESETS) -> Self { + let device = uart::UartPeripheral::new(device, pinout, resets); + Self { + device: Some(Device::Disabled(device)), + peripheral_freq, + } + } + + pub fn configure(&mut self, config: Config) { + let disabled_device = match self.device.take().unwrap() { + Device::Disabled(device) => device, + Device::Enabled(device) => device.disable(), + }; + + let mut device = disabled_device.enable(config, self.peripheral_freq).expect("failed to enable the uart peripheral"); + device.set_fifos(true); + device.enable_rx_interrupt(); + self.device = Some(Device::Enabled(device)); + } + + pub fn read(&self, data: &mut[u8]) -> usize { + if let Some(Device::Enabled(uart)) = self.device.as_ref() { + uart.read_raw(data).unwrap_or(0) + } else { + 0 + } + } +} \ No newline at end of file diff --git a/src/usb.rs b/src/usb.rs index 1a215b9..327eeea 100644 --- a/src/usb.rs +++ b/src/usb.rs @@ -55,6 +55,14 @@ impl ProbeUsb { } } + pub fn serial_write(&mut self, data: &[u8]) -> usize { + if self.device.state() == UsbDeviceState::Configured && self.serial.dtr() { + self.serial.write(data).unwrap_or(0) + } else { + 0 + } + } + pub fn flush_logs(&mut self) { #[cfg(feature = "defmt-bbq")] { @@ -86,16 +94,7 @@ impl ProbeUsb { return Some(Request::Suspend); } - // Discard data from the serial interface - let mut buf = [0; 64 as usize]; - let _read_data = self.serial.read(&mut buf); - - #[cfg(feature = "usb-serial-reboot")] - if let Ok(read_data) = _read_data { - if &buf[..read_data] == &0xDABAD000u32.to_be_bytes() { - rp2040_hal::rom_data::reset_to_usb_boot(0, 0); - } - } + // self.flush_serial_buffers(); let r = self.dap_v1.process(); if r.is_some() { @@ -110,6 +109,28 @@ impl ProbeUsb { None } + // pub fn flush_serial_buffers(&mut self) { + // if self.device.state() == UsbDeviceState::Configured { + // if let Ok(grant) = self.serial_consumer.read() { + // if let Ok(write_size) = self.serial.write(&grant) { + // grant.release(write_size); + // } + // } + // } + + // if let Ok(mut grant) = self.serial_producer.grant_max_remaining(64) { + // if let Ok(read_size) = self.serial.read(&mut grant) { + // #[cfg(feature = "usb-serial-reboot")] + // if &grant[..read_data] == &0xDABAD000u32.to_be_bytes() { + // rp2040_hal::rom_data::reset_to_usb_boot(0, 0); + // } + // if self.device.state() == UsbDeviceState::Configured { + // grant.commit(read_size); + // } + // } + // } + // } + /// Transmit a DAP report back over the DAPv1 HID interface pub fn dap1_reply(&mut self, data: &[u8]) { self.dap_v1 From 0d3863c390408245f23e4eab3c92bdeaf2c40cf0 Mon Sep 17 00:00:00 2001 From: Jonathan Herbst Date: Fri, 4 Oct 2024 14:26:35 -0400 Subject: [PATCH 02/13] fixed merge --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dc899c2..2251bb6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,8 +32,8 @@ defmt-brtt = { version = "0.1.0", default-features = false } bbqueue = { version = "0.5", features = ["thumbv6"] } [features] -default = [ "defmt-brtt/rtt", "gnddetect" ] -defmt-bbq = ["defmt-brtt/bbq", "dep:bbqueue"] +default = [ "defmt-brtt/rtt" ] +defmt-bbq = ["defmt-brtt/bbq"] gnddetect = [] usb-serial-reboot = [] From f1e0a5bd14ee0297d8fc65e0ed315ae743ab6559 Mon Sep 17 00:00:00 2001 From: Jonathan Herbst Date: Fri, 4 Oct 2024 22:55:58 -0400 Subject: [PATCH 03/13] almost working --- .cargo/config.toml | 4 ++-- src/bin/app.rs | 42 ++++++++++++++++++++++++++++-------------- src/uart.rs | 32 ++++++++++++++++++++++++++++++++ src/usb.rs | 4 ++++ 4 files changed, 66 insertions(+), 16 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index d4cac6d..34df4f0 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,7 +2,7 @@ # probe-run is recommended if you have a debugger # elf2uf2-rs loads firmware over USB when the rp2040 is in boot mode [target.'cfg(all(target_arch = "arm", target_os = "none"))'] -# runner = "probe-run --chip RP2040 --probe 3c004b001051383439393134" +runner = "probe-rs run --chip RP2040 --probe 1209:4853:dc645020134c2e22ef4014" # runner = "probe-run --chip RP2040 --probe dc6168968f3b812eef4014" # runner = "probe-run --chip RP2040 --probe dc61cd078f667031ef4014" # runner = "elf2uf2-rs -d" @@ -12,7 +12,7 @@ # # The target in this runner is the _host_ compilation target # You may have to change it -runner = "cargo xtask --target x86_64-unknown-linux-gnu debug --defmt-print" +#runner = "cargo xtask --target x86_64-unknown-linux-gnu debug --defmt-print" rustflags = [ "-C", "linker=flip-link", diff --git a/src/bin/app.rs b/src/bin/app.rs index 5304d21..a12d04a 100644 --- a/src/bin/app.rs +++ b/src/bin/app.rs @@ -20,11 +20,11 @@ mod app { #[shared] struct Shared { probe_usb: pico_probe::usb::ProbeUsb, + uart: Uart, } #[local] struct Local { - uart: Uart, dap_handler: DapHandler, target_vcc: TargetVccReader, translator_power: TranslatorPower, @@ -58,9 +58,8 @@ mod app { led_driver::spawn(leds).ok(); ( - Shared { probe_usb }, + Shared { probe_usb, uart }, Local { - uart, dap_handler, target_vcc, translator_power, @@ -121,9 +120,10 @@ mod app { } } - #[task(binds = USBCTRL_IRQ, priority = 2, shared = [ probe_usb ], local = [dap_handler, resp_buf: [u8; 64] = [0; 64]])] + #[task(binds = USBCTRL_IRQ, priority = 2, shared = [ probe_usb, uart ], local = [dap_handler, resp_buf: [u8; 64] = [0; 64]])] fn on_usb(ctx: on_usb::Context) { let mut probe_usb = ctx.shared.probe_usb; + let mut uart = ctx.shared.uart; let dap = ctx.local.dap_handler; let resp_buf = ctx.local.resp_buf; @@ -152,20 +152,34 @@ mod app { } } } + + uart.lock(|uart| { + if let Some(mut grant) = uart.try_grant_write(64) { + let used = probe_usb.serial_read(&mut grant); + grant.commit(used); + if used > 0 { + uart.flush_write_buffer(); + } + } + }); }); } - #[task(binds = UART1_IRQ, priority = 2, shared = [probe_usb], local = [uart])] - fn on_uart_rx(ctx: on_uart_rx::Context) { + #[task(binds = UART1_IRQ, priority = 2, shared = [probe_usb, uart])] + fn on_uart(ctx: on_uart::Context) { let mut probe_usb = ctx.shared.probe_usb; - let uart = ctx.local.uart; + let mut uart = ctx.shared.uart; + + uart.lock(|uart| { + let mut uart_buf = [0u8; 32]; + let read_size = uart.read(&mut uart_buf); + if read_size > 0 { + probe_usb.lock(|probe_usb| { + probe_usb.serial_write(&uart_buf[..read_size]); + }); + } - let mut uart_buf = [0u8; 32]; - let read_size = uart.read(&mut uart_buf); - if read_size > 0 { - probe_usb.lock(|probe_usb| { - probe_usb.serial_write(&uart_buf[..read_size]); - }); - } + uart.flush_write_buffer(); + }); } } diff --git a/src/uart.rs b/src/uart.rs index e8c58a5..08c1ea0 100644 --- a/src/uart.rs +++ b/src/uart.rs @@ -8,17 +8,25 @@ enum Device> { pub use uart::UartConfig as Config; +const WRITE_BUFFER_SIZE: usize = 256; +static WRITE_BUFFER: bbqueue::BBBuffer = bbqueue::BBBuffer::new(); + pub struct Uart> { device: Option>, peripheral_freq: HertzU32, + write_buffer_consumer: bbqueue::Consumer<'static, WRITE_BUFFER_SIZE>, + write_buffer_producer: bbqueue::Producer<'static, WRITE_BUFFER_SIZE>, } impl> Uart { pub fn new(device: D, pinout: P, peripheral_freq: HertzU32, resets: &mut rp2040_hal::pac::RESETS) -> Self { + let (producer, consumer) = WRITE_BUFFER.try_split().unwrap(); let device = uart::UartPeripheral::new(device, pinout, resets); Self { device: Some(Device::Disabled(device)), peripheral_freq, + write_buffer_consumer: consumer, + write_buffer_producer: producer, } } @@ -41,4 +49,28 @@ impl> Uart { 0 } } + + pub fn try_grant_write(&mut self, max_size: usize) -> Option> { + self.write_buffer_producer.grant_max_remaining(max_size).ok() + } + + pub fn flush_write_buffer(&mut self) { + if let Some(Device::Enabled(uart)) = self.device.as_mut() { + if let Ok(grant) = self.write_buffer_consumer.split_read() { + let written = uart.write_raw(grant.bufs().0).unwrap_or(&[]); + let mut used = written.len(); + if written.len() == grant.bufs().0.len() { + let written = uart.write_raw(grant.bufs().1).unwrap_or(&[]); + used += written.len(); + } + + if used < grant.combined_len() { + uart.enable_tx_interrupt(); + } else { + uart.disable_tx_interrupt(); + } + grant.release(used); + } + } + } } \ No newline at end of file diff --git a/src/usb.rs b/src/usb.rs index 327eeea..8e44107 100644 --- a/src/usb.rs +++ b/src/usb.rs @@ -63,6 +63,10 @@ impl ProbeUsb { } } + pub fn serial_read(&mut self, data: &mut [u8]) -> usize { + self.serial.read(data).unwrap_or(0) + } + pub fn flush_logs(&mut self) { #[cfg(feature = "defmt-bbq")] { From 1afb8f1d087ab86aa890fb246ad8f1c44760d1c1 Mon Sep 17 00:00:00 2001 From: Jonathan Herbst Date: Sat, 5 Oct 2024 11:36:52 -0400 Subject: [PATCH 04/13] Fixed: doesn't release --- src/uart.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/uart.rs b/src/uart.rs index 08c1ea0..68b7262 100644 --- a/src/uart.rs +++ b/src/uart.rs @@ -57,11 +57,11 @@ impl> Uart { pub fn flush_write_buffer(&mut self) { if let Some(Device::Enabled(uart)) = self.device.as_mut() { if let Ok(grant) = self.write_buffer_consumer.split_read() { - let written = uart.write_raw(grant.bufs().0).unwrap_or(&[]); - let mut used = written.len(); - if written.len() == grant.bufs().0.len() { - let written = uart.write_raw(grant.bufs().1).unwrap_or(&[]); - used += written.len(); + let unused = uart.write_raw(grant.bufs().0).unwrap_or(grant.bufs().0); + let mut used = grant.bufs().0.len() - unused.len(); + if unused.len() == 0 { + let unused = uart.write_raw(grant.bufs().1).unwrap_or(grant.bufs().1); + used += grant.bufs().1.len() - unused.len(); } if used < grant.combined_len() { From 1a0f9886059888c0cb55f02ff5f3ac1423383276 Mon Sep 17 00:00:00 2001 From: Jonathan Herbst Date: Sat, 5 Oct 2024 19:21:14 -0400 Subject: [PATCH 05/13] baud rate control working --- src/bin/app.rs | 67 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/uart.rs | 2 ++ src/usb.rs | 4 +++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/bin/app.rs b/src/bin/app.rs index a12d04a..f34c400 100644 --- a/src/bin/app.rs +++ b/src/bin/app.rs @@ -15,7 +15,60 @@ mod app { use rp2040_hal::usb::UsbBus; use usb_device::class_prelude::*; - use rtic_monotonics::rp2040::{ExtU64, Timer}; + use rtic_monotonics::rp2040::{fugit::RateExtU32, ExtU64, Timer}; + + struct UsbUartState { + data_rate: u32, + data_bits: u8, + stop_bits: usbd_serial::StopBits, + parity_type: usbd_serial::ParityType, + } + + impl PartialEq for UsbUartState { + fn eq(&self, other: &usbd_serial::LineCoding) -> bool { + self.data_bits == other.data_bits() && + self.data_rate == other.data_rate() && + self.parity_type == other.parity_type() && + self.stop_bits == other.stop_bits() + } + } + + impl UsbUartState { + pub fn new(line_coding: &usbd_serial::LineCoding) -> Self { + Self { + data_rate: line_coding.data_rate(), + data_bits: line_coding.data_bits(), + stop_bits: line_coding.stop_bits(), + parity_type: line_coding.parity_type(), + } + } + + pub fn try_get_uart_config(&self) -> Option { + let data_bits = match self.data_bits { + 5 => Some(rp2040_hal::uart::DataBits::Five), + 6 => Some(rp2040_hal::uart::DataBits::Six), + 7 => Some(rp2040_hal::uart::DataBits::Seven), + 8 => Some(rp2040_hal::uart::DataBits::Eight), + _ => None, + }?; + let parity = match self.parity_type { + // "Event" is probably a typo + usbd_serial::ParityType::Event => Some(Some(rp2040_hal::uart::Parity::Even)), + usbd_serial::ParityType::Odd => Some(Some(rp2040_hal::uart::Parity::Odd)), + usbd_serial::ParityType::None => Some(None), + _ => None, + }?; + let stop_bits = match self.stop_bits { + usbd_serial::StopBits::One => Some(rp2040_hal::uart::StopBits::One), + usbd_serial::StopBits::Two => Some(rp2040_hal::uart::StopBits::Two), + _ => None + }?; + + Some(rp2040_hal::uart::UartConfig::new( + self.data_rate.Hz(), + data_bits, parity, stop_bits)) + } + } #[shared] struct Shared { @@ -30,6 +83,7 @@ mod app { translator_power: TranslatorPower, target_power: TargetPower, target_physically_connected: TargetPhysicallyConnected, + uart_state: Option, } #[init(local = [ @@ -65,6 +119,7 @@ mod app { translator_power, target_power, target_physically_connected, + uart_state: None, }, ) } @@ -120,12 +175,13 @@ mod app { } } - #[task(binds = USBCTRL_IRQ, priority = 2, shared = [ probe_usb, uart ], local = [dap_handler, resp_buf: [u8; 64] = [0; 64]])] + #[task(binds = USBCTRL_IRQ, priority = 2, shared = [ probe_usb, uart ], local = [dap_handler, uart_state, resp_buf: [u8; 64] = [0; 64]])] fn on_usb(ctx: on_usb::Context) { let mut probe_usb = ctx.shared.probe_usb; let mut uart = ctx.shared.uart; let dap = ctx.local.dap_handler; let resp_buf = ctx.local.resp_buf; + let uart_state = ctx.local.uart_state; probe_usb.lock(|probe_usb| { if let Some(request) = probe_usb.interrupt() { @@ -154,6 +210,13 @@ mod app { } uart.lock(|uart| { + if uart_state.as_ref().map_or(true, |uart_state| !uart_state.eq(probe_usb.serial_line_coding())) { + *uart_state = Some(UsbUartState::new(probe_usb.serial_line_coding())); + if let Some(uart_config) = uart_state.as_ref().unwrap().try_get_uart_config() { + uart.configure(uart_config); + } + } + if let Some(mut grant) = uart.try_grant_write(64) { let used = probe_usb.serial_read(&mut grant); grant.commit(used); diff --git a/src/uart.rs b/src/uart.rs index 68b7262..68dce3d 100644 --- a/src/uart.rs +++ b/src/uart.rs @@ -36,6 +36,8 @@ impl> Uart { Device::Enabled(device) => device.disable(), }; + defmt::info!("configure uart: {}bps", config.baudrate.raw()); + let mut device = disabled_device.enable(config, self.peripheral_freq).expect("failed to enable the uart peripheral"); device.set_fifos(true); device.enable_rx_interrupt(); diff --git a/src/usb.rs b/src/usb.rs index 8e44107..4dc7d0b 100644 --- a/src/usb.rs +++ b/src/usb.rs @@ -67,6 +67,10 @@ impl ProbeUsb { self.serial.read(data).unwrap_or(0) } + pub fn serial_line_coding(&self) -> &usbd_serial::LineCoding { + self.serial.line_coding() + } + pub fn flush_logs(&mut self) { #[cfg(feature = "defmt-bbq")] { From fcd9fc1e0e851e3b6865dbca234c24541090d31d Mon Sep 17 00:00:00 2001 From: Jonathan Herbst Date: Sat, 5 Oct 2024 19:53:17 -0400 Subject: [PATCH 06/13] put usb-serial-reboot back --- src/bin/app.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bin/app.rs b/src/bin/app.rs index f34c400..ed012cd 100644 --- a/src/bin/app.rs +++ b/src/bin/app.rs @@ -219,6 +219,10 @@ mod app { if let Some(mut grant) = uart.try_grant_write(64) { let used = probe_usb.serial_read(&mut grant); + #[cfg(feature = "usb-serial-reboot")] + if &grant[..read_data] == &0xDABAD000u32.to_be_bytes() { + rp2040_hal::rom_data::reset_to_usb_boot(0, 0); + } grant.commit(used); if used > 0 { uart.flush_write_buffer(); From 14633b976ab325b142edc10b389f1f15c00e3fb2 Mon Sep 17 00:00:00 2001 From: Jonathan Herbst Date: Sat, 5 Oct 2024 20:22:40 -0400 Subject: [PATCH 07/13] cleanup --- src/usb.rs | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/usb.rs b/src/usb.rs index 4dc7d0b..58e0a59 100644 --- a/src/usb.rs +++ b/src/usb.rs @@ -102,8 +102,6 @@ impl ProbeUsb { return Some(Request::Suspend); } - // self.flush_serial_buffers(); - let r = self.dap_v1.process(); if r.is_some() { return r; @@ -117,28 +115,6 @@ impl ProbeUsb { None } - // pub fn flush_serial_buffers(&mut self) { - // if self.device.state() == UsbDeviceState::Configured { - // if let Ok(grant) = self.serial_consumer.read() { - // if let Ok(write_size) = self.serial.write(&grant) { - // grant.release(write_size); - // } - // } - // } - - // if let Ok(mut grant) = self.serial_producer.grant_max_remaining(64) { - // if let Ok(read_size) = self.serial.read(&mut grant) { - // #[cfg(feature = "usb-serial-reboot")] - // if &grant[..read_data] == &0xDABAD000u32.to_be_bytes() { - // rp2040_hal::rom_data::reset_to_usb_boot(0, 0); - // } - // if self.device.state() == UsbDeviceState::Configured { - // grant.commit(read_size); - // } - // } - // } - // } - /// Transmit a DAP report back over the DAPv1 HID interface pub fn dap1_reply(&mut self, data: &[u8]) { self.dap_v1 From 56ce17acf322f5a47e6e00ae19dab659baf298bd Mon Sep 17 00:00:00 2001 From: Jonathan Herbst Date: Sat, 5 Oct 2024 20:27:06 -0400 Subject: [PATCH 08/13] removed default configuration --- src/bin/app.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/bin/app.rs b/src/bin/app.rs index ed012cd..478ffab 100644 --- a/src/bin/app.rs +++ b/src/bin/app.rs @@ -94,7 +94,7 @@ mod app { let ( leds, probe_usb, - mut uart, + uart, dap_handler, target_vcc, translator_power, @@ -102,8 +102,6 @@ mod app { target_physically_connected, ) = setup(cx.device, cx.core, cx.local.usb_bus, cx.local.delay); - uart.configure(UartConfig::default()); - voltage_translator_control::spawn().ok(); #[cfg(feature = "defmt-bbq")] From 0435eeb502ddf4bd9a56583f4c0dc10cec49c48d Mon Sep 17 00:00:00 2001 From: Jonathan Herbst Date: Mon, 7 Oct 2024 16:35:34 -0400 Subject: [PATCH 09/13] made an app to overload the uart buffer, tried to fix --- src/bin/app.rs | 6 ++ uart-test/Cargo.lock | 206 ++++++++++++++++++++++++++++++++++++++++++ uart-test/Cargo.toml | 7 ++ uart-test/src/main.rs | 19 ++++ 4 files changed, 238 insertions(+) create mode 100644 uart-test/Cargo.lock create mode 100644 uart-test/Cargo.toml create mode 100644 uart-test/src/main.rs diff --git a/src/bin/app.rs b/src/bin/app.rs index 478ffab..d5139c2 100644 --- a/src/bin/app.rs +++ b/src/bin/app.rs @@ -244,6 +244,12 @@ mod app { }); } + if let Some(mut grant) = uart.try_grant_write(64) { + probe_usb.lock(|probe_usb| { + let read_size = probe_usb.serial_read(&mut grant); + grant.commit(read_size); + }); + } uart.flush_write_buffer(); }); } diff --git a/uart-test/Cargo.lock b/uart-test/Cargo.lock new file mode 100644 index 0000000..0cefa65 --- /dev/null +++ b/uart-test/Cargo.lock @@ -0,0 +1,206 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "io-kit-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b" +dependencies = [ + "core-foundation-sys", + "mach2", +] + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "libudev" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b324152da65df7bb95acfcaab55e3097ceaab02fb19b228a9eb74d55f135e0" +dependencies = [ + "libc", + "libudev-sys", +] + +[[package]] +name = "libudev-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", +] + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "proc-macro2" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serialport" +version = "4.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ba776acc8c373b9175829206229366273225436845c04f9c20aab8099960e2e" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "core-foundation-sys", + "io-kit-sys", + "libudev", + "mach2", + "nix", + "scopeguard", + "unescaper", + "winapi", +] + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "uart-test" +version = "0.1.0" +dependencies = [ + "serialport", +] + +[[package]] +name = "unescaper" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c878a167baa8afd137494101a688ef8c67125089ff2249284bd2b5f9bfedb815" +dependencies = [ + "thiserror", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/uart-test/Cargo.toml b/uart-test/Cargo.toml new file mode 100644 index 0000000..2e7d8c3 --- /dev/null +++ b/uart-test/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "uart-test" +version = "0.1.0" +edition = "2021" + +[dependencies] +serialport = "4.2" \ No newline at end of file diff --git a/uart-test/src/main.rs b/uart-test/src/main.rs new file mode 100644 index 0000000..0f8d004 --- /dev/null +++ b/uart-test/src/main.rs @@ -0,0 +1,19 @@ +type SerialPort = Box; + +fn try_transmit(target: &mut SerialPort, host: &mut SerialPort, data: &[u8]) { + target.write_all(data).unwrap(); + let mut host_buffer = vec![0u8; data.len()]; + host.read_exact(&mut host_buffer).unwrap(); + assert_eq!(data, &host_buffer); +} + +fn main() { + let mut target_serial = serialport::new("/dev/ttyACM0", 115200).open().expect("failed to open target serial"); + target_serial.set_timeout(std::time::Duration::from_secs(1)); + let mut host_serial = serialport::new("/dev/ttyUSB0", 115200).open().expect("failed to open host serial"); + host_serial.set_timeout(std::time::Duration::from_secs(1)); + + let test_data: Vec = (0..512/4).collect(); + let test_data_bytes = unsafe{ std::slice::from_raw_parts(test_data.as_ptr() as *const u8, 64) }; + try_transmit(&mut target_serial, &mut host_serial, test_data_bytes); +} \ No newline at end of file From 1badf8adaa6937e408ca6c7cb8c706e154abc4e9 Mon Sep 17 00:00:00 2001 From: Jonathan Herbst Date: Mon, 7 Oct 2024 19:45:15 -0400 Subject: [PATCH 10/13] it works --- src/bin/app.rs | 45 ++++++++++++++++++++++--------------------- uart-test/src/main.rs | 19 ++++++++++++++---- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/bin/app.rs b/src/bin/app.rs index d5139c2..f191d8b 100644 --- a/src/bin/app.rs +++ b/src/bin/app.rs @@ -10,7 +10,6 @@ mod app { use pico_probe::{ leds::{LedManager, Vtarget}, setup::*, - uart::Config as UartConfig, }; use rp2040_hal::usb::UsbBus; use usb_device::class_prelude::*; @@ -215,22 +214,14 @@ mod app { } } - if let Some(mut grant) = uart.try_grant_write(64) { - let used = probe_usb.serial_read(&mut grant); - #[cfg(feature = "usb-serial-reboot")] - if &grant[..read_data] == &0xDABAD000u32.to_be_bytes() { - rp2040_hal::rom_data::reset_to_usb_boot(0, 0); - } - grant.commit(used); - if used > 0 { - uart.flush_write_buffer(); - } + if buffer_uart_tx_data(probe_usb, uart) > 0 { + uart.flush_write_buffer(); } }); }); } - #[task(binds = UART1_IRQ, priority = 2, shared = [probe_usb, uart])] + #[task(binds = UART1_IRQ, priority = 3, shared = [probe_usb, uart])] fn on_uart(ctx: on_uart::Context) { let mut probe_usb = ctx.shared.probe_usb; let mut uart = ctx.shared.uart; @@ -238,19 +229,29 @@ mod app { uart.lock(|uart| { let mut uart_buf = [0u8; 32]; let read_size = uart.read(&mut uart_buf); - if read_size > 0 { - probe_usb.lock(|probe_usb| { + probe_usb.lock(|probe_usb| { + if read_size > 0 { probe_usb.serial_write(&uart_buf[..read_size]); - }); - } + } + + buffer_uart_tx_data(probe_usb, uart); + }); - if let Some(mut grant) = uart.try_grant_write(64) { - probe_usb.lock(|probe_usb| { - let read_size = probe_usb.serial_read(&mut grant); - grant.commit(read_size); - }); - } uart.flush_write_buffer(); }); } + + fn buffer_uart_tx_data(probe_usb: &mut pico_probe::usb::ProbeUsb, uart: &mut Uart) -> usize { + if let Some(mut grant) = uart.try_grant_write(64) { + let used = probe_usb.serial_read(&mut grant); + #[cfg(feature = "usb-serial-reboot")] + if grant.len() >= 4 && &grant[..read_data] == &0xDABAD000u32.to_be_bytes() { + rp2040_hal::rom_data::reset_to_usb_boot(0, 0); + } + grant.commit(used); + used + } else { + 0 + } + } } diff --git a/uart-test/src/main.rs b/uart-test/src/main.rs index 0f8d004..399acbe 100644 --- a/uart-test/src/main.rs +++ b/uart-test/src/main.rs @@ -8,12 +8,23 @@ fn try_transmit(target: &mut SerialPort, host: &mut SerialPort, data: &[u8]) { } fn main() { - let mut target_serial = serialport::new("/dev/ttyACM0", 115200).open().expect("failed to open target serial"); + let args: Vec = std::env::args().collect(); + if args.len() != 5 { + eprintln!("Usage: {} ", args[0]); + std::process::exit(1); + } + + let target_path = args[1].as_str(); + let host_path = args[2].as_str(); + let baud_rate = args[3].parse::().expect("invalid baud rate"); + let count = args[4].parse::().expect("invalid count"); + + let mut target_serial = serialport::new(target_path, baud_rate).open().expect("failed to open target serial"); target_serial.set_timeout(std::time::Duration::from_secs(1)); - let mut host_serial = serialport::new("/dev/ttyUSB0", 115200).open().expect("failed to open host serial"); + let mut host_serial = serialport::new(host_path, baud_rate).open().expect("failed to open host serial"); host_serial.set_timeout(std::time::Duration::from_secs(1)); - let test_data: Vec = (0..512/4).collect(); - let test_data_bytes = unsafe{ std::slice::from_raw_parts(test_data.as_ptr() as *const u8, 64) }; + let test_data: Vec = (0..count).collect(); + let test_data_bytes = unsafe{ std::slice::from_raw_parts(test_data.as_ptr() as *const u8, (count * 4) as usize) }; try_transmit(&mut target_serial, &mut host_serial, test_data_bytes); } \ No newline at end of file From 2918ccd405e2946e143793ca9f74139d6f90e916 Mon Sep 17 00:00:00 2001 From: Jonathan Herbst Date: Tue, 8 Oct 2024 13:05:18 -0400 Subject: [PATCH 11/13] fixed usb-serial-reboot feature, some cleanup --- src/bin/app.rs | 5 +++-- uart-test/src/main.rs | 33 ++++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/bin/app.rs b/src/bin/app.rs index f191d8b..611f77c 100644 --- a/src/bin/app.rs +++ b/src/bin/app.rs @@ -206,8 +206,9 @@ mod app { } } + let uart_state_changed = uart_state.as_ref().map_or(true, |uart_state| !uart_state.eq(probe_usb.serial_line_coding())); uart.lock(|uart| { - if uart_state.as_ref().map_or(true, |uart_state| !uart_state.eq(probe_usb.serial_line_coding())) { + if uart_state_changed { *uart_state = Some(UsbUartState::new(probe_usb.serial_line_coding())); if let Some(uart_config) = uart_state.as_ref().unwrap().try_get_uart_config() { uart.configure(uart_config); @@ -245,7 +246,7 @@ mod app { if let Some(mut grant) = uart.try_grant_write(64) { let used = probe_usb.serial_read(&mut grant); #[cfg(feature = "usb-serial-reboot")] - if grant.len() >= 4 && &grant[..read_data] == &0xDABAD000u32.to_be_bytes() { + if grant.len() >= 4 && &grant[..used] == &0xDABAD000u32.to_be_bytes() { rp2040_hal::rom_data::reset_to_usb_boot(0, 0); } grant.commit(used); diff --git a/uart-test/src/main.rs b/uart-test/src/main.rs index 399acbe..9373c52 100644 --- a/uart-test/src/main.rs +++ b/uart-test/src/main.rs @@ -7,24 +7,43 @@ fn try_transmit(target: &mut SerialPort, host: &mut SerialPort, data: &[u8]) { assert_eq!(data, &host_buffer); } +enum Command { + TransmitCount(u32), + Bootload, +} + +impl Command { + fn from_command_line(arg: &String) -> Self { + if arg == "bootload" { + Self::Bootload + } else { + Self::TransmitCount(arg.parse::().expect("invalid count")) + } + } +} + fn main() { let args: Vec = std::env::args().collect(); if args.len() != 5 { - eprintln!("Usage: {} ", args[0]); + eprintln!("Usage: {} bootload|", args[0]); std::process::exit(1); } let target_path = args[1].as_str(); let host_path = args[2].as_str(); let baud_rate = args[3].parse::().expect("invalid baud rate"); - let count = args[4].parse::().expect("invalid count"); + let command = Command::from_command_line(&args[4]); let mut target_serial = serialport::new(target_path, baud_rate).open().expect("failed to open target serial"); target_serial.set_timeout(std::time::Duration::from_secs(1)); - let mut host_serial = serialport::new(host_path, baud_rate).open().expect("failed to open host serial"); - host_serial.set_timeout(std::time::Duration::from_secs(1)); - let test_data: Vec = (0..count).collect(); - let test_data_bytes = unsafe{ std::slice::from_raw_parts(test_data.as_ptr() as *const u8, (count * 4) as usize) }; - try_transmit(&mut target_serial, &mut host_serial, test_data_bytes); + if let Command::TransmitCount(count) = command { + let mut host_serial = serialport::new(host_path, baud_rate).open().expect("failed to open host serial"); + host_serial.set_timeout(std::time::Duration::from_secs(1)); + let test_data: Vec = (0..count).collect(); + let test_data_bytes = unsafe{ std::slice::from_raw_parts(test_data.as_ptr() as *const u8, (count * 4) as usize) }; + try_transmit(&mut target_serial, &mut host_serial, test_data_bytes); + } else { + target_serial.write_all(&0xDABAD000u32.to_be_bytes()); + } } \ No newline at end of file From cfd7c1e1edd91e8b044b4b67d9b97e5c4404bf88 Mon Sep 17 00:00:00 2001 From: Jonathan Herbst Date: Tue, 8 Oct 2024 13:08:31 -0400 Subject: [PATCH 12/13] reverted some stuff I setup for testing --- .cargo/config.toml | 3 +-- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 34df4f0..750259e 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,7 +2,6 @@ # probe-run is recommended if you have a debugger # elf2uf2-rs loads firmware over USB when the rp2040 is in boot mode [target.'cfg(all(target_arch = "arm", target_os = "none"))'] -runner = "probe-rs run --chip RP2040 --probe 1209:4853:dc645020134c2e22ef4014" # runner = "probe-run --chip RP2040 --probe dc6168968f3b812eef4014" # runner = "probe-run --chip RP2040 --probe dc61cd078f667031ef4014" # runner = "elf2uf2-rs -d" @@ -12,7 +11,7 @@ runner = "probe-rs run --chip RP2040 --probe 1209:4853:dc645020134c2e22ef4014" # # The target in this runner is the _host_ compilation target # You may have to change it -#runner = "cargo xtask --target x86_64-unknown-linux-gnu debug --defmt-print" +runner = "cargo xtask --target x86_64-unknown-linux-gnu debug --defmt-print" rustflags = [ "-C", "linker=flip-link", diff --git a/Cargo.toml b/Cargo.toml index 2251bb6..489e6b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ defmt-brtt = { version = "0.1.0", default-features = false } bbqueue = { version = "0.5", features = ["thumbv6"] } [features] -default = [ "defmt-brtt/rtt" ] +default = [ "defmt-brtt/rtt", "gnddetect" ] defmt-bbq = ["defmt-brtt/bbq"] gnddetect = [] usb-serial-reboot = [] From 21a771b982c531e28faa3ea8c12027e6b923ccce Mon Sep 17 00:00:00 2001 From: Jonathan Herbst Date: Tue, 8 Oct 2024 13:10:33 -0400 Subject: [PATCH 13/13] more stuff I accidentally committed --- .cargo/config.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/.cargo/config.toml b/.cargo/config.toml index 750259e..d4cac6d 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,6 +2,7 @@ # probe-run is recommended if you have a debugger # elf2uf2-rs loads firmware over USB when the rp2040 is in boot mode [target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# runner = "probe-run --chip RP2040 --probe 3c004b001051383439393134" # runner = "probe-run --chip RP2040 --probe dc6168968f3b812eef4014" # runner = "probe-run --chip RP2040 --probe dc61cd078f667031ef4014" # runner = "elf2uf2-rs -d"