diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-04-06 03:14:22 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-04-06 05:38:11 +0200 |
| commit | 22a47aeeb2bc9d459a6e83414632890164a7b448 (patch) | |
| tree | 294dac5c31fa1e46a88314e95d3dd5feeba4d20e | |
| parent | f6d11dfba56b2b04868e87a14d10395e1916306d (diff) | |
usb: abort control data in/out on reset or when receiving another SETUP.
This removes the horrible timeout hack.
| -rw-r--r-- | embassy-nrf/src/usb.rs | 71 | ||||
| -rw-r--r-- | embassy-usb/src/control.rs | 8 | ||||
| -rw-r--r-- | embassy-usb/src/driver.rs | 2 |
3 files changed, 50 insertions, 31 deletions
diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs index c16e1be00..b5e173078 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs | |||
| @@ -6,7 +6,6 @@ use core::sync::atomic::{compiler_fence, AtomicU32, Ordering}; | |||
| 6 | use core::task::Poll; | 6 | use core::task::Poll; |
| 7 | use cortex_m::peripheral::NVIC; | 7 | use cortex_m::peripheral::NVIC; |
| 8 | use embassy::interrupt::InterruptExt; | 8 | use embassy::interrupt::InterruptExt; |
| 9 | use embassy::time::{with_timeout, Duration}; | ||
| 10 | use embassy::util::Unborrow; | 9 | use embassy::util::Unborrow; |
| 11 | use embassy::waitqueue::AtomicWaker; | 10 | use embassy::waitqueue::AtomicWaker; |
| 12 | use embassy_hal_common::unborrow; | 11 | use embassy_hal_common::unborrow; |
| @@ -59,6 +58,7 @@ impl<'d, T: Instance> Driver<'d, T> { | |||
| 59 | if regs.events_usbreset.read().bits() != 0 { | 58 | if regs.events_usbreset.read().bits() != 0 { |
| 60 | regs.intenclr.write(|w| w.usbreset().clear()); | 59 | regs.intenclr.write(|w| w.usbreset().clear()); |
| 61 | BUS_WAKER.wake(); | 60 | BUS_WAKER.wake(); |
| 61 | EP0_WAKER.wake(); | ||
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | if regs.events_ep0setup.read().bits() != 0 { | 64 | if regs.events_ep0setup.read().bits() != 0 { |
| @@ -585,7 +585,7 @@ pub struct ControlPipe<'d, T: Instance> { | |||
| 585 | impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | 585 | impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { |
| 586 | type SetupFuture<'a> = impl Future<Output = Request> + 'a where Self: 'a; | 586 | type SetupFuture<'a> = impl Future<Output = Request> + 'a where Self: 'a; |
| 587 | type DataOutFuture<'a> = impl Future<Output = Result<usize, ReadError>> + 'a where Self: 'a; | 587 | type DataOutFuture<'a> = impl Future<Output = Result<usize, ReadError>> + 'a where Self: 'a; |
| 588 | type DataInFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | 588 | type DataInFuture<'a> = impl Future<Output = Result<(), WriteError>> + 'a where Self: 'a; |
| 589 | 589 | ||
| 590 | fn max_packet_size(&self) -> usize { | 590 | fn max_packet_size(&self) -> usize { |
| 591 | usize::from(self.max_packet_size) | 591 | usize::from(self.max_packet_size) |
| @@ -596,7 +596,10 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 596 | let regs = T::regs(); | 596 | let regs = T::regs(); |
| 597 | 597 | ||
| 598 | // Wait for SETUP packet | 598 | // Wait for SETUP packet |
| 599 | regs.intenset.write(|w| w.ep0setup().set()); | 599 | regs.intenset.write(|w| { |
| 600 | w.ep0setup().set(); | ||
| 601 | w.ep0datadone().set() | ||
| 602 | }); | ||
| 600 | poll_fn(|cx| { | 603 | poll_fn(|cx| { |
| 601 | EP0_WAKER.register(cx.waker()); | 604 | EP0_WAKER.register(cx.waker()); |
| 602 | let regs = T::regs(); | 605 | let regs = T::regs(); |
| @@ -639,22 +642,27 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 639 | let regs = T::regs(); | 642 | let regs = T::regs(); |
| 640 | 643 | ||
| 641 | // Wait until ready | 644 | // Wait until ready |
| 642 | regs.intenset.write(|w| w.ep0datadone().set()); | 645 | regs.intenset.write(|w| { |
| 646 | w.usbreset().set(); | ||
| 647 | w.ep0setup().set(); | ||
| 648 | w.ep0datadone().set() | ||
| 649 | }); | ||
| 643 | poll_fn(|cx| { | 650 | poll_fn(|cx| { |
| 644 | EP0_WAKER.register(cx.waker()); | 651 | EP0_WAKER.register(cx.waker()); |
| 645 | let regs = T::regs(); | 652 | let regs = T::regs(); |
| 646 | if regs | 653 | if regs.events_usbreset.read().bits() != 0 { |
| 647 | .events_ep0datadone | 654 | trace!("aborted control data_out: usb reset"); |
| 648 | .read() | 655 | Poll::Ready(Err(ReadError::Disabled)) |
| 649 | .events_ep0datadone() | 656 | } else if regs.events_ep0setup.read().bits() != 0 { |
| 650 | .bit_is_set() | 657 | trace!("aborted control data_out: received another SETUP"); |
| 651 | { | 658 | Poll::Ready(Err(ReadError::Disabled)) |
| 652 | Poll::Ready(()) | 659 | } else if regs.events_ep0datadone.read().bits() != 0 { |
| 660 | Poll::Ready(Ok(())) | ||
| 653 | } else { | 661 | } else { |
| 654 | Poll::Pending | 662 | Poll::Pending |
| 655 | } | 663 | } |
| 656 | }) | 664 | }) |
| 657 | .await; | 665 | .await?; |
| 658 | 666 | ||
| 659 | unsafe { read_dma::<T>(0, buf) } | 667 | unsafe { read_dma::<T>(0, buf) } |
| 660 | } | 668 | } |
| @@ -671,24 +679,29 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 671 | regs.shorts | 679 | regs.shorts |
| 672 | .modify(|_, w| w.ep0datadone_ep0status().bit(last_packet)); | 680 | .modify(|_, w| w.ep0datadone_ep0status().bit(last_packet)); |
| 673 | 681 | ||
| 674 | regs.intenset.write(|w| w.ep0datadone().set()); | 682 | regs.intenset.write(|w| { |
| 675 | let res = with_timeout( | 683 | w.usbreset().set(); |
| 676 | Duration::from_millis(10), | 684 | w.ep0setup().set(); |
| 677 | poll_fn(|cx| { | 685 | w.ep0datadone().set() |
| 678 | EP0_WAKER.register(cx.waker()); | 686 | }); |
| 679 | let regs = T::regs(); | ||
| 680 | if regs.events_ep0datadone.read().bits() != 0 { | ||
| 681 | Poll::Ready(()) | ||
| 682 | } else { | ||
| 683 | Poll::Pending | ||
| 684 | } | ||
| 685 | }), | ||
| 686 | ) | ||
| 687 | .await; | ||
| 688 | 687 | ||
| 689 | if res.is_err() { | 688 | poll_fn(|cx| { |
| 690 | error!("ControlPipe::data_in timed out."); | 689 | cx.waker().wake_by_ref(); |
| 691 | } | 690 | EP0_WAKER.register(cx.waker()); |
| 691 | let regs = T::regs(); | ||
| 692 | if regs.events_usbreset.read().bits() != 0 { | ||
| 693 | trace!("aborted control data_in: usb reset"); | ||
| 694 | Poll::Ready(Err(WriteError::Disabled)) | ||
| 695 | } else if regs.events_ep0setup.read().bits() != 0 { | ||
| 696 | trace!("aborted control data_in: received another SETUP"); | ||
| 697 | Poll::Ready(Err(WriteError::Disabled)) | ||
| 698 | } else if regs.events_ep0datadone.read().bits() != 0 { | ||
| 699 | Poll::Ready(Ok(())) | ||
| 700 | } else { | ||
| 701 | Poll::Pending | ||
| 702 | } | ||
| 703 | }) | ||
| 704 | .await | ||
| 692 | } | 705 | } |
| 693 | } | 706 | } |
| 694 | 707 | ||
diff --git a/embassy-usb/src/control.rs b/embassy-usb/src/control.rs index b15ba4463..7c46812bd 100644 --- a/embassy-usb/src/control.rs +++ b/embassy-usb/src/control.rs | |||
| @@ -295,7 +295,13 @@ impl<C: driver::ControlPipe> ControlPipe<C> { | |||
| 295 | .chain(need_zlp.then(|| -> &[u8] { &[] })); | 295 | .chain(need_zlp.then(|| -> &[u8] { &[] })); |
| 296 | 296 | ||
| 297 | while let Some(chunk) = chunks.next() { | 297 | while let Some(chunk) = chunks.next() { |
| 298 | self.control.data_in(chunk, chunks.size_hint().0 == 0).await; | 298 | match self.control.data_in(chunk, chunks.size_hint().0 == 0).await { |
| 299 | Ok(()) => {} | ||
| 300 | Err(e) => { | ||
| 301 | warn!("control accept_in failed: {:?}", e); | ||
| 302 | return; | ||
| 303 | } | ||
| 304 | } | ||
| 299 | } | 305 | } |
| 300 | } | 306 | } |
| 301 | 307 | ||
diff --git a/embassy-usb/src/driver.rs b/embassy-usb/src/driver.rs index 6eaa40b0d..d3231cb45 100644 --- a/embassy-usb/src/driver.rs +++ b/embassy-usb/src/driver.rs | |||
| @@ -147,7 +147,7 @@ pub trait ControlPipe { | |||
| 147 | type DataOutFuture<'a>: Future<Output = Result<usize, ReadError>> + 'a | 147 | type DataOutFuture<'a>: Future<Output = Result<usize, ReadError>> + 'a |
| 148 | where | 148 | where |
| 149 | Self: 'a; | 149 | Self: 'a; |
| 150 | type DataInFuture<'a>: Future<Output = ()> + 'a | 150 | type DataInFuture<'a>: Future<Output = Result<(), WriteError>> + 'a |
| 151 | where | 151 | where |
| 152 | Self: 'a; | 152 | Self: 'a; |
| 153 | 153 | ||
