Skip to content

CouchTurtle/sc2-research

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sc2-research

Notes and tools for the Steam Controller 2 (Triton): HID input layout, firmware update protocol, feature-report routing, static analysis of the firmware blobs, and a generated per-build firmware change log.

Status: a host-side reference and learning artifact, lightly maintained. For actively-developed SC2 work (open custom firmware, a DIY replacement puck, Linux drivers) see the Related SC2 projects list under Background. Corrections here are still welcome via issues / PRs.

Most of this comes from extracting hardwareupdater.x86_64 (the PyInstaller bundle that ships with the Steam client) and verifying against an actual SC2 + Puck on a Steam Deck (SteamOS) with controller firmware bcdDevice 0.02. Hobby project with heavy AI assistance (see Disclaimer).

Covers: SC2 (USB 28DE:1302/1303), the Proteus puck (28DE:1304), and the parallel Nereid dongle (28DE:1305). Nereid is plausibly the Steam-Machine-integrated dongle, based on SDL3 commit timing and the absence of a Nereid bootloader path in Steam's user-facing updater.

Documentation

Path Contents
docs/FIRMWARE_PROTOCOL.md Update protocol: HDLC framing, message IDs, firmware-file format, bootloader-mode switching, live feature-report attribute queries, ARM Cortex-M static analysis.
docs/METHODOLOGY.md RE notes: PyInstaller-bundle extraction, bytecode disassembly without a decompiler, the InHand-flag debunking, capture-timing pitfalls, SteamOS ACL quirks, multi-device fr_id routing.
docs/CONTROLLER_CAPABILITIES.md Hardware notes: chip identification, USB topology, haptic actuator sides, components found via firmware-string analysis.
docs/HID_REPORT_FORMAT.md The 54-byte Report-0x42 layout (from SDL3, verified against ~9k frames), puck USB topology, Lizard-mode timing, sub-reports 0x43 (battery) and 0x7b (the one Triton input report ID not in SDL3), SteamOS access notes.
docs/SDL3_REFERENCE.md Cross-reference of what SDL3's open-source code says about Triton: report IDs, output haptic message types, settings, audio cues, charge states, IMU axis swizzle and scaling, trackpad transforms, timing constants.
docs/HAPTICS.md Cross-reference of the haptic + audio output reports (0x800x89), reverse-engineered by iczero: actuator sides, script IDs, audio-stream formats, the 0x44 feedback channel.
docs/CHANGELOG.md Per-build firmware change log: a binary diff of every version in the Ibex-Firmware archive, showing the size and which strings changed between builds. Generated by tools/fw_changelog.py.

Tools

Python 3.10+, stdlib only. Run as the deck user on SteamOS (not sudo: root is blocked by the hidraw ACL).

Firmware analysis & extraction:

Tool What it does
tools/extract_pyinst.py Minimal PyInstaller bundle extractor: MEI cookie + TOC walker.
tools/walk_pyc.py Walks marshaled Python code objects, lists nested functions + constants.
tools/analyze_fw.py Parses ARM Cortex-M firmware blobs (header, vector table, IRQ handlers, strings).
tools/attr_query.py Sends HID Feature-Reports via ioctl to query device attributes.
tools/fw_changelog.py Diffs two firmware versions (or sweeps the whole archive) into a plain "what changed" report: size, and which strings appeared or vanished. Pulls the blobs from the Ibex-Firmware archive, so no controller is needed.

Live capture & observation:

Tool What it does
tools/live_monitor.py Streams /dev/hidraw9, prints button transitions + analog deflection.
tools/one_capture.py NAME [NAME...] Captures 3 s of hidraw9 traffic per named action; diffs against a baseline.
tools/event_logger.py [seconds] Parallel logger across hidraw9–13; report-ID histogram per interface.

Quick start

git clone <this-repo>
cd sc2-research

# Probe puck + controller via HID Feature-Reports
python3 tools/attr_query.py

# Extract Steam's firmware updater
python3 tools/extract_pyinst.py
python3 tools/walk_pyc.py

# Analyse a firmware blob
python3 tools/analyze_fw.py ~/.local/share/Steam/bin/hardwareupdater/IBEX_FW_69FA5889.fw

Background

Valve's own open releases this work builds on:

Related SC2 projects (several are further along than this repo, and are cross-checked throughout the docs):

  • mwdmwd/sc26reopen custom firmware (Zephyr) for the controller, flashed over SWD and already playable. The authoritative source for how the hardware works; independently confirms the nRF52833 SoC, the 0x42 layout, the firmware-file header, the feature opcodes and the I2C map used here.
  • iczero/steam-controller-stuff — Wireshark dissector + audio player; the reference for the haptic/audio output protocol (docs/HAPTICS.md).
  • safijari/openpuck — firmware for an ~$8 nRF52840 Pro Micro that replaces the puck and emulates Xbox/Switch/PS pads; its docs/PROTOCOL.md covers the host↔puck and 2.4 GHz RF layers.
  • OpenSteamController/Ibex-Firmware — versioned archive of every .fw blob Valve ships (source of the reproducible firmware links below). Documents the 32-byte header (CRC32 at 0x08).
  • Use-without-Steam drivers: Rune580/sc-evdev (Linux evdev), njanke96/steam-controller-dsu (motion/DSU), among others.

Adjacent / historical:

  • SteamHapticsSinger — haptic MIDI player. "Note-On 0x83" = HAPTIC_LFO_TONE, "Note-Off 0x81" = HAPTIC_PULSE.
  • SteamlessController — Windows tool that disables Lizard mode and bridges Report 0x42 to a virtual Xbox 360 pad.
  • OpenSteamController (greggersaurus) — RE for the 2015 Steam Controller (LPC11U37F + nRF51822); architecturally unrelated to the SC2.

Hardware identification:

Codenames that were already public before this work:

License

MIT: see LICENSE. Some patterns credited inline to the BSD-3-Clause SteamHapticsSinger.

Disclaimer

Hobby project, done with heavy AI assistance (Claude) for hypothesis-testing, cross-referencing, and drafting. The hardware testing, firmware extraction, and packet captures were on my own Steam Deck (SteamOS) with an SC2 + Puck (USB bcdDevice 0.02). Cross-checked against SDL3 source where possible; I may have missed conventions someone with deeper RE background would catch. Corrections via issues / PRs welcome.

Baseline: the firmware blobs analysed here are IBEX_FW_69FA5889 + 69FE17FF (Triton) and PROTEUS_FW_69FA587F + 69FBD45D (Proteus), all from early May 2026. Both pairs are byte-identically mirrored in OpenSteamController/Ibex-Firmware, so anyone can reproduce the analysis without their own Steam install:

curl -O https://opensteamcontroller.github.io/Ibex-Firmware/Controller/IBEX_FW_69FE17FF.fw
curl -O https://opensteamcontroller.github.io/Ibex-Firmware/Puck/PROTEUS_FW_69FBD45D.fw
python3 tools/analyze_fw.py IBEX_FW_69FE17FF.fw

Valve has shipped further updates since (the June 2026 release added LED dimming in settings + trigger-deadzone tweaks). The protocol layer is expected to be stable across these; static-analysis offsets are tied to the specific FW versions above.

No proprietary code or firmware blobs are redistributed here. For the blobs see OpenSteamController/Ibex-Firmware. No affiliation with Valve.

About

Notes and Python tools for the Steam Controller 2 (Triton): HID reports, the firmware-update protocol, and firmware-blob analysis.

Topics

Resources

License

Stars

5 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages