diff options
Diffstat (limited to 'usbh/src/usbproto.rs')
-rw-r--r-- | usbh/src/usbproto.rs | 144 |
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); + } +} |