diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-05-30 00:08:28 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-05-30 00:08:28 +0200 |
| commit | 883e28a0fb80f9139c0236ce44597c23a0917e4d (patch) | |
| tree | f56b605cddb7ace0b4ee9e43665fbf07b2ba1cdc /embassy-usb | |
| parent | 1ec2e5672f6652aa3e2cbe38a3c47919e6700baa (diff) | |
usb: add first, last params to ControlPipe data_in, data_out.
Diffstat (limited to 'embassy-usb')
| -rw-r--r-- | embassy-usb/src/driver.rs | 10 | ||||
| -rw-r--r-- | embassy-usb/src/lib.rs | 23 |
2 files changed, 26 insertions, 7 deletions
diff --git a/embassy-usb/src/driver.rs b/embassy-usb/src/driver.rs index acd2e298d..9cd4afdab 100644 --- a/embassy-usb/src/driver.rs +++ b/embassy-usb/src/driver.rs | |||
| @@ -155,12 +155,18 @@ pub trait ControlPipe { | |||
| 155 | /// | 155 | /// |
| 156 | /// Must be called after `setup()` for requests with `direction` of `Out` | 156 | /// Must be called after `setup()` for requests with `direction` of `Out` |
| 157 | /// and `length` greater than zero. | 157 | /// and `length` greater than zero. |
| 158 | fn data_out<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::DataOutFuture<'a>; | 158 | fn data_out<'a>( |
| 159 | &'a mut self, | ||
| 160 | buf: &'a mut [u8], | ||
| 161 | first: bool, | ||
| 162 | last: bool, | ||
| 163 | ) -> Self::DataOutFuture<'a>; | ||
| 159 | 164 | ||
| 160 | /// Sends a DATA IN packet with `data` in response to a control read request. | 165 | /// Sends a DATA IN packet with `data` in response to a control read request. |
| 161 | /// | 166 | /// |
| 162 | /// If `last_packet` is true, the STATUS packet will be ACKed following the transfer of `data`. | 167 | /// If `last_packet` is true, the STATUS packet will be ACKed following the transfer of `data`. |
| 163 | fn data_in<'a>(&'a mut self, data: &'a [u8], last_packet: bool) -> Self::DataInFuture<'a>; | 168 | fn data_in<'a>(&'a mut self, data: &'a [u8], first: bool, last: bool) |
| 169 | -> Self::DataInFuture<'a>; | ||
| 164 | 170 | ||
| 165 | /// Accepts a control request. | 171 | /// Accepts a control request. |
| 166 | /// | 172 | /// |
diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index a2879bdbc..9101d81bd 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs | |||
| @@ -292,12 +292,12 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 292 | let len = data.len().min(resp_length); | 292 | let len = data.len().min(resp_length); |
| 293 | let need_zlp = len != resp_length && (len % usize::from(max_packet_size)) == 0; | 293 | let need_zlp = len != resp_length && (len % usize::from(max_packet_size)) == 0; |
| 294 | 294 | ||
| 295 | let mut chunks = data[0..len] | 295 | let chunks = data[0..len] |
| 296 | .chunks(max_packet_size) | 296 | .chunks(max_packet_size) |
| 297 | .chain(need_zlp.then(|| -> &[u8] { &[] })); | 297 | .chain(need_zlp.then(|| -> &[u8] { &[] })); |
| 298 | 298 | ||
| 299 | while let Some(chunk) = chunks.next() { | 299 | for (first, last, chunk) in first_last(chunks) { |
| 300 | match self.control.data_in(chunk, chunks.size_hint().0 == 0).await { | 300 | match self.control.data_in(chunk, first, last).await { |
| 301 | Ok(()) => {} | 301 | Ok(()) => {} |
| 302 | Err(e) => { | 302 | Err(e) => { |
| 303 | warn!("control accept_in failed: {:?}", e); | 303 | warn!("control accept_in failed: {:?}", e); |
| @@ -315,8 +315,9 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 315 | let max_packet_size = self.control.max_packet_size(); | 315 | let max_packet_size = self.control.max_packet_size(); |
| 316 | let mut total = 0; | 316 | let mut total = 0; |
| 317 | 317 | ||
| 318 | for chunk in self.control_buf[..req_length].chunks_mut(max_packet_size) { | 318 | let chunks = self.control_buf[..req_length].chunks_mut(max_packet_size); |
| 319 | let size = match self.control.data_out(chunk).await { | 319 | for (first, last, chunk) in first_last(chunks) { |
| 320 | let size = match self.control.data_out(chunk, first, last).await { | ||
| 320 | Ok(x) => x, | 321 | Ok(x) => x, |
| 321 | Err(e) => { | 322 | Err(e) => { |
| 322 | warn!("usb: failed to read CONTROL OUT data stage: {:?}", e); | 323 | warn!("usb: failed to read CONTROL OUT data stage: {:?}", e); |
| @@ -668,3 +669,15 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { | |||
| 668 | } | 669 | } |
| 669 | } | 670 | } |
| 670 | } | 671 | } |
| 672 | |||
| 673 | fn first_last<T: Iterator>(iter: T) -> impl Iterator<Item = (bool, bool, T::Item)> { | ||
| 674 | let mut iter = iter.peekable(); | ||
| 675 | let mut first = true; | ||
| 676 | core::iter::from_fn(move || { | ||
| 677 | let val = iter.next()?; | ||
| 678 | let is_first = first; | ||
| 679 | first = false; | ||
| 680 | let is_last = iter.peek().is_none(); | ||
| 681 | Some((is_first, is_last, val)) | ||
| 682 | }) | ||
| 683 | } | ||
