From 5fd55f95293b50ea2899c621186146dcb2be7823 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 12 May 2022 18:14:48 +0200 Subject: [PATCH 1/2] usb: parse request in embassy-usb instead of the driver. --- embassy-nrf/src/usb.rs | 13 ++++--------- embassy-usb/src/driver.rs | 4 +--- embassy-usb/src/lib.rs | 4 +++- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs index 1162946a9..9dedc471e 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs @@ -9,7 +9,6 @@ use embassy::interrupt::InterruptExt; use embassy::util::Unborrow; use embassy::waitqueue::AtomicWaker; use embassy_hal_common::unborrow; -use embassy_usb::control::Request; use embassy_usb::driver::{self, EndpointError, Event, Unsupported}; use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection}; use futures::future::poll_fn; @@ -682,14 +681,7 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { buf[6] = regs.wlengthl.read().wlengthl().bits(); buf[7] = regs.wlengthh.read().wlengthh().bits(); - let req = Request::parse(&buf); - - if req.direction == UsbDirection::Out { - regs.tasks_ep0rcvout - .write(|w| w.tasks_ep0rcvout().set_bit()); - } - - req + buf } } @@ -697,6 +689,9 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { async move { let regs = T::regs(); + regs.tasks_ep0rcvout + .write(|w| w.tasks_ep0rcvout().set_bit()); + // Wait until ready regs.intenset.write(|w| { w.usbreset().set(); diff --git a/embassy-usb/src/driver.rs b/embassy-usb/src/driver.rs index 57f2b0656..8454b041f 100644 --- a/embassy-usb/src/driver.rs +++ b/embassy-usb/src/driver.rs @@ -1,7 +1,5 @@ use core::future::Future; -use crate::control::Request; - use super::types::*; /// Driver for a specific USB peripheral. Implement this to add support for a new hardware @@ -146,7 +144,7 @@ pub trait EndpointOut: Endpoint { } pub trait ControlPipe { - type SetupFuture<'a>: Future + 'a + type SetupFuture<'a>: Future + 'a where Self: 'a; type DataOutFuture<'a>: Future> + 'a diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index b135f5eb3..7b85a2884 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs @@ -246,7 +246,9 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { } } - async fn handle_control(&mut self, req: Request) { + async fn handle_control(&mut self, req: [u8; 8]) { + let req = Request::parse(&req); + trace!("control request: {:02x}", req); match req.direction { From 0764fad5871fb2296fe3efbef57364028cf0b0c1 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 12 May 2022 18:45:10 +0200 Subject: [PATCH 2/2] nrf/usb: fix control out transfers getting corrupted due to ep0rcvout sticking from earlier. --- embassy-nrf/src/usb.rs | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs index 9dedc471e..8d589aeda 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs @@ -525,10 +525,6 @@ unsafe fn read_dma(i: usize, buf: &mut [u8]) -> Result { } impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { - type SetupFuture<'a> = impl Future + 'a where Self: 'a; + type SetupFuture<'a> = impl Future + 'a where Self: 'a; type DataOutFuture<'a> = impl Future> + 'a where Self: 'a; type DataInFuture<'a> = impl Future> + 'a where Self: 'a; @@ -651,11 +647,11 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { async move { let regs = T::regs(); + // Reset shorts + regs.shorts.write(|w| w); + // Wait for SETUP packet - regs.intenset.write(|w| { - w.ep0setup().set(); - w.ep0datadone().set() - }); + regs.intenset.write(|w| w.ep0setup().set()); poll_fn(|cx| { EP0_WAKER.register(cx.waker()); let regs = T::regs(); @@ -667,8 +663,6 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { }) .await; - // Reset shorts - regs.shorts.write(|w| w); regs.events_ep0setup.reset(); let mut buf = [0; 8]; @@ -689,6 +683,9 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { async move { let regs = T::regs(); + regs.events_ep0datadone.reset(); + + // This starts a RX on EP0. events_ep0datadone notifies when done. regs.tasks_ep0rcvout .write(|w| w.tasks_ep0rcvout().set_bit()); @@ -723,13 +720,13 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { async move { let regs = T::regs(); regs.events_ep0datadone.reset(); - unsafe { - write_dma::(0, buf); - } regs.shorts .write(|w| w.ep0datadone_ep0status().bit(last_packet)); + // This starts a TX on EP0. events_ep0datadone notifies when done. + unsafe { write_dma::(0, buf) } + regs.intenset.write(|w| { w.usbreset().set(); w.ep0setup().set();