aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchemicstry <[email protected]>2023-01-11 17:47:12 +0100
committerDario Nieuwenhuis <[email protected]>2023-01-11 17:47:12 +0100
commitce842fe28c27e6f57a05efc92bc417f6f7d7af64 (patch)
treeb825147f49704853d07cb0dd16b1da09980c1a2e
parent96b97c4711af0851f7d3a6785be13b0202b6e902 (diff)
Refactor embassy-usb address handling to allow reordering of status resoponse
-rw-r--r--embassy-nrf/src/usb.rs10
-rw-r--r--embassy-rp/src/usb.rs15
-rw-r--r--embassy-stm32/src/usb/usb.rs25
-rw-r--r--embassy-usb-driver/src/lib.rs9
-rw-r--r--embassy-usb/src/lib.rs23
5 files changed, 44 insertions, 38 deletions
diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs
index ed4d5cf35..6be4fec8c 100644
--- a/embassy-nrf/src/usb.rs
+++ b/embassy-nrf/src/usb.rs
@@ -391,11 +391,6 @@ impl<'d, T: Instance, P: UsbSupply> driver::Bus for Bus<'d, T, P> {
391 .await 391 .await
392 } 392 }
393 393
394 #[inline]
395 fn set_address(&mut self, _addr: u8) {
396 // Nothing to do, the peripheral handles this.
397 }
398
399 fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) { 394 fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) {
400 let regs = T::regs(); 395 let regs = T::regs();
401 unsafe { 396 unsafe {
@@ -841,6 +836,11 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
841 let regs = T::regs(); 836 let regs = T::regs();
842 regs.tasks_ep0stall.write(|w| w.tasks_ep0stall().bit(true)); 837 regs.tasks_ep0stall.write(|w| w.tasks_ep0stall().bit(true));
843 } 838 }
839
840 async fn accept_set_address(&mut self, _addr: u8) {
841 self.accept().await;
842 // Nothing to do, the peripheral handles this.
843 }
844} 844}
845 845
846fn dma_start() { 846fn dma_start() {
diff --git a/embassy-rp/src/usb.rs b/embassy-rp/src/usb.rs
index 8361736a9..2710c4ad9 100644
--- a/embassy-rp/src/usb.rs
+++ b/embassy-rp/src/usb.rs
@@ -406,13 +406,6 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
406 .await 406 .await
407 } 407 }
408 408
409 #[inline]
410 fn set_address(&mut self, addr: u8) {
411 let regs = T::regs();
412 trace!("setting addr: {}", addr);
413 unsafe { regs.addr_endp().write(|w| w.set_address(addr)) }
414 }
415
416 fn endpoint_set_stalled(&mut self, _ep_addr: EndpointAddress, _stalled: bool) { 409 fn endpoint_set_stalled(&mut self, _ep_addr: EndpointAddress, _stalled: bool) {
417 todo!(); 410 todo!();
418 } 411 }
@@ -812,4 +805,12 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
812 T::dpram().ep_in_buffer_control(0).write(|w| w.set_stall(true)); 805 T::dpram().ep_in_buffer_control(0).write(|w| w.set_stall(true));
813 } 806 }
814 } 807 }
808
809 async fn accept_set_address(&mut self, addr: u8) {
810 self.accept().await;
811
812 let regs = T::regs();
813 trace!("setting addr: {}", addr);
814 unsafe { regs.addr_endp().write(|w| w.set_address(addr)) }
815 }
815} 816}
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs
index cba4915c1..062c7ef77 100644
--- a/embassy-stm32/src/usb/usb.rs
+++ b/embassy-stm32/src/usb/usb.rs
@@ -489,18 +489,6 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
489 .await 489 .await
490 } 490 }
491 491
492 #[inline]
493 fn set_address(&mut self, addr: u8) {
494 let regs = T::regs();
495 trace!("setting addr: {}", addr);
496 unsafe {
497 regs.daddr().write(|w| {
498 w.set_ef(true);
499 w.set_add(addr);
500 })
501 }
502 }
503
504 fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) { 492 fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) {
505 // This can race, so do a retry loop. 493 // This can race, so do a retry loop.
506 let reg = T::regs().epr(ep_addr.index() as _); 494 let reg = T::regs().epr(ep_addr.index() as _);
@@ -1017,4 +1005,17 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
1017 }); 1005 });
1018 } 1006 }
1019 } 1007 }
1008
1009 async fn accept_set_address(&mut self, addr: u8) {
1010 self.accept().await;
1011
1012 let regs = T::regs();
1013 trace!("setting addr: {}", addr);
1014 unsafe {
1015 regs.daddr().write(|w| {
1016 w.set_ef(true);
1017 w.set_add(addr);
1018 })
1019 }
1020 }
1020} 1021}
diff --git a/embassy-usb-driver/src/lib.rs b/embassy-usb-driver/src/lib.rs
index d7238dc7d..64d647351 100644
--- a/embassy-usb-driver/src/lib.rs
+++ b/embassy-usb-driver/src/lib.rs
@@ -164,9 +164,6 @@ pub trait Bus {
164 164
165 async fn poll(&mut self) -> Event; 165 async fn poll(&mut self) -> Event;
166 166
167 /// Sets the device USB address to `addr`.
168 fn set_address(&mut self, addr: u8);
169
170 /// Enables or disables an endpoint. 167 /// Enables or disables an endpoint.
171 fn endpoint_set_enabled(&mut self, ep_addr: EndpointAddress, enabled: bool); 168 fn endpoint_set_enabled(&mut self, ep_addr: EndpointAddress, enabled: bool);
172 169
@@ -306,6 +303,12 @@ pub trait ControlPipe {
306 /// 303 ///
307 /// Sets a STALL condition on the pipe to indicate an error. 304 /// Sets a STALL condition on the pipe to indicate an error.
308 async fn reject(&mut self); 305 async fn reject(&mut self);
306
307 /// Accept SET_ADDRESS control and change bus address.
308 ///
309 /// For most drivers this function should firstly call `accept()` and then change the bus address.
310 /// However, there are peripherals (Synopsys USB OTG) that have reverse order.
311 async fn accept_set_address(&mut self, addr: u8);
309} 312}
310 313
311pub trait EndpointIn: Endpoint { 314pub trait EndpointIn: Endpoint {
diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs
index 661b84119..096e8b07a 100644
--- a/embassy-usb/src/lib.rs
+++ b/embassy-usb/src/lib.rs
@@ -122,10 +122,9 @@ struct Inner<'d, D: Driver<'d>> {
122 122
123 /// Our device address, or 0 if none. 123 /// Our device address, or 0 if none.
124 address: u8, 124 address: u8,
125 /// When receiving a set addr control request, we have to apply it AFTER we've 125 /// SET_ADDRESS requests have special handling depending on the driver.
126 /// finished handling the control request, as the status stage still has to be 126 /// This flag indicates that requests must be handled by `ControlPipe::accept_set_address()`
127 /// handled with addr 0. 127 /// instead of regular `accept()`.
128 /// If true, do a set_addr after finishing the current control req.
129 set_address_pending: bool, 128 set_address_pending: bool,
130 129
131 interfaces: Vec<Interface<'d>, MAX_INTERFACE_COUNT>, 130 interfaces: Vec<Interface<'d>, MAX_INTERFACE_COUNT>,
@@ -254,11 +253,6 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
254 Direction::In => self.handle_control_in(req).await, 253 Direction::In => self.handle_control_in(req).await,
255 Direction::Out => self.handle_control_out(req).await, 254 Direction::Out => self.handle_control_out(req).await,
256 } 255 }
257
258 if self.inner.set_address_pending {
259 self.inner.bus.set_address(self.inner.address);
260 self.inner.set_address_pending = false;
261 }
262 } 256 }
263 257
264 async fn handle_control_in(&mut self, req: Request) { 258 async fn handle_control_in(&mut self, req: Request) {
@@ -328,7 +322,14 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
328 trace!(" control out data: {:02x?}", data); 322 trace!(" control out data: {:02x?}", data);
329 323
330 match self.inner.handle_control_out(req, data) { 324 match self.inner.handle_control_out(req, data) {
331 OutResponse::Accepted => self.control.accept().await, 325 OutResponse::Accepted => {
326 if self.inner.set_address_pending {
327 self.control.accept_set_address(self.inner.address).await;
328 self.inner.set_address_pending = false;
329 } else {
330 self.control.accept().await
331 }
332 }
332 OutResponse::Rejected => self.control.reject().await, 333 OutResponse::Rejected => self.control.reject().await,
333 } 334 }
334 } 335 }
@@ -655,7 +656,7 @@ impl<'d, D: Driver<'d>> Inner<'d, D> {
655 buf[1] = descriptor_type::STRING; 656 buf[1] = descriptor_type::STRING;
656 let mut pos = 2; 657 let mut pos = 2;
657 for c in s.encode_utf16() { 658 for c in s.encode_utf16() {
658 if pos >= buf.len() { 659 if pos + 2 >= buf.len() {
659 panic!("control buffer too small"); 660 panic!("control buffer too small");
660 } 661 }
661 662