Repository navigation
Conversation
Pure codecs for the UtechSmart Venus MMO wired mouse: F2/F3 feature-report framing, reply validation, DPI (x1/x2/x3 range bands), button actions including modifier combos, status decoding and minimal write plans. Decoded against a memory dump and vendor-UI readings from real hardware; F1 commit and F5 polling commands remain unverified.
Registers the 04d9:fc55 config collection (0xFFA0:0x01) as a UtechSmart client, disjoint from the Redragon Holtek mice by product id. Reads the active profile's DPI stages, polling rate and 20 button slots, and writes DPI, polling and button mappings (including modifier combos) through minimal F3 frames verified by readback. F1 commit frames stay disabled and the F5 polling frame stays behind a constant until hardware testing decides both.
F5 is a 0/1 session bracket on the Venus (04d9:fc55), not a polling divisor. Sending F5 with the divisor hung the mouse at 125 Hz. Polling now writes the full two-byte word at 0x32+2p inside F5(0) / F3 / F1 02 08 / F5(1), with the delays used by the vendor software, then reads it back. The sequence was verified on hardware (stored word 04->02->04, no other byte changed). Unchanged rates send nothing; failures attempt one F5(1) close and keep the original error. Button and DPI writes are unchanged. Effective report rate is not measured.
Require both feature reports 2 and 3 on the same vendor collection, since long reads use report 3. Report valuesVerified only when every enabled DPI stage of the active profile decodes from a known code and range, and expose an additive exact flag on decoded stages. Update the driver notes with what was exercised on the owner's unit; effective polling rate and polling persistence across a replug remain unmeasured.
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a codec (
src/utechsmart/) and a WebHID driver (src/drivers/utechsmart/) for the wired UtechSmart Venus MMO gaming mouse, USB04d9:fc55(Holtek controller), registered in the driver registry and vendor filters.Supported settings:
Ctrl+1)Not supported: LEDs, macros, and switching the active profile.
Device and connection
04d9:fc550xFFA0, usage0x01Protocol
Frames are
[report 02, command, address lo, address hi, length, 0, 0, 0, data…].F2reads memory. Replies are[02 08 addrLo 60+addrHi len 00 FA FA data…].F3writes memory. Button and DPI writes take effect immediately, with no commit command.F5 00→F3with the 2-byte polling word →F1 02 08→F5 01, with 100 ms pauses.F5is a 0/1 bracket, not a rate divisor.Memory layout (5 profiles):
0x002C0x32 + 2·profile, value1000 / Hz0040/0100/01B0/0260/0310: header[count, 0, current stage, 0], then 6-byte stages[01, code, range, 0, 0, 0]. Codes use the Redragon M724 table, range 0/1/4 = ×1/×2/×3.0080/0140/01F0/02A0/0350: count0x14, then 4-byte slots. A key is90 00 usage 00; a key with modifiers is8F mod usage 00.The driver reads before each settings change, preserves unknown bytes, and verifies the result by readback. Button and DPI updates use minimal changed spans; polling writes the complete two-byte word, preserving its unknown second byte. It refuses to remove the last Left click.
Review scope
This draft is one device-focused change: 1,319 additions and 4 deletions across 11 files, including codec and fake-device tests. The existing commits are kept together so the corrected polling transaction and verification safeguards are present in the reviewed result. LEDs, artwork, macros and profile switching remain separate follow-ups.
Evidence
F5meaning. No vendor code or binaries are included.F5as a polling divisor did not match the hardware and hung the mouse at 125 Hz, so it is not used.Tested on hardware
All on the owner's wired unit, through the OpenMouse UI with this package installed locally:
Ctrl+1→1: the new key was typed immediatelyUnknowns
F1 02 08is taken from the vendor software's apply sequence, not fully understood.0x0448 + 8·profile) were identified but are not implemented.Checks
npm run check(mouse-protocol): pass, 3104/3104 tests, pack dry-run OKnpm run checkwith the local package: build passes; the JS bundle-size gate is exceeded by 2,564 bytes (3,952,564 / 3,950,000). OpenMouse main passes with 8,685 bytes of headroom, and its budget comment notes it "leaves room for one more release", which provides context for discussing a budget adjustment with maintainers; no adjustment has been approved. The local install also updated unrelated dependencies, so this is not an isolated driver-only size measurement. No OpenMouse change is part of this PR. OpenMouse tests with the local package: 658 tests, 652 pass, 0 fail, 6 cancelled. The same 6 cancellations (test/discord-card.test.ts,test/feedback-security.test.ts) occur with the published 0.59.0 package: their hanging-fetch mocks wait onAbortSignal.timeout, which does not keep Node's event loop alive. Unrelated to this driver.No matching OpenMouse PR is required: the existing UI works with this driver. The generic profile selector is shown although this driver has no
setProfile; that can be raised separately.