Skip to content

Add Lamzu Inca 8K under Lamzu's own vendor id 0x37b0 - #45

Draft
bpavlina wants to merge 1 commit into
OpenMouse-Project:mainfrom
bpavlina:feat/lamzu-inca-8k
Draft

Add Lamzu Inca 8K under Lamzu's own vendor id 0x37b0#45
bpavlina wants to merge 1 commit into
OpenMouse-Project:mainfrom
bpavlina:feat/lamzu-inca-8k

Conversation

@bpavlina

@bpavlina bpavlina commented Sep 4, 2026

Copy link
Copy Markdown

Model: Lamzu Inca 8K

Vendor id: 0x37b0 — Lamzu's own, not the shared CompX ODM id 0x373e that every existing Lamzu / CRDRAKO / Attack Shark product in this repo enumerates under. Because the same product id means different hardware depending on which vendor id it arrived under, the product lookup has to split per vendor id. Lamzu's configurator confirms both ids are live (DeviceInitFilterVID = 373E;37B0).

Product ids:

PID Role Connection Status
0x0009 Mouse on its cable Wired Verified on hardware
0x0010 8K receiver Wireless Verified on hardware
0x000f 1K receiver Wireless Not verified — vendor device table only, no dongle on hand
0x000a Mouse DFU bootloader Deliberately excluded
0x0002 Receiver DFU bootloader Deliberately excluded

Verified on real hardware (Windows 11, hidapi), both connection modes:

  • Config channel is MI_02, usage page 0xffff, usage 0x0000, report id 0, 65-byte feature buffer (report id + 64-byte packet). It accepts no other buffer size.
  • Both connections address the mouse as target 0x02, so no mouseTarget override is needed.
  • The Inca answers the existing CompX framing unchanged — same header, same 0xa1 OK status as the Maya X and KO-ONE. This is a catalog and discovery change, not a new protocol.
  • Every existing CompX decoder returns a correct value with no new cases: firmware 0.18, battery 100%, five DPI stages read unscaled as big-endian (400 / 2000 / 1600 / 3200 / 6400), lift-off 0x01 → Medium, sleep 60 s, debounce 0 ms.
  • The active stage read back as 2000 DPI — a value the owner had set by hand, since that stage defaults to 800 and 2000 is not a preset option. That is what pins the stage index as 1-based and the DPI as unscaled, rather than leaving it a guess.
  • Polling-rate families differ per connection. LAMZU_POLLING_RATES encodes 1000 Hz twice: 0x01 in the 125–1000 family and 0x10 in the 1000–8000 family. The cable answered 0x01 and the 8K receiver answered 0x40, so the two connections genuinely run different families — RATES_1K wired, RATES_8K on the 8K receiver.

Explicitly NOT verified:

  • This is read-only support. Every write path is uncaptured. The driver inherits DPI / polling / LOD / debounce setters from the shared Lamzu client and not one of them was exercised on an Inca. Please don't read this as more than read support.
  • 0x000f, the 1K receiver this model can also ship with, comes from the vendor's configurator device table only — nobody has held that dongle. The protocol is the receiver protocol either way, so the risk is a wrong rate list rather than a dead device.

Discovery note: the WebHID filter is narrowed to usage page 0xffff, which keeps the mouse, consumer, system and keyboard collections out of the picker on a platform that exposes a device's interfaces separately. A WebHID enumeration of both connections settles the one collection that narrowing cannot exclude: MI_01's 0xffff/0x0001 declares no feature reports at all, while only 0xffff/0x0000 declares report 0 — so the driver's feature-report-0 check rejects it rather than offering a dead entry. On Chrome/Windows all seven collections arrive on a single HIDDevice anyway, so each connection is a single picker entry however the filter is written.

Evidence: capture notes are in docs/lamzu-inca-testing.md — reads only, no setting was changed while capturing, serials redacted. No vendor binary or vendor source is included; the vendor configurator's device table is cited only as the stated provenance for the two ids that could not be checked on hardware.

