summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhathach <[email protected]>2025-04-18 22:39:59 +0700
committerhathach <[email protected]>2025-04-18 22:46:37 +0700
commitd51863d1a006f01f9d4ab9e9863dd6c6fdf8f13b (patch)
treeb881dcfeb35169b5bc1091a0387600c3ddb8ac0f /src
parent8111e53ff067ca3a55f06389e4571fd57554ae5a (diff)
- correctly do_ping if received nyet as transfer complete e.g msc 31 byte command
- correctly carry out OUT transfer when PING is ack
Diffstat (limited to 'src')
-rw-r--r--src/portable/synopsys/dwc2/dwc2_type.h6
-rw-r--r--src/portable/synopsys/dwc2/hcd_dwc2.c14
2 files changed, 12 insertions, 8 deletions
diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h
index 34e046346..0a8dacf5f 100644
--- a/src/portable/synopsys/dwc2/dwc2_type.h
+++ b/src/portable/synopsys/dwc2/dwc2_type.h
@@ -2088,9 +2088,9 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size");
#define HCTSIZ_DOPING_Pos (31U)
#define HCTSIZ_DOPING_Msk (0x1UL << HCTSIZ_DOPING_Pos) // 0x80000000
#define HCTSIZ_DOPING HCTSIZ_DOPING_Msk // Do PING
-#define HCTSIZ_PID_Pos (29U)
-#define HCTSIZ_PID_Msk (0x3UL << HCTSIZ_PID_Pos) // 0x60000000
-#define HCTSIZ_PID HCTSIZ_PID_Msk // Data PID
+#define HCTSIZ_PID_Pos (29U)
+#define HCTSIZ_PID_Msk (0x3UL << HCTSIZ_PID_Pos) // 0x60000000
+#define HCTSIZ_PID HCTSIZ_PID_Msk // Data PID
/******************** Bit definition for DIEPDMA register ********************/
#define DIEPDMA_DMAADDR_Pos (0U)
diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c
index e1035fa55..1845c5e19 100644
--- a/src/portable/synopsys/dwc2/hcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/hcd_dwc2.c
@@ -959,6 +959,10 @@ static bool handle_channel_out_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t
is_done = true;
xfer->result = XFER_RESULT_SUCCESS;
channel->hcintmsk &= ~HCINT_ACK;
+ if (hcint & HCINT_NYET) {
+ // complete transfer with NYET, do ping next time
+ edpt->next_do_ping = 1;
+ }
} else if (hcint & HCINT_STALL) {
xfer->result = XFER_RESULT_STALLED;
channel_disable(dwc2, channel);
@@ -1002,16 +1006,16 @@ static bool handle_channel_out_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t
channel->hcintmsk &= ~HCINT_ACK;
if (hcsplt.split_en) {
if (!hcsplt.split_compl) {
- // start split is ACK --> do complete split
+ // ACK for start split --> do complete split
hcsplt.split_compl = 1;
channel->hcsplt = hcsplt.value;
channel->hcchar |= HCCHAR_CHENA;
}
} else {
- // Device is ready, resume transfer
- edpt->next_do_ping = 0;
- xfer->err_count = 0;
- TU_ASSERT(channel_xfer_start(dwc2, ch_id));
+ // ACK interrupt is only enabled for Split and PING
+ // ACK for PING, which mean device is ready to receive data
+ channel->hctsiz &= ~HCTSIZ_DOPING; // HC already cleared PING bit, but we clear anyway
+ channel->hcchar |= HCCHAR_CHENA;
}
}