aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2019-08-01 21:38:07 -0400
committerBrian Cully <bjc@kublai.com>2019-08-01 21:38:07 -0400
commitde3e8606c3bc199dfe417d3737c37fc898dc0442 (patch)
treec8676a25685eaef3f6e2ec998158697f21d2430f
parent0771a8d2466fb418b566846cfd165480760fd9ce (diff)
downloadsamd21-demo-de3e8606c3bc199dfe417d3737c37fc898dc0442.tar.gz
samd21-demo-de3e8606c3bc199dfe417d3737c37fc898dc0442.zip
Short-circuit out of NAK on interrupt pipes.
Don't bother retrying. NAK on an interrupt endpoint means there's no data.
-rw-r--r--usbh/src/device.rs11
-rw-r--r--usbh/src/pipe.rs11
2 files changed, 14 insertions, 8 deletions
diff --git a/usbh/src/device.rs b/usbh/src/device.rs
index aba3919..fd5c1a1 100644
--- a/usbh/src/device.rs
+++ b/usbh/src/device.rs
@@ -302,7 +302,7 @@ impl Device {
FSM::GetReport(0) => self.state = FSM::Steady,
FSM::GetReport(count) => {
- info!("+++ getting report {}", count);
+ debug!("+++ getting report {}", count);
// For now, just do an IN transfer to see if we can
// get some keyboard reports without further setup.
@@ -324,12 +324,11 @@ impl Device {
fn read_report(&mut self, pipe_table: &mut PipeTable, host: &mut usb::HOST, id: u8) {
if let Some(ref mut ep) = self.endpoints[id as usize] {
let mut pipe = pipe_table.pipe_for(host, ep);
- let mut buf: core::mem::MaybeUninit<[u8; 8]> = core::mem::MaybeUninit::uninit();
+ let mut buf: [u8; 8] = [0; 8];
match pipe.in_transfer(ep, &mut buf, 15, self.millis) {
- Ok(bytes_received) => {
- let tmp = unsafe { &(buf.assume_init())[..bytes_received] };
- info!("report {}: {:?}", id, tmp);
- }
+ Ok(bytes_received) => info!("report {}: {} - {:?}", id, bytes_received, buf),
+
+ Err(PipeErr::Flow) => return,
Err(e) => trace!("error {}: {:?}", id, e),
}
diff --git a/usbh/src/pipe.rs b/usbh/src/pipe.rs
index abdba2a..80ebe11 100644
--- a/usbh/src/pipe.rs
+++ b/usbh/src/pipe.rs
@@ -321,9 +321,9 @@ impl Pipe<'_, '_> {
ep.out_toggle,
);
if self.regs.status.read().dtgl().bit_is_set() {
- self.dtgl_clear();
- } else {
self.dtgl_set();
+ } else {
+ self.dtgl_clear();
}
if token == PToken::In {
ep.in_toggle = self.regs.status.read().dtgl().bit_is_set()
@@ -377,6 +377,13 @@ impl Pipe<'_, '_> {
last_err = e;
match last_err {
PipeErr::DataToggle => self.dtgl(ep, token),
+
+ // Flow error on interrupt pipes means we got
+ // a NAK, which in this context means there's
+ // no data. cf ยง32.8.7.5 of SAM D21 data
+ // sheet.
+ PipeErr::Flow if ep.transfer_type == TransferType::Interrupt => break,
+
PipeErr::Stall => break,
_ => {
naks += 1;