diff options
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, +} |