- 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.
14 KiB
Azeron Configuration Protocol Documentation
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.
Protocol Status: ✅ Fully Reverse-Engineered
Implementation Status: 🔄 Ready for Development
USB Device Analysis
Device Descriptor Summary
- Vendor ID: 0x16d0 (MCS)
- Product ID: 0x113c (Azeron Keypad)
- Configuration: 1 configuration, 5 interfaces
- Power: 500mA (bus-powered)
Interface Breakdown
-
Interface 0: Vendor-specific (0xFF)
- Endpoints: 0x81 (IN), 0x01 (OUT)
- Purpose: Unused for configuration
- Status: Not utilized by Azeron software
-
Interface 1: HID
- Endpoint: 0x82 (IN)
- Purpose: Main button input (30 buttons)
- Packet size: 16 bytes
-
Interface 2: HID Boot Mouse
- Endpoint: 0x83 (IN)
- Purpose: Mouse emulation
- Packet size: 7 bytes
-
Interface 3: HID
- Endpoint: 0x84 (IN)
- Purpose: Analog stick input
- Packet size: 16 bytes
-
Interface 4: HID with IN/OUT
- Endpoints: 0x85 (IN), 0x06 (OUT)
- Purpose: Configuration interface
- Packet size: 64 bytes
- Protocol: Custom HID reports
Configuration Protocol
Protocol Characteristics
- Interface Used: Interface 4 (endpoints 0x06 OUT, 0x85 IN)
- 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)
Packet Format
All configuration packets follow this structure:
Byte 0: Flags/Type (0x00=request, 0x01=response)
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 (Cyborg Model)
0x122a - Get Status (Heartbeat)
Purpose: Periodic device status check.
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)
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)
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.
0x26FC - Write Profile Data
Purpose: Write profile configuration to device (does not persist).
0x26FD - Save Profile
Purpose: Commit profile to device EEPROM.
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:
- Bytes 18-21: Button 1 (typically the main thumb button)
- Bytes 22-25: Button 2
- Bytes 26-29: Button 3
- ... (continues linearly)
- Bytes 134-137: Button 30
Key Type Codes
| Code | Type | Description |
|---|---|---|
| 0xf0 | Keyboard | Standard keyboard key |
| 0xf1 | Mouse | Mouse button/wheel |
| 0xf2 | Gamepad | Gamepad button/axis |
| 0xf3 | Macro | Macro sequence |
| 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):
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)
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:
- Write Profile Data (0x26FC) - Write new profile configuration
- Status Response (0x26FC) - Device acknowledges
- Save Profile (0x26FD) - Commit to EEPROM
- 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
- LED color changes to profile-specific color
Implementation Guide
Wireshark Filters for Analysis
# 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
# 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)
- Handle modifier flags
- Create profile management functions
- 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
// 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:
- Request-Response: Every command gets an acknowledgment
- Two-Phase Write: Write data → Verify → Commit/Save
- Command IDs: Unique 2-byte identifiers for each operation
- Status Polling: Regular heartbeat to detect device presence
- 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
- Timing: Device expects responses within ~100ms
- Checksums: May need to implement data validation
- Atomic Operations: Write + Save must be atomic
- Device State: Must track active profile and settings
- 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:
- Document the command format with examples
- Provide USB capture files (PCAP format)
- Include test code if available
- Update this documentation
- 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
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:
USBPcapCMD.exe -d \\.\USBPcap6 -o capture.pcap -s 64
Analysis Filters:
usb.device_address == 8 && usb.transfer_type == 0x01 && usb.data_len == 64
Phase 2: Protocol Discovery
Key Findings:
- Configuration uses Interface 4 (not Interface 0 as initially assumed)
- Protocol uses HID interrupt transfers, not vendor control transfers
- Fixed 64-byte packet format
- Request-response pattern for all commands
- 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:
- Implement HID report parser in libazeron
- Create command builder functions
- Add button mapping support (30 buttons)
- Implement joystick configuration
- Add profile management
- Create comprehensive test suite
Estimated Timeline: 2-3 weeks for full implementation
Phase 4: Testing and Validation
Test Plan:
- Read current configuration from device
- Modify single button mapping
- Write new configuration
- Save to device
- Verify persistence after power cycle
- Test all 30 buttons
- Test joystick modes
- 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
- Timing: Device expects responses within ~100ms
- Checksums: May need to implement data validation
- Atomic Operations: Write + Save must be atomic
- Device State: Must track active profile and settings
- Error Recovery: Handle disconnects and reconnection
Next Steps
- Implement Core Protocol: Add HID report functions to libazeron
- Button Mapping UI: Create user interface for configuring 30 buttons
- Joystick Configuration: Add analog stick settings
- Profile Management: Implement profile switching and persistence
- Testing: Comprehensive test suite with all features
- Documentation: Update user documentation
Contributing
If you discover protocol details:
- Document the command format
- Provide USB capture files (PCAP format)
- Include test code if available
- Update this documentation
- 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.