diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-05-12 16:46:35 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-05-12 16:46:35 +0000 |
| commit | 13bcb5ffb692997df192ab3bf8c20b4fb2a1d172 (patch) | |
| tree | 9fd3242c8ab8bc9a8d552730511466803064906a | |
| parent | 45c0f1ab88edb7a635faf3bb0941d81772100da1 (diff) | |
| parent | 0764fad5871fb2296fe3efbef57364028cf0b0c1 (diff) | |
Merge #768
768: nrf/usb: fix control out transfers getting corrupted due to ep0rcvout sticking from earlier. r=Dirbaio a=Dirbaio
bors r+
Co-authored-by: Dario Nieuwenhuis <[email protected]>
| -rw-r--r-- | embassy-nrf/src/usb.rs | 38 | ||||
| -rw-r--r-- | embassy-usb/src/driver.rs | 4 | ||||
| -rw-r--r-- | embassy-usb/src/lib.rs | 4 |
3 files changed, 19 insertions, 27 deletions
diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs index 1162946a9..8d589aeda 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs | |||
| @@ -9,7 +9,6 @@ use embassy::interrupt::InterruptExt; | |||
| 9 | use embassy::util::Unborrow; | 9 | use embassy::util::Unborrow; |
| 10 | use embassy::waitqueue::AtomicWaker; | 10 | use embassy::waitqueue::AtomicWaker; |
| 11 | use embassy_hal_common::unborrow; | 11 | use embassy_hal_common::unborrow; |
| 12 | use embassy_usb::control::Request; | ||
| 13 | use embassy_usb::driver::{self, EndpointError, Event, Unsupported}; | 12 | use embassy_usb::driver::{self, EndpointError, Event, Unsupported}; |
| 14 | use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection}; | 13 | use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection}; |
| 15 | use futures::future::poll_fn; | 14 | use futures::future::poll_fn; |
| @@ -526,10 +525,6 @@ unsafe fn read_dma<T: Instance>(i: usize, buf: &mut [u8]) -> Result<usize, Endpo | |||
| 526 | return Err(EndpointError::BufferOverflow); | 525 | return Err(EndpointError::BufferOverflow); |
| 527 | } | 526 | } |
| 528 | 527 | ||
| 529 | if i == 0 { | ||
| 530 | regs.events_ep0datadone.reset(); | ||
| 531 | } | ||
| 532 | |||
| 533 | let epout = [ | 528 | let epout = [ |
| 534 | ®s.epout0, | 529 | ®s.epout0, |
| 535 | ®s.epout1, | 530 | ®s.epout1, |
| @@ -640,7 +635,7 @@ pub struct ControlPipe<'d, T: Instance> { | |||
| 640 | } | 635 | } |
| 641 | 636 | ||
| 642 | impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | 637 | impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { |
| 643 | type SetupFuture<'a> = impl Future<Output = Request> + 'a where Self: 'a; | 638 | type SetupFuture<'a> = impl Future<Output = [u8;8]> + 'a where Self: 'a; |
| 644 | type DataOutFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a; | 639 | type DataOutFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a; |
| 645 | type DataInFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a; | 640 | type DataInFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a; |
| 646 | 641 | ||
| @@ -652,11 +647,11 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 652 | async move { | 647 | async move { |
| 653 | let regs = T::regs(); | 648 | let regs = T::regs(); |
| 654 | 649 | ||
| 650 | // Reset shorts | ||
| 651 | regs.shorts.write(|w| w); | ||
| 652 | |||
| 655 | // Wait for SETUP packet | 653 | // Wait for SETUP packet |
| 656 | regs.intenset.write(|w| { | 654 | regs.intenset.write(|w| w.ep0setup().set()); |
| 657 | w.ep0setup().set(); | ||
| 658 | w.ep0datadone().set() | ||
| 659 | }); | ||
| 660 | poll_fn(|cx| { | 655 | poll_fn(|cx| { |
| 661 | EP0_WAKER.register(cx.waker()); | 656 | EP0_WAKER.register(cx.waker()); |
| 662 | let regs = T::regs(); | 657 | let regs = T::regs(); |
| @@ -668,8 +663,6 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 668 | }) | 663 | }) |
| 669 | .await; | 664 | .await; |
| 670 | 665 | ||
| 671 | // Reset shorts | ||
| 672 | regs.shorts.write(|w| w); | ||
| 673 | regs.events_ep0setup.reset(); | 666 | regs.events_ep0setup.reset(); |
| 674 | 667 | ||
| 675 | let mut buf = [0; 8]; | 668 | let mut buf = [0; 8]; |
| @@ -682,14 +675,7 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 682 | buf[6] = regs.wlengthl.read().wlengthl().bits(); | 675 | buf[6] = regs.wlengthl.read().wlengthl().bits(); |
| 683 | buf[7] = regs.wlengthh.read().wlengthh().bits(); | 676 | buf[7] = regs.wlengthh.read().wlengthh().bits(); |
| 684 | 677 | ||
| 685 | let req = Request::parse(&buf); | 678 | buf |
| 686 | |||
| 687 | if req.direction == UsbDirection::Out { | ||
| 688 | regs.tasks_ep0rcvout | ||
| 689 | .write(|w| w.tasks_ep0rcvout().set_bit()); | ||
| 690 | } | ||
| 691 | |||
| 692 | req | ||
| 693 | } | 679 | } |
| 694 | } | 680 | } |
| 695 | 681 | ||
| @@ -697,6 +683,12 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 697 | async move { | 683 | async move { |
| 698 | let regs = T::regs(); | 684 | let regs = T::regs(); |
| 699 | 685 | ||
| 686 | regs.events_ep0datadone.reset(); | ||
| 687 | |||
| 688 | // This starts a RX on EP0. events_ep0datadone notifies when done. | ||
| 689 | regs.tasks_ep0rcvout | ||
| 690 | .write(|w| w.tasks_ep0rcvout().set_bit()); | ||
| 691 | |||
| 700 | // Wait until ready | 692 | // Wait until ready |
| 701 | regs.intenset.write(|w| { | 693 | regs.intenset.write(|w| { |
| 702 | w.usbreset().set(); | 694 | w.usbreset().set(); |
| @@ -728,13 +720,13 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 728 | async move { | 720 | async move { |
| 729 | let regs = T::regs(); | 721 | let regs = T::regs(); |
| 730 | regs.events_ep0datadone.reset(); | 722 | regs.events_ep0datadone.reset(); |
| 731 | unsafe { | ||
| 732 | write_dma::<T>(0, buf); | ||
| 733 | } | ||
| 734 | 723 | ||
| 735 | regs.shorts | 724 | regs.shorts |
| 736 | .write(|w| w.ep0datadone_ep0status().bit(last_packet)); | 725 | .write(|w| w.ep0datadone_ep0status().bit(last_packet)); |
| 737 | 726 | ||
| 727 | // This starts a TX on EP0. events_ep0datadone notifies when done. | ||
| 728 | unsafe { write_dma::<T>(0, buf) } | ||
| 729 | |||
| 738 | regs.intenset.write(|w| { | 730 | regs.intenset.write(|w| { |
| 739 | w.usbreset().set(); | 731 | w.usbreset().set(); |
| 740 | w.ep0setup().set(); | 732 | w.ep0setup().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 @@ | |||
| 1 | use core::future::Future; | 1 | use core::future::Future; |
| 2 | 2 | ||
| 3 | use crate::control::Request; | ||
| 4 | |||
| 5 | use super::types::*; | 3 | use super::types::*; |
| 6 | 4 | ||
| 7 | /// Driver for a specific USB peripheral. Implement this to add support for a new hardware | 5 | /// Driver for a specific USB peripheral. Implement this to add support for a new hardware |
| @@ -146,7 +144,7 @@ pub trait EndpointOut: Endpoint { | |||
| 146 | } | 144 | } |
| 147 | 145 | ||
| 148 | pub trait ControlPipe { | 146 | pub trait ControlPipe { |
| 149 | type SetupFuture<'a>: Future<Output = Request> + 'a | 147 | type SetupFuture<'a>: Future<Output = [u8; 8]> + 'a |
| 150 | where | 148 | where |
| 151 | Self: 'a; | 149 | Self: 'a; |
| 152 | type DataOutFuture<'a>: Future<Output = Result<usize, EndpointError>> + 'a | 150 | type DataOutFuture<'a>: Future<Output = Result<usize, EndpointError>> + '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> { | |||
| 246 | } | 246 | } |
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | async fn handle_control(&mut self, req: Request) { | 249 | async fn handle_control(&mut self, req: [u8; 8]) { |
| 250 | let req = Request::parse(&req); | ||
| 251 | |||
| 250 | trace!("control request: {:02x}", req); | 252 | trace!("control request: {:02x}", req); |
| 251 | 253 | ||
| 252 | match req.direction { | 254 | match req.direction { |
