Skip to content

Commit 5572168

Browse files
authored
Merge pull request hathach#3077 from HiFiPhile/ping_out
2 parents e44f556 + d51863d commit 5572168

File tree

2 files changed

+26
-15
lines changed

2 files changed

+26
-15
lines changed

src/portable/synopsys/dwc2/dwc2_type.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,9 +2088,9 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size");
20882088
#define HCTSIZ_DOPING_Pos (31U)
20892089
#define HCTSIZ_DOPING_Msk (0x1UL << HCTSIZ_DOPING_Pos) // 0x80000000
20902090
#define HCTSIZ_DOPING HCTSIZ_DOPING_Msk // Do PING
2091-
#define HCTSIZ_PID_Pos (29U)
2092-
#define HCTSIZ_PID_Msk (0x3UL << HCTSIZ_PID_Pos) // 0x60000000
2093-
#define HCTSIZ_PID HCTSIZ_PID_Msk // Data PID
2091+
#define HCTSIZ_PID_Pos (29U)
2092+
#define HCTSIZ_PID_Msk (0x3UL << HCTSIZ_PID_Pos) // 0x60000000
2093+
#define HCTSIZ_PID HCTSIZ_PID_Msk // Data PID
20942094

20952095
/******************** Bit definition for DIEPDMA register ********************/
20962096
#define DIEPDMA_DMAADDR_Pos (0U)

src/portable/synopsys/dwc2/hcd_dwc2.c

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ typedef struct {
7575

7676
struct TU_ATTR_PACKED {
7777
uint32_t uframe_interval : 18; // micro-frame interval
78-
uint32_t speed : 2;
79-
uint32_t next_pid : 2;
80-
uint32_t do_ping : 1;
78+
uint32_t speed : 2;
79+
uint32_t next_pid : 2; // PID for next transfer
80+
uint32_t next_do_ping : 1; // Do PING for next transfer if possible (highspeed OUT)
8181
// uint32_t : 9;
8282
};
8383

@@ -567,12 +567,12 @@ static bool channel_xfer_start(dwc2_regs_t* dwc2, uint8_t ch_id) {
567567
hctsiz.pid = edpt->next_pid; // next PID is set in transfer complete interrupt
568568
hctsiz.packet_count = packet_count;
569569
hctsiz.xfer_size = edpt->buflen;
570-
if (edpt->do_ping && edpt->speed == TUSB_SPEED_HIGH &&
570+
if (edpt->next_do_ping && edpt->speed == TUSB_SPEED_HIGH &&
571571
edpt->next_pid != HCTSIZ_PID_SETUP && hcchar_bm->ep_dir == TUSB_DIR_OUT) {
572572
hctsiz.do_ping = 1;
573573
}
574574
channel->hctsiz = hctsiz.value;
575-
edpt->do_ping = 0;
575+
edpt->next_do_ping = 0;
576576

577577
// pre-calculate next PID based on packet count, adjusted in transfer complete interrupt if short packet
578578
if (hcchar_bm->ep_num == 0) {
@@ -603,7 +603,7 @@ static bool channel_xfer_start(dwc2_regs_t* dwc2, uint8_t ch_id) {
603603
hcintmsk |= HCINT_BABBLE_ERR | HCINT_DATATOGGLE_ERR | HCINT_ACK;
604604
} else {
605605
hcintmsk |= HCINT_NYET;
606-
if (edpt->hcsplt_bm.split_en) {
606+
if (edpt->hcsplt_bm.split_en || hctsiz.do_ping) {
607607
hcintmsk |= HCINT_ACK;
608608
}
609609
}
@@ -959,6 +959,10 @@ static bool handle_channel_out_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t
959959
is_done = true;
960960
xfer->result = XFER_RESULT_SUCCESS;
961961
channel->hcintmsk &= ~HCINT_ACK;
962+
if (hcint & HCINT_NYET) {
963+
// complete transfer with NYET, do ping next time
964+
edpt->next_do_ping = 1;
965+
}
962966
} else if (hcint & HCINT_STALL) {
963967
xfer->result = XFER_RESULT_STALLED;
964968
channel_disable(dwc2, channel);
@@ -970,7 +974,7 @@ static bool handle_channel_out_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t
970974
channel->hcsplt = hcsplt.value;
971975
channel->hcchar |= HCCHAR_CHENA;
972976
} else {
973-
edpt->do_ping = 1;
977+
edpt->next_do_ping = 1;
974978
channel_xfer_out_wrapup(dwc2, ch_id);
975979
channel_disable(dwc2, channel);
976980
}
@@ -983,7 +987,7 @@ static bool handle_channel_out_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t
983987
channel->hcintmsk |= HCINT_ACK;
984988
} else {
985989
// NAK disable channel to flush all posted request and try again
986-
edpt->do_ping = 1;
990+
edpt->next_do_ping = 1;
987991
xfer->err_count = 0;
988992
}
989993
} else if (hcint & HCINT_HALTED) {
@@ -1000,10 +1004,17 @@ static bool handle_channel_out_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t
10001004
} else if (hcint & HCINT_ACK) {
10011005
xfer->err_count = 0;
10021006
channel->hcintmsk &= ~HCINT_ACK;
1003-
if (hcsplt.split_en && !hcsplt.split_compl) {
1004-
// start split is ACK --> do complete split
1005-
hcsplt.split_compl = 1;
1006-
channel->hcsplt = hcsplt.value;
1007+
if (hcsplt.split_en) {
1008+
if (!hcsplt.split_compl) {
1009+
// ACK for start split --> do complete split
1010+
hcsplt.split_compl = 1;
1011+
channel->hcsplt = hcsplt.value;
1012+
channel->hcchar |= HCCHAR_CHENA;
1013+
}
1014+
} else {
1015+
// ACK interrupt is only enabled for Split and PING
1016+
// ACK for PING, which mean device is ready to receive data
1017+
channel->hctsiz &= ~HCTSIZ_DOPING; // HC already cleared PING bit, but we clear anyway
10071018
channel->hcchar |= HCCHAR_CHENA;
10081019
}
10091020
}

0 commit comments

Comments
 (0)