aboutsummaryrefslogtreecommitdiffstats
path: root/usbh/src/device.rs
diff options
context:
space:
mode:
Diffstat (limited to 'usbh/src/device.rs')
-rw-r--r--usbh/src/device.rs78
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,
+}