summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/portable/synopsys/dwc2/dcd_dwc2.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c
index 30e24a9ad..9b8f44df8 100644
--- a/src/portable/synopsys/dwc2/dcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/dcd_dwc2.c
@@ -946,7 +946,17 @@ static void handle_rxflvl_irq(uint8_t rhport) {
}
static void handle_epout_slave(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepint_bm) {
+ xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
+ const bool ep0_status_complete_before_setup = (epnum == 0) && doepint_bm.setup_phase_done &&
+ doepint_bm.xfer_complete &&
+ (_dcd_data.ep0_pending[TUSB_DIR_OUT] == 0) &&
+ (xfer->total_len == 0);
+
if (doepint_bm.setup_phase_done) {
+ if (ep0_status_complete_before_setup) {
+ dcd_event_xfer_complete(rhport, epnum, 0, XFER_RESULT_SUCCESS, true);
+ }
+
// Cleanup previous pending EP0 IN transfer if any
dwc2_dep_t* epin0 = &DWC2_REG(rhport)->epin[0];
if (edpt_is_enabled(epin0)) {
@@ -962,7 +972,6 @@ static void handle_epout_slave(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doe
// Note: even though (xfer_complete + status_phase_rx) is for buffered DMA only, for STM32L47x (dwc2 v3.00a) they
// can is set when GRXSTS_PKTSTS_SETUP_RX is popped therefore they can bet set before/together with setup_phase_done
if (!doepint_bm.status_phase_rx && !doepint_bm.setup_packet_rx) {
- xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
if ((epnum == 0) && _dcd_data.ep0_pending[TUSB_DIR_OUT]) {
// EP0 can only handle one packet, Schedule another packet to be received.
edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT);
@@ -1005,8 +1014,17 @@ static void handle_epin_slave(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diep
#if CFG_TUD_DWC2_DMA_ENABLE
static void handle_epout_dma(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepint_bm) {
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
+ xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
+ const bool ep0_status_complete_before_setup = (epnum == 0) && doepint_bm.setup_phase_done &&
+ doepint_bm.xfer_complete &&
+ (_dcd_data.ep0_pending[TUSB_DIR_OUT] == 0) &&
+ (xfer->total_len == 0);
if (doepint_bm.setup_phase_done) {
+ if (ep0_status_complete_before_setup) {
+ dcd_event_xfer_complete(rhport, epnum, 0, XFER_RESULT_SUCCESS, true);
+ }
+
// Cleanup previous pending EP0 IN transfer if any
dwc2_dep_t* epin0 = &DWC2_REG(rhport)->epin[0];
if (edpt_is_enabled(epin0)) {
@@ -1028,7 +1046,6 @@ static void handle_epout_dma(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepi
edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT);
} else {
dwc2_dep_t* epout = &dwc2->epout[epnum];
- xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
// determine actual received bytes
const dwc2_ep_tsize_t tsiz = {.value = epout->tsiz};