Uh oh!
There was an error while loading. Please reload this page.
corsair: phase 2 — live DPI stage, lift-off, and angle-snap writes - #69
Merged
Merged
Conversation
Turns the NIGHTSWORD RGB driver from read-only into a settings client. Every write addresses the live profile (byte 3 = 0), gets no reply, and is confirmed by the matching GET, following the ckb-next layout that the write probe in captures/corsair-nightsword verified on fw 3.41. Setters, matching the shared stage-editor contract: - setDpi(x, y?) rewrites whichever slot is selected, reading its colour first so the RGB-required stage write does not clear it. - setDpiStageValue / setDpiStageColor / setActiveDpiStage index the numbered stages (slots d1–d5); the Sniper slot d0 is never touched. A stage whose Y already differs keeps it. - setDpiStageCount seeds never-populated slots from the last enabled stage before enabling them, preserves the Sniper bit in the mask, and moves the selection back inside the enabled range when shrinking. - setLiftOffDistance maps Low/Medium/High onto the raw 1–5 scale (1/3/5 on write; 1–2/3/4–5 on read) until iCUE's Surface Calibration labels are captured against it. - setAngleSnapping sends ckb-next's trailing 0x05, which the mouse accepts with or without. Status now reports dpiStageColors, liftOffDistance and the three supported stops, settingsReady/valuesVerified true, a dpiStageEditor hint (5 stages, 100–18,000 in 50-DPI steps to keep the option list usable), and showAdvancedSection so the processing card appears. Polling rate stays read-only because the device re-enumerates on that write. The identity-only fallback is unchanged. The driver test's fake device is now stateful: GETs answer from the iCUE-loaded fixture state big-endian, SETs mutate it little-endian and leave the feature buffer alone, so every setter is checked against both the bytes on the wire and the read-back. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The first phase-2 hardware run failed "Set DPI stage count to 4" with "kept 0 DPI on stage 4": the driver wrote slot d4 while the mask still had it disabled, and the mouse dropped the write. Write the mask first, confirm it, then seed any newly enabled slot that holds 0 DPI. The test fake now drops writes to disabled slots so the old order fails there too, and the run's other findings (a stale reply caught by the echo check, iCUE not reading live state back) are recorded in PROTOCOL.md. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
kfrancis
marked this pull request as ready for review
September 7, 2026 01:23
kfrancis
commented
Sep 7, 2026
ContributorAuthor
Re-ran the stage-count change on hardware with the mask-first ordering (fw 3.41, iCUE running): 3 → 4 adds a fourth 5,700 stage and reads back, 4 → 3 removes it. Marking ready. |
…iCUE iCUE has no manual lift-off control for the NIGHTSWORD, only the spiral surface-calibration pass, so there are no vendor labels to map the raw 1–5 byte against. The scale is ckb-next's slider range; Low/Medium/High = 1/3/5 is this driver's definition. Comment and notes only. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Polled 0e 13 03 00 twice a second through a complete spiral calibration pass in iCUE (fw 3.41); the lift byte stayed at 5 throughout. Surface tuning is therefore a separate command, still to be captured. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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
Follows #66 (read-only NIGHTSWORD RGB driver). Turns
CorsairHidClientinto a settings client. Every write addresses the live profile (byte 3 = 0), gets no reply, and is confirmed by the matching GET.Setters, matching the shared stage-editor contract:
setDpi(x, y?)rewrites whichever slot is selected, reading its colour first so the RGB-required stage write does not clear it.setDpiStageValue,setDpiStageColor,setActiveDpiStageindex iCUE's numbered stages (slots d1–d5). The Sniper slot d0 is never written. A stage whose Y already differs keeps it.setDpiStageCountwrites the mask first, confirms it, then seeds any newly enabled slot that holds 0 DPI from the last previously enabled stage. Preserves the Sniper bit; moves the selection back inside the enabled range when shrinking.setLiftOffDistancemaps Low/Medium/High onto the raw 1–5 scale (1/3/5 on write; 1–2/3/4–5 on read).setAngleSnappingsends ckb-next's trailing0x05, which the mouse accepts with or without.Status now reports
dpiStageColors,liftOffDistancewith the three stops,settingsReady/valuesVerifiedtrue, adpiStageEditorhint (5 stages, 100–18,000 in 50-DPI steps to keep the option list usable), andshowAdvancedSectionso the processing card appears. Polling rate stays read-only because that write re-enumerates the device. The identity-only fallback is unchanged.The driver test's fake device is stateful: GETs answer from the iCUE-loaded fixture big-endian, SETs mutate it little-endian and leave the feature buffer alone, and writes to disabled slots are dropped, so every setter is checked against both the bytes on the wire and the read-back.
Tested on hardware
NIGHTSWORD RGB fw 3.41, Windows 11, Chrome 152, OpenMouse control-panel, iCUE app + service running:
captures/corsair-nightsword/write-probe.txt): stage select is live (cursor speed changes), snap works with and without the trailing byte, lift accepts 1–5.Known limits
Checks
npm run checkpasses (1099 tests).🤖 Generated with Claude Code