This is a reverse engineered and reference implementation of GPD WinControls, developed and tested on GPD Win Max 2 2023.
[!CAUTION]
This repository is the product of reverse engineering
USB data frames sent to the device will be written directly to the EC ROM. Wrong speculation and implementation during the reverse engineering process may irreversibly destroy your device.
This repository and its contributors do not make any commitments, and all consequences are at the user’s own risk.
All request commands should be sent by SET_REPORT
, and read the response by GET_REPORT
.
SET_REPORT | GET_REPORT | |
---|---|---|
bmRequestType | 0x21 | 0xa1 |
bRequest | 0x09 | 0x01 |
wValue | 0x0201 | 0x0101 |
wIndex | 2 | 2 |
wLength | 33 | 65 |
Keyboard-Mouse follows HID Usage ID
In addition, there are GPD defined HID Usage ID extensions:
0xE8
: Mouse_UP0xE9
: Mouse_DownVIBRATE
0
: disable1
: light2
: heavyIn range [-10, 10] ([0xF6, 0x0A])
0x00
: 0 ms0x64
: 100 ms0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
01a5 | R/W | MAJOR_SERIAL | 5a | CHECK_DIGIT | 00 | MINOR_DIGIT | 00 |
R/W
1
2
MAJOR_SERIAL
R/W
= 1
: In range [0, 2]R/W
= 2
: In range [1, 3]CHECK_DIGIT
+ Header[2]
= 0xFF
MINOR_SERIAL
MAJOR_SERIAL
= 1
R/W
= 1
: In range [0, 3]R/W
= 2
: In range [0, 7]0
R/W
= 1
MAJOR_SERIAL
= 0
Command: 01a5105aef00000000000000000000000000000000000000000000000000000000
0-8 | 9 | 10 | 11 | 12 | 13-63 |
GPD Mainboard(GamePad) Firmware | GPD Extendboard(Keyboard-Mouse) Firmware | ||||
01a5105aef000000aa | MAJOR_VERSION | MINOR_VERSION | MAJOR_VERSION | MINOR_VERSION | 000000000000000000000000000000e40200000000000000000000000000000000000000000000000000000000000000000000 |
MAJOR_SERIAL
= 1
MINOR_SERIAL
= 0
Command: 01a5115aee00000000000000000000000000000000000000000000000000000000
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28-49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
Keyboard-Mouse | 000000000000ea00eb00ec00ed000000000000000000 | Back Button | ||||||||||||||||||||||||||||||||||||||||
Directional Pad | A Button | 00 | B Button | 00 | X Button | 00 | Y Button | 00 | Left Stick | Right Stick | LEFT_1 | 00 | LEFT_2 | 00 | LEFT_3 | 00 | LEFT_4 | 00 | RIGHT_1 | 00 | RIGHT_2 | 00 | RIGHT_3 | 00 | ||||||||||||||||||
UP | 00 | DOWN | 00 | LEFT | 00 | RIGHT | 00 | UP | 00 | DOWN | 00 | LEFT | 00 | RIGHT | 00 | PUSH | 00 | PUSH | 00 |
MINOR_SERIAL
= 1
Command: 01a5115aee00010000000000000000000000000000000000000000000000000000
0 | 1 | 2 | 3-7 | 8 | 9 | 10 | 11 | 12-15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32-63 |
Back Button | VIBRATE | 0000ff0000 | Stick Dead Zones | Back Button Delay | 2c | 01 | Back Button Delay | 2c | 01 | 0000000000000000000000000000000000000000000000000000000000000000 | |||||||||||||||
RIGHT_4 | 00 | LEFT_CENTER | LEFT_BORDER | RIGHT_CENTER | RIGHT_BORDER | 00000000 | LEFT_1 | 00 | LEFT_2 | 00 | LEFT_3 | 00 | RIGHT_1 | 00 | RIGHT_2 | 00 | RIGHT_3 | 00 |
MINOR_SERIAL
= 2
Command: 01a5115aee00020000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
MINOR_SERIAL
= 3
Command: 01a5115aee00030000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
MAJOR_SERIAL
= 2
Command: 01a5125aed00000000000000000000000000000000000000000000000000000000
0-7 | 8-23 | 24-29 | 30-63 |
Header | aa031401230000000000000000000000 | CHECKSUM | 00000000000000000000000000000000000000000000000000000000000000000000 |
01a5125aed000000 |
R/W
= 2
Write commands usually has no response.
MAJOR_SERIAL
= 1
MINOR_SERIAL
= 0
0-7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24-32 |
Header | Keyboard-Mouse | 000000000000000000 | |||||||||||||||
Directional Pad | A Button | 00 | B Button | 00 | X Button | 00 | Y Button | 00 | |||||||||
01a5215ade000000 | UP | 00 | DOWN | 00 | LEFT | 00 | RIGHT | 00 |
MINOR_SERIAL
= 1
0-7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20-32 |
Header | Keyboard-Mouse | 00000000000000000000000000 | |||||||||||
Left Stick | Right Stick | ||||||||||||
01a5215ade000100 | UP | 00 | DOWN | 00 | LEFT | 00 | RIGHT | 00 | PUSH | 00 | PUSH | 00 |
MINOR_SERIAL
= 2
01a5215ade0002000000ea00eb00ec00ed00000000000000000000000000000000
MINOR_SERIAL
= 3
0-7 | 8-9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24-32 |
Header | 0000 | Back Button | 000000000000000000 | |||||||||||||
01a5215ade000300 | LEFT_1 | 00 | LEFT_2 | 00 | LEFT_3 | 00 | LEFT_4 | 00 | RIGHT_1 | 00 | RIGHT_2 | 00 | RIGHT_3 | 00 |
MINOR_SERIAL
= 4
0-7 | 8 | 9 | 10 | 11-15 | 16 | 17 | 18 | 19 | 20-32 |
Header | Back Button | VIBRATE | 0000ff0000 | Stick Dead Zones | 00000000000000000000000000 | ||||
01a5215ade0004 | RIGHT_4 | 00 | LEFT_CENTER | LEFT_BORDER | RIGHT_CENTER | RIGHT_BORDER |
MINOR_SERIAL
= 5
0-7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24-32 |
Header | Back Button Delay | 2c | 01 | Back Button Delay | 2c | 01 | 000000000000000000 | ||||||||||
01a5215ade000500 | LEFT_1 | 00 | LEFT_2 | 00 | LEFT_3 | 00 | RIGHT_1 | 00 | RIGHT_2 | 00 | RIGHT_3 | 00 |
MINOR_SERIAL
= 6
01a5215ade00060000000000000000000000000000000000000000000000000000
MINOR_SERIAL
= 7
01a5215ade00070000000000000000000000000000000000000000000000000000
MAJOR_SERIAL
= 2
01a5225aed00000000000000000000000000000000000000000000000000000000
0-7 | 8-23 | 24-29 | 30-63 |
Header | aa031401230000000000000000000000 | CHECKSUM | 00000000000000000000000000000000000000000000000000000000000000000000 |
01a5225aed000000 |
MAJOR_SERIAL
= 3
01a5235adc00000000000000000000000000000000000000000000000000000000
This command will save all config into ROM.