summaryrefslogtreecommitdiff
path: root/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
diff options
context:
space:
mode:
authorHiFiPHile <[email protected]>2026-08-25 09:27:48 +0200
committerHiFiPHile <[email protected]>2026-08-25 09:27:48 +0200
commitdfac26a272fa7bbbca2050fbe9f1ca09008e548e (patch)
treeefbc53f8f2c1e5d9c7f38e5fef6d774a20053cec /src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
parente590b45fcf51f9ddace73178074e4fe6d691e319 (diff)
parent5c0e31cdabaf37f14e1f5e988a020abfc1000495 (diff)
Merge master updates into the UAC1 host branch
Bring the audio work onto the current host core and build files before applying the remaining review fixes. Signed-off-by: HiFiPHile <[email protected]>
Diffstat (limited to 'src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c')
-rw-r--r--src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
index aecd689b3..ba05818b6 100644
--- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
@@ -835,7 +835,17 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
ep_reg &= U_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir);
if (!ep_is_iso(ep_reg)) {
- ep_change_status(&ep_reg, dir, EP_STAT_NAK);
+ // Only knock a genuinely STALLED endpoint down to NAK (the class then re-arms it). If the
+ // endpoint is armed (VALID) - e.g. a clear-halt used purely to reset the data toggle, as in
+ // usbtest case 29 - leave STAT untouched so the in-flight transfer isn't disarmed with no
+ // completion, which would leak the usbd claim and starve the endpoint. Masking the STAT bits
+ // to 0 writes no toggle, so an armed/idle endpoint keeps its current status.
+ const uint8_t stat_pos = (uint8_t) (U_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0u : 8u));
+ if (((ep_reg >> stat_pos) & 0x3u) == EP_STAT_STALL) {
+ ep_change_status(&ep_reg, dir, EP_STAT_NAK);
+ } else {
+ ep_reg &= ~EP_STAT_MASK(dir);
+ }
}
ep_change_dtog(&ep_reg, dir, 0); // Reset to DATA0
ep_write(ep_idx, ep_reg, true);