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 | |
| parent | 1ec2e5672f6652aa3e2cbe38a3c47919e6700baa (diff) | |
usb: add first, last params to ControlPipe data_in, data_out.
| -rw-r--r-- | embassy-nrf/src/usb.rs | 17 | ||||
| -rw-r--r-- | embassy-usb/src/driver.rs | 10 | ||||
| -rw-r--r-- | embassy-usb/src/lib.rs | 23 |
3 files changed, 39 insertions, 11 deletions
diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs index 23401c837..9155eb37a 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs | |||
| @@ -657,7 +657,12 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 657 | } | 657 | } |
| 658 | } | 658 | } |
| 659 | 659 | ||
| 660 | fn data_out<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::DataOutFuture<'a> { | 660 | fn data_out<'a>( |
| 661 | &'a mut self, | ||
| 662 | buf: &'a mut [u8], | ||
| 663 | _first: bool, | ||
| 664 | _last: bool, | ||
| 665 | ) -> Self::DataOutFuture<'a> { | ||
| 661 | async move { | 666 | async move { |
| 662 | let regs = T::regs(); | 667 | let regs = T::regs(); |
| 663 | 668 | ||
| @@ -694,13 +699,17 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 694 | } | 699 | } |
| 695 | } | 700 | } |
| 696 | 701 | ||
| 697 | fn data_in<'a>(&'a mut self, buf: &'a [u8], last_packet: bool) -> Self::DataInFuture<'a> { | 702 | fn data_in<'a>( |
| 703 | &'a mut self, | ||
| 704 | buf: &'a [u8], | ||
| 705 | _first: bool, | ||
| 706 | last: bool, | ||
| 707 | ) -> Self::DataInFuture<'a> { | ||
| 698 | async move { | 708 | async move { |
| 699 | let regs = T::regs(); | 709 | let regs = T::regs(); |
| 700 | regs.events_ep0datadone.reset(); | 710 | regs.events_ep0datadone.reset(); |
| 701 | 711 | ||
| 702 | regs.shorts | 712 | regs.shorts.write(|w| w.ep0datadone_ep0status().bit(last)); |
| 703 | .write(|w| w.ep0datadone_ep0status().bit(last_packet)); | ||
| 704 | 713 | ||
| 705 | // This starts a TX on EP0. events_ep0datadone notifies when done. | 714 | // This starts a TX on EP0. events_ep0datadone notifies when done. |
| 706 | unsafe { write_dma::<T>(0, buf) } | 715 | unsafe { write_dma::<T>(0, buf) } |
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 | } | ||
