diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-05-31 00:46:22 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-05-31 00:46:22 +0000 |
| commit | a0d43c863dd9859e94e5d202d5b5bb6b107f152c (patch) | |
| tree | 4e72b71fe808d6d4a71b5b92795875c9a6ec4872 | |
| parent | 70e4418df91d0ff9edf49e15900a53a92cf2709f (diff) | |
| parent | 39ab599eed8c807d6b5fd74c1a6b373920d8f751 (diff) | |
Merge #788
788: Misc USB improvements, for stm32 r=Dirbaio a=Dirbaio
See individual commit messages.
These changes help implementing the driver for STM32 USBD (#709)
Co-authored-by: Dario Nieuwenhuis <[email protected]>
| -rw-r--r-- | embassy-nrf/src/usb.rs | 97 | ||||
| -rw-r--r-- | embassy-usb/src/builder.rs | 2 | ||||
| -rw-r--r-- | embassy-usb/src/driver.rs | 29 | ||||
| -rw-r--r-- | embassy-usb/src/lib.rs | 56 |
4 files changed, 103 insertions, 81 deletions
diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs index 8d589aeda..842abf162 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs | |||
| @@ -101,37 +101,6 @@ impl<'d, T: Instance> Driver<'d, T> { | |||
| 101 | } | 101 | } |
| 102 | } | 102 | } |
| 103 | } | 103 | } |
| 104 | |||
| 105 | fn set_stalled(ep_addr: EndpointAddress, stalled: bool) { | ||
| 106 | let regs = T::regs(); | ||
| 107 | |||
| 108 | unsafe { | ||
| 109 | if ep_addr.index() == 0 { | ||
| 110 | regs.tasks_ep0stall | ||
| 111 | .write(|w| w.tasks_ep0stall().bit(stalled)); | ||
| 112 | } else { | ||
| 113 | regs.epstall.write(|w| { | ||
| 114 | w.ep().bits(ep_addr.index() as u8 & 0b111); | ||
| 115 | w.io().bit(ep_addr.is_in()); | ||
| 116 | w.stall().bit(stalled) | ||
| 117 | }); | ||
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 121 | //if stalled { | ||
| 122 | // self.busy_in_endpoints &= !(1 << ep_addr.index()); | ||
| 123 | //} | ||
| 124 | } | ||
| 125 | |||
| 126 | fn is_stalled(ep_addr: EndpointAddress) -> bool { | ||
| 127 | let regs = T::regs(); | ||
| 128 | |||
| 129 | let i = ep_addr.index(); | ||
| 130 | match ep_addr.direction() { | ||
| 131 | UsbDirection::Out => regs.halted.epout[i].read().getstatus().is_halted(), | ||
| 132 | UsbDirection::In => regs.halted.epin[i].read().getstatus().is_halted(), | ||
| 133 | } | ||
| 134 | } | ||
| 135 | } | 104 | } |
| 136 | 105 | ||
| 137 | impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> { | 106 | impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> { |
| @@ -294,11 +263,28 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { | |||
| 294 | } | 263 | } |
| 295 | 264 | ||
| 296 | fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) { | 265 | fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) { |
| 297 | Driver::<T>::set_stalled(ep_addr, stalled) | 266 | let regs = T::regs(); |
| 267 | unsafe { | ||
| 268 | if ep_addr.index() == 0 { | ||
| 269 | regs.tasks_ep0stall | ||
| 270 | .write(|w| w.tasks_ep0stall().bit(stalled)); | ||
| 271 | } else { | ||
| 272 | regs.epstall.write(|w| { | ||
| 273 | w.ep().bits(ep_addr.index() as u8 & 0b111); | ||
| 274 | w.io().bit(ep_addr.is_in()); | ||
| 275 | w.stall().bit(stalled) | ||
| 276 | }); | ||
| 277 | } | ||
| 278 | } | ||
| 298 | } | 279 | } |
| 299 | 280 | ||
| 300 | fn endpoint_is_stalled(&mut self, ep_addr: EndpointAddress) -> bool { | 281 | fn endpoint_is_stalled(&mut self, ep_addr: EndpointAddress) -> bool { |
| 301 | Driver::<T>::is_stalled(ep_addr) | 282 | let regs = T::regs(); |
| 283 | let i = ep_addr.index(); | ||
| 284 | match ep_addr.direction() { | ||
| 285 | UsbDirection::Out => regs.halted.epout[i].read().getstatus().is_halted(), | ||
| 286 | UsbDirection::In => regs.halted.epin[i].read().getstatus().is_halted(), | ||
| 287 | } | ||
| 302 | } | 288 | } |
| 303 | 289 | ||
| 304 | fn endpoint_set_enabled(&mut self, ep_addr: EndpointAddress, enabled: bool) { | 290 | fn endpoint_set_enabled(&mut self, ep_addr: EndpointAddress, enabled: bool) { |
| @@ -464,14 +450,6 @@ impl<'d, T: Instance, Dir: EndpointDir> driver::Endpoint for Endpoint<'d, T, Dir | |||
| 464 | &self.info | 450 | &self.info |
| 465 | } | 451 | } |
| 466 | 452 | ||
| 467 | fn set_stalled(&self, stalled: bool) { | ||
| 468 | Driver::<T>::set_stalled(self.info.addr, stalled) | ||
| 469 | } | ||
| 470 | |||
| 471 | fn is_stalled(&self) -> bool { | ||
| 472 | Driver::<T>::is_stalled(self.info.addr) | ||
| 473 | } | ||
| 474 | |||
| 475 | type WaitEnabledFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | 453 | type WaitEnabledFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; |
| 476 | 454 | ||
| 477 | fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_> { | 455 | fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_> { |
| @@ -638,6 +616,8 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 638 | type SetupFuture<'a> = impl Future<Output = [u8;8]> + 'a where Self: 'a; | 616 | type SetupFuture<'a> = impl Future<Output = [u8;8]> + 'a where Self: 'a; |
| 639 | type DataOutFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a; | 617 | type DataOutFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a; |
| 640 | type DataInFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a; | 618 | type DataInFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a; |
| 619 | type AcceptFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | ||
| 620 | type RejectFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | ||
| 641 | 621 | ||
| 642 | fn max_packet_size(&self) -> usize { | 622 | fn max_packet_size(&self) -> usize { |
| 643 | usize::from(self.max_packet_size) | 623 | usize::from(self.max_packet_size) |
| @@ -679,7 +659,12 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 679 | } | 659 | } |
| 680 | } | 660 | } |
| 681 | 661 | ||
| 682 | fn data_out<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::DataOutFuture<'a> { | 662 | fn data_out<'a>( |
| 663 | &'a mut self, | ||
| 664 | buf: &'a mut [u8], | ||
| 665 | _first: bool, | ||
| 666 | _last: bool, | ||
| 667 | ) -> Self::DataOutFuture<'a> { | ||
| 683 | async move { | 668 | async move { |
| 684 | let regs = T::regs(); | 669 | let regs = T::regs(); |
| 685 | 670 | ||
| @@ -716,13 +701,17 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 716 | } | 701 | } |
| 717 | } | 702 | } |
| 718 | 703 | ||
| 719 | fn data_in<'a>(&'a mut self, buf: &'a [u8], last_packet: bool) -> Self::DataInFuture<'a> { | 704 | fn data_in<'a>( |
| 705 | &'a mut self, | ||
| 706 | buf: &'a [u8], | ||
| 707 | _first: bool, | ||
| 708 | last: bool, | ||
| 709 | ) -> Self::DataInFuture<'a> { | ||
| 720 | async move { | 710 | async move { |
| 721 | let regs = T::regs(); | 711 | let regs = T::regs(); |
| 722 | regs.events_ep0datadone.reset(); | 712 | regs.events_ep0datadone.reset(); |
| 723 | 713 | ||
| 724 | regs.shorts | 714 | regs.shorts.write(|w| w.ep0datadone_ep0status().bit(last)); |
| 725 | .write(|w| w.ep0datadone_ep0status().bit(last_packet)); | ||
| 726 | 715 | ||
| 727 | // This starts a TX on EP0. events_ep0datadone notifies when done. | 716 | // This starts a TX on EP0. events_ep0datadone notifies when done. |
| 728 | unsafe { write_dma::<T>(0, buf) } | 717 | unsafe { write_dma::<T>(0, buf) } |
| @@ -753,15 +742,19 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 753 | } | 742 | } |
| 754 | } | 743 | } |
| 755 | 744 | ||
| 756 | fn accept(&mut self) { | 745 | fn accept<'a>(&'a mut self) -> Self::AcceptFuture<'a> { |
| 757 | let regs = T::regs(); | 746 | async move { |
| 758 | regs.tasks_ep0status | 747 | let regs = T::regs(); |
| 759 | .write(|w| w.tasks_ep0status().bit(true)); | 748 | regs.tasks_ep0status |
| 749 | .write(|w| w.tasks_ep0status().bit(true)); | ||
| 750 | } | ||
| 760 | } | 751 | } |
| 761 | 752 | ||
| 762 | fn reject(&mut self) { | 753 | fn reject<'a>(&'a mut self) -> Self::RejectFuture<'a> { |
| 763 | let regs = T::regs(); | 754 | async move { |
| 764 | regs.tasks_ep0stall.write(|w| w.tasks_ep0stall().bit(true)); | 755 | let regs = T::regs(); |
| 756 | regs.tasks_ep0stall.write(|w| w.tasks_ep0stall().bit(true)); | ||
| 757 | } | ||
| 765 | } | 758 | } |
| 766 | } | 759 | } |
| 767 | 760 | ||
diff --git a/embassy-usb/src/builder.rs b/embassy-usb/src/builder.rs index 698a5f765..09904949f 100644 --- a/embassy-usb/src/builder.rs +++ b/embassy-usb/src/builder.rs | |||
| @@ -104,7 +104,7 @@ impl<'a> Config<'a> { | |||
| 104 | device_class: 0x00, | 104 | device_class: 0x00, |
| 105 | device_sub_class: 0x00, | 105 | device_sub_class: 0x00, |
| 106 | device_protocol: 0x00, | 106 | device_protocol: 0x00, |
| 107 | max_packet_size_0: 8, | 107 | max_packet_size_0: 64, |
| 108 | vendor_id: vid, | 108 | vendor_id: vid, |
| 109 | product_id: pid, | 109 | product_id: pid, |
| 110 | device_release: 0x0010, | 110 | device_release: 0x0010, |
diff --git a/embassy-usb/src/driver.rs b/embassy-usb/src/driver.rs index 8454b041f..0680df7a5 100644 --- a/embassy-usb/src/driver.rs +++ b/embassy-usb/src/driver.rs | |||
| @@ -118,17 +118,8 @@ pub trait Endpoint { | |||
| 118 | /// Get the endpoint address | 118 | /// Get the endpoint address |
| 119 | fn info(&self) -> &EndpointInfo; | 119 | fn info(&self) -> &EndpointInfo; |
| 120 | 120 | ||
| 121 | /// Sets or clears the STALL condition for an endpoint. If the endpoint is an OUT endpoint, it | ||
| 122 | /// should be prepared to receive data again. | ||
| 123 | fn set_stalled(&self, stalled: bool); | ||
| 124 | |||
| 125 | /// Gets whether the STALL condition is set for an endpoint. | ||
| 126 | fn is_stalled(&self) -> bool; | ||
| 127 | |||
| 128 | /// Waits for the endpoint to be enabled. | 121 | /// Waits for the endpoint to be enabled. |
| 129 | fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_>; | 122 | fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_>; |
| 130 | |||
| 131 | // TODO enable/disable? | ||
| 132 | } | 123 | } |
| 133 | 124 | ||
| 134 | pub trait EndpointOut: Endpoint { | 125 | pub trait EndpointOut: Endpoint { |
| @@ -153,6 +144,12 @@ pub trait ControlPipe { | |||
| 153 | type DataInFuture<'a>: Future<Output = Result<(), EndpointError>> + 'a | 144 | type DataInFuture<'a>: Future<Output = Result<(), EndpointError>> + 'a |
| 154 | where | 145 | where |
| 155 | Self: 'a; | 146 | Self: 'a; |
| 147 | type AcceptFuture<'a>: Future<Output = ()> + 'a | ||
| 148 | where | ||
| 149 | Self: 'a; | ||
| 150 | type RejectFuture<'a>: Future<Output = ()> + 'a | ||
| 151 | where | ||
| 152 | Self: 'a; | ||
| 156 | 153 | ||
| 157 | /// Maximum packet size for the control pipe | 154 | /// Maximum packet size for the control pipe |
| 158 | fn max_packet_size(&self) -> usize; | 155 | fn max_packet_size(&self) -> usize; |
| @@ -164,22 +161,28 @@ pub trait ControlPipe { | |||
| 164 | /// | 161 | /// |
| 165 | /// Must be called after `setup()` for requests with `direction` of `Out` | 162 | /// Must be called after `setup()` for requests with `direction` of `Out` |
| 166 | /// and `length` greater than zero. | 163 | /// and `length` greater than zero. |
| 167 | fn data_out<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::DataOutFuture<'a>; | 164 | fn data_out<'a>( |
| 165 | &'a mut self, | ||
| 166 | buf: &'a mut [u8], | ||
| 167 | first: bool, | ||
| 168 | last: bool, | ||
| 169 | ) -> Self::DataOutFuture<'a>; | ||
| 168 | 170 | ||
| 169 | /// Sends a DATA IN packet with `data` in response to a control read request. | 171 | /// Sends a DATA IN packet with `data` in response to a control read request. |
| 170 | /// | 172 | /// |
| 171 | /// If `last_packet` is true, the STATUS packet will be ACKed following the transfer of `data`. | 173 | /// If `last_packet` is true, the STATUS packet will be ACKed following the transfer of `data`. |
| 172 | fn data_in<'a>(&'a mut self, data: &'a [u8], last_packet: bool) -> Self::DataInFuture<'a>; | 174 | fn data_in<'a>(&'a mut self, data: &'a [u8], first: bool, last: bool) |
| 175 | -> Self::DataInFuture<'a>; | ||
| 173 | 176 | ||
| 174 | /// Accepts a control request. | 177 | /// Accepts a control request. |
| 175 | /// | 178 | /// |
| 176 | /// Causes the STATUS packet for the current request to be ACKed. | 179 | /// Causes the STATUS packet for the current request to be ACKed. |
| 177 | fn accept(&mut self); | 180 | fn accept<'a>(&'a mut self) -> Self::AcceptFuture<'a>; |
| 178 | 181 | ||
| 179 | /// Rejects a control request. | 182 | /// Rejects a control request. |
| 180 | /// | 183 | /// |
| 181 | /// Sets a STALL condition on the pipe to indicate an error. | 184 | /// Sets a STALL condition on the pipe to indicate an error. |
| 182 | fn reject(&mut self); | 185 | fn reject<'a>(&'a mut self) -> Self::RejectFuture<'a>; |
| 183 | } | 186 | } |
| 184 | 187 | ||
| 185 | pub trait EndpointIn: Endpoint { | 188 | pub trait EndpointIn: Endpoint { |
diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index 7b85a2884..b691bf11e 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs | |||
| @@ -119,7 +119,14 @@ struct Inner<'d, D: Driver<'d>> { | |||
| 119 | suspended: bool, | 119 | suspended: bool, |
| 120 | remote_wakeup_enabled: bool, | 120 | remote_wakeup_enabled: bool, |
| 121 | self_powered: bool, | 121 | self_powered: bool, |
| 122 | pending_address: u8, | 122 | |
| 123 | /// Our device address, or 0 if none. | ||
| 124 | address: u8, | ||
| 125 | /// When receiving a set addr control request, we have to apply it AFTER we've | ||
| 126 | /// finished handling the control request, as the status stage still has to be | ||
| 127 | /// handled with addr 0. | ||
| 128 | /// If true, do a set_addr after finishing the current control req. | ||
| 129 | set_address_pending: bool, | ||
| 123 | 130 | ||
| 124 | interfaces: Vec<Interface<'d>, MAX_INTERFACE_COUNT>, | 131 | interfaces: Vec<Interface<'d>, MAX_INTERFACE_COUNT>, |
| 125 | } | 132 | } |
| @@ -154,7 +161,8 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 154 | suspended: false, | 161 | suspended: false, |
| 155 | remote_wakeup_enabled: false, | 162 | remote_wakeup_enabled: false, |
| 156 | self_powered: false, | 163 | self_powered: false, |
| 157 | pending_address: 0, | 164 | address: 0, |
| 165 | set_address_pending: false, | ||
| 158 | interfaces, | 166 | interfaces, |
| 159 | }, | 167 | }, |
| 160 | } | 168 | } |
| @@ -255,6 +263,11 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 255 | UsbDirection::In => self.handle_control_in(req).await, | 263 | UsbDirection::In => self.handle_control_in(req).await, |
| 256 | UsbDirection::Out => self.handle_control_out(req).await, | 264 | UsbDirection::Out => self.handle_control_out(req).await, |
| 257 | } | 265 | } |
| 266 | |||
| 267 | if self.inner.set_address_pending { | ||
| 268 | self.inner.bus.set_address(self.inner.address); | ||
| 269 | self.inner.set_address_pending = false; | ||
| 270 | } | ||
| 258 | } | 271 | } |
| 259 | 272 | ||
| 260 | async fn handle_control_in(&mut self, req: Request) { | 273 | async fn handle_control_in(&mut self, req: Request) { |
| @@ -266,7 +279,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 266 | // a full-length packet is a short packet, thinking we're done sending data. | 279 | // a full-length packet is a short packet, thinking we're done sending data. |
| 267 | // See https://github.com/hathach/tinyusb/issues/184 | 280 | // See https://github.com/hathach/tinyusb/issues/184 |
| 268 | const DEVICE_DESCRIPTOR_LEN: usize = 18; | 281 | const DEVICE_DESCRIPTOR_LEN: usize = 18; |
| 269 | if self.inner.pending_address == 0 | 282 | if self.inner.address == 0 |
| 270 | && max_packet_size < DEVICE_DESCRIPTOR_LEN | 283 | && max_packet_size < DEVICE_DESCRIPTOR_LEN |
| 271 | && (max_packet_size as usize) < resp_length | 284 | && (max_packet_size as usize) < resp_length |
| 272 | { | 285 | { |
| @@ -279,12 +292,12 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 279 | let len = data.len().min(resp_length); | 292 | let len = data.len().min(resp_length); |
| 280 | 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; |
| 281 | 294 | ||
| 282 | let mut chunks = data[0..len] | 295 | let chunks = data[0..len] |
| 283 | .chunks(max_packet_size) | 296 | .chunks(max_packet_size) |
| 284 | .chain(need_zlp.then(|| -> &[u8] { &[] })); | 297 | .chain(need_zlp.then(|| -> &[u8] { &[] })); |
| 285 | 298 | ||
| 286 | while let Some(chunk) = chunks.next() { | 299 | for (first, last, chunk) in first_last(chunks) { |
| 287 | match self.control.data_in(chunk, chunks.size_hint().0 == 0).await { | 300 | match self.control.data_in(chunk, first, last).await { |
| 288 | Ok(()) => {} | 301 | Ok(()) => {} |
| 289 | Err(e) => { | 302 | Err(e) => { |
| 290 | warn!("control accept_in failed: {:?}", e); | 303 | warn!("control accept_in failed: {:?}", e); |
| @@ -293,7 +306,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 293 | } | 306 | } |
| 294 | } | 307 | } |
| 295 | } | 308 | } |
| 296 | InResponse::Rejected => self.control.reject(), | 309 | InResponse::Rejected => self.control.reject().await, |
| 297 | } | 310 | } |
| 298 | } | 311 | } |
| 299 | 312 | ||
| @@ -302,8 +315,9 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 302 | let max_packet_size = self.control.max_packet_size(); | 315 | let max_packet_size = self.control.max_packet_size(); |
| 303 | let mut total = 0; | 316 | let mut total = 0; |
| 304 | 317 | ||
| 305 | 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); |
| 306 | 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 { | ||
| 307 | Ok(x) => x, | 321 | Ok(x) => x, |
| 308 | Err(e) => { | 322 | Err(e) => { |
| 309 | warn!("usb: failed to read CONTROL OUT data stage: {:?}", e); | 323 | warn!("usb: failed to read CONTROL OUT data stage: {:?}", e); |
| @@ -323,8 +337,8 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 323 | trace!(" control out data: {:02x?}", data); | 337 | trace!(" control out data: {:02x?}", data); |
| 324 | 338 | ||
| 325 | match self.inner.handle_control_out(req, data) { | 339 | match self.inner.handle_control_out(req, data) { |
| 326 | OutResponse::Accepted => self.control.accept(), | 340 | OutResponse::Accepted => self.control.accept().await, |
| 327 | OutResponse::Rejected => self.control.reject(), | 341 | OutResponse::Rejected => self.control.reject().await, |
| 328 | } | 342 | } |
| 329 | } | 343 | } |
| 330 | } | 344 | } |
| @@ -337,7 +351,7 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { | |||
| 337 | self.device_state = UsbDeviceState::Default; | 351 | self.device_state = UsbDeviceState::Default; |
| 338 | self.suspended = false; | 352 | self.suspended = false; |
| 339 | self.remote_wakeup_enabled = false; | 353 | self.remote_wakeup_enabled = false; |
| 340 | self.pending_address = 0; | 354 | self.address = 0; |
| 341 | 355 | ||
| 342 | for iface in self.interfaces.iter_mut() { | 356 | for iface in self.interfaces.iter_mut() { |
| 343 | iface.current_alt_setting = 0; | 357 | iface.current_alt_setting = 0; |
| @@ -389,11 +403,11 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { | |||
| 389 | OutResponse::Accepted | 403 | OutResponse::Accepted |
| 390 | } | 404 | } |
| 391 | (Request::SET_ADDRESS, addr @ 1..=127) => { | 405 | (Request::SET_ADDRESS, addr @ 1..=127) => { |
| 392 | self.pending_address = addr as u8; | 406 | self.address = addr as u8; |
| 393 | self.bus.set_address(self.pending_address); | 407 | self.set_address_pending = true; |
| 394 | self.device_state = UsbDeviceState::Addressed; | 408 | self.device_state = UsbDeviceState::Addressed; |
| 395 | if let Some(h) = &self.handler { | 409 | if let Some(h) = &self.handler { |
| 396 | h.addressed(self.pending_address); | 410 | h.addressed(self.address); |
| 397 | } | 411 | } |
| 398 | OutResponse::Accepted | 412 | OutResponse::Accepted |
| 399 | } | 413 | } |
| @@ -655,3 +669,15 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { | |||
| 655 | } | 669 | } |
| 656 | } | 670 | } |
| 657 | } | 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 | } | ||
