diff options
| -rw-r--r-- | embassy-nrf/src/usb.rs | 10 | ||||
| -rw-r--r-- | embassy-rp/src/usb.rs | 15 | ||||
| -rw-r--r-- | embassy-stm32/src/usb/usb.rs | 25 | ||||
| -rw-r--r-- | embassy-usb-driver/src/lib.rs | 9 | ||||
| -rw-r--r-- | embassy-usb/src/lib.rs | 23 |
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 | ||
| 846 | fn dma_start() { | 846 | fn 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 | ||
| 311 | pub trait EndpointIn: Endpoint { | 314 | pub 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 | ||
