summaryrefslogtreecommitdiff
path: root/src/class/usbtmc/usbtmc_device.c
diff options
context:
space:
mode:
authorHiFiPHile <[email protected]>2026-09-04 11:18:06 +0200
committerHiFiPHile <[email protected]>2026-09-04 11:18:06 +0200
commit3976e532800cfa065b4fbf3f32b01b4a68e4d7f4 (patch)
tree65a2d91d0a3ea8abefd78c83e2974da3b5971b32 /src/class/usbtmc/usbtmc_device.c
parentcd9bbed39f5851d5e4dc64271f18b8db777acb53 (diff)
parent29851564af08cb4909175315d20c71f5eca13040 (diff)
Merge remote-tracking branch 'origin/master' into codex/class-reference-docs
Diffstat (limited to 'src/class/usbtmc/usbtmc_device.c')
-rw-r--r--src/class/usbtmc/usbtmc_device.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c
index 07190d89f..0e9978a81 100644
--- a/src/class/usbtmc/usbtmc_device.c
+++ b/src/class/usbtmc/usbtmc_device.c
@@ -497,9 +497,24 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint
#if (CFG_TUD_USBTMC_ENABLE_488)
case USBTMC_MSGID_USB488_TRIGGER:
- // Spec says we halt the EP if we didn't declare we support it.
- TU_VERIFY(usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger);
- TU_VERIFY(tud_usbtmc_msg_trigger_cb(msg));
+ // Unlike the messages above, TRIGGER is complete on arrival and has no response, so nothing else
+ // will move us out of STATE_IDLE. Do it here, otherwise the tud_usbtmc_start_bus_read() below (and
+ // any call the application makes from its callback) is a no-op and the bulk-OUT endpoint is left
+ // un-armed, silently timing out every subsequent host transfer.
+ TU_VERIFY(atomicChangeState(STATE_IDLE, STATE_NAK));
+
+ // Spec says we halt the EP if we didn't declare we support it; do the same when the application
+ // rejects the trigger. The callback result must not be wrapped in TU_VERIFY() here: returning
+ // early would skip both the stall and the re-arm below.
+ if (!usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger ||
+ !tud_usbtmc_msg_trigger_cb(msg)) {
+ usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out);
+ return false;
+ }
+ // Result deliberately ignored: false here means the endpoint is already armed - either the
+ // application re-armed it from its callback, or a transfer is still queued - not that arming
+ // failed. Stalling on it would halt a healthy endpoint.
+ tud_usbtmc_start_bus_read();
break;
#endif