aboutsummaryrefslogtreecommitdiffstats
path: root/usbh
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2019-07-25 14:43:09 -0400
committerBrian Cully <bjc@kublai.com>2019-07-25 14:43:31 -0400
commit9839be45a1523c6dba392ebd0cdef858157f6724 (patch)
treecbd4a5de7f0eda03d34f4243a1ea9d1fb5551c30 /usbh
parentb3ea2870b33ff3f6414d7689d4f452dd7313036d (diff)
downloadsamd21-demo-9839be45a1523c6dba392ebd0cdef858157f6724.tar.gz
samd21-demo-9839be45a1523c6dba392ebd0cdef858157f6724.zip
Put packet repr back. Add tests.
Packed was causing problems for logging, so use derived Debug impl instead. Add tests to make sure serialization works as expected.
Diffstat (limited to 'usbh')
-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);
+ }
+}