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_low_or_value, raw_low_or_value, raw_hi_or_flags, group_check]
group_check = (0x255 - raw - raw - flags_or_hi) & 0xFF

Additional DPI slider captures show that the third byte in the group can also change. This means it is DPI-related data or a high/flag byte, not just padding.

3d 3d cc 0f
cb cb 22 9d
79 79 33 30
b8 b8 33 b2
bd bd 00 db
b4 b4 00 ed

Likely encoding:

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

ATK V HUB allows DPI changes in 10 DPI steps, which matches this encoding.

Examples:

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

Confirmed fixed-value captures:

1600 DPI: 9f 9f 00 17
1800 DPI: b3 b3 00 ef

This confirms 0xb4 is 1810 DPI, not 1800 DPI, for standard DPI groups. The non-zero third byte cases from slider dragging still need exact visible DPI values before implementing the high/flag byte path.

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.

Firmware / Performance Mode

The 0xB5 block also stores the ATK firmware/performance mode.

ATK Juesha competition firmware:
07 00 00 b5 06 00 55 06 4f 01 54 00 00 00 00 8c

Basic mode:
07 00 00 b5 06 00 55 06 4f 00 55 00 00 00 00 8c

Observed fields:

byte[7..8]  timer raw/check pair, raw = seconds / 10
byte[9..10] firmware/performance mode: 0=basic, 1=ATK Juesha competition firmware

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.

DPI 4 color assignment confirmed the second group of address 0x34:

DPI 4 color changed:
07 00 00 34 08 00 00 ff 56 92 38 07 84 00 00 60
07 00 00 34 08 00 00 ff 56 07 17 92 a5 00 00 60
07 00 00 34 08 00 00 ff 56 09 21 d7 54 00 00 60
07 00 00 34 08 00 00 ff 56 d7 32 09 43 00 00 60
07 00 00 34 08 00 00 ff 56 f0 34 05 2c 00 00 60

This confirms:

0x34 first group  = DPI 3 color
0x34 second group = DPI 4 color

The RGB values above are color-picker intermediate values, not final preset defaults.

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.

Button / Action Slot Writes

Captured while selecting System and confirming an action assignment. ATK V HUB wrote several 4-byte action slots at addresses 0x60..0x74.

07 00 00 70 04 01 04 00 50 00 00 00 00 00 00 7d

07 00 00 60 04 01 01 00 53 00 00 00 00 00 00 8d
07 00 00 64 04 01 02 00 52 00 00 00 00 00 00 89
07 00 00 68 04 01 04 00 50 00 00 00 00 00 00 85
07 00 00 6c 04 01 08 00 4c 00 00 00 00 00 00 81
07 00 00 70 04 01 10 00 44 00 00 00 00 00 00 7d
07 00 00 74 04 02 01 00 52 00 00 00 00 00 00 79

Observed slot layout:

byte[3] = slot address
byte[4] = 0x04
byte[5..8] = action data

The exact mapping from slot address to physical button and action code still needs one clean capture per remap.

Confirmed single remap:

Forward side button -> Back side button:
07 00 00 70 04 01 08 00 4c 00 00 00 00 00 00 7d

This indicates:

slot 0x70 = physical forward side button, likely
action 01 08 00 4c = side back button

Factory Reset

Factory reset starts with the same primary reset frame observed on IPI:

09 00 00 00 00 00 00 00 00 00 00 00 00 00 00 44

ATK V HUB then writes a long sequence of default blocks. These are bulk default configuration writes, not separate UI feature commands.

Observed reset block pattern:

07 00 03 00 0a 08 02 02 02 02 02 02 02 02 ff 22
07 00 03 0a 0a ff ff ff ff ff ff ff ff ff ff 39
07 00 03 14 0a ff ff ff ff ff ff ff ff ff ff 2f
07 00 03 1e 0a ff 00 00 00 00 00 00 00 00 00 1c

07 00 04 80 0a 08 02 02 02 02 02 02 02 02 ff a1
07 00 04 8a 0a ff ff ff ff ff ff ff ff ff ff b8
07 00 04 94 0a ff ff ff ff ff ff ff ff ff ff ae
07 00 04 9e 0a ff 00 00 00 00 00 00 00 00 00 9b

The same four-block pattern repeats across multiple high address groups.

Implementation note:

For app support, send only the primary reset frame first and verify whether the
mouse performs the reset by itself. Treat the following bulk writes as the web
driver's restore-defaults sequence unless testing proves the primary reset frame
is insufficient.

Post-reset readback captured these likely defaults:

polling rate = 2000 Hz
active DPI stage = 4
LOD raw = 6
Ultra Distance = off
debounce = 8 ms
sleep = 30 s
motion sync / linear correction / ripple correction = off
firmware/performance mode = basic

Representative default readbacks:

Config block 0x00:
08 00 00 00 08 10 45 04 51 03 52 00 55 00 00 e9

DPI blocks:
08 00 00 0c 08 4f 4f 00 b7 b4 b4 00 ed 00 00 87
08 00 00 14 08 59 59 00 a3 9f 9f 00 17 00 00 7f

LOD raw 6:
08 00 00 0a 02 06 4f 00 00 00 00 00 00 00 00 e4

Ultra Distance off:
16 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 2d

Sleep/debounce/toggles:
07 00 00 a9 0a 08 4d 00 55 03 52 00 55 00 55 ea

Remaining Work

  • Confirm fixed DPI values for 800, 900, 1600 and 1800.
  • Capture DPI 1, DPI 2 and any receiver-only color slot one at a time.
  • Identify firmware/version reads.
  • Capture additional physical buttons and action codes.