aboutsummaryrefslogtreecommitdiff
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
parent1ec2e5672f6652aa3e2cbe38a3c47919e6700baa (diff)
usb: add first, last params to ControlPipe data_in, data_out.
-rw-r--r--embassy-nrf/src/usb.rs17
-rw-r--r--embassy-usb/src/driver.rs10
-rw-r--r--embassy-usb/src/lib.rs23
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
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}