diff options
| author | hathach <[email protected]> | 2026-06-17 16:27:03 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2026-06-18 15:56:23 +0700 |
| commit | 6d74543ce6b3d79c2ba24e11f23fccad52571464 (patch) | |
| tree | 182af4da33de7771851db81926b65fc639ae005c /src | |
| parent | de341b14abe3bc3e25962cbb26aa61bc0126adcf (diff) | |
dcd/stm32_fsdev: restore CH32 EP0 CONTROL type when stalling
The CH32 workaround only restored EP0 to CONTROL in edpt_xfer(). When
the stack rejects a control write with data (handle_ctr_setup having
already switched EP0 to BULK) it stalls EP0 via dcd_edpt_stall() without
ever calling dcd_edpt_xfer(), leaving EP0 typed BULK+STALL. As SETUP
recognition is tied to CONTROL-typed endpoints, the host's recovery
SETUP (which should auto-clear the stall) would be ignored, wedging EP0
until a bus reset.
Restore CONTROL for EP0 in the same exclusive write that sets the STALL
status. DFU download-in-wrong-state is a concrete trigger.
Co-Authored-By: Claude Fable 5 <[email protected]>
Diffstat (limited to 'src')
| -rw-r--r-- | src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 6279f8102..f5a8beb65 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -833,6 +833,14 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { ep_reg &= U_EPREG_MASK | EP_STAT_MASK(dir); ep_change_status(&ep_reg, dir, EP_STAT_STALL); +#if defined(TUP_USBIP_FSDEV_CH32) + // Stall ends the transfer without edpt_xfer() (the only other CONTROL restore); else a rejected + // control-write leaves EP0 typed BULK and the host's recovery SETUP is ignored until bus reset. + if (ep_num == 0u) { + ep_reg = (ep_reg & ~U_EP_T_FIELD) | U_EP_CONTROL; + } +#endif + ep_write(ep_idx, ep_reg, true); } |
