From 49ba6e750dcbab8b4add734bfae8baa7e26ff45c Mon Sep 17 00:00:00 2001 From: Ian Rees Date: Sat, 17 Jul 2021 11:09:55 +1200 Subject: [PATCH] Optimisation in USB poll() --- hal/src/thumbv6m/usb/bus.rs | 31 ++++++++++++++++++------------- hal/src/thumbv7em/usb/bus.rs | 31 ++++++++++++++++++------------- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/hal/src/thumbv6m/usb/bus.rs b/hal/src/thumbv6m/usb/bus.rs index 9ef562719a84..06900cc5dbcb 100644 --- a/hal/src/thumbv6m/usb/bus.rs +++ b/hal/src/thumbv6m/usb/bus.rs @@ -810,27 +810,32 @@ impl Inner { let mut ep_in_complete = 0; let mut ep_setup = 0; + let intbits = self.usb().epintsmry.read().bits(); + for ep in 0..8u16 { let mask = 1 << ep; let idx = ep as usize; - if let Ok(bank1) = self.bank1(EndpointAddress::from_parts(idx, UsbDirection::In)) { - if bank1.is_transfer_complete() { - bank1.clear_transfer_complete(); - ep_in_complete |= mask; - // Continuing (and hence not setting masks to indicate complete - // OUT transfers) is necessary for operation to proceed beyond - // the device-address + descriptor stage. The authors suspect a - // deadlock caused by waiting on a write when handling a read - // somewhere in an underlying class or control crate, but we - // can't be sure. Either way, if a write has finished, we only - // set the flag for a completed write on that endpoint index. - // Future polls will handle the reads. - continue; + if (intbits & mask) != 0 { + if let Ok(bank1) = self.bank1(EndpointAddress::from_parts(idx, UsbDirection::In)) { + if bank1.is_transfer_complete() { + bank1.clear_transfer_complete(); + ep_in_complete |= mask; + // Continuing (and hence not setting masks to indicate complete + // OUT transfers) is necessary for operation to proceed beyond + // the device-address + descriptor stage. The authors suspect a + // deadlock caused by waiting on a write when handling a read + // somewhere in an underlying class or control crate, but we + // can't be sure. Either way, if a write has finished, we only + // set the flag for a completed write on that endpoint index. + // Future polls will handle the reads. + continue; + } } } + // Can't test intbits, because bk0rdy doesn't interrupt if let Ok(bank0) = self.bank0(EndpointAddress::from_parts(idx, UsbDirection::Out)) { if bank0.received_setup_interrupt() { ep_setup |= mask; diff --git a/hal/src/thumbv7em/usb/bus.rs b/hal/src/thumbv7em/usb/bus.rs index 972ad8f5d2d0..53ed5fe4ded9 100644 --- a/hal/src/thumbv7em/usb/bus.rs +++ b/hal/src/thumbv7em/usb/bus.rs @@ -754,27 +754,32 @@ impl Inner { let mut ep_in_complete = 0; let mut ep_setup = 0; + let intbits = self.usb().epintsmry.read().bits(); + for ep in 0..8u16 { let mask = 1 << ep; let idx = ep as usize; - if let Ok(bank1) = self.bank1(EndpointAddress::from_parts(idx, UsbDirection::In)) { - if bank1.is_transfer_complete() { - bank1.clear_transfer_complete(); - ep_in_complete |= mask; - // Continuing (and hence not setting masks to indicate complete - // OUT transfers) is necessary for operation to proceed beyond - // the device-address + descriptor stage. The authors suspect a - // deadlock caused by waiting on a write when handling a read - // somewhere in an underlying class or control crate, but we - // can't be sure. Either way, if a write has finished, we only - // set the flag for a completed write on that endpoint index. - // Future polls will handle the reads. - continue; + if (intbits & mask) != 0 { + if let Ok(bank1) = self.bank1(EndpointAddress::from_parts(idx, UsbDirection::In)) { + if bank1.is_transfer_complete() { + bank1.clear_transfer_complete(); + ep_in_complete |= mask; + // Continuing (and hence not setting masks to indicate complete + // OUT transfers) is necessary for operation to proceed beyond + // the device-address + descriptor stage. The authors suspect a + // deadlock caused by waiting on a write when handling a read + // somewhere in an underlying class or control crate, but we + // can't be sure. Either way, if a write has finished, we only + // set the flag for a completed write on that endpoint index. + // Future polls will handle the reads. + continue; + } } } + // Can't test intbits, because bk0rdy doesn't interrupt if let Ok(bank0) = self.bank0(EndpointAddress::from_parts(idx, UsbDirection::Out)) { if bank0.received_setup_interrupt() { ep_setup |= mask;