diff --git a/src/device/dcd.h b/src/device/dcd.h index 9fa98c669..c88465cbb 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -119,6 +119,10 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr); // clear stall, data toggle is also reset to DATA0 void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); +// Invoked when a control transfer's status stage is complete. +// May help DCD to prepare for next control transfer, this API is optional. +void dcd_control_status_complete(uint8_t rhport) TU_ATTR_WEAK; + //--------------------------------------------------------------------+ // Event API //--------------------------------------------------------------------+ diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index f41614ef1..d37e9ec2a 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -129,6 +129,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result if ( tu_edpt_dir(ep_addr) != _ctrl_xfer.request.bmRequestType_bit.direction ) { TU_ASSERT(0 == xferred_bytes); + if (dcd_control_status_complete) dcd_control_status_complete(rhport); return true; } diff --git a/test/test/device/usbd/test_usbd.c b/test/test/device/usbd/test_usbd.c index add947b3d..a4063a488 100644 --- a/test/test/device/usbd/test_usbd.c +++ b/test/test/device/usbd/test_usbd.c @@ -231,5 +231,7 @@ void test_usbd_control_in_zlp(void) dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_CTRL_OUT, NULL, 0, true); dcd_event_xfer_complete(rhport, EDPT_CTRL_OUT, 0, 0, false); + dcd_control_status_complete_Expect(rhport); + tud_task(); }