diff --git a/src/device/usbd.c b/src/device/usbd.c index f2becab95..5c6fc3748 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -44,6 +44,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint8_t connected : 1; + volatile uint8_t addressed : 1; volatile uint8_t configured : 1; volatile uint8_t suspended : 1; @@ -478,6 +479,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // Depending on mcu, status phase could be sent either before or after changing device address // Therefore DCD must include zero-length status response dcd_set_address(rhport, (uint8_t) p_request->wValue); + _usbd_dev.addressed = 1; return true; // skip status break; @@ -752,7 +754,17 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const switch(desc_type) { case TUSB_DESC_DEVICE: - return tud_control_xfer(rhport, p_request, (void*) tud_descriptor_device_cb(), sizeof(tusb_desc_device_t)); + { + uint16_t len = sizeof(tusb_desc_device_t); + + // Only send up to EP0 Packet Size if not addressed + if ((CFG_TUD_ENDPOINT0_SIZE < sizeof(tusb_desc_device_t)) && !_usbd_dev.addressed) + { + len = CFG_TUD_ENDPOINT0_SIZE; + } + + return tud_control_xfer(rhport, p_request, (void*) tud_descriptor_device_cb(), len); + } break; case TUSB_DESC_BOS: @@ -820,6 +832,7 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr) case DCD_EVENT_UNPLUGGED: _usbd_dev.connected = 0; + _usbd_dev.addressed = 0; _usbd_dev.configured = 0; _usbd_dev.suspended = 0; osal_queue_send(_usbd_q, event, in_isr);