usb: Ensure control events are handled in order

Use EP0 OUT flow control to NAK OUT packets when we're not yet expecting
any. This prevents the status OUT event from arriving while the control
state machine is still expecting the data IN completion event.
This commit is contained in:
Vegard Storheil Eriksen 2017-04-27 17:07:13 +02:00 committed by Karl Palsson
parent d97c1b0435
commit 58f2ee34fa

View File

@ -211,6 +211,8 @@ static void usb_control_setup_write(usbd_device *usbd_dev,
} else { } else {
usbd_dev->control_state.state = LAST_DATA_OUT; usbd_dev->control_state.state = LAST_DATA_OUT;
} }
usbd_ep_nak_set(usbd_dev, 0, 0);
} }
/* Do not appear to belong to the API, so are omitted from docs */ /* Do not appear to belong to the API, so are omitted from docs */
@ -223,6 +225,8 @@ void _usbd_control_setup(usbd_device *usbd_dev, uint8_t ea)
usbd_dev->control_state.complete = NULL; usbd_dev->control_state.complete = NULL;
usbd_ep_nak_set(usbd_dev, 0, 1);
if (usbd_ep_read_packet(usbd_dev, 0, req, 8) != 8) { if (usbd_ep_read_packet(usbd_dev, 0, req, 8) != 8) {
stall_transaction(usbd_dev); stall_transaction(usbd_dev);
return; return;
@ -294,6 +298,7 @@ void _usbd_control_in(usbd_device *usbd_dev, uint8_t ea)
break; break;
case LAST_DATA_IN: case LAST_DATA_IN:
usbd_dev->control_state.state = STATUS_OUT; usbd_dev->control_state.state = STATUS_OUT;
usbd_ep_nak_set(usbd_dev, 0, 0);
break; break;
case STATUS_IN: case STATUS_IN:
if (usbd_dev->control_state.complete) { if (usbd_dev->control_state.complete) {