Status of the branch: npm run check passes, 833/833 tests. The OpenMouse cross-build passes too — tsc --noEmit && vite build clean and 112/112 tests against the local package, on the control-panel branch.

Matching OpenMouse change: src/supported-mice.ts currently carries the Inca as status: "quickwin" with the note "Inca PID not yet in driver", which this makes stale. That change is open as OpenMouse-Project/openmouse#157. It marks the row "pr" rather than "supported" on purpose: the PID_UNIVERSE check in supported-mice.test.ts imports from @openmouse/protocol, so pinning the Inca PIDs as supported cannot compile until this lands. The row flips to supported in a one-line follow-up afterwards.

Pre-review checklist (CONTRIBUTING):

  • npm run check passes in this repository — 833/833.
  • OpenMouse builds and its full test suite passes with the local package (npm install --no-save --package-lock=false ../mouse-protocol on control-panel): tsc --noEmit && vite build clean, 112/112.
  • New public API is exported through the intended subpath — LAMZU_INCA_VENDOR_ID, LAMZU_INCA_PRODUCTS, LAMZU_VENDOR_IDS and lamzuProduct() all reach @openmouse/protocol/lamzu, which is already in package.json exports and tsconfig.json paths.
  • No generated files, no captures carrying identifiers, no unrelated changes. dist/ is untracked; the capture doc has its serials redacted.
  • Registry overlap tests pass. VENDOR_ID.lamzuInca is picked up by registry.test.ts automatically, and 0xffff was already in its USAGE_PAGES.

Left as a draft deliberately: this is read-only support and every setter the driver inherits is unproven on an Inca. Happy to narrow it further — dropping 0x000f until someone has the 1K dongle is a one-line change if you would rather not carry a vendor-sourced rate list.

The Inca enumerates under vendor id 0x37b0, not the shared CompX ODM id
0x373e that every earlier Lamzu, CRDRAKO, and Attack Shark product uses,
so it was invisible to the driver. It answers the existing CompX framing
unchanged, so this is a catalog and discovery change rather than a new
protocol: only the product lookup needed splitting per vendor id.

Confirmed on hardware (Windows 11, hidapi) in both connection modes:

- 0x0009, the mouse on its cable
- 0x0010, the 8K receiver

Both answer on MI_02 (usage page 0xffff, usage 0x0000), report id 0, a
65-byte feature buffer, and both address the mouse as target 0x02, so
neither needs a mouseTarget override. Every existing CompX decoder
produces a correct value with no new cases: firmware 0.18, battery 100%,
five DPI stages read unscaled as big-endian, lift-off 0x01 -> Medium,
sleep 60 s.

The two connections run different polling-rate families, which the
capture shows directly: LAMZU_POLLING_RATES encodes 1000 Hz twice, 0x01
in the 125-1000 family and 0x10 in the 1000-8000 family, and the cable
answered 0x01 where the 8K receiver answered 0x40. Wired is therefore
RATES_1K and the 8K receiver RATES_8K.

0x000f, the 1K receiver this model can also ship with, is taken from
Lamzu's own configurator device table and has not been exercised on
hardware. That table also names 0x000a and 0x0002 as the mouse and
dongle DFU bootloader identities; they never speak this protocol and are
excluded on purpose, with a test to keep them out.

The WebHID filter is narrowed to usage page 0xffff, which keeps the
mouse, consumer, system and keyboard collections out of the picker on a
platform that exposes a device's interfaces separately. A WebHID
enumeration of both connections settles the one collection that
narrowing cannot exclude: MI_01's 0xffff/0x0001 declares no feature
reports at all, while only 0xffff/0x0000 declares report 0, so the
driver's feature-report-0 check rejects it rather than offering a dead
entry. On Chrome/Windows the point is moot anyway — all seven
collections arrive on a single HIDDevice, so each connection is one
picker entry however the filter is written.

Writes are entirely uncaptured. The inherited setters are unproven on an
Inca, so this should be treated as read-only support.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018C96pMdnhGcXhLQhHYkLWc
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.

1 participant