diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-12-19 12:41:25 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-12-19 12:41:25 +0100 |
| commit | 14efaf71d76ad0af569522ee0c4082d473fdede7 (patch) | |
| tree | ee9f4352e70815e97e424bb534c1c096242b9af0 /embassy-usb | |
| parent | 3214021ed5ae17b96ac006c0f460e222502e411d (diff) | |
| parent | 62ed44f99af9e33d689c8308149f8f992176895f (diff) | |
Merge pull request #4745 from embassy-rs/io07
Update to embedded-io 0.7
Diffstat (limited to 'embassy-usb')
| -rw-r--r-- | embassy-usb/Cargo.toml | 2 | ||||
| -rw-r--r-- | embassy-usb/src/class/cdc_acm.rs | 51 |
2 files changed, 46 insertions, 7 deletions
diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml index 3d1e005e4..6c3ddc1db 100644 --- a/embassy-usb/Cargo.toml +++ b/embassy-usb/Cargo.toml | |||
| @@ -66,7 +66,7 @@ embassy-net-driver-channel = { version = "0.3.2", path = "../embassy-net-driver- | |||
| 66 | defmt = { version = "1", optional = true } | 66 | defmt = { version = "1", optional = true } |
| 67 | log = { version = "0.4.14", optional = true } | 67 | log = { version = "0.4.14", optional = true } |
| 68 | heapless = "0.8" | 68 | heapless = "0.8" |
| 69 | embedded-io-async = "0.6.1" | 69 | embedded-io-async = { version = "0.7.0" } |
| 70 | 70 | ||
| 71 | # for HID | 71 | # for HID |
| 72 | usbd-hid = { version = "0.9.0", optional = true } | 72 | usbd-hid = { version = "0.9.0", optional = true } |
diff --git a/embassy-usb/src/class/cdc_acm.rs b/embassy-usb/src/class/cdc_acm.rs index ab2311f4e..56acdb2a6 100644 --- a/embassy-usb/src/class/cdc_acm.rs +++ b/embassy-usb/src/class/cdc_acm.rs | |||
| @@ -33,6 +33,30 @@ const REQ_SET_LINE_CODING: u8 = 0x20; | |||
| 33 | const REQ_GET_LINE_CODING: u8 = 0x21; | 33 | const REQ_GET_LINE_CODING: u8 = 0x21; |
| 34 | const REQ_SET_CONTROL_LINE_STATE: u8 = 0x22; | 34 | const REQ_SET_CONTROL_LINE_STATE: u8 = 0x22; |
| 35 | 35 | ||
| 36 | /// CDC ACM error. | ||
| 37 | #[derive(Clone, Debug)] | ||
| 38 | pub enum CdcAcmError { | ||
| 39 | /// USB is not connected. | ||
| 40 | NotConnected, | ||
| 41 | } | ||
| 42 | |||
| 43 | impl core::fmt::Display for CdcAcmError { | ||
| 44 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| 45 | match *self { | ||
| 46 | Self::NotConnected => f.write_str("NotConnected"), | ||
| 47 | } | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | impl core::error::Error for CdcAcmError {} | ||
| 52 | impl embedded_io_async::Error for CdcAcmError { | ||
| 53 | fn kind(&self) -> embedded_io_async::ErrorKind { | ||
| 54 | match *self { | ||
| 55 | Self::NotConnected => embedded_io_async::ErrorKind::NotConnected, | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 36 | /// Internal state for CDC-ACM | 60 | /// Internal state for CDC-ACM |
| 37 | pub struct State<'a> { | 61 | pub struct State<'a> { |
| 38 | control: MaybeUninit<Control<'a>>, | 62 | control: MaybeUninit<Control<'a>>, |
| @@ -421,14 +445,21 @@ impl<'d, D: Driver<'d>> Sender<'d, D> { | |||
| 421 | } | 445 | } |
| 422 | 446 | ||
| 423 | impl<'d, D: Driver<'d>> embedded_io_async::ErrorType for Sender<'d, D> { | 447 | impl<'d, D: Driver<'d>> embedded_io_async::ErrorType for Sender<'d, D> { |
| 424 | type Error = EndpointError; | 448 | type Error = CdcAcmError; |
| 425 | } | 449 | } |
| 426 | 450 | ||
| 427 | impl<'d, D: Driver<'d>> embedded_io_async::Write for Sender<'d, D> { | 451 | impl<'d, D: Driver<'d>> embedded_io_async::Write for Sender<'d, D> { |
| 428 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | 452 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 429 | let len = core::cmp::min(buf.len(), self.max_packet_size() as usize); | 453 | let len = core::cmp::min(buf.len(), self.max_packet_size() as usize); |
| 430 | self.write_packet(&buf[..len]).await?; | 454 | match self.write_packet(&buf[..len]).await { |
| 431 | Ok(len) | 455 | Ok(()) => Ok(len), |
| 456 | Err(EndpointError::BufferOverflow) => unreachable!(), | ||
| 457 | Err(EndpointError::Disabled) => Err(CdcAcmError::NotConnected), | ||
| 458 | } | ||
| 459 | } | ||
| 460 | |||
| 461 | async fn flush(&mut self) -> Result<(), Self::Error> { | ||
| 462 | Ok(()) | ||
| 432 | } | 463 | } |
| 433 | } | 464 | } |
| 434 | 465 | ||
| @@ -539,7 +570,7 @@ impl<'d, D: Driver<'d>> BufferedReceiver<'d, D> { | |||
| 539 | } | 570 | } |
| 540 | 571 | ||
| 541 | impl<'d, D: Driver<'d>> embedded_io_async::ErrorType for BufferedReceiver<'d, D> { | 572 | impl<'d, D: Driver<'d>> embedded_io_async::ErrorType for BufferedReceiver<'d, D> { |
| 542 | type Error = EndpointError; | 573 | type Error = CdcAcmError; |
| 543 | } | 574 | } |
| 544 | 575 | ||
| 545 | impl<'d, D: Driver<'d>> embedded_io_async::Read for BufferedReceiver<'d, D> { | 576 | impl<'d, D: Driver<'d>> embedded_io_async::Read for BufferedReceiver<'d, D> { |
| @@ -552,14 +583,22 @@ impl<'d, D: Driver<'d>> embedded_io_async::Read for BufferedReceiver<'d, D> { | |||
| 552 | // If the caller's buffer is large enough to contain an entire packet, read directly into | 583 | // If the caller's buffer is large enough to contain an entire packet, read directly into |
| 553 | // that instead of buffering the packet internally. | 584 | // that instead of buffering the packet internally. |
| 554 | if buf.len() > self.receiver.max_packet_size() as usize { | 585 | if buf.len() > self.receiver.max_packet_size() as usize { |
| 555 | return self.receiver.read_packet(buf).await; | 586 | return match self.receiver.read_packet(buf).await { |
| 587 | Ok(n) => Ok(n), | ||
| 588 | Err(EndpointError::BufferOverflow) => unreachable!(), | ||
| 589 | Err(EndpointError::Disabled) => Err(CdcAcmError::NotConnected), | ||
| 590 | }; | ||
| 556 | } | 591 | } |
| 557 | 592 | ||
| 558 | // Otherwise read a packet into the internal buffer, and return some of it to the caller. | 593 | // Otherwise read a packet into the internal buffer, and return some of it to the caller. |
| 559 | // | 594 | // |
| 560 | // It's important that `start` and `end` be updated in this order so they're left in a | 595 | // It's important that `start` and `end` be updated in this order so they're left in a |
| 561 | // consistent state if the `read` future is dropped mid-execution, e.g. from a timeout. | 596 | // consistent state if the `read` future is dropped mid-execution, e.g. from a timeout. |
| 562 | self.end = self.receiver.read_packet(&mut self.buffer).await?; | 597 | match self.receiver.read_packet(&mut self.buffer).await { |
| 598 | Ok(n) => self.end = n, | ||
| 599 | Err(EndpointError::BufferOverflow) => unreachable!(), | ||
| 600 | Err(EndpointError::Disabled) => return Err(CdcAcmError::NotConnected), | ||
| 601 | } | ||
| 563 | self.start = 0; | 602 | self.start = 0; |
| 564 | return Ok(self.read_from_buffer(buf)); | 603 | return Ok(self.read_from_buffer(buf)); |
| 565 | } | 604 | } |
