diff options
Diffstat (limited to 'usbh/src/usbproto.rs')
| -rw-r--r-- | usbh/src/usbproto.rs | 438 |
1 files changed, 0 insertions, 438 deletions
diff --git a/usbh/src/usbproto.rs b/usbh/src/usbproto.rs deleted file mode 100644 index 33bc28c..0000000 --- a/usbh/src/usbproto.rs +++ /dev/null @@ -1,438 +0,0 @@ -/// USB Protocol level types and functions. -/// -/// Everything in here is defined by the USB specification, and -/// hardware independent. -use core::convert::TryFrom; -use core::convert::TryInto; - -// TODO: Put protocol section references in for types and -// documentation. - -#[derive(Copy, Clone, Debug, Default, PartialEq)] -#[repr(C, packed)] -pub struct DeviceDescriptor { - pub b_length: u8, - pub b_descriptor_type: DescriptorType, - pub bcd_usb: u16, - pub b_device_class: u8, - pub b_device_sub_class: u8, - pub b_device_protocol: u8, - pub b_max_packet_size: u8, - pub id_vendor: u16, - pub id_product: u16, - pub bcd_device: u16, - pub i_manufacturer: u8, - pub i_product: u8, - pub i_serial_number: u8, - pub b_num_configurations: u8, -} - -#[derive(Copy, Clone, Debug, Default, PartialEq)] -#[repr(C, packed)] -pub struct ConfigurationDescriptor { - pub b_length: u8, - pub b_descriptor_type: DescriptorType, - pub w_total_length: u16, - pub b_num_interfaces: u8, - pub b_configuration_value: u8, - pub i_configuration: u8, - pub bm_attributes: u8, - pub b_max_power: u8, -} - -#[derive(Copy, Clone, Debug, Default, PartialEq)] -#[repr(C, packed)] -pub struct InterfaceDescriptor { - pub b_length: u8, - pub b_descriptor_type: DescriptorType, - pub b_interface_number: u8, - pub b_alternate_setting: u8, - pub b_num_endpoints: u8, - pub b_interface_class: u8, - pub b_interface_sub_class: u8, - pub b_interface_protocol: u8, - pub i_interface: u8, -} - -#[derive(Copy, Clone, Debug, Default, PartialEq)] -#[repr(C, packed)] -pub struct EndpointDescriptor { - pub b_length: u8, - pub b_descriptor_type: DescriptorType, - pub b_endpoint_address: u8, - pub bm_attributes: u8, - pub w_max_packet_size: u16, - pub b_interval: u8, -} - -#[derive(Copy, Clone, Debug, Default, PartialEq)] -#[repr(C, packed)] -pub struct SetupPacket { - pub bm_request_type: RequestType, - pub b_request: RequestCode, - pub w_value: WValue, - pub w_index: u16, - pub w_length: u16, -} - -#[derive(Clone, Copy, Debug, Default, PartialEq)] -#[repr(C)] -pub struct RequestType(u8); -impl RequestType { - // Get descriptor request type. - pub fn get_descr() -> Self { - Self::from(( - RequestDirection::DeviceToHost, - RequestKind::Standard, - RequestRecipient::Device, - )) - } - - // Set request type for all but 'set feature' and 'set interface'. - pub fn set() -> Self { - Self::from(( - RequestDirection::HostToDevice, - RequestKind::Standard, - RequestRecipient::Device, - )) - } - - // Get interface request type. - pub fn cl_get_intf() -> Self { - Self::from(( - RequestDirection::DeviceToHost, - RequestKind::Class, - RequestRecipient::Interface, - )) - } - - pub fn recipient(&self) -> Result<RequestRecipient, &'static str> { - const POS: u8 = 0; - const MASK: u8 = 0x1f; - (self.0 & (MASK << POS)).try_into() - } - - pub fn set_recipient(&mut self, v: RequestRecipient) { - const POS: u8 = 0; - const MASK: u8 = 0x1f; - self.0 &= !(MASK << POS); - self.0 |= v as u8 & MASK; - } - - pub fn kind(&self) -> Result<RequestKind, &'static str> { - const POS: u8 = 5; - const MASK: u8 = 0x3; - (self.0 & (MASK << POS)).try_into() - } - - pub fn set_kind(&mut self, v: RequestKind) { - const POS: u8 = 5; - const MASK: u8 = 0x3; - self.0 &= !(MASK << POS); - self.0 |= v as u8 & MASK; - } - - pub fn direction(&self) -> Result<RequestDirection, &'static str> { - const POS: u8 = 7; - const MASK: u8 = 0x1; - (self.0 & (MASK << POS)).try_into() - } - - pub fn set_direction(&mut self, v: RequestDirection) { - const POS: u8 = 7; - const MASK: u8 = 0x1; - self.0 &= !(MASK << POS); - self.0 |= v as u8 & MASK; - } -} -impl From<(RequestDirection, RequestKind, RequestRecipient)> for RequestType { - fn from(v: (RequestDirection, RequestKind, RequestRecipient)) -> Self { - Self(v.0 as u8 | v.1 as u8 | v.2 as u8) - } -} - -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum RequestDirection { - HostToDevice = 0x00, - DeviceToHost = 0x80, -} -impl TryFrom<u8> for RequestDirection { - type Error = &'static str; - - fn try_from(v: u8) -> Result<Self, Self::Error> { - match v { - 0x00 => Ok(Self::HostToDevice), - 0x80 => Ok(Self::DeviceToHost), - _ => Err("direction can only be 0x00 or 0x80"), - } - } -} - -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum RequestKind { - Standard = 0x00, - Class = 0x20, - Vendor = 0x40, -} -impl TryFrom<u8> for RequestKind { - type Error = &'static str; - - fn try_from(v: u8) -> Result<Self, Self::Error> { - match v { - 0x00 => Ok(Self::Standard), - 0x20 => Ok(Self::Class), - 0x40 => Ok(Self::Vendor), - _ => Err("type can only be 0x00, 0x20, or 0x40"), - } - } -} - -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum RequestRecipient { - Device = 0x00, - Interface = 0x01, - Endpoint = 0x02, - Other = 0x03, -} -impl TryFrom<u8> for RequestRecipient { - type Error = &'static str; - - fn try_from(v: u8) -> Result<Self, Self::Error> { - match v { - 0x00 => Ok(Self::Device), - 0x01 => Ok(Self::Interface), - 0x02 => Ok(Self::Endpoint), - 0x03 => Ok(Self::Other), - _ => Err("recipient can only be between 0 and 3"), - } - } -} - -#[derive(Clone, Copy, Debug, Default, PartialEq)] -#[repr(C)] -pub struct WValue(u16); -impl WValue { - pub fn w_value_lo(&self) -> u8 { - const POS: u8 = 0; - const MASK: u16 = 0xff; - ((self.0 >> POS) & MASK) as u8 - } - - pub fn set_w_value_lo(&mut self, v: u8) { - const POS: u8 = 0; - const MASK: u8 = 0xff; - self.0 &= !((MASK as u16) << POS); - self.0 |= ((v & MASK) as u16) << POS; - } - - pub fn w_value_hi(&self) -> u8 { - const POS: u8 = 8; - const MASK: u16 = 0xff; - ((self.0 >> POS) & MASK) as u8 - } - - pub fn set_w_value_hi(&mut self, v: u8) { - const POS: u8 = 8; - const MASK: u8 = 0xff; - self.0 &= !((MASK as u16) << POS); - self.0 |= ((v & MASK) as u16) << POS; - } -} -impl From<(u8, u8)> for WValue { - fn from(v: (u8, u8)) -> Self { - let mut rc = Self(0); - rc.set_w_value_lo(v.0); - rc.set_w_value_hi(v.1); - rc - } -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum RequestCode { - GetStatus = 0, - ClearFeature = 1, - SetFeature = 3, - SetAddress = 5, - GetDescriptor = 6, - SetDescriptor = 7, - GetConfiguration = 8, - SetConfiguration = 9, - GetInterface = 10, - SetInterface = 11, - SynchFrame = 12, -} -impl TryFrom<u8> for RequestCode { - type Error = &'static str; - - fn try_from(v: u8) -> Result<Self, Self::Error> { - match v { - 0 => Ok(Self::GetStatus), - 1 => Ok(Self::ClearFeature), - 3 => Ok(Self::SetFeature), - 5 => Ok(Self::SetAddress), - 6 => Ok(Self::GetDescriptor), - 7 => Ok(Self::SetDescriptor), - 8 => Ok(Self::GetConfiguration), - 9 => Ok(Self::SetConfiguration), - 10 => Ok(Self::GetInterface), - 11 => Ok(Self::SetInterface), - 12 => Ok(Self::SynchFrame), - _ => Err("invalid request value"), - } - } -} -impl Default for RequestCode { - fn default() -> Self { - Self::GetStatus - } -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum USBFeature { - EndpointHalt = 0, - DeviceRemoteWakeup = 1, - TestMode = 2, -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum DescriptorType { - Device = 1, - Configuration = 2, - String = 3, - Interface = 4, - Endpoint = 5, - DeviceQualifier = 6, - OtherSpeed = 7, - InterfacePower = 8, -} -impl Default for DescriptorType { - fn default() -> Self { - Self::Device - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn dev_desc_serialize() { - let desc = DeviceDescriptor { - b_length: 18, - b_descriptor_type: DescriptorType::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 want = [ - 0x12, 0x01, 0x10, 0x01, 0x02, 0x03, 0x04, 64, 0xad, 0xde, 0xef, 0xbe, 0x32, 0x54, 0xa0, - 0xa1, 0xa2, 1, - ]; - - serde_test(&desc, &want); - } - - #[test] - fn config_desc_serialize() { - let desc = ConfigurationDescriptor { - b_length: 18, - b_descriptor_type: DescriptorType::Configuration, - w_total_length: 0x20, - b_num_interfaces: 5, - b_configuration_value: 10, - i_configuration: 1, - bm_attributes: 0x40, - b_max_power: 0xfa, - }; - let want = [0x12, 0x02, 0x20, 0x00, 0x05, 0x0a, 0x01, 0x40, 0xfa]; - - serde_test(&desc, &want); - } - - #[test] - fn interface_desc_serialize() { - let desc = InterfaceDescriptor { - b_length: 18, - b_descriptor_type: DescriptorType::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 want = [0x12, 0x04, 0x02, 0xaa, 0x05, 0x11, 0x22, 0x33, 0x0a]; - - serde_test(&desc, &want); - } - - #[test] - fn endpoint_desc_serialize() { - let desc = EndpointDescriptor { - b_length: 18, - b_descriptor_type: DescriptorType::Endpoint, - b_endpoint_address: 1, - bm_attributes: 0x22, - w_max_packet_size: 0xdead, - b_interval: 0x33, - }; - let want = [0x12, 0x05, 0x01, 0x22, 0xad, 0xde, 0x33]; - - serde_test(&desc, &want); - } - - #[test] - fn setup_packet_serialize() { - let setup_packet = SetupPacket { - bm_request_type: RequestType::get_descr(), - b_request: RequestCode::GetDescriptor, - w_value: WValue::from((0x00, 0x01)), - w_index: 0xbeef, - w_length: 18, - }; - let want = [0x80, 0x06, 0x00, 0x01, 0xef, 0xbe, 0x012, 0x00]; - - serde_test(&setup_packet, &want); - } - - fn serde_test<T>(native: &T, raw: &[u8]) - where - T: Default + PartialEq + core::fmt::Debug, - { - ser_test(native, raw); - de_test(raw, native); - } - - fn ser_test<T>(native: &T, raw: &[u8]) { - let ptr = native as *const T as *const u8; - let len = core::mem::size_of::<T>(); - assert_eq!(len, raw.len()); - let got_raw = unsafe { core::slice::from_raw_parts(ptr, len) }; - assert_eq!(got_raw, raw); - } - - fn de_test<T>(raw: &[u8], native: &T) - where - T: Default + PartialEq + core::fmt::Debug, - { - let mut got_native: T = Default::default(); - let ptr = &mut got_native as *mut T as *mut u8; - let len = core::mem::size_of::<T>(); - assert_eq!(raw.len(), len); - let dbslice = unsafe { core::slice::from_raw_parts_mut(ptr, len) }; - for i in 0..len { - dbslice[i] = raw[i]; - } - assert_eq!(got_native, *native); - } -} |
