Skip to content

Refactor EVisionKeyboardController to support 128 LEDs and update pac…#91

Open
juampe wants to merge 1 commit into
CalcProgrammer1:masterfrom
juampe:evision-phoenix
Open

Refactor EVisionKeyboardController to support 128 LEDs and update pac…#91
juampe wants to merge 1 commit into
CalcProgrammer1:masterfrom
juampe:evision-phoenix

Conversation

@juampe
Copy link
Copy Markdown

@juampe juampe commented May 17, 2026

Summary

This PR fixes the EVision keyboard controller (VID 0x320F, PID 0x5078) Phoenix MK1 Elite so that all hardware lighting modes (Static, Breathing, Color Wave, Rainbow, etc.) actually take effect on the physical device. Previously, sending commands produced no visible result on the keyboard. The root cause was an incorrect HID protocol implementation discovered by reverse-engineering USB captures from the official Windows software.

Changes

EVisionKeyboardController.h

  • Packet size: EVISION_KB_MAX_PACKET_SIZE corrected from 0x36 to 0x38 (56 → 56+2 bytes, matching firmware expectation)
  • Offset type: SendKeyboardData data offset widened from unsigned short to unsigned int to support LE24 encoding. The protocol encodes the chunk offset across three bytes ([5], [6], [7]), making it a 24-bit field. unsigned short is only 16 bits and cannot represent the third byte, so usb_buf[0x07] was never populated. Although current offsets (max 6 × 0x38 = 0x150) fit in 16 bits, the type must be at least 24 bits wide to correctly extract all three bytes with (offset >> 16) & 0xFF

EVisionKeyboardController.cpp

  • Non-blocking reads: All hid_read() calls replaced with hid_read_timeout(..., 100) to prevent the driver from hanging when the device sends no response
  • Color data command: SendKeyboardData corrected from command 0x11 to 0x12 (WRITE_LIVE_COLOR_DATA), which is what the firmware actually accepts
  • Offset encoding: Chunk offset changed from 16-bit LE to 24-bit LE (bytes [5], [6], [7]), matching the observed wire format
  • Mode protocol rewrite: SendKeyboardModeEx now sends the real compound 27-byte parameter (param 0x00) wrapped in BEGIN/END packets, as captured from the Windows driver. The previous implementation sent an 8-byte parameter without BEGIN/END, which the firmware silently ignored

RGBController_EVisionKeyboard.cpp

  • LED count: Corrected from 126 to 128 LEDs (actual hardware count). The color buffer in DeviceUpdateLEDs is updated accordingly: 128 * 3 bytes (one R, G, B byte per LED), and the loop and SetKeyboardColors size argument match. The previous 7 * 0x36 = 378 byte buffer was 6 bytes short of the 384 bytes needed to address all 128 LEDs, leaving the last two LEDs always black

Protocol Details

The firmware stores lighting configuration in flash via a single SET_PARAMETER call carrying a 27-byte compound payload:

BEGIN  →  04 01 00 01 00 ...  (64 bytes)

SET_PARAMETER (cmd=0x06, param_id=0x00, size=27):
  byte  0  : profile index (0x00)
  byte  1  : mode
  byte  2  : brightness
  byte  3  : speed
  byte  4  : direction
  byte  5  : random flag
  bytes 6-8: R, G, B
  bytes 9-17: 0x00
  byte 18  : 0x03
  bytes 19-21: 0x00
  byte 22  : 0x03
  bytes 23-26: 0x00

END    →  04 02 00 02 00 ...  (64 bytes)

This sequence persists the setting to flash. The color survives USB disconnection, OS reboots, and KVM switches.

Related Issues

  • Fixes hardware modes (Static, Breathing, Color Wave, etc.) producing no visible effect on Phoenix MK1 Elite - EVision keyboard

Checklist

  • Compiles cleanly with no errors or warnings
  • Static mode tested: ./openrgb --noautoconnect --device 2 --mode Static --color 6667AB — color applied and persists after reboot
  • Color Wave mode tested via GUI — animation starts correctly
  • No debug output, no temporary code
  • No new dependencies

Testing Notes

Tested on:

  • Linux 6.x, USB HID interface 1 (COL04 vendor-defined)
  • Device: EVision Keyboard VID 0x320F / PID 0x5078 Phoenix MK1 Elite
  • Modes confirmed working: Static, Color Wave, Breathing, Spectrum Cycle, Rainbow Circle
  • Setting persists across: USB reconnect, reboot, KVM switch

Breaking Changes

None. All changes are corrections to match the actual hardware protocol. Existing behavior for all modes is preserved or improved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant