From 57716cd0b45c2a8d124569748a59bd499bf80a60 Mon Sep 17 00:00:00 2001 From: RockyZeroFour Date: Tue, 3 Mar 2026 07:35:44 +0100 Subject: [PATCH] Fixes a bug where non-control endpoint might get incorrectly STALLed - An OUT transaction of a non control endpoint might get STALLed if started right after the host tried to send an OUT handshake on the control endpoint - Occurs if the host tries to send data to a non control endpoint if the OUT handshake of the data stage on the control endpoint was NAKed exactly once --- src/portable/synopsys/dwc2/dcd_dwc2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 70c8734399..c16a8e28d7 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -575,9 +575,15 @@ void dcd_init (uint8_t rhport) // Clear A override, force B Valid dwc2->gotgctl = (dwc2->gotgctl & ~GOTGCTL_AVALOEN) | GOTGCTL_BVALOEN | GOTGCTL_BVALOVAL; + // Don't handle a non-zero-length status OUT handshake on GD32F4 + // as due to a hardware bug the MCU can mistake a non control endpoint + // as the control endpoint and so incorrectly trigger a STALL for the + // first. +#if !TU_CHECK_MCU(OPT_MCU_GD32F4) // If USB host misbehaves during status portion of control xfer // (non zero-length packet), send STALL back and discard. dwc2->dcfg |= DCFG_NZLSOHSK; +#endif // Clear all interrupts dwc2->gintsts |= dwc2->gintsts;