mirror of
https://github.com/safijari/openpuck.git
synced 2026-11-03 22:30:22 +00:00
Labels
No labels
pull-request
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
safijari/openpuck#238
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/safijari/openpuck/pull/199
Author: @safijari
Created: 7/29/2026
Status: ✅ Merged
Merged: 8/2/2026
Merged by: @safijari
Base:
main← Head:fix-haptic-pulse-0x81📝 Commits (1)
84ebce8Relay OUTPUT report 0x81 HAPTIC_PULSE (fixes #163, #166)📊 Changes
6 files changed (+68 additions, -17 deletions)
View changed files
📝
OpenPuck/puck_hid.cpp(+26 -13)📝
OpenPuck/serial_console.cpp(+3 -2)📝
ReversePuckFirmware/ctrl_link.cpp(+1 -1)📝
ReversePuckFirmware/deck_input.cpp(+9 -0)📝
ReversePuckFirmware/deck_input.h(+2 -1)📝
docs/PROTOCOL.md(+27 -0)📄 Description
Both issues are one bug: OpenPuck was discarding Steam's haptic pulse reports.
Root cause
Two different Valve ID spaces both use
0x81:0x81means0x01(command channel)ID_CLEAR_DIGITAL_MAPPINGS— the connect-time amp-clicker, correctly dropped in Steam modeID_OUT_REPORT_HAPTIC_PULSE—MsgHapticPulse [side][on_us u16][off_us u16][repeat_count u16]668bda6("Support latest beta, fix buzzing, fix stability problems", #102) extended the feature-channel drop to the OUTPUT report as well, describing it as "Steam's haptic-reset action, a 7-byte report id 0x81 with payloads00../01..". Those leading00/01bytes areside = left/right pad— that was Steam firing legitimate click pulses at the pads, mistaken for spurious clicks.So every pulse-based cue disappeared: trackpad "Regular Press" click (#166), trigger full-pull click (#163), GripSense. "Soft Press" kept working because it rides
0x82 ID_OUT_REPORT_HAPTIC_COMMAND, which is still relayed — exactly the symptom split reported in #166. Timeline matches: the drop landed 2026-07-03, the issues were filed Jul 10 and Jul 13.Why the ID mapping is certain
Ground truth is SDL
src/joystick/hidapi/steam/controller_structs.h(ValveTritonOutReportMessageIDs), whose payload sizes match our cloned report descriptor byte-for-byte:0x80rumble(9) ·0x81pulse(7) ·0x82command(3) ·0x83lfo_tone(9) ·0x84log_sweep(8) ·0x85script(3)SDL also notes "Triton and derivatives utilize output reports for haptic commands", and the controller's feature-command table has no
0x8F/0xEA(legacy pulse) handler — so every Steam haptic must arrive in0x80–0x86, and0x81was the only one being dropped.Changes
OpenPuck/puck_hid.cpp— relay OUTPUT0x81again;g_drop81applies only to the feature-channel command it was written for. Both ID spaces documented at the relay gate so they can't be conflated again.OpenPuck/serial_console.cpp—S81help text says feature-only.docs/PROTOCOL.md— two-ID-space table with payload layouts and the0x81trap.ReversePuckFirmware/*— mirror-image bug in the Deck forwarder: it rendered0x82/0x8Fbut not0x81(and0x8Fis a feature-channel id Triton doesn't implement), so it now buzzes on real pulses.Pulses carry their own
repeat_count, so unlike0x80rumble or the0x82on/off pair there's no latch to strand and no stop frame that can be lost — no stuck-rumble risk from re-enabling this. The feature-channel drop is untouched, so the mechanism blamed for the buzz in #102 stays suppressed.Testing
Both firmwares compile clean (
make build187268 B flash / 42524 B RAM;make reversepuckOK). Not hardware-verified — confirmation is code + protocol-level only.On-hardware notes:
S81is no longer the lever for OUTPUT-side clicking; those pulses are now unconditional.0x87SET_SETTINGS landing whitelist inrfConnFlushRelaydiscarding Steam's haptic config — consoleL87lands all0x87verbatim for an A/B. Shouldn't be needed given Steam demonstrably sends the pulses we were dropping.🤖 Generated with Claude Code
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.