summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2024-10-10 11:34:05 +0700
committerGitHub <[email protected]>2024-10-10 11:34:05 +0700
commitffdf81f53a84111a2536defa86e4a637c3c46854 (patch)
tree66246177d826c1ebf1a38d66d3197b1ec442a21f /src
parent65242fd11f8f37d8c05170143ffe2f37697a15a2 (diff)
parent1406ad84e3cd7e39771303dd23e6be361b51de96 (diff)
Merge pull request #2833 from hathach/update-dwc2
more dwc2 enhance
Diffstat (limited to 'src')
-rw-r--r--src/portable/synopsys/dwc2/dcd_dwc2.c313
-rw-r--r--src/portable/synopsys/dwc2/dwc2_info.md116
-rwxr-xr-xsrc/portable/synopsys/dwc2/dwc2_info.py149
-rw-r--r--src/portable/synopsys/dwc2/dwc2_type.h102
4 files changed, 382 insertions, 298 deletions
diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c
index 4fa869241..1ba3507ef 100644
--- a/src/portable/synopsys/dwc2/dcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/dcd_dwc2.c
@@ -327,53 +327,49 @@ static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoin
xfer->interval = p_endpoint_desc->bInterval;
// USBAEP, EPTYP, SD0PID_SEVNFRM, MPSIZ are the same for IN and OUT endpoints.
- uint32_t const dxepctl = (1 << DOEPCTL_USBAEP_Pos) |
- (p_endpoint_desc->bmAttributes.xfer << DOEPCTL_EPTYP_Pos) |
- (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DOEPCTL_SD0PID_SEVNFRM : 0) |
- (xfer->max_size << DOEPCTL_MPSIZ_Pos);
-
- if (dir == TUSB_DIR_OUT) {
- dwc2->epout[epnum].doepctl = dxepctl;
- dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum);
- } else {
- dwc2->epin[epnum].diepctl = dxepctl | (epnum << DIEPCTL_TXFNUM_Pos);
- dwc2->daintmsk |= TU_BIT(DAINTMSK_IEPM_Pos + epnum);
+ uint32_t epctl = (1 << DOEPCTL_USBAEP_Pos) |
+ (p_endpoint_desc->bmAttributes.xfer << DOEPCTL_EPTYP_Pos) |
+ (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DOEPCTL_SD0PID_SEVNFRM : 0) |
+ (xfer->max_size << DOEPCTL_MPSIZ_Pos);
+ if (dir == TUSB_DIR_IN) {
+ epctl |= (epnum << DIEPCTL_TXFNUM_Pos);
}
+
+ dwc2_dep_t* dep = &dwc2->ep[1 - dir][epnum];
+ dep->ctl = epctl;
+ dwc2->daintmsk |= TU_BIT(epnum + DAINT_SHIFT(dir));
}
static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) {
(void) rhport;
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
- uint8_t const epnum = tu_edpt_number(ep_addr);
- uint8_t const dir = tu_edpt_dir(ep_addr);
+ const uint8_t epnum = tu_edpt_number(ep_addr);
+ const uint8_t dir = tu_edpt_dir(ep_addr);
+ dwc2_dep_t* dep = &dwc2->ep[1 - dir][epnum];
if (dir == TUSB_DIR_IN) {
- dwc2_epin_t* epin = dwc2->epin;
-
// Only disable currently enabled non-control endpoint
- if ((epnum == 0) || !(epin[epnum].diepctl & DIEPCTL_EPENA)) {
- epin[epnum].diepctl |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0);
+ if ((epnum == 0) || !(dep->diepctl & DIEPCTL_EPENA)) {
+ dep->diepctl |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0);
} else {
// Stop transmitting packets and NAK IN xfers.
- epin[epnum].diepctl |= DIEPCTL_SNAK;
- while ((epin[epnum].diepint & DIEPINT_INEPNE) == 0) {}
+ dep->diepctl |= DIEPCTL_SNAK;
+ while ((dep->diepint & DIEPINT_INEPNE) == 0) {}
// Disable the endpoint.
- epin[epnum].diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0);
- while ((epin[epnum].diepint & DIEPINT_EPDISD_Msk) == 0) {}
+ dep->diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0);
+ while ((dep->diepint & DIEPINT_EPDISD_Msk) == 0) {}
- epin[epnum].diepint = DIEPINT_EPDISD;
+ dep->diepint = DIEPINT_EPDISD;
}
// Flush the FIFO, and wait until we have confirmed it cleared.
dfifo_flush_tx(dwc2, epnum);
} else {
- dwc2_epout_t* epout = dwc2->epout;
-
// Only disable currently enabled non-control endpoint
- if ((epnum == 0) || !(epout[epnum].doepctl & DOEPCTL_EPENA)) {
- epout[epnum].doepctl |= stall ? DOEPCTL_STALL : 0;
+ if ((epnum == 0) || !(dep->doepctl & DOEPCTL_EPENA)) {
+ dep->doepctl |= stall ? DOEPCTL_STALL : 0;
} else {
// Asserting GONAK is required to STALL an OUT endpoint.
// Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt
@@ -382,11 +378,11 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) {
dwc2->dctl |= DCTL_SGONAK;
while ((dwc2->gintsts & GINTSTS_BOUTNAKEFF_Msk) == 0) {}
- // Ditto here- disable the endpoint.
- epout[epnum].doepctl |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0);
- while ((epout[epnum].doepint & DOEPINT_EPDISD_Msk) == 0) {}
+ // Ditto here disable the endpoint.
+ dep->doepctl |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0);
+ while ((dep->doepint & DOEPINT_EPDISD_Msk) == 0) {}
- epout[epnum].doepint = DOEPINT_EPDISD;
+ dep->doepint = DOEPINT_EPDISD;
// Allow other OUT endpoints to keep receiving.
dwc2->dctl |= DCTL_CGONAK;
@@ -402,12 +398,8 @@ static void bus_reset(uint8_t rhport) {
tu_memclr(xfer_status, sizeof(xfer_status));
_sof_en = false;
-
_allocated_ep_in_count = 1;
- // clear device address
- dwc2->dcfg &= ~DCFG_DAD_Msk;
-
// 1. NAK for all OUT endpoints
for (uint8_t n = 0; n < ep_count; n++) {
dwc2->epout[n].doepctl |= DOEPCTL_SNAK;
@@ -423,14 +415,18 @@ static void bus_reset(uint8_t rhport) {
dfifo_flush_tx(dwc2, 0x10); // all tx fifo
dfifo_flush_rx(dwc2);
- // 3. Set up interrupt mask
+ // 3. Set up interrupt mask for EP0
dwc2->daintmsk = TU_BIT(DAINTMSK_OEPM_Pos) | TU_BIT(DAINTMSK_IEPM_Pos);
dwc2->doepmsk = DOEPMSK_STUPM | DOEPMSK_XFRCM;
dwc2->diepmsk = DIEPMSK_TOM | DIEPMSK_XFRCM;
+ // 4. Set up DFIFO
dfifo_init(rhport);
- // Fixed control EP0 size to 64 bytes
+ // 5. Reset device address
+ dwc2->dcfg &= ~DCFG_DAD_Msk;
+
+ // Fixed both control EP0 size to 64 bytes
dwc2->epin[0].diepctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos);
dwc2->epout[0].doepctl &= ~(0x03 << DOEPCTL_MPSIZ_Pos);
@@ -461,33 +457,33 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c
}
// IN and OUT endpoint xfers are interrupt-driven, we just schedule them here.
- if (dir == TUSB_DIR_IN) {
- dwc2_epin_t* epin = dwc2->epin;
+ const uint8_t is_epout = 1 - dir;
+ dwc2_dep_t* dep = &dwc2->ep[is_epout][epnum];
+ if (dir == TUSB_DIR_IN) {
// A full IN transfer (multiple packets, possibly) triggers XFRC.
- epin[epnum].dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) |
+ dep->dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) |
((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk);
if(dma_enabled(dwc2)) {
- epin[epnum].diepdma = (uintptr_t)xfer->buffer;
+ dep->diepdma = (uintptr_t)xfer->buffer;
// For ISO endpoint set correct odd/even bit for next frame.
- if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) {
+ if ((dep->diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) {
// Take odd/even bit from frame counter.
uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos));
- epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk);
+ dep->diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk);
}
- epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK;
+ dep->diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK;
} else {
-
- epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK;
+ dep->diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK;
// For ISO endpoint set correct odd/even bit for next frame.
- if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) {
+ if ((dep->diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) {
// Take odd/even bit from frame counter.
uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos));
- epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk);
+ dep->diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk);
}
// Enable fifo empty interrupt only if there are something to put in the fifo.
if (total_bytes != 0) {
@@ -495,25 +491,23 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c
}
}
} else {
- dwc2_epout_t* epout = dwc2->epout;
-
// A full OUT transfer (multiple packets, possibly) triggers XFRC.
- epout[epnum].doeptsiz &= ~(DOEPTSIZ_PKTCNT_Msk | DOEPTSIZ_XFRSIZ);
- epout[epnum].doeptsiz |= (num_packets << DOEPTSIZ_PKTCNT_Pos) |
+ dep->doeptsiz &= ~(DOEPTSIZ_PKTCNT_Msk | DOEPTSIZ_XFRSIZ);
+ dep->doeptsiz |= (num_packets << DOEPTSIZ_PKTCNT_Pos) |
((total_bytes << DOEPTSIZ_XFRSIZ_Pos) & DOEPTSIZ_XFRSIZ_Msk);
- if ((epout[epnum].doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 &&
+ if ((dep->doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 &&
XFER_CTL_BASE(epnum, dir)->interval == 1) {
// Take odd/even bit from frame counter.
uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos));
- epout[epnum].doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk);
+ dep->doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk);
}
if(dma_enabled(dwc2)) {
- epout[epnum].doepdma = (uintptr_t)xfer->buffer;
+ dep->doepdma = (uintptr_t)xfer->buffer;
}
- epout[epnum].doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK;
+ dep->doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK;
}
}
@@ -637,7 +631,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) {
static bool check_dwc2(dwc2_regs_t* dwc2) {
#if CFG_TUSB_DEBUG >= DWC2_DEBUG
// print guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4
- // Run 'dwc2_info.py render-md' and check dwc2_info.md for bit-field value and comparison with other ports
+ // Run 'python dwc2_info.py' and check dwc2_info.md for bit-field value and comparison with other ports
volatile uint32_t const* p = (volatile uint32_t const*) &dwc2->guid;
TU_LOG1("guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4\r\n");
for (size_t i = 0; i < 5; i++) {
@@ -837,17 +831,13 @@ void dcd_edpt_close_all(uint8_t rhport) {
dwc2->daintmsk = (1 << DAINTMSK_OEPM_Pos) | (1 << DAINTMSK_IEPM_Pos);
for (uint8_t n = 1; n < ep_count; n++) {
- // disable OUT endpoint
- if (dwc2->epout[n].doepctl & DOEPCTL_EPENA) {
- dwc2->epout[n].doepctl |= DOEPCTL_SNAK | DOEPCTL_EPDIS;
- }
- xfer_status[n][TUSB_DIR_OUT].max_size = 0;
-
- // disable IN endpoint
- if (dwc2->epin[n].diepctl & DIEPCTL_EPENA) {
- dwc2->epin[n].diepctl |= DIEPCTL_SNAK | DIEPCTL_EPDIS;
+ for (uint8_t d = 0; d < 2; d++) {
+ dwc2_dep_t* dep = &dwc2->ep[d][n];
+ if (dep->ctl & EPCTL_EPENA) {
+ dep->ctl |= EPCTL_SNAK | EPCTL_EPDIS;
+ }
+ xfer_status[n][1-d].max_size = 0;
}
- xfer_status[n][TUSB_DIR_IN].max_size = 0;
}
dfifo_flush_tx(dwc2, 0x10); // all tx fifo
@@ -917,7 +907,9 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t
uint16_t const short_packet_size = total_bytes % xfer->max_size;
// Zero-size packet is special case.
- if (short_packet_size > 0 || (total_bytes == 0)) num_packets++;
+ if (short_packet_size > 0 || (total_bytes == 0)) {
+ num_packets++;
+ }
// Schedule packets to be sent within interrupt
edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes);
@@ -937,50 +929,32 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
}
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
- (void) rhport;
-
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
-
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
+ dwc2_dep_t* dep = &dwc2->ep[1 - dir][epnum];
// Clear stall and reset data toggle
- if (dir == TUSB_DIR_IN) {
- dwc2->epin[epnum].diepctl &= ~DIEPCTL_STALL;
- dwc2->epin[epnum].diepctl |= DIEPCTL_SD0PID_SEVNFRM;
- } else {
- dwc2->epout[epnum].doepctl &= ~DOEPCTL_STALL;
- dwc2->epout[epnum].doepctl |= DOEPCTL_SD0PID_SEVNFRM;
- }
+ dep->ctl &= ~EPCTL_STALL;;
+ dep->ctl |= EPCTL_SD0PID_SEVNFRM;
}
//--------------------------------------------------------------------
// Interrupt Handler
//--------------------------------------------------------------------
+// Process shared receive FIFO, this interrupt is only used in Slave mode
static void handle_rxflvl_irq(uint8_t rhport) {
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
volatile uint32_t const* rx_fifo = dwc2->fifo[0];
// Pop control word off FIFO
- uint32_t const ctl_word = dwc2->grxstsp;
- uint8_t const pktsts = (ctl_word & GRXSTSP_PKTSTS_Msk) >> GRXSTSP_PKTSTS_Pos;
- uint8_t const epnum = (ctl_word & GRXSTSP_EPNUM_Msk) >> GRXSTSP_EPNUM_Pos;
- uint16_t const bcnt = (ctl_word & GRXSTSP_BCNT_Msk) >> GRXSTSP_BCNT_Pos;
-
+ uint32_t const grxstsp = dwc2->grxstsp;
+ uint8_t const pktsts = (grxstsp & GRXSTSP_PKTSTS_Msk) >> GRXSTSP_PKTSTS_Pos;
+ uint8_t const epnum = (grxstsp & GRXSTSP_EPNUM_Msk) >> GRXSTSP_EPNUM_Pos;
+ uint16_t const bcnt = (grxstsp & GRXSTSP_BCNT_Msk) >> GRXSTSP_BCNT_Pos;
dwc2_epout_t* epout = &dwc2->epout[epnum];
-//#if CFG_TUSB_DEBUG >= DWC2_DEBUG
-// const char * pktsts_str[] =
-// {
-// "ASSERT", "Global NAK (ISR)", "Out Data Received", "Out Transfer Complete (ISR)",
-// "Setup Complete (ISR)", "ASSERT", "Setup Data Received"
-// };
-// TU_LOG_LOCATION();
-// TU_LOG(DWC2_DEBUG, " EP %02X, Byte Count %u, %s\r\n", epnum, bcnt, pktsts_str[pktsts]);
-// TU_LOG(DWC2_DEBUG, " daint = %08lX, doepint = %04X\r\n", (unsigned long) dwc2->daint, (unsigned int) epout->doepint);
-//#endif
-
switch (pktsts) {
// Global OUT NAK: do nothing
case GRXSTS_PKTSTS_GLOBALOUTNAK:
@@ -988,15 +962,14 @@ static void handle_rxflvl_irq(uint8_t rhport) {
case GRXSTS_PKTSTS_SETUPRX:
// Setup packet received
-
- // We can receive up to three setup packets in succession, but
- // only the last one is valid.
+ // We can receive up to three setup packets in succession, but only the last one is valid.
_setup_packet[0] = (*rx_fifo);
_setup_packet[1] = (*rx_fifo);
break;
case GRXSTS_PKTSTS_SETUPDONE:
- // Setup packet done (Interrupt)
+ // Setup packet done:
+ // After popping this out, dwc2 asserts a DOEPINT_SETUP interrupt which is handled by handle_epout_irq()
epout->doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos);
break;
@@ -1024,20 +997,16 @@ static void handle_rxflvl_irq(uint8_t rhport) {
ep0_pending[TUSB_DIR_OUT] = 0;
}
}
- }
break;
+ }
- // Out packet done (Interrupt)
case GRXSTS_PKTSTS_OUTDONE:
- // Occurred on STM32L47 with dwc2 version 3.10a but not found on other version like 2.80a or 3.30a
- // May (or not) be 3.10a specific feature/bug or depending on MCU configuration
- // XFRC complete is additionally generated when
- // - setup packet is received
- // - complete the data stage of control write is complete
- // It will be handled in handle_epout_irq()
+ /* Out packet done
+ After this entry is popped from the receive FIFO, dwc2 asserts a Transfer Completed interrupt on
+ the specified OUT endpoint which will be handled by handle_epout_irq() */
break;
- default: // Invalid
+ default:
TU_BREAKPOINT();
break;
}
@@ -1049,80 +1018,70 @@ static void handle_epout_irq(uint8_t rhport) {
// DAINT for a given EP clears when DOEPINTx is cleared.
// OEPINT will be cleared when DAINT's out bits are cleared.
- for (uint8_t n = 0; n < ep_count; n++) {
- if (dwc2->daint & TU_BIT(DAINT_OEPINT_Pos + n)) {
- dwc2_epout_t* epout = &dwc2->epout[n];
+ for (uint8_t epnum = 0; epnum < ep_count; epnum++) {
+ if (dwc2->daint & TU_BIT(DAINT_OEPINT_Pos + epnum)) {
+ dwc2_epout_t* epout = &dwc2->epout[epnum];
+ const uint32_t doepint = epout->doepint;
+ TU_ASSERT((epout->doepint & DOEPINT_AHBERR) == 0, );
- uint32_t const doepint = epout->doepint;
+ // Setup and/or STPKTRX/STSPHSRX (from 3.00a) can be set along with XFRC, and also set independently.
+ if (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a) {
+ if (doepint & DOEPINT_STSPHSRX) {
+ // Status phase received for control write: In token received from Host
+ epout->doepint = DOEPINT_STSPHSRX;
+ }
- TU_ASSERT((epout->doepint & DOEPINT_AHBERR) == 0, );
+ if (doepint & DOEPINT_STPKTRX) {
+ // New setup packet received, but wait for Setup done, since we can receive up to 3 setup consecutively
+ epout->doepint = DOEPINT_STPKTRX;
+ }
+ }
+
+ if (doepint & DOEPINT_SETUP) {
+ epout->doepint = DOEPINT_SETUP;
+
+ if(dma_enabled(dwc2)) {
+ dma_setup_prepare(rhport);
+ }
+
+ dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true);
+ }
// OUT XFER complete
- if (epout->doepint & DOEPINT_XFRC) {
+ if (doepint & DOEPINT_XFRC) {
epout->doepint = DOEPINT_XFRC;
- xfer_ctl_t* xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT);
+ // only handle data skip if it is setup or status related
+ // Normal OUT transfer complete
+ if (!(doepint & (DOEPINT_SETUP | DOEPINT_STPKTRX | DOEPINT_STSPHSRX))) {
+ xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
- if(dma_enabled(dwc2)) {
- if (doepint & DOEPINT_STUP) {
- // STPKTRX is only available for version from 3_00a
- if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) {
- epout->doepint = DOEPINT_STPKTRX;
- }
- } else if (doepint & DOEPINT_OTEPSPR) {
- epout->doepint = DOEPINT_OTEPSPR;
- } else {
- if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) {
- epout->doepint = DOEPINT_STPKTRX;
+ if(dma_enabled(dwc2)) {
+ if ((epnum == 0) && 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, 1, ep0_pending[TUSB_DIR_OUT]);
} else {
- // EP0 can only handle one packet
- if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) {
- // Schedule another packet to be received.
- edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]);
- } else {
- // Fix packet length
- uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos;
- xfer->total_len -= remain;
- // this is ZLP, so prepare EP0 for next setup
- if(n == 0 && xfer->total_len == 0) {
- dma_setup_prepare(rhport);
- }
-
- dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true);
+ // Fix packet length
+ uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos;
+ xfer->total_len -= remain;
+ // this is ZLP, so prepare EP0 for next setup
+ if(epnum == 0 && xfer->total_len == 0) {
+ dma_setup_prepare(rhport);
}
+
+ dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true);
}
- }
- } else {
- if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) {
- epout->doepint = DOEPINT_STPKTRX;
} else {
- if ((doepint & DOEPINT_OTEPSPR) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) {
- epout->doepint = DOEPINT_OTEPSPR;
- }
-
// EP0 can only handle one packet
- if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) {
+ if ((epnum == 0) && ep0_pending[TUSB_DIR_OUT]) {
// Schedule another packet to be received.
- edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]);
+ edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]);
} else {
- dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true);
+ dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true);
}
}
}
}
-
- // SETUP packet Setup Phase done.
- if (doepint & DOEPINT_STUP) {
- epout->doepint = DOEPINT_STUP;
- if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) {
- epout->doepint = DOEPINT_STPKTRX;
- }
- if(dma_enabled(dwc2) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) {
- dma_setup_prepare(rhport);
- }
-
- dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true);
- }
}
}
}
@@ -1195,6 +1154,29 @@ static void handle_epin_irq(uint8_t rhport) {
}
}
+/* Interrupt Hierarchy
+
+ DxEPMSK.XferComplMsk DxEPINTn.XferCompl
+ | |
+ +---------- AND --------+
+ |
+ DAINT.xEPnInt DAINTMSK.xEPnMsk
+ | |
+ +---------- AND --------+
+ |
+ GINTSTS.xEPInt GINTMSK.xEPIntMsk
+ | |
+ +---------- AND --------+
+ |
+ GAHBCFG.GblIntrMsk
+ |
+ IRQn
+
+ Note: when OTG_MULTI_PROC_INTRPT = 1, Device Each endpoint interrupt deachint/deachmsk/diepeachmsk/doepeachmsk
+ are combined to generate dedicated interrupt line for each endpoint.
+ */
+
+
void dcd_int_handler(uint8_t rhport) {
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
@@ -1272,13 +1254,10 @@ void dcd_int_handler(uint8_t rhport) {
// RxFIFO non-empty interrupt handling.
if (int_status & GINTSTS_RXFLVL) {
// RXFLVL bit is read-only
+ dwc2->gintmsk &= ~GINTMSK_RXFLVLM; // disable RXFLVL interrupt while reading
- // Mask out RXFLVL while reading data from FIFO
- dwc2->gintmsk &= ~GINTMSK_RXFLVLM;
-
- // Loop until all available packets were handled
do {
- handle_rxflvl_irq(rhport);
+ handle_rxflvl_irq(rhport); // read all packets
} while(dwc2->gintsts & GINTSTS_RXFLVL);
dwc2->gintmsk |= GINTMSK_RXFLVLM;
diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md
index 462b5856a..cfd0c81a8 100644
--- a/src/portable/synopsys/dwc2/dwc2_info.md
+++ b/src/portable/synopsys/dwc2/dwc2_info.md
@@ -1,58 +1,58 @@
-| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | ESP32-P4 | STM32F 407/411/429 FS | STM32F 407/429 HS | STM32F 412/767 FS | STM32F723 FS | STM32F723 HS | STM32H743 HS | STM32L476 FS | STM32U5A5 HS | GD32VF103 FS | XMC4500 |
-|:---------------------------|:----------------|:-------------|:--------------|:-----------|:------------------------|:--------------------|:--------------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:-----------|
-| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 |
-| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A |
-| - specs version | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a |
-| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 |
-| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 |
-| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 |
-| - arch | 2 | 2 | 2 | 2 | 0 | 2 | 0 | 0 | 2 | 2 | 0 | 2 | 0 | 2 |
-| - point2point | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 |
-| - hs_phy_type | 1 | 0 | 0 | 3 | 0 | 2 | 0 | 0 | 3 | 2 | 0 | 1 | 0 | 0 |
-| - fs_phy_type | 1 | 1 | 1 | 3 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
-| - num_dev_ep | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 |
-| - num_host_ch | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 11 | 15 | 0 | 13 |
-| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
-| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
-| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
-| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-| - nptx_q_depth | 2 | 2 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 |
-| - ptx_q_depth | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 |
-| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 |
-| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 |
-| - xfer_size_width | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 |
-| - packet_size_width | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 |
-| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
-| - i2c_enable | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 |
-| - vendor_ctrl_itf | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 |
-| - optional_feature_removed | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-| - synch_reset | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-| - otg_adp_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
-| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-| - battery_charger_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
-| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 |
-| - dfifo_depth | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 952 | 512 | 952 | 0 | 634 |
-| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 |
-| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
-| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
-| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
-| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
-| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
-| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
-| - enhanced_lpm_support | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
-| - phy_data_width | 0 | 2 | 2 | 2 | 2 | 0 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 2 |
-| - ctrl_ep_num | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
-| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
-| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
-| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
-| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
-| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
-| - num_dev_in_eps | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 |
-| - dma_desc_enable | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
-| - dma_desc_dynamic | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
+| | BCM2711 (Pi4) | EFM32GG | ESP32-S2/S3 | ESP32-P4 | ST F207/F407/411/429 FS | ST F407/429 HS | ST F412/767 FS | ST F723/L4P5 FS | ST F723 HS | ST F769 | ST H743/H750 | ST L476 FS | ST U5A5 HS | GD32VF103 | XMC4500 |
+|:---------------------------|:----------------|:-------------|:--------------|:-------------|:--------------------------|:-----------------|:-----------------|:------------------|:-------------|:-------------|:---------------|:-------------|:-------------|:------------|:-------------|
+| GUID | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 |
+| GSNPSID | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A |
+| - specs version | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a |
+| GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 |
+| GHWCFG2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 |
+| - op_mode | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP |
+| - arch | DMA internal | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | Slave only | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | DMA internal |
+| - p2p (hub support) | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
+| - hs_phy_type | UTMI+ | n/a | n/a | UTMI+/ULPI | n/a | ULPI | n/a | n/a | UTMI+/ULPI | ULPI | ULPI | n/a | UTMI+ | n/a | n/a |
+| - fs_phy_type | Dedicated | Dedicated | Dedicated | Shared ULPI | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | n/a | n/a | Dedicated |
+| - num_dev_ep | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 |
+| - num_host_ch | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 0 | 13 |
+| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
+| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
+| - mul_proc_intrpt | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
+| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+| - nptx_q_depth | 2 | 2 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 |
+| - ptx_q_depth | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 |
+| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 |
+| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+| GHWCFG3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 |
+| - xfer_size_width | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 |
+| - packet_size_width | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 |
+| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
+| - i2c_enable | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
+| - vendor_ctrl_itf | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
+| - optional_feature_removed | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+| - synch_reset | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+| - otg_adp_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
+| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+| - battery_charger_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
+| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 |
+| - dfifo_depth | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 1006 | 952 | 512 | 952 | 0 | 634 |
+| GHWCFG4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 |
+| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
+| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
+| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
+| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
+| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
+| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
+| - enhanced_lpm_support | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
+| - phy_data_width | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8 bit | 8/16 bit |
+| - ctrl_ep_num | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
+| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
+| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
+| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
+| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
+| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
+| - num_dev_in_eps | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 |
+| - dma_desc_enable | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
+| - dma_desc_dynamic | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py
index 33997ca19..d1793a005 100755
--- a/src/portable/synopsys/dwc2/dwc2_info.py
+++ b/src/portable/synopsys/dwc2/dwc2_info.py
@@ -1,37 +1,41 @@
#!/usr/bin/env python3
-import click
+
import ctypes
+import argparse
+import click
import pandas as pd
# hex value for register: guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4
# Note: FS is FullSpeed, HS is HighSpeed
-dwc2_reg_list = ['guid', 'gsnpsid', 'ghwcfg1', 'ghwcfg2', 'ghwcfg3', 'ghwcfg4']
+dwc2_reg_list = ['GUID', 'GSNPSID', 'GHWCFG1', 'GHWCFG2', 'GHWCFG3', 'GHWCFG4']
dwc2_reg_value = {
'BCM2711 (Pi4)': [0x2708A000, 0x4F54280A, 0, 0x228DDD50, 0xFF000E8, 0x1FF00020],
- 'EFM32GG FS': [0, 0x4F54330A, 0, 0x228F5910, 0x1F204E8, 0x1BF08030],
- 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0xC804B5, 0xD3F0A030],
+ 'EFM32GG': [0, 0x4F54330A, 0, 0x228F5910, 0x01F204E8, 0x1BF08030],
+ 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0x0C804B5, 0xD3F0A030],
'ESP32-P4': [0, 0x4F54400A, 0, 0x215FFFD0, 0x03805EB5, 0xDFF1A030],
- 'STM32F 407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030],
- 'STM32F 407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030],
- 'STM32F 412/767 FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030],
- 'STM32F723 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x200D1E8, 0x17F08030],
- 'STM32F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x3EED2E8, 0x23F00030],
- 'STM32H743 HS': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x3B8D2E8, 0xE3F00030], # both HS cores
- 'STM32L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x200D1E8, 0x17F08030],
- 'STM32U5A5 HS': [0x5000, 0x4F54411A, 0, 0x228FE052, 0x03B882E8, 0xE2103E30],
- 'GD32VF103 FS': [0x1000, 0, 0, 0, 0, 0],
- 'XMC4500': [0xAEC000, 0x4F54292A, 0, 0x228F5930, 0x27A01E5, 0xDBF08030]
+ 'ST F207/F407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x020001E8, 0x0FF08030],
+ 'ST F407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x03F403E8, 0x17F00030],
+ 'ST F412/767 FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030],
+ 'ST F723/L4P5 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030],
+ 'ST F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x03EED2E8, 0x23F00030],
+ 'ST F769': [0x2100, 0x4F54320A, 0, 0x229FE190, 0x03EED2E8, 0x23F00030],
+ 'ST H743/H750': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x03B8D2E8, 0xE3F00030],
+ 'ST L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030],
+ 'ST U5A5 HS': [0x5000, 0x4F54411A, 0, 0x228FE052, 0x03B882E8, 0xE2103E30],
+ 'GD32VF103': [0x1000, 0, 0, 0, 0, 0],
+ 'XMC4500': [0xAEC000, 0x4F54292A, 0, 0x228F5930, 0x027A01E5, 0xDBF08030]
+
}
# Combine dwc2_info with dwc2_reg_list
# dwc2_info = {
# 'BCM2711 (Pi4)': {
-# 'guid': 0x2708A000,
-# 'gsnpsid': 0x4F54280A,
-# 'ghwcfg1': 0,
-# 'ghwcfg2': 0x228DDD50,
-# 'ghwcfg3': 0xFF000E8,
-# 'ghwcfg4': 0x1FF00020
+# 'GUID': 0x2708A000,
+# 'GSNPSID': 0x4F54280A,
+# 'GHWCFG1': 0,
+# 'GHWCFG2': 0x228DDD50,
+# 'GHWCFG3': 0xFF000E8,
+# 'GHWCFG4': 0x1FF00020
# },
dwc2_info = {key: {field: value for field, value in zip(dwc2_reg_list, values)} for key, values in dwc2_reg_value.items()}
@@ -40,14 +44,14 @@ class GHWCFG2(ctypes.LittleEndianStructure):
_fields_ = [
("op_mode", ctypes.c_uint32, 3),
("arch", ctypes.c_uint32, 2),
- ("point2point", ctypes.c_uint32, 1),
+ ("p2p (hub support)", ctypes.c_uint32, 1),
("hs_phy_type", ctypes.c_uint32, 2),
("fs_phy_type", ctypes.c_uint32, 2),
("num_dev_ep", ctypes.c_uint32, 4),
("num_host_ch", ctypes.c_uint32, 4),
("period_channel_support", ctypes.c_uint32, 1),
("enable_dynamic_fifo", ctypes.c_uint32, 1),
- ("mul_cpu_int", ctypes.c_uint32, 1),
+ ("mul_proc_intrpt", ctypes.c_uint32, 1),
("reserved21", ctypes.c_uint32, 1),
("nptx_q_depth", ctypes.c_uint32, 2),
("ptx_q_depth", ctypes.c_uint32, 2),
@@ -99,63 +103,84 @@ class GHWCFG4(ctypes.LittleEndianStructure):
("dma_desc_dynamic", ctypes.c_uint32, 1)
]
+# mapping for specific fields in GHWCFG2
+GHWCFG2_field = {
+ 'op_mode': {
+ 0: "HNP SRP",
+ 1: "SRP",
+ 2: "noHNP noSRP",
+ 3: "SRP Device",
+ 4: "noOTG Device",
+ 5: "SRP Host",
+ 6: "noOTG Host"
+ },
+ 'arch': {
+ 0: "Slave only",
+ 1: "DMA external",
+ 2: "DMA internal"
+ },
+ 'hs_phy_type': {
+ 0: "n/a",
+ 1: "UTMI+",
+ 2: "ULPI",
+ 3: "UTMI+/ULPI"
+ },
+ 'fs_phy_type': {
+ 0: "n/a",
+ 1: "Dedicated",
+ 2: "Shared UTMI+",
+ 3: "Shared ULPI"
+ }
+}
-def cli():
- pass
-
-
[email protected]('mcus', nargs=-1)
[email protected]('-a', '--all', is_flag=True, help='Print all bit-field values')
-def info(mcus, all):
- """Print DWC2 register values for given MCU(s)"""
- if len(mcus) == 0:
- mcus = dwc2_info
+# mapping for specific fields in GHWCFG4
+GHWCFG4_field = {
+ 'phy_data_width': {
+ 0: "8 bit",
+ 1: "16 bit",
+ 2: "8/16 bit",
+ 3: "Reserved"
+ },
+ }
- for mcu in mcus:
- for entry in dwc2_info:
- if mcu.lower() in entry.lower():
- print(f"## {entry}")
- for r_name, r_value in dwc2_info[entry].items():
- print(f"{r_name} = 0x{r_value:08X}")
- # Print bit-field values
- if all and r_name.upper() in globals():
- class_name = globals()[r_name.upper()]
- ghwcfg = class_name.from_buffer_copy(r_value.to_bytes(4, byteorder='little'))
- for field_name, field_type, _ in class_name._fields_:
- print(f" {field_name} = {getattr(ghwcfg, field_name)}")
+def main():
+ """Render dwc2_info to Markdown table"""
+ parser = argparse.ArgumentParser()
+ args = parser.parse_args()
-def render_md():
- """Render dwc2_info to Markdown table"""
# Create an empty list to hold the dictionaries
- dwc2_info_list = []
+ md_table = []
# Iterate over the dwc2_info dictionary and extract fields
for device, reg_values in dwc2_info.items():
- entry_dict = {"Device": device}
+ md_item = {"Device": device}
for r_name, r_value in reg_values.items():
- entry_dict[r_name] = f"0x{r_value:08X}"
+ md_item[r_name] = f"0x{r_value:08X}"
- if r_name == 'gsnpsid':
+ if r_name == 'GSNPSID':
# Get dwc2 specs version
major = ((r_value >> 8) >> 4) & 0x0F
minor = (r_value >> 4) & 0xFF
patch = chr((r_value & 0x0F) + ord('a') - 0xA)
- entry_dict[f' - specs version'] = f"{major:X}.{minor:02X}{patch}"
- elif r_name.upper() in globals():
+ md_item[f' - specs version'] = f"{major:X}.{minor:02X}{patch}"
+ elif r_name in globals():
# Get bit-field values which exist as ctypes structures
- class_name = globals()[r_name.upper()]
- ghwcfg = class_name.from_buffer_copy(r_value.to_bytes(4, byteorder='little'))
- for field_name, field_type, _ in class_name._fields_:
- entry_dict[f' - {field_name}'] = getattr(ghwcfg, field_name)
+ class_hdl = globals()[r_name]
+ ghwcfg = class_hdl.from_buffer_copy(r_value.to_bytes(4, byteorder='little'))
+ for field_name, field_type, _ in class_hdl._fields_:
+ field_value = getattr(ghwcfg, field_name)
+ if class_hdl == GHWCFG2 and field_name in GHWCFG2_field:
+ field_value = GHWCFG2_field[field_name].get(field_value, f"Unknown ({field_value})")
+ if class_hdl == GHWCFG4 and field_name in GHWCFG4_field:
+ field_value = GHWCFG4_field[field_name].get(field_value, f"Unknown ({field_value})")
+
+ md_item[f' - {field_name}'] = field_value
- dwc2_info_list.append(entry_dict)
+ md_table.append(md_item)
# Create a Pandas DataFrame from the list of dictionaries
- df = pd.DataFrame(dwc2_info_list).set_index('Device')
+ df = pd.DataFrame(md_table).set_index('Device')
# Transpose the DataFrame to switch rows and columns
df = df.T
@@ -168,4 +193,4 @@ def render_md():
if __name__ == '__main__':
- cli()
+ main()
diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h
index ac88dd24d..cf05bbfec 100644
--- a/src/portable/synopsys/dwc2/dwc2_type.h
+++ b/src/portable/synopsys/dwc2/dwc2_type.h
@@ -250,7 +250,7 @@ typedef struct TU_ATTR_PACKED {
uint32_t num_host_ch : 4; // 14..17 Number of host channel (excluding control)
uint32_t period_channel_support : 1; // 18 Support Periodic OUT Host Channel
uint32_t enable_dynamic_fifo : 1; // 19 Dynamic FIFO Sizing Enabled
- uint32_t mul_cpu_int : 1; // 20 Multi-Processor Interrupt Enabled
+ uint32_t mul_proc_intrpt : 1; // 20 Multi-Processor Interrupt enabled (OTG_MULTI_PROC_INTRPT)
uint32_t reserved21 : 1; // 21 reserved
uint32_t nptx_q_depth : 2; // 22..23 Non-periodic request queue depth: 0 = 2. 1 = 4, 2 = 8
uint32_t ptx_q_depth : 2; // 24..25 Host periodic request queue depth: 0 = 2. 1 = 4, 2 = 8
@@ -336,6 +336,32 @@ typedef struct {
uint32_t reserved18[2]; // B18..B1C
} dwc2_epout_t;
+typedef struct {
+ union {
+ volatile uint32_t diepctl;
+ volatile uint32_t doepctl;
+ volatile uint32_t ctl;
+ };
+ uint32_t rsv04;
+ union {
+ volatile uint32_t diepint;
+ volatile uint32_t doepint;
+ };
+ uint32_t rsv0c;
+ union {
+ volatile uint32_t dieptsiz;
+ volatile uint32_t doeptsiz;
+ };
+ union {
+ volatile uint32_t diepdma;
+ volatile uint32_t doepdma;
+ };
+ volatile uint32_t dtxfsts;
+ uint32_t rsv1c;
+}dwc2_dep_t;
+
+TU_VERIFY_STATIC(sizeof(dwc2_dep_t) == 0x20, "incorrect size");
+
//--------------------------------------------------------------------
// CSR Register Map
//--------------------------------------------------------------------
@@ -418,16 +444,24 @@ typedef struct {
volatile uint32_t dvbuspulse; // 82C Device VBUS Pulsing Time
volatile uint32_t dthrctl; // 830 Device threshold Control
volatile uint32_t diepempmsk; // 834 Device IN Endpoint FIFO Empty Interrupt Mask
+
+ // Device Each Endpoint (IN/OUT) Interrupt/Mask for generating dedicated EP interrupt line
+ // require OTG_MULTI_PROC_INTRPT=1
volatile uint32_t deachint; // 838 Device Each Endpoint Interrupt
- volatile uint32_t deachmsk; // 83C Device Each Endpoint Interrupt msk
+ volatile uint32_t deachmsk; // 83C Device Each Endpoint Interrupt mask
volatile uint32_t diepeachmsk[16]; // 840..87C Device Each IN Endpoint mask
volatile uint32_t doepeachmsk[16]; // 880..8BF Device Each OUT Endpoint mask
uint32_t reserved8c0[16]; // 8C0..8FF
//------------- Device Endpoint -------------//
- dwc2_epin_t epin[16]; // 900..AFF IN Endpoints
- dwc2_epout_t epout[16]; // B00..CFF OUT Endpoints
- uint32_t reservedd00[64]; // D00..DFF
+ union {
+ dwc2_dep_t ep[2][16]; // 0: IN, 1 OUT
+ struct {
+ dwc2_epin_t epin[16]; // 900..AFF IN Endpoints
+ dwc2_epout_t epout[16]; // B00..CFF OUT Endpoints
+ };
+ };
+ uint32_t reservedd00[64]; // D00..DFF
//------------- Power Clock -------------//
volatile uint32_t pcgctl; // E00 Power and Clock Gating Control
@@ -1094,6 +1128,8 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size");
#define DAINTMSK_OEPM_Msk (0xFFFFUL << DAINTMSK_OEPM_Pos) // 0xFFFF0000
#define DAINTMSK_OEPM DAINTMSK_OEPM_Msk // OUT EP interrupt mask bits
+#define DAINT_SHIFT(_dir) ((_dir == TUSB_DIR_IN) ? 0 : 16)
+
#if 0
/******************** Bit definition for OTG register ********************/
#define CHNUM_Pos (0U)
@@ -1803,6 +1839,45 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size");
#define DIEPTXF_INEPTXFD_Msk (0xFFFFUL << DIEPTXF_INEPTXFD_Pos) // 0xFFFF0000
#define DIEPTXF_INEPTXFD DIEPTXF_INEPTXFD_Msk // IN endpoint TxFIFO depth
+
+/******************** Bit definition for Common EPCTL register ********************/
+#define EPCTL_MPSIZ_Pos (0U)
+#define EPCTL_MPSIZ_Msk (0x7FFUL << EPCTL_MPSIZ_Pos) // 0x000007FF
+#define EPCTL_MPSIZ EPCTL_MPSIZ_Msk // Maximum packet size //Bit 1
+#define EPCTL_USBAEP_Pos (15U)
+#define EPCTL_USBAEP_Msk (0x1UL << EPCTL_USBAEP_Pos) // 0x00008000
+#define EPCTL_USBAEP EPCTL_USBAEP_Msk // USB active endpoint
+#define EPCTL_NAKSTS_Pos (17U)
+#define EPCTL_NAKSTS_Msk (0x1UL << EPCTL_NAKSTS_Pos) // 0x00020000
+#define EPCTL_NAKSTS EPCTL_NAKSTS_Msk // NAK status
+#define EPCTL_EPTYP_Pos (18U)
+#define EPCTL_EPTYP_Msk (0x3UL << EPCTL_EPTYP_Pos) // 0x000C0000
+#define EPCTL_EPTYP EPCTL_EPTYP_Msk // Endpoint type
+#define EPCTL_EPTYP_0 (0x1UL << EPCTL_EPTYP_Pos) // 0x00040000
+#define EPCTL_EPTYP_1 (0x2UL << EPCTL_EPTYP_Pos) // 0x00080000
+#define EPCTL_SNPM EPCTL_SNPM_Msk // Snoop mode
+#define EPCTL_STALL_Pos (21U)
+#define EPCTL_STALL_Msk (0x1UL << EPCTL_STALL_Pos) // 0x00200000
+#define EPCTL_STALL EPCTL_STALL_Msk // STALL handshake
+#define EPCTL_CNAK_Pos (26U)
+#define EPCTL_CNAK_Msk (0x1UL << EPCTL_CNAK_Pos) // 0x04000000
+#define EPCTL_CNAK EPCTL_CNAK_Msk // Clear NAK
+#define EPCTL_SNAK_Pos (27U)
+#define EPCTL_SNAK_Msk (0x1UL << EPCTL_SNAK_Pos) // 0x08000000
+#define EPCTL_SNAK EPCTL_SNAK_Msk // Set NAK
+#define EPCTL_SD0PID_SEVNFRM_Pos (28U)
+#define EPCTL_SD0PID_SEVNFRM_Msk (0x1UL << EPCTL_SD0PID_SEVNFRM_Pos) // 0x10000000
+#define EPCTL_SD0PID_SEVNFRM EPCTL_SD0PID_SEVNFRM_Msk // Set DATA0 PID
+#define EPCTL_SODDFRM_Pos (29U)
+#define EPCTL_SODDFRM_Msk (0x1UL << EPCTL_SODDFRM_Pos) // 0x20000000
+#define EPCTL_SODDFRM EPCTL_SODDFRM_Msk // Set odd frame
+#define EPCTL_EPDIS_Pos (30U)
+#define EPCTL_EPDIS_Msk (0x1UL << EPCTL_EPDIS_Pos) // 0x40000000
+#define EPCTL_EPDIS EPCTL_EPDIS_Msk // Endpoint disable
+#define EPCTL_EPENA_Pos (31U)
+#define EPCTL_EPENA_Msk (0x1UL << EPCTL_EPENA_Pos) // 0x80000000
+#define EPCTL_EPENA EPCTL_EPENA_Msk // Endpoint enable
+
/******************** Bit definition for DOEPCTL register ********************/
#define DOEPCTL_MPSIZ_Pos (0U)
#define DOEPCTL_MPSIZ_Msk (0x7FFUL << DOEPCTL_MPSIZ_Pos) // 0x000007FF
@@ -1853,15 +1928,19 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size");
#define DOEPINT_AHBERR_Pos (2U)
#define DOEPINT_AHBERR_Msk (0x1UL << DOEPINT_AHBERR_Pos) // 0x00000004
#define DOEPINT_AHBERR DOEPINT_AHBERR_Msk // AHB Error (AHBErr) during an OUT transaction
-#define DOEPINT_STUP_Pos (3U)
-#define DOEPINT_STUP_Msk (0x1UL << DOEPINT_STUP_Pos) // 0x00000008
-#define DOEPINT_STUP DOEPINT_STUP_Msk // SETUP phase done
+
+#define DOEPINT_SETUP_Pos (3U)
+#define DOEPINT_SETUP_Msk (0x1UL << DOEPINT_SETUP_Pos) // 0x00000008
+#define DOEPINT_SETUP DOEPINT_SETUP_Msk // SETUP phase done
+
#define DOEPINT_OTEPDIS_Pos (4U)
#define DOEPINT_OTEPDIS_Msk (0x1UL << DOEPINT_OTEPDIS_Pos) // 0x00000010
#define DOEPINT_OTEPDIS DOEPINT_OTEPDIS_Msk // OUT token received when endpoint disabled
-#define DOEPINT_OTEPSPR_Pos (5U)
-#define DOEPINT_OTEPSPR_Msk (0x1UL << DOEPINT_OTEPSPR_Pos) // 0x00000020
-#define DOEPINT_OTEPSPR DOEPINT_OTEPSPR_Msk // Status Phase Received For Control Write
+
+#define DOEPINT_STSPHSRX_Pos (5U)
+#define DOEPINT_STSPHSRX_Msk (0x1UL << DOEPINT_STSPHSRX_Pos) // 0x00000020
+#define DOEPINT_STSPHSRX DOEPINT_STSPHSRX_Msk // Status Phase Received For Control Write
+
#define DOEPINT_B2BSTUP_Pos (6U)
#define DOEPINT_B2BSTUP_Msk (0x1UL << DOEPINT_B2BSTUP_Pos) // 0x00000040
#define DOEPINT_B2BSTUP DOEPINT_B2BSTUP_Msk // Back-to-back SETUP packets received
@@ -1874,6 +1953,7 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size");
#define DOEPINT_NYET_Pos (14U)
#define DOEPINT_NYET_Msk (0x1UL << DOEPINT_NYET_Pos) // 0x00004000
#define DOEPINT_NYET DOEPINT_NYET_Msk // NYET interrupt
+
#define DOEPINT_STPKTRX_Pos (15U)
#define DOEPINT_STPKTRX_Msk (0x1UL << DOEPINT_STPKTRX_Pos) // 0x00008000
#define DOEPINT_STPKTRX DOEPINT_STPKTRX_Msk // Setup Packet Received