From 7f3601e081f71776d3b5f9fc58d5e1adda7772a3 Mon Sep 17 00:00:00 2001 From: Brian Cully Date: Tue, 30 Jul 2019 18:26:10 -0400 Subject: WIP: Holy smokes I read my first keyboard report. Too bad it's still trfail town after the first, but progress! --- usbh/src/device.rs | 8 ++++---- usbh/src/pipe.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/usbh/src/device.rs b/usbh/src/device.rs index aaf82d1..6efc395 100644 --- a/usbh/src/device.rs +++ b/usbh/src/device.rs @@ -225,7 +225,7 @@ impl Device { debug!(" -- idle set"); debug!("+++ setting report"); - let mut rep_res: u8 = 0; + let mut report: u8 = 0; pipe.control_transfer( RequestType::from(( RequestDirection::HostToDevice, @@ -235,10 +235,10 @@ impl Device { RequestCode::SetConfiguration, WValue::from((0, 2)), 0, - Some(&mut rep_res), + Some(&mut report), self.millis, )?; - debug!(" -- report set: {}", rep_res); + debug!(" -- report set"); self.state = FSM::GetReport(3) } @@ -276,7 +276,7 @@ impl Device { } fn read_report(&mut self, pipe: &mut Pipe, id: u8) { - let mut buf: core::mem::MaybeUninit<[u8; 64]> = core::mem::MaybeUninit::uninit(); + let mut buf: core::mem::MaybeUninit<[u8; 8]> = core::mem::MaybeUninit::uninit(); match pipe.in_transfer(&mut buf, 15, self.millis) { Ok(bytes_received) => { let tmp = unsafe { &(buf.assume_init())[..bytes_received] }; 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( + &mut self, + buf: &mut T, + nak_limit: usize, + millis: &dyn Fn() -> usize, + ) -> Result { + 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( &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 -- cgit v1.2.3