Skip to content

fix(bldc_haptics): clean reconnect — web RX-drain + clear TX backlog on auto-pause - #775

Merged
finger563 merged 2 commits into
mainfrom
fix/haptics-reconnect-robustness
Sep 5, 2026
Merged

fix(bldc_haptics): clean reconnect — web RX-drain + clear TX backlog on auto-pause#775
finger563 merged 2 commits into
mainfrom
fix/haptics-reconnect-robustness

Conversation

@finger563

Copy link
Copy Markdown
Contributor

Two haptics reconnect-robustness fixes that landed after #773 was merged (the RX-drain missed the squash-merge, and the device-side clear needed #774's API which is now on main).

Web: drain stale RX before the connect handshake

On an abrupt tab close the device's vendor TX FIFO isn't cleared, so a reconnecting page could read leftover telemetry/reply frames and mis-handle them (the reported "first Connect returns immediately, second works"). initializeDevice() now flushes the pipe before the handshake: set a draining flag, reset the parser, let the RX pump discard whatever arrives for ~150 ms, then start GET_INFO on a clean stream. dispatchFrame drops frames while draining.

Device: clear the vendor TX backlog on telemetry auto-pause

When the telemetry stall guard (from #773) fires — host stopped draining — the example now also calls usb.vendor_write_clear() (added in #774) to drop the queued-but-unsent telemetry. A tab close doesn't unmount the device, so the FIFO isn't cleared for us; clearing it here means a reconnecting host reads a clean stream instead of a stale backlog.

Together with #773's auto-pause + visibility pause and #774's tud_umount_cb clear, this covers the tab-close, backgrounded-tab, and cable-pull cases. cppcheck-clean; the web console passes a JS parse check.

🤖 Generated with Claude Code

finger563 and others added 2 commits September 4, 2026 23:29
Re-applies the RX-drain that missed the #773 squash-merge. On an abrupt tab close
the device's vendor TX FIFO is not cleared, so a reconnecting page could read
leftover telemetry / reply frames and mis-handle them ("first Connect returns
immediately, second works"). initializeDevice() now flushes the pipe (set a
`draining` flag, reset the parser, let the RX pump discard for ~150 ms) before the
GET_INFO handshake; dispatchFrame drops frames while draining.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…uses

When the telemetry stall guard fires (host stopped draining), also drop the
queued-but-unsent telemetry via usb.vendor_write_clear() (added in #774). An
abrupt tab close does not unmount the device, so the FIFO is not cleared for us;
clearing it here means a reconnecting host reads a clean stream instead of a
stale backlog it might mis-parse as the reply to its first command.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 5, 2026 04:30
@finger563
finger563 merged commit 444fa1b into main Sep 5, 2026
148 of 155 checks passed
@finger563
finger563 deleted the fix/haptics-reconnect-robustness branch September 5, 2026 04:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Pull request overview

Improves reconnect robustness for the BLDC haptics example by preventing stale USB vendor frames (left queued across abrupt tab closes) from being misinterpreted on reconnect.

Changes:

  • Web: add a brief pre-handshake RX drain that discards stale frames and resets the stream parser.
  • Device: clear queued vendor TX telemetry when the telemetry stall guard auto-pauses streaming.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
components/bldc_haptics/example/webapp/index.html Adds a draining mode to drop pre-handshake RX frames and resets the parser before starting initialization.
components/bldc_haptics/example/main/bldc_haptics_example.cpp Clears the vendor TX backlog when telemetry auto-pauses due to host not draining.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 648 to +651
function dispatchFrame(frame) {
// Discard everything during the brief pre-handshake RX drain: these are
// stale frames from a previous session, not replies to anything we sent.
if (draining) return;
Comment on lines 800 to +810
async function initializeDevice() {
try {
// Flush any stale frames the device queued for a previous session (its TX
// FIFO is not cleared on an abrupt tab close) before we send anything, so
// an old telemetry / reply frame can't be mis-read as the response to our
// first command. RX keeps running; dispatchFrame drops frames while
// draining is set.
draining = true;
parser.reset();
await new Promise((resolve) => setTimeout(resolve, 150));
draining = false;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants