diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-01-31 22:27:19 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-01-31 22:27:19 +0100 |
| commit | ca10fe7135d10084e38038f3cd433da39e505bea (patch) | |
| tree | 075aca4a76caccd1bba95869c64bbb838969c8b1 /embassy-usb/src/class | |
| parent | 4c1946454874597c358e7c7d5bf555b687376a5b (diff) | |
usb: docs
Diffstat (limited to 'embassy-usb/src/class')
| -rw-r--r-- | embassy-usb/src/class/cdc_acm.rs | 9 | ||||
| -rw-r--r-- | embassy-usb/src/class/cdc_ncm/embassy_net.rs | 11 | ||||
| -rw-r--r-- | embassy-usb/src/class/cdc_ncm/mod.rs | 51 | ||||
| -rw-r--r-- | embassy-usb/src/class/hid.rs | 21 | ||||
| -rw-r--r-- | embassy-usb/src/class/mod.rs | 1 |
5 files changed, 77 insertions, 16 deletions
diff --git a/embassy-usb/src/class/cdc_acm.rs b/embassy-usb/src/class/cdc_acm.rs index 84db20621..09f17456c 100644 --- a/embassy-usb/src/class/cdc_acm.rs +++ b/embassy-usb/src/class/cdc_acm.rs | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | //! CDC-ACM class implementation, aka Serial over USB. | ||
| 2 | |||
| 1 | use core::cell::Cell; | 3 | use core::cell::Cell; |
| 2 | use core::mem::{self, MaybeUninit}; | 4 | use core::mem::{self, MaybeUninit}; |
| 3 | use core::sync::atomic::{AtomicBool, Ordering}; | 5 | use core::sync::atomic::{AtomicBool, Ordering}; |
| @@ -28,12 +30,14 @@ const REQ_SET_LINE_CODING: u8 = 0x20; | |||
| 28 | const REQ_GET_LINE_CODING: u8 = 0x21; | 30 | const REQ_GET_LINE_CODING: u8 = 0x21; |
| 29 | const REQ_SET_CONTROL_LINE_STATE: u8 = 0x22; | 31 | const REQ_SET_CONTROL_LINE_STATE: u8 = 0x22; |
| 30 | 32 | ||
| 33 | /// Internal state for CDC-ACM | ||
| 31 | pub struct State<'a> { | 34 | pub struct State<'a> { |
| 32 | control: MaybeUninit<Control<'a>>, | 35 | control: MaybeUninit<Control<'a>>, |
| 33 | shared: ControlShared, | 36 | shared: ControlShared, |
| 34 | } | 37 | } |
| 35 | 38 | ||
| 36 | impl<'a> State<'a> { | 39 | impl<'a> State<'a> { |
| 40 | /// Create a new `State`. | ||
| 37 | pub fn new() -> Self { | 41 | pub fn new() -> Self { |
| 38 | Self { | 42 | Self { |
| 39 | control: MaybeUninit::uninit(), | 43 | control: MaybeUninit::uninit(), |
| @@ -284,10 +288,15 @@ impl From<u8> for StopBits { | |||
| 284 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] | 288 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] |
| 285 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 289 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 286 | pub enum ParityType { | 290 | pub enum ParityType { |
| 291 | /// No parity bit. | ||
| 287 | None = 0, | 292 | None = 0, |
| 293 | /// Parity bit is 1 if the amount of `1` bits in the data byte is odd. | ||
| 288 | Odd = 1, | 294 | Odd = 1, |
| 295 | /// Parity bit is 1 if the amount of `1` bits in the data byte is even. | ||
| 289 | Even = 2, | 296 | Even = 2, |
| 297 | /// Parity bit is always 1 | ||
| 290 | Mark = 3, | 298 | Mark = 3, |
| 299 | /// Parity bit is always 0 | ||
| 291 | Space = 4, | 300 | Space = 4, |
| 292 | } | 301 | } |
| 293 | 302 | ||
diff --git a/embassy-usb/src/class/cdc_ncm/embassy_net.rs b/embassy-usb/src/class/cdc_ncm/embassy_net.rs index 501df2d8c..bc79b3671 100644 --- a/embassy-usb/src/class/cdc_ncm/embassy_net.rs +++ b/embassy-usb/src/class/cdc_ncm/embassy_net.rs | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | //! [`embassy-net`](crates.io/crates/embassy-net) driver for the CDC-NCM class. | ||
| 1 | use embassy_futures::select::{select, Either}; | 2 | use embassy_futures::select::{select, Either}; |
| 2 | use embassy_net_driver_channel as ch; | 3 | use embassy_net_driver_channel as ch; |
| 3 | use embassy_net_driver_channel::driver::LinkState; | 4 | use embassy_net_driver_channel::driver::LinkState; |
| @@ -5,11 +6,13 @@ use embassy_usb_driver::Driver; | |||
| 5 | 6 | ||
| 6 | use super::{CdcNcmClass, Receiver, Sender}; | 7 | use super::{CdcNcmClass, Receiver, Sender}; |
| 7 | 8 | ||
| 9 | /// Internal state for the embassy-net integration. | ||
| 8 | pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> { | 10 | pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> { |
| 9 | ch_state: ch::State<MTU, N_RX, N_TX>, | 11 | ch_state: ch::State<MTU, N_RX, N_TX>, |
| 10 | } | 12 | } |
| 11 | 13 | ||
| 12 | impl<const MTU: usize, const N_RX: usize, const N_TX: usize> State<MTU, N_RX, N_TX> { | 14 | impl<const MTU: usize, const N_RX: usize, const N_TX: usize> State<MTU, N_RX, N_TX> { |
| 15 | /// Create a new `State`. | ||
| 13 | pub const fn new() -> Self { | 16 | pub const fn new() -> Self { |
| 14 | Self { | 17 | Self { |
| 15 | ch_state: ch::State::new(), | 18 | ch_state: ch::State::new(), |
| @@ -17,6 +20,9 @@ impl<const MTU: usize, const N_RX: usize, const N_TX: usize> State<MTU, N_RX, N_ | |||
| 17 | } | 20 | } |
| 18 | } | 21 | } |
| 19 | 22 | ||
| 23 | /// Background runner for the CDC-NCM class. | ||
| 24 | /// | ||
| 25 | /// You must call `.run()` in a background task for the class to operate. | ||
| 20 | pub struct Runner<'d, D: Driver<'d>, const MTU: usize> { | 26 | pub struct Runner<'d, D: Driver<'d>, const MTU: usize> { |
| 21 | tx_usb: Sender<'d, D>, | 27 | tx_usb: Sender<'d, D>, |
| 22 | rx_usb: Receiver<'d, D>, | 28 | rx_usb: Receiver<'d, D>, |
| @@ -24,6 +30,9 @@ pub struct Runner<'d, D: Driver<'d>, const MTU: usize> { | |||
| 24 | } | 30 | } |
| 25 | 31 | ||
| 26 | impl<'d, D: Driver<'d>, const MTU: usize> Runner<'d, D, MTU> { | 32 | impl<'d, D: Driver<'d>, const MTU: usize> Runner<'d, D, MTU> { |
| 33 | /// Run the CDC-NCM class. | ||
| 34 | /// | ||
| 35 | /// You must call this in a background task for the class to operate. | ||
| 27 | pub async fn run(mut self) -> ! { | 36 | pub async fn run(mut self) -> ! { |
| 28 | let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split(); | 37 | let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split(); |
| 29 | let rx_fut = async move { | 38 | let rx_fut = async move { |
| @@ -66,9 +75,11 @@ impl<'d, D: Driver<'d>, const MTU: usize> Runner<'d, D, MTU> { | |||
| 66 | 75 | ||
| 67 | // would be cool to use a TAIT here, but it gives a "may not live long enough". rustc bug? | 76 | // would be cool to use a TAIT here, but it gives a "may not live long enough". rustc bug? |
| 68 | //pub type Device<'d, const MTU: usize> = impl embassy_net_driver_channel::driver::Driver + 'd; | 77 | //pub type Device<'d, const MTU: usize> = impl embassy_net_driver_channel::driver::Driver + 'd; |
| 78 | /// Type alias for the embassy-net driver for CDC-NCM. | ||
| 69 | pub type Device<'d, const MTU: usize> = embassy_net_driver_channel::Device<'d, MTU>; | 79 | pub type Device<'d, const MTU: usize> = embassy_net_driver_channel::Device<'d, MTU>; |
| 70 | 80 | ||
| 71 | impl<'d, D: Driver<'d>> CdcNcmClass<'d, D> { | 81 | impl<'d, D: Driver<'d>> CdcNcmClass<'d, D> { |
| 82 | /// Obtain a driver for using the CDC-NCM class with [`embassy-net`](crates.io/crates/embassy-net). | ||
| 72 | pub fn into_embassy_net_device<const MTU: usize, const N_RX: usize, const N_TX: usize>( | 83 | pub fn into_embassy_net_device<const MTU: usize, const N_RX: usize, const N_TX: usize>( |
| 73 | self, | 84 | self, |
| 74 | state: &'d mut State<MTU, N_RX, N_TX>, | 85 | state: &'d mut State<MTU, N_RX, N_TX>, |
diff --git a/embassy-usb/src/class/cdc_ncm/mod.rs b/embassy-usb/src/class/cdc_ncm/mod.rs index 4954a65bc..5e59b72fe 100644 --- a/embassy-usb/src/class/cdc_ncm/mod.rs +++ b/embassy-usb/src/class/cdc_ncm/mod.rs | |||
| @@ -1,18 +1,19 @@ | |||
| 1 | /// CDC-NCM, aka Ethernet over USB. | 1 | //! CDC-NCM class implementation, aka Ethernet over USB. |
| 2 | /// | 2 | //! |
| 3 | /// # Compatibility | 3 | //! # Compatibility |
| 4 | /// | 4 | //! |
| 5 | /// Windows: NOT supported in Windows 10. Supported in Windows 11. | 5 | //! Windows: NOT supported in Windows 10 (though there's apparently a driver you can install?). Supported out of the box in Windows 11. |
| 6 | /// | 6 | //! |
| 7 | /// Linux: Well-supported since forever. | 7 | //! Linux: Well-supported since forever. |
| 8 | /// | 8 | //! |
| 9 | /// Android: Support for CDC-NCM is spotty and varies across manufacturers. | 9 | //! Android: Support for CDC-NCM is spotty and varies across manufacturers. |
| 10 | /// | 10 | //! |
| 11 | /// - On Pixel 4a, it refused to work on Android 11, worked on Android 12. | 11 | //! - On Pixel 4a, it refused to work on Android 11, worked on Android 12. |
| 12 | /// - if the host's MAC address has the "locally-administered" bit set (bit 1 of first byte), | 12 | //! - if the host's MAC address has the "locally-administered" bit set (bit 1 of first byte), |
| 13 | /// it doesn't work! The "Ethernet tethering" option in settings doesn't get enabled. | 13 | //! it doesn't work! The "Ethernet tethering" option in settings doesn't get enabled. |
| 14 | /// This is due to regex spaghetti: https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-mainline-12.0.0_r84/core/res/res/values/config.xml#417 | 14 | //! This is due to regex spaghetti: https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-mainline-12.0.0_r84/core/res/res/values/config.xml#417 |
| 15 | /// and this nonsense in the linux kernel: https://github.com/torvalds/linux/blob/c00c5e1d157bec0ef0b0b59aa5482eb8dc7e8e49/drivers/net/usb/usbnet.c#L1751-L1757 | 15 | //! and this nonsense in the linux kernel: https://github.com/torvalds/linux/blob/c00c5e1d157bec0ef0b0b59aa5482eb8dc7e8e49/drivers/net/usb/usbnet.c#L1751-L1757 |
| 16 | |||
| 16 | use core::intrinsics::copy_nonoverlapping; | 17 | use core::intrinsics::copy_nonoverlapping; |
| 17 | use core::mem::{size_of, MaybeUninit}; | 18 | use core::mem::{size_of, MaybeUninit}; |
| 18 | 19 | ||
| @@ -114,6 +115,7 @@ fn byteify<T>(buf: &mut [u8], data: T) -> &[u8] { | |||
| 114 | &buf[..len] | 115 | &buf[..len] |
| 115 | } | 116 | } |
| 116 | 117 | ||
| 118 | /// Internal state for the CDC-NCM class. | ||
| 117 | pub struct State<'a> { | 119 | pub struct State<'a> { |
| 118 | comm_control: MaybeUninit<CommControl<'a>>, | 120 | comm_control: MaybeUninit<CommControl<'a>>, |
| 119 | data_control: MaybeUninit<DataControl>, | 121 | data_control: MaybeUninit<DataControl>, |
| @@ -121,6 +123,7 @@ pub struct State<'a> { | |||
| 121 | } | 123 | } |
| 122 | 124 | ||
| 123 | impl<'a> State<'a> { | 125 | impl<'a> State<'a> { |
| 126 | /// Create a new `State`. | ||
| 124 | pub fn new() -> Self { | 127 | pub fn new() -> Self { |
| 125 | Self { | 128 | Self { |
| 126 | comm_control: MaybeUninit::uninit(), | 129 | comm_control: MaybeUninit::uninit(), |
| @@ -223,6 +226,7 @@ impl ControlHandler for DataControl { | |||
| 223 | } | 226 | } |
| 224 | } | 227 | } |
| 225 | 228 | ||
| 229 | /// CDC-NCM class | ||
| 226 | pub struct CdcNcmClass<'d, D: Driver<'d>> { | 230 | pub struct CdcNcmClass<'d, D: Driver<'d>> { |
| 227 | _comm_if: InterfaceNumber, | 231 | _comm_if: InterfaceNumber, |
| 228 | comm_ep: D::EndpointIn, | 232 | comm_ep: D::EndpointIn, |
| @@ -235,6 +239,7 @@ pub struct CdcNcmClass<'d, D: Driver<'d>> { | |||
| 235 | } | 239 | } |
| 236 | 240 | ||
| 237 | impl<'d, D: Driver<'d>> CdcNcmClass<'d, D> { | 241 | impl<'d, D: Driver<'d>> CdcNcmClass<'d, D> { |
| 242 | /// Create a new CDC NCM class. | ||
| 238 | pub fn new( | 243 | pub fn new( |
| 239 | builder: &mut Builder<'d, D>, | 244 | builder: &mut Builder<'d, D>, |
| 240 | state: &'d mut State<'d>, | 245 | state: &'d mut State<'d>, |
| @@ -319,6 +324,9 @@ impl<'d, D: Driver<'d>> CdcNcmClass<'d, D> { | |||
| 319 | } | 324 | } |
| 320 | } | 325 | } |
| 321 | 326 | ||
| 327 | /// Split the class into a sender and receiver. | ||
| 328 | /// | ||
| 329 | /// This allows concurrently sending and receiving packets from separate tasks. | ||
| 322 | pub fn split(self) -> (Sender<'d, D>, Receiver<'d, D>) { | 330 | pub fn split(self) -> (Sender<'d, D>, Receiver<'d, D>) { |
| 323 | ( | 331 | ( |
| 324 | Sender { | 332 | Sender { |
| @@ -334,12 +342,18 @@ impl<'d, D: Driver<'d>> CdcNcmClass<'d, D> { | |||
| 334 | } | 342 | } |
| 335 | } | 343 | } |
| 336 | 344 | ||
| 345 | /// CDC NCM class packet sender. | ||
| 346 | /// | ||
| 347 | /// You can obtain a `Sender` with [`CdcNcmClass::split`] | ||
| 337 | pub struct Sender<'d, D: Driver<'d>> { | 348 | pub struct Sender<'d, D: Driver<'d>> { |
| 338 | write_ep: D::EndpointIn, | 349 | write_ep: D::EndpointIn, |
| 339 | seq: u16, | 350 | seq: u16, |
| 340 | } | 351 | } |
| 341 | 352 | ||
| 342 | impl<'d, D: Driver<'d>> Sender<'d, D> { | 353 | impl<'d, D: Driver<'d>> Sender<'d, D> { |
| 354 | /// Write a packet. | ||
| 355 | /// | ||
| 356 | /// This waits until the packet is succesfully stored in the CDC-NCM endpoint buffers. | ||
| 343 | pub async fn write_packet(&mut self, data: &[u8]) -> Result<(), EndpointError> { | 357 | pub async fn write_packet(&mut self, data: &[u8]) -> Result<(), EndpointError> { |
| 344 | let seq = self.seq; | 358 | let seq = self.seq; |
| 345 | self.seq = self.seq.wrapping_add(1); | 359 | self.seq = self.seq.wrapping_add(1); |
| @@ -393,6 +407,9 @@ impl<'d, D: Driver<'d>> Sender<'d, D> { | |||
| 393 | } | 407 | } |
| 394 | } | 408 | } |
| 395 | 409 | ||
| 410 | /// CDC NCM class packet receiver. | ||
| 411 | /// | ||
| 412 | /// You can obtain a `Receiver` with [`CdcNcmClass::split`] | ||
| 396 | pub struct Receiver<'d, D: Driver<'d>> { | 413 | pub struct Receiver<'d, D: Driver<'d>> { |
| 397 | data_if: InterfaceNumber, | 414 | data_if: InterfaceNumber, |
| 398 | comm_ep: D::EndpointIn, | 415 | comm_ep: D::EndpointIn, |
| @@ -400,7 +417,9 @@ pub struct Receiver<'d, D: Driver<'d>> { | |||
| 400 | } | 417 | } |
| 401 | 418 | ||
| 402 | impl<'d, D: Driver<'d>> Receiver<'d, D> { | 419 | impl<'d, D: Driver<'d>> Receiver<'d, D> { |
| 403 | /// Reads a single packet from the OUT endpoint. | 420 | /// Write a network packet. |
| 421 | /// | ||
| 422 | /// This waits until a packet is succesfully received from the endpoint buffers. | ||
| 404 | pub async fn read_packet(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> { | 423 | pub async fn read_packet(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> { |
| 405 | // Retry loop | 424 | // Retry loop |
| 406 | loop { | 425 | loop { |
diff --git a/embassy-usb/src/class/hid.rs b/embassy-usb/src/class/hid.rs index b967aba0e..2493061b0 100644 --- a/embassy-usb/src/class/hid.rs +++ b/embassy-usb/src/class/hid.rs | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | //! USB HID (Human Interface Device) class implementation. | ||
| 2 | |||
| 1 | use core::mem::MaybeUninit; | 3 | use core::mem::MaybeUninit; |
| 2 | use core::ops::Range; | 4 | use core::ops::Range; |
| 3 | use core::sync::atomic::{AtomicUsize, Ordering}; | 5 | use core::sync::atomic::{AtomicUsize, Ordering}; |
| @@ -28,6 +30,7 @@ const HID_REQ_SET_REPORT: u8 = 0x09; | |||
| 28 | const HID_REQ_GET_PROTOCOL: u8 = 0x03; | 30 | const HID_REQ_GET_PROTOCOL: u8 = 0x03; |
| 29 | const HID_REQ_SET_PROTOCOL: u8 = 0x0b; | 31 | const HID_REQ_SET_PROTOCOL: u8 = 0x0b; |
| 30 | 32 | ||
| 33 | /// Configuration for the HID class. | ||
| 31 | pub struct Config<'d> { | 34 | pub struct Config<'d> { |
| 32 | /// HID report descriptor. | 35 | /// HID report descriptor. |
| 33 | pub report_descriptor: &'d [u8], | 36 | pub report_descriptor: &'d [u8], |
| @@ -46,11 +49,15 @@ pub struct Config<'d> { | |||
| 46 | pub max_packet_size: u16, | 49 | pub max_packet_size: u16, |
| 47 | } | 50 | } |
| 48 | 51 | ||
| 52 | /// Report ID | ||
| 49 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 53 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| 50 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 54 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 51 | pub enum ReportId { | 55 | pub enum ReportId { |
| 56 | /// IN report | ||
| 52 | In(u8), | 57 | In(u8), |
| 58 | /// OUT report | ||
| 53 | Out(u8), | 59 | Out(u8), |
| 60 | /// Feature report | ||
| 54 | Feature(u8), | 61 | Feature(u8), |
| 55 | } | 62 | } |
| 56 | 63 | ||
| @@ -65,12 +72,14 @@ impl ReportId { | |||
| 65 | } | 72 | } |
| 66 | } | 73 | } |
| 67 | 74 | ||
| 75 | /// Internal state for USB HID. | ||
| 68 | pub struct State<'d> { | 76 | pub struct State<'d> { |
| 69 | control: MaybeUninit<Control<'d>>, | 77 | control: MaybeUninit<Control<'d>>, |
| 70 | out_report_offset: AtomicUsize, | 78 | out_report_offset: AtomicUsize, |
| 71 | } | 79 | } |
| 72 | 80 | ||
| 73 | impl<'d> State<'d> { | 81 | impl<'d> State<'d> { |
| 82 | /// Create a new `State`. | ||
| 74 | pub fn new() -> Self { | 83 | pub fn new() -> Self { |
| 75 | State { | 84 | State { |
| 76 | control: MaybeUninit::uninit(), | 85 | control: MaybeUninit::uninit(), |
| @@ -79,6 +88,7 @@ impl<'d> State<'d> { | |||
| 79 | } | 88 | } |
| 80 | } | 89 | } |
| 81 | 90 | ||
| 91 | /// USB HID reader/writer. | ||
| 82 | pub struct HidReaderWriter<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N: usize> { | 92 | pub struct HidReaderWriter<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N: usize> { |
| 83 | reader: HidReader<'d, D, READ_N>, | 93 | reader: HidReader<'d, D, READ_N>, |
| 84 | writer: HidWriter<'d, D, WRITE_N>, | 94 | writer: HidWriter<'d, D, WRITE_N>, |
| @@ -180,20 +190,30 @@ impl<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N: usize> HidReaderWrit | |||
| 180 | } | 190 | } |
| 181 | } | 191 | } |
| 182 | 192 | ||
| 193 | /// USB HID writer. | ||
| 194 | /// | ||
| 195 | /// You can obtain a `HidWriter` using [`HidReaderWriter::split`]. | ||
| 183 | pub struct HidWriter<'d, D: Driver<'d>, const N: usize> { | 196 | pub struct HidWriter<'d, D: Driver<'d>, const N: usize> { |
| 184 | ep_in: D::EndpointIn, | 197 | ep_in: D::EndpointIn, |
| 185 | } | 198 | } |
| 186 | 199 | ||
| 200 | /// USB HID reader. | ||
| 201 | /// | ||
| 202 | /// You can obtain a `HidReader` using [`HidReaderWriter::split`]. | ||
| 187 | pub struct HidReader<'d, D: Driver<'d>, const N: usize> { | 203 | pub struct HidReader<'d, D: Driver<'d>, const N: usize> { |
| 188 | ep_out: D::EndpointOut, | 204 | ep_out: D::EndpointOut, |
| 189 | offset: &'d AtomicUsize, | 205 | offset: &'d AtomicUsize, |
| 190 | } | 206 | } |
| 191 | 207 | ||
| 208 | /// Error when reading a HID report. | ||
| 192 | #[derive(Debug, Clone, PartialEq, Eq)] | 209 | #[derive(Debug, Clone, PartialEq, Eq)] |
| 193 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 210 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 194 | pub enum ReadError { | 211 | pub enum ReadError { |
| 212 | /// The given buffer was too small to read the received report. | ||
| 195 | BufferOverflow, | 213 | BufferOverflow, |
| 214 | /// The endpoint is disabled. | ||
| 196 | Disabled, | 215 | Disabled, |
| 216 | /// The report was only partially read. See [`HidReader::read`] for details. | ||
| 197 | Sync(Range<usize>), | 217 | Sync(Range<usize>), |
| 198 | } | 218 | } |
| 199 | 219 | ||
| @@ -344,6 +364,7 @@ impl<'d, D: Driver<'d>, const N: usize> HidReader<'d, D, N> { | |||
| 344 | } | 364 | } |
| 345 | } | 365 | } |
| 346 | 366 | ||
| 367 | /// Handler for HID-related control requests. | ||
| 347 | pub trait RequestHandler { | 368 | pub trait RequestHandler { |
| 348 | /// Reads the value of report `id` into `buf` returning the size. | 369 | /// Reads the value of report `id` into `buf` returning the size. |
| 349 | /// | 370 | /// |
diff --git a/embassy-usb/src/class/mod.rs b/embassy-usb/src/class/mod.rs index af27577a6..b23e03d40 100644 --- a/embassy-usb/src/class/mod.rs +++ b/embassy-usb/src/class/mod.rs | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | //! Implementations of well-known USB classes. | ||
| 1 | pub mod cdc_acm; | 2 | pub mod cdc_acm; |
| 2 | pub mod cdc_ncm; | 3 | pub mod cdc_ncm; |
| 3 | pub mod hid; | 4 | pub mod hid; |
