diff options
author | Brian Cully <bjc@kublai.com> | 2019-07-30 18:26:10 -0400 |
---|---|---|
committer | Brian Cully <bjc@kublai.com> | 2019-07-30 18:26:10 -0400 |
commit | 7f3601e081f71776d3b5f9fc58d5e1adda7772a3 (patch) | |
tree | 2be13a2d22d590719d8828b83afbe6fa31eceba0 /usbh/src/pipe.rs | |
parent | fb45c6c269bb1440fdf8750bed875dfe973ca8bb (diff) | |
download | samd21-demo-7f3601e081f71776d3b5f9fc58d5e1adda7772a3.tar.gz samd21-demo-7f3601e081f71776d3b5f9fc58d5e1adda7772a3.zip |
WIP: Holy smokes I read my first keyboard report.
Too bad it's still trfail town after the first, but progress!
Diffstat (limited to 'usbh/src/pipe.rs')
-rw-r--r-- | usbh/src/pipe.rs | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/usbh/src/pipe.rs b/usbh/src/pipe.rs index 9b0eedd..d7b7981 100644 --- a/usbh/src/pipe.rs +++ b/usbh/src/pipe.rs @@ -19,7 +19,7 @@ use atsamd_hal::target_device::usb::{ host::{BINTERVAL, PCFG, PINTFLAG, PSTATUS, PSTATUSCLR, PSTATUSSET}, }; use core::convert::TryInto; -use log::{debug, trace}; +use log::{trace, warn}; // Maximum time to wait for a control request with data to finish. cf // ยง9.2.6.1 of USB 2.0. @@ -149,7 +149,7 @@ impl Pipe<'_, '_> { } RequestDirection::HostToDevice => { - debug!("Should OUT for {}b", len); + self.out_transfer(b, NAK_LIMIT, millis)?; } } } @@ -197,6 +197,36 @@ impl Pipe<'_, '_> { self.dispatch_retries(token, nak_limit, millis) } + pub(crate) fn out_transfer<T>( + &mut self, + buf: &mut T, + nak_limit: usize, + millis: &dyn Fn() -> usize, + ) -> Result<usize, PipeErr> { + let db: DataBuf = buf.into(); + + trace!("p{}: Should OUT for {}b.", self.num, db.len); + self.desc.bank0.pcksize.write(|w| { + unsafe { w.byte_count().bits(db.len as u16) }; + unsafe { w.multi_packet_size().bits(0) } + }); + + let mut bytes_sent = 0; + while bytes_sent < db.len { + self.desc + .bank0 + .addr + .write(|w| unsafe { w.addr().bits(db.ptr as u32 + bytes_sent as u32) }); + self.dispatch_retries(PToken::Out, nak_limit, millis)?; + + let sent = self.desc.bank0.pcksize.read().byte_count().bits() as usize; + bytes_sent += sent; + trace!("!! wrote {} of {}", bytes_sent, db.len); + } + + Ok(bytes_sent) + } + pub(crate) fn in_transfer<T>( &mut self, buf: &mut T, @@ -297,9 +327,6 @@ impl Pipe<'_, '_> { retries: usize, millis: &dyn Fn() -> usize, ) -> Result<(), PipeErr> { - trace!("initial regs"); - self.log_regs(); - self.dispatch_packet(token); let until = millis() + USB_TIMEOUT; @@ -328,8 +355,6 @@ impl Pipe<'_, '_> { } } - trace!("dispatch err: {:?}", last_err); - self.log_regs(); Err(last_err) } @@ -337,6 +362,10 @@ impl Pipe<'_, '_> { self.regs .cfg .modify(|_, w| unsafe { w.ptoken().bits(token as u8) }); + + trace!("initial regs"); + self.log_regs(); + match token { PToken::Setup => { self.regs.intflag.write(|w| w.txstp().set_bit()); @@ -356,27 +385,39 @@ impl Pipe<'_, '_> { if self.is_transfer_complete(token)? { Ok(true) } else if self.regs.intflag.read().stall().bit_is_set() { + warn!("stall"); + self.log_regs(); self.regs.intflag.write(|w| w.stall().set_bit()); Err(PipeErr::Stall) } else if self.regs.intflag.read().trfail().bit_is_set() { + warn!("trfail"); + self.log_regs(); self.regs.intflag.write(|w| w.trfail().set_bit()); Err(PipeErr::TransferFail) } else if self.regs.intflag.read().perr().bit_is_set() { + warn!("perr"); + self.log_regs(); self.regs.intflag.write(|w| w.perr().set_bit()); Err(PipeErr::PipeErr) } else if self.desc.bank0.status_bk.read().errorflow().bit_is_set() { + warn!("errorflow"); + self.log_regs(); self.desc .bank0 .status_bk .write(|w| w.errorflow().clear_bit()); Err(PipeErr::Flow) } else if self.desc.bank0.status_pipe.read().touter().bit_is_set() { + warn!("touter"); + self.log_regs(); self.desc .bank0 .status_pipe .write(|w| w.touter().clear_bit()); Err(PipeErr::HWTimeout) } else if self.desc.bank0.status_pipe.read().dtgler().bit_is_set() { + warn!("dtgler"); + self.log_regs(); self.desc .bank0 .status_pipe |