feat: implement cyborg joystick bulk write, global timings, and enhanced CLI mapping feedback
This commit is contained in:
374
docs/protocol.md
374
docs/protocol.md
@@ -2,10 +2,10 @@
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes the USB configuration protocol for the Azeron Cyborg keypad (USB ID: 16d0:113c). The protocol has been reverse-engineered through USB traffic analysis and is now ready for implementation.
|
||||
This document describes the USB configuration protocol for the Azeron Cyborg keypad (USB ID: 16d0:113c). The protocol has been reverse-engineered through USB traffic analysis and is now implemented in libazeron.
|
||||
|
||||
**Protocol Status:** ✅ Fully Reverse-Engineered
|
||||
**Implementation Status:** 🔄 Ready for Development
|
||||
**Implementation Status:** ✅ Implemented in libazeron
|
||||
|
||||
## USB Device Analysis
|
||||
|
||||
@@ -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 (except offsets)
|
||||
- **Endianness**: Little-endian for offsets and delays, Big-endian for Command IDs.
|
||||
|
||||
### Packet Format
|
||||
|
||||
@@ -68,12 +68,20 @@ Bytes 6-63: Data payload (varies by command)
|
||||
### Command Reference (Cyborg Model)
|
||||
|
||||
#### 0x122a - Get Status (Heartbeat)
|
||||
**Purpose:** Periodic device status check.
|
||||
**Purpose:** Periodic device status check. Returns current profile configuration.
|
||||
- **Payload Index 0:** Status (0x01 = Success)
|
||||
- **Payload Index 1:** Active Profile ID (0, 1, 2)
|
||||
- **Payload Index 3:** Joystick Mode
|
||||
- **Payload Index 8:** Stick Angle
|
||||
- **Payload Index 10:** Deadzone
|
||||
- **Payload Index 11:** Response Curve
|
||||
- **Payload Index 12:** Sensitivity
|
||||
- **Payload Index 13:** Inversion flags (Bit 0: X, Bit 1: Y)
|
||||
|
||||
#### 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)
|
||||
- **Bytes 54-55 (Payload):** Long Press Delay (ms, little-endian, e.g., `f401` = 500ms)
|
||||
- **Bytes 56-57 (Payload):** Double Press Delay (ms, little-endian, e.g., `c800` = 200ms)
|
||||
|
||||
#### 0x20F6 - Set Single Press
|
||||
#### 0x20F8 - Set Long Press
|
||||
@@ -88,8 +96,9 @@ Bytes 6-63: Data payload (varies by command)
|
||||
|
||||
#### 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)
|
||||
- **Byte 3 (Payload):** Joystick Mode (0x00=Analog, 0x01=WASD4, 0x02=WASD8, 0x03=Mouse)
|
||||
- **Byte 8 (Payload):** Stick Angle (0-255)
|
||||
- **Byte 10 (Payload):** Deadzone (0-100)
|
||||
|
||||
#### 0x26ED - Commit Bulk Write
|
||||
**Purpose:** Persists bulk changes to EEPROM.
|
||||
@@ -101,24 +110,20 @@ Bytes 6-63: Data payload (varies by command)
|
||||
#### 0x12C8 - Read Configuration
|
||||
**Purpose:** Read full device configuration.
|
||||
|
||||
#### 0x26FC - Write Profile Data
|
||||
**Purpose:** Write profile configuration to device (does not persist).
|
||||
|
||||
#### 0x26FD - Save Profile
|
||||
**Purpose:** Commit profile to device EEPROM.
|
||||
#### 0x26FB - Read Configuration (Cyborg)
|
||||
**Purpose:** Read specific memory blocks.
|
||||
|
||||
## Button Mapping Reference
|
||||
|
||||
The Azeron Cyborg has **30 configurable buttons** plus **1 analog joystick**.
|
||||
|
||||
### Button Numbering
|
||||
Buttons are numbered 1-30 in the configuration data:
|
||||
Buttons are numbered 1-30 in the configuration data. Each button has 3 actions (Single, Long, Double), each 4 bytes.
|
||||
|
||||
- **Bytes 18-21:** Button 1 (typically the main thumb button)
|
||||
- **Bytes 22-25:** Button 2
|
||||
- **Bytes 26-29:** Button 3
|
||||
- **Profile Offset 8-11:** Button 1 Single
|
||||
- **Profile Offset 12-15:** Button 1 Long
|
||||
- **Profile Offset 16-19:** Button 1 Double
|
||||
- ... (continues linearly)
|
||||
- **Bytes 134-137:** Button 30
|
||||
|
||||
### Key Type Codes
|
||||
|
||||
@@ -131,219 +136,43 @@ Buttons are numbered 1-30 in the configuration data:
|
||||
| 0xf4 | Media | Media control key |
|
||||
| 0xf5 | Layer | Layer switch |
|
||||
|
||||
### Key Code Values
|
||||
|
||||
**Keyboard (0xf0):**
|
||||
- 0x04 = A, 0x05 = B, 0x06 = C, ... (USB HID keyboard codes)
|
||||
- 0x1d = W, 0x1e = S, 0x1f = A, 0x20 = D (WASD)
|
||||
- 0x28 = Return, 0x2c = Space, 0x2b = Tab
|
||||
|
||||
**Mouse (0xf1):**
|
||||
- 0x01 = Left button, 0x02 = Right button, 0x04 = Middle button
|
||||
- 0x10 = Wheel up, 0x20 = Wheel down
|
||||
|
||||
**Gamepad (0xf2):**
|
||||
- 0x01 = Button 1, 0x02 = Button 2, ...
|
||||
- 0x30 = D-pad up, 0x31 = D-pad down, etc.
|
||||
|
||||
### Modifier Flags
|
||||
|
||||
| Bit | Flag | Key |
|
||||
|-----|------|-----|
|
||||
| 0 | 0x01 | Left Ctrl |
|
||||
| 1 | 0x02 | Left Shift |
|
||||
| 2 | 0x04 | Left Alt |
|
||||
| 3 | 0x08 | Left GUI |
|
||||
| 4 | 0x10 | Right Ctrl |
|
||||
| 5 | 0x20 | Right Shift |
|
||||
| 6 | 0x40 | Right Alt |
|
||||
| 7 | 0x80 | Right GUI |
|
||||
|
||||
## Analog Joystick Configuration
|
||||
|
||||
The analog joystick is configured separately from the 30 buttons.
|
||||
|
||||
**Joystick Data Bytes (58-61):**
|
||||
**Joystick Profile Data (Indices relative to payload start):**
|
||||
```
|
||||
Byte 58: Dead zone (0-100%)
|
||||
Byte 59: Sensitivity curve (0=linear, 1=exponential, 2=custom)
|
||||
Byte 60: X-axis inversion (0=normal, 1=inverted)
|
||||
Byte 61: Y-axis inversion (0=normal, 1=inverted)
|
||||
Index 3: Joystick Mode (0x00=Analog, 0x01=WASD4, 0x02=WASD8, 0x03=Mouse)
|
||||
Index 8: Stick Angle (0-255)
|
||||
Index 10: Dead zone (0-100%)
|
||||
Index 11: Sensitivity curve (0=linear, 1=exponential, etc.)
|
||||
Index 12: Sensitivity (0-100)
|
||||
Index 13: Inversion flags (Bit 0: X, Bit 1: Y)
|
||||
```
|
||||
|
||||
**Joystick Modes:**
|
||||
- **0x00 = Analog:** Standard analog stick behavior
|
||||
- **0x01 = 4-way:** Digital 4-direction pad
|
||||
- **0x02 = 8-way:** Digital 8-direction pad
|
||||
- **0x03 = Mouse:** Mouse emulation mode
|
||||
|
||||
## Profile Management
|
||||
|
||||
The device supports **3 profiles** (Profile 0, 1, 2).
|
||||
|
||||
### Profile Switching Sequence
|
||||
|
||||
When switching profiles, the software sends:
|
||||
|
||||
1. **Write Profile Data** (0x26FC) - Write new profile configuration
|
||||
2. **Status Response** (0x26FC) - Device acknowledges
|
||||
3. **Save Profile** (0x26FD) - Commit to EEPROM
|
||||
4. **Save Confirmation** (0x26FD) - Device confirms persistence
|
||||
|
||||
**Profile Numbers:**
|
||||
- Byte 5 of operation field: 0x00 = Profile 0, 0x01 = Profile 1, 0x02 = Profile 2
|
||||
|
||||
### Active Profile Indication
|
||||
|
||||
The currently active profile is indicated in status responses:
|
||||
- **Byte 6 of response:** Active profile number
|
||||
- **Byte 1 of payload:** Active profile number
|
||||
- **LED color** changes to profile-specific color
|
||||
|
||||
## Implementation Guide
|
||||
## Implementation Checklist
|
||||
|
||||
### Wireshark Filters for Analysis
|
||||
|
||||
```wireshark
|
||||
# All configuration commands (exclude heartbeat):
|
||||
usb.device_address == 8 && usb.data_len == 64 && !(usb.setup.wValue == 0x122a)
|
||||
|
||||
# Just write operations:
|
||||
usb.device_address == 8 && usb.data_len == 64 && usb.setup.wValue == 0x26fc
|
||||
|
||||
# Just save operations:
|
||||
usb.device_address == 8 && usb.data_len == 64 && usb.setup.wValue == 0x26fd
|
||||
|
||||
# All status polls (heartbeat):
|
||||
usb.device_address == 8 && usb.setup.wValue == 0x122a
|
||||
```
|
||||
|
||||
### USBPcap Capture Commands
|
||||
|
||||
```bash
|
||||
# Minimal capture (only config, no joystick data):
|
||||
USBPcapCMD.exe -d \\.\USBPcap6 -o config.pcap -s 64
|
||||
|
||||
# Capture only control transfers:
|
||||
USBPcapCMD.exe -d \\.\USBPcap6 -o config.pcap -F c
|
||||
```
|
||||
|
||||
### Implementation Checklist
|
||||
|
||||
- [ ] Implement 64-byte HID report parser
|
||||
- [ ] Create command builder for 0x122a, 0x12C8, 0x26FC, 0x26FD
|
||||
- [ ] Parse button mapping data (30 buttons)
|
||||
- [ ] Parse joystick configuration (4 bytes)
|
||||
- [ ] Implement profile read/write/save operations
|
||||
- [ ] Add support for all key types (keyboard, mouse, gamepad, macro)
|
||||
- [x] Implement 64-byte HID report parser
|
||||
- [x] Create command builder for 0x122a, 0x26FB, 0x26EC, 0x26ED
|
||||
- [x] Parse button mapping data (30 buttons x 3 actions)
|
||||
- [x] Parse joystick configuration (mode, angle, deadzone, etc)
|
||||
- [x] Implement profile read/write/save operations
|
||||
- [x] Add support for all key types (keyboard, mouse, gamepad)
|
||||
- [ ] Handle modifier flags
|
||||
- [ ] Create profile management functions
|
||||
- [ ] Add analog stick mode switching
|
||||
- [x] Create profile management functions
|
||||
- [x] Add analog stick mode switching
|
||||
- [ ] Implement LED color control
|
||||
|
||||
## Protocol Examples
|
||||
|
||||
### Example 1: Read Current Configuration
|
||||
|
||||
```
|
||||
Host → Device: 000012c801010000000000000000000000...
|
||||
Device → Host: 010012c8010101013f4f691b0700ff060606...
|
||||
```
|
||||
|
||||
### Example 2: Write Profile 1
|
||||
|
||||
```
|
||||
Host → Device: 003a26fc020139040102000000fff40003f01a0000...
|
||||
Device → Host: 000026fc010100013f4f691b0700ff060606...
|
||||
```
|
||||
|
||||
### Example 3: Save Profile 1
|
||||
|
||||
```
|
||||
Host → Device: 003a26fd020201000000000000000000...
|
||||
Device → Host: 000026fd010100013f4f691b0700ff060606...
|
||||
```
|
||||
|
||||
### Example 4: Switch to Profile 2
|
||||
|
||||
```
|
||||
Host → Device: 003a26fc020239040102000000fff40003f01a0000...
|
||||
Device → Host: 000026fc010200023f4f691b0700ff060606...
|
||||
Host → Device: 003a26fd020202000000000000000000...
|
||||
Device → Host: 000026fd010200023f4f691b0700ff060606...
|
||||
```
|
||||
|
||||
## Development Notes
|
||||
|
||||
### USB Control Transfer Format
|
||||
|
||||
```c
|
||||
// Send HID report to device
|
||||
int azeron_send_report(struct azeron_device *device,
|
||||
uint8_t *report, size_t length)
|
||||
{
|
||||
return libusb_interrupt_transfer(device->handle,
|
||||
0x06, // Endpoint OUT
|
||||
report,
|
||||
length,
|
||||
&transferred,
|
||||
1000); // Timeout
|
||||
}
|
||||
|
||||
// Receive HID report from device
|
||||
int azeron_receive_report(struct azeron_device *device,
|
||||
uint8_t *report, size_t length)
|
||||
{
|
||||
return libusb_interrupt_transfer(device->handle,
|
||||
0x85, // Endpoint IN
|
||||
report,
|
||||
length,
|
||||
&transferred,
|
||||
1000); // Timeout
|
||||
}
|
||||
```
|
||||
|
||||
### Common Gaming Device Protocol Patterns
|
||||
|
||||
The Azeron protocol follows these standard patterns:
|
||||
|
||||
1. **Request-Response:** Every command gets an acknowledgment
|
||||
2. **Two-Phase Write:** Write data → Verify → Commit/Save
|
||||
3. **Command IDs:** Unique 2-byte identifiers for each operation
|
||||
4. **Status Polling:** Regular heartbeat to detect device presence
|
||||
5. **Fixed Packet Size:** 64-byte reports for simplicity
|
||||
|
||||
### Tools for Development
|
||||
|
||||
- **USBPcap:** Windows USB capture
|
||||
- **Wireshark:** Protocol analysis with custom filters
|
||||
- **libusb:** Cross-platform USB communication
|
||||
- **hidapi:** Alternative HID-specific library
|
||||
|
||||
### Expected Challenges
|
||||
|
||||
1. **Timing:** Device expects responses within ~100ms
|
||||
2. **Checksums:** May need to implement data validation
|
||||
3. **Atomic Operations:** Write + Save must be atomic
|
||||
4. **Device State:** Must track active profile and settings
|
||||
5. **Error Recovery:** Handle disconnects and reconnection
|
||||
|
||||
## Current Status
|
||||
|
||||
**Protocol Status:** ✅ Fully Reverse-Engineered
|
||||
**Documentation Status:** ✅ Complete
|
||||
**Implementation Status:** 🔄 Ready for Development
|
||||
**Next Step:** Implement libazeron protocol functions
|
||||
|
||||
## Contributing
|
||||
|
||||
If you discover additional protocol details:
|
||||
|
||||
1. Document the command format with examples
|
||||
2. Provide USB capture files (PCAP format)
|
||||
3. Include test code if available
|
||||
4. Update this documentation
|
||||
5. Submit pull request with changes
|
||||
|
||||
## Safety Notes
|
||||
|
||||
- Always test with backup configurations
|
||||
@@ -353,127 +182,6 @@ If you discover additional protocol details:
|
||||
- Stop if device behaves unexpectedly
|
||||
- Keep original configuration files as backup
|
||||
|
||||
## References
|
||||
|
||||
- USB HID Specification: https://www.usb.org/hid
|
||||
- libusb Documentation: https://libusb.info
|
||||
- Azeron Cyborg Product Page: https://azeron.net
|
||||
- Wireshark USB Analysis: https://wiki.wireshark.org/USB
|
||||
|
||||
## Reverse Engineering Process
|
||||
|
||||
### Phase 1: USB Traffic Capture
|
||||
|
||||
**Tools Used:**
|
||||
- USBPcap 1.5.4.0
|
||||
- Wireshark 4.0.0
|
||||
- Azeron Windows Software v1.0.0
|
||||
|
||||
**Capture Method:**
|
||||
```bash
|
||||
USBPcapCMD.exe -d \\.\USBPcap6 -o capture.pcap -s 64
|
||||
```
|
||||
|
||||
**Analysis Filters:**
|
||||
```wireshark
|
||||
usb.device_address == 8 && usb.transfer_type == 0x01 && usb.data_len == 64
|
||||
```
|
||||
|
||||
### Phase 2: Protocol Discovery
|
||||
|
||||
**Key Findings:**
|
||||
1. Configuration uses Interface 4 (not Interface 0 as initially assumed)
|
||||
2. Protocol uses HID interrupt transfers, not vendor control transfers
|
||||
3. Fixed 64-byte packet format
|
||||
4. Request-response pattern for all commands
|
||||
5. Two-phase write (write → save) for persistence
|
||||
|
||||
**Command IDs Identified:**
|
||||
- 0x122a: Get Status (heartbeat)
|
||||
- 0x12C8: Read Configuration
|
||||
- 0x26FC: Write Profile Data
|
||||
- 0x26FD: Save Profile
|
||||
|
||||
### Phase 3: Implementation Strategy
|
||||
|
||||
**Next Steps:**
|
||||
1. Implement HID report parser in libazeron
|
||||
2. Create command builder functions
|
||||
3. Add button mapping support (30 buttons)
|
||||
4. Implement joystick configuration
|
||||
5. Add profile management
|
||||
6. Create comprehensive test suite
|
||||
|
||||
**Estimated Timeline:** 2-3 weeks for full implementation
|
||||
|
||||
### Phase 4: Testing and Validation
|
||||
|
||||
**Test Plan:**
|
||||
1. Read current configuration from device
|
||||
2. Modify single button mapping
|
||||
3. Write new configuration
|
||||
4. Save to device
|
||||
5. Verify persistence after power cycle
|
||||
6. Test all 30 buttons
|
||||
7. Test joystick modes
|
||||
8. Test profile switching
|
||||
|
||||
**Validation Criteria:**
|
||||
- All button mappings work correctly
|
||||
- Joystick behaves as configured
|
||||
- Profiles persist after power loss
|
||||
- No device crashes or errors
|
||||
- Performance: <100ms response time
|
||||
|
||||
### Tools for Reverse Engineering
|
||||
|
||||
#### USB Capture Tools
|
||||
- **USBPcap**: Windows USB capture
|
||||
- **Wireshark**: Protocol analysis
|
||||
- **usbmon**: Linux kernel USB monitoring
|
||||
- **libusb debug**: Enable debug output
|
||||
|
||||
#### Analysis Tools
|
||||
- **Protocol analyzers**: Wireshark with USB dissectors
|
||||
- **Hex editors**: For examining binary data
|
||||
- **Custom scripts**: Python with pyusb for testing
|
||||
|
||||
### Expected Challenges
|
||||
|
||||
1. **Timing:** Device expects responses within ~100ms
|
||||
2. **Checksums:** May need to implement data validation
|
||||
3. **Atomic Operations:** Write + Save must be atomic
|
||||
4. **Device State:** Must track active profile and settings
|
||||
5. **Error Recovery:** Handle disconnects and reconnection
|
||||
|
||||
### Next Steps
|
||||
|
||||
1. **Implement Core Protocol:** Add HID report functions to libazeron
|
||||
2. **Button Mapping UI:** Create user interface for configuring 30 buttons
|
||||
3. **Joystick Configuration:** Add analog stick settings
|
||||
4. **Profile Management:** Implement profile switching and persistence
|
||||
5. **Testing:** Comprehensive test suite with all features
|
||||
6. **Documentation:** Update user documentation
|
||||
|
||||
### Contributing
|
||||
|
||||
If you discover protocol details:
|
||||
|
||||
1. Document the command format
|
||||
2. Provide USB capture files (PCAP format)
|
||||
3. Include test code if available
|
||||
4. Update this documentation
|
||||
5. Submit pull request with changes
|
||||
|
||||
### Safety Notes
|
||||
|
||||
- Always test with backup configurations
|
||||
- Be prepared to reset device to factory defaults
|
||||
- Don't send malformed packets to device
|
||||
- Monitor device temperature during testing
|
||||
- Stop if device behaves unexpectedly
|
||||
- Keep original configuration files as backup
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
Special thanks to the Azeron community for providing captures and testing assistance during the reverse engineering process.
|
||||
Special thanks to the Azeron community for providing captures and testing assistance during the reverse engineering process.
|
||||
|
||||
Reference in New Issue
Block a user