diff options
author | Brian Cully <bjc@kublai.com> | 2019-07-27 14:52:27 -0400 |
---|---|---|
committer | Brian Cully <bjc@kublai.com> | 2019-07-27 14:52:27 -0400 |
commit | e0a9f75354564b22ef41b4a3a58e5ff321a3fc25 (patch) | |
tree | f6a1c4b5d9000c5ddc657e44ca2ec60a1aea3d9a /usbh/src/lib.rs | |
parent | 4421c02a3e98d8b9e3af8db207dfeb9d276e2962 (diff) | |
download | samd21-demo-e0a9f75354564b22ef41b4a3a58e5ff321a3fc25.tar.gz samd21-demo-e0a9f75354564b22ef41b4a3a58e5ff321a3fc25.zip |
WIP: we have lights on the keyboard!
Diffstat (limited to 'usbh/src/lib.rs')
-rwxr-xr-x | usbh/src/lib.rs | 87 |
1 files changed, 66 insertions, 21 deletions
diff --git a/usbh/src/lib.rs b/usbh/src/lib.rs index 8c19a3c..63b5581 100755 --- a/usbh/src/lib.rs +++ b/usbh/src/lib.rs @@ -1,9 +1,11 @@ #![no_std] #![allow(dead_code)] +mod device; mod pipe; mod usbproto; +use device::DeviceTable; use pipe::{DataBuf, PipeErr, PipeTable, USBPipeType, USBToken}; use rb::{Reader, RingBuffer, Writer}; use usbproto::*; @@ -55,7 +57,6 @@ enum TaskState { Steady(SteadyState), } -const MAX_DEVICES: usize = 16; const SETTLE_DELAY: usize = 205; // Delay in sec/1024 const NAK_LIMIT: usize = 15; @@ -78,6 +79,8 @@ where // register. pipe_table: PipeTable, + devices: DeviceTable, + // need sof 1kHz pad? _sof_pad: gpio::Pa23<gpio::PfG>, _dm_pad: gpio::Pa24<gpio::PfG>, @@ -104,13 +107,18 @@ where millis: &'static F, ) -> (Self, impl FnMut()) { let (eventr, mut eventw) = unsafe { EVENTS.split() }; + let mut rc = Self { usb: usb, + events: eventr, task_state: TaskState::Detached(DetachedState::Initialize), delay: 0, + pipe_table: PipeTable::new(), + devices: DeviceTable::new(), + _sof_pad: sof_pin.into_function_g(port), _dm_pad: dm_pin.into_function_g(port), _dp_pad: dp_pin.into_function_g(port), @@ -265,9 +273,7 @@ where } } - fn poll_devices(&mut self) { - for _ in 0..MAX_DEVICES {} - } + fn poll_devices(&mut self) {} fn fsm(&mut self) { // respond to events from interrupt. @@ -353,10 +359,7 @@ where } fn configure_dev(&mut self, _parent: u32, _port: u32, _low_speed: u32) -> Result<(), PipeErr> { - // addr: 0x20007774 - let tmp: USBDeviceDescriptor = Default::default(); - // addr: 0x20007788 - let mut vol_descr = ::vcell::VolatileCell::new(tmp); + let mut vol_descr = ::vcell::VolatileCell::<USBDeviceDescriptor>::new(Default::default()); self.control_req( 0, 0, @@ -373,7 +376,7 @@ where // Assign address to this device and: // - Stash bMaxPacketSize // Then SET_ADDRESS(newAddr) - let new_address: u8 = 1; + let new_address: u8 = 5; debug!("Setting address to {}.", new_address); self.control_req( 0, @@ -388,26 +391,62 @@ where let until = (self.millis)() + 300; while (self.millis)() < until {} - debug!("getting config with array"); - //let tmp: USBConfigurationDescriptor = Default::default(); - let mut tmp: [u8; 9] = [0; 9]; - //let vol_descr = ::vcell::VolatileCell::new(tmp); + // Everything after this point is what linux does. So do that? + + // Dunno why we get the device descriptor a second time. + trace!( + " -- getting devDesc2 from {}:{}: {:?}", + new_address, + 0, + desc + ); + let tmp: USBDeviceDescriptor = Default::default(); + let mut vol_descr = ::vcell::VolatileCell::new(tmp); self.control_req( new_address, 0, BMRequestType::get_descr(), - USBRequest::GetConfiguration, - WValue::from((0, 0)), + USBRequest::GetDescriptor, + WValue::from((0, USBDescriptor::Device as u8)), 0, - Some(DataBuf::from(&mut tmp)), + Some(DataBuf::from(&mut vol_descr)), + )?; + + let desc = vol_descr.get(); + trace!(" -- devDesc2: {:?}", desc); + + // Get config descriptor with minimal data, to see how much we need to allocate for the full descriptor. + let mut vol_descr = + ::vcell::VolatileCell::<USBConfigurationDescriptor>::new(Default::default()); + self.control_req( + new_address, + 0, + BMRequestType::get_descr(), + USBRequest::GetDescriptor, + WValue::from((0, USBDescriptor::Configuration as u8)), + 0, + Some(DataBuf::from(&mut vol_descr)), )?; + let desc = vol_descr.get(); + debug!("config: {:?}", desc); - //let desc = vol_descr.get(); - debug!("cdesc.len: {}, type: {}", tmp[0], tmp[1]); + // TODO: do real allocation later. + assert!(desc.w_total_length < 64); + let buf: [u8; 64] = [0; 64]; + let mut tmp = &buf[..desc.w_total_length as usize]; + self.control_req( + new_address, + 0, + BMRequestType::get_descr(), + USBRequest::GetDescriptor, + WValue::from((0, USBDescriptor::Configuration as u8)), + 0, + Some(DataBuf::from(&mut tmp)), + )?; // Once addressed, SET_CONFIGURATION(0) debug!("+++ setting configuration"); - let conf: u8 = 0; + let conf: u8 = 1; self.control_req( new_address, 0, @@ -439,6 +478,9 @@ where assert!(b.len <= 65_535); } + // Pipe data toggles for control pipes defined in SAMD21 data + // sheet ยง32.6.3.9 + /* * Setup stage. */ @@ -453,6 +495,7 @@ where }, }; let mut pipe = self.pipe_table.pipe_for(self.usb.host_mut(), addr, ep); + pipe.dtgl_clear(); pipe.send( USBToken::Setup, &DataBuf::from(&mut setup_packet), @@ -463,6 +506,7 @@ where /* * Data stage. */ + pipe.dtgl_set(); if let Some(b) = buf { match bm_request_type.direction() { USBSetupDirection::DeviceToHost => { @@ -480,9 +524,10 @@ where /* * Status stage. */ + pipe.dtgl_set(); pipe.desc.bank0.pcksize.write(|w| { - // FIXME: see note in `Pipe.send`. - unsafe { w.bits(0) } + unsafe { w.byte_count().bits(0) }; + unsafe { w.multi_packet_size().bits(0) } }); // PSTATUSSET.DTGL set -- TODO: figure out if this is |