usb: delay bus.set_address() to after ending the control transfer.

This commit is contained in:
Dario Nieuwenhuis 2022-05-30 00:03:36 +02:00
parent 82e873d920
commit 98d8c9373d

View file

@ -119,7 +119,14 @@ struct Inner<'d, D: Driver<'d>> {
suspended: bool, suspended: bool,
remote_wakeup_enabled: bool, remote_wakeup_enabled: bool,
self_powered: bool, self_powered: bool,
pending_address: u8,
/// Our device address, or 0 if none.
address: u8,
/// When receiving a set addr control request, we have to apply it AFTER we've
/// finished handling the control request, as the status stage still has to be
/// handled with addr 0.
/// If true, do a set_addr after finishing the current control req.
set_address_pending: bool,
interfaces: Vec<Interface<'d>, MAX_INTERFACE_COUNT>, interfaces: Vec<Interface<'d>, MAX_INTERFACE_COUNT>,
} }
@ -154,7 +161,8 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
suspended: false, suspended: false,
remote_wakeup_enabled: false, remote_wakeup_enabled: false,
self_powered: false, self_powered: false,
pending_address: 0, address: 0,
set_address_pending: false,
interfaces, interfaces,
}, },
} }
@ -255,6 +263,11 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
UsbDirection::In => self.handle_control_in(req).await, UsbDirection::In => self.handle_control_in(req).await,
UsbDirection::Out => self.handle_control_out(req).await, UsbDirection::Out => self.handle_control_out(req).await,
} }
if self.inner.set_address_pending {
self.inner.bus.set_address(self.inner.address);
self.inner.set_address_pending = false;
}
} }
async fn handle_control_in(&mut self, req: Request) { async fn handle_control_in(&mut self, req: Request) {
@ -266,7 +279,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
// a full-length packet is a short packet, thinking we're done sending data. // a full-length packet is a short packet, thinking we're done sending data.
// See https://github.com/hathach/tinyusb/issues/184 // See https://github.com/hathach/tinyusb/issues/184
const DEVICE_DESCRIPTOR_LEN: usize = 18; const DEVICE_DESCRIPTOR_LEN: usize = 18;
if self.inner.pending_address == 0 if self.inner.address == 0
&& max_packet_size < DEVICE_DESCRIPTOR_LEN && max_packet_size < DEVICE_DESCRIPTOR_LEN
&& (max_packet_size as usize) < resp_length && (max_packet_size as usize) < resp_length
{ {
@ -337,7 +350,7 @@ impl<'d, D: Driver<'d>> Inner<'d, D> {
self.device_state = UsbDeviceState::Default; self.device_state = UsbDeviceState::Default;
self.suspended = false; self.suspended = false;
self.remote_wakeup_enabled = false; self.remote_wakeup_enabled = false;
self.pending_address = 0; self.address = 0;
for iface in self.interfaces.iter_mut() { for iface in self.interfaces.iter_mut() {
iface.current_alt_setting = 0; iface.current_alt_setting = 0;
@ -389,11 +402,11 @@ impl<'d, D: Driver<'d>> Inner<'d, D> {
OutResponse::Accepted OutResponse::Accepted
} }
(Request::SET_ADDRESS, addr @ 1..=127) => { (Request::SET_ADDRESS, addr @ 1..=127) => {
self.pending_address = addr as u8; self.address = addr as u8;
self.bus.set_address(self.pending_address); self.set_address_pending = true;
self.device_state = UsbDeviceState::Addressed; self.device_state = UsbDeviceState::Addressed;
if let Some(h) = &self.handler { if let Some(h) = &self.handler {
h.addressed(self.pending_address); h.addressed(self.address);
} }
OutResponse::Accepted OutResponse::Accepted
} }