diff options
author | Brian Cully <bjc@kublai.com> | 2019-08-01 21:16:07 -0400 |
---|---|---|
committer | Brian Cully <bjc@kublai.com> | 2019-08-01 21:16:07 -0400 |
commit | c2119f219eb538fa3ebcb942e99f615a7b1be266 (patch) | |
tree | c693ab90991c434f51dd8f35e2ce967759ec11e2 /usbh/src/lib.rs | |
parent | 7f3601e081f71776d3b5f9fc58d5e1adda7772a3 (diff) | |
download | samd21-demo-c2119f219eb538fa3ebcb942e99f615a7b1be266.tar.gz samd21-demo-c2119f219eb538fa3ebcb942e99f615a7b1be266.zip |
Refactor so Endpoint controls pipe characteristics.
Endpoints know their own address, number, max packet size, and data
toggle states. When a pipe is needed, pass in the endpoint its needed
for so that configuration can happen according to that endpoint.
Diffstat (limited to 'usbh/src/lib.rs')
-rwxr-xr-x | usbh/src/lib.rs | 35 |
1 files changed, 12 insertions, 23 deletions
diff --git a/usbh/src/lib.rs b/usbh/src/lib.rs index 63b28ba..1ed414c 100755 --- a/usbh/src/lib.rs +++ b/usbh/src/lib.rs @@ -5,8 +5,8 @@ mod device; mod pipe; mod usbproto; -use device::DeviceTable; -use pipe::{PType, PipeErr, PipeTable, NO_DATA_STAGE}; +use device::{Device, DeviceTable}; +use pipe::{PipeErr, PipeTable, NO_DATA_STAGE}; use rb::{Reader, RingBuffer, Writer}; use usbproto::*; @@ -57,6 +57,7 @@ enum TaskState { Steady(SteadyState), } +// Must be at least 100ms. cf §9.1.2 of USB 2.0. const SETTLE_DELAY: usize = 205; // Delay in sec/1024 const NAK_LIMIT: usize = 15; @@ -79,6 +80,7 @@ where pipe_table: PipeTable, devices: DeviceTable, + addr0: Device, // need sof 1kHz pad? _sof_pad: gpio::Pa23<gpio::PfG>, @@ -115,7 +117,8 @@ where pipe_table: PipeTable::new(), - devices: DeviceTable::new(), + devices: DeviceTable::new(millis), + addr0: Device::new(0, 8, millis), _sof_pad: sof_pin.into_function_g(port), _dm_pad: dm_pin.into_function_g(port), @@ -314,9 +317,6 @@ where trace!("reset was sent"); self.usb.host().intflag.write(|w| w.rst().set_bit()); - // Make sure we always have a control pipe set up. - self.init_pipe0(); - // Seems unneccesary, since SOFE will be set // immediately after reset according to §32.6.3.3. self.usb.host().ctrlb.modify(|_, w| w.sofe().set_bit()); @@ -358,9 +358,12 @@ where } fn configure_dev(&mut self) -> Result<(), PipeErr> { - let mut pipe = self.pipe_table.pipe_for(self.usb.host_mut(), 0, 0); + let mut pipe = self + .pipe_table + .pipe_for(self.usb.host_mut(), &self.addr0.ep0); let mut vol_descr = ::vcell::VolatileCell::<DeviceDescriptor>::new(Default::default()); pipe.control_transfer( + &mut self.addr0.ep0, RequestType::get_descr(), RequestCode::GetDescriptor, WValue::from((0, DescriptorType::Device as u8)), @@ -372,13 +375,13 @@ where let desc = vol_descr.get(); trace!(" -- devDesc: {:?}", desc); - match self.devices.next(self.millis) { + match self.devices.next(desc.b_max_packet_size, self.millis) { // TODO: new error for being out of devices. None => Err(PipeErr::Other("out of devices")), Some(device) => { - device.max_packet_size = desc.b_max_packet_size; debug!("Setting address to {}.", device.addr); pipe.control_transfer( + &mut self.addr0.ep0, RequestType::set(), RequestCode::SetAddress, WValue::from((device.addr, 0)), @@ -393,20 +396,6 @@ where } } } - - // Set up a default pipe for the control endpoint 0 on pipe 0. - fn init_pipe0(&mut self) { - let speed = self.usb.host().status.read().speed().bits(); - let pipe = self.pipe_table.pipe_for(self.usb.host_mut(), 0, 0); - pipe.regs.cfg.write(|w| { - unsafe { w.ptype().bits(PType::Control as u8) }; - w.bk().clear_bit() - }); - pipe.desc.bank0.pcksize.write(|w| match speed { - 0 => w.size().bytes64(), - _ => w.size().bytes8(), - }); - } } pub fn handler(usbp: usize, events: &mut EventWriter) { |