#[repr(C)]
#[derive(Clone, Copy, Default, Debug)]
pub struct SetupPacket {
pub request_type: u8,
pub request: u8,
pub value: u16,
pub index: u16,
pub length: u16,
}
impl From<[u8; 8]> for SetupPacket {
fn from(buffer: [u8; 8]) -> Self {
unsafe { core::mem::transmute::<[u8; 8], SetupPacket>(buffer) }
}
}
impl SetupPacket {
#[must_use]
pub fn as_bytes(setup_packet: SetupPacket) -> [u8; 8] {
unsafe { core::mem::transmute::<SetupPacket, [u8; 8]>(setup_packet) }
}
}
impl SetupPacket {
#[must_use]
pub fn request_type(&self) -> RequestType {
RequestType::from(self.request_type)
}
#[must_use]
pub fn recipient(&self) -> Recipient {
Recipient::from(self.request_type)
}
#[must_use]
pub fn direction(&self) -> Direction {
Direction::from(self.request_type)
}
#[must_use]
pub fn request(&self) -> Request {
Request::from(self.request)
}
}
#[derive(Debug, PartialEq)]
#[repr(u8)]
pub enum Recipient {
Device = 0,
Interface = 1,
Endpoint = 2,
Other = 3,
Reserved = 4,
}
impl From<u8> for Recipient {
fn from(value: u8) -> Self {
match value & 0b0001_1111 {
0 => Recipient::Device,
1 => Recipient::Interface,
2 => Recipient::Endpoint,
3 => Recipient::Other,
4..=u8::MAX => Recipient::Reserved,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(u8)]
pub enum RequestType {
Standard = 0,
Class = 1,
Vendor = 2,
Reserved(u8) = 3,
}
impl From<u8> for RequestType {
fn from(value: u8) -> Self {
match (value >> 5) & 0b0000_0011 {
0 => RequestType::Standard,
1 => RequestType::Class,
2 => RequestType::Vendor,
3..=u8::MAX => RequestType::Reserved(value),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u8)]
pub enum Direction {
HostToDevice = 0x00,
DeviceToHost = 0x80, }
impl Direction {
pub const OUT: Direction = Direction::HostToDevice;
pub const IN: Direction = Direction::DeviceToHost;
}
impl From<u8> for Direction {
fn from(endpoint_or_request_type: u8) -> Self {
if endpoint_or_request_type & 0b1000_0000 == 0 {
Direction::HostToDevice
} else {
Direction::DeviceToHost
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(u8)]
pub enum Request {
GetStatus = 0,
ClearFeature = 1,
SetFeature = 3,
SetAddress = 5,
GetDescriptor = 6,
SetDescriptor = 7,
GetConfiguration = 8,
SetConfiguration = 9,
GetInterface = 10,
SetInterface = 11,
SynchronizeFrame = 12,
ClassOrVendor(u8),
Reserved(u8),
}
impl From<u8> for Request {
fn from(value: u8) -> Self {
match value {
0 => Request::GetStatus,
1 => Request::ClearFeature,
2 => Request::Reserved(2),
3 => Request::SetFeature,
4 => Request::Reserved(4),
5 => Request::SetAddress,
6 => Request::GetDescriptor,
7 => Request::SetDescriptor,
8 => Request::GetConfiguration,
9 => Request::SetConfiguration,
10 => Request::GetInterface,
11 => Request::SetInterface,
12 => Request::SynchronizeFrame,
13..=u8::MAX => Request::ClassOrVendor(value),
}
}
}
#[derive(Debug, PartialEq)]
#[repr(u8)]
pub enum Feature {
EndpointHalt = 0,
DeviceRemoteWakeup = 1,
DeviceTestMode = 2,
DeviceBHnpEnable = 3,
DeviceAHnpSupport = 4,
DeviceAAltHnpSupport = 5,
Unknown(u16) = 255,
}
impl From<u16> for Feature {
fn from(value: u16) -> Self {
match value {
0 => Feature::EndpointHalt,
1 => Feature::DeviceRemoteWakeup,
2 => Feature::DeviceTestMode,
3 => Feature::DeviceBHnpEnable,
4 => Feature::DeviceAHnpSupport,
5 => Feature::DeviceAAltHnpSupport,
_ => Feature::Unknown(value),
}
}
}