diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-09-26 12:29:27 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-09-26 12:29:27 +0200 |
| commit | 7f7c14b7bce5b84eb27c8122535a96a6f0e5dd77 (patch) | |
| tree | c7481fd07b616128718301de7aafea553cc8dd6f /embassy-usb/src | |
| parent | a9efbf18c62186de0581ec72cca90a69340a02a3 (diff) | |
usb: split driver trait to separate crate.
Diffstat (limited to 'embassy-usb/src')
| -rw-r--r-- | embassy-usb/src/builder.rs | 11 | ||||
| -rw-r--r-- | embassy-usb/src/control.rs | 5 | ||||
| -rw-r--r-- | embassy-usb/src/descriptor.rs | 7 | ||||
| -rw-r--r-- | embassy-usb/src/descriptor_reader.rs | 2 | ||||
| -rw-r--r-- | embassy-usb/src/driver.rs | 232 | ||||
| -rw-r--r-- | embassy-usb/src/lib.rs | 18 | ||||
| -rw-r--r-- | embassy-usb/src/types.rs | 105 |
7 files changed, 22 insertions, 358 deletions
diff --git a/embassy-usb/src/builder.rs b/embassy-usb/src/builder.rs index 6be88bc76..87a8333bb 100644 --- a/embassy-usb/src/builder.rs +++ b/embassy-usb/src/builder.rs | |||
| @@ -1,11 +1,10 @@ | |||
| 1 | use heapless::Vec; | 1 | use heapless::Vec; |
| 2 | 2 | ||
| 3 | use super::control::ControlHandler; | 3 | use crate::control::ControlHandler; |
| 4 | use super::descriptor::{BosWriter, DescriptorWriter}; | 4 | use crate::descriptor::{BosWriter, DescriptorWriter}; |
| 5 | use super::driver::{Driver, Endpoint}; | 5 | use crate::driver::{Driver, Endpoint, EndpointType}; |
| 6 | use super::types::*; | 6 | use crate::types::*; |
| 7 | use super::{DeviceStateHandler, UsbDevice, MAX_INTERFACE_COUNT}; | 7 | use crate::{DeviceStateHandler, Interface, UsbDevice, MAX_INTERFACE_COUNT, STRING_INDEX_CUSTOM_START}; |
| 8 | use crate::{Interface, STRING_INDEX_CUSTOM_START}; | ||
| 9 | 8 | ||
| 10 | #[derive(Debug, Copy, Clone)] | 9 | #[derive(Debug, Copy, Clone)] |
| 11 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 10 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
diff --git a/embassy-usb/src/control.rs b/embassy-usb/src/control.rs index 3e5749a01..9e0dee888 100644 --- a/embassy-usb/src/control.rs +++ b/embassy-usb/src/control.rs | |||
| @@ -1,7 +1,8 @@ | |||
| 1 | //! USB control data types. | 1 | //! USB control data types. |
| 2 | use core::mem; | 2 | use core::mem; |
| 3 | 3 | ||
| 4 | use super::types::*; | 4 | use crate::driver::Direction; |
| 5 | use crate::types::StringIndex; | ||
| 5 | 6 | ||
| 6 | /// Control request type. | 7 | /// Control request type. |
| 7 | #[repr(u8)] | 8 | #[repr(u8)] |
| @@ -42,7 +43,7 @@ pub enum Recipient { | |||
| 42 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 43 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 43 | pub struct Request { | 44 | pub struct Request { |
| 44 | /// Direction of the request. | 45 | /// Direction of the request. |
| 45 | pub direction: UsbDirection, | 46 | pub direction: Direction, |
| 46 | /// Type of the request. | 47 | /// Type of the request. |
| 47 | pub request_type: RequestType, | 48 | pub request_type: RequestType, |
| 48 | /// Recipient of the request. | 49 | /// Recipient of the request. |
diff --git a/embassy-usb/src/descriptor.rs b/embassy-usb/src/descriptor.rs index b94a4b161..497f03196 100644 --- a/embassy-usb/src/descriptor.rs +++ b/embassy-usb/src/descriptor.rs | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | use super::builder::Config; | 1 | use crate::builder::Config; |
| 2 | use super::types::*; | 2 | use crate::driver::EndpointInfo; |
| 3 | use super::CONFIGURATION_VALUE; | 3 | use crate::types::*; |
| 4 | use crate::CONFIGURATION_VALUE; | ||
| 4 | 5 | ||
| 5 | /// Standard descriptor types | 6 | /// Standard descriptor types |
| 6 | #[allow(missing_docs)] | 7 | #[allow(missing_docs)] |
diff --git a/embassy-usb/src/descriptor_reader.rs b/embassy-usb/src/descriptor_reader.rs index 0a12b566c..d64bcb73b 100644 --- a/embassy-usb/src/descriptor_reader.rs +++ b/embassy-usb/src/descriptor_reader.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | use crate::descriptor::descriptor_type; | 1 | use crate::descriptor::descriptor_type; |
| 2 | use crate::types::EndpointAddress; | 2 | use crate::driver::EndpointAddress; |
| 3 | 3 | ||
| 4 | #[derive(Copy, Clone, PartialEq, Eq, Debug)] | 4 | #[derive(Copy, Clone, PartialEq, Eq, Debug)] |
| 5 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 5 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
diff --git a/embassy-usb/src/driver.rs b/embassy-usb/src/driver.rs deleted file mode 100644 index 7888f1639..000000000 --- a/embassy-usb/src/driver.rs +++ /dev/null | |||
| @@ -1,232 +0,0 @@ | |||
| 1 | use core::future::Future; | ||
| 2 | |||
| 3 | use super::types::*; | ||
| 4 | |||
| 5 | /// Driver for a specific USB peripheral. Implement this to add support for a new hardware | ||
| 6 | /// platform. | ||
| 7 | pub trait Driver<'a> { | ||
| 8 | type EndpointOut: EndpointOut + 'a; | ||
| 9 | type EndpointIn: EndpointIn + 'a; | ||
| 10 | type ControlPipe: ControlPipe + 'a; | ||
| 11 | type Bus: Bus + 'a; | ||
| 12 | |||
| 13 | /// Allocates an endpoint and specified endpoint parameters. This method is called by the device | ||
| 14 | /// and class implementations to allocate endpoints, and can only be called before | ||
| 15 | /// [`start`](Self::start) is called. | ||
| 16 | /// | ||
| 17 | /// # Arguments | ||
| 18 | /// | ||
| 19 | /// * `ep_addr` - A static endpoint address to allocate. If Some, the implementation should | ||
| 20 | /// attempt to return an endpoint with the specified address. If None, the implementation | ||
| 21 | /// should return the next available one. | ||
| 22 | /// * `max_packet_size` - Maximum packet size in bytes. | ||
| 23 | /// * `interval` - Polling interval parameter for interrupt endpoints. | ||
| 24 | fn alloc_endpoint_out( | ||
| 25 | &mut self, | ||
| 26 | ep_type: EndpointType, | ||
| 27 | max_packet_size: u16, | ||
| 28 | interval: u8, | ||
| 29 | ) -> Result<Self::EndpointOut, EndpointAllocError>; | ||
| 30 | |||
| 31 | fn alloc_endpoint_in( | ||
| 32 | &mut self, | ||
| 33 | ep_type: EndpointType, | ||
| 34 | max_packet_size: u16, | ||
| 35 | interval: u8, | ||
| 36 | ) -> Result<Self::EndpointIn, EndpointAllocError>; | ||
| 37 | |||
| 38 | /// Start operation of the USB device. | ||
| 39 | /// | ||
| 40 | /// This returns the `Bus` and `ControlPipe` instances that are used to operate | ||
| 41 | /// the USB device. Additionally, this makes all the previously allocated endpoints | ||
| 42 | /// start operating. | ||
| 43 | /// | ||
| 44 | /// This consumes the `Driver` instance, so it's no longer possible to allocate more | ||
| 45 | /// endpoints. | ||
| 46 | fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe); | ||
| 47 | |||
| 48 | /// Indicates that `set_device_address` must be called before accepting the corresponding | ||
| 49 | /// control transfer, not after. | ||
| 50 | /// | ||
| 51 | /// The default value for this constant is `false`, which corresponds to the USB 2.0 spec, 9.4.6 | ||
| 52 | const QUIRK_SET_ADDRESS_BEFORE_STATUS: bool = false; | ||
| 53 | } | ||
| 54 | |||
| 55 | pub trait Bus { | ||
| 56 | type EnableFuture<'a>: Future<Output = ()> + 'a | ||
| 57 | where | ||
| 58 | Self: 'a; | ||
| 59 | type DisableFuture<'a>: Future<Output = ()> + 'a | ||
| 60 | where | ||
| 61 | Self: 'a; | ||
| 62 | type PollFuture<'a>: Future<Output = Event> + 'a | ||
| 63 | where | ||
| 64 | Self: 'a; | ||
| 65 | type RemoteWakeupFuture<'a>: Future<Output = Result<(), Unsupported>> + 'a | ||
| 66 | where | ||
| 67 | Self: 'a; | ||
| 68 | |||
| 69 | /// Enables the USB peripheral. Soon after enabling the device will be reset, so | ||
| 70 | /// there is no need to perform a USB reset in this method. | ||
| 71 | fn enable(&mut self) -> Self::EnableFuture<'_>; | ||
| 72 | |||
| 73 | /// Disables and powers down the USB peripheral. | ||
| 74 | fn disable(&mut self) -> Self::DisableFuture<'_>; | ||
| 75 | |||
| 76 | fn poll<'a>(&'a mut self) -> Self::PollFuture<'a>; | ||
| 77 | |||
| 78 | /// Sets the device USB address to `addr`. | ||
| 79 | fn set_address(&mut self, addr: u8); | ||
| 80 | |||
| 81 | /// Enables or disables an endpoint. | ||
| 82 | fn endpoint_set_enabled(&mut self, ep_addr: EndpointAddress, enabled: bool); | ||
| 83 | |||
| 84 | /// Sets or clears the STALL condition for an endpoint. If the endpoint is an OUT endpoint, it | ||
| 85 | /// should be prepared to receive data again. Only used during control transfers. | ||
| 86 | fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool); | ||
| 87 | |||
| 88 | /// Gets whether the STALL condition is set for an endpoint. Only used during control transfers. | ||
| 89 | fn endpoint_is_stalled(&mut self, ep_addr: EndpointAddress) -> bool; | ||
| 90 | |||
| 91 | /// Simulates a disconnect from the USB bus, causing the host to reset and re-enumerate the | ||
| 92 | /// device. | ||
| 93 | /// | ||
| 94 | /// The default implementation just returns `Unsupported`. | ||
| 95 | /// | ||
| 96 | /// # Errors | ||
| 97 | /// | ||
| 98 | /// * [`Unsupported`](crate::driver::Unsupported) - This UsbBus implementation doesn't support | ||
| 99 | /// simulating a disconnect or it has not been enabled at creation time. | ||
| 100 | fn force_reset(&mut self) -> Result<(), Unsupported> { | ||
| 101 | Err(Unsupported) | ||
| 102 | } | ||
| 103 | |||
| 104 | /// Initiates a remote wakeup of the host by the device. | ||
| 105 | /// | ||
| 106 | /// # Errors | ||
| 107 | /// | ||
| 108 | /// * [`Unsupported`](crate::driver::Unsupported) - This UsbBus implementation doesn't support | ||
| 109 | /// remote wakeup or it has not been enabled at creation time. | ||
| 110 | fn remote_wakeup(&mut self) -> Self::RemoteWakeupFuture<'_>; | ||
| 111 | } | ||
| 112 | |||
| 113 | pub trait Endpoint { | ||
| 114 | type WaitEnabledFuture<'a>: Future<Output = ()> + 'a | ||
| 115 | where | ||
| 116 | Self: 'a; | ||
| 117 | |||
| 118 | /// Get the endpoint address | ||
| 119 | fn info(&self) -> &EndpointInfo; | ||
| 120 | |||
| 121 | /// Waits for the endpoint to be enabled. | ||
| 122 | fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_>; | ||
| 123 | } | ||
| 124 | |||
| 125 | pub trait EndpointOut: Endpoint { | ||
| 126 | type ReadFuture<'a>: Future<Output = Result<usize, EndpointError>> + 'a | ||
| 127 | where | ||
| 128 | Self: 'a; | ||
| 129 | |||
| 130 | /// Reads a single packet of data from the endpoint, and returns the actual length of | ||
| 131 | /// the packet. | ||
| 132 | /// | ||
| 133 | /// This should also clear any NAK flags and prepare the endpoint to receive the next packet. | ||
| 134 | fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a>; | ||
| 135 | } | ||
| 136 | |||
| 137 | pub trait ControlPipe { | ||
| 138 | type SetupFuture<'a>: Future<Output = [u8; 8]> + 'a | ||
| 139 | where | ||
| 140 | Self: 'a; | ||
| 141 | type DataOutFuture<'a>: Future<Output = Result<usize, EndpointError>> + 'a | ||
| 142 | where | ||
| 143 | Self: 'a; | ||
| 144 | type DataInFuture<'a>: Future<Output = Result<(), EndpointError>> + 'a | ||
| 145 | where | ||
| 146 | Self: 'a; | ||
| 147 | type AcceptFuture<'a>: Future<Output = ()> + 'a | ||
| 148 | where | ||
| 149 | Self: 'a; | ||
| 150 | type RejectFuture<'a>: Future<Output = ()> + 'a | ||
| 151 | where | ||
| 152 | Self: 'a; | ||
| 153 | |||
| 154 | /// Maximum packet size for the control pipe | ||
| 155 | fn max_packet_size(&self) -> usize; | ||
| 156 | |||
| 157 | /// Reads a single setup packet from the endpoint. | ||
| 158 | fn setup<'a>(&'a mut self) -> Self::SetupFuture<'a>; | ||
| 159 | |||
| 160 | /// Reads a DATA OUT packet into `buf` in response to a control write request. | ||
| 161 | /// | ||
| 162 | /// Must be called after `setup()` for requests with `direction` of `Out` | ||
| 163 | /// and `length` greater than zero. | ||
| 164 | fn data_out<'a>(&'a mut self, buf: &'a mut [u8], first: bool, last: bool) -> Self::DataOutFuture<'a>; | ||
| 165 | |||
| 166 | /// Sends a DATA IN packet with `data` in response to a control read request. | ||
| 167 | /// | ||
| 168 | /// If `last_packet` is true, the STATUS packet will be ACKed following the transfer of `data`. | ||
| 169 | fn data_in<'a>(&'a mut self, data: &'a [u8], first: bool, last: bool) -> Self::DataInFuture<'a>; | ||
| 170 | |||
| 171 | /// Accepts a control request. | ||
| 172 | /// | ||
| 173 | /// Causes the STATUS packet for the current request to be ACKed. | ||
| 174 | fn accept<'a>(&'a mut self) -> Self::AcceptFuture<'a>; | ||
| 175 | |||
| 176 | /// Rejects a control request. | ||
| 177 | /// | ||
| 178 | /// Sets a STALL condition on the pipe to indicate an error. | ||
| 179 | fn reject<'a>(&'a mut self) -> Self::RejectFuture<'a>; | ||
| 180 | } | ||
| 181 | |||
| 182 | pub trait EndpointIn: Endpoint { | ||
| 183 | type WriteFuture<'a>: Future<Output = Result<(), EndpointError>> + 'a | ||
| 184 | where | ||
| 185 | Self: 'a; | ||
| 186 | |||
| 187 | /// Writes a single packet of data to the endpoint. | ||
| 188 | fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a>; | ||
| 189 | } | ||
| 190 | |||
| 191 | #[derive(Copy, Clone, Eq, PartialEq, Debug)] | ||
| 192 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 193 | /// Event returned by [`Bus::poll`]. | ||
| 194 | pub enum Event { | ||
| 195 | /// The USB reset condition has been detected. | ||
| 196 | Reset, | ||
| 197 | |||
| 198 | /// A USB suspend request has been detected or, in the case of self-powered devices, the device | ||
| 199 | /// has been disconnected from the USB bus. | ||
| 200 | Suspend, | ||
| 201 | |||
| 202 | /// A USB resume request has been detected after being suspended or, in the case of self-powered | ||
| 203 | /// devices, the device has been connected to the USB bus. | ||
| 204 | Resume, | ||
| 205 | |||
| 206 | /// The USB power has been detected. | ||
| 207 | PowerDetected, | ||
| 208 | |||
| 209 | /// The USB power has been removed. Not supported by all devices. | ||
| 210 | PowerRemoved, | ||
| 211 | } | ||
| 212 | |||
| 213 | #[derive(Copy, Clone, Eq, PartialEq, Debug)] | ||
| 214 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 215 | pub struct EndpointAllocError; | ||
| 216 | |||
| 217 | #[derive(Copy, Clone, Eq, PartialEq, Debug)] | ||
| 218 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 219 | /// Operation is unsupported by the driver. | ||
| 220 | pub struct Unsupported; | ||
| 221 | |||
| 222 | #[derive(Copy, Clone, Eq, PartialEq, Debug)] | ||
| 223 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 224 | /// Errors returned by [`EndpointIn::write`] and [`EndpointOut::read`] | ||
| 225 | pub enum EndpointError { | ||
| 226 | /// Either the packet to be written is too long to fit in the transmission | ||
| 227 | /// buffer or the received packet is too long to fit in `buf`. | ||
| 228 | BufferOverflow, | ||
| 229 | |||
| 230 | /// The endpoint is disabled. | ||
| 231 | Disabled, | ||
| 232 | } | ||
diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index 6f58c953c..e1a99cfae 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs | |||
| @@ -4,23 +4,23 @@ | |||
| 4 | // This mod MUST go first, so that the others see its macros. | 4 | // This mod MUST go first, so that the others see its macros. |
| 5 | pub(crate) mod fmt; | 5 | pub(crate) mod fmt; |
| 6 | 6 | ||
| 7 | pub use embassy_usb_driver as driver; | ||
| 8 | |||
| 7 | mod builder; | 9 | mod builder; |
| 8 | pub mod control; | 10 | pub mod control; |
| 9 | pub mod descriptor; | 11 | pub mod descriptor; |
| 10 | mod descriptor_reader; | 12 | mod descriptor_reader; |
| 11 | pub mod driver; | ||
| 12 | pub mod types; | 13 | pub mod types; |
| 13 | 14 | ||
| 14 | use embassy_futures::select::{select, Either}; | 15 | use embassy_futures::select::{select, Either}; |
| 15 | use heapless::Vec; | 16 | use heapless::Vec; |
| 16 | 17 | ||
| 17 | pub use self::builder::{Builder, Config}; | 18 | pub use crate::builder::{Builder, Config}; |
| 18 | use self::control::*; | 19 | use crate::control::*; |
| 19 | use self::descriptor::*; | 20 | use crate::descriptor::*; |
| 20 | use self::driver::{Bus, Driver, Event}; | ||
| 21 | use self::types::*; | ||
| 22 | use crate::descriptor_reader::foreach_endpoint; | 21 | use crate::descriptor_reader::foreach_endpoint; |
| 23 | use crate::driver::ControlPipe; | 22 | use crate::driver::{Bus, ControlPipe, Direction, Driver, EndpointAddress, Event}; |
| 23 | use crate::types::*; | ||
| 24 | 24 | ||
| 25 | /// The global state of the USB device. | 25 | /// The global state of the USB device. |
| 26 | /// | 26 | /// |
| @@ -250,8 +250,8 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 250 | trace!("control request: {:?}", req); | 250 | trace!("control request: {:?}", req); |
| 251 | 251 | ||
| 252 | match req.direction { | 252 | match req.direction { |
| 253 | UsbDirection::In => self.handle_control_in(req).await, | 253 | Direction::In => self.handle_control_in(req).await, |
| 254 | UsbDirection::Out => self.handle_control_out(req).await, | 254 | Direction::Out => self.handle_control_out(req).await, |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | if self.inner.set_address_pending { | 257 | if self.inner.set_address_pending { |
diff --git a/embassy-usb/src/types.rs b/embassy-usb/src/types.rs index b8717ffa9..aeab063d1 100644 --- a/embassy-usb/src/types.rs +++ b/embassy-usb/src/types.rs | |||
| @@ -1,108 +1,3 @@ | |||
| 1 | /// Direction of USB traffic. Note that in the USB standard the direction is always indicated from | ||
| 2 | /// the perspective of the host, which is backward for devices, but the standard directions are used | ||
| 3 | /// for consistency. | ||
| 4 | /// | ||
| 5 | /// The values of the enum also match the direction bit used in endpoint addresses and control | ||
| 6 | /// request types. | ||
| 7 | #[repr(u8)] | ||
| 8 | #[derive(Copy, Clone, Eq, PartialEq, Debug)] | ||
| 9 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 10 | pub enum UsbDirection { | ||
| 11 | /// Host to device (OUT) | ||
| 12 | Out = 0x00, | ||
| 13 | /// Device to host (IN) | ||
| 14 | In = 0x80, | ||
| 15 | } | ||
| 16 | |||
| 17 | impl From<u8> for UsbDirection { | ||
| 18 | fn from(value: u8) -> Self { | ||
| 19 | unsafe { core::mem::transmute(value & 0x80) } | ||
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 23 | /// USB endpoint transfer type. The values of this enum can be directly cast into `u8` to get the | ||
| 24 | /// transfer bmAttributes transfer type bits. | ||
| 25 | #[repr(u8)] | ||
| 26 | #[derive(Copy, Clone, Eq, PartialEq, Debug)] | ||
| 27 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 28 | pub enum EndpointType { | ||
| 29 | /// Control endpoint. Used for device management. Only the host can initiate requests. Usually | ||
| 30 | /// used only endpoint 0. | ||
| 31 | Control = 0b00, | ||
| 32 | /// Isochronous endpoint. Used for time-critical unreliable data. Not implemented yet. | ||
| 33 | Isochronous = 0b01, | ||
| 34 | /// Bulk endpoint. Used for large amounts of best-effort reliable data. | ||
| 35 | Bulk = 0b10, | ||
| 36 | /// Interrupt endpoint. Used for small amounts of time-critical reliable data. | ||
| 37 | Interrupt = 0b11, | ||
| 38 | } | ||
| 39 | |||
| 40 | /// Type-safe endpoint address. | ||
| 41 | #[derive(Debug, Clone, Copy, Eq, PartialEq)] | ||
| 42 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 43 | pub struct EndpointAddress(u8); | ||
| 44 | |||
| 45 | impl From<u8> for EndpointAddress { | ||
| 46 | #[inline] | ||
| 47 | fn from(addr: u8) -> EndpointAddress { | ||
| 48 | EndpointAddress(addr) | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | impl From<EndpointAddress> for u8 { | ||
| 53 | #[inline] | ||
| 54 | fn from(addr: EndpointAddress) -> u8 { | ||
| 55 | addr.0 | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | impl EndpointAddress { | ||
| 60 | const INBITS: u8 = UsbDirection::In as u8; | ||
| 61 | |||
| 62 | /// Constructs a new EndpointAddress with the given index and direction. | ||
| 63 | #[inline] | ||
| 64 | pub fn from_parts(index: usize, dir: UsbDirection) -> Self { | ||
| 65 | EndpointAddress(index as u8 | dir as u8) | ||
| 66 | } | ||
| 67 | |||
| 68 | /// Gets the direction part of the address. | ||
| 69 | #[inline] | ||
| 70 | pub fn direction(&self) -> UsbDirection { | ||
| 71 | if (self.0 & Self::INBITS) != 0 { | ||
| 72 | UsbDirection::In | ||
| 73 | } else { | ||
| 74 | UsbDirection::Out | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | /// Returns true if the direction is IN, otherwise false. | ||
| 79 | #[inline] | ||
| 80 | pub fn is_in(&self) -> bool { | ||
| 81 | (self.0 & Self::INBITS) != 0 | ||
| 82 | } | ||
| 83 | |||
| 84 | /// Returns true if the direction is OUT, otherwise false. | ||
| 85 | #[inline] | ||
| 86 | pub fn is_out(&self) -> bool { | ||
| 87 | (self.0 & Self::INBITS) == 0 | ||
| 88 | } | ||
| 89 | |||
| 90 | /// Gets the index part of the endpoint address. | ||
| 91 | #[inline] | ||
| 92 | pub fn index(&self) -> usize { | ||
| 93 | (self.0 & !Self::INBITS) as usize | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | #[derive(Copy, Clone, Eq, PartialEq, Debug)] | ||
| 98 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 99 | pub struct EndpointInfo { | ||
| 100 | pub addr: EndpointAddress, | ||
| 101 | pub ep_type: EndpointType, | ||
| 102 | pub max_packet_size: u16, | ||
| 103 | pub interval: u8, | ||
| 104 | } | ||
| 105 | |||
| 106 | /// A handle for a USB interface that contains its number. | 1 | /// A handle for a USB interface that contains its number. |
| 107 | #[derive(Copy, Clone, Eq, PartialEq)] | 2 | #[derive(Copy, Clone, Eq, PartialEq)] |
| 108 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 3 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
