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/device.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/device.rs')
-rw-r--r-- | usbh/src/device.rs | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/usbh/src/device.rs b/usbh/src/device.rs new file mode 100644 index 0000000..3bb0304 --- /dev/null +++ b/usbh/src/device.rs @@ -0,0 +1,78 @@ +use core::convert::TryInto; + +const MAX_DEVICES: usize = 16; +const MAX_ENDPOINTS: usize = 8; + +pub struct DeviceTable { + devices: [Option<Device>; MAX_DEVICES], +} +impl DeviceTable { + pub fn new() -> Self { + Self { + devices: Default::default(), + } + } + + /// Return the device at address `addr`. + pub fn device_for(&mut self, addr: u8) -> Option<&mut Device> { + if let Some(ref mut d) = self.devices[addr as usize] { + Some(d) + } else { + None + } + } + + /// Allocate a device with the next available address. + pub fn next(&mut self) -> Option<&mut Device> { + for i in 0..self.devices.len() { + if self.devices[i].is_none() { + let a = i.try_into().unwrap(); + let mut d: Device = Default::default(); + d.addr = a; + self.devices[i] = Some(d); + return self.device_for(a); + } + } + None + } + + /// Remove the device at address `addr`. + pub fn remove(&mut self, addr: u8) -> Option<Device> { + let v = core::mem::replace(&mut self.devices[addr as usize], None); + v + } +} + +pub struct Device { + addr: u8, + max_packet_size: u8, + endpoints: [Endpoint; MAX_ENDPOINTS], +} +impl Default for Device { + fn default() -> Self { + Self { + addr: 0, + max_packet_size: 8, + endpoints: Default::default(), + } + } +} + +pub struct Endpoint { + num: u8, + typ: EndpointType, +} +impl Default for Endpoint { + fn default() -> Self { + Self { + num: 0, + typ: EndpointType::Control, + } + } +} + +enum EndpointType { + Control, + In, + Out, +} |