feat: implement initial cyborg multi-action button mappings

- Added support for Single, Long, and Double press actions in libazeron.
- Mapped Cyborg surgical command IDs (0x20F6, 0x20F8, 0x204A).
- Updated azeron-cli to support --long and --double mapping flags.
- Updated protocol documentation with newly discovered Cyborg commands.
- Added TODO.md for remaining joystick and timing tasks.
This commit is contained in:
2026-02-22 19:08:13 +00:00
parent db5c3505da
commit 18f84a538a
12 changed files with 37131 additions and 152 deletions

View File

@@ -51,7 +51,7 @@ This document describes the USB configuration protocol for the Azeron Cyborg key
- **Transfer Type**: Interrupt transfers (0x01)
- **Packet Format**: Fixed 64-byte HID reports
- **Command Structure**: Request-response pattern
- **Endianness**: Big-endian for multi-byte values
- **Endianness**: Big-endian for multi-byte values (except offsets)
### Packet Format
@@ -59,135 +59,53 @@ All configuration packets follow this structure:
```
Byte 0: Flags/Type (0x00=request, 0x01=response)
Byte 1: Reserved (0x00)
Byte 1: Reserved/Length (0x3a for config writes)
Bytes 2-3: Command ID (big-endian)
Bytes 4-5: Operation type and parameters
Bytes 6-63: Data payload (varies by command)
```
### Command Reference
### Command Reference (Cyborg Model)
#### 0x122a - Get Status (Heartbeat)
**Purpose:** Periodic device status check (occurs every 1-2 seconds automatically)
**Purpose:** Periodic device status check.
**Request:**
```
OUT 0x06: 0000122a010100000000000000000000...
││ ││││└────┬────┘└────┬──────┘
││ ││││ │ └─ Payload (zeros)
││ ││││ └─ Operation: 0x0101 (read status)
││ ││└─────── Command ID: 0x122a
││ └──────── Reserved: 0x00
└─────────── Type: 0x00 (request)
```
#### 0x2000 - Set Global Settings
**Purpose:** Configure timing delays for actions.
- **Bytes 60-61 (Payload):** Long Press Delay (ms, big-endian, e.g., `01f4` = 500ms)
- **Bytes 62-63 (Payload):** Double Press Delay (ms, big-endian, e.g., `00c8` = 200ms)
**Response:**
```
IN 0x85: 0100122a010100013f4f691b0700ff060606...
││ ││││ │└────┬──────┘└────┬──────┘
││ ││││ │ └─ Device data starts here
││ ││││ └─ Status: 0x01 (success)
││ ││└─────── Command ID: 0x122a
││ └──────── Reserved: 0x00
└─────────── Type: 0x01 (response)
```
#### 0x20F6 - Set Single Press
#### 0x20F8 - Set Long Press
#### 0x204A - Set Double Press
**Purpose:** Surgical update for a specific button action.
- **Byte 10 (Payload):** Button ID (0-based)
- **Byte 22 (Payload):** Key Type (0xf0 = Keyboard)
- **Byte 23 (Payload):** Key Code (HID)
**Device Data Bytes:**
- Bytes 6-7: Profile number (0x0001 = Profile 1)
- Bytes 8-11: Joystick X/Y position
- Bytes 12-15: Button states (bitmask)
- Bytes 16-19: Analog stick settings
- Bytes 20-23: LED color (RGB)
- Bytes 24-63: Additional status data
#### 0x204B - Commit Button Changes
**Purpose:** Makes surgical updates (`0x20F6/F8/4A`) active.
#### 0x26EC - Bulk Write Profile
**Purpose:** Writes a complete profile block.
- **Byte 3 (Payload):** Joystick Mode (0x00 = Analog, 0x01 = WASD)
- **Byte 8 (Payload):** Stick Angle (degrees)
#### 0x26ED - Commit Bulk Write
**Purpose:** Persists bulk changes to EEPROM.
### Command Reference (Classic Model)
*Note: These commands are used by older Azeron versions and may differ from Cyborg.*
#### 0x12C8 - Read Configuration
**Purpose:** Read full device configuration
**Request:**
```
OUT 0x06: 000012c801010000000000000000000000...
││ ││││└────┬────┘
││ ││││ └─ Operation: 0x0101 (read config)
││ ││└─────── Command ID: 0x12c8
└──────────── Standard header
```
**Response:**
```
IN 0x85: 010012c8010101013f4f691b0700ff060606...
││ ││││ │└────┬──────┘
││ ││││ │ └─ Full configuration data (58 bytes)
││ ││││ └─ Status: 0x01 (success)
└──────────── Standard header
```
**Configuration Data Structure:**
- Bytes 6-9: Device signature/version
- Bytes 10-13: Profile 0 settings
- Bytes 14-17: Profile 1 settings
- Bytes 18-21: Profile 2 settings
- Bytes 22-25: Button mapping offsets
- Bytes 26-57: Button mappings (30 buttons × 1 byte each)
- Bytes 58-61: Joystick configuration
- Bytes 62-63: Checksum
**Purpose:** Read full device configuration.
#### 0x26FC - Write Profile Data
**Purpose:** Write profile configuration to device (does not persist)
**Request:**
```
OUT 0x06: 003a26fc020139040102000000fff40003f01a0000...
││ ││││└────┬────┘└────┬──────┘└────┬──────┘
││ ││││ │ │ └─ Button/key codes
││ ││││ │ └─ Offset: 0x0439 (1081)
││ ││││ └─ Operation: 0x0201 (write profile 1)
││ ││└─────── Command ID: 0x26fc
└──────────── Length: 0x003a (58 bytes)
```
**Response:**
```
IN 0x85: 000026fc010100013f4f691b0700ff060606...
Standard header + status + device data
```
**Profile Data Bytes:**
- Bytes 6-9: Offset/address (0x00000439)
- Bytes 10-13: Profile header (0x01020000)
- Bytes 14-17: LED color (0xfff40003 = RGBA)
- Bytes 18-21: Button 1 mapping (0xf01a0000)
- Bytes 22-25: Button 2 mapping (0xf0070000)
- ... (continues for all 30 buttons)
- Bytes 58-61: Joystick settings
- Bytes 62-63: Reserved
**Button Mapping Format:**
```
Byte 0: Key type (0xf0 = keyboard, 0xf1 = mouse, 0xf2 = gamepad, 0xf3 = macro)
Byte 1: Key code (USB HID code)
Byte 2: Modifier flags (shift, ctrl, alt)
Byte 3: Reserved
```
**Purpose:** Write profile configuration to device (does not persist).
#### 0x26FD - Save Profile
**Purpose:** Commit profile to device EEPROM (persists after power-off)
**Request:**
```
OUT 0x06: 003a26fd020201000000000000000000000000...
││ ││││└────┬────┘
││ ││││ └─ Operation: 0x0202 (save profile 1)
││ ││└─────── Command ID: 0x26fd
└──────────── Length: 0x003a (58 bytes, mostly zeros)
```
**Response:**
```
IN 0x85: 000026fd010100013f4f691b0700ff060606...
Standard header + confirmation
```
**Note:** The save command echoes the write command structure but with operation 0x0202 and minimal data payload. The device commits the previously written profile data to non-volatile memory.
**Purpose:** Commit profile to device EEPROM.
## Button Mapping Reference