aboutsummaryrefslogtreecommitdiffstats
path: root/usbh/src/usbproto.rs
diff options
context:
space:
mode:
Diffstat (limited to 'usbh/src/usbproto.rs')
-rw-r--r--usbh/src/usbproto.rs144
1 files changed, 130 insertions, 14 deletions
diff --git a/usbh/src/usbproto.rs b/usbh/src/usbproto.rs
index 9c1dbcb..246a9a4 100644
--- a/usbh/src/usbproto.rs
+++ b/usbh/src/usbproto.rs
@@ -6,11 +6,11 @@
// TODO: Put protocol section references in for types and
// documentation.
-#[derive(Copy, Clone, Debug, Default)]
-#[repr(C)]
+#[derive(Copy, Clone, Debug, Default, PartialEq)]
+#[repr(C, packed)]
pub struct USBDeviceDescriptor {
pub b_length: u8,
- pub b_descriptor_type: u8,
+ pub b_descriptor_type: USBDescriptor,
pub bcd_usb: u16,
pub b_device_class: u8,
pub b_device_sub_class: u8,
@@ -25,11 +25,11 @@ pub struct USBDeviceDescriptor {
pub b_num_configurations: u8,
}
-#[derive(Copy, Clone, Debug, Default)]
-#[repr(C)]
+#[derive(Copy, Clone, Debug, Default, PartialEq)]
+#[repr(C, packed)]
pub struct USBConfigurationDescriptor {
pub b_length: u8,
- pub b_descriptor_type: u8,
+ pub b_descriptor_type: USBDescriptor,
pub w_total_length: u16,
pub b_num_interfaces: u8,
pub b_configuration_value: u8,
@@ -38,11 +38,11 @@ pub struct USBConfigurationDescriptor {
pub b_max_power: u8,
}
-#[derive(Copy, Clone, Debug, Default)]
-#[repr(C)]
+#[derive(Copy, Clone, Debug, Default, PartialEq)]
+#[repr(C, packed)]
pub struct USBInterfaceDescriptor {
pub b_length: u8,
- pub b_descriptor_type: u8,
+ pub b_descriptor_type: USBDescriptor,
pub b_interface_number: u8,
pub b_alternate_setting: u8,
pub b_num_endpoints: u8,
@@ -52,19 +52,19 @@ pub struct USBInterfaceDescriptor {
pub i_interface: u8,
}
-#[derive(Copy, Clone, Debug, Default)]
-#[repr(C)]
+#[derive(Copy, Clone, Debug, Default, PartialEq)]
+#[repr(C, packed)]
pub struct USBEndpointDescriptor {
pub b_length: u8,
- pub b_descriptor_type: u8,
+ pub b_descriptor_type: USBDescriptor,
pub b_endpoint_address: u8,
pub bm_attributes: u8,
pub w_max_packet_size: u16,
pub b_interval: u8,
}
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
+#[derive(Copy, Clone, Debug, Default, PartialEq)]
+#[repr(C, packed)]
pub struct USBSetupPacket {
pub bm_request_type: BMRequestType,
pub b_request: USBRequest,
@@ -289,6 +289,11 @@ where
}
}
}
+impl Default for USBRequest {
+ fn default() -> Self {
+ Self::GetStatus
+ }
+}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum USBFeature {
@@ -309,6 +314,11 @@ pub enum USBDescriptor {
InterfacePower = 0x08,
OTG = 0x09,
}
+impl Default for USBDescriptor {
+ fn default() -> Self {
+ Self::Device
+ }
+}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum HIDDescriptor {
@@ -329,3 +339,109 @@ pub enum USBTransferType {
Bulk = 0x02,
Interrupt = 0x03,
}
+
+#[cfg(test)]
+mod test {
+ use super::super::pipe::DataBuf;
+ use super::*;
+
+ #[test]
+ fn dev_desc_serialize() {
+ let desc = USBDeviceDescriptor {
+ b_length: 18,
+ b_descriptor_type: USBDescriptor::Device,
+ bcd_usb: 0x0110,
+ b_device_class: 0x02,
+ b_device_sub_class: 0x03,
+ b_device_protocol: 0x04,
+ b_max_packet_size: 64,
+ id_vendor: 0xdead,
+ id_product: 0xbeef,
+ bcd_device: 0x5432,
+ i_manufacturer: 0xa0,
+ i_product: 0xa1,
+ i_serial_number: 0xa2,
+ b_num_configurations: 1,
+ };
+ let db = DataBuf::from(&desc);
+ assert_eq!(db.len, 18);
+ let want = [
+ 0x12, 0x01, 0x10, 0x01, 0x02, 0x03, 0x04, 64, 0xad, 0xde, 0xef, 0xbe, 0x32, 0x54, 0xa0,
+ 0xa1, 0xa2, 1,
+ ];
+ let got = unsafe { core::slice::from_raw_parts(db.ptr, db.len) };
+ assert_eq!(got, want);
+ }
+
+ #[test]
+ fn config_desc_serialize() {
+ let desc = USBConfigurationDescriptor {
+ b_length: 18,
+ b_descriptor_type: USBDescriptor::Configuration,
+ w_total_length: 0x20,
+ b_num_interfaces: 5,
+ b_configuration_value: 10,
+ i_configuration: 1,
+ bm_attributes: 0x40,
+ b_max_power: 0xfa,
+ };
+ let db = DataBuf::from(&desc);
+ assert_eq!(db.len, 9);
+ let want = [0x12, 0x02, 0x20, 0x00, 0x05, 0x0a, 0x01, 0x40, 0xfa];
+ let got = unsafe { core::slice::from_raw_parts(db.ptr, db.len) };
+ assert_eq!(got, want);
+ }
+
+ #[test]
+ fn interface_desc_serialize() {
+ let desc = USBInterfaceDescriptor {
+ b_length: 18,
+ b_descriptor_type: USBDescriptor::Interface,
+ b_interface_number: 2,
+ b_alternate_setting: 0xaa,
+ b_num_endpoints: 5,
+ b_interface_class: 0x11,
+ b_interface_sub_class: 0x22,
+ b_interface_protocol: 0x33,
+ i_interface: 10,
+ };
+ let db = DataBuf::from(&desc);
+ assert_eq!(db.len, 9);
+ let want = [0x12, 0x04, 0x02, 0xaa, 0x05, 0x11, 0x22, 0x33, 0x0a];
+ let got = unsafe { core::slice::from_raw_parts(db.ptr, db.len) };
+ assert_eq!(got, want);
+ }
+
+ #[test]
+ fn endpoint_desc_serialize() {
+ let desc = USBEndpointDescriptor {
+ b_length: 18,
+ b_descriptor_type: USBDescriptor::Endpoint,
+ b_endpoint_address: 1,
+ bm_attributes: 0x22,
+ w_max_packet_size: 0xdead,
+ b_interval: 0x33,
+ };
+ let db = DataBuf::from(&desc);
+ assert_eq!(db.len, 7);
+ let want = [0x12, 0x05, 0x01, 0x22, 0xad, 0xde, 0x33];
+ let got = unsafe { core::slice::from_raw_parts(db.ptr, db.len) };
+ assert_eq!(got, want);
+ }
+
+ #[test]
+ fn setup_packet_serialize() {
+ let setup_packet = USBSetupPacket {
+ bm_request_type: BMRequestType::get_descr(),
+ b_request: USBRequest::GetDescriptor,
+ w_value: WValue::from((0x00, 0x01)),
+ w_index: 0xbeef,
+ w_length: 18,
+ };
+ let db = DataBuf::from(&setup_packet);
+ assert_eq!(db.len, 8);
+ let want = [0x80, 0x06, 0x00, 0x01, 0xef, 0xbe, 0x012, 0x00];
+ let got = unsafe { core::slice::from_raw_parts(db.ptr, db.len) };
+ assert_eq!(got, want);
+ }
+}