aboutsummaryrefslogtreecommitdiffstats
path: root/usbh/src/usbproto.rs
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2019-08-04 14:19:25 -0400
committerBrian Cully <bjc@kublai.com>2019-08-04 14:19:25 -0400
commite405c474f5e0e94288191223de7ae0f31ae0b15f (patch)
tree4ca89a92f0c868eb8feae272513c1e924b834adc /usbh/src/usbproto.rs
parentabd478d9425dd2d4acd5b58202b1a95b73ff217b (diff)
downloadsamd21-demo-e405c474f5e0e94288191223de7ae0f31ae0b15f.tar.gz
samd21-demo-e405c474f5e0e94288191223de7ae0f31ae0b15f.zip
Migrate everything over to separate libraries.
* `usb-host` is the crate containing the HAL traits. * `bootkbd` is a crate for a bare-bones boot protocol keyboard driver. * `samd21-host` is a crate with an implementation of `usb-host` for a SAMD21 platform, with an example for the trinket-m0 which uses the `bootkbd` driver to print keyboard reports.
Diffstat (limited to 'usbh/src/usbproto.rs')
-rw-r--r--usbh/src/usbproto.rs438
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);
- }
-}