aboutsummaryrefslogtreecommitdiffstats
path: root/usbh/src/lib.rs
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2019-08-01 21:16:07 -0400
committerBrian Cully <bjc@kublai.com>2019-08-01 21:16:07 -0400
commitc2119f219eb538fa3ebcb942e99f615a7b1be266 (patch)
treec693ab90991c434f51dd8f35e2ce967759ec11e2 /usbh/src/lib.rs
parent7f3601e081f71776d3b5f9fc58d5e1adda7772a3 (diff)
downloadsamd21-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-xusbh/src/lib.rs35
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) {