aboutsummaryrefslogtreecommitdiff
path: root/embassy-usb
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-05-30 00:08:28 +0200
committerDario Nieuwenhuis <[email protected]>2022-05-30 00:08:28 +0200
commit883e28a0fb80f9139c0236ce44597c23a0917e4d (patch)
treef56b605cddb7ace0b4ee9e43665fbf07b2ba1cdc /embassy-usb
parent1ec2e5672f6652aa3e2cbe38a3c47919e6700baa (diff)
usb: add first, last params to ControlPipe data_in, data_out.
Diffstat (limited to 'embassy-usb')
-rw-r--r--embassy-usb/src/driver.rs10
-rw-r--r--embassy-usb/src/lib.rs23
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
673fn 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}