Skip to content

ATK FIERCE X Protocol Notes

SpookyyQ edited this page May 12, 2026 · 10 revisions

ATK FIERCE X Protocol Notes

This page tracks the current reverse-engineering state for the ATK FIERCE X using ATK V HUB Web at https://hub.atk.pro/.

These notes are based on WebHID captures from the local sniffer in tools/webhid-sniffer-extension.

Device

Field Value
Product string ATK Mouse 8K Dongle
Vendor ID 0x373B
Product ID 0x101B
WebHID report ID 8
Frame size 16 bytes
Config usage page 0xFF02
Config usage 0x0002

Frame Shape

ATK uses the same 16-byte payload shape and global checksum rule as the IPI FLY PRO:

byte[0] = (0x4D - sum(byte[2..=15])) & 0xFF

Most ATK settings are not IPI-compatible commands. They are block writes where values are stored as value/check pairs:

check = 0x55 - value

Confirmed Commands

Active DPI Stage

The active DPI stage is stored in the 0x00 block. Bytes 9/10 carry the stage index and check byte.

stage 1: 07 00 00 00 08 20 35 04 51 00 55 00 00 00 00 3f
stage 2: 07 00 00 00 08 20 35 04 51 01 54 00 00 00 00 3f
stage 3: 07 00 00 00 08 20 35 04 51 02 53 00 00 00 00 3f
stage 4: 07 00 00 00 08 20 35 04 51 03 52 00 00 00 00 3f

Polling Rate

Polling is stored in the same 0x00 block. Bytes 5/6 carry the polling value and check byte.

125 Hz  -> 08 4d
250 Hz  -> 04 51
500 Hz  -> 02 53
1000 Hz -> 01 54
2000 Hz -> 10 45
4000 Hz -> 20 35
8000 Hz -> 40 15

Captured with active stage 4:

125 Hz:  07 00 00 00 08 08 4d 04 51 03 52 00 00 00 00 3f
250 Hz:  07 00 00 00 08 04 51 04 51 03 52 00 00 00 00 3f
500 Hz:  07 00 00 00 08 02 53 04 51 03 52 00 00 00 00 3f
1000 Hz: 07 00 00 00 08 01 54 04 51 03 52 00 00 00 00 3f
2000 Hz: 07 00 00 00 08 10 45 04 51 03 52 00 00 00 00 3f
4000 Hz: 07 00 00 00 08 20 35 04 51 03 52 00 00 00 00 3f
8000 Hz: 07 00 00 00 08 40 15 04 51 03 52 00 00 00 00 3f

DPI Values

Changing DPI writes four 8-byte blocks. A DPI value group appears to use:

[raw, raw, flags_or_hi, group_check]
group_check = (0x255 - raw - raw - flags_or_hi) & 0xFF

Likely encoding:

dpi = (raw + 1) * 10
raw = (dpi / 10) - 1

Examples:

0x4f -> 800 DPI
0x59 -> 900 DPI
0x9f -> 1600 DPI

More fixed-value captures are still needed before implementing DPI writes.

DPI LED

off:       07 00 00 4c 08 00 00 80 d5 03 52 00 55 00 00 f3
solid:     07 00 00 4c 08 01 54 80 d5 03 52 01 54 00 00 9e
breathing: 07 00 00 4c 08 02 53 80 d5 03 52 01 54 00 00 9e

The same 0x4C block also carries LED brightness and speed:

brightness min: 07 00 00 4c 08 01 54 10 45 03 52 01 54 00 00 9e
brightness mid: 07 00 00 4c 08 01 54 80 d5 03 52 01 54 00 00 9e
brightness max: 07 00 00 4c 08 01 54 ff 56 03 52 01 54 00 00 9e

speed slow: 07 00 00 4c 08 02 53 ff 56 01 54 01 54 00 00 9e
speed mid:  07 00 00 4c 08 02 53 ff 56 03 52 01 54 00 00 9e

Field layout:

byte[5]  mode: 0=off, 1=solid, 2=breathing
byte[7]  brightness raw: 0x10=min, 0x80=middle, 0xff=max
byte[9]  speed raw: 0x01=slow, 0x03=middle
byte[11] enable: 0=off, 1=on

Debounce

Debounce is stored in the 0xA9 block. Bytes 5/6 are the debounce value in milliseconds and its check byte.

0 ms  -> 00 55
1 ms  -> 01 54
2 ms  -> 02 53
4 ms  -> 04 51
8 ms  -> 08 4d
15 ms -> 0f 46
20 ms -> 14 41

Sleep Timer

Sleep is also stored in the 0xA9 block. Bytes 9/10 are the raw timer and check byte.

raw = seconds / 10

Confirmed:

30 s  -> 03 52
1 min -> 06 4f
2 min -> 0c 49
3 min -> 12 43
5 min -> 1e 37
20 min -> 78 dd
25 min -> 96 bf
30 min -> b4 a1

Changing sleep also emits a 0xB5 write with the same timer raw value. Treat this as part of the sleep write sequence until proven otherwise.

Sensor Toggles

All three are in the 0xA9 block and use 00 55 for off, 01 54 for on.

byte[7..8]   Motion Sync
byte[11..12] Linear Correction
byte[13..14] Ripple Correction

Examples:

Motion Sync on: 07 00 00 a9 0a 08 4d 01 54 03 52 00 55 00 55 ea
Linear on:      07 00 00 a9 0a 08 4d 00 55 03 52 01 54 00 55 ea
Ripple on:      07 00 00 a9 0a 08 4d 00 55 03 52 00 55 01 54 ea

Ultra Distance Mode

on:  16 00 00 00 0a 01 00 00 00 00 00 00 00 00 00 2c
off: 16 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 2d

RGB / Underglow Mode

This is separate from DPI preset colors. DPI colors are assigned per DPI preset and still need their own captures.

off:                    18 00 00 00 0a 00 ff 00 08 05 09 01 00 00 00 15
color stream:           18 00 00 00 0a 01 ff 00 08 05 09 01 00 00 00 14
single-color breathing: 18 00 00 00 0a 02 ff 00 08 05 09 01 00 00 00 13
single-color solid:     18 00 00 00 0a 03 ff 00 08 05 09 01 00 00 00 12
neon:                   18 00 00 00 0a 04 ff 00 08 05 09 01 00 00 00 11
mixed-color breathing:  18 00 00 00 0a 05 ff 00 08 05 09 01 00 00 00 10
colorful solid:         18 00 00 00 0a 06 ff 00 08 05 09 01 00 00 00 0f

Captured brightness, speed and timer fields for single-color breathing (mode = 0x02):

brightness min: 18 00 00 00 0a 02 ff 00 08 05 00 01 00 00 00 1c
brightness mid: 18 00 00 00 0a 02 ff 00 08 05 05 01 00 00 00 17
brightness max: 18 00 00 00 0a 02 ff 00 08 05 09 01 00 00 00 13

speed slowest: 18 00 00 00 0a 02 ff 00 08 00 09 01 00 00 00 18
speed mid:     18 00 00 00 0a 02 ff 00 08 05 09 01 00 00 00 13
speed max:     18 00 00 00 0a 02 ff 00 08 09 09 01 00 00 00 0f

timer 1 min:   18 00 00 00 0a 02 ff 00 08 09 09 01 00 00 00 0f
timer 5 min:   18 00 00 00 0a 02 ff 00 08 09 09 05 00 00 00 0b
timer 10 min:  18 00 00 00 0a 02 ff 00 08 09 09 0a 00 00 00 06

Observed field layout:

byte[5]  mode
byte[6]  red
byte[7]  green
byte[8]  blue
byte[9]  speed, range 0x00..0x09
byte[10] brightness, range 0x00..0x09
byte[11] timer in minutes

Captured color picker examples:

18 00 00 00 0a 02 12 ff 05 05 09 01 00 00 00 04
18 00 00 00 0a 02 ff 00 0d 05 09 01 00 00 00 0e

This indicates direct RGB bytes:

byte[6..8] = red, green, blue

DPI Preset / Receiver LED Color Table

Changing the receiver LED color from red to green and back caused ATK V HUB to write a color table at addresses 0x2C, 0x34, 0x3C and 0x44. Each block contains two RGB groups.

Group format:

[red, green, blue, check]
check = (0x255 - red - green - blue) & 0xFF

Examples:

red:     ff 00 00 56
green:   00 ff 00 56
blue:    00 00 ff 56
magenta: ff 00 ff 57

Observed block writes:

07 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 68
07 00 00 34 08 00 00 ff 56 04 00 ff 52 00 00 60
07 00 00 3c 08 ff 00 ff 57 ff 00 ff 57 00 00 58
07 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 50

Likely slot layout:

0x2C -> color slots 1 and 2
0x34 -> color slots 3 and 4
0x3C -> color slots 5 and 6
0x44 -> color slots 7 and 8

Clean one-slot captures are still needed because dragging the color picker emits intermediate colors.

Lift-Off Distance

Captured from increase/decrease controls. Byte 5 is the raw value and byte 6 is 0x55 - value.

07 00 00 0a 02 01 54 00 00 00 00 00 00 00 00 e5
07 00 00 0a 02 02 53 00 00 00 00 00 00 00 00 e5
07 00 00 0a 02 03 52 00 00 00 00 00 00 00 00 e5
07 00 00 0a 02 04 51 00 00 00 00 00 00 00 00 e5
07 00 00 0a 02 05 50 00 00 00 00 00 00 00 00 e5
07 00 00 0a 02 06 4f 00 00 00 00 00 00 00 00 e5
07 00 00 0a 02 07 4e 00 00 00 00 00 00 00 00 e5
07 00 00 0a 02 08 4d 00 00 00 00 00 00 00 00 e5
07 00 00 0a 02 09 4c 00 00 00 00 00 00 00 00 e5
07 00 00 0a 02 0a 4b 00 00 00 00 00 00 00 00 e5
07 00 00 0a 02 0b 4a 00 00 00 00 00 00 00 00 e5

This is confirmed as the ATK LOD settings control. It differs from IPI's 0.7/1/2 mm mapping and uses raw values 1..11.

Remaining Work

  • Confirm fixed DPI values for 800, 900, 1600 and 1800.
  • Capture DPI preset / receiver LED color slots one slot at a time.
  • Identify firmware/version reads.
  • Capture one simple button remap.

Clone this wiki locally