Compare commits

...
Author SHA1 Message Date
Adam Honse 4c1ec2f187 Center the device view horizontally 2020-07-27 00:10:03 -05:00
Adam Honse 7dadc8d9ee Use matrix map when available 2020-07-27 00:09:56 -05:00
Adam Honse cd7146d611 Move device view above other controls, begin working on matrix display 2020-07-27 00:09:48 -05:00
Adam Honse 853833d18a Device view resizes width to fit window size, UI updates on SDKcontroller update 2020-07-27 00:09:41 -05:00
Adam Honse c500803d95 Add widget that displays the current color of all LEDs on a controller 2020-07-27 00:09:34 -05:00
crashniels 68a92d0219 Read device mode and colours 2020-07-26 23:13:13 -05:00
crashniels 5221d93fc0 Changed UpdateMode() to DeviceUpdateMode() 2020-07-26 23:13:07 -05:00
crashniels 22deb13ac0 Added Galax modes in 2020-07-26 23:12:28 -05:00
crashniels 58b875d5ed Added missing references in the Qt Project file 2020-07-26 23:12:15 -05:00
crashniels 12f5d6070f WIP Galax RTX GPU support
Setting RGB values works. Modes still unknown.
2020-07-26 23:07:35 -05:00
crashniels 5e0b1fa3cc Added 0x3A to the Aura Ram Address list 2020-07-26 20:04:35 -05:00
Roger Roger 1ee3a7c3e2 Fix crash related to Razer Naga Trinity
Not all devices have static_mode at position 1, just setting it without
checking can crash the app
2020-07-26 15:49:39 -05:00
edbgon 43c13db970 Updated HID feature report with report ID for Windows compatibility 2020-07-26 15:46:20 -05:00
edbgon b5818d22af Update HID feature report to include report number for windows compatibility 2020-07-26 15:45:45 -05:00
Adam Honse fd7a5fc057 Add empty files/classes for HyperX Pulsefire Surge 2020-07-25 17:36:24 -05:00
Adam Honse 5af1ca9363 Fix formatting 2020-07-25 16:51:56 -05:00
Adam Honse c4d096e60c Update warning section in README to clarify a few things 2020-07-25 16:50:41 -05:00
Adam Honse 174b0743a9 Update timer resolution every 500ms to ensure it stays set while OpenRGB is active 2020-07-25 01:51:39 -05:00
Adam Honse 4b50533560 Uncomment timer initialization... 2020-07-25 01:33:18 -05:00
Adam Honse 1555dae1c8 Set timer resolution to 0.5ms on Windows 2020-07-25 01:20:49 -05:00
Chris 8b5717470a Fix for Gigabyte Fusion2 USB detection
* Adjusted the selection criteria for  USE_HID_USAGE flags
* Slight changes to the Fusion2USB controller to avoid crashes
* Updated DMIInfo to return correct Motherboard name on windows
2020-07-24 12:41:25 -05:00
edbgon 38b2cf03b0 LED name for 3rd LED group fixed 2020-07-24 12:39:24 -05:00
cjber 1293b07c9e add MSI 2070S Gaming X Support 2020-07-24 12:37:39 -05:00
Adam Honse aa4c41ddf7 Add Razer Blade Stealth and Blade Pro (2017) keymaps 2020-07-24 12:02:16 -05:00
Chris 628f423171 Minor fix for the Razer Blackwidow X Chroma 1532:0216
* Changed the 'w' to 'W' to match upstream
2020-07-23 21:57:21 -05:00
roger roger a9d179f93a Fixed typo that prevented the razer naga trinity from being detected 2020-07-23 21:56:26 -05:00
衛俊儒 4955dc0844 Update MSIGPUControllerDetect.cpp
MSI RTX2080 Sea Hawk EK X
2020-07-23 21:55:04 -05:00
Al_eXs 3f66f0d67a Fix Tab navigation order in the GUI 2020-07-23 21:48:31 -05:00
Adam Honse bc7ab5170a Add Razer BlackWidow Chroma Tournament Edition keymap 2020-07-23 21:18:30 -05:00
Adam Honse d61649f748 Add Razer BlackWidow Chroma keymap 2020-07-23 21:09:38 -05:00
Adam Honse 9a33a78574 Add keymap support to OpenRazer code and add a keymap for the Huntsman Elite 2020-07-23 14:42:34 -05:00
Adam Honse 030c0c60f3 Add (ANSI) and (ISO) specifiers to keys that differ between layouts 2020-07-23 11:17:23 -05:00
Adam Honse 19ff834d99 Fix apostrophe key on G810 2020-07-23 10:54:59 -05:00
Adam Honse 400a078a05 Fix media key names 2020-07-23 10:46:45 -05:00
Adam Honse 618bebc46b Update key names for G810 and Poseidon Z RGB 2020-07-23 10:26:16 -05:00
Adam Honse dee23ec52e Use synchronous mode update function in CLI 2020-07-22 23:29:32 -05:00
Adam Honse baca85b8cd Create a detection list for MSI GPU controller with card names 2020-07-22 22:32:00 -05:00
Arturo Casal 00b1cfcb3b Added Identifiers for MSI RTX 2080 Gaming X Trio 2020-07-22 20:47:55 -05:00
Shawn a9dbf5ef70 Add support for MSI 2060 Gaming X 2020-07-22 20:45:45 -05:00
Jeff Geer a0b1153ec3 Added Identifiers for MSI RTX 2080 Ti Gaming X Trio 2020-07-21 23:22:15 -05:00
Adam Honse 39a5e0eba0 Increment version number post-release 2020-07-21 23:21:10 -05:00
Adam Honse 308bb6f9b8 OpenRGB version 0.3 2020-07-21 19:34:18 -05:00
Adam Honse 86d96848a2 Fix buffer pointer in HyperX Alloy Origins controller 2020-07-21 19:33:34 -05:00
Adam Honse 98100a9bad Add two skipped slots before Number Pad Enter on HyperX Alloy Origins 2020-07-21 17:28:40 -05:00
Adam Honse e66562bb25 Fix number pad mapping on HyperX Alloy Origins 2020-07-21 16:29:17 -05:00
Adam Honse 902ebc2e83 Initialize transmit color count after inserting blanks 2020-07-21 12:28:05 -05:00
Adam Honse 403d60e214 Update skip list for HyperX Alloy Origins 2020-07-21 12:25:34 -05:00
Adam Honse 1c5130e78a HyperX Alloy Origins keymap 2020-07-20 23:30:10 -05:00
Miles M 481a5dea2e Update RGBController/OpenRazerDevices.h 2020-07-20 18:14:46 -05:00
Adam Honse 320129633d Add SMBus detection mode selection box 2020-07-20 17:49:12 -05:00
xgelectro 0dea21a53e i2c_smbus_nvapi::i2c_smbus_xfer now returns -1 for I2C_SMBUS_QUICK accesses which are unsupported 2020-07-20 17:37:43 -05:00
xgelectro 79625e9c8a Removed read bit from i2c_dev_address, so the detection of ASUS ROG RTX20xx Super is now working 2020-07-20 17:37:38 -05:00
Adam Honse 0cff1734ce Use 65 as size for Alloy Origins feature reports 2020-07-20 17:29:45 -05:00
David Reidsma e1d8f48cb9 changed max brightness from 5 to 4 2020-07-19 13:32:47 -05:00
B Horn 752737034b AddressSanitizer build time configuration option
This adds a configuration time option for enabling AddressSanitizer,
a tool included with recent versions of gcc (4.8+) and clang (3.1+).

To use it:
qmake CONFIG+=asan <path to orgb>
2020-07-19 13:25:51 -05:00
B Horn ecf1d2ce98 Bounds checking for ResizeZone implementations
As noted in #350, various RGBControllers don't validate if the zone they
are trying to resize actually exists.

This was fixed by a just checking they remain in bounds.
2020-07-19 13:23:40 -05:00
B Horn bb743c6b62 Validating user provided indexes in RGBController
When using the SDK Server, it was possible to provide indexes that would
later be used inside the various SetXDescription functions in
RGBController. This would result in possible out of bounds reads /
writes.

This is patched by checking the various indexes remain in bounds.
2020-07-19 13:19:59 -05:00
B Horn f02223d6ba Checks to avoid null dereferences in NetworkServer
Various commands in NetworkServer require extra data. However, if the
packet size is set to 0 for these, the code will skip over reading the
data in and allocating memory. This results in null dereferences.

This patch adds checks to the relevant commands to make sure they don't
continue reading a null pointer.
2020-07-19 13:16:19 -05:00
edbgon b87980965d Updated key names in accordance with usb spec 2020-07-19 13:05:51 -05:00
edbgon 2255eea14e Proper matrix map for Apex 7 keyboard 2020-07-19 13:05:26 -05:00
Adam Honse 0ccf2d0c33 Remove some debugging printouts in Network Client and Server code 2020-07-17 22:10:53 -05:00
Adam Honse 5ce6ec9ea7 Request updated controller mode from server after sending a Set Custom Mode command 2020-07-17 18:29:37 -05:00
Adam Honse 97e1c3e913 Update mode asynchronously 2020-07-17 18:29:37 -05:00
Adam Honse 9937731ad8 Remove WinUSB instructions and instead provide WinUSB uninstall instructions after the Windows HID switch 2020-07-17 17:15:19 -05:00
Adam Honse bd4f3728f6 Re-add interface check for Corsair driver when not using HID usages. Only set special function control for non-keyboards 2020-07-17 09:23:50 -05:00
Chris 009a6ccd2a Updated detector to include code pages
* Report descriptor for GB Fusion2 USB 048d:8297

0x06, 0x89, 0xFF,  // Usage Page (Vendor Defined 0xFF89)
0x09, 0x10,        // Usage (0x10)
0xA1, 0x01,        // Collection (Application)
0x85, 0x5A,        //   Report ID (90)
0x09, 0x01,        //   Usage (0x01)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x10,        //   Report Count (16)
0xB1, 0x00,        //   Feature (Data,Array,Abs,No Wrap,Linear,Preferred
State,No Null Position,Non-volatile)
0xC0,              // End Collection
0x06, 0x89, 0xFF,  // Usage Page (Vendor Defined 0xFF89)
0x09, 0xCC,        // Usage (0xCC)
0xA1, 0x01,        // Collection (Application)
0x85, 0xCC,        //   Report ID (-52)
0x09, 0x01,        //   Usage (0x01)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x3F,        //   Report Count (63)
0xB1, 0x00,        //   Feature (Data,Array,Abs,No Wrap,Linear,Preferred
State,No Null Position,Non-volatile)
0xC0,              // End Collection
2020-07-17 09:23:50 -05:00
Katzenbiber 6606ab92bd Fix Wraith Prism using WinUSB on Windows
- Add Usage Page to Wraith Prism Detect, which fixes WinUSB bugs.
- Change AMDWraithPrismControllerDetect.cpp structure
2020-07-17 09:23:49 -05:00
Adam Honse 595248cc10 Fix issues preventing hidapi from working without WinUSB on Windows 2020-07-17 09:23:49 -05:00
Chris ffc02e6c98 Coolermaster MP750 now supports on load status from device
Previous issues with hidapi-hidraw vs hidapi-libusb have been resolved.
CMMP750Controller.cpp now calls GetStatus in the constructor to query
device and set current state. Added "Getters" to the public interface to
allow the RGBController_CMMP750Controller.cpp to access current state in
construction.
2020-07-17 09:16:02 -05:00
Adam Honse ac2d911566 Disable MSI Mystic Light controller until the bricking issues are understood 2020-07-16 23:34:50 -05:00
Adam Honse 633dfdbddd Re-add EKControllerDetect.cpp with fixed capitalization (to fix build break on case-sensitive systems 2020-07-16 13:09:59 -05:00
Adam Honse 54cd8408e8 Temporarily delete EKControllerdetect.cpp (lower case) 2020-07-16 13:09:19 -05:00
Chris 384011aab3 Preliminary functionality implemented for EK Loop Connect
* 9 modes implemented
* Speed Slider works
* Currently single (non linear) zone
2020-07-16 11:12:59 -05:00
Chris 95ded7b871 Initial commit for the EK Loop Connect Support
* Implemented Static & Breathing modes
2020-07-16 11:12:48 -05:00
Adam Honse 607d83b795 More Sapphire GPU work 2020-07-15 14:47:37 -05:00
SuNNjek f4872c52bd Add support for MSI RTX 2070 ARMOR 2020-07-15 10:20:05 -05:00
Adam Honse 505e2d2aa4 Initial driver for Sapphire GPU (tested on RX580 Nitro+ on Windows) 2020-07-15 00:22:46 -05:00
Chris 77ecfc3b46 Cleaned up MSI Mysticlight detect pids
* Added all MSI Mystic light PIDS to udev rules
* Slight tweak to speed up CM detector
2020-07-14 15:43:40 -05:00
Chris 8107288838 Additonal code corrections and updates for B550 2020-07-14 15:36:56 -05:00
Adam Honse 05e76cc733 Fix Windows build 2020-07-12 17:02:11 -05:00
Adam Honse 816eabb1d1 Update direct packet for HyperX keyboards based on Alloy FPS captures 2020-07-12 16:53:20 -05:00
Adam Honse 9b6e24947d Code style cleanup for MSI GPU controller 2020-07-12 16:29:34 -05:00
Hex3l 5778d344e0 adds support to MSI 2080 Ti Sea Hawk EK X 2020-07-12 16:25:56 -05:00
xyz b785f2efbf Attach PCI IDs in DetectNvAPII2CBusses() 2020-07-12 16:25:07 -05:00
xyz 224f59450e Add support for MSI RTX 2080S Gaming X Trio 2020-07-12 16:20:57 -05:00
Adam Honse b80cbe931e Add Corsair Glaive RGB PRO to detection list 2020-07-12 16:06:58 -05:00
Adam Honse 87adb0bdb7 Add keepalive thread for Alloy Origins 2020-07-12 02:41:07 -05:00
Adam Honse 78c7572a2c Update constants for Alloy Origin driver and use 64 byte instead of 65 byte operations 2020-07-12 02:10:05 -05:00
Adam Honse bbed1f64a7 Use interface 3 for Alloy Origins 2020-07-12 01:20:59 -05:00
Adam Honse ac071902c0 Fix MSVC paths from 2017 to 2019 upgrade 2020-07-12 00:54:06 -05:00
Adam Honse 62a4cd31c5 Update QT path for GitLab CI 2020-07-12 00:47:32 -05:00
Adam Honse 751961b3b3 Initial controller for HyperX Alloy Origins 2020-07-12 00:31:40 -05:00
Chris 30625548e5 Adding USB PID 048D:5702 for Gigabyte B550 Aorus Elite 2020-07-09 22:38:12 -05:00
Chris 9451771ccb Rewrote the RGBFusion2USBController to allow for per model
configurations of LED's and zones

* largely changed knownLayoutsLookup to remove reliance on other enums /
structures and made it a map of maps
* rewritten the code to accomodate that change
2020-07-09 22:25:56 -05:00
Chris 12442046e2 Initial commit for dmiinfo.cpp
- Tested working for Linux
- Implemented in Fusion2USB controller and the motherboard name will
populate the controller name in the GUI / CLI
2020-07-09 22:25:45 -05:00
B Horn 47baeb6b6b Improving NetworkServer's memory management (#373)
This patch resolves several bugs:

* NetworkServer would allocate various instances of `NetworkClientInfo`.
  This is patched by deallocating the NetworkClientInfo when it's
  listening thread ends in the `listen_done` section.

* Memory would be allocated for threads that wouldn't be freed. This
  is resolved by detaching from the threads, so they no longer need to
  be joined to be freed, and then freeing the memory as they finish.

* Thread-Safety issues involving `ServerClients` would result in stray
  `NetworkClientInfo`'s not being removed from the list in certain
  situations. This is resolved by used a mutex to lock access to this
  from different threads.
2020-07-09 21:56:42 -05:00
Neel Chotai 263561868c fix musl compilation 2020-07-09 21:51:33 -05:00
Adam Honse 9bc58b039b Add Corsair Harpoon (non-Pro) to detected Corsair Peripheral list 2020-07-09 12:00:02 -05:00
Adam Honse 82c0ff8452 Add HyperX Alloy FPS to detected HyperX keyboard list 2020-07-08 11:43:41 -05:00
edbgon 2d7e996e4b Added initial support for SteelSeries Apex 7 Keyboard (Nordic model) 2020-07-08 03:22:03 -05:00
Adam Honse 0ae76e40c2 Add matrix map for Ducky One 2 TKL 2020-07-07 16:33:21 -05:00
Adam Honse 343c285321 Initial driver for Ducky One 2 keyboard 2020-07-07 13:15:02 -05:00
Adam Honse 6492852627 Add Corsair Harpoon RGB Pro to supported devices list 2020-07-07 01:20:56 -05:00
Adam Honse acc032a69c Adjust Polychrome speed 2020-07-06 13:17:39 -05:00
Adam Honse 950a3be01d More MSI Mystic Light cleanup 2020-07-06 03:45:45 -05:00
Adam Honse 6626321e80 Don't update NZXT fan status for any Hue 2 devices until we get initialization packet working 2020-07-06 02:13:00 -05:00
Adam Honse 7276f5e1d5 Add speed control to Polychrome controller 2020-07-06 02:03:47 -05:00
Adam Honse 5f9c4f8432 Code cleanup and rework for MSI Mystic Light controller
* Replace decimal constants with hexadecimal constants when ANDing/ORing values
* Add comments to explain what the code is doing
* Use C-style casts to fit the project standards
2020-07-05 18:27:51 -05:00
Adam Honse a1cd324731 Add comments and minor cleanup to Kraken driver 2020-07-05 12:12:07 -05:00
Adam Honse c2c5e6666d Fix previous commit 2020-07-05 12:04:35 -05:00
Adam Honse f7d6ede033 Update NZXT Hue 2 and Kraken detectors 2020-07-05 12:02:29 -05:00
Adam Honse 25f9e2a110 Add --client command line argument for opening network clients 2020-07-05 04:25:46 -05:00
Adam Honse 8ef6888a28 Add I2C byte operation to piix4 driver on Windows 2020-07-04 15:40:46 -05:00
B Horn 78a7be63ef Using the correct PID for the Steelseries 300 (0x1710) 2020-07-04 03:28:46 -05:00
Adam Honse f108515a6e Fix Set All Devices being slow and crashing on certain setups. It was sending the update multiple times 2020-07-03 02:59:54 -05:00
Adam Honse ad4e198aea Replace C-style clock() with std::chrono::steady_clock to fix timing on Linux 2020-07-02 16:59:30 -05:00
Adam Honse 5aad79135f Don't try to read fan status for Hue 2 devices without fan controllers 2020-07-01 19:25:29 -05:00
Adam Honse 5fc6981c16 Fix OpenRazer devices with logo/scroll/left/right matrix effect nodes on Windows 2020-06-30 18:11:15 -05:00
Adam Honse 942df26432 Update Readme 2020-06-30 18:10:44 -05:00
Adam Honse b3860be638 Bring in NZXT Hue 2 controller improvements from fan_devel branch 2020-06-28 23:44:35 -05:00
Adam Honse 8ecabb0789 Add 32-bit GitLab CI build target for Windows 2020-06-28 22:40:42 -05:00
Adam Honse d3fc88b24f Fix USB serial port detection in Windows. Fixes false Hue+ detection 2020-06-28 22:36:25 -05:00
Adam Honse dfb2e52e7b Add --i2c-tools to help text with warning, set GUI flag if --i2c-tools is specified 2020-06-28 21:41:00 -05:00
Adam Honse 96af869d79 Check for local server before detecting devices from hardware and tweak timeouts to make network connections faster 2020-06-28 21:08:59 -05:00
Adam Honse 4c6429ae76 Add OpenRGB client support to GUI 2020-06-28 17:57:27 -05:00
Adam Honse 7d2877a8e9 Don't exit after loading a profile from the command line 2020-06-28 11:21:56 -05:00
Adam Honse a25f3ef2fc GUI rework to provide more control over optional tabs to main.cpp, add TODO comments for client mode 2020-06-28 03:01:43 -05:00
Adam Honse 15ace9d094 Add flag to start application minimized to tray 2020-06-28 02:30:23 -05:00
Adam Honse 58aba0a147 Allow specifying --gui and --server together 2020-06-28 02:18:28 -05:00
EXtremeExploit 199db16ec0 Fix RGB problem with strip and media keys 2020-06-26 20:59:54 -05:00
EXtremeExploit c364fabf57 Add the UK Enter and UK Backslash leds 2020-06-26 20:20:46 -05:00
Adam Honse 15a2d5beaf Add zadig clarification to readme 2020-06-26 13:50:00 -05:00
Adam Honse 5b956f7ff1 Add missing Corsair PIDs 2020-06-26 11:15:59 -05:00
Chris dc42248a88 Added Warrior Kane TC235 2020-06-25 23:59:28 -05:00
Adam Honse eeeab399be Fix LED count in Corsair Lighting Node controller 2020-06-25 22:32:33 -05:00
Adam Honse 39d451793b Update Lighting Node detection to detect multiple of the same device. Add reads to Lighting Node driver to fix compatibility with Corsair Lighting Protocol Arduino project 2020-06-25 22:30:31 -05:00
Adam Honse 5db888fba0 Add Fedora dependency list to README 2020-06-25 14:51:02 -05:00
Adam Honse 1b91687fac Re-add LED 2 for WiFi X570 Gigabyte boards 2020-06-25 13:25:11 -05:00
Chris 7d38cd4a78 Fix issue #161
- removed added LED in known_channels for the x570
- ensured that the .header address is passed to SetLEDEffect() correctly
2020-06-25 13:07:18 -05:00
Chris 899b90decc Udev rules to replace 99-openRGB.rules
- whilst rule number is arbiturary TAG=+"uaccess" needs to be run prior
to /lib/udev/rules.d/70-uaccess.rules
- Removed unsafe MODE="666" access
- Removed GROUP tags as no longer required

- Confirmed working on Ubuntu & Arch. See issue #329
2020-06-25 09:15:50 -05:00
edbgon 8dcb1f075d Add LED header for Gigabyte RGB Fusion 2.0 - X570 I AORUS PRO WIFI (rev. 1.0) motherboards. Solves #161. 2020-06-25 08:50:47 -05:00
Nate Dean 5588f9b7a9 Quick G403 Hero support (First Time contributing to something so hopefully I don't mess up) 2020-06-25 08:16:54 -05:00
Thomas Karl Pietrowski 717620e8dd debian: openrgb-udev depends on udev
Makes sense, no?

Signed-off-by: Thomas Karl Pietrowski <[email protected]>
2020-06-24 12:05:29 -05:00
Thomas Karl Pietrowski 877d462dbc debian: Remove package dependencies
debhelper is smart enough to determine these on it's own.

Signed-off-by: Thomas Karl Pietrowski <[email protected]>
2020-06-24 12:05:19 -05:00
Thomas Karl Pietrowski d3cf315175 debian: Also recommend openrgb-dkms-drivers
Signed-off-by: Thomas Karl Pietrowski <[email protected]>
2020-06-24 10:51:32 -05:00
Thomas Karl Pietrowski f47129902a debian: Building in parallel
Signed-off-by: Thomas Karl Pietrowski <[email protected]>
2020-06-24 10:51:07 -05:00
Thomas Karl Pietrowski 5a3c69ec32 debian: Recommend to install openrgb-udev
Signed-off-by: Thomas Karl Pietrowski <[email protected]>
2020-06-24 10:50:55 -05:00
Thomas Karl Pietrowski 392c547b87 debian: Making openrgb-udev a arch-indep package
Signed-off-by: Thomas Karl Pietrowski <[email protected]>
2020-06-24 10:50:37 -05:00
Thomas Karl Pietrowski 38527a5122 debian: Adding pkg-config as Build-Dep
Signed-off-by: Thomas Karl Pietrowski <[email protected]> (github: thopiekar)
2020-06-24 10:49:37 -05:00
Thomas Karl Pietrowski 77412a959f debian: Cleanup
Signed-off-by: Thomas Karl Pietrowski <[email protected]> (github: thopiekar)
2020-06-24 10:49:17 -05:00
Thomas Karl Pietrowski 3a5ebe387e debian: Adding separate package for udev rule
Signed-off-by: Thomas Karl Pietrowski <[email protected]>
2020-06-24 10:48:49 -05:00
Térence Clastres 1db412e970 Fix high CPU usage when running the SDK server
It was coming from `recv_select()` and `accept_select()`
The timeval struct members for select() is reset after each call to select() for
whatever reason so like FD_ZERO and FD_SET it needs to be placed inside
the loop.

Source: https://stackoverflow.com/questions/3324078/why-select-always-return-0-after-the-first-timeout
2020-06-24 10:08:40 -05:00
Chris a3c931392a Merged MP750 Medium changes and made logic changes to correctly compile
and execute
2020-06-24 10:04:39 -05:00
Térence Clastres b94f701db8 Fix high CPU usage when running the SDK server
It was coming from `recv_select()` `nd accept_select()`
The timeout for select() is only when waiting for the file descriptor to
be ready for reading/writing so when the FD is ready AND there is
nothing to read, it will not return and instead keep executing the while loop with no timeout.
Fix this by adding a 100ms timeout when there is nothing to read.
2020-06-24 09:35:31 -05:00
Térence Clastres b79ff124e6 Replace Sleep() by std::thread::sleep_for() 2020-06-24 09:28:11 -05:00
Adam Honse 60baf6d05f Remove duplicate line 2020-06-24 08:26:09 -05:00
Swyter cb9b22804a Implement human color parsing in the command-line by using the standardized CSS 3 subset, well known for styling. Interpret first as text to avoid problems like 'darkgreen' being picked up as 0xDA.
- Also, and make case insensitive by using the strcasecmp() function. Both for colors and modes. The only improvement I can think of is stripping whitespace beforehand.
  - Also, improve digit parsing by using `strtoul()`, previously only FF00FF worked, whereas now we can type things like 0xFF00ff or 0xff00ff.

For example; something like this should work: `OpenRGB.exe -c darkgreen,ff00ff,0xff0000,red,REd,teal,pink,gOLd,AAgoldo,magenta -m breathing`

(`AAgoldo` will throw a `Error: Unknown color: 'AAgoldo', skipping.`; and pick the next color instead, this is intended behavior)
2020-06-23 23:15:10 -05:00
Térence Clastres d2dfd03551 Use the default SDK port constant in the CLI 2020-06-23 23:10:41 -05:00
Térence Clastres f3bdee9bd2 CLI: Allow --mode flag to be case insensitive
Also fix handling when no argument passed
2020-06-23 23:10:29 -05:00
Adam Honse 7a3de1edbb Add firmware version request to NZXT Hue 2 controller 2020-06-22 23:23:36 -05:00
Adam Honse 0464fbcbe2 Make default SDK port a defined constant 2020-06-22 11:32:32 -05:00
Adam Honse 12226804f3 Rename small to medium for Cooler Master MP750 2020-06-22 11:23:26 -05:00
Adam Honse f06d71bd0c Add Cooler Master MP750 small variant PID 2020-06-22 08:59:42 -05:00
Adam Honse 112d5a1cb2 Add Corsair Strafe IDs to detection list 2020-06-22 08:47:46 -05:00
Martin Hartl b70658e37d Asus USB: Fail detection if config table read fails 2020-06-21 20:24:52 -05:00
Adam Honse 80a2770263 Update Corsair peripheral controller to use HID writes and reads instead of feature reports where possible 2020-06-21 20:11:16 -05:00
Erik Karlsson 765ef62858 Add SteelSeries Siberia 350 2020-06-21 19:18:38 -05:00
Matthias Wirtz 0e58fcc236 Update AuraUSBControllerDetect.cpp 2020-06-21 01:45:42 -05:00
Adam Honse 4bf0330974 Fix mode colors in Corsair Lighting Node controller 2020-06-20 22:14:30 -05:00
Térence Clastres 6d585d3eeb Network: Print used port on startup and change default to 6742
Also print an error if server can't be started

1337 is already used by razer's rest server
Port idea by @bahorn (6742 = ORGB on a phone numpad)
2020-06-20 14:39:14 -05:00
Térence Clastres 0286a5dd58 CLI: Add daemon/server mode 2020-06-20 14:39:01 -05:00
Térence Clastres b3cadbae5d Fix CLI
It was not changing the colors since e3e6c034 and had an overflow on
`options->devices.size()` since 0f4ddd16 causing options not to be applied

Second issue was a bit trickier as it was not reproducable when using a
debug build. It seemed like `std::vector<DeviceOptions> devices` had an
overflow. I saw a bunch of warnings regarding comparison with implicit
cast so I figured I'd fix that first and see if it makes a difference.
Turns out it did and fixed the issue.

While toying around, I also noticed that `throw` didn't seem to work,
causing crashes later in the program. It turns out the catch-all clause
`catch (...)` is not necessary matching a `throw NULL` expression as it
might be of type `int`. The solution is to use `thrown nullptr;`
instead.

Reference: https://en.cppreference.com/w/cpp/language/try_catch
2020-06-19 16:46:57 -05:00
Adam Honse e26e874d1c Fix file that didn't get renamed 2020-06-19 16:34:51 -05:00
Adam Honse c9c214267d Update matrix map to fix offsets and add ISO layout keys to the matrix. ENTER was shifted right one column to account for ISO #/~ key 2020-06-19 15:18:52 -05:00
Adam Honse 6957c1ca03 Add link to OpenRGB.NET project by diogotr7 to README 2020-06-19 14:51:37 -05:00
Diogo Trindade f5aafda340 Added logitech g512 PID 2020-06-19 14:41:14 -05:00
Adam Honse f1fe428f59 Rename Hue2Controller to NZXTHue2Controller and add additional Hue 2 protocol devices documented in liquidctl 2020-06-19 14:41:09 -05:00
Thomas Karl Pietrowski 614c9768ad Needed changes for nightly builds on launchpad.net
Signed-off-by: Thomas Karl Pietrowski <[email protected]>
2020-06-19 08:35:43 -05:00
Adam Honse 5828c4df8d Add Debian packaging files 2020-06-19 08:35:26 -05:00
Adam Honse 6cf32b8a94 Remove icon extension in desktop file 2020-06-18 21:51:51 -05:00
B Horn bc6487505a Adding scripts and tooling to build an AppImage 2020-06-18 21:36:59 -05:00
Diogo Trindade d1e8104442 Added missing g810 keys and PID 2020-06-18 11:48:33 -05:00
Adam Honse 91414084d6 Move Off mode to second position in MSI Mystic Light mode list so that custom mode works 2020-06-18 10:50:25 -05:00
Adam Honse 372ff746ad Add SteelSeries Rival 300 Black Ops edition to PID detecton list 2020-06-18 09:47:39 -05:00
Adam Honse ab297281d3 Fix Blackwidow 2019 string in OpenRazer device list 2020-06-17 03:26:22 -05:00
Adam Honse 2cbba19bf9 Code style changes to MSI Mystic Light detection, use the same hidapi detection code as used by other drivers 2020-06-16 17:21:35 -05:00
Adam Honse b5001c983e Add RGB Fusion 2 USB to udev rules 2020-06-16 13:47:14 -05:00
Adam Honse 7d4d6152ab Add OpenRGB E1.31 Receiver to SDK projects list 2020-06-15 22:46:51 -05:00
Adam Honse f2c1022c7f Don't consider client online until it has been initialized 2020-06-15 22:41:33 -05:00
Adam Honse 771e362a63 Do not automatically refresh HyperX direct mode unless it has been 50ms since last device update to prevent flickering 2020-06-15 11:04:59 -05:00
Adam Honse 3eba2c3dd3 Add underglow zone for Razer Huntsman Elite 2020-06-14 15:57:50 -05:00
Adam Honse 305f66ad3d Treat the LED strip on the Razer Diamondback as a single zone 2020-06-14 14:14:12 -05:00
Adam Honse 3191a87f46 Update README 2020-06-13 19:45:59 -05:00
Adam Honse a9493d46aa Implement LED packing for Logitech G810 direct mode 2020-06-13 17:32:39 -05:00
Adam Honse 6499ee4312 Add Logitech G810 direct mode, LED list, and matrix keymap. Update function still needs optimization to pack multiple keys per packet 2020-06-13 16:51:20 -05:00
Adam Honse f26897df71 Fix Logitech G810 controller build on Linux 2020-06-12 19:49:04 -05:00
Adam Honse 8ae07ea9e2 Logitech G810 Orion Spectrum driver, does not include direct mode yet 2020-06-12 15:23:22 -05:00
Adam Honse cb94b4fe28 Update .gitignore 2020-06-11 08:31:51 -05:00
Adam Honse f51f222fb4 Initialize color modes for per-LED modes on Aura Core controller 2020-06-10 18:58:00 -05:00
Swyter d3162ea2e8 Initial version of the MSVC/Qt5 GitLab buildbot. On Windows also copy inpoutx64.dll and libusb-1.0.dll to the final destination and use intermediate build folders to get rid of the cruft. 2020-06-10 18:32:40 -05:00
Adam Honse fa1f0b05ce Initialize i2c start and done flags 2020-06-10 11:42:28 -05:00
Adam Honse c7bb002b7c Add Aura X570 interface number workaround to libusb DLLs
Source for my libusb fork can be found on GitHub:

https://github.com/CalcProgrammer1/libusb
2020-06-10 09:43:30 -05:00
crashniels b1de039f21 Finished up all the modes 2020-06-07 18:05:29 -05:00
Adam Honse e086ecd0bb Fix wheel color changing when setting all devices 2020-06-07 18:01:48 -05:00
Adam Honse f612ca8bdc Fix bug with ColorWheel updating 2020-06-07 17:58:55 -05:00
Adam Honse 5b8441c57d Initial implementation of RGB Fusion 2 DRAM controller 2020-06-07 15:49:28 -05:00
Adam Honse 919d89d52f Update Redragon M711 controller with generic write function 2020-06-03 21:48:17 -05:00
crashniels 479d51df87 AMD ADL Windows 2020-06-02 20:39:26 -05:00
Adam Honse 687424e732 Rename Glorious Model 0 detection file 2020-06-02 17:35:22 -05:00
crashniels a2a613f22d use hidapi instead of libusb 2020-06-02 17:34:01 -05:00
crashniels a34d0f93a3 Added most modes in 2020-06-02 17:31:14 -05:00
crashniels 8e62be0b9e Added the Model O 2020-06-02 17:31:02 -05:00
vinno97 95bcc5e0fd Add pkgconf to the dependencies in the README
If the `pkg-config` command cannot be found, `packagesExist(...) {...} else {...}` always chooses the 'else' branch.
2020-06-02 17:11:04 -05:00
Chris 19ef8afe70 Updated controller to use HIDAPI instead of LIBUSB
& added code to pass back info from the USB device
2020-06-02 17:08:29 -05:00
Adam Honse 5fdea9d34f Delete zone matrix maps when destroying RGBController 2020-05-31 19:36:01 -05:00
Adam Honse 32938ec2af Add sleep to OpenRazer driver to fix hangs updating certain devices 2020-05-31 16:20:35 -05:00
Adam Honse 8d29a40954 Convert Corsair Lighting Node driver to use hidapi instead of libusb 2020-05-30 23:48:59 -05:00
Adam Honse a75a2bbf8b Update README udev rules section 2020-05-30 13:44:53 -05:00
Adam Honse f96a4c3557 Fix incorrect PID in Corsair Peripheral driver and add udev rules file for all OpenRGB devices 2020-05-30 13:26:54 -05:00
Adam Honse 1d426f109a Convert AMD Wraith Prism driver to use hidapi instead of libusb 2020-05-29 16:21:05 -05:00
Adam Honse 8827d0e0c2 Convert Hue 2 driver to use hidapi instead of libusb 2020-05-29 13:19:16 -05:00
Adam Honse edfb4f8d4e Update app screenshot in README 2020-05-29 11:02:31 -05:00
Adam Honse 13ce388e9a Convert Thermaltake Riing driver to use hidapi instead of libusb 2020-05-28 23:16:20 -05:00
Adam Honse 316902b2c3 Fix Steelseries path 2020-05-28 22:47:50 -05:00
B Horn 6667cdeed9 Rival 300 should now be properly intergrated with the RGBController. 2020-05-28 17:04:09 -05:00
B Horn de44c57081 Added all the PIDs for the various Rival 300 Mouses 2020-05-28 17:00:12 -05:00
B Horn 30a1bc9893 fixing bug that would stop the mouse from updating color 2020-05-28 16:57:20 -05:00
B Horn cf4b421abd Early work on enabling support for the Rival 300. 2020-05-28 16:56:01 -05:00
B Horn 1a9e1c2430 List all the devices types in the switch statement 2020-05-28 16:50:34 -05:00
B Horn bde9e7ea6b Adding list of devices this should support currently (all the 100-series rival mouses) 2020-05-28 16:49:57 -05:00
B Horn fc9c6585af Modified the SteelSeries RGB Controller to read the device name. 2020-05-28 16:47:07 -05:00
B Horn be9711a021 First working version to support the Rival 110 mouse 2020-05-28 16:44:46 -05:00
Adam Honse bfa7f63486 Add hidapi dependency to readme 2020-05-27 23:24:01 -05:00
Adam Honse 8f19267886 Use hidraw backend for hidapi if available 2020-05-27 23:19:03 -05:00
Adam Honse fab6e41810 Fix uninitialized loop counter in AuraUSB controller 2020-05-27 11:17:21 -05:00
Adam Honse c3ceac1ed9 Add more MacOS project definitions 2020-05-26 01:44:39 -05:00
Adam Honse bb01790d71 Add MacOS libraries and paths to project file 2020-05-26 01:25:46 -05:00
Adam Honse 9cf7bdea29 Use system hidapi on Linux 2020-05-26 00:21:10 -05:00
Adam Honse 6da6ff6cc0 Reorganize Qt project file and add section for MacOS configuration 2020-05-25 20:21:22 -05:00
Adam Honse baa04913c3 Add headset stand type string 2020-05-25 16:45:58 -05:00
Adam Honse 64c0861097 Move icon lookup to its own function for reusability 2020-05-25 16:41:56 -05:00
Adam Honse 522016137b Razer Base Station Chroma is a headset stand 2020-05-25 14:06:11 -05:00
Adam Honse 40d0f17ae2 Update icons 2020-05-25 13:57:04 -05:00
Adam Honse c88e71d52a Add device table to HyperX keyboard detection code 2020-05-24 16:16:52 -05:00
Adam Honse c3d284c97b Add speed control to Logitech G203 2020-05-24 15:10:20 -05:00
Adam Honse 19b572da30 Fix Polychrome controller detection 2020-05-24 14:18:07 -05:00
Martin Hartl e6c4017ad0 Add Logitech G403 driver 2020-05-24 14:04:07 -05:00
Martin Hartl b862912fb1 NZXT Kraken: Rewrite to use hidapi 2020-05-24 12:35:03 -05:00
Adam Honse 02f7f57130 Fix BlackWidow Elite string 2020-05-18 17:55:49 -05:00
Adam Honse c6b3d7c675 Add matrix mapping for Redragon keyboards 2020-05-18 17:35:33 -05:00
Adam Honse 1b2a5a4b14 Add Redragon K552 Kumara to Redragon device list 2020-05-18 16:24:37 -05:00
Adam Honse c0190d35d1 Logitech G203 requires a read after writing 2020-05-18 11:12:29 -05:00
Adam Honse 4d0219b184 Add Tecware Phantom Elite to Redragon driver as it uses the same controller 2020-05-18 10:24:10 -05:00
Adam Honse 85fc72232a Logitech G203 and Corsair ST100 support 2020-05-18 09:45:38 -05:00
Adam Honse cbb13b0d22 Add MacOS support to NetworkClient.cpp 2020-05-16 23:33:49 -07:00
Adam Honse bd6ec4c41e Get client stop function working 2020-05-14 10:06:22 -05:00
Martin Hartl d843b3d619 Aura USB: Do effect changes only once
* Improve the zone naming
2020-05-13 18:41:00 -05:00
Martin Hartl ca9c40f084 Aura USB: Addressable header and direct mode fixes
* Add addressable header and integrated LED count detection
* Correctly use the direct mode
2020-05-13 18:24:23 -05:00
Adam Honse 6a85729f10 Increment version number post-release 2020-05-12 16:35:34 -05:00
Adam Honse 13414ec9b8 OpenRGB version 0.2 2020-05-12 16:33:41 -05:00
Adam Honse 74faee0f73 Reorder Thermaltake Riing modes to put direct at top 2020-05-12 16:04:52 -05:00
Adam Honse 3f0027aa90 Use byte index 2 of config table for channel count on addressable Aura controllers 2020-05-12 15:58:00 -05:00
Adam Honse d22aa1ed6c Only allow ASRock firmwares 1.x, 2.x, and 3.x for now 2020-05-12 15:11:11 -05:00
Adam Honse 23d51f65d0 Only update mode for zones with nonzero size 2020-05-12 15:02:02 -05:00
Adam Honse cad356efca Remove hard coded list of Polychrome firmware versions as it seems all firmwares 1.x and 2.x use ASR LED protocol and 3.x+ use Polychrome 2020-05-12 14:46:11 -05:00
Adam Honse 70e83c13cc Attempt to auto detect unknown Polychrome firmware versions 2020-05-12 13:39:14 -05:00
Martin Hartl 7ca0a1b6ab Add Aura USB controller for X570 mainboards 2020-05-12 12:25:02 -05:00
Adam Honse 9bd5536d07 Add ASR LED firmware 1.5 2020-05-12 12:06:34 -05:00
Adam Honse eaa3b9a368 Add command line option to enable i2c tools 2020-05-12 11:01:46 -05:00
Adam Honse 599c468de8 Small changes for 0.2 - report 5 channels from Aura Addressable controller until config table is figured out, increase sleep in Corsair Peripheral write to 2ms to prevent device crashing in Linux 2020-05-12 08:59:19 -05:00
Adam Honse 9f21814395 Code style changes for RGB Fusion 2 SMBus 2020-05-11 12:24:25 -05:00
Adam Honse cb8a551683 Disable RGB Fusion 2 SMBus controller until better detection scheme is implemented 2020-05-11 11:43:42 -05:00
Matt Harper 7f1156d81c Rename UpdateLEDs to DeviceUpdateLEDs 2020-05-11 11:40:34 -05:00
Matt Harper 5beee08166 Write only the absolutely necessary LEDs 2020-05-11 11:40:34 -05:00
Matt Harper 1334129078 Additional protocol options 2020-05-11 11:40:34 -05:00
Matt Harper 216b492f24 Const cleanup, fix behavioral bugs by writing all LEDs every time 2020-05-11 11:40:34 -05:00
Matt Harper 1b65bb9cc3 Rudimentary RGB Fusion 2 SMBus support 2020-05-11 11:40:34 -05:00
Adam Honse 0f4ddd164f RGB Fusion 2 SMBus initial work 2020-05-11 11:40:33 -05:00
Adam Honse e6aadc414b Handle socket errors on Windows, which does not return 0 when a socket is disconnected like Linux does 2020-05-10 16:22:29 -05:00
Adam Honse 883a78ad9d Fix client on Windows 2020-05-10 16:16:59 -05:00
Adam Honse 15d23d3009 Add client status update callback to NetworkClient 2020-05-10 13:41:01 -05:00
Adam Honse e2c2b8c1df Client will now close listener thread when disconnected and attempt to reconnect. Initialization behavior (controller requests, client string update) are performed automatically upon reconnection 2020-05-10 01:19:38 -05:00
Adam Honse 5133c30242 Update BlackWidow V2 device string 2020-05-09 18:21:46 -05:00
Matt Harper 69e1e19bf9 Bugfix - properly free ServerClients 2020-05-09 17:30:54 -05:00
Adam Honse 46f08f7423 Disable SMBus tools again 2020-05-09 15:49:47 -05:00
Adam Honse 352b9928ca Add file headers to network files and some minor code cleanup 2020-05-09 15:48:16 -05:00
Adam Honse 87854d5781 Fix crash when stopping server 2020-05-09 15:48:16 -05:00
Adam Honse 1b3f8f9eb4 Clean up server page 2020-05-09 15:48:16 -05:00
Adam Honse 6438c15dd3 Fix build on Windows 2020-05-09 15:48:16 -05:00
Adam Honse dbe29991f0 Send client string after server is connected 2020-05-09 15:48:15 -05:00
Adam Honse a5e9a3de05 Add mutex on updating callbacks 2020-05-09 15:48:15 -05:00
Adam Honse edf1b251c0 Send and receive client string 2020-05-09 15:48:15 -05:00
Adam Honse 9ff4314840 Add callback to NetworkServer to handle UI updates when client information changes 2020-05-09 15:48:15 -05:00
Adam Honse 3ad0986ae7 Add IP field to client information and display client IP in the server tab's connected client list 2020-05-09 15:48:15 -05:00
Adam Honse 6bfc9dd9db Create a structure to hold client information in the network server and fix i2c hanging on destructor when bus is not available. 2020-05-09 15:48:15 -05:00
Adam Honse 9b8a0d465e Functions to set IP and port and start client 2020-05-09 15:48:15 -05:00
Adam Honse 119741b736 Fix build on Windows 2020-05-09 15:48:15 -05:00
Adam Honse 2fe958783c Use select on accept call as well so that server closes on Linux 2020-05-09 15:48:15 -05:00
Adam Honse 1c59ef6b80 Fix build on Linux 2020-05-09 15:48:15 -05:00
Adam Honse 9e44e4ba4f Add server information to user interface and provide buttons to start and stop server, change port 2020-05-09 15:48:15 -05:00
Adam Honse b8e14ea067 Server info WIP 2020-05-09 15:48:14 -05:00
Adam Honse 525071c205 Use condition variables and mutexes to eliminate sleeps from SMBus threading 2020-05-09 15:48:14 -05:00
Adam Honse bfe03b0564 Handle all SMBus controller activity on a separate thread to avoid corrupting the SMBus data 2020-05-09 15:48:14 -05:00
Adam Honse 04b87ce2eb Use std::thread for NetworkClient threads 2020-05-09 15:48:14 -05:00
Adam Honse 81acc47cd6 Use std::thread for NetworkServer threads 2020-05-09 15:48:14 -05:00
Adam Honse 6e426b1403 Fix thread conflicts for HyperX keyboard in Direct mode 2020-05-09 15:48:14 -05:00
Adam Honse 6509e53a9b Disable I2C devices until threading issues are resolved, don't start a NetworkClient in main 2020-05-09 15:48:14 -05:00
Adam Honse 5b42b3d11d Use TCP_NODELAY on client socket 2020-05-09 15:48:14 -05:00
Adam Honse 8bd515296d Add key matrix map for Corsair K70 keyboards 2020-05-09 15:48:14 -05:00
Adam Honse 2bbf66c0ee Fix memory leaks in client 2020-05-09 15:48:14 -05:00
Adam Honse d716973642 Get network client working on Windows 2020-05-09 15:48:14 -05:00
Adam Honse 25f7a87a79 Get network server working in Windows 2020-05-09 15:48:14 -05:00
Adam Honse 0619a16be2 Add matrix map for HyperX Alloy Elite 2020-05-09 15:48:13 -05:00
Adam Honse 4a3802f344 Add matrix map for Poseidon Z RGB keyboard 2020-05-09 15:48:13 -05:00
Adam Honse 105f5642ef Add matrix map support 2020-05-09 15:48:13 -05:00
Adam Honse 54ab57cea6 Add zone types to HyperX and Poseidon Z RGB keyboard controllers 2020-05-09 15:48:13 -05:00
Adam Honse e3e6c0347e Add a thread to RGBController to asynchronously perform device updates. Only implemented for UpdateLEDs for now 2020-05-09 15:48:13 -05:00
Adam Honse 4d6706ce61 Close server listener thread when read returns zero (client connection lost) 2020-05-09 15:48:13 -05:00
Adam Honse 39c5aff864 Send color data over the network when calling color update functions 2020-05-09 15:48:13 -05:00
Adam Honse 450f438538 Send mode data block when updating mode 2020-05-09 15:48:13 -05:00
Adam Honse 0270c745ce Implement RGBController_Network packet sending for current set of RGBController commands 2020-05-09 15:48:13 -05:00
Adam Honse e2dfcd5b0f Client now requests list of all controllers from server and adds them to the master list 2020-05-09 15:48:13 -05:00
Adam Honse 68fa3c2def Create functions for sending replies 2020-05-09 15:48:13 -05:00
Adam Honse cde7469191 Create functions for sending requests 2020-05-09 15:48:13 -05:00
Adam Honse 7c1a1396ca Client requests controller count and first controller data block from server, prints response 2020-05-09 15:48:13 -05:00
Adam Honse 7f052f21aa Run client from main 2020-05-09 15:48:12 -05:00
Adam Honse dff667751b Start work on network client 2020-05-09 15:48:12 -05:00
Adam Honse 2625807c1a Add RGBController function call packet functionality 2020-05-09 15:48:12 -05:00
Adam Honse 7af283fdbf Implement requests for number of controllers and controller information block 2020-05-09 15:48:12 -05:00
Adam Honse c7ffe3b926 Network server can now receive packets properly 2020-05-09 15:48:12 -05:00
Adam Honse 46339c5f86 More work on network support, need to implement spawning of one read thread for each client socket 2020-05-09 15:48:12 -05:00
Adam Honse cf69598fd1 Start working on server request processing code 2020-05-09 15:48:12 -05:00
Adam Honse 594f66ab23 Initial network files 2020-05-09 15:48:12 -05:00
Adam Honse 01e0808e41 Add 1ms sleep after every Corsair peripheral USB message because K70 RGB locks up on Linux otherwise 2020-05-04 17:02:39 -05:00
289 changed files with 23955 additions and 3226 deletions
+7
View File
@@ -1 +1,8 @@
*.pro.user*
*.o
ui_*
moc_*
qrc_*
OpenRGB
Makefile
OpenRGB-x86_64.AppImage
+181
View File
@@ -0,0 +1,181 @@
# swy: some useful references; the MSVC part of the CI script is based on the one from bind9, by Michał Kępień:
# https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/gcp/windows-containers/blob/master/cookbooks/preinstalled-software/README.md
# https://gitlab.isc.org/isc-projects/bind9/commit/facc6a051fcac70fbbc61cb92a37be8c3e4db5ec#587d266bb27a4dc3022bbed44dfa19849df3044c_718_731
# https://www.kittell.net/code/powershell-unix-sed-equivalent-change-text-file/
# https://powershell.org/forums/topic/how-to-use-ansi-vt100-formatting-in-powershell-ooh-pretty-colors/
#-----------------------------------------------------------------------#
# OpenRGB GitLab CI Configuration #
#-----------------------------------------------------------------------#
.shared_windows_runners:
tags:
- shared-windows
- windows
- windows-1809
stages:
- build
before_script:
- echo "started by ${GITLAB_USER_NAME}"
#-----------------------------------------------------------------------#
# Linux (AppImage) Build Target #
#-----------------------------------------------------------------------#
build_linux:
image: ubuntu:bionic
stage: build
script:
- apt update
- apt install -y build-essential qtcreator qt5-default libusb-1.0-0-dev libhidapi-dev pkgconf wget git
- ./scripts/build-appimage.sh
artifacts:
paths:
- OpenRGB-x86_64.AppImage
expire_in: 1337 years
#-----------------------------------------------------------------------#
# Windows (32-bit) Build Target #
#-----------------------------------------------------------------------#
build_windows_32:
extends:
- .shared_windows_runners
stage: build
script:
- $esc = "$([char]27)"
- $count = 0
- function _unix_tmsec_ { [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalSeconds }
- function _fold_start_ { param( [string]$TEXT_TAG ) $t=_unix_tmsec_; $global:count += 1; Write-Host -NoNewLine "`r`n`r`nsection_start:${t}:sect_${count}`r${esc}[0K${esc}[33m${TEXT_TAG}${esc}[39m`r`n"; }
- function _fold_final_ { $t=_unix_tmsec_; Write-Host -NoNewLine "`r`n`r`nsection_end:${t}:sect_${count}`r${esc}[0K`r`n" ; }
- _fold_start_ 'configuring the msvc environment variables'
- Push-Location "C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Auxiliary/Build"
- '& cmd.exe /C "vcvarsall.bat x86 & set" | Foreach-Object { if ($_ -match "(.*?)=(.*)") { Set-Item -force -path "Env:\$($matches[1])" -value "$($matches[2])" } }'
- Pop-Location
- _fold_final_
- _fold_start_ 'downloading precompiled versions of qtbase, qttools (for windeployqt) and jom (for a more parallel nmake)'
- mkdir _qt
- mkdir _qt_download
- Push-Location _qt_download
- curl.exe -LJ -o qt-base.7z 'https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win32_msvc2019/5.15.0-0-202005150700qtbase-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86.7z'
- curl.exe -LJ -o qt-tools.7z 'https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win32_msvc2019/5.15.0-0-202005150700qttools-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86.7z'
- curl.exe -LJ -o qt-jom.zip 'https://download.qt.io/official_releases/jom/jom.zip'
- _fold_final_
- _fold_start_ 'extracting the downloaded qt binaries'
- 7z x qt-base.7z '-o../_qt' -y
- 7z x qt-tools.7z '-o../_qt' -y
- 7z x qt-jom.zip '-o../_qt' -y
- _fold_final_
- _fold_start_ 'turn the qt install from enterprise to foss; remove the licensing checks'
- ${qconfig-pri-folder} = '..\_qt\5.15.0\msvc2019\mkspecs\qconfig.pri'
- (Get-Content ${qconfig-pri-folder}).replace('QT_EDITION = Enterprise', 'QT_EDITION = OpenSource') | Set-Content ${qconfig-pri-folder}
- (Get-Content ${qconfig-pri-folder}).replace('QT_LICHECK = licheck.exe', '') | Set-Content ${qconfig-pri-folder}
- Pop-Location
- _fold_final_
- _fold_start_ 'run qmake and generate the msvc nmake makefile'
- mkdir _build; cd _build
- ..\_qt\5.15.0\msvc2019\bin\qmake ..\OpenRGB.pro
- _fold_final_
- _fold_start_ 'start the actual build with jom instead of nmake; for speed'
- ..\_qt\jom
- _fold_final_
- _fold_start_ 'run windeployqt to automatically copy the needed dll files'
- ..\_qt\5.15.0\msvc2019\bin\windeployqt --no-angle --no-translations --no-opengl-sw --no-system-d3d-compiler --no-compiler-runtime --no-webkit2 .\release\
- _fold_final_
- _fold_start_ 'compressing the release folder so that we can upload it as artifact'
- mv release 'OpenRGB Windows 32-bit'
- ${datetime} = Get-Date ([datetime]::UtcNow) -Format "yyyy-MM-ddTHH-mm-ss"
- ${revision} = ((git rev-parse --short HEAD) | Out-String).Trim()
- ${rversion} = (((Get-Content '..\OpenRGB.pro' | Select-String -Pattern "VERSION =") | Out-String).Trim().Split("="))[1].Trim()
- 7z a -mx9 -r -y "OpenRGB_${rversion}_32_${revision}_nightly_${datetime}.7z" 'OpenRGB Windows 32-bit'
- _fold_final_
# cache:
# key: same-key
# paths:
# - C:\vcpkg\installed\
artifacts:
paths:
- _build/*.7z
expire_in: 1337 years
#-----------------------------------------------------------------------#
# Windows (64-bit) Build Target #
#-----------------------------------------------------------------------#
build_windows_64:
extends:
- .shared_windows_runners
stage: build
script:
- $esc = "$([char]27)"
- $count = 0
- function _unix_tmsec_ { [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalSeconds }
- function _fold_start_ { param( [string]$TEXT_TAG ) $t=_unix_tmsec_; $global:count += 1; Write-Host -NoNewLine "`r`n`r`nsection_start:${t}:sect_${count}`r${esc}[0K${esc}[33m${TEXT_TAG}${esc}[39m`r`n"; }
- function _fold_final_ { $t=_unix_tmsec_; Write-Host -NoNewLine "`r`n`r`nsection_end:${t}:sect_${count}`r${esc}[0K`r`n" ; }
- _fold_start_ 'configuring the msvc environment variables'
- Push-Location "C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Auxiliary/Build"
- '& cmd.exe /C "vcvarsall.bat x64 & set" | Foreach-Object { if ($_ -match "(.*?)=(.*)") { Set-Item -force -path "Env:\$($matches[1])" -value "$($matches[2])" } }'
- Pop-Location
- _fold_final_
- _fold_start_ 'downloading precompiled versions of qtbase, qttools (for windeployqt) and jom (for a more parallel nmake)'
- mkdir _qt
- mkdir _qt_download
- Push-Location _qt_download
- curl.exe -LJ -o qt-base.7z 'https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win64_msvc2019_64/5.15.0-0-202005150700qtbase-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86_64.7z'
- curl.exe -LJ -o qt-tools.7z 'https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win64_msvc2019_64/5.15.0-0-202005150700qttools-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86_64.7z'
- curl.exe -LJ -o qt-jom.zip 'https://download.qt.io/official_releases/jom/jom.zip'
- _fold_final_
- _fold_start_ 'extracting the downloaded qt binaries'
- 7z x qt-base.7z '-o../_qt' -y
- 7z x qt-tools.7z '-o../_qt' -y
- 7z x qt-jom.zip '-o../_qt' -y
- _fold_final_
- _fold_start_ 'turn the qt install from enterprise to foss; remove the licensing checks'
- ${qconfig-pri-folder} = '..\_qt\5.15.0\msvc2019_64\mkspecs\qconfig.pri'
- (Get-Content ${qconfig-pri-folder}).replace('QT_EDITION = Enterprise', 'QT_EDITION = OpenSource') | Set-Content ${qconfig-pri-folder}
- (Get-Content ${qconfig-pri-folder}).replace('QT_LICHECK = licheck.exe', '') | Set-Content ${qconfig-pri-folder}
- Pop-Location
- _fold_final_
- _fold_start_ 'run qmake and generate the msvc nmake makefile'
- mkdir _build; cd _build
- ..\_qt\5.15.0\msvc2019_64\bin\qmake ..\OpenRGB.pro
- _fold_final_
- _fold_start_ 'start the actual build with jom instead of nmake; for speed'
- ..\_qt\jom
- _fold_final_
- _fold_start_ 'run windeployqt to automatically copy the needed dll files'
- ..\_qt\5.15.0\msvc2019_64\bin\windeployqt --no-angle --no-translations --no-opengl-sw --no-system-d3d-compiler --no-compiler-runtime --no-webkit2 .\release\
- _fold_final_
- _fold_start_ 'compressing the release folder so that we can upload it as artifact'
- mv release 'OpenRGB Windows 64-bit'
- ${datetime} = Get-Date ([datetime]::UtcNow) -Format "yyyy-MM-ddTHH-mm-ss"
- ${revision} = ((git rev-parse --short HEAD) | Out-String).Trim()
- ${rversion} = (((Get-Content '..\OpenRGB.pro' | Select-String -Pattern "VERSION =") | Out-String).Trim().Split("="))[1].Trim()
- 7z a -mx9 -r -y "OpenRGB_${rversion}_64_${revision}_nightly_${datetime}.7z" 'OpenRGB Windows 64-bit'
- _fold_final_
# cache:
# key: same-key
# paths:
# - C:\vcpkg\installed\
artifacts:
paths:
- _build/*.7z
expire_in: 1337 years
+262
View File
@@ -0,0 +1,262 @@
#---------------------------------------------------------------#
# OpenRGB udev rules #
# #
# Adam Honse (CalcProgrammer1) 5/29/2020 #
#---------------------------------------------------------------#
#---------------------------------------------------------------#
# User I2C/SMBus Access #
#---------------------------------------------------------------#
KERNEL=="i2c-[0-99]*", TAG+="uaccess"
#---------------------------------------------------------------#
# User hidraw Access #
#---------------------------------------------------------------#
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", TAG+="uaccess"
#---------------------------------------------------------------#
# AMD Wraith Prism #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0051", TAG+="uaccess"
#---------------------------------------------------------------#
# ASUS Aura Core Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1854", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1869", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1866", TAG+="uaccess"
#---------------------------------------------------------------#
# ASUS Aura USB Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1867", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1872", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1889", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18a3", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18f3", TAG+="uaccess"
#---------------------------------------------------------------#
# Cooler Master Peripheral Devices #
# #
# Mousemats: #
# Cooler Master MP750 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0109", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Lighting Node Devices #
# #
# Corsair Lighting Node Core #
# Corsair Lighting Node Pro #
# Corsair Commander Pro #
# Corsair LS100 #
# Corsair 1000D Obsidian #
# Corsair Spec Omega RGB #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c1a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c0b", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c10", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c1e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1d00", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1d04", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Peripheral Devices #
# #
# Keyboards: #
# Corsair K55 RGB #
# Corsair K65 RGB #
# Corsair K65 RGB Lux #
# Corsair K65 RGB Rapidfire #
# Corsair K68 RGB #
# Corsair K70 RGB #
# Corsair K70 RGB Lux #
# Corsair K70 RGB Rapidfire #
# Corsair K70 RGB MK2 #
# Corsair K70 RGB MK2 SE #
# Corsair K70 RGB MK2 LP #
# Corsair K95 RGB #
# Corsair K95 Platinum #
# Corsair Strafe #
# Corsair Strafe MK2 #
# #
# Mice: #
# Corsair M65 Pro #
# Corsair M65 RGB Elite #
# #
# Mousemats: #
# Corsair MM800 RGB Polaris #
# #
# Headset Stands: #
# Corsair ST100 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3d", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b17", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b37", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b39", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b4f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b13", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b33", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b38", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b49", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b6b", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b55", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b11", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2d", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b20", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b48", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b5a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3b", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0a34", TAG+="uaccess"
#---------------------------------------------------------------#
# HyperX Peripheral Devices #
# #
# Keyboards: #
# HyperX Alloy Elite #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16be", TAG+="uaccess"
#---------------------------------------------------------------#
# Logitech Peripheral Devices #
# #
# Mice: #
# Logitech G203 Prodigy #
# Logitech G403 Prodigy #
# Logitech G403 Hero #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c084", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c083", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08f", TAG+="uaccess"
#---------------------------------------------------------------#
# MSI Mysticlight #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="3EA4", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="4559", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B10", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B93", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B94", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B96", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C34", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C35", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C36", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C37", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C42", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C56", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C59", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C60", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C67", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C70", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C71", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C73", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C75", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C76", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C77", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C79", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C80", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C81", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C82", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C83", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C84", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C85", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C86", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C87", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C88", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C89", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C90", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C91", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C92", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C94", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C95", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C96", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C98", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C99", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="905D", TAG+="uaccess"
#---------------------------------------------------------------#
# MSI/SteelSeries 3-Zone Laptop Keyboard #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1770", ATTR{idProduct}=="FF00", TAG+="uaccess"
#---------------------------------------------------------------#
# NZXT Hue 2 Devices #
# #
# NZXT Hue 2 #
# NZXT Smart Device V2 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2001", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2006", TAG+="uaccess"
#---------------------------------------------------------------#
# NZXT Kraken #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="170e", TAG+="uaccess"
#---------------------------------------------------------------#
# Redragon Peripheral Devices #
# #
# Keyboards: #
# Redragon K550 Yama #
# Redragon K552 Kumara #
# Redragon K556 Devarajas #
# Tecware Phantom Elite #
# #
# Mice: #
# Redragon M711 Cobra #
# Redragon M715 Dagger #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="5204", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="5104", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="5004", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="652f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc30", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc39", TAG+="uaccess"
#---------------------------------------------------------------#
# Gigabyte/Aorus RGB Fusion 2 USB #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="048d", ATTR{idProduct}=="8297", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="048d", ATTR{idProduct}=="5702", TAG+="uaccess"
#---------------------------------------------------------------#
# SteelSeries Peripheral Devices #
# #
# Mice: #
# SteelSeries Rival 100 #
# SteelSeries Rival 100 DotA 2 Edition #
# SteelSeries Rival 105 #
# SteelSeries Rival 110 #
# SteelSeries Rival 300 #
# Acer Predator Gaming Mouse (Rival 300) #
# SteelSeries Rival 300 CS:GO Fade Edition #
# SteelSeries Rival 300 CS:GO Fade Edition (stm32) #
# SteelSeries Rival 300 CS:GO Hyperbeast Edition #
# SteelSeries Rival 300 Dota 2 Edition #
# SteelSeries Rival 300 HP Omen Edition #
# Headsets: #
# SteelSeries Siberia 350 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1702", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="170c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1814", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1729", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1384", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1714", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1394", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1716", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="171a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1392", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1718", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1229", TAG+="uaccess"
#---------------------------------------------------------------#
# Thermaltake Poseidon Z RGB Keyboard #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="3006", TAG+="uaccess"
@@ -12,7 +12,7 @@
#include <stdio.h>
#include <stdlib.h>
AMDWraithPrismController::AMDWraithPrismController(libusb_device_handle* dev_handle)
AMDWraithPrismController::AMDWraithPrismController(hid_device* dev_handle)
{
dev = dev_handle;
@@ -49,6 +49,7 @@ std::string AMDWraithPrismController::GetEffectChannelString(unsigned char chann
unsigned char usb_buf[] =
{
0x00,
0x40, 0x21, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
@@ -67,12 +68,10 @@ std::string AMDWraithPrismController::GetEffectChannelString(unsigned char chann
0x00, 0x00, 0x00, 0x00,
};
int actual;
usb_buf[0x03] = channel;
usb_buf[0x02] = channel;
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
ret_string.append((char *)&usb_buf[0x08]);
@@ -85,6 +84,7 @@ std::string AMDWraithPrismController::GetFirmwareVersionString()
unsigned char usb_buf[] =
{
0x00,
0x12, 0x20, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
@@ -103,11 +103,10 @@ std::string AMDWraithPrismController::GetFirmwareVersionString()
0x00, 0x00, 0x00, 0x00,
};
int actual;
unsigned char fw_buf[16] = {0x00};
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
for(int char_idx = 0; char_idx < 16; char_idx+=2)
{
@@ -209,6 +208,7 @@ void AMDWraithPrismController::SendEnableCommand()
{
unsigned char usb_buf[] =
{
0x00,
0x41, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
@@ -227,16 +227,15 @@ void AMDWraithPrismController::SendEnableCommand()
0x00, 0x00, 0x00, 0x00,
};
int actual;
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
}
void AMDWraithPrismController::SendApplyCommand()
{
unsigned char usb_buf[] =
{
0x00,
0x51, 0x28, 0x00, 0x00,
0xE0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
@@ -255,10 +254,8 @@ void AMDWraithPrismController::SendApplyCommand()
0x00, 0x00, 0x00, 0x00,
};
int actual;
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
}
void AMDWraithPrismController::SendEffectChannelUpdate
@@ -276,6 +273,7 @@ void AMDWraithPrismController::SendEffectChannelUpdate
{
unsigned char usb_buf[] =
{
0x00,
0x51, 0x2C, 0x01, 0x00,
0x05, 0xFF, 0x00, 0x01,
0xFF, 0xFF, 0x00, 0xFF,
@@ -294,27 +292,26 @@ void AMDWraithPrismController::SendEffectChannelUpdate
0xFF, 0xFF, 0xFF, 0xFF
};
int actual;
usb_buf[0x05] = effect_channel;
usb_buf[0x06] = speed;
usb_buf[0x07] = (direction ? 0x01 : 0x00) | (random_color ? 0x80 : 0x00);
usb_buf[0x08] = mode;
usb_buf[0x04] = effect_channel;
usb_buf[0x05] = speed;
usb_buf[0x06] = (direction ? 0x01 : 0x00) | (random_color ? 0x80 : 0x00);
usb_buf[0x07] = mode;
usb_buf[0x0A] = brightness;
usb_buf[0x09] = brightness;
usb_buf[0x0B] = red;
usb_buf[0x0C] = green;
usb_buf[0x0D] = blue;
usb_buf[0x0A] = red;
usb_buf[0x0B] = green;
usb_buf[0x0C] = blue;
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
}
void AMDWraithPrismController::SendChannelRemap(unsigned char ring_channel, unsigned char logo_channel, unsigned char fan_channel)
{
unsigned char usb_buf[] =
{
0x00,
0x51, 0xA0, 0x01, 0x00,
0x00, 0x03, 0x00, 0x00,
0x05, 0x06, 0x07, 0x07,
@@ -333,16 +330,14 @@ void AMDWraithPrismController::SendChannelRemap(unsigned char ring_channel, unsi
0x00, 0x00, 0x00, 0x00,
};
int actual;
usb_buf[0x09] = logo_channel;
usb_buf[0x0A] = fan_channel;
usb_buf[0x08] = logo_channel;
usb_buf[0x09] = fan_channel;
for(int led = 0x0A; led <= 0x18; led++)
for(int led = 0x0B; led <= 0x19; led++)
{
usb_buf[led] = ring_channel;
}
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
}
@@ -8,7 +8,7 @@
\*-----------------------------------------*/
#include <string>
#include <libusb-1.0/libusb.h>
#include <hidapi/hidapi.h>
#pragma once
@@ -109,7 +109,7 @@ enum
class AMDWraithPrismController
{
public:
AMDWraithPrismController(libusb_device_handle* dev_handle);
AMDWraithPrismController(hid_device* dev_handle);
~AMDWraithPrismController();
char* GetDeviceName();
@@ -130,7 +130,7 @@ public:
private:
char device_name[32];
libusb_device_handle* dev;
hid_device* dev;
unsigned char current_fan_mode;
unsigned char current_fan_speed;
@@ -2,8 +2,7 @@
#include "RGBController.h"
#include "RGBController_AMDWraithPrism.h"
#include <vector>
#include <libusb-1.0/libusb.h>
#include <hidapi/hidapi.h>
#define AMD_WRAITH_PRISM_VID 0x2516
#define AMD_WRAITH_PRISM_PID 0x0051
@@ -17,21 +16,36 @@
void DetectAMDWraithPrismControllers(std::vector<RGBController*>& rgb_controllers)
{
libusb_context * ctx;
libusb_init(&ctx);
hid_device_info* info;
hid_device* dev = NULL;
hid_init();
info = hid_enumerate(AMD_WRAITH_PRISM_VID, AMD_WRAITH_PRISM_PID);
//Look for AMD Wraith Prism
libusb_device_handle * dev = libusb_open_device_with_vid_pid(ctx, AMD_WRAITH_PRISM_VID, AMD_WRAITH_PRISM_PID);
if( dev )
while(info)
{
libusb_detach_kernel_driver(dev, 1);
libusb_claim_interface(dev, 1);
if((info->vendor_id == AMD_WRAITH_PRISM_VID)
&&(info->product_id == AMD_WRAITH_PRISM_PID)
#if USE_HID_USAGE
&&(info->interface_number == 1)
&&(info->usage_page == 0xFF00))
#else
&&(info->interface_number == 1))
#endif
{
dev = hid_open_path(info->path);
if( dev )
{
AMDWraithPrismController* controller = new AMDWraithPrismController(dev);
AMDWraithPrismController* controller = new AMDWraithPrismController(dev);
RGBController_AMDWraithPrism* rgb_controller = new RGBController_AMDWraithPrism(controller);
RGBController_AMDWraithPrism* rgb_controller = new RGBController_AMDWraithPrism(controller);
rgb_controllers.push_back(rgb_controller);
rgb_controllers.push_back(rgb_controller);
}
}
info = info->next;
}
}
@@ -1,269 +0,0 @@
/*-----------------------------------------*\
| AuraAddressableController.cpp |
| |
| Driver for ASUS Aura RGB Addressable |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 1/18/2020 |
\*-----------------------------------------*/
#include "AuraAddressableController.h"
#include <cstring>
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
AuraAddressableController::AuraAddressableController(hid_device* dev_handle)
{
dev = dev_handle;
GetFirmwareVersion();
GetConfigTable();
}
AuraAddressableController::~AuraAddressableController()
{
}
unsigned int AuraAddressableController::GetChannelCount()
{
return( 1 );
}
std::string AuraAddressableController::GetDeviceName()
{
return(device_name);
}
void AuraAddressableController::SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors)
{
unsigned char led_data[60];
unsigned int leds_sent = 0;
while(leds_sent < num_colors)
{
unsigned int leds_to_send = 20;
if((num_colors - leds_sent) < leds_to_send)
{
leds_to_send = num_colors - leds_sent;
}
for(int led_idx = 0; led_idx < leds_to_send; led_idx++)
{
led_data[(led_idx * 3) + 0] = RGBGetRValue(colors[led_idx + leds_sent]);
led_data[(led_idx * 3) + 1] = RGBGetGValue(colors[led_idx + leds_sent]);
led_data[(led_idx * 3) + 2] = RGBGetBValue(colors[led_idx + leds_sent]);
}
SendDirect
(
channel,
leds_sent,
leds_to_send,
led_data
);
leds_sent += leds_to_send;
}
SendDirectApply(channel);
}
void AuraAddressableController::SetMode
(
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
)
{
for(int channel_idx = 0; channel_idx < GetChannelCount(); channel_idx++)
{
SendEffect
(
channel_idx,
mode,
red,
grn,
blu
);
}
}
void AuraAddressableController::GetConfigTable()
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_REQUEST_CONFIG_TABLE;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 65);
/*-----------------------------------------------------*\
| Copy the firmware string if the reply ID is correct |
\*-----------------------------------------------------*/
if(usb_buf[1] == 0x30)
{
memcpy(config_table, &usb_buf[4], 60);
for(int i = 0; i < 60; i+=6)
{
printf("%02X %02X %02X %02X %02X %02X\r\n", config_table[i + 0],
config_table[i + 1],
config_table[i + 2],
config_table[i + 3],
config_table[i + 4],
config_table[i + 5]);
}
}
}
void AuraAddressableController::GetFirmwareVersion()
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up firmware version request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_REQUEST_FIRMWARE_VERSION;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 65);
/*-----------------------------------------------------*\
| Copy the firmware string if the reply ID is correct |
\*-----------------------------------------------------*/
if(usb_buf[1] == 0x02)
{
memcpy(device_name, &usb_buf[2], 16);
}
}
void AuraAddressableController::SendEffect
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_CONTROL_MODE_EFFECT;
usb_buf[0x02] = channel;
usb_buf[0x03] = 0x00;
usb_buf[0x04] = mode;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
usb_buf[0x05] = red;
usb_buf[0x06] = grn;
usb_buf[0x07] = blu;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
void AuraAddressableController::SendDirect
(
unsigned char device,
unsigned char start_led,
unsigned char led_count,
unsigned char* led_data
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_CONTROL_MODE_DIRECT;
usb_buf[0x02] = device;
usb_buf[0x03] = start_led;
usb_buf[0x04] = led_count;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x05], led_data, led_count * 3);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
void AuraAddressableController::SendDirectApply
(
unsigned char channel
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_CONTROL_MODE_DIRECT;
usb_buf[0x02] = 0x80 | channel;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
@@ -1,47 +0,0 @@
#include "AuraAddressableController.h"
#include "RGBController.h"
#include "RGBController_AuraAddressable.h"
#include <vector>
#include <hidapi/hidapi.h>
#define AURA_ADDRESSABLE_VID 0x0B05
#define NUM_PIDS 4
static const unsigned short pid_table[] =
{
0x1867,
0x1872,
0x1889,
0x18A3
};
/******************************************************************************************\
* *
* DetectAuraAddressableControllers *
* *
* Tests the USB address to see if an Asus Aura addressable RGB header controller *
* exists there. *
* *
\******************************************************************************************/
void DetectAuraAddressableControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device* dev;
//Look for Asus Aura addressable RGB header controller
hid_init();
for(int pid_idx = 0; pid_idx < NUM_PIDS; pid_idx++)
{
dev = hid_open(AURA_ADDRESSABLE_VID, pid_table[pid_idx], 0);
if( dev )
{
AuraAddressableController* controller = new AuraAddressableController(dev);
RGBController_AuraAddressable* rgb_controller = new RGBController_AuraAddressable(controller);
rgb_controllers.push_back(rgb_controller);
}
}
}
@@ -14,16 +14,7 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
using namespace std::chrono_literals;
/*-------------------------------------------------------------*\
| This list contains the available I2C addresses for Aura GPUs |
@@ -88,7 +79,7 @@ void DetectAuraGPUControllers(std::vector<i2c_smbus_interface*> &busses, std::ve
rgb_controllers.push_back(new_controller);
}
Sleep(1);
std::this_thread::sleep_for(1ms);
}
}
} /* DetectAuraGPUControllers() */
@@ -6,21 +6,12 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
using namespace std::chrono_literals;
/*----------------------------------------------------------------------*\
| This list contains the available SMBus addresses for mapping Aura RAM |
\*----------------------------------------------------------------------*/
#define AURA_RAM_ADDRESS_COUNT 22
#define AURA_RAM_ADDRESS_COUNT 23
static const unsigned char aura_ram_addresses[] =
{
@@ -43,6 +34,7 @@ static const unsigned char aura_ram_addresses[] =
0x66,
0x67,
0x39,
0x3A,
0x3B,
0x3C,
0x3D
@@ -178,7 +170,7 @@ void DetectAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses, std::
rgb_controllers.push_back(new_controller);
}
Sleep(1);
std::this_thread::sleep_for(1ms);
}
// Add Aura-enabled motherboard controllers
@@ -191,7 +183,7 @@ void DetectAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses, std::
rgb_controllers.push_back(new_controller);
}
Sleep(1);
std::this_thread::sleep_for(1ms);
}
}
@@ -0,0 +1,144 @@
/*-----------------------------------------*\
| AuraAddressableController.cpp |
| |
| Driver for ASUS Aura RGB Addressable |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 1/18/2020 |
\*-----------------------------------------*/
#include "AuraAddressableController.h"
#include <cstring>
AuraAddressableController::AuraAddressableController(hid_device* dev_handle) : AuraUSBController(dev_handle)
{
/*-----------------------------------------------------*\
| Add addressable devices |
\*-----------------------------------------------------*/
for(int i = 0; i < config_table[0x02]; ++i)
{
device_info.push_back({0x01, (unsigned char)i, 0x01, AuraDeviceType::ADDRESSABLE});
}
}
AuraAddressableController::~AuraAddressableController()
{
}
void AuraAddressableController::SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors)
{
unsigned char led_data[60];
unsigned int leds_sent = 0;
while(leds_sent < num_colors)
{
unsigned int leds_to_send = 20;
if((num_colors - leds_sent) < leds_to_send)
{
leds_to_send = num_colors - leds_sent;
}
for(int led_idx = 0; led_idx < leds_to_send; led_idx++)
{
led_data[(led_idx * 3) + 0] = RGBGetRValue(colors[led_idx + leds_sent]);
led_data[(led_idx * 3) + 1] = RGBGetGValue(colors[led_idx + leds_sent]);
led_data[(led_idx * 3) + 2] = RGBGetBValue(colors[led_idx + leds_sent]);
}
SendDirect
(
channel,
leds_sent,
leds_to_send,
led_data
);
leds_sent += leds_to_send;
}
SendDirectApply(channel);
}
void AuraAddressableController::SetMode
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
)
{
SendEffect
(
channel,
mode,
red,
grn,
blu
);
}
void AuraAddressableController::SendEffect
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_ADDRESSABLE_CONTROL_MODE_EFFECT;
usb_buf[0x02] = channel;
usb_buf[0x03] = 0x00;
usb_buf[0x04] = mode;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
usb_buf[0x05] = red;
usb_buf[0x06] = grn;
usb_buf[0x07] = blu;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
void AuraAddressableController::SendDirectApply
(
unsigned char channel
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_CONTROL_MODE_DIRECT;
usb_buf[0x02] = 0x80 | channel;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
@@ -0,0 +1,60 @@
/*-----------------------------------------*\
| AuraAddressableController.h |
| |
| Definitions and types for ASUS Aura |
| Addressable RGB lighting controller |
| |
| Adam Honse (CalcProgrammer1) 1/18/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include "AuraUSBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
AURA_ADDRESSABLE_CONTROL_MODE_EFFECT = 0x3B, /* Effect control mode */
};
class AuraAddressableController : public AuraUSBController
{
public:
AuraAddressableController(hid_device* dev_handle);
~AuraAddressableController();
void SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
unsigned int num_colors
);
void SetMode
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
);
private:
void SendEffect
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
);
void SendDirectApply
(
unsigned char channel
);
};
@@ -0,0 +1,199 @@
/*-----------------------------------------*\
| AuraMainboardController.cpp |
| |
| Driver for ASUS Aura RGB USB mainboard |
| lighting controller |
| |
| Martin Hartl (inlart) 4/25/2020 |
\*-----------------------------------------*/
#include "AuraMainboardController.h"
#include <cstring>
AuraMainboardController::AuraMainboardController(hid_device* dev_handle) : AuraUSBController(dev_handle), mode(AURA_MODE_DIRECT)
{
/*-----------------------------------------------------*\
| Add mainboard device |
\*-----------------------------------------------------*/
device_info.push_back({0x00, 0x04, config_table[0x1B], AuraDeviceType::FIXED});
/*-----------------------------------------------------*\
| Add addressable devices |
\*-----------------------------------------------------*/
for(int i = 0; i < config_table[0x02]; ++i)
{
device_info.push_back({0x01, (unsigned char)i, 0x01, AuraDeviceType::ADDRESSABLE});
}
}
AuraMainboardController::~AuraMainboardController()
{
}
void AuraMainboardController::SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors)
{
unsigned char led_data[60];
unsigned int leds_sent = 0;
while(leds_sent < num_colors)
{
unsigned int leds_to_send = 20;
if((num_colors - leds_sent) < leds_to_send)
{
leds_to_send = num_colors - leds_sent;
}
for(int led_idx = 0; led_idx < leds_to_send; led_idx++)
{
led_data[(led_idx * 3) + 0] = RGBGetRValue(colors[led_idx + leds_sent]);
led_data[(led_idx * 3) + 1] = RGBGetGValue(colors[led_idx + leds_sent]);
led_data[(led_idx * 3) + 2] = RGBGetBValue(colors[led_idx + leds_sent]);
}
SendDirect
(
device_info[channel].direct_channel,
leds_sent,
leds_to_send,
led_data,
leds_sent + leds_to_send >= num_colors
);
leds_sent += leds_to_send;
}
SendCommit();
}
void AuraMainboardController::SetMode
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
)
{
this->mode = mode;
RGBColor color = ToRGBColor(red, grn, blu);
SendEffect(device_info[channel].effect_channel, mode);
if(mode == AURA_MODE_DIRECT)
{
return;
}
unsigned char led_data[60];
unsigned char start_led = 0;
for(std::size_t i = 0; i < channel; ++i)
{
start_led += device_info[i].num_leds;
}
for(std::size_t led_idx = 0; led_idx < device_info[channel].num_leds; led_idx++)
{
led_data[(led_idx * 3) + 0] = RGBGetRValue(color);
led_data[(led_idx * 3) + 1] = RGBGetGValue(color);
led_data[(led_idx * 3) + 2] = RGBGetBValue(color);
}
SendColor
(
channel,
start_led,
device_info[channel].num_leds,
led_data,
device_info[channel].device_type == AuraDeviceType::FIXED
);
SendCommit();
}
void AuraMainboardController::SendEffect
(
unsigned char channel,
unsigned char mode
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_MAINBOARD_CONTROL_MODE_EFFECT;
usb_buf[0x02] = channel;
usb_buf[0x03] = 0x00;
usb_buf[0x04] = 0x00;
usb_buf[0x05] = mode;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
void AuraMainboardController::SendColor
(
unsigned char channel,
unsigned char start_led,
unsigned char led_count,
unsigned char* led_data,
bool fixed
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_MAINBOARD_CONTROL_MODE_EFFECT_COLOR;
usb_buf[0x02] = channel;
usb_buf[0x03] = fixed ? 0xFF : 0x00;
usb_buf[0x04] = 0x00;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x05 + 3 * start_led], led_data, led_count * 3);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
void AuraMainboardController::SendCommit()
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_MAINBOARD_CONTROL_MODE_COMMIT;
usb_buf[0x02] = 0x55;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
@@ -0,0 +1,66 @@
/*-----------------------------------------*\
| AuraMainboardController.h |
| |
| Definitions and types for ASUS Aura |
| USB Mainboard RGB lighting controller |
| |
| Martin Hartl (inlart) 4/25/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include "AuraUSBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
AURA_MAINBOARD_CONTROL_MODE_EFFECT = 0x35, /* Effect control mode */
AURA_MAINBOARD_CONTROL_MODE_EFFECT_COLOR = 0x36, /* Effect color control mode */
AURA_MAINBOARD_CONTROL_MODE_COMMIT = 0x3F, /* Commit mode */
};
class AuraMainboardController : public AuraUSBController
{
public:
AuraMainboardController(hid_device* dev_handle);
~AuraMainboardController();
void SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
unsigned int num_colors
);
void SetMode
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
);
private:
unsigned int mode;
void SendEffect
(
unsigned char channel,
unsigned char mode
);
void SendColor
(
unsigned char channel,
unsigned char start_led,
unsigned char led_count,
unsigned char* led_data,
bool fixed
);
void SendCommit();
};
@@ -0,0 +1,155 @@
/*-----------------------------------------*\
| AuraUSBController.cpp |
| |
| Driver for ASUS Aura RGB USB |
| lighting controller |
| |
| Martin Hartl (inlart) 4/25/2020 |
\*-----------------------------------------*/
#include "AuraUSBController.h"
#include <cstring>
#include <stdexcept>
AuraUSBController::AuraUSBController(hid_device* dev_handle)
{
dev = dev_handle;
GetFirmwareVersion();
GetConfigTable();
}
AuraUSBController::~AuraUSBController()
{
}
unsigned int AuraUSBController::GetChannelCount()
{
return(device_info.size());
}
std::string AuraUSBController::GetDeviceName()
{
return(device_name);
}
const std::vector<AuraDeviceInfo>& AuraUSBController::GetAuraDevices() const
{
return(device_info);
}
void AuraUSBController::GetConfigTable()
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_REQUEST_CONFIG_TABLE;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 65);
/*-----------------------------------------------------*\
| Copy the firmware string if the reply ID is correct |
\*-----------------------------------------------------*/
if(usb_buf[1] == 0x30)
{
memcpy(config_table, &usb_buf[4], 60);
for(int i = 0; i < 60; i+=6)
{
printf("%02X %02X %02X %02X %02X %02X\r\n", config_table[i + 0],
config_table[i + 1],
config_table[i + 2],
config_table[i + 3],
config_table[i + 4],
config_table[i + 5]);
}
}
else
{
if(dev)
{
hid_close(dev);
}
throw std::runtime_error("Could not read config table");
}
}
void AuraUSBController::GetFirmwareVersion()
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up firmware version request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_REQUEST_FIRMWARE_VERSION;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 65);
/*-----------------------------------------------------*\
| Copy the firmware string if the reply ID is correct |
\*-----------------------------------------------------*/
if(usb_buf[1] == 0x02)
{
memcpy(device_name, &usb_buf[2], 16);
}
}
void AuraUSBController::SendDirect
(
unsigned char device,
unsigned char start_led,
unsigned char led_count,
unsigned char* led_data,
bool apply /* = false */
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_CONTROL_MODE_DIRECT;
usb_buf[0x02] = apply ? 0x80 : 0x00;
usb_buf[0x02] |= device;
usb_buf[0x03] = start_led;
usb_buf[0x04] = led_count;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x05], led_data, led_count * 3);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
@@ -1,15 +1,16 @@
/*-----------------------------------------*\
| AuraAddressableController.h |
| AuraUSBController.h |
| |
| Definitions and types for ASUS Aura |
| Addressable RGB lighting controller |
| USB RGB lighting controller |
| |
| Adam Honse (CalcProgrammer1) 1/18/2020 |
| Martin Hartl (inlart) 4/25/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
@@ -36,66 +37,71 @@ enum
enum
{
AURA_CONTROL_MODE_EFFECT = 0x3B, /* Effect control mode */
AURA_CONTROL_MODE_DIRECT = 0x40, /* Direct control mode */
AURA_REQUEST_FIRMWARE_VERSION = 0x82, /* Request firmware string */
AURA_REQUEST_CONFIG_TABLE = 0xB0, /* Request configuration table */
AURA_CONTROL_MODE_DIRECT = 0x40, /* Direct control mode */
};
class AuraAddressableController
enum class AuraDeviceType
{
FIXED,
ADDRESSABLE,
};
struct AuraDeviceInfo
{
unsigned char effect_channel;
unsigned char direct_channel;
unsigned char num_leds;
AuraDeviceType device_type;
};
class AuraUSBController
{
public:
AuraAddressableController(hid_device* dev_handle);
~AuraAddressableController();
AuraUSBController(hid_device* dev_handle);
virtual ~AuraUSBController();
unsigned int GetChannelCount();
std::string GetDeviceName();
void SetChannelLEDs
const std::vector<AuraDeviceInfo>& GetAuraDevices() const;
virtual void SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
unsigned int num_colors
);
) = 0;
void SetMode
(
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
);
private:
char device_name[16];
unsigned char config_table[60];
hid_device* dev;
unsigned int led_count;
void GetConfigTable();
void GetFirmwareVersion();
void SendEffect
virtual void SetMode
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
);
) = 0;
protected:
hid_device* dev;
unsigned char config_table[60];
std::vector<AuraDeviceInfo> device_info;
void SendDirect
(
unsigned char device,
unsigned char start_led,
unsigned char led_count,
unsigned char* led_data
unsigned char* led_data,
bool apply = false
);
private:
char device_name[16];
unsigned int led_count;
void SendDirectApply
(
unsigned char channel
);
void GetConfigTable();
void GetFirmwareVersion();
};
@@ -0,0 +1,77 @@
#include "AuraAddressableController.h"
#include "AuraMainboardController.h"
#include "RGBController.h"
#include "RGBController_AuraUSB.h"
#include <vector>
#include <stdexcept>
#include <hidapi/hidapi.h>
#define AURA_USB_VID 0x0B05
#define NUM_ADDRESSABLE_PIDS 4
static const unsigned short addressable_pid_table[] =
{
0x1867,
0x1872,
0x1889,
0x18A3
};
#define NUM_MAINBOARD_PIDS 2
static const unsigned short mainboard_pid_table[] =
{
0x18f3,
0x1939
};
/******************************************************************************************\
* *
* DetectAuraUSBControllers *
* *
* Tests the USB address to see if an Asus Aura USB RGB header controller *
* exists there. *
* *
\******************************************************************************************/
void DetectAuraUSBControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device* dev;
//Look for Asus Aura addressable RGB header controller
hid_init();
for(int pid_idx = 0; pid_idx < NUM_ADDRESSABLE_PIDS; pid_idx++)
{
dev = hid_open(AURA_USB_VID, addressable_pid_table[pid_idx], 0);
if( dev )
{
AuraAddressableController* controller = new AuraAddressableController(dev);
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
rgb_controllers.push_back(rgb_controller);
}
}
for(int pid_idx = 0; pid_idx < NUM_MAINBOARD_PIDS; pid_idx++)
{
dev = hid_open(AURA_USB_VID, mainboard_pid_table[pid_idx], 0);
if( dev )
{
try
{
AuraMainboardController* controller = new AuraMainboardController(dev);
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
rgb_controllers.push_back(rgb_controller);
}
catch(std::runtime_error&)
{
// reading the config table failed
}
}
}
}
@@ -8,33 +8,56 @@
\*-------------------------------------------------------------------*/
#include "CMMP750Controller.h"
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
CMMP750Controller::CMMP750Controller(libusb_device_handle* dev_handle, unsigned int _inAddr, unsigned int _outAddr, int _interface)
CMMP750Controller::CMMP750Controller(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path)
{
dev = dev_handle;
inAddr = _inAddr;
outAddr = _outAddr;
interface = _interface;
int tmp_size = wcslen(_vendor);
dev = dev_handle;
location = _path;
libusb_device* device = libusb_get_device(dev);
int bus = libusb_get_bus_number(device);
int bus_addr = libusb_get_device_address(device);
int port = libusb_get_port_number(device);
location = "Bus: " + std::to_string(bus) + " Addr: " + std::to_string(bus_addr) + " Port: " + std::to_string(port);
for (int i=0; ( i<tmp_size && i<CM_DEVICE_NAME_SIZE); i++)
{
device_name[i] = (char)_vendor[i];
}
for (int j=0; ( j<wcslen(_vendor) && tmp_size+j<CM_DEVICE_NAME_SIZE); j++)
device_name[tmp_size+j] = (char)_device_name[j];
strcpy(device_name, "Cooler Master MP750");
current_mode = MP750_MODE_STATIC;
current_speed = MP750_SPEED_NORMAL;
GetStatus(); //When setting up device get current status
}
CMMP750Controller::~CMMP750Controller()
{
libusb_release_interface(dev, interface);
libusb_attach_kernel_driver(dev, interface);
hid_close(dev);
}
void CMMP750Controller::GetStatus()
{
unsigned char buffer[0x40] = { 0x00 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
buffer[0] = 0x07;
hid_write(dev, buffer, buffer_size);
hid_read(dev, buffer, buffer_size);
if( buffer[0] == 0x80 && buffer[1] == 0x05 )
{
current_mode = buffer[2] - 1;
current_red = buffer[3];
current_green = buffer[4];
current_blue = buffer[5];
for( int i = 0; speed_mode_data[current_mode][i] >= buffer[6]; i++)
current_speed = i;
}
else
{
//Code should never reach here however just in case there is a failure set something
current_mode = MP750_MODE_COLOR_CYCLE; //Unicorn Spew
current_red = 0xFF;
current_green = 0xFF;
current_blue = 0xFF;
current_speed = MP750_SPEED_NORMAL;
}
}
char* CMMP750Controller::GetDeviceName()
@@ -52,6 +75,31 @@ std::string CMMP750Controller::GetLocation()
return location;
}
unsigned char CMMP750Controller::GetMode()
{
return current_mode;
}
unsigned char CMMP750Controller::GetLedRed()
{
return current_red;
}
unsigned char CMMP750Controller::GetLedGreen()
{
return current_green;
}
unsigned char CMMP750Controller::GetLedBlue()
{
return current_blue;
}
unsigned char CMMP750Controller::GetLedSpeed()
{
return current_speed;
}
void CMMP750Controller::SetMode(unsigned char mode, unsigned char speed)
{
current_mode = mode;
@@ -71,7 +119,6 @@ void CMMP750Controller::SetColor(unsigned char red, unsigned char green, unsigne
void CMMP750Controller::SendUpdate()
{
int actual = 0;
unsigned char buffer[0x40] = { 0x00 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
@@ -94,7 +141,5 @@ void CMMP750Controller::SendUpdate()
buffer[CM_SPEED_BYTE] = speed_mode_data[current_mode][current_speed];
}
//Nothing will be done with the "actual" transfer length
libusb_interrupt_transfer(dev, outAddr, buffer, buffer_size, nullptr, CM_INTERRUPT_TIMEOUT);
}
hid_write(dev, buffer, buffer_size);
}
@@ -16,12 +16,15 @@
#include <string>
#include <array>
#include <libusb-1.0/libusb.h>
#include <hidapi/hidapi.h>
#pragma once
#define CM_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data) / sizeof(colour_mode_data[0]))
#define CM_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
#define CM_INTERRUPT_TIMEOUT 250
#define CM_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
#define CM_SERIAL_SIZE (sizeof(serial) / sizeof(serial[ 0 ]))
#define HID_MAX_STR 255
enum
{
@@ -53,10 +56,10 @@ static unsigned char colour_mode_data[][6] =
static unsigned char speed_mode_data[][9] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },/* Static */
{ 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0, 0xFF },/* Blinking */
{ 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0, 0xFF },/* Breathing */
{ 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0, 0xFF },/* Colour Cycle */
{ 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0, 0xFF } /* Colour Breath */
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 },/* Blinking */
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 },/* Breathing */
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 },/* Colour Cycle */
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 } /* Colour Breath */
};
enum
@@ -75,13 +78,18 @@ enum
class CMMP750Controller
{
public:
CMMP750Controller(libusb_device_handle *dev_handle, unsigned int _inAddr, unsigned int _outAddr, int _interface);
CMMP750Controller(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path);
~CMMP750Controller();
char* GetDeviceName();
char* GetSerial();
std::string GetLocation();
unsigned char GetMode();
unsigned char GetLedRed();
unsigned char GetLedGreen();
unsigned char GetLedBlue();
unsigned char GetLedSpeed();
void SetMode(unsigned char mode, unsigned char speed);
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
@@ -89,10 +97,7 @@ private:
char device_name[32];
char serial[32];
std::string location;
libusb_device_handle* dev;
unsigned char inAddr;
unsigned char outAddr;
int interface;
hid_device* dev;
unsigned char current_mode;
unsigned char current_speed;
@@ -101,5 +106,6 @@ private:
unsigned char current_green;
unsigned char current_blue;
void GetStatus();
void SendUpdate();
};
@@ -1,24 +1,25 @@
#include "CMMP750Controller.h"
#include "RGBController.h"
#include "RGBController_CMMP750Controller.h"
#include <vector>
#include <libusb-1.0/libusb.h>
#include <hidapi/hidapi.h>
#define COOLERMASTER_VID 0x2516
#define COOLERMASTER_VID 0x2516
#define COOLERMASTER_MP750_XL_PID 0x0109
#define COOLERMASTER_MP750_MEDIUM_PID 0x0105
#define COOLERMASTER_NUM_DEVICES (sizeof(cm_pids) / sizeof(cm_pids[ 0 ]))
enum
{
CM_PID = 0,
CM_INADDR = 1,
CM_OUTADDR = 2,
CM_INTERFACE = 3
CM_INTERFACE = 1
};
static const unsigned int cm_pids[][4] =
{ //PID, inAddr, outAddr, interface
{ 0x0109, 0x82, 0x03, 0x00 } //Coolermaster MP750
{ // PID, Interface
{ COOLERMASTER_MP750_XL_PID, 0x00 }, //Coolermaster MP750 (Extra Large)
{ COOLERMASTER_MP750_MEDIUM_PID, 0x00 } //Coolermaster MP750 (Medium)
};
/******************************************************************************************\
@@ -31,27 +32,35 @@ static const unsigned int cm_pids[][4] =
void DetectCoolerMasterControllers(std::vector<RGBController*>& rgb_controllers)
{
libusb_context * context;
libusb_init(&context);
hid_device_info* info;
for(int cm_pid_idx = 0; cm_pid_idx < COOLERMASTER_NUM_DEVICES; cm_pid_idx++)
//Look for the passed in cm_pids
hid_init();
info = hid_enumerate(COOLERMASTER_VID, 0x0);
while(info)
{
//Look for the passed in cm_pids
libusb_device_handle * dev = libusb_open_device_with_vid_pid(context, COOLERMASTER_VID, cm_pids[cm_pid_idx][CM_PID]);
hid_device* dev = NULL;
if(info->vendor_id == COOLERMASTER_VID)
{
for(int cm_pid_idx = 0; cm_pid_idx < COOLERMASTER_NUM_DEVICES; cm_pid_idx++)
{
if((info->product_id == cm_pids[cm_pid_idx][CM_PID])
&&(info->interface_number == cm_pids[cm_pid_idx][CM_INTERFACE]))
{
dev = hid_open_path(info->path);
break;
}
}
}
if(dev)
{
int status = libusb_detach_kernel_driver(dev, cm_pids[cm_pid_idx][CM_INTERFACE]);
status = libusb_claim_interface(dev, cm_pids[cm_pid_idx][CM_INTERFACE]);
if(status == 0)
{
// Success: Device has been claimed
CMMP750Controller* controller = new CMMP750Controller(dev, cm_pids[cm_pid_idx][CM_INADDR], cm_pids[cm_pid_idx][CM_OUTADDR], cm_pids[cm_pid_idx][CM_INTERFACE]);
RGBController_CMMP750Controller* rgb_controller = new RGBController_CMMP750Controller(controller);
rgb_controllers.push_back(rgb_controller);
}
CMMP750Controller* controller = new CMMP750Controller(dev, info->manufacturer_string, info->product_string, info->path);
RGBController_CMMP750Controller* rgb_controller = new RGBController_CMMP750Controller(controller);
rgb_controllers.push_back(rgb_controller);
}
info = info->next;
}
hid_free_enumeration(info);
}
@@ -28,16 +28,7 @@
#define THREADRETURN return(NULL);
#endif
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
using namespace std::chrono_literals;
THREAD keepalive_thread(void *param)
{
@@ -46,10 +37,9 @@ THREAD keepalive_thread(void *param)
THREADRETURN
}
CorsairLightingNodeController::CorsairLightingNodeController(libusb_device_handle* dev_handle, unsigned int dev_endpoint)
CorsairLightingNodeController::CorsairLightingNodeController(hid_device* dev_handle)
{
dev = dev_handle;
endpoint = dev_endpoint;
SendFirmwareRequest();
@@ -75,8 +65,11 @@ void CorsairLightingNodeController::KeepaliveThread()
{
while(1)
{
SendCommit();
Sleep(5000);
if((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::seconds(5))
{
SendCommit();
}
std::this_thread::sleep_for(1s);
}
}
@@ -205,7 +198,7 @@ void CorsairLightingNodeController::SetChannelLEDs(unsigned char channel, RGBCol
void CorsairLightingNodeController::SendFirmwareRequest()
{
int actual;
unsigned char usb_buf[64];
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -215,13 +208,14 @@ void CorsairLightingNodeController::SendFirmwareRequest()
/*-----------------------------------------------------*\
| Set up Firmware Version Request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_FIRMWARE;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_FIRMWARE;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_interrupt_transfer(dev, endpoint, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x80 + endpoint, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 65);
actual = hid_read(dev, usb_buf, 17);
if(actual > 0)
{
@@ -238,8 +232,7 @@ void CorsairLightingNodeController::SendDirect
unsigned char* color_data
)
{
int actual;
unsigned char usb_buf[64];
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -249,43 +242,51 @@ void CorsairLightingNodeController::SendDirect
/*-----------------------------------------------------*\
| Set up Direct packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_DIRECT;
usb_buf[0x01] = channel;
usb_buf[0x02] = start;
usb_buf[0x03] = count;
usb_buf[0x04] = color_channel;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_DIRECT;
usb_buf[0x02] = channel;
usb_buf[0x03] = start;
usb_buf[0x04] = count;
usb_buf[0x05] = color_channel;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x05], color_data, count);
memcpy(&usb_buf[0x06], color_data, count);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_interrupt_transfer(dev, endpoint, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SendCommit()
{
int actual;
unsigned char usb_buf[64];
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Update last commit time |
\*-----------------------------------------------------*/
last_commit_time = std::chrono::steady_clock::now();
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_COMMIT;
usb_buf[0x01] = 0xFF;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_COMMIT;
usb_buf[0x02] = 0xFF;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_interrupt_transfer(dev, endpoint, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SendBegin
@@ -293,8 +294,7 @@ void CorsairLightingNodeController::SendBegin
unsigned char channel
)
{
int actual;
unsigned char usb_buf[64];
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -304,13 +304,15 @@ void CorsairLightingNodeController::SendBegin
/*-----------------------------------------------------*\
| Set up Begin packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_BEGIN;
usb_buf[0x01] = channel;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_BEGIN;
usb_buf[0x02] = channel;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_interrupt_transfer(dev, endpoint, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SendEffectConfig
@@ -336,8 +338,7 @@ void CorsairLightingNodeController::SendEffectConfig
unsigned short temperature_2
)
{
int actual;
unsigned char usb_buf[64];
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -347,47 +348,49 @@ void CorsairLightingNodeController::SendEffectConfig
/*-----------------------------------------------------*\
| Set up Effect Config packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_EFFECT_CONFIG;
usb_buf[0x01] = channel;
usb_buf[0x02] = count * 10;
usb_buf[0x03] = led_type;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_EFFECT_CONFIG;
usb_buf[0x02] = channel;
usb_buf[0x03] = count;
usb_buf[0x04] = led_type;
/*-----------------------------------------------------*\
| Set up mode parameters |
\*-----------------------------------------------------*/
usb_buf[0x04] = mode;
usb_buf[0x05] = speed;
usb_buf[0x06] = direction;
usb_buf[0x07] = change_style;
usb_buf[0x08] = 0;
usb_buf[0x05] = mode;
usb_buf[0x06] = speed;
usb_buf[0x07] = direction;
usb_buf[0x08] = change_style;
usb_buf[0x09] = 0;
/*-----------------------------------------------------*\
| Set up mode colors |
\*-----------------------------------------------------*/
usb_buf[0x09] = color_0_red;
usb_buf[0x10] = color_0_green;
usb_buf[0x11] = color_0_blue;
usb_buf[0x12] = color_1_red;
usb_buf[0x13] = color_1_green;
usb_buf[0x14] = color_1_blue;
usb_buf[0x15] = color_2_red;
usb_buf[0x16] = color_2_green;
usb_buf[0x17] = color_2_blue;
usb_buf[0x0A] = color_0_red;
usb_buf[0x0B] = color_0_green;
usb_buf[0x0C] = color_0_blue;
usb_buf[0x0D] = color_1_red;
usb_buf[0x0E] = color_1_green;
usb_buf[0x0F] = color_1_blue;
usb_buf[0x10] = color_2_red;
usb_buf[0x11] = color_2_green;
usb_buf[0x12] = color_2_blue;
/*-----------------------------------------------------*\
| Set up temperatures |
\*-----------------------------------------------------*/
usb_buf[0x12] = (temperature_0 >> 8);
usb_buf[0x13] = (temperature_0 & 0xFF);
usb_buf[0x14] = (temperature_1 >> 8);
usb_buf[0x15] = (temperature_1 & 0xFF);
usb_buf[0x16] = (temperature_2 >> 8);
usb_buf[0x17] = (temperature_2 & 0xFF);
usb_buf[0x13] = (temperature_0 >> 8);
usb_buf[0x14] = (temperature_0 & 0xFF);
usb_buf[0x15] = (temperature_1 >> 8);
usb_buf[0x16] = (temperature_1 & 0xFF);
usb_buf[0x17] = (temperature_2 >> 8);
usb_buf[0x18] = (temperature_2 & 0xFF);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_interrupt_transfer(dev, endpoint, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SendTemperature()
@@ -400,8 +403,7 @@ void CorsairLightingNodeController::SendReset
unsigned char channel
)
{
int actual;
unsigned char usb_buf[64];
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -411,13 +413,15 @@ void CorsairLightingNodeController::SendReset
/*-----------------------------------------------------*\
| Set up Reset packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_RESET;
usb_buf[0x01] = channel;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_RESET;
usb_buf[0x02] = channel;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_interrupt_transfer(dev, endpoint, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SendPortState
@@ -426,8 +430,7 @@ void CorsairLightingNodeController::SendPortState
unsigned char state
)
{
int actual;
unsigned char usb_buf[64];
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -437,14 +440,16 @@ void CorsairLightingNodeController::SendPortState
/*-----------------------------------------------------*\
| Set up Port State packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_PORT_STATE;
usb_buf[0x01] = channel;
usb_buf[0x02] = state;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_PORT_STATE;
usb_buf[0x02] = channel;
usb_buf[0x03] = state;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_interrupt_transfer(dev, endpoint, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SendBrightness()
@@ -5,8 +5,9 @@
\*---------------------------------------------------------*/
#include "RGBController.h"
#include <chrono>
#include <vector>
#include <libusb-1.0/libusb.h>
#include <hidapi/hidapi.h>
#pragma once
@@ -78,7 +79,7 @@ enum
class CorsairLightingNodeController
{
public:
CorsairLightingNodeController(libusb_device_handle* dev_handle, unsigned int dev_endpoint);
CorsairLightingNodeController(hid_device* dev_handle);
~CorsairLightingNodeController();
std::string GetFirmwareString();
@@ -107,9 +108,9 @@ public:
void KeepaliveThread();
private:
libusb_device_handle* dev;
unsigned int endpoint;
hid_device* dev;
std::string firmware_version;
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
void SendFirmwareRequest();
@@ -2,7 +2,7 @@
#include "RGBController.h"
#include "RGBController_CorsairLightingNode.h"
#include <vector>
#include <libusb-1.0/libusb.h>
#include <hidapi/hidapi.h>
#define CORSAIR_VID 0x1B1C
#define CORSAIR_LIGHTING_NODE_CORE_PID 0x0C1A
@@ -16,20 +16,20 @@ typedef struct
{
unsigned short usb_vid;
unsigned short usb_pid;
unsigned char usb_endpoint;
unsigned char channel_count;
const char * name;
} corsair_node_device;
static const corsair_node_device device_list[6] =
{
{ CORSAIR_VID, CORSAIR_LIGHTING_NODE_CORE_PID, 1, 1, "Corsair Lighting Node Core" },
{ CORSAIR_VID, CORSAIR_LIGHTING_NODE_PRO_PID, 1, 2, "Corsair Lighting Node Pro" },
{ CORSAIR_VID, CORSAIR_COMMANDER_PRO_PID, 2, 2, "Corsair Commander Pro" },
{ CORSAIR_VID, CORSAIR_LS100_PID, 1, 1, "Corsair LS100 Lighting Kit" },
{ CORSAIR_VID, CORSAIR_1000D_OBSIDIAN_PID, 2, 2, "Corsair 1000D Obsidian" },
{ CORSAIR_VID, CORSAIR_SPEC_OMEGA_RGB_PID, 1, 2, "Corsair SPEC OMEGA RGB" }
#define CORSAIR_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
static const corsair_node_device device_list[] =
{
{ CORSAIR_VID, CORSAIR_LIGHTING_NODE_CORE_PID, 1, "Corsair Lighting Node Core" },
{ CORSAIR_VID, CORSAIR_LIGHTING_NODE_PRO_PID, 2, "Corsair Lighting Node Pro" },
{ CORSAIR_VID, CORSAIR_COMMANDER_PRO_PID, 2, "Corsair Commander Pro" },
{ CORSAIR_VID, CORSAIR_LS100_PID, 1, "Corsair LS100 Lighting Kit" },
{ CORSAIR_VID, CORSAIR_1000D_OBSIDIAN_PID, 2, "Corsair 1000D Obsidian" },
{ CORSAIR_VID, CORSAIR_SPEC_OMEGA_RGB_PID, 2, "Corsair SPEC OMEGA RGB" }
};
/******************************************************************************************\
@@ -37,31 +37,43 @@ static const corsair_node_device device_list[6] =
* DetectCorsairLightingNodeControllers *
* *
* Detect devices supported by the Corsair Lighting Node Pro driver *
* * *
* *
\******************************************************************************************/
void DetectCorsairLightingNodeControllers(std::vector<RGBController*> &rgb_controllers)
{
libusb_context * ctx;
libusb_init(&ctx);
hid_device_info* info;
hid_device* dev;
for(int device_idx = 0; device_idx < 6; device_idx++)
hid_init();
for(std::size_t device_idx = 0; device_idx < CORSAIR_NUM_DEVICES; device_idx++)
{
//Look for Corsair Lighting Node Device
libusb_device_handle * dev = libusb_open_device_with_vid_pid(ctx, device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
dev = NULL;
if( dev )
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for Corsair Lighting Node Devices
while(info)
{
libusb_detach_kernel_driver(dev, 0);
libusb_claim_interface(dev, 0);
if((info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid))
{
dev = hid_open_path(info->path);
CorsairLightingNodeController* controller = new CorsairLightingNodeController(dev, device_list[device_idx].usb_endpoint);
if( dev )
{
CorsairLightingNodeController* controller = new CorsairLightingNodeController(dev);
RGBController_CorsairLightingNode* rgb_controller = new RGBController_CorsairLightingNode(controller);
RGBController_CorsairLightingNode* rgb_controller = new RGBController_CorsairLightingNode(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
rgb_controllers.push_back(rgb_controller);
}
}
info = info->next;
}
}
} /* DetectCorsairLightingNodeControllers() */
@@ -11,6 +11,8 @@
#include <cstring>
using namespace std::chrono_literals;
static unsigned int keys[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12,
0x14, 0x15, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x24, 0x25, 0x26,
0x27, 0x28, 0x2A, 0x2B, 0x2C, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
@@ -20,17 +22,7 @@ static unsigned int keys[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x
116, 117, 120, 121, 122, 123, 124, 126, 127, 128, 129, 132, 133, 134, 135,
136, 137, 139, 140, 141};
static void send_usb_msg(hid_device* dev, char * data_pkt)
{
char usb_pkt[65];
usb_pkt[0] = 0x00;
for(int i = 1; i < 65; i++)
{
usb_pkt[i] = data_pkt[i-1];
}
int bytes = hid_send_feature_report(dev, (unsigned char *)usb_pkt, 65);
bytes++;
}
static unsigned int st100[] = { 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x04 };
CorsairPeripheralController::CorsairPeripheralController(hid_device* dev_handle)
{
@@ -38,7 +30,6 @@ CorsairPeripheralController::CorsairPeripheralController(hid_device* dev_handle)
ReadFirmwareInfo();
SpecialFunctionControl();
LightingControl();
}
@@ -72,6 +63,26 @@ void CorsairPeripheralController::SetLEDs(std::vector<RGBColor>colors)
case DEVICE_TYPE_MOUSEMAT:
SetLEDsMousemat(colors);
break;
case DEVICE_TYPE_HEADSET_STAND:
/*-----------------------------------------------------*\
| The logo zone of the ST100 is in the middle of the |
| base LED strip, so remap the colors so that the logo |
| is the last LED in the sequence. |
\*-----------------------------------------------------*/
std::vector<RGBColor> remap_colors;
remap_colors.resize(colors.size());
for(int i = 0; i < 9; i++)
{
remap_colors[st100[i]] = colors[i];
}
/*-----------------------------------------------------*\
| The ST100 uses the mousemat protocol |
\*-----------------------------------------------------*/
SetLEDsMousemat(remap_colors);
break;
}
}
@@ -207,7 +218,7 @@ void CorsairPeripheralController::SetLEDsKeyboardLimited(std::vector<RGBColor> c
void CorsairPeripheralController::LightingControl()
{
char usb_buf[64];
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -217,39 +228,44 @@ void CorsairPeripheralController::LightingControl()
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_LIGHTING_CONTROL;
usb_buf[0x02] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_LIGHTING_CONTROL;
usb_buf[0x03] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
/*-----------------------------------------------------*\
| Lighting control byte needs to be 3 for keyboards, 1 |
| for mice and mousepads |
| Lighting control byte needs to be 3 for keyboards and |
| headset stand, 1 for mice and mousepads |
\*-----------------------------------------------------*/
switch(type)
{
default:
case DEVICE_TYPE_KEYBOARD:
usb_buf[0x04] = 0x03;
usb_buf[0x05] = 0x03;
break;
case DEVICE_TYPE_MOUSE:
usb_buf[0x04] = 0x01;
usb_buf[0x05] = 0x01;
break;
case DEVICE_TYPE_MOUSEMAT:
usb_buf[0x04] = 0x04;
usb_buf[0x05] = 0x04;
break;
case DEVICE_TYPE_HEADSET_STAND:
usb_buf[0x05] = 0x03;
break;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf);
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void CorsairPeripheralController::SpecialFunctionControl()
{
char usb_buf[64];
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -259,19 +275,22 @@ void CorsairPeripheralController::SpecialFunctionControl()
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_SPECIAL_FUNCTION;
usb_buf[0x02] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SPECIAL_FUNCTION;
usb_buf[0x03] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf);
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void CorsairPeripheralController::ReadFirmwareInfo()
{
char usb_buf[64];
int actual;
char usb_buf[65];
char offset = 0;
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -281,22 +300,44 @@ void CorsairPeripheralController::ReadFirmwareInfo()
/*-----------------------------------------------------*\
| Set up Read Firmware Info packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_READ;
usb_buf[0x01] = CORSAIR_PROPERTY_FIRMWARE_INFO;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_READ;
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
/*-----------------------------------------------------*\
| Send packet |
| Send packet and try reading it using an HID read |
| If that fails, repeat the send and read the reply as |
| a feature report. |
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf);
hid_get_feature_report(dev, (unsigned char*)usb_buf, 64);
hid_write(dev, (unsigned char*)usb_buf, 65);
actual = hid_read_timeout(dev, (unsigned char*)usb_buf, 65, 1000);
if(actual == 0)
{
/*-------------------------------------------------*\
| Zero out buffer |
\*-------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-------------------------------------------------*\
| Set up Read Firmware Info packet |
\*-------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_READ;
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
hid_send_feature_report(dev, (unsigned char*)usb_buf, 65);
actual = hid_get_feature_report(dev, (unsigned char*)usb_buf, 65);
offset = 1;
}
/*-----------------------------------------------------*\
| Get device type |
| 0xC0 Device is a keyboard |
| 0xC1 Device is a mouse |
| 0xC2 Device is a mousepad |
| 0xC2 Device is a mousepad or headset stand |
\*-----------------------------------------------------*/
switch((unsigned char)usb_buf[0x14])
switch((unsigned char)usb_buf[0x14 + offset])
{
case 0xC0:
type = DEVICE_TYPE_KEYBOARD;
@@ -304,10 +345,26 @@ void CorsairPeripheralController::ReadFirmwareInfo()
case 0xC1:
type = DEVICE_TYPE_MOUSE;
SpecialFunctionControl();
break;
case 0xC2:
type = DEVICE_TYPE_MOUSEMAT;
{
unsigned short pid = (unsigned short)(usb_buf[0x0F] << 8) + (unsigned char)(usb_buf[0x0E]);
switch(pid)
{
case 0x0A34:
type = DEVICE_TYPE_HEADSET_STAND;
SpecialFunctionControl();
break;
default:
type = DEVICE_TYPE_MOUSEMAT;
SpecialFunctionControl();
break;
}
}
break;
default:
@@ -320,7 +377,7 @@ void CorsairPeripheralController::ReadFirmwareInfo()
\*-----------------------------------------------------*/
if(type != DEVICE_TYPE_UNKNOWN)
{
firmware_version = std::to_string(usb_buf[0x09]) + "." + std::to_string(usb_buf[0x08]);
firmware_version = std::to_string(usb_buf[0x09 + offset]) + "." + std::to_string(usb_buf[0x08 + offset]);
}
}
@@ -331,7 +388,7 @@ void CorsairPeripheralController::StreamPacket
unsigned char* data_ptr
)
{
char usb_buf[64];
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -341,19 +398,20 @@ void CorsairPeripheralController::StreamPacket
/*-----------------------------------------------------*\
| Set up Stream packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_STREAM;
usb_buf[0x01] = packet_id;
usb_buf[0x02] = data_sz;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_STREAM;
usb_buf[0x02] = packet_id;
usb_buf[0x03] = data_sz;
/*-----------------------------------------------------*\
| Copy in data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x04], data_ptr, data_sz);
memcpy(&usb_buf[0x05], data_ptr, data_sz);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf);
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void CorsairPeripheralController::SubmitKeyboardFullColors
@@ -363,7 +421,7 @@ void CorsairPeripheralController::SubmitKeyboardFullColors
unsigned char finish_val
)
{
char usb_buf[64];
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -373,16 +431,17 @@ void CorsairPeripheralController::SubmitKeyboardFullColors
/*-----------------------------------------------------*\
| Set up Submit Keyboard 24-Bit Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_24;
usb_buf[0x02] = color_channel;
usb_buf[0x03] = packet_count;
usb_buf[0x04] = finish_val;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_24;
usb_buf[0x03] = color_channel;
usb_buf[0x04] = packet_count;
usb_buf[0x05] = finish_val;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf);
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void CorsairPeripheralController::SubmitKeyboardLimitedColors
@@ -390,7 +449,7 @@ void CorsairPeripheralController::SubmitKeyboardLimitedColors
unsigned char byte_count
)
{
char usb_buf[64];
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -400,14 +459,15 @@ void CorsairPeripheralController::SubmitKeyboardLimitedColors
/*-----------------------------------------------------*\
| Set up Submit Keyboard 9-Bit Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_9;
usb_buf[0x04] = byte_count;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_9;
usb_buf[0x05] = byte_count;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf);
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void CorsairPeripheralController::SubmitMouseColors
@@ -416,7 +476,7 @@ void CorsairPeripheralController::SubmitMouseColors
RGBColor * color_data
)
{
char usb_buf[64];
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -426,26 +486,27 @@ void CorsairPeripheralController::SubmitMouseColors
/*-----------------------------------------------------*\
| Set up Submit Mouse Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
usb_buf[0x02] = num_zones;
usb_buf[0x03] = 0x00;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
usb_buf[0x03] = num_zones;
usb_buf[0x04] = 0x00;
/*-----------------------------------------------------*\
| Copy in colors in <ZONE> <RED> <GREEN> <BLUE> order |
\*-----------------------------------------------------*/
for(unsigned int zone_idx = 0; zone_idx < num_zones; zone_idx++)
{
usb_buf[(zone_idx * 4) + 4] = zone_idx;
usb_buf[(zone_idx * 4) + 5] = RGBGetRValue(color_data[zone_idx]);
usb_buf[(zone_idx * 4) + 6] = RGBGetGValue(color_data[zone_idx]);
usb_buf[(zone_idx * 4) + 7] = RGBGetBValue(color_data[zone_idx]);
usb_buf[(zone_idx * 4) + 5] = zone_idx;
usb_buf[(zone_idx * 4) + 6] = RGBGetRValue(color_data[zone_idx]);
usb_buf[(zone_idx * 4) + 7] = RGBGetGValue(color_data[zone_idx]);
usb_buf[(zone_idx * 4) + 8] = RGBGetBValue(color_data[zone_idx]);
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf);
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void CorsairPeripheralController::SubmitMousematColors
@@ -454,7 +515,7 @@ void CorsairPeripheralController::SubmitMousematColors
RGBColor * color_data
)
{
char usb_buf[64];
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -464,24 +525,25 @@ void CorsairPeripheralController::SubmitMousematColors
/*-----------------------------------------------------*\
| Set up Submit Mouse Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
usb_buf[0x02] = num_zones;
usb_buf[0x03] = 0x00;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
usb_buf[0x03] = num_zones;
usb_buf[0x04] = 0x00;
/*-----------------------------------------------------*\
| Copy in colors in <ZONE> <RED> <GREEN> <BLUE> order |
| Copy in colors in <RED> <GREEN> <BLUE> order |
\*-----------------------------------------------------*/
for(unsigned int zone_idx = 0; zone_idx < num_zones; zone_idx++)
{
//usb_buf[(zone_idx * 4) + 4] = zone_idx;
usb_buf[(zone_idx * 3) + 4] = RGBGetRValue(color_data[zone_idx]);
usb_buf[(zone_idx * 3) + 5] = RGBGetGValue(color_data[zone_idx]);
usb_buf[(zone_idx * 3) + 6] = RGBGetBValue(color_data[zone_idx]);
usb_buf[(zone_idx * 3) + 5] = RGBGetRValue(color_data[zone_idx]);
usb_buf[(zone_idx * 3) + 6] = RGBGetGValue(color_data[zone_idx]);
usb_buf[(zone_idx * 3) + 7] = RGBGetBValue(color_data[zone_idx]);
}
/*-----------------------------------------------------*\
| Send packet |
| Send packet using feature reports, as headset stand |
| seems to not update completely using HID writes |
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf);
}
hid_write(dev, (unsigned char *)usb_buf, 65);
}
@@ -25,7 +25,7 @@
#define CORSAIR_K70_RGB_PID 0x1B13
#define CORSAIR_K70_LUX_RGB_PID 0x1B33
#define CORSAIR_K70_RGB_RAPIDFIRE_PID 0x1B38
#define CORSAIR_K70_RGB_MK2_PID 0x1B38
#define CORSAIR_K70_RGB_MK2_PID 0x1B49
#define CORSAIR_K70_RGB_MK2_SE_PID 0x1B6B
#define CORSAIR_K70_RGB_MK2_LP_PID 0x1B55
@@ -39,6 +39,9 @@
| Mouse product IDs |
| List taken from ckb-next |
\*-----------------------------------------------------*/
#define CORSAIR_GLAIVE_RGB_PRO_PID 0x1B74
#define CORSAIR_HARPOON_RGB_PID 0x1B3C
#define CORSAIR_HARPOON_RGB_PRO_PID 0x1B75
#define CORSAIR_M65_PRO_PID 0x1B2E
#define CORSAIR_M65_RGB_ELITE_PID 0x1B5A
@@ -48,6 +51,12 @@
\*-----------------------------------------------------*/
#define CORSAIR_MM800_RGB_POLARIS_PID 0x1B3B
/*-----------------------------------------------------*\
| Headset Stand product IDs |
| List taken from ckb-next |
\*-----------------------------------------------------*/
#define CORSAIR_ST100_PID 0x0A34
typedef struct
{
unsigned short usb_vid;
@@ -63,6 +72,10 @@ static const corsair_node_device device_list[] =
/*-----------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-----------------------------------------------------------------------------------------------------*/
// { CORSAIR_VID, CORSAIR_K55_RGB_PID, 1, "Corsair K55 RGB" }, //Not per-key, disabled for now
{ CORSAIR_VID, CORSAIR_K65_RGB_PID, 1, "Corsair K65 RGB" },
{ CORSAIR_VID, CORSAIR_K65_LUX_RGB_PID, 1, "Corsair K65 LUX RGB" },
{ CORSAIR_VID, CORSAIR_K65_RGB_RAPIDFIRE_PID, 1, "Corsair K65 RGB RAPIDFIRE" },
{ CORSAIR_VID, CORSAIR_K68_RGB, 1, "Corsair K68 RGB" },
{ CORSAIR_VID, CORSAIR_K70_RGB_PID, 1, "Corsair K70 RGB" },
{ CORSAIR_VID, CORSAIR_K70_LUX_RGB_PID, 1, "Corsair K70 LUX RGB" },
@@ -72,15 +85,24 @@ static const corsair_node_device device_list[] =
{ CORSAIR_VID, CORSAIR_K70_RGB_MK2_LP_PID, 1, "Corsair K70 RGB MK.2 Low Profile" },
{ CORSAIR_VID, CORSAIR_K95_RGB_PID, 1, "Corsair K95 RGB" },
{ CORSAIR_VID, CORSAIR_K95_PLATINUM_PID, 1, "Corsair K95 RGB PLATINUM" },
{ CORSAIR_VID, CORSAIR_STRAFE_PID, 1, "Corsair Strafe" },
{ CORSAIR_VID, CORSAIR_STRAFE_MK2_PID, 1, "Corsair Strafe MK.2" },
/*-----------------------------------------------------------------------------------------------------*\
| Mice |
\*-----------------------------------------------------------------------------------------------------*/
{ CORSAIR_VID, CORSAIR_GLAIVE_RGB_PRO_PID, 1, "Corsair Glaive RGB PRO" },
{ CORSAIR_VID, CORSAIR_HARPOON_RGB_PID, 1, "Corsair Harpoon RGB" },
{ CORSAIR_VID, CORSAIR_HARPOON_RGB_PRO_PID, 1, "Corsair Harpoon RGB PRO" },
{ CORSAIR_VID, CORSAIR_M65_PRO_PID, 1, "Corsair M65 PRO" },
{ CORSAIR_VID, CORSAIR_M65_RGB_ELITE_PID, 1, "Corsair M65 RGB Elite" },
/*-----------------------------------------------------------------------------------------------------*\
| Mousemats |
\*-----------------------------------------------------------------------------------------------------*/
{ CORSAIR_VID, CORSAIR_MM800_RGB_POLARIS_PID, 0, "Corsair MM800 RGB Polaris" }
{ CORSAIR_VID, CORSAIR_MM800_RGB_POLARIS_PID, 0, "Corsair MM800 RGB Polaris" },
/*-----------------------------------------------------------------------------------------------------*\
| Headset Stands |
\*-----------------------------------------------------------------------------------------------------*/
{ CORSAIR_VID, CORSAIR_ST100_PID, 0, "Corsair ST100 RGB" }
};
/******************************************************************************************\
@@ -108,30 +130,31 @@ void DetectCorsairPeripheralControllers(std::vector<RGBController*>& rgb_control
while(info)
{
if((info->vendor_id == device_list[device_idx].usb_vid)
#ifdef USE_HID_USAGE
&&(info->product_id == device_list[device_idx].usb_pid)
&&(info->usage_page == 0xFFC2))
#else
&&(info->product_id == device_list[device_idx].usb_pid)
&&(info->interface_number == device_list[device_idx].usb_interface))
#endif
{
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
if( dev )
{
CorsairPeripheralController* controller = new CorsairPeripheralController(dev);
if( dev )
{
CorsairPeripheralController* controller = new CorsairPeripheralController(dev);
if(controller->GetDeviceType() != DEVICE_TYPE_UNKNOWN)
{
RGBController_CorsairPeripheral* rgb_controller = new RGBController_CorsairPeripheral(controller);
if(controller->GetDeviceType() != DEVICE_TYPE_UNKNOWN)
{
RGBController_CorsairPeripheral* rgb_controller = new RGBController_CorsairPeripheral(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
}
info = info->next;
}
}
}
@@ -10,16 +10,7 @@
#include "CorsairVengeanceProController.h"
#include <cstring>
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
using namespace std::chrono_literals;
CorsairVengeanceProController::CorsairVengeanceProController(i2c_smbus_interface* bus, corsair_dev_id dev)
{
@@ -89,9 +80,9 @@ void CorsairVengeanceProController::SetLEDColor(unsigned int led, unsigned char
void CorsairVengeanceProController::ApplyColors()
{
bus->i2c_smbus_write_byte_data(dev, 0x26, 0x02);
Sleep(1);
std::this_thread::sleep_for(1ms);
bus->i2c_smbus_write_byte_data(dev, 0x21, 0x00);
Sleep(1);
std::this_thread::sleep_for(1ms);
for (int i = 0; i < 10; i++)
{
@@ -119,9 +110,9 @@ void CorsairVengeanceProController::SetEffect(unsigned char mode,
effect_mode = mode;
bus->i2c_smbus_write_byte_data(dev, 0x26, 0x01);
Sleep(1);
std::this_thread::sleep_for(1ms);
bus->i2c_smbus_write_byte_data(dev, 0x21, 0x00);
Sleep(1);
std::this_thread::sleep_for(1ms);
unsigned char random_byte;
@@ -165,7 +156,7 @@ bool CorsairVengeanceProController::WaitReady()
while (bus->i2c_smbus_read_byte_data(dev, 0x41) != 0x00)
{
i++;
Sleep(1);
std::this_thread::sleep_for(1ms);
}
return false;
@@ -6,16 +6,7 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
using namespace std::chrono_literals;
/******************************************************************************************\
* *
@@ -50,7 +41,7 @@ bool TestForCorsairVengeanceProController(i2c_smbus_interface* bus, unsigned cha
}
}
Sleep(10);
std::this_thread::sleep_for(10ms);
return(pass);
@@ -0,0 +1,187 @@
/*-----------------------------------------*\
| DuckyKeyboardController.cpp |
| |
| Driver for Ducky RGB keyboardlighting |
| controller |
| |
| Adam Honse (CalcProgrammer1) 7/4/2020 |
\*-----------------------------------------*/
#include <cstring>
#include "DuckyKeyboardController.h"
DuckyKeyboardController::DuckyKeyboardController(hid_device* dev_handle)
{
dev = dev_handle;
SendInitialize();
}
DuckyKeyboardController::~DuckyKeyboardController()
{
}
void DuckyKeyboardController::SendColors
(
unsigned char* color_data,
unsigned int color_data_size
)
{
unsigned int bytes_sent;
unsigned char* color_data_ptr = color_data;
SendInitializeColorPacket();
for(int i = 0; i < 8; i++)
{
bytes_sent = SendColorDataPacket(i, color_data_ptr, color_data_size);
color_data_ptr += bytes_sent;
color_data_size -= bytes_sent;
}
SendTerminateColorPacket();
}
void DuckyKeyboardController::SendInitialize()
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Initialize Direct Mode packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x41;
usb_buf[0x02] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void DuckyKeyboardController::SendInitializeColorPacket()
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Initialize Color packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x56;
usb_buf[0x02] = 0x81;
usb_buf[0x05] = 0x01;
usb_buf[0x09] = 0x08;
usb_buf[0x0D] = 0xAA;
usb_buf[0x0E] = 0xAA;
usb_buf[0x0F] = 0xAA;
usb_buf[0x10] = 0xAA;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
unsigned int DuckyKeyboardController::SendColorDataPacket
(
unsigned char packet_id,
unsigned char* color_data,
unsigned int color_size
)
{
unsigned int bytes_sent;
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Color Data packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x56;
usb_buf[0x02] = 0x83;
usb_buf[0x03] = packet_id;
if(packet_id == 0x00)
{
usb_buf[0x05] = 0x01;
usb_buf[0x09] = 0x80;
usb_buf[0x0A] = 0x01;
usb_buf[0x0C] = 0xC1;
usb_buf[0x11] = 0xFF;
usb_buf[0x12] = 0xFF;
usb_buf[0x13] = 0xFF;
usb_buf[0x14] = 0xFF;
}
/*-----------------------------------------------------*\
| Copy in color data |
\*-----------------------------------------------------*/
if(packet_id == 0x00)
{
bytes_sent = 65 - 0x19;
if(color_size < bytes_sent)
{
bytes_sent = color_size;
}
memcpy(&usb_buf[0x19], color_data, bytes_sent);
}
else
{
bytes_sent = 65 - 0x05;
if(color_size < bytes_sent)
{
bytes_sent = color_size;
}
memcpy(&usb_buf[0x05], color_data, bytes_sent);
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
return(bytes_sent);
}
void DuckyKeyboardController::SendTerminateColorPacket()
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Terminate Color packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x51;
usb_buf[0x02] = 0x28;
usb_buf[0x05] = 0xFF;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
@@ -0,0 +1,41 @@
/*-----------------------------------------*\
| DuckyKeyboardController.h |
| |
| Definitions and types for Ducky RGB |
| keyboard lighting controller |
| |
| Adam Honse (CalcProgrammer1) 7/4/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
class DuckyKeyboardController
{
public:
DuckyKeyboardController(hid_device* dev_handle);
~DuckyKeyboardController();
void SendColors
(
unsigned char* color_data,
unsigned int color_data_size
);
private:
hid_device* dev;
void SendInitialize();
void SendInitializeColorPacket();
unsigned int SendColorDataPacket
(
unsigned char packet_id,
unsigned char* color_data,
unsigned int color_size
);
void SendTerminateColorPacket();
};
@@ -0,0 +1,81 @@
#include "DuckyKeyboardController.h"
#include "RGBController.h"
#include "RGBController_DuckyKeyboard.h"
#include <vector>
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| Ducky vendor ID |
\*-----------------------------------------------------*/
#define DUCKY_VID 0x04D9
/*-----------------------------------------------------*\
| Keyboard product IDs |
\*-----------------------------------------------------*/
#define DUCKY_SHINE_7_ONE_2_RGB_PID 0x0348
#define DUCKY_ONE_2_RGB_TKL_PID 0x0356
typedef struct
{
unsigned short usb_vid;
unsigned short usb_pid;
unsigned char usb_interface;
const char * name;
} ducky_device;
#define DUCKY_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
static const ducky_device device_list[] =
{
/*-----------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-----------------------------------------------------------------------------------------------------*/
{ DUCKY_VID, DUCKY_SHINE_7_ONE_2_RGB_PID, 1, "Ducky Shine 7/Ducky One 2 RGB" },
{ DUCKY_VID, DUCKY_ONE_2_RGB_TKL_PID, 1, "Ducky One 2 RGB TKL" },
};
/******************************************************************************************\
* *
* DetectDuckyKeyboardControllers *
* *
* Tests the USB address to see if a Ducky RGB Keyboard controller exists there. *
* *
\******************************************************************************************/
void DetectDuckyKeyboardControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device_info* info;
hid_device* dev;
hid_init();
for(std::size_t device_idx = 0; device_idx < DUCKY_NUM_DEVICES; device_idx++)
{
dev = NULL;
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for Ducky RGB Peripheral
while(info)
{
if((info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid)
&&(info->interface_number == device_list[device_idx].usb_interface))
{
dev = hid_open_path(info->path);
if( dev )
{
DuckyKeyboardController* controller = new DuckyKeyboardController(dev);
RGBController_DuckyKeyboard* rgb_controller = new RGBController_DuckyKeyboard(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
info = info->next;
}
}
}
+92
View File
@@ -0,0 +1,92 @@
/*-------------------------------------------------------------------*\
| EKController.cpp |
| |
| Driver for EK Loop Connect |
| |
| Chris M (Dr_No) 16th Jul 2020 |
| |
\*-------------------------------------------------------------------*/
#include "EKController.h"
EKController::EKController(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path)
{
int tmp_size = wcslen(_vendor);
dev = dev_handle;
for(int i=0; (i < tmp_size) && (i < EK_DEVICE_NAME_SIZE); i++)
{
device_name[i] = (char)_vendor[i];
}
for(int j=0; (j < wcslen(_vendor)) && ((tmp_size + j) < EK_DEVICE_NAME_SIZE); j++)
{
device_name[tmp_size+j] = (char)_device_name[j];
}
location = _path;
current_mode = EK_MODE_STATIC;
current_speed = EK_SPEED_NORMAL;
}
EKController::~EKController()
{
hid_close(dev);
}
char* EKController::GetDeviceName()
{
return device_name;
}
char* EKController::GetSerial()
{
return serial;
}
std::string EKController::GetLocation()
{
return location;
}
void EKController::SetMode(unsigned char mode, unsigned char speed)
{
current_mode = mode;
current_speed = speed;
SendUpdate();
}
void EKController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
{
current_red = red;
current_green = green;
current_blue = blue;
SendUpdate();
}
void EKController::SendUpdate()
{
unsigned char buffer[EK_PACKET_LENGTH] = { 0x00 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
for(int i = 0; i < EK_COLOUR_MODE_DATA_SIZE; i++)
{
buffer[i] = colour_mode_data[current_mode][i];
}
//Set the relevant colour info
buffer[EK_RED_BYTE] = current_red;
buffer[EK_GREEN_BYTE] = current_green;
buffer[EK_BLUE_BYTE] = current_blue;
buffer[EK_SPEED_BYTE] = speed_mode_data[current_mode][current_speed];
buffer[10] = 0x10;
buffer[47] = 0xFF;
buffer[48] = 0x00;
hid_write(dev, buffer, buffer_size);
}
+119
View File
@@ -0,0 +1,119 @@
/*-------------------------------------------------------------------*\
| EKController.h |
| |
| Driver for EK Loop Connect |
| |
| Chris M (Dr_No) 16th Jul 2020 |
| |
\*-------------------------------------------------------------------*/
#ifndef EKCONTROLLER_H
#define EKCONTROLLER_H
#include <string>
#include <hidapi/hidapi.h>
#define EK_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
#define EK_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
#define EK_PACKET_LENGTH 0x3F
enum
{
EK_MODE_BYTE = 12,
EK_SPEED_BYTE = 14,
EK_RED_BYTE = 16,
EK_GREEN_BYTE = 17,
EK_BLUE_BYTE = 18
};
enum
{
EK_MODE_STATIC = 0x00, //Static Mode
EK_MODE_BREATHING = 0x01, //Breathing Mode
EK_MODE_FADING = 0x02, //Fading Mode
EK_MODE_MARQUEE = 0x03, //Marquee Mode
EK_MODE_COVERING_MARQUEE = 0x04, //Covering Marquee Mode
EK_MODE_PULSE = 0x05, //Pulse Mode
EK_MODE_SPECTRUM_WAVE = 0x06, //Spectrum Wave Mode
EK_MODE_ALTERNATING = 0x07, //Alternating Mode
EK_MODE_CANDLE = 0x08 //Candle Mode
};
static unsigned char colour_mode_data[][16] =
{
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
0x00, 0x10, 0x20, 0x01, 0x01, 0x00, 0xFF, 0x64}, // Static
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
0x00, 0x10, 0x20, 0x01, 0x02, 0x00, 0xFF, 0x64}, // Breathing
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
0x00, 0x10, 0x20, 0x01, 0x03, 0xFF, 0xFF, 0x64}, // Fading
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
0x00, 0x10, 0x20, 0x01, 0x04, 0x00, 0xFF, 0x64}, // Marquee
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
0x00, 0x10, 0x20, 0x01, 0x05, 0x00, 0xFF, 0x64}, // Covering Marquee
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
0x00, 0x10, 0x20, 0x01, 0x06, 0x00, 0xFF, 0x64}, // Pulse
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
0x00, 0x10, 0x20, 0x01, 0x07, 0x00, 0xFF, 0x64}, // Wave
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
0x00, 0x10, 0x20, 0x01, 0x08, 0x00, 0xFF, 0x64}, // Alternating
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
0x00, 0x10, 0x20, 0x01, 0x09, 0x00, 0xFF, 0x64}, // Candle
};
static unsigned char speed_mode_data[][9] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Static
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Breathing
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Fading
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Marquee
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Covering Marquee
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Pulse
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Wave
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Alternating
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 } // Candle
};
enum
{
EK_SPEED_SLOWEST = 0x00, // Slowest speed
EK_SPEED_SLOWER = 0x01, // Slower speed
EK_SPEED_SLOW = 0x02, // Slow speed
EK_SPEED_SLOWISH = 0x03, // Slowish speed
EK_SPEED_NORMAL = 0x04, // Normal speed
EK_SPEED_FASTISH = 0x05, // Fastish speed
EK_SPEED_FAST = 0x06, // Fast speed
EK_SPEED_FASTER = 0x07, // Faster speed
EK_SPEED_FASTEST = 0x08, // Fastest speed
};
class EKController
{
public:
EKController(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path);
~EKController();
char* GetDeviceName();
char* GetSerial();
std::string GetLocation();
void SetMode(unsigned char mode, unsigned char speed);
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
private:
char device_name[32];
char serial[32];
std::string location;
hid_device* dev;
unsigned char current_mode;
unsigned char current_speed;
unsigned char current_red;
unsigned char current_green;
unsigned char current_blue;
void SendUpdate();
};
#endif // EKCONTROLLER_H
@@ -0,0 +1,64 @@
#include "EKController.h"
#include "RGBController.h"
#include "RGBController_EKController.h"
#include <hidapi/hidapi.h>
#define EK_VID 0x0483
#define EK_LOOP_CONNECT 0x5750
#define EK_NUM_DEVICES (sizeof(ek_pids) / sizeof(ek_pids[ 0 ]))
enum
{
EK_PID = 0,
EK_INTERFACE = 1
};
static const unsigned int ek_pids[][2] =
{ // PID, Interface
{ EK_LOOP_CONNECT, 0x00 } //EK Loop Connect
};
/******************************************************************************************\
* *
* DetectEKControllers *
* *
* Tests the USB address to see if any EK Controllers exists there. *
* *
\******************************************************************************************/
void DetectEKControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device_info* info;
//Look for the passed in cm_pids
hid_init();
info = hid_enumerate(0x0, 0x0);
while(info)
{
hid_device* dev = NULL;
if(info->vendor_id == EK_VID)
{
for(int ek_pid_idx = 0; ek_pid_idx < EK_NUM_DEVICES; ek_pid_idx++)
{
if((info->product_id == ek_pids[ek_pid_idx][EK_PID])
&&(info->interface_number == ek_pids[ek_pid_idx][EK_INTERFACE]))
{
dev = hid_open_path(info->path);
break;
}
}
}
if(dev)
{
EKController* controller = new EKController(dev, info->manufacturer_string, info->product_string, info->path);
RGBController_EKController* rgb_controller = new RGBController_EKController(controller);
rgb_controllers.push_back(rgb_controller);
}
info = info->next;
}
hid_free_enumeration(info);
}
@@ -0,0 +1,106 @@
/*-----------------------------------------*\
| GalaxGPUController.cpp |
| |
| Driver for Galax / KFA2 RGB on GPUs |
| |
| Niels Westphal (crashniels) 12.07.2020 |
\*-----------------------------------------*/
#include "GalaxGPUController.h"
#include <cstring>
GalaxGPUController::GalaxGPUController(i2c_smbus_interface* bus, galax_gpu_dev_id dev)
{
this->bus = bus;
this->dev = dev;
strcpy(device_name, "Galax RTX GPU"); // Would be nice to get the actual GPU name. Using this as a placeholder.
}
GalaxGPUController::~GalaxGPUController()
{
}
std::string GalaxGPUController::GetDeviceName()
{
return(device_name);
}
std::string GalaxGPUController::GetDeviceLocation()
{
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
return_string.append(addr);
return(return_string);
}
unsigned char GalaxGPUController::GetLEDRed()
{
return(GalaxGPURegisterRead(GALAX_RED_REGISTER));
}
unsigned char GalaxGPUController::GetLEDGreen()
{
return(GalaxGPURegisterRead(GALAX_GREEN_REGISTER));
}
unsigned char GalaxGPUController::GetLEDBlue()
{
return(GalaxGPURegisterRead(GALAX_BLUE_REGISTER));
}
void GalaxGPUController::SetLEDColorsDirect(unsigned char red, unsigned char green, unsigned char blue) // Direct Mode is just Static Mode without applying color changes
{
GalaxGPURegisterWrite(GALAX_RED_REGISTER, red);
GalaxGPURegisterWrite(GALAX_GREEN_REGISTER, green);
GalaxGPURegisterWrite(GALAX_BLUE_REGISTER, blue);
}
void GalaxGPUController::SetLEDColorsEffect(unsigned char red, unsigned char green, unsigned char blue)
{
GalaxGPURegisterWrite(GALAX_RED_REGISTER, red);
GalaxGPURegisterWrite(GALAX_GREEN_REGISTER, green);
GalaxGPURegisterWrite(GALAX_BLUE_REGISTER, blue);
}
void GalaxGPUController::SetMode(unsigned char mode)
{
switch(mode)
{
case 1:
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_1, GALAX_MODE_STATIC_VALUE_1);
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_2, GALAX_MODE_STATIC_VALUE_2);
break;
case 2:
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_1, GALAX_MODE_BREATHING_VALUE_1);
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_2, GALAX_MODE_BREATHING_VALUE_2);
break;
case 3:
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_1, GALAX_MODE_RAINBOW_VALUE_1);
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_2, GALAX_MODE_RAINBOW_VALUE_2);
break;
case 4:
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_1, GALAX_MODE_CYCLE_BREATHING_VALUE_1);
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_2, GALAX_MODE_CYCLE_BREATHING_VALUE_2);
break;
default:
break;
}
}
unsigned char GalaxGPUController::GalaxGPURegisterRead(unsigned char reg)
{
return(bus->i2c_smbus_read_byte_data(dev, reg));
}
void GalaxGPUController::GalaxGPURegisterWrite(unsigned char reg, unsigned char val)
{
bus->i2c_smbus_write_byte_data(dev, reg, val);
}
@@ -0,0 +1,67 @@
/*-----------------------------------------*\
| GalaxGPUController.h |
| |
| Driver for Galax / KFA2 RGB on GPUs |
| |
| Niels Westphal (crashniels) 12.07.2020 |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char galax_gpu_dev_id;
enum
{
/* RGB Registers */
GALAX_RED_REGISTER = 0x02, /* Red Register */
GALAX_GREEN_REGISTER = 0x03, /* Green Register */
GALAX_BLUE_REGISTER = 0x04, /* Blue Register */
/* MODE Registers */
GALAX_MODE_REGISTER_1 = 0x05, /* Mode Register 1 */
GALAX_MODE_REGISTER_2 = 0x06, /* Mode Register 2 */
};
enum
{
/* Static Mode Values */
GALAX_MODE_STATIC_VALUE_1 = 0x00,
GALAX_MODE_STATIC_VALUE_2 = 0x01,
/* Breathing Mode Values */
GALAX_MODE_BREATHING_VALUE_1 = 0x04,
GALAX_MODE_BREATHING_VALUE_2 = 0x00,
/* Rainbow Mode Values */
GALAX_MODE_RAINBOW_VALUE_1 = 0x84,
GALAX_MODE_RAINBOW_VALUE_2 = 0x02,
/* Cycle Breathing Mode Values */
GALAX_MODE_CYCLE_BREATHING_VALUE_1 = 0x84,
GALAX_MODE_CYCLE_BREATHING_VALUE_2 = 0x40,
};
class GalaxGPUController
{
public:
GalaxGPUController(i2c_smbus_interface* bus, galax_gpu_dev_id);
~GalaxGPUController();
std::string GetDeviceName();
std::string GetDeviceLocation();
unsigned char GetLEDRed();
unsigned char GetLEDGreen();
unsigned char GetLEDBlue();
void SetLEDColorsDirect(unsigned char red, unsigned char green, unsigned char blue);
void SetLEDColorsEffect(unsigned char red, unsigned char green, unsigned char blue);
void SetMode(unsigned char mode);
unsigned char GalaxGPURegisterRead(unsigned char reg);
void GalaxGPURegisterWrite(unsigned char reg, unsigned char val);
bool direct = false; // Temporary solution to check if we are in "Direct" mode
private:
char device_name[16];
i2c_smbus_interface * bus;
galax_gpu_dev_id dev;
};
@@ -0,0 +1,68 @@
/*-----------------------------------------*\
| GalaxGPUControllerDetect.cpp |
| |
| Driver for Galax / KFA2 RGB on GPUs |
| |
| Niels Westphal (crashniels) 12.07.2020 |
\*-----------------------------------------*/
#include "GalaxGPUController.h"
#include "RGBController.h"
#include "RGBController_GalaxGPU.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std::chrono_literals;
/******************************************************************************************\
* *
* TestForGalaxGPUController *
* *
* Tests the given address to see if a Galax GPU controller exists there. *
* *
\******************************************************************************************/
bool TestForGalaxGPUController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
unsigned char res = bus->i2c_smbus_read_byte_data(address, 0x00);
unsigned char res2 = bus->i2c_smbus_read_byte_data(address, 0x01);
if(res == 0x27 && res2 == 0x10)
{
pass = true;
}
return(pass);
} /* TestForGalaxGPUController() */
/******************************************************************************************\
* *
* DetectGalaxGPUControllers *
* *
* Detect Galax GPU controllers on the enumerated I2C busses. *
* *
\******************************************************************************************/
void DetectGalaxGPUControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
GalaxGPUController* new_GalaxGPU;
RGBController_GalaxGPU* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Check for GALAX controller at 0x23
if (TestForGalaxGPUController(busses[bus], 0x23))
{
new_GalaxGPU = new GalaxGPUController(busses[bus], 0x23);
new_controller = new RGBController_GalaxGPU(new_GalaxGPU);
rgb_controllers.push_back(new_controller);
}
}
} /* DetectGalaxGPUControllers() */
@@ -0,0 +1,278 @@
/*-----------------------------------------*\
| RGBController_GloriousModelO.cpp |
| |
| Definitions and types for Glorious |
| and other Mice |
| |
| Niels Westphal (crashniels) 20/5/2020 |
\*-----------------------------------------*/
#include "GloriousModelOController.h"
#include <cstring>
using namespace std::chrono_literals;
GloriousModelOController::GloriousModelOController(hid_device* dev_handle)
{
dev = dev_handle;
strcpy(device_name, "Glorious Mouse");
led_count = 1;
current_mode = GLORIOUS_MODE_STATIC;
current_speed = GLORIOUS_SPEED_NORMAL;
current_direction = GLORIOUS_DIRECTION_UP;
}
GloriousModelOController::~GloriousModelOController()
{
}
std::string GloriousModelOController::GetDeviceName()
{
return(device_name);
}
unsigned int GloriousModelOController::GetLEDCount()
{
return(led_count);
}
void GloriousModelOController::SetLEDColor(RGBColor* color_buf)
{
unsigned char usb_buf[520] =
{
0x04, 0x11, 0x00, 0x7b,
0x00, 0x00, 0x00, 0x00, 0x64, 0x06, 0x04, 0x24,
0xf0, 0x03, 0x07, 0x0f, 0x1f, 0x31, 0x63, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x41, 0x01, 0x40, 0xff, 0xff, 0xff,
0x42, 0x07, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff,
0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x43,
0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x42, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x42, 0x02, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
usb_buf[0x0B] = 0x24;
usb_buf[0x35] = GLORIOUS_MODE_STATIC;
usb_buf[0x38] = 0x40; //max brightness
usb_buf[0x39] = RGBGetRValue(color_buf[0]);
usb_buf[0x3A] = RGBGetBValue(color_buf[0]);
usb_buf[0x3B] = RGBGetGValue(color_buf[0]);
//DPI Button
/*
usb_buf[0x0B] = 0x44; //third DPI
usb_buf[0x26] = red;
usb_buf[0x27] = blue;
usb_buf[0x28] = green;
*/
hid_send_feature_report(dev, usb_buf, sizeof(usb_buf));
std::this_thread::sleep_for(1ms);
}
void GloriousModelOController::SetMode(unsigned char mode,
unsigned char speed,
unsigned char direction,
RGBColor* color_buf)
{
unsigned char usb_buf[520] =
{
0x04, 0x11, 0x00, 0x7b,
0x00, 0x00, 0x00, 0x00, 0x64, 0x06, 0x04, 0x24,
0xf0, 0x03, 0x07, 0x0f, 0x1f, 0x31, 0x63, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x41, 0x01, 0x40, 0xff, 0xff, 0xff,
0x42, 0x07, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff,
0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x43,
0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x42, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x42, 0x02, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
usb_buf[0x35] = mode;
switch (mode)
{
case GLORIOUS_MODE_OFF:
usb_buf[0x81] = 0x00; //mode 0 either 0x00 or 0x03
break;
case GLORIOUS_MODE_RAINBOW:
usb_buf[0x36] = speed;
usb_buf[0x37] = direction;
break;
case GLORIOUS_MODE_SPECTRUM_BREATING:
//colours not yet researched
usb_buf[0x3C] = speed; //speed for mode 3
usb_buf[0x3D] = 0x07; //maybe some kind of bank change?+
//usb_buf[0x3D] = 0x06;
usb_buf[0x3E] = RGBGetRValue(color_buf[0]); //mode 3 red 1
usb_buf[0x3F] = RGBGetBValue(color_buf[0]); //mode 3 blue 1
usb_buf[0x40] = RGBGetGValue(color_buf[0]); //mode 3 green 1
usb_buf[0x41] = RGBGetRValue(color_buf[1]); //mode 3 red 2
usb_buf[0x42] = RGBGetBValue(color_buf[1]); //mode 3 blue 2
usb_buf[0x43] = RGBGetGValue(color_buf[1]); //mode 3 green 2
usb_buf[0x44] = RGBGetRValue(color_buf[2]); //mode 3 red 3
usb_buf[0x45] = RGBGetBValue(color_buf[2]); //mode 3 blue 3
usb_buf[0x46] = RGBGetGValue(color_buf[2]); //mode 3 green 3
usb_buf[0x47] = RGBGetRValue(color_buf[3]); //mode 3 red 4
usb_buf[0x48] = RGBGetBValue(color_buf[3]); //mode 3 blue 4
usb_buf[0x49] = RGBGetGValue(color_buf[3]); //mode 3 green 4
usb_buf[0x4A] = RGBGetRValue(color_buf[4]); //mode 3 red 5
usb_buf[0x4B] = RGBGetBValue(color_buf[4]); //mode 3 blue 5
usb_buf[0x4C] = RGBGetGValue(color_buf[4]); //mode 3 green 5
usb_buf[0x4D] = RGBGetRValue(color_buf[5]); //mode 3 red 6
usb_buf[0x4E] = RGBGetBValue(color_buf[5]); //mode 3 blue 6
usb_buf[0x4F] = RGBGetGValue(color_buf[5]); //mode 3 green 6
usb_buf[0x50] = RGBGetRValue(color_buf[6]); //mode 3 red 7
usb_buf[0x51] = RGBGetBValue(color_buf[6]); //mode 3 blue 7
usb_buf[0x52] = RGBGetGValue(color_buf[6]); //mode 3 green 7
break;
case GLORIOUS_MODE_TAIL:
usb_buf[0x53] = speed; //Speed for mode 4
break;
case GLORIOUS_MODE_SPECTRUM_CYCLE:
usb_buf[0x54] = speed; //Speed for mode 1,2,5
break;
case GLORIOUS_MODE_RAVE:
usb_buf[0x74] = speed; //Speed for mode 7
usb_buf[0x75] = RGBGetRValue(color_buf[0]); //mode 7 red 1
usb_buf[0x76] = RGBGetBValue(color_buf[0]); //mode 7 blue 1
usb_buf[0x77] = RGBGetGValue(color_buf[0]); //mode 7 green 1
usb_buf[0x78] = RGBGetRValue(color_buf[1]); //mode 7 red 2
usb_buf[0x79] = RGBGetBValue(color_buf[1]); //mode 7 blue 2
usb_buf[0x7A] = RGBGetGValue(color_buf[1]); //mode 7 green 2
break;
case GLORIOUS_MODE_WAVE:
usb_buf[0x7C] = speed; //Speed for mode 9
break;
case GLORIOUS_MODE_BREATHING:
usb_buf[0x7D] = speed;
usb_buf[0x7E] = RGBGetRValue(color_buf[0]); //mode 0a red
usb_buf[0x7F] = RGBGetBValue(color_buf[0]); //mode 0a blue
usb_buf[0x80] = RGBGetGValue(color_buf[0]); //mode 0a green
default:
break;
}
hid_send_feature_report(dev, usb_buf, sizeof(usb_buf));
std::this_thread::sleep_for(1ms);
}
@@ -0,0 +1,71 @@
/*-----------------------------------------*\
| GloriousModelOController.h |
| |
| Definitions and types for Glorious |
| and other Mice |
| |
| Niels Westphal (crashniels) 20/5/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
enum
{
GLORIOUS_MODE_OFF = 0x00, //does nothing
GLORIOUS_MODE_RAINBOW = 0x01,
GLORIOUS_MODE_STATIC = 0x02,
GLORIOUS_MODE_SPECTRUM_BREATING = 0x03,
GLORIOUS_MODE_TAIL = 0x04,
GLORIOUS_MODE_SPECTRUM_CYCLE = 0x05,
GLORIOUS_MODE_RAVE = 0x07,
GLORIOUS_MODE_EPILEPSY = 0x08, //not in the official software
GLORIOUS_MODE_WAVE = 0x09,
GLORIOUS_MODE_BREATHING = 0x0a,
};
enum
{
GLORIOUS_SPEED_SLOW = 0x41,
GLORIOUS_SPEED_NORMAL = 0x42,
GLORIOUS_SPEED_FAST = 0x43,
};
enum
{
GLORIOUS_DIRECTION_UP = 0x00,
GLORIOUS_DIRECTION_DOWN = 0x01,
};
enum
{
GLORIOUS_MODE_BREATING_SLOW = 0x01,
GLORIOUS_MODE_BREATING_NORMAL = 0x02,
GLORIOUS_MODE_BREATING_FAST = 0x03,
};
class GloriousModelOController
{
public:
GloriousModelOController(hid_device* dev_handle);
~GloriousModelOController();
std::string GetDeviceName();
unsigned int GetLEDCount();
void SetLEDColor(RGBColor* color_buf);
void SetMode(unsigned char mode, unsigned char speed, unsigned char direction, RGBColor* color_buf);
private:
hid_device* dev;
char device_name[32];
unsigned int led_count;
unsigned char current_mode;
unsigned char current_speed;
unsigned char current_direction;
};
@@ -0,0 +1,60 @@
#include "GloriousModelOController.h"
#include "RGBController.h"
#include "RGBController_GloriousModelO.h"
#include <vector>
#include <hidapi/hidapi.h>
#define Glorious_Model_O_VID 0x258A
#define Glorious_Model_O_PID 0x0036
/******************************************************************************************\
* *
* DetectGloriousModelController *
* *
* Tests the USB address to see if a Glorious Model O controller exists there. *
* *
\******************************************************************************************/
void DetectGloriousModelOControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device_info* info;
hid_device* dev = NULL;
hid_init();
dev = NULL;
info = hid_enumerate(Glorious_Model_O_VID, Glorious_Model_O_PID);
//Look for Glorious Model O
while(info)
{
if((info->vendor_id == Glorious_Model_O_VID)
&&(info->product_id == Glorious_Model_O_PID)
#ifdef USE_HID_USAGE
&&(info->interface_number == 1)
&&(info->usage_page == 0xFF00))
#else
&&(info->interface_number == 1))
#endif
{
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
if( dev )
{
GloriousModelOController* controller = new GloriousModelOController(dev);
RGBController_GloriousModelO* rgb_controller = new RGBController_GloriousModelO(controller);
rgb_controller->name = "Glorious Mouse";
rgb_controllers.push_back(rgb_controller);
}
}
@@ -1,53 +0,0 @@
#include "Hue2Controller.h"
#include "RGBController.h"
#include "RGBController_Hue2.h"
#include <vector>
#include <libusb-1.0/libusb.h>
#define NZXT_HUE_2_VID 0x1E71
#define NZXT_HUE_2_PID 0x2001
#define NZXT_SMART_DEVICE_V2_PID 0x2006
/******************************************************************************************\
* *
* DetectHue2Controllers *
* *
* Detect devices supported by the Hue2 driver *
* * *
\******************************************************************************************/
void DetectHue2Controllers(std::vector<RGBController*> &rgb_controllers)
{
libusb_context * ctx;
libusb_init(&ctx);
//Look for NZXT Hue 2
libusb_device_handle * hue_2_dev = libusb_open_device_with_vid_pid(ctx, NZXT_HUE_2_VID, NZXT_HUE_2_PID);
if( hue_2_dev )
{
libusb_detach_kernel_driver(hue_2_dev, 0);
libusb_claim_interface(hue_2_dev, 0);
Hue2Controller* controller = new Hue2Controller(hue_2_dev);
RGBController_Hue2* rgb_controller = new RGBController_Hue2(controller);
rgb_controllers.push_back(rgb_controller);
}
//Look for NZXT Smart Device V2
libusb_device_handle * smart_dev_2_dev = libusb_open_device_with_vid_pid(ctx, NZXT_HUE_2_VID, NZXT_SMART_DEVICE_V2_PID);
if( smart_dev_2_dev )
{
libusb_detach_kernel_driver(smart_dev_2_dev, 0);
libusb_claim_interface(smart_dev_2_dev, 0);
Hue2Controller* controller = new Hue2Controller(smart_dev_2_dev);
RGBController_Hue2* rgb_controller = new RGBController_Hue2(controller);
rgb_controllers.push_back(rgb_controller);
}
} /* DetectHuePlusControllers() */
@@ -11,16 +11,7 @@
#include <string>
#include <cstring>
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
using namespace std::chrono_literals;
HuePlusController::HuePlusController()
{
@@ -64,7 +55,7 @@ unsigned int HuePlusController::GetLEDsOnChannel(unsigned int channel)
serialport->serial_write((char *)serial_buf, 2);
serialport->serial_flush_tx();
Sleep(50);
std::this_thread::sleep_for(50ms);
int bytes_read = serialport->serial_read((char *)serial_buf, 5);
@@ -244,5 +235,5 @@ void HuePlusController::SendPacket
/*-----------------------------------------------------*\
| Delay to allow Hue+ device to ready for next packet |
\*-----------------------------------------------------*/
Sleep(20);
std::this_thread::sleep_for(20ms);
}
@@ -6,16 +6,7 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
using namespace std::chrono_literals;
/******************************************************************************************\
* *
@@ -76,7 +67,7 @@ void DetectHyperXDRAMControllers(std::vector<i2c_smbus_interface*> &busses, std:
{
busses[bus]->i2c_smbus_write_byte_data(0x37, 0x00, 0xFF);
Sleep(1);
std::this_thread::sleep_for(1ms);
for(int slot_addr = 0x50; slot_addr <= 0x57; slot_addr++)
{
@@ -89,7 +80,7 @@ void DetectHyperXDRAMControllers(std::vector<i2c_smbus_interface*> &busses, std:
slots_valid |= (1 << (slot_addr - 0x50));
}
Sleep(1);
std::this_thread::sleep_for(1ms);
}
if(slots_valid != 0)
@@ -0,0 +1,131 @@
/*-----------------------------------------*\
| HyperXAlloyOriginsController.cpp |
| |
| Driver for HyperX Alloy Origins RGB |
| Keyboard lighting controller |
| |
| Adam Honse (CalcProgrammer1) 7/11/2020 |
\*-----------------------------------------*/
#include "HyperXAlloyOriginsController.h"
#include <cstring>
// Skip these indices in the color output
static unsigned int skip_idx[] = { 6, 23, 29, 41, 47, 59, 70, 71, 75, 76, 87, 88, 93, 99, 100, 102, 108, 113, 114, 120, 123, 124 };
HyperXAlloyOriginsController::HyperXAlloyOriginsController(hid_device* dev_handle)
{
dev = dev_handle;
}
HyperXAlloyOriginsController::~HyperXAlloyOriginsController()
{
}
void HyperXAlloyOriginsController::SetLEDsDirect(std::vector<RGBColor> colors)
{
/*-----------------------------------------------------*\
| Insert color data for unused positions |
\*-----------------------------------------------------*/
for(unsigned int skip_cnt = 0; skip_cnt < (sizeof(skip_idx) / sizeof(skip_idx[0])); skip_cnt++)
{
colors.insert(colors.begin() + skip_idx[skip_cnt], 0x00000000);
}
/*-----------------------------------------------------*\
| Set up variables to track progress of color transmit |
| Do this after inserting blanks |
\*-----------------------------------------------------*/
int colors_to_send = colors.size();
int colors_sent = 0;
SendDirectInitialization();
for(int pkt_idx = 0; pkt_idx < 9; pkt_idx++)
{
if(colors_to_send > 16)
{
SendDirectColorPacket(&colors[colors_sent], 16);
colors_sent += 16;
colors_to_send -= 16;
}
else if(colors_to_send > 0)
{
SendDirectColorPacket(&colors[colors_sent], colors_to_send);
colors_sent += colors_to_send;
colors_to_send -= colors_to_send;
}
else
{
RGBColor temp = 0x00000000;
SendDirectColorPacket(&temp, 1);
}
}
}
void HyperXAlloyOriginsController::SendDirectInitialization()
{
unsigned char buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Direct Initialization packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x00;
buf[0x01] = 0x04;
buf[0x02] = 0xF2;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 65);
}
void HyperXAlloyOriginsController::SendDirectColorPacket
(
RGBColor* color_data,
unsigned int color_count
)
{
unsigned char buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Direct Initialization packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x00;
/*-----------------------------------------------------*\
| The maximum number of colors per packet is 16 |
\*-----------------------------------------------------*/
if(color_count > 16)
{
color_count = 16;
}
/*-----------------------------------------------------*\
| Copy in color data |
\*-----------------------------------------------------*/
for(int color_idx = 0; color_idx < color_count; color_idx++)
{
buf[(color_idx * 4) + 1] = 0x81;
buf[(color_idx * 4) + 2] = RGBGetRValue(color_data[color_idx]);
buf[(color_idx * 4) + 3] = RGBGetGValue(color_data[color_idx]);
buf[(color_idx * 4) + 4] = RGBGetBValue(color_data[color_idx]);
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 65);
}
@@ -0,0 +1,34 @@
/*-----------------------------------------*\
| HyperXAlloyOriginsController.h |
| |
| Definitions and types for HyperX Alloy |
| Origins RGB Keyboard lighting controller |
| |
| Adam Honse (CalcProgrammer1) 7/11/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
class HyperXAlloyOriginsController
{
public:
HyperXAlloyOriginsController(hid_device* dev_handle);
~HyperXAlloyOriginsController();
void SetLEDsDirect(std::vector<RGBColor> colors);
private:
hid_device* dev;
void SendDirectInitialization();
void SendDirectColorPacket
(
RGBColor* color_data,
unsigned int color_count
);
};
@@ -11,26 +11,17 @@
#include <cstring>
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
using namespace std::chrono_literals;
static unsigned int keys[] = {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1D, 0x1E, 0x20, 0x21, 0x22, 0x23, 0x24,
0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,
0x33, 0x34, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3E, 0x3F, 0x41, 0x44, 0x45,
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x51, 0x54, 0x55, 0x58, 0x59,
0x5A, 0x5B, 0x5C, 0x5E, 0x5F, 0x61, 0x64, 0x65, 0x68, 0x69, 0x6A, 0x6B, 0x6C,
0x6E, 0x6F, 0x74, 0x75, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x81,
0x84, 0x85, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x91, 0x94, 0x95 };
0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x20, 0x21, 0x22,
0x23, 0x24, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
0x31, 0x32, 0x33, 0x34, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3E, 0x3F, 0x41,
0x44, 0x45, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x51, 0x54, 0x55,
0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5E, 0x5F, 0x61, 0x64, 0x65, 0x68, 0x69, 0x6A,
0x6B, 0x6C, 0x6E, 0x6F, 0x74, 0x75, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E,
0x7F, 0x81, 0x84, 0x85, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x91,
0x94, 0x95 };
static unsigned int extended_red[] = {0x08, 0x48, 0x88, 0x09, 0x89, 0x0A, 0x8A, 0x0B, 0x8B, 0x0C, 0x8C, 0x0D, 0x8D, 0x0E, 0x8F, 0x8E, 0x0F, 0x4F, 0x92, 0x13, 0x93, 0x12 };
static unsigned int extended_grn[] = {0x29, 0x28, 0x78, 0x19, 0x79, 0x1A, 0x7A, 0x1B, 0x7B, 0x1C, 0x7C, 0x1D, 0x7D, 0x1E, 0x6E, 0x7E, 0x1F, 0x6F, 0x82, 0x23, 0x83, 0x22 };
@@ -107,17 +98,17 @@ void HyperXKeyboardController::SetMode
mode_colors[8]
);
Sleep(100);
std::this_thread::sleep_for(100ms);
}
void HyperXKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
{
unsigned char red_color_data[104];
unsigned char grn_color_data[104];
unsigned char blu_color_data[104];
unsigned char red_color_data[106];
unsigned char grn_color_data[106];
unsigned char blu_color_data[106];
unsigned char ext_color_data[150];
for(std::size_t i = 0; i < 104; i++)
for(std::size_t i = 0; i < 106; i++)
{
red_color_data[i] = RGBGetRValue(colors[i]);
grn_color_data[i] = RGBGetGValue(colors[i]);
@@ -126,9 +117,9 @@ void HyperXKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
for(std::size_t i = 0; i < 22; i++)
{
ext_color_data[extended_red[i]] = RGBGetRValue(colors[i + 104]);
ext_color_data[extended_grn[i]] = RGBGetGValue(colors[i + 104]);
ext_color_data[extended_blu[i]] = RGBGetBValue(colors[i + 104]);
ext_color_data[extended_red[i]] = RGBGetRValue(colors[i + 106]);
ext_color_data[extended_grn[i]] = RGBGetGValue(colors[i + 106]);
ext_color_data[extended_blu[i]] = RGBGetBValue(colors[i + 106]);
}
SendDirect
@@ -137,7 +128,7 @@ void HyperXKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
red_color_data
);
Sleep(5);
std::this_thread::sleep_for(5ms);
SendDirect
(
@@ -145,7 +136,7 @@ void HyperXKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
grn_color_data
);
Sleep(5);
std::this_thread::sleep_for(5ms);
SendDirect
(
@@ -153,7 +144,7 @@ void HyperXKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
blu_color_data
);
Sleep(5);
std::this_thread::sleep_for(5ms);
SendDirectExtended
(
@@ -163,12 +154,12 @@ void HyperXKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
void HyperXKeyboardController::SetLEDs(std::vector<RGBColor> colors)
{
unsigned char red_color_data[104];
unsigned char grn_color_data[104];
unsigned char blu_color_data[104];
unsigned char red_color_data[106];
unsigned char grn_color_data[106];
unsigned char blu_color_data[106];
unsigned char ext_color_data[150];
for(std::size_t i = 0; i < 104; i++)
for(std::size_t i = 0; i < 106; i++)
{
red_color_data[i] = RGBGetRValue(colors[i]);
grn_color_data[i] = RGBGetGValue(colors[i]);
@@ -177,9 +168,9 @@ void HyperXKeyboardController::SetLEDs(std::vector<RGBColor> colors)
for(std::size_t i = 0; i < 22; i++)
{
ext_color_data[extended_red[i]] = RGBGetRValue(colors[i + 104]);
ext_color_data[extended_grn[i]] = RGBGetGValue(colors[i + 104]);
ext_color_data[extended_blu[i]] = RGBGetBValue(colors[i + 104]);
ext_color_data[extended_red[i]] = RGBGetRValue(colors[i + 106]);
ext_color_data[extended_grn[i]] = RGBGetGValue(colors[i + 106]);
ext_color_data[extended_blu[i]] = RGBGetBValue(colors[i + 106]);
}
SendColor
@@ -189,7 +180,7 @@ void HyperXKeyboardController::SetLEDs(std::vector<RGBColor> colors)
red_color_data
);
Sleep(5);
std::this_thread::sleep_for(5ms);
SendColor
(
@@ -198,7 +189,7 @@ void HyperXKeyboardController::SetLEDs(std::vector<RGBColor> colors)
grn_color_data
);
Sleep(5);
std::this_thread::sleep_for(5ms);
SendColor
(
@@ -207,7 +198,7 @@ void HyperXKeyboardController::SetLEDs(std::vector<RGBColor> colors)
blu_color_data
);
Sleep(5);
std::this_thread::sleep_for(5ms);
SendExtendedColor
(
@@ -375,7 +366,7 @@ void HyperXKeyboardController::SendColor
/*-----------------------------------------------------*\
| Fill in color data |
\*-----------------------------------------------------*/
for(int i = 0; i < 104; i++)
for(int i = 0; i < 106; i++)
{
buf[keys[i]] = color_data[i];
}
@@ -440,11 +431,12 @@ void HyperXKeyboardController::SendDirect
buf[0x00] = 0x07;
buf[0x01] = HYPERX_PACKET_ID_DIRECT;
buf[0x02] = color_channel;
buf[0x03] = 0xA0;
/*-----------------------------------------------------*\
| Fill in color data |
\*-----------------------------------------------------*/
for(int i = 0; i < 104; i++)
for(int i = 0; i < 106; i++)
{
buf[keys[i]] = color_data[i];
}
@@ -473,6 +465,7 @@ void HyperXKeyboardController::SendDirectExtended
buf[0x00] = 0x07;
buf[0x01] = HYPERX_PACKET_ID_DIRECT;
buf[0x02] = HYPERX_COLOR_CHANNEL_EXTENDED;
buf[0x03] = 0xA0;
/*-----------------------------------------------------*\
| Fill in color data |
@@ -1,11 +1,38 @@
#include "HyperXAlloyOriginsController.h"
#include "HyperXKeyboardController.h"
#include "RGBController.h"
#include "RGBController_HyperXAlloyOrigins.h"
#include "RGBController_HyperXKeyboard.h"
#include <vector>
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| HyperX keyboard vendor IDs |
\*-----------------------------------------------------*/
#define HYPERX_KEYBOARD_VID 0x0951
#define HYPERX_ALLOY_ELITE_PID 0x16BE
#define HYPERX_ALLOY_FPS_RGB_PID 0x16DC
#define HYPERX_ALLOY_ORIGINS_PID 0x16E5
typedef struct
{
unsigned short usb_vid;
unsigned short usb_pid;
unsigned char usb_interface;
const char * name;
} hyperx_device;
#define HYPERX_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
static const hyperx_device device_list[] =
{
/*-----------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-----------------------------------------------------------------------------------------------------*/
{ HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ELITE_PID, 2, "HyperX Alloy Elite RGB" },
{ HYPERX_KEYBOARD_VID, HYPERX_ALLOY_FPS_RGB_PID, 2, "HyperX Alloy FPS RGB" },
{ HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_PID, 3, "HyperX Alloy Origins" },
};
/******************************************************************************************\
* *
@@ -22,30 +49,59 @@ void DetectHyperXKeyboardControllers(std::vector<RGBController*>& rgb_controller
hid_init();
info = hid_enumerate(HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ELITE_PID);
//Look for HyperX Keyboard, Interface 2
while(info)
for(std::size_t device_idx = 0; device_idx < HYPERX_NUM_DEVICES; device_idx++)
{
if((info->vendor_id == HYPERX_KEYBOARD_VID)
&&(info->product_id == HYPERX_ALLOY_ELITE_PID)
&&(info->interface_number == 2))
{
dev = hid_open_path(info->path);
break;
}
else
dev = NULL;
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for HyperX RGB Peripheral
while(info)
{
if((device_list[device_idx].usb_pid != HYPERX_ALLOY_ORIGINS_PID)
&&(info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid)
#ifdef USE_HID_USAGE
&&(info->interface_number == device_list[device_idx].usb_interface)
&&(info->usage_page == 0xFF01))
#else
&&(info->interface_number == device_list[device_idx].usb_interface))
#endif
{
dev = hid_open_path(info->path);
if( dev )
{
HyperXKeyboardController* controller = new HyperXKeyboardController(dev);
RGBController_HyperXKeyboard* rgb_controller = new RGBController_HyperXKeyboard(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
if((device_list[device_idx].usb_pid == HYPERX_ALLOY_ORIGINS_PID)
&&(info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid)
&&(info->interface_number == device_list[device_idx].usb_interface))
{
dev = hid_open_path(info->path);
if( dev )
{
HyperXAlloyOriginsController* controller = new HyperXAlloyOriginsController(dev);
RGBController_HyperXAlloyOrigins* rgb_controller = new RGBController_HyperXAlloyOrigins(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
info = info->next;
}
}
if( dev )
{
HyperXKeyboardController* controller = new HyperXKeyboardController(dev);
RGBController_HyperXKeyboard* rgb_controller = new RGBController_HyperXKeyboard(controller);
rgb_controllers.push_back(rgb_controller);
}
}
@@ -0,0 +1,76 @@
#include "HyperXPulsefireSurgeController.h"
#include "RGBController.h"
#include "RGBController_HyperXPulsefireSurge.h"
#include <vector>
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| HyperX keyboard vendor IDs |
\*-----------------------------------------------------*/
#define HYPERX_VID 0x0951
#define HYPERX_PULSEFIRE_SURGE_PID 0x16D3
typedef struct
{
unsigned short usb_vid;
unsigned short usb_pid;
unsigned char usb_interface;
const char * name;
} hyperx_device;
#define HYPERX_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
static const hyperx_device device_list[] =
{
/*-----------------------------------------------------------------------------------------------------*\
| Mice |
\*-----------------------------------------------------------------------------------------------------*/
{ HYPERX_VID, HYPERX_PULSEFIRE_SURGE_PID, 1, "HyperX Pulsefire Surge" },
};
/******************************************************************************************\
* *
* DetectHyperXMouseControllers *
* *
* Tests the USB address to see if a HyperX Mouse controller exists there. *
* *
\******************************************************************************************/
void DetectHyperXMouseControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device_info* info;
hid_device* dev = NULL;
hid_init();
for(std::size_t device_idx = 0; device_idx < HYPERX_NUM_DEVICES; device_idx++)
{
dev = NULL;
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for HyperX RGB Peripheral
while(info)
{
if((info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid)
&&(info->interface_number == device_list[device_idx].usb_interface))
{
dev = hid_open_path(info->path);
if( dev )
{
HyperXPulsefireSurgeController* controller = new HyperXPulsefireSurgeController(dev);
RGBController_HyperXPulsefireSurge* rgb_controller = new RGBController_HyperXPulsefireSurge(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
info = info->next;
}
}
}
@@ -0,0 +1,22 @@
/*-----------------------------------------*\
| HyperXPulsefireSurgeController.cpp |
| |
| Driver for HyperX Pulsefire Surge |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 7/25/2020 |
\*-----------------------------------------*/
#include "HyperXPulsefireSurgeController.h"
#include <cstring>
HyperXPulsefireSurgeController::HyperXPulsefireSurgeController(hid_device* dev_handle)
{
dev = dev_handle;
}
HyperXPulsefireSurgeController::~HyperXPulsefireSurgeController()
{
}
@@ -0,0 +1,25 @@
/*-----------------------------------------*\
| HyperXPulsefireSurgeController.h |
| |
| Definitions and types for HyperX |
| Pulsefire Surge lighting controller |
| |
| Adam Honse (CalcProgrammer1) 7/25/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
class HyperXPulsefireSurgeController
{
public:
HyperXPulsefireSurgeController(hid_device* dev_handle);
~HyperXPulsefireSurgeController();
private:
hid_device* dev;
};
@@ -0,0 +1,196 @@
#include "LogitechG203Controller.h"
#include "LogitechG403Controller.h"
#include "LogitechG810Controller.h"
#include "RGBController.h"
#include "RGBController_LogitechG203.h"
#include "RGBController_LogitechG403.h"
#include "RGBController_LogitechG810.h"
#include <vector>
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| Logitech vendor ID |
\*-----------------------------------------------------*/
#define LOGITECH_VID 0x046D
/*-----------------------------------------------------*\
| Keyboard product IDs |
\*-----------------------------------------------------*/
#define LOGITECH_G810_1_PID 0xC337
#define LOGITECH_G810_2_PID 0xC331
#define LOGITECH_G512_PID 0xC342
/*-----------------------------------------------------*\
| Mouse product IDs |
\*-----------------------------------------------------*/
#define LOGITECH_G203_PID 0xC084
#define LOGITECH_G403_PID 0xC083
#define LOGITECH_G403H_PID 0xC08F
typedef struct
{
unsigned short usb_vid;
unsigned short usb_pid;
unsigned char usb_interface;
device_type type;
const char * name;
} logitech_device;
#define LOGITECH_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
static const logitech_device device_list[] =
{
/*-------------------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-------------------------------------------------------------------------------------------------------------*/
{ LOGITECH_VID, LOGITECH_G810_1_PID, 1, DEVICE_TYPE_KEYBOARD, "Logitech G810 Orion Spectrum" },
{ LOGITECH_VID, LOGITECH_G810_2_PID, 1, DEVICE_TYPE_KEYBOARD, "Logitech G810 Orion Spectrum" },
{ LOGITECH_VID, LOGITECH_G512_PID, 1, DEVICE_TYPE_KEYBOARD, "Logitech G512" },
/*-------------------------------------------------------------------------------------------------------------*\
| Mice |
\*-------------------------------------------------------------------------------------------------------------*/
{ LOGITECH_VID, LOGITECH_G203_PID, 1, DEVICE_TYPE_MOUSE, "Logitech G203 Prodigy" },
{ LOGITECH_VID, LOGITECH_G403_PID, 1, DEVICE_TYPE_MOUSE, "Logitech G403 Prodigy" },
{ LOGITECH_VID, LOGITECH_G403H_PID, 1, DEVICE_TYPE_MOUSE, "Logitech G403 Hero" },
/*-------------------------------------------------------------------------------------------------------------*\
| Mousemats |
\*-------------------------------------------------------------------------------------------------------------*/
};
/******************************************************************************************\
* *
* DetectLogitechControllers *
* *
* Tests the USB address to see if a Logitech RGB Keyboard controller exists there. *
* *
\******************************************************************************************/
void DetectLogitechControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_init();
for(int device_idx = 0; device_idx < LOGITECH_NUM_DEVICES; device_idx++)
{
switch(device_list[device_idx].type)
{
/*-------------------------------------------------------------------------------------------------*\
| Logitech keyboards use two different usages, one for 20-byte packets and one for 64-byte packets |
| Usage 0x0602 for 20 byte, usage 0x0604 for 64 byte, both are on usage page 0xFF43 |
\*-------------------------------------------------------------------------------------------------*/
case DEVICE_TYPE_KEYBOARD:
{
hid_device_info* info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
while(info)
{
if((info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid)
#ifdef USE_HID_USAGE
&&(info->interface_number == device_list[device_idx].usb_interface)
&&(info->usage_page == 0xFF43)
&&(info->usage == 0x0602))
#else
&&(info->interface_number == device_list[device_idx].usb_interface))
#endif
{
hid_device* dev_usage_0x0602 = hid_open_path(info->path);
if(dev_usage_0x0602)
{
#ifdef USE_HID_USAGE
hid_device_info* tmp_info_0x0604 = info;
while(tmp_info_0x0604)
{
if((tmp_info_0x0604->vendor_id == device_list[device_idx].usb_vid)
&&(tmp_info_0x0604->product_id == device_list[device_idx].usb_pid)
&&(tmp_info_0x0604->interface_number == device_list[device_idx].usb_interface)
&&(tmp_info_0x0604->usage_page == 0xFF43)
&&(tmp_info_0x0604->usage == 0x0604))
{
hid_device* dev_usage_0x0604 = hid_open_path(tmp_info_0x0604->path);
if(dev_usage_0x0604)
{
LogitechG810Controller* controller = new LogitechG810Controller(dev_usage_0x0602, dev_usage_0x0604);
RGBController_LogitechG810* rgb_controller = new RGBController_LogitechG810(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
tmp_info_0x0604 = tmp_info_0x0604->next;
}
#else
LogitechG810Controller* controller = new LogitechG810Controller(dev_usage_0x0602, dev_usage_0x0602);
RGBController_LogitechG810* rgb_controller = new RGBController_LogitechG810(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
#endif
}
}
info = info->next;
}
hid_free_enumeration(info);
}
break;
/*-------------------------------------------------------------------------------------------------*\
| Logitech mice use a single usage on page 0xFF00 |
\*-------------------------------------------------------------------------------------------------*/
case DEVICE_TYPE_MOUSE:
{
hid_device_info* info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
while(info)
{
if((info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid)
#ifdef USE_HID_USAGE
&&(info->interface_number == device_list[device_idx].usb_interface)
&&(info->usage_page == 0xFF00)
&&(info->usage == 2))
#else
&&(info->interface_number == device_list[device_idx].usb_interface))
#endif
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
switch(device_list[device_idx].usb_pid)
{
case LOGITECH_G203_PID:
{
LogitechG203Controller* controller = new LogitechG203Controller(dev);
RGBController_LogitechG203* rgb_controller = new RGBController_LogitechG203(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
break;
case LOGITECH_G403_PID:
case LOGITECH_G403H_PID:
{
LogitechG403Controller* controller = new LogitechG403Controller(dev);
RGBController_LogitechG403* rgb_controller = new RGBController_LogitechG403(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
}
}
info = info->next;
}
hid_free_enumeration(info);
}
break;
}
}
}
@@ -0,0 +1,73 @@
/*-----------------------------------------*\
| LogitechG203Controller.cpp |
| |
| Driver for Logitech G203 Prodigy mouse |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 5/17/2020 |
\*-----------------------------------------*/
#include "LogitechG203Controller.h"
#include <cstring>
LogitechG203Controller::LogitechG203Controller(hid_device* dev_handle)
{
dev = dev_handle;
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void LogitechG203Controller::SendMouseMode
(
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x0E;
usb_buf[0x03] = 0x3C;
usb_buf[0x04] = 0x00;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 1000 + 4750 * (LOGITECH_G203_SPEED_FASTEST - speed);
if(mode == LOGITECH_G203_MODE_CYCLE)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = 0x64;
}
else if(mode == LOGITECH_G203_MODE_BREATHING)
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
usb_buf[0x0C] = 0x64;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 20);
hid_read(dev, (unsigned char *)usb_buf, 20);
}
@@ -0,0 +1,51 @@
/*-----------------------------------------*\
| LogitechG203Controller.h |
| |
| Definitions and types for Logitech G203 |
| Prodigy mouse lighting controller |
| |
| Adam Honse (CalcProgrammer1) 5/17/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
LOGITECH_G203_MODE_OFF = 0x00,
LOGITECH_G203_MODE_STATIC = 0x01,
LOGITECH_G203_MODE_CYCLE = 0x02,
LOGITECH_G203_MODE_BREATHING = 0x03,
};
enum
{
LOGITECH_G203_SPEED_SLOWEST = 0x00, /* Slowest speed */
LOGITECH_G203_SPEED_SLOW = 0x01, /* Slow speed */
LOGITECH_G203_SPEED_NORMAL = 0x02, /* Normal speed */
LOGITECH_G203_SPEED_FAST = 0x03, /* Fast speed */
LOGITECH_G203_SPEED_FASTEST = 0x04, /* Fastest speed */
};
class LogitechG203Controller
{
public:
LogitechG203Controller(hid_device* dev_handle);
~LogitechG203Controller();
void SendMouseMode
(
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
hid_device* dev;
};
@@ -0,0 +1,75 @@
/*-----------------------------------------*\
| LogitechG403Controller.cpp |
| |
| Driver for Logitech G403 Prodigy mouse |
| lighting controller |
| |
| Martin Hartl (inlart) 5/19/2020 |
\*-----------------------------------------*/
#include "LogitechG403Controller.h"
#include <cstring>
LogitechG403Controller::LogitechG403Controller(hid_device* dev_handle)
{
dev = dev_handle;
}
LogitechG403Controller::~LogitechG403Controller()
{
hid_close(dev);
}
void LogitechG403Controller::SendMouseMode
(
unsigned char mode,
std::uint16_t speed,
unsigned char channel,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
unsigned char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x0E;
usb_buf[0x03] = 0x3C;
usb_buf[0x04] = channel;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 1000 + 4750 * (LOGITECH_G403_SPEED_FASTEST - speed);
if(mode == LOGITECH_G403_MODE_CYCLE)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = 0x64;
}
else if(mode == LOGITECH_G403_MODE_BREATHING)
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
usb_buf[0x0C] = 0x64;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 20);
hid_read(dev, usb_buf, 20);
}
@@ -0,0 +1,52 @@
/*-----------------------------------------*\
| LogitechG403Controller.h |
| |
| Definitions and types for Logitech G403 |
| Prodigy mouse lighting controller |
| |
| Martin Hartl (inlart) 5/19/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
LOGITECH_G403_MODE_OFF = 0x00,
LOGITECH_G403_MODE_STATIC = 0x01,
LOGITECH_G403_MODE_CYCLE = 0x02,
LOGITECH_G403_MODE_BREATHING = 0x03,
};
enum
{
LOGITECH_G403_SPEED_SLOWEST = 0x00, /* Slowest speed */
LOGITECH_G403_SPEED_SLOW = 0x01, /* Slow speed */
LOGITECH_G403_SPEED_NORMAL = 0x02, /* Normal speed */
LOGITECH_G403_SPEED_FAST = 0x03, /* Fast speed */
LOGITECH_G403_SPEED_FASTEST = 0x04, /* Fastest speed */
};
class LogitechG403Controller
{
public:
LogitechG403Controller(hid_device* dev_handle);
~LogitechG403Controller();
void SendMouseMode
(
unsigned char mode,
unsigned short speed,
unsigned char channel,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
hid_device* dev;
};
@@ -0,0 +1,169 @@
/*-----------------------------------------*\
| LogitechG810Controller.cpp |
| |
| Driver for Logitech G810 Orion Spectrum |
| keyboard light controller |
| |
| Adam Honse (CalcProgrammer1) 6/11/2020 |
\*-----------------------------------------*/
#include "LogitechG810Controller.h"
#include <cstring>
LogitechG810Controller::LogitechG810Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12)
{
dev_pkt_0x11 = dev_handle_0x11;
dev_pkt_0x12 = dev_handle_0x12;
}
LogitechG810Controller::~LogitechG810Controller()
{
}
void LogitechG810Controller::Commit()
{
SendCommit();
}
void LogitechG810Controller::SetDirect
(
unsigned char zone,
unsigned char frame_count,
unsigned char * frame_data
)
{
SendDirectFrame(zone, frame_count, frame_data);
}
void LogitechG810Controller::SetMode
(
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
SendMode(LOGITECH_G810_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
SendMode(LOGITECH_G810_ZONE_MODE_LOGO, mode, speed, red, green, blue);
SendCommit();
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void LogitechG810Controller::SendCommit()
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x0C;
usb_buf[0x03] = 0x5D;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
hid_read(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
}
void LogitechG810Controller::SendDirectFrame
(
unsigned char zone,
unsigned char frame_count,
unsigned char * frame_data
)
{
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x12;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x0C;
usb_buf[0x03] = 0x3D;
usb_buf[0x05] = zone;
usb_buf[0x07] = frame_count;
/*-----------------------------------------------------*\
| Copy in frame data |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x08], frame_data, frame_count * 4);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_pkt_0x12, (unsigned char *)usb_buf, 64);
hid_read(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
}
void LogitechG810Controller::SendMode
(
unsigned char zone,
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x0D;
usb_buf[0x03] = 0x3D;
usb_buf[0x04] = zone;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 1000 + 4750 * (LOGITECH_G810_SPEED_FASTEST - speed);
if(mode == LOGITECH_G810_MODE_CYCLE)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = 0x64;
}
else if(mode == LOGITECH_G810_MODE_BREATHING)
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
usb_buf[0x0C] = 0x64;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
hid_read(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
}
@@ -0,0 +1,95 @@
/*-----------------------------------------*\
| LogitechG810Controller.h |
| |
| Definitions and types for Logitech G810 |
| Orion Spectrum keyboard light controller |
| |
| Adam Honse (CalcProgrammer1) 6/11/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
LOGITECH_G810_ZONE_MODE_KEYBOARD = 0x00,
LOGITECH_G810_ZONE_MODE_LOGO = 0x01,
};
enum
{
LOGITECH_G810_ZONE_DIRECT_KEYBOARD = 0x01,
LOGITECH_G810_ZONE_DIRECT_MEDIA = 0x02,
LOGITECH_G810_ZONE_DIRECT_LOGO = 0x10,
LOGITECH_G810_ZONE_DIRECT_INDICATORS = 0x40,
};
enum
{
LOGITECH_G810_MODE_OFF = 0x00,
LOGITECH_G810_MODE_STATIC = 0x01,
LOGITECH_G810_MODE_BREATHING = 0x02,
LOGITECH_G810_MODE_CYCLE = 0x03,
LOGITECH_G810_MODE_WAVE = 0x04,
};
enum
{
LOGITECH_G810_SPEED_SLOWEST = 0x00, /* Slowest speed */
LOGITECH_G810_SPEED_SLOW = 0x01, /* Slow speed */
LOGITECH_G810_SPEED_NORMAL = 0x02, /* Normal speed */
LOGITECH_G810_SPEED_FAST = 0x03, /* Fast speed */
LOGITECH_G810_SPEED_FASTEST = 0x04, /* Fastest speed */
};
class LogitechG810Controller
{
public:
LogitechG810Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12);
~LogitechG810Controller();
void Commit();
void SetDirect
(
unsigned char zone,
unsigned char frame_count,
unsigned char * frame_data
);
void SetMode
(
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
hid_device* dev_pkt_0x11;
hid_device* dev_pkt_0x12;
void SendDirectFrame
(
unsigned char zone,
unsigned char frame_count,
unsigned char * frame_data
);
void SendMode
(
unsigned char zone,
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
void SendCommit();
};
@@ -0,0 +1,67 @@
/*-----------------------------------------*\
| MSIGPUController.cpp |
| |
| Driver for MSI GPUs |
| |
\*-----------------------------------------*/
#include "MSIGPUController.h"
#include <cstring>
MSIGPUController::MSIGPUController(i2c_smbus_interface* bus)
{
this->bus = bus;
this->dev = 0x68;
}
MSIGPUController::~MSIGPUController()
{
}
std::string MSIGPUController::GetDeviceLocation()
{
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
return_string.append(addr);
return(return_string);
}
void MSIGPUController::SetRGB1(unsigned char red, unsigned char green, unsigned char blue)
{
MSIGPURegisterWrite(MSI_GPU_REG_R1, red);
MSIGPURegisterWrite(MSI_GPU_REG_G1, green);
MSIGPURegisterWrite(MSI_GPU_REG_B1, blue);
}
void MSIGPUController::SetRGB2(unsigned char red, unsigned char green, unsigned char blue)
{
MSIGPURegisterWrite(MSI_GPU_REG_R2, red);
MSIGPURegisterWrite(MSI_GPU_REG_G2, green);
MSIGPURegisterWrite(MSI_GPU_REG_B2, blue);
}
void MSIGPUController::SetRGB3(unsigned char red, unsigned char green, unsigned char blue)
{
MSIGPURegisterWrite(MSI_GPU_REG_R3, red);
MSIGPURegisterWrite(MSI_GPU_REG_G3, green);
MSIGPURegisterWrite(MSI_GPU_REG_B3, blue);
}
void MSIGPUController::SetMode(unsigned char mode)
{
MSIGPURegisterWrite(MSI_GPU_REG_MODE, mode);
MSIGPURegisterWrite(MSI_GPU_REG_APPLY, 0x01);
}
unsigned char MSIGPUController::MSIGPURegisterRead(unsigned char reg)
{
return(bus->i2c_smbus_read_byte_data(dev, reg));
}
void MSIGPUController::MSIGPURegisterWrite(unsigned char reg, unsigned char val)
{
bus->i2c_smbus_write_byte_data(dev, reg, val);
}
@@ -0,0 +1,77 @@
/*-----------------------------------------*\
| MSIGPUController.h |
| |
| Definitions for MSI GPUs |
| |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char msi_gpu_dev_id;
enum
{
MSI_GPU_REG_BRIGHTNESS = 0x36, /* MSI GPU Brightness Register */
MSI_GPU_REG_SPEED = 0x38, /* MSI GPU Speed Register */
MSI_GPU_REG_UNKNOWN = 0x26, /* MSI GPU Unknown Register */
MSI_GPU_REG_R1 = 0x30, /* MSI GPU R1 Register */
MSI_GPU_REG_G1 = 0x31, /* MSI GPU G1 Register */
MSI_GPU_REG_B1 = 0x32, /* MSI GPU B1 Register */
MSI_GPU_REG_R2 = 0x27, /* MSI GPU R2 Register */
MSI_GPU_REG_G2 = 0x28, /* MSI GPU G2 Register */
MSI_GPU_REG_B2 = 0x29, /* MSI GPU B2 Register */
MSI_GPU_REG_R3 = 0x2a, /* MSI GPU R3 Register */
MSI_GPU_REG_G3 = 0x2b, /* MSI GPU G3 Register */
MSI_GPU_REG_B3 = 0x2c, /* MSI GPU B3 Register */
MSI_GPU_REG_MODE = 0x22, /* MSI GPU Mode Selection Register */
MSI_GPU_REG_APPLY = 0x3f, /* MSI GPU Apply Changes Register */
};
enum
{
MSI_GPU_MODE_OFF = 0x01, /* OFF mode */
MSI_GPU_MODE_RAINBOW = 0x08, /* Rainbow effect mode */
MSI_GPU_MODE_STATIC = 0x13, /* Static color mode */
MSI_GPU_MODE_RAINDROP = 0x1a, /* Raindrop effect mode */
MSI_GPU_MODE_MAGIC = 0x07, /* Magic effect mode */
MSI_GPU_MODE_PATROLLING = 0x05, /* Patrolling effect mode */
MSI_GPU_MODE_STREAMING = 0x06, /* Streaming effect mode */
MSI_GPU_MODE_LIGHTNING = 0x15, /* Lightning effect mode */
MSI_GPU_MODE_WAVE = 0x1f, /* Wave effect mode */
MSI_GPU_MODE_METEOR = 0x16, /* Meteor effect mode */
MSI_GPU_MODE_STACK = 0x0d, /* Stack effect mode */
MSI_GPU_MODE_RHYTHM = 0x0b, /* Rhythm effect mode */
MSI_GPU_MODE_FLOWING = 0x09, /* Flowing effect mode */
MSI_GPU_MODE_WHIRLING = 0x0f, /* Whirling effect mode */
MSI_GPU_MODE_TWISTING = 0x11, /* Twisting effect mode */
MSI_GPU_MODE_LAMINATING = 0x1d, /* Laminating effect mode */
MSI_GPU_MODE_FADEIN = 0x14, /* Fadein effect mode */
MSI_GPU_MODE_BREATHING = 0x04, /* Breathing effect mode */
MSI_GPU_MODE_FLASHING = 0x02, /* Flashing effect mode */
MSI_GPU_MODE_DOUBLEFLASHING = 0x03, /* Doubleflashing effect mode */
};
class MSIGPUController
{
public:
MSIGPUController(i2c_smbus_interface* bus);
~MSIGPUController();
std::string GetDeviceLocation();
void SetRGB1(unsigned char red, unsigned char green, unsigned char blue);
void SetRGB2(unsigned char red, unsigned char green, unsigned char blue);
void SetRGB3(unsigned char red, unsigned char green, unsigned char blue);
void SetMode(unsigned char mode);
unsigned char MSIGPURegisterRead(unsigned char reg);
void MSIGPURegisterWrite(unsigned char reg, unsigned char val);
private:
i2c_smbus_interface * bus;
msi_gpu_dev_id dev;
};
@@ -0,0 +1,113 @@
/*-----------------------------------------*\
| MSIGPUControllerDetect.cpp |
| |
| Driver for MSI GPUs |
| |
\*-----------------------------------------*/
#include "MSIGPUController.h"
#include "RGBController.h"
#include "RGBController_MSIGPU.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
/*-----------------------------------------------------*\
| NVidia vendor ID |
\*-----------------------------------------------------*/
#define NVIDIA_VEN 0x10DE
/*-----------------------------------------------------*\
| NVidia device IDs |
\*-----------------------------------------------------*/
#define NVIDIA_RTX2060_DEV 0x1F08
#define NVIDIA_RTX2060S_DEV 0x1F06
#define NVIDIA_RTX2070_DEV 0x1F02
#define NVIDIA_RTX2070S_DEV 0x1E84
#define NVIDIA_RTX2080_DEV 0x1E87
#define NVIDIA_RTX2080S_DEV 0x1E81
#define NVIDIA_RTX2080TI_DEV 0x1E07
/*-----------------------------------------------------*\
| MSI sub-vendor ID |
\*-----------------------------------------------------*/
#define MSI_SUB_VEN 0x1462
/*-----------------------------------------------------*\
| MSI sub-device IDs |
\*-----------------------------------------------------*/
#define MSI_RTX2060S_GAMING_X_SUB_DEV 0xC752
#define MSI_RTX2070S_GAMING_X_SUB_DEV 0x373e
#define MSI_RTX2070S_GAMING_X_TRIO_SUB_DEV 0xC726
#define MSI_RTX2080_GAMING_X_TRIO_SUB_DEV 0x3726
#define MSI_RTX2080S_GAMING_X_TRIO_SUB_DEV 0xC724
#define MSI_RTX2080TI_GAMING_X_TRIO_SUB_DEV 0x3715
#define MSI_RTX2060_GAMING_Z_6G_SUB_DEV 0x3754
#define MSI_RTX2070_ARMOR_SUB_DEV 0x3734
#define MSI_RTX2060S_ARMOR_OC_SUB_DEV 0xC754
#define MSI_RTX2080_SEA_HAWK_EK_X_SUB_DEV 0x3728
#define MSI_RTX2080TI_SEA_HAWK_EK_X_SUB_DEV 0x3717
typedef struct
{
int pci_vendor;
int pci_device;
int pci_subsystem_vendor;
int pci_subsystem_device;
const char * name;
} msi_gpu_pci_device;
#define MSI_GPU_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
static const msi_gpu_pci_device device_list[] =
{
{ NVIDIA_VEN, NVIDIA_RTX2060S_DEV, MSI_SUB_VEN, MSI_RTX2060S_GAMING_X_SUB_DEV, "MSI GeForce RTX 2060 Super Gaming X" },
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, MSI_SUB_VEN, MSI_RTX2070S_GAMING_X_SUB_DEV, "MSI GeForce RTX 2070 Super Gaming X" },
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, MSI_SUB_VEN, MSI_RTX2070S_GAMING_X_TRIO_SUB_DEV, "MSI GeForce RTX 2070 Super Gaming X Trio" },
{ NVIDIA_VEN, NVIDIA_RTX2080_DEV, MSI_SUB_VEN, MSI_RTX2080_GAMING_X_TRIO_SUB_DEV, "MSI GeForce RTX 2080 Gaming X Trio" },
{ NVIDIA_VEN, NVIDIA_RTX2080S_DEV, MSI_SUB_VEN, MSI_RTX2080S_GAMING_X_TRIO_SUB_DEV, "MSI GeForce RTX 2080 Super Gaming X Trio" },
{ NVIDIA_VEN, NVIDIA_RTX2080TI_DEV, MSI_SUB_VEN, MSI_RTX2080TI_GAMING_X_TRIO_SUB_DEV, "MSI GeForce RTX 2080Ti Gaming X Trio" },
{ NVIDIA_VEN, NVIDIA_RTX2060_DEV, MSI_SUB_VEN, MSI_RTX2060_GAMING_Z_6G_SUB_DEV, "MSI GeForce RTX 2060 Gaming Z 6G" },
{ NVIDIA_VEN, NVIDIA_RTX2060S_DEV, MSI_SUB_VEN, MSI_RTX2060S_ARMOR_OC_SUB_DEV, "MSI GeForce RTX 2060 Super ARMOR OC" },
{ NVIDIA_VEN, NVIDIA_RTX2070_DEV, MSI_SUB_VEN, MSI_RTX2070_ARMOR_SUB_DEV, "MSI GeForce RTX 2070 ARMOR" },
{ NVIDIA_VEN, NVIDIA_RTX2080_DEV, MSI_SUB_VEN, MSI_RTX2080_SEA_HAWK_EK_X_SUB_DEV, "MSI GeForce RTX 2080 Sea Hawk EK X" },
{ NVIDIA_VEN, NVIDIA_RTX2080TI_DEV, MSI_SUB_VEN, MSI_RTX2080TI_SEA_HAWK_EK_X_SUB_DEV, "MSI GeForce RTX 2080Ti Sea Hawk EK X" },
};
/******************************************************************************************\
* *
* DetectMSIGPUControllers *
* *
* Detect MSI GPU controllers on the enumerated I2C busses. *
* *
\******************************************************************************************/
void DetectMSIGPUControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
MSIGPUController* new_msi_gpu;
RGBController_MSIGPU* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
for(unsigned int dev_idx = 0; dev_idx < MSI_GPU_NUM_DEVICES; dev_idx++)
{
if (busses[bus]->port_id != 1)
{
break;
}
if(busses[bus]->pci_vendor == device_list[dev_idx].pci_vendor &&
busses[bus]->pci_device == device_list[dev_idx].pci_device &&
busses[bus]->pci_subsystem_vendor == device_list[dev_idx].pci_subsystem_vendor &&
busses[bus]->pci_subsystem_device == device_list[dev_idx].pci_subsystem_device)
{
new_msi_gpu = new MSIGPUController(busses[bus]);
new_controller = new RGBController_MSIGPU(new_msi_gpu);
new_controller->name = device_list[dev_idx].name;
rgb_controllers.push_back(new_controller);
}
}
}
} /* DetectMSIGPUControllers() */
@@ -35,25 +35,34 @@ MSIMysticLightController::~MSIMysticLightController()
}
}
unsigned int MSIMysticLightController::GetZoneMinLedCount(ZONE /*zone*/)
unsigned int MSIMysticLightController::GetZoneMinLedCount
(
MSI_ZONE /*zone*/
)
{
return 1u;
return 1;
}
unsigned int MSIMysticLightController::GetZoneMaxLedCount(ZONE zone)
unsigned int MSIMysticLightController::GetZoneMaxLedCount
(
MSI_ZONE zone
)
{
switch (zone)
switch(zone)
{
case J_RAINBOW_1:
case J_RAINBOW_2:
case J_CORSAIR:
return 4u; // TODO: It can be different by zone and by mobo
case MSI_ZONE_J_RAINBOW_1:
case MSI_ZONE_J_RAINBOW_2:
case MSI_ZONE_J_CORSAIR:
return 4; // TODO: It can be different by zone and by mobo
default:
return 1u;
return 1;
}
}
unsigned int MSIMysticLightController::GetZoneLedCount(ZONE zone)
unsigned int MSIMysticLightController::GetZoneLedCount
(
MSI_ZONE zone
)
{
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
@@ -65,7 +74,11 @@ unsigned int MSIMysticLightController::GetZoneLedCount(ZONE zone)
return requestedZone->cycle_or_led_num;
}
void MSIMysticLightController::SetZoneLedCount(ZONE zone, unsigned int led_count)
void MSIMysticLightController::SetZoneLedCount
(
MSI_ZONE zone,
unsigned int led_count
)
{
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
@@ -78,7 +91,14 @@ void MSIMysticLightController::SetZoneLedCount(ZONE zone, unsigned int led_count
requestedZone->cycle_or_led_num = led_count;
}
void MSIMysticLightController::SetMode(ZONE zone, EFFECT mode, SPEED speed, BRIGHTNESS brightness, bool rainbow_color)
void MSIMysticLightController::SetMode
(
MSI_ZONE zone,
MSI_MODE mode,
MSI_SPEED speed,
MSI_BRIGHTNESS brightness,
bool rainbow_color
)
{
ZoneData* zoneData = GetZoneData(zone);
if(!zoneData)
@@ -113,12 +133,18 @@ std::string MSIMysticLightController::GetSerial()
bool MSIMysticLightController::ReadSettings()
{
return hid_get_feature_report(dev, reinterpret_cast<unsigned char *>(&data), sizeof data) == sizeof data;
/*-----------------------------------------------------*\
| Read packet from hardware, return true if successful |
\*-----------------------------------------------------*/
return(hid_get_feature_report(dev, (unsigned char *)&data, sizeof(data)) == sizeof data);
}
bool MSIMysticLightController::Update()
{
return hid_send_feature_report(dev, reinterpret_cast<unsigned char *>(&data), sizeof data) == sizeof data;
/*-----------------------------------------------------*\
| Send packet to hardware, return true if successful |
\*-----------------------------------------------------*/
return(hid_send_feature_report(dev, (unsigned char *)&data, sizeof(data)) == sizeof data);
}
void MSIMysticLightController::SaveOnUpdate(bool save)
@@ -126,26 +152,40 @@ void MSIMysticLightController::SaveOnUpdate(bool save)
data.save_data = save;
}
void MSIMysticLightController::SetZoneColor(ZONE zone, unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2)
void MSIMysticLightController::SetZoneColor
(
MSI_ZONE zone,
unsigned char red1,
unsigned char grn1,
unsigned char blu1,
unsigned char red2,
unsigned char grn2,
unsigned char blu2
)
{
ZoneData* zoneData = GetZoneData(zone);
if(!zoneData)
{
return;
}
zoneData->color.R = r1;
zoneData->color.G = g1;
zoneData->color.B = b1;
zoneData->color.R = red1;
zoneData->color.G = grn1;
zoneData->color.B = blu1;
zoneData->color2.R = r2;
zoneData->color2.G = g2;
zoneData->color2.B = b2;
zoneData->color2.R = red2;
zoneData->color2.G = grn2;
zoneData->color2.B = blu2;
}
std::pair<Color, Color> MSIMysticLightController::GetZoneColor(ZONE zone)
std::pair<Color, Color> MSIMysticLightController::GetZoneColor
(
MSI_ZONE zone
)
{
ZoneData *zoneData = GetZoneData(zone);
if (!zoneData)
{
return std::make_pair(Color{}, Color{});
@@ -158,61 +198,67 @@ std::pair<Color, Color> MSIMysticLightController::GetZoneColor(ZONE zone)
Color{zoneData->color2.R, zoneData->color2.G, zoneData->color2.B});
}
ZoneData *MSIMysticLightController::GetZoneData(ZONE zone)
ZoneData *MSIMysticLightController::GetZoneData
(
MSI_ZONE zone
)
{
switch (zone)
switch(zone)
{
case J_RGB_1:
case MSI_ZONE_J_RGB_1:
return &data.j_rgb_1;
case J_RGB_2:
case MSI_ZONE_J_RGB_2:
return &data.j_rgb_2;
case J_RAINBOW_1:
case MSI_ZONE_J_RAINBOW_1:
return &data.j_rainbow_1;
case J_RAINBOW_2:
case MSI_ZONE_J_RAINBOW_2:
return &data.j_rainbow_2;
case J_PIPE_1:
case MSI_ZONE_J_PIPE_1:
return &data.j_pipe_1;
case J_PIPE_2:
case MSI_ZONE_J_PIPE_2:
return &data.j_pipe_2;
case ON_BOARD_LED:
case MSI_ZONE_ON_BOARD_LED:
return &data.on_board_led;
case ON_BOARD_LED_1:
case MSI_ZONE_ON_BOARD_LED_1:
return &data.on_board_led_1;
case ON_BOARD_LED_2:
case MSI_ZONE_ON_BOARD_LED_2:
return &data.on_board_led_2;
case ON_BOARD_LED_3:
case MSI_ZONE_ON_BOARD_LED_3:
return &data.on_board_led_3;
case ON_BOARD_LED_4:
case MSI_ZONE_ON_BOARD_LED_4:
return &data.on_board_led_4;
case ON_BOARD_LED_5:
case MSI_ZONE_ON_BOARD_LED_5:
return &data.on_board_led_5;
case ON_BOARD_LED_6:
case MSI_ZONE_ON_BOARD_LED_6:
return &data.on_board_led_6;
case ON_BOARD_LED_7:
case MSI_ZONE_ON_BOARD_LED_7:
return &data.on_board_led_7;
case ON_BOARD_LED_8:
case MSI_ZONE_ON_BOARD_LED_8:
return &data.on_board_led_8;
case ON_BOARD_LED_9:
case MSI_ZONE_ON_BOARD_LED_9:
return &data.on_board_led_9;
case J_CORSAIR_OUTERLL120:
case MSI_ZONE_J_CORSAIR_OUTERLL120:
return &data.j_corsair_outerll120;
default:
case J_CORSAIR:
case MSI_ZONE_J_CORSAIR:
break;
}
return nullptr;
}
RainbowZoneData *MSIMysticLightController::GetRainbowZoneData(ZONE zone)
RainbowZoneData *MSIMysticLightController::GetRainbowZoneData
(
MSI_ZONE zone
)
{
switch (zone)
switch(zone)
{
case J_RAINBOW_1:
case MSI_ZONE_J_RAINBOW_1:
return &data.j_rainbow_1;
case J_RAINBOW_2:
case MSI_ZONE_J_RAINBOW_2:
return &data.j_rainbow_2;
case J_CORSAIR:
case MSI_ZONE_J_CORSAIR:
default:
return nullptr;
}
@@ -220,39 +266,98 @@ RainbowZoneData *MSIMysticLightController::GetRainbowZoneData(ZONE zone)
bool MSIMysticLightController::ReadFwVersion()
{
// First read the APROM
// Checksum also available at report ID 180, with highCheksum stored at index 8, and low at 9
int num = 1;
unsigned char request[64] = {1, 176};
unsigned char request[64];
unsigned char response[64];
int ret_val = 64;
std::fill_n(request + 2, sizeof request - 2, 204);
num &= hid_write(dev, request, 64);
num &= hid_read(dev, response, 64);
/*-----------------------------------------------------*\
| First read the APROM |
| Checksum also available at report ID 180, with MSB |
| stored at index 0x08 and LSB at 0x09 |
\*-----------------------------------------------------*/
/*-----------------------------------------------------*\
| Zero out buffers |
\*-----------------------------------------------------*/
memset(request, 0x00, sizeof(request));
memset(response, 0x00, sizeof(response));
/*-----------------------------------------------------*\
| Set up APROM Firmware Version Request packet |
\*-----------------------------------------------------*/
request[0x00] = 0x01;
request[0x01] = 0xB0;
/*-----------------------------------------------------*\
| Fill request from 0x02 to 0x61 with 0xCC |
\*-----------------------------------------------------*/
memset(&request[0x02], 0xCC, sizeof(request) - 2);
/*-----------------------------------------------------*\
| Send request and receive response packets |
\*-----------------------------------------------------*/
ret_val &= hid_write(dev, request, 64);
ret_val &= hid_read(dev, response, 64);
/*-----------------------------------------------------*\
| Extract high and low values from response |
\*-----------------------------------------------------*/
unsigned char highValue = response[2] >> 4;
unsigned char lowValue = response[2] & 15;
unsigned char lowValue = response[2] & 0x0F;
/*-----------------------------------------------------*\
| Build firmware string <high>.<low> |
\*-----------------------------------------------------*/
version_APROM = std::to_string(static_cast<int>(highValue)).append(".").append(std::to_string(static_cast<int>(lowValue)));
// Now read the LDROM
// Checksum also available at report ID 184, with highCheksum stored at index 8, and low at 9
request[1] = 182u;
num &= hid_write(dev, request, 64);
num &= hid_read(dev, response, 64);
/*-----------------------------------------------------*\
| First read the LDROM |
| Checksum also available at report ID 184, with MSB |
| stored at index 0x08 and LSB at 0x09 |
\*-----------------------------------------------------*/
highValue = response[2] >> 4u;
lowValue = response[2] & 15u;
/*-----------------------------------------------------*\
| Set up LDROM Firmware Version Request packet |
\*-----------------------------------------------------*/
request[0x00] = 0x01;
request[0x01] = 0xB6;
/*-----------------------------------------------------*\
| Send request and receive response packets |
\*-----------------------------------------------------*/
ret_val &= hid_write(dev, request, 64);
ret_val &= hid_read(dev, response, 64);
/*-----------------------------------------------------*\
| Extract high and low values from response |
\*-----------------------------------------------------*/
highValue = response[2] >> 4;
lowValue = response[2] & 0x0F;
/*-----------------------------------------------------*\
| Build firmware string <high>.<low> |
\*-----------------------------------------------------*/
version_LDROM = std::to_string(static_cast<int>(highValue)).append(".").append(std::to_string(static_cast<int>(lowValue)));
return num == 1;
/*-----------------------------------------------------*\
| If return value is zero it means an HID transfer |
| failed |
\*-----------------------------------------------------*/
return(ret_val > 0);
}
void MSIMysticLightController::ReadSerial()
{
wchar_t serial[256];
/*-----------------------------------------------------*\
| Get the serial number string from HID |
\*-----------------------------------------------------*/
hid_get_serial_number_string(dev, serial, 256);
/*-----------------------------------------------------*\
| Convert wchar_t into std::wstring into std::string |
\*-----------------------------------------------------*/
std::wstring wserial = std::wstring(serial);
chip_id = std::string(wserial.begin(), wserial.end());
}
@@ -260,27 +365,53 @@ void MSIMysticLightController::ReadSerial()
void MSIMysticLightController::ReadName()
{
wchar_t tname[256];
/*-----------------------------------------------------*\
| Get the manufacturer string from HID |
\*-----------------------------------------------------*/
hid_get_manufacturer_string(dev, tname, 256);
/*-----------------------------------------------------*\
| Convert wchar_t into std::wstring into std::string |
\*-----------------------------------------------------*/
std::wstring wname = std::wstring(tname);
name = std::string(wname.begin(), wname.end());
/*-----------------------------------------------------*\
| Get the product string from HID |
\*-----------------------------------------------------*/
hid_get_product_string(dev, tname, 256);
/*-----------------------------------------------------*\
| Append the product string to the manufacturer string |
\*-----------------------------------------------------*/
wname = std::wstring(tname);
name.append(" ").append(std::string(wname.begin(), wname.end()));
}
void MSIMysticLightController::SetDeviceSettings(bool is_fan, FAN_TYPE fan_type,
unsigned char corsair_device_quantity,
bool is_LL120Outer_individual)
void MSIMysticLightController::SetDeviceSettings
(
bool is_fan,
MSI_FAN_TYPE fan_type,
unsigned char corsair_device_quantity,
bool is_LL120Outer_individual
)
{
// If is_fan false, it is a stripe
CorsairZoneData &settingsZone = data.j_corsair;
settingsZone.fan_flags = (settingsZone.fan_flags & 128u) | fan_type << 1u | is_fan;
settingsZone.corsair_quantity = corsair_device_quantity << 2u;
settingsZone.is_individual = BitSet(settingsZone.is_individual, is_LL120Outer_individual, 0u);
/*-----------------------------------------------------*\
| If is_fan is false, it is an LED strip |
\*-----------------------------------------------------*/
CorsairZoneData &settingsZone = data.j_corsair;
settingsZone.fan_flags = (settingsZone.fan_flags & 0x80) | fan_type << 1 | is_fan;
settingsZone.corsair_quantity = corsair_device_quantity << 2;
settingsZone.is_individual = BitSet(settingsZone.is_individual, is_LL120Outer_individual, 0);
}
bool MSIMysticLightController::SetVolume(unsigned char main, unsigned char left, unsigned char right)
bool MSIMysticLightController::SetVolume
(
unsigned char main,
unsigned char left,
unsigned char right
)
{
unsigned char packet[64];
std::fill_n(packet, sizeof packet, 204u);
@@ -309,41 +440,78 @@ bool MSIMysticLightController::SetVolume(unsigned char main, unsigned char left,
return hid_write(dev, packet, sizeof packet);
}
void MSIMysticLightController::SetBoardSyncSettings(bool onboard_sync, bool combine_JRGB, bool combine_JPIPE1,
bool combine_JPIPE2, bool combine_JRAINBOW1, bool combine_JRAINBOW2,
bool combine_crossair)
void MSIMysticLightController::SetBoardSyncSettings
(
bool onboard_sync,
bool combine_JRGB,
bool combine_JPIPE1,
bool combine_JPIPE2,
bool combine_JRAINBOW1,
bool combine_JRAINBOW2,
bool combine_crossair
)
{
ZoneData &syncZone = data.on_board_led;
syncZone.colorFlags = BitSet(syncZone.colorFlags, onboard_sync, 0u);
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JRAINBOW1, 1u);
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JRAINBOW2, 2u);
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_crossair, 3u);
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JPIPE1, 4u);
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JPIPE2, 5u);
syncZone.speedAndBrightnessFlags = BitSet(syncZone.speedAndBrightnessFlags, combine_JRGB, 7u);
/*-----------------------------------------------------*\
| Set sync flags for on-board LED zone |
\*-----------------------------------------------------*/
syncZone.colorFlags = BitSet(syncZone.colorFlags, onboard_sync, 0);
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JRAINBOW1, 1);
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JRAINBOW2, 2);
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_crossair, 3);
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JPIPE1, 4);
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JPIPE2, 5);
syncZone.speedAndBrightnessFlags = BitSet(syncZone.speedAndBrightnessFlags, combine_JRGB, 7);
}
void MSIMysticLightController::GetMode(ZONE zone, EFFECT &mode, SPEED &speed, BRIGHTNESS &brightness, bool &rainbow_color)
void MSIMysticLightController::GetMode
(
MSI_ZONE zone,
MSI_MODE &mode,
MSI_SPEED &speed,
MSI_BRIGHTNESS &brightness,
bool &rainbow_color
)
{
/*-----------------------------------------------------*\
| Get data for given zone |
\*-----------------------------------------------------*/
ZoneData *zoneData = GetZoneData(zone);
/*-----------------------------------------------------*\
| Return if zone is invalid |
\*-----------------------------------------------------*/
if (!zoneData)
{
return;
}
mode = static_cast<EFFECT>(zoneData->effect);
speed = static_cast<SPEED>(zoneData->speedAndBrightnessFlags & 3u);
brightness = static_cast<BRIGHTNESS>((zoneData->speedAndBrightnessFlags >> 2u) & 31u);
rainbow_color = (zoneData->colorFlags & 128u) >> 7u;
/*-----------------------------------------------------*\
| Update pointers with data |
\*-----------------------------------------------------*/
mode = (MSI_MODE)(zoneData->effect);
speed = (MSI_SPEED)(zoneData->speedAndBrightnessFlags & 0x03);
brightness = (MSI_BRIGHTNESS)((zoneData->speedAndBrightnessFlags >> 2) & 0x1F);
rainbow_color = (zoneData->colorFlags & 0x80) >> 7;
}
unsigned char MSIMysticLightController::BitSet(unsigned char value, bool bit, unsigned int position)
unsigned char MSIMysticLightController::BitSet
(
unsigned char value,
bool bit,
unsigned int position
)
{
return static_cast<unsigned char>(std::bitset<8>(value).set(position, bit).to_ulong());
}
void MSIMysticLightController::SetCycleCount(ZONE zone, unsigned char cycle_num)
void MSIMysticLightController::SetCycleCount
(
MSI_ZONE zone,
unsigned char cycle_num
)
{
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
@@ -355,7 +523,10 @@ void MSIMysticLightController::SetCycleCount(ZONE zone, unsigned char cycle_num)
requestedZone->cycle_or_led_num = cycle_num;
}
unsigned char MSIMysticLightController::GetCycleCount(ZONE zone)
unsigned char MSIMysticLightController::GetCycleCount
(
MSI_ZONE zone
)
{
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
@@ -367,28 +538,43 @@ unsigned char MSIMysticLightController::GetCycleCount(ZONE zone)
return requestedZone->cycle_or_led_num;
}
void MSIMysticLightController::GetBoardSyncSettings(bool &onboard_sync, bool &combine_JRGB, bool &combine_JPIPE1,
bool &combine_JPIPE2, bool &combine_JRAINBOW1,
bool &combine_JRAINBOW2, bool &combine_crossair)
void MSIMysticLightController::GetBoardSyncSettings
(
bool &onboard_sync,
bool &combine_JRGB,
bool &combine_JPIPE1,
bool &combine_JPIPE2,
bool &combine_JRAINBOW1,
bool &combine_JRAINBOW2,
bool &combine_crossair
)
{
ZoneData &syncZone = data.on_board_led;
onboard_sync = syncZone.colorFlags & 1u;
combine_JRAINBOW1 = syncZone.colorFlags >> 1u & 1u;
combine_JRAINBOW2 = syncZone.colorFlags >> 1u & 1u;
combine_crossair = syncZone.colorFlags >> 3u & 1u;
combine_JPIPE1 = syncZone.colorFlags >> 4u & 1u;
combine_JPIPE2 = syncZone.colorFlags >> 5u & 1u;
combine_JRGB = (syncZone.speedAndBrightnessFlags & 128u) >> 7u;
/*-----------------------------------------------------*\
| Get sync flags for on-board LED zone |
\*-----------------------------------------------------*/
onboard_sync = (syncZone.colorFlags >> 0) & 0x01;
combine_JRAINBOW1 = (syncZone.colorFlags >> 1) & 0x01;
combine_JRAINBOW2 = (syncZone.colorFlags >> 2) & 0x01;
combine_crossair = (syncZone.colorFlags >> 3) & 0x01;
combine_JPIPE1 = (syncZone.colorFlags >> 4) & 0x01;
combine_JPIPE2 = (syncZone.colorFlags >> 5) & 0x01;
combine_JRGB = (syncZone.speedAndBrightnessFlags & 0x80) >> 7;
}
void MSIMysticLightController::GetDeviceSettings(bool &stripe_or_fan, FAN_TYPE &fan_type,
unsigned char &corsair_device_quantity,
bool &is_LL120Outer_individual)
void MSIMysticLightController::GetDeviceSettings
(
bool &stripe_or_fan,
MSI_FAN_TYPE &fan_type,
unsigned char &corsair_device_quantity,
bool &is_LL120Outer_individual
)
{
CorsairZoneData &settingsZone = data.j_corsair;
stripe_or_fan = settingsZone.fan_flags & 1u;
fan_type = static_cast<FAN_TYPE >((settingsZone.fan_flags & 14u) >> 1u);
corsair_device_quantity = (settingsZone.corsair_quantity & 252u) >> 2u;
is_LL120Outer_individual = settingsZone.is_individual & 1u;
CorsairZoneData &settingsZone = data.j_corsair;
stripe_or_fan = settingsZone.fan_flags & 0x01;
fan_type = (MSI_FAN_TYPE )((settingsZone.fan_flags & 14u) >> 1);
corsair_device_quantity = (settingsZone.corsair_quantity & 0xFC) >> 2;
is_LL120Outer_individual = settingsZone.is_individual & 0x01;
}
@@ -14,105 +14,105 @@
#pragma once
enum ZONE
enum MSI_ZONE
{
J_RGB_1 = 1,
J_RGB_2 = 174,
J_PIPE_1 = 11,
J_PIPE_2 = 21,
J_RAINBOW_1 = 31,
J_RAINBOW_2 = 42,
J_CORSAIR = 53,
J_CORSAIR_OUTERLL120 = 64,
ON_BOARD_LED = 74,
ON_BOARD_LED_1 = 84,
ON_BOARD_LED_2 = 94,
ON_BOARD_LED_3 = 104,
ON_BOARD_LED_4 = 114,
ON_BOARD_LED_5 = 124,
ON_BOARD_LED_6 = 134,
ON_BOARD_LED_7 = 144,
ON_BOARD_LED_8 = 154,
ON_BOARD_LED_9 = 164
MSI_ZONE_J_RGB_1 = 1,
MSI_ZONE_J_RGB_2 = 174,
MSI_ZONE_J_PIPE_1 = 11,
MSI_ZONE_J_PIPE_2 = 21,
MSI_ZONE_J_RAINBOW_1 = 31,
MSI_ZONE_J_RAINBOW_2 = 42,
MSI_ZONE_J_CORSAIR = 53,
MSI_ZONE_J_CORSAIR_OUTERLL120 = 64,
MSI_ZONE_ON_BOARD_LED = 74,
MSI_ZONE_ON_BOARD_LED_1 = 84,
MSI_ZONE_ON_BOARD_LED_2 = 94,
MSI_ZONE_ON_BOARD_LED_3 = 104,
MSI_ZONE_ON_BOARD_LED_4 = 114,
MSI_ZONE_ON_BOARD_LED_5 = 124,
MSI_ZONE_ON_BOARD_LED_6 = 134,
MSI_ZONE_ON_BOARD_LED_7 = 144,
MSI_ZONE_ON_BOARD_LED_8 = 154,
MSI_ZONE_ON_BOARD_LED_9 = 164
};
struct ZoneDescription
{
std::string name;
ZONE value;
MSI_ZONE value;
};
enum EFFECT
enum MSI_MODE
{
DISABLE,
STATIC,
BREATHING,
FLASHING,
DOUBLE_FLASHING,
LIGHTNING,
MSI_MARQUEE,
METEOR,
WATER_DROP,
MSI_RAINBOW,
POP,
RAP,
JAZZ,
PLAY,
MOVIE,
COLOR_RING,
PLANETARY,
DOUBLE_METEOR,
ENERGY,
BLINK,
CLOCK,
COLOR_PULSE,
COLOR_SHIFT,
COLOR_WAVE,
MARQUEE,
RAINBOW,
RAINBOW_WAVE,
VISOR,
JRAINBOW,
RAINBOW_FLASHING,
RAINBOW_DOUBLE_FLASHING,
RANDOM,
FAN_CONTROL,
DISABLE_2,
COLOR_RING_FLASHING,
COLOR_RING_DOUBLE_FLASHING,
STACK,
CORSAIR_QUE,
FIRE,
LAVA
MSI_MODE_DISABLE = 0,
MSI_MODE_STATIC = 1,
MSI_MODE_BREATHING = 2,
MSI_MODE_FLASHING = 3,
MSI_MODE_DOUBLE_FLASHING = 4,
MSI_MODE_LIGHTNING = 5,
MSI_MODE_MSI_MARQUEE = 6,
MSI_MODE_METEOR = 7,
MSI_MODE_WATER_DROP = 8,
MSI_MODE_MSI_RAINBOW = 9,
MSI_MODE_POP = 10,
MSI_MODE_RAP = 11,
MSI_MODE_JAZZ = 12,
MSI_MODE_PLAY = 13,
MSI_MODE_MOVIE = 14,
MSI_MODE_COLOR_RING = 15,
MSI_MODE_PLANETARY = 16,
MSI_MODE_DOUBLE_METEOR = 17,
MSI_MODE_ENERGY = 18,
MSI_MODE_BLINK = 19,
MSI_MODE_CLOCK = 20,
MSI_MODE_COLOR_PULSE = 21,
MSI_MODE_COLOR_SHIFT = 22,
MSI_MODE_COLOR_WAVE = 23,
MSI_MODE_MARQUEE = 24,
MSI_MODE_RAINBOW = 25,
MSI_MODE_RAINBOW_WAVE = 26,
MSI_MODE_VISOR = 27,
MSI_MODE_JRAINBOW = 28,
MSI_MODE_RAINBOW_FLASHING = 29,
MSI_MODE_RAINBOW_DOUBLE_FLASHING = 30,
MSI_MODE_RANDOM = 31,
MSI_MODE_FAN_CONTROL = 32,
MSI_MODE_DISABLE_2 = 33,
MSI_MODE_COLOR_RING_FLASHING = 34,
MSI_MODE_COLOR_RING_DOUBLE_FLASHING = 35,
MSI_MODE_STACK = 36,
MSI_MODE_CORSAIR_QUE = 37,
MSI_MODE_FIRE = 38,
MSI_MODE_LAVA = 39,
};
enum SPEED
enum MSI_SPEED
{
LOW,
MEDIUM,
HIGH
MSI_SPEED_LOW = 0,
MSI_SPEED_MEDIUM = 1,
MSI_SPEED_HIGH = 2,
};
enum FAN_TYPE
enum MSI_FAN_TYPE
{
SP,
HD,
LL
MSI_FAN_TYPE_SP = 0,
MSI_FAN_TYPE_HD = 1,
MSI_FAN_TYPE_LL = 2,
};
enum BRIGHTNESS
enum MSI_BRIGHTNESS
{
OFF,
LEVEL_10,
LEVEL_20,
LEVEL_30,
LEVEL_40,
LEVEL_50,
LEVEL_60,
LEVEL_70,
LEVEL_80,
LEVEL_90,
LEVEL_100
MSI_BRIGHTNESS_OFF = 0,
MSI_BRIGHTNESS_LEVEL_10 = 1,
MSI_BRIGHTNESS_LEVEL_20 = 2,
MSI_BRIGHTNESS_LEVEL_30 = 3,
MSI_BRIGHTNESS_LEVEL_40 = 4,
MSI_BRIGHTNESS_LEVEL_50 = 5,
MSI_BRIGHTNESS_LEVEL_60 = 6,
MSI_BRIGHTNESS_LEVEL_70 = 7,
MSI_BRIGHTNESS_LEVEL_80 = 8,
MSI_BRIGHTNESS_LEVEL_90 = 9,
MSI_BRIGHTNESS_LEVEL_100 = 10,
};
struct Color
@@ -124,54 +124,51 @@ struct Color
struct CorsairZoneData
{
unsigned char effect = EFFECT::STATIC;
Color color { std::numeric_limits<unsigned char>::max(), 0, 0 };
unsigned char fan_flags = 40;
unsigned char effect = MSI_MODE_STATIC;
Color color { 0, 0, 0 };
unsigned char fan_flags = 40;
unsigned char corsair_quantity;
unsigned char padding[3];
unsigned char is_individual = 0;
unsigned char is_individual = 0;
};
struct ZoneData
{
unsigned char effect = EFFECT::STATIC;
Color color { std::numeric_limits<unsigned char>::max(), 0u, 0u };
unsigned char speedAndBrightnessFlags = 40u;
Color color2 { 0, std::numeric_limits<unsigned char>::max(), 0u };
unsigned char colorFlags = 128u;
const unsigned char padding = 0u;
unsigned char effect = MSI_MODE_STATIC;
Color color { 0, 0, 0 };
unsigned char speedAndBrightnessFlags = 40;
Color color2 { 0, 0, 0 };
unsigned char colorFlags = 128;
const unsigned char padding = 0;
};
struct RainbowZoneData : ZoneData
{
unsigned char cycle_or_led_num = 20u;
unsigned char cycle_or_led_num = 20;
};
struct FeaturePacket
{
const unsigned char report_id = 82u; // Report ID
ZoneData j_rgb_1; // 1
ZoneData j_pipe_1; // 11
ZoneData j_pipe_2; // 21
RainbowZoneData j_rainbow_1; // 31
RainbowZoneData j_rainbow_2; // 42
CorsairZoneData j_corsair; // 53
ZoneData j_corsair_outerll120; // 64
ZoneData on_board_led; // 74
ZoneData on_board_led_1; // 84
ZoneData on_board_led_2; // 94
ZoneData on_board_led_3; // 104
ZoneData on_board_led_4; // 114
ZoneData on_board_led_5; // 124
ZoneData on_board_led_6; // 134
ZoneData on_board_led_7; // 144
ZoneData on_board_led_8; // 154
ZoneData on_board_led_9; // 164
ZoneData j_rgb_2; // 174
unsigned char save_data = 0u; // 184
const unsigned char report_id = 0x52; // Report ID
ZoneData j_rgb_1; // 1
ZoneData j_pipe_1; // 11
ZoneData j_pipe_2; // 21
RainbowZoneData j_rainbow_1; // 31
RainbowZoneData j_rainbow_2; // 42
CorsairZoneData j_corsair; // 53
ZoneData j_corsair_outerll120; // 64
ZoneData on_board_led; // 74
ZoneData on_board_led_1; // 84
ZoneData on_board_led_2; // 94
ZoneData on_board_led_3; // 104
ZoneData on_board_led_4; // 114
ZoneData on_board_led_5; // 124
ZoneData on_board_led_6; // 134
ZoneData on_board_led_7; // 144
ZoneData on_board_led_8; // 154
ZoneData on_board_led_9; // 164
ZoneData j_rgb_2; // 174
unsigned char save_data = 0; // 184
};
@@ -181,25 +178,116 @@ public:
MSIMysticLightController(hid_device* handle, const char *path);
~MSIMysticLightController();
unsigned int GetZoneMinLedCount(ZONE zone);
unsigned int GetZoneMaxLedCount(ZONE zone);
unsigned int GetZoneLedCount(ZONE zone);
void SetZoneLedCount(ZONE zone, unsigned int led_count);
unsigned int GetZoneMinLedCount
(
MSI_ZONE zone
);
unsigned int GetZoneMaxLedCount
(
MSI_ZONE zone
);
unsigned int GetZoneLedCount
(
MSI_ZONE zone
);
void SetZoneLedCount
(
MSI_ZONE zone,
unsigned int led_count
);
void SetMode
(
MSI_ZONE zone,
MSI_MODE mode,
MSI_SPEED speed,
MSI_BRIGHTNESS brightness,
bool rainbow_color
);
void GetMode
(
MSI_ZONE zone,
MSI_MODE &mode,
MSI_SPEED &speed,
MSI_BRIGHTNESS &brightness,
bool &rainbow_color
);
void SetZoneColor
(
MSI_ZONE zone,
unsigned char red1,
unsigned char grn1,
unsigned char blu1,
unsigned char red2,
unsigned char grn2,
unsigned char blu2
);
void SetCycleCount
(
MSI_ZONE zone,
unsigned char cycle_num
);
unsigned char GetCycleCount
(
MSI_ZONE zone
);
void SetMode(ZONE zone, EFFECT mode, SPEED speed, BRIGHTNESS brightness, bool rainbow_color);
void GetMode(ZONE zone, EFFECT &mode, SPEED &speed, BRIGHTNESS &brightness, bool &rainbow_color);
void SetZoneColor(ZONE zone, unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2);
void SetCycleCount(ZONE zone, unsigned char cycle_num);
unsigned char GetCycleCount(ZONE zone);
std::pair<Color, Color>
GetZoneColor(ZONE zone);
GetZoneColor(MSI_ZONE zone);
bool Update();
void SetDeviceSettings(bool stripe_or_fan, FAN_TYPE fan_type, unsigned char corsair_device_quantity, bool is_LL120Outer_individual);
void GetDeviceSettings(bool &stripe_or_fan, FAN_TYPE &fan_type, unsigned char &corsair_device_quantity, bool &is_LL120Outer_individual);
bool SetVolume(unsigned char main, unsigned char left, unsigned char right);
void SetBoardSyncSettings(bool onboard_sync, bool combine_JRGB, bool combine_JPIPE1, bool combine_JPIPE2, bool combine_JRAINBOW1, bool combine_JRAINBOW2, bool combine_crossair);
void GetBoardSyncSettings(bool &onboard_sync, bool &combine_JRGB, bool &combine_JPIPE1, bool &combine_JPIPE2, bool &combine_JRAINBOW1, bool &combine_JRAINBOW2, bool &combine_crossair);
void SetDeviceSettings
(
bool stripe_or_fan,
MSI_FAN_TYPE fan_type,
unsigned char corsair_device_quantity,
bool is_LL120Outer_individual
);
void GetDeviceSettings
(
bool &stripe_or_fan,
MSI_FAN_TYPE &fan_type,
unsigned char &corsair_device_quantity,
bool &is_LL120Outer_individual
);
bool SetVolume
(
unsigned char main,
unsigned char left,
unsigned char right
);
void SetBoardSyncSettings
(
bool onboard_sync,
bool combine_JRGB,
bool combine_JPIPE1,
bool combine_JPIPE2,
bool combine_JRAINBOW1,
bool combine_JRAINBOW2,
bool combine_crossair
);
void GetBoardSyncSettings
(
bool &onboard_sync,
bool &combine_JRGB,
bool &combine_JPIPE1,
bool &combine_JPIPE2,
bool &combine_JRAINBOW1,
bool &combine_JRAINBOW2,
bool &combine_crossair
);
std::string GetDeviceName();
std::string GetDeviceLocation();
@@ -212,9 +300,9 @@ private:
bool ReadFwVersion();
void ReadSerial();
void ReadName();
ZoneData* GetZoneData(ZONE zone);
ZoneData* GetZoneData(MSI_ZONE zone);
RainbowZoneData*
GetRainbowZoneData(ZONE zone);
GetRainbowZoneData(MSI_ZONE zone);
static unsigned char BitSet(unsigned char value, bool bit, unsigned int position);
hid_device* dev;
@@ -1,52 +1,56 @@
#include "MSIMysticLightController.h"
#include "RGBController_MSIMysticLight.h"
#include <algorithm>
#define MSI_VID 0x1462
#define MSI_USB_VID 0x1462
constexpr unsigned short SupportedPIDs[41] =
#define NUM_MSI_PIDS 41
static const unsigned short msi_pid_table[] =
{
31847, // MS_7C67
31504, // MS_7B10
31879, // MS_7C87
31635, // MS_7B93
31796, // MS_7C34
31797, // MS_7C35
31798, // MS_7C36
31799, // MS_7C37
31810, // MS_7C42
31876, // MS_7C84
31636, // MS_7B94
31638, // MS_7B96
31833, // MS_7C59
31840, // MS_7C60
31856, // MS_7C70
31857, // MS_7C71
31859, // MS_7C73
31861, // MS_7C75
31862, // MS_7C76
31863, // MS_7C77
31865, // MS_7C79
31872, // MS_7C80
31896, // MS_7C98
31897, // MS_7C99
31873, // MS_7C81
31874, // MS_7C82
31875, // MS_7C83
31877, // MS_7C85
31878, // MS_7C86
31880, // MS_7C88
31881, // MS_7C89
17497, // MS_4459
16036, // MS_3EA4
36957, // MS_905D
31888, // MS_7C90
31889, // MS_7C91
31890, // MS_7C92
31892, // MS_7C94
31893, // MS_7C95
31894, // MS_7C96
31830 // MS_7C56
0x3EA4, // MS_3EA4
0x4559, // MS_4459
0x7B10, // MS_7B10
0x7B93, // MSI B450 Gaming Pro Carbon AC
0x7B94, // MS_7B94
0x7B96, // MS_7B96
0x7C34, // MS_7C34
0x7C35, // MS_7C35
0x7C36, // MS_7C36
0x7C37, // MS_7C37
0x7C42, // MS_7C42
0x7C56, // MS_7C56
0x7C59, // MS_7C59
0x7C60, // MS_7C60
0x7C67, // MS_7C67
0x7C70, // MS_7C70
0x7C71, // MS_7C71
0x7C73, // MS_7C73
0x7C75, // MS_7C75
0x7C76, // MS_7C76
0x7C77, // MS_7C77
0x7C79, // MS_7C79
0x7C80, // MS_7C80
0x7C81, // MS_7C81
0x7C82, // MS_7C82
0x7C83, // MS_7C83
0x7C84, // MS_7C84
0x7C85, // MS_7C85
0x7C86, // MS_7C86
0x7C87, // MS_7C87
0x7C88, // MS_7C88
0x7C89, // MS_7C89
0x7C90, // MS_7C90
0x7C91, // MS_7C91
0x7C92, // MS_7C92
0x7C94, // MS_7C94
0x7C95, // MS_7C95
0x7C96, // MS_7C96
0x7C98, // MS_7C98
0x7C99, // MS_7C99
0x905D // MS_905D
};
/******************************************************************************************\
@@ -59,32 +63,39 @@ constexpr unsigned short SupportedPIDs[41] =
void DetectMSIMysticLightControllers(std::vector<RGBController*> &rgb_controllers)
{
if(hid_init() < 0)
{
return;
}
hid_device_info* info;
hid_device* dev;
hid_device_info * device_list = hid_enumerate(MSI_VID, 0);
if(!device_list)
{
return;
}
hid_init();
hid_device_info * device = device_list;
while(device)
for(int device_idx = 0; device_idx < NUM_MSI_PIDS; device_idx++)
{
if(std::find(std::begin(SupportedPIDs), std::end(SupportedPIDs), device->product_id) != std::end(SupportedPIDs))
dev = NULL;
info = hid_enumerate(MSI_USB_VID, msi_pid_table[device_idx]);
//Look for MSI Mystic Light Controller
while(info)
{
hid_device * dev = hid_open_path(device->path);
if(dev)
if((info->vendor_id == MSI_USB_VID)
&&(info->product_id == msi_pid_table[device_idx]))
{
MSIMysticLightController * controller = new MSIMysticLightController(dev, device_list->path);
RGBController_MSIMysticLight * rgb_controller = new RGBController_MSIMysticLight(controller);
rgb_controllers.push_back(rgb_controller);
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
device = device->next;
}
hid_free_enumeration(device_list);
if( dev )
{
MSIMysticLightController * controller = new MSIMysticLightController(dev, info->path);
RGBController_MSIMysticLight * rgb_controller = new RGBController_MSIMysticLight(controller);
rgb_controllers.push_back(rgb_controller);
}
}
}
@@ -4,54 +4,123 @@
| Adam Honse (calcprogrammer1@gmail.com), 12/29/2016 |
\*---------------------------------------------------------*/
#include "Hue2Controller.h"
#include "NZXTHue2Controller.h"
#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
Hue2Controller::Hue2Controller(libusb_device_handle* dev_handle)
NZXTHue2Controller::NZXTHue2Controller(hid_device* dev_handle, unsigned int rgb_channels, unsigned int fan_channels)
{
dev = dev_handle;
GetStripsOnChannel(HUE_2_CHANNEL_1);
num_fan_channels = fan_channels;
num_rgb_channels = rgb_channels;
SendFirmwareRequest();
UpdateDeviceList();
fan_cmd.resize(num_fan_channels);
fan_rpm.resize(num_fan_channels);
UpdateStatus();
}
Hue2Controller::~Hue2Controller()
NZXTHue2Controller::~NZXTHue2Controller()
{
}
unsigned int Hue2Controller::GetStripsOnChannel(unsigned int /*channel*/)
unsigned char NZXTHue2Controller::GetFanCommand
(
unsigned char fan_channel
)
{
unsigned int ret_val = 0;
return(fan_cmd[fan_channel]);
}
unsigned char usb_buf[] =
unsigned short NZXTHue2Controller::GetFanRPM
(
unsigned char fan_channel
)
{
return(fan_rpm[fan_channel]);
}
unsigned int NZXTHue2Controller::GetNumFanChannels()
{
return(num_fan_channels);
}
unsigned int NZXTHue2Controller::GetNumRGBChannels()
{
return(num_rgb_channels);
}
std::string NZXTHue2Controller::GetFirmwareVersion()
{
return(firmware_version);
}
void NZXTHue2Controller::SendFan
(
unsigned char port,
unsigned char mode,
unsigned char speed
)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up RGB packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x62;
usb_buf[0x01] = 0x01;
usb_buf[0x02] = 1 << port;
usb_buf[port + 3] = speed;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
}
void NZXTHue2Controller::UpdateDeviceList()
{
unsigned char usb_buf[64];
unsigned int ret_val = 0;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Device Information Request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x20;
usb_buf[0x01] = 0x03;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
/*-----------------------------------------------------*\
| Receive packets until 0x21 0x03 is received |
\*-----------------------------------------------------*/
do
{
0x20, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
int actual = 0;
ret_val = hid_read(dev, usb_buf, sizeof(usb_buf));
} while( (ret_val != 64) || (usb_buf[0] != 0x21) || (usb_buf[1] != 0x03) );
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x81, usb_buf, 64, &actual, 0);
for(int chan = 0; chan < 4; chan++)
for(int chan = 0; chan < num_rgb_channels; chan++)
{
unsigned int start = 0x0F + (6 * chan);
unsigned int num_leds_on_channel = 0;
@@ -85,10 +154,46 @@ unsigned int Hue2Controller::GetStripsOnChannel(unsigned int /*channel*/)
}
channel_leds[chan] = num_leds_on_channel;
}
return(ret_val);
}
void Hue2Controller::SetChannelEffect
void NZXTHue2Controller::UpdateStatus()
{
unsigned char usb_buf[64];
unsigned int ret_val = 0;
if(false)//num_fan_channels > 0)
{
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Read packet |
\*-----------------------------------------------------*/
do
{
ret_val = hid_read(dev, usb_buf, sizeof(usb_buf));
} while( (ret_val != 64) || (usb_buf[0] != 0x67) || (usb_buf[1] != 0x02) );
/*-----------------------------------------------------*\
| Extract fan information |
\*-----------------------------------------------------*/
for(int fan_idx = 0; fan_idx < num_fan_channels; fan_idx++)
{
unsigned char cmd;
unsigned short rpm;
cmd = usb_buf[40 + fan_idx];
rpm = ( usb_buf[25 + (2 * fan_idx)] << 8 ) | usb_buf[24 + (2 * fan_idx)];
fan_cmd[fan_idx] = cmd;
fan_rpm[fan_idx] = rpm;
}
}
}
void NZXTHue2Controller::SetChannelEffect
(
unsigned char channel,
unsigned char mode,
@@ -118,7 +223,7 @@ void Hue2Controller::SetChannelEffect
SendEffect(channel, mode, speed, direction, num_colors, &color_data[0]);
}
void Hue2Controller::SetChannelLEDs
void NZXTHue2Controller::SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
@@ -162,12 +267,11 @@ void Hue2Controller::SetChannelLEDs
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void Hue2Controller::SendApply
void NZXTHue2Controller::SendApply
(
unsigned char channel
)
{
int actual;
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
@@ -190,11 +294,11 @@ void Hue2Controller::SendApply
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x81, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 64);
//hid_read(dev, usb_buf, 64);
}
void Hue2Controller::SendDirect
void NZXTHue2Controller::SendDirect
(
unsigned char channel,
unsigned char group,
@@ -202,7 +306,6 @@ void Hue2Controller::SendDirect
unsigned char* color_data
)
{
int actual;
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
@@ -226,11 +329,11 @@ void Hue2Controller::SendDirect
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x81, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 64);
//hid_read(dev, usb_buf, 64);
}
void Hue2Controller::SendEffect
void NZXTHue2Controller::SendEffect
(
unsigned char channel,
unsigned char mode,
@@ -240,7 +343,6 @@ void Hue2Controller::SendEffect
unsigned char* color_data
)
{
int actual;
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
@@ -281,6 +383,35 @@ void Hue2Controller::SendEffect
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x0A], color_data, color_count * 3);
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x81, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 64);
//hid_read(dev, usb_buf, 64);
}
void NZXTHue2Controller::SendFirmwareRequest()
{
unsigned char usb_buf[64];
unsigned int ret_val = 0;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Firmware Request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x10;
usb_buf[0x01] = 0x01;
hid_write(dev, usb_buf, 64);
/*-----------------------------------------------------*\
| Receive packets until 0x11 0x01 is received |
\*-----------------------------------------------------*/
do
{
ret_val = hid_read(dev, usb_buf, sizeof(usb_buf));
} while( (ret_val != 64) || (usb_buf[0] != 0x11) || (usb_buf[1] != 0x01) );
snprintf(firmware_version, 16, "%u.%u.%u", usb_buf[0x11], usb_buf[0x12], usb_buf[0x13]);
}
@@ -5,8 +5,9 @@
\*---------------------------------------------------------*/
#include "RGBController.h"
#include <string>
#include <vector>
#include <libusb-1.0/libusb.h>
#include <hidapi/hidapi.h>
#pragma once
@@ -50,15 +51,33 @@ enum
HUE_2_NUM_MODES /* Number of Hue 2 modes */
};
class Hue2Controller
class NZXTHue2Controller
{
public:
Hue2Controller(libusb_device_handle* dev_handle);
~Hue2Controller();
NZXTHue2Controller(hid_device* dev_handle, unsigned int rgb_channels, unsigned int fan_channels);
~NZXTHue2Controller();
unsigned int GetStripsOnChannel
std::string GetFirmwareVersion();
unsigned char GetFanCommand
(
unsigned int channel
unsigned char fan_channel
);
unsigned short GetFanRPM
(
unsigned char fan_channel
);
unsigned int GetNumFanChannels();
unsigned int GetNumRGBChannels();
void SendFan
(
unsigned char port,
unsigned char mode,
unsigned char speed
);
void SetChannelEffect
@@ -77,11 +96,22 @@ public:
RGBColor * colors,
unsigned int num_colors
);
void UpdateDeviceList();
void UpdateStatus();
unsigned int channel_leds[HUE_2_NUM_CHANNELS];
private:
libusb_device_handle* dev;
hid_device* dev;
std::vector<unsigned char> fan_cmd;
std::vector<unsigned short> fan_rpm;
char firmware_version[16];
unsigned int num_fan_channels;
unsigned int num_rgb_channels;
void SendApply
(
@@ -105,4 +135,6 @@ private:
unsigned char color_count,
unsigned char* color_data
);
void SendFirmwareRequest();
};
@@ -0,0 +1,78 @@
#include "NZXTHue2Controller.h"
#include "RGBController.h"
#include "RGBController_NZXTHue2.h"
#include <vector>
#include <hidapi/hidapi.h>
#define NZXT_VID 0x1E71
#define NZXT_HUE_2_PID 0x2001
#define NZXT_HUE_2_AMBIENT_PID 0x2002
#define NZXT_SMART_DEVICE_V2_PID 0x2006
#define NZXT_RGB_FAN_CONTROLLER_PID 0x2009
typedef struct
{
unsigned short usb_vid;
unsigned short usb_pid;
unsigned int num_rgb_channels;
unsigned int num_fan_channels;
const char * name;
} nzxt_hue_2_device;
#define NZXT_HUE_2_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
static const nzxt_hue_2_device device_list[] =
{
/*-----------------------------------------------------------------------------------------------------*\
| NZXT Hue 2 devices |
\*-----------------------------------------------------------------------------------------------------*/
{ NZXT_VID, NZXT_HUE_2_PID, 4, 0, "NZXT Hue 2" },
{ NZXT_VID, NZXT_HUE_2_AMBIENT_PID, 2, 0, "NZXT Hue 2 Ambient" },
{ NZXT_VID, NZXT_SMART_DEVICE_V2_PID, 2, 3, "NZXT Smart Device V2" },
{ NZXT_VID, NZXT_RGB_FAN_CONTROLLER_PID, 2, 3, "NZXT RGB & Fan Controller" },
};
/******************************************************************************************\
* *
* DetectNZXTHue2Controllers *
* *
* Detect devices supported by the NZXT Hue 2 driver *
* *
\******************************************************************************************/
void DetectNZXTHue2Controllers(std::vector<RGBController*> &rgb_controllers)
{
hid_device_info* info;
hid_device* dev;
hid_init();
for(std::size_t device_idx = 0; device_idx < NZXT_HUE_2_NUM_DEVICES; device_idx++)
{
dev = NULL;
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for NZXT Hue 2 devices
while(info)
{
if((info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid))
{
dev = hid_open_path(info->path);
if( dev )
{
NZXTHue2Controller* controller = new NZXTHue2Controller(dev, device_list[device_idx].num_rgb_channels, device_list[device_idx].num_fan_channels);
RGBController_NZXTHue2* rgb_controller = new RGBController_NZXTHue2(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
info = info->next;
}
}
} /* DetectNZXTHue2Controllers() */
@@ -10,9 +10,6 @@
#include <sstream>
#include <cstring>
const int NZXT_KRAKEN_READ_ENDPOINT = 0x81;
const int NZXT_KRAKEN_WRITE_ENDPOINT = 0x01;
static void SetColor(const std::vector<RGBColor>& colors, unsigned char* color_data)
{
for (std::size_t idx = 0; idx < colors.size(); idx++)
@@ -30,7 +27,7 @@ static RGBColor ToLogoColor(RGBColor rgb)
return ToRGBColor(RGBGetGValue(rgb), RGBGetRValue(rgb), RGBGetBValue(rgb));
}
NZXTKrakenController::NZXTKrakenController(libusb_device_handle* dev_handle)
NZXTKrakenController::NZXTKrakenController(hid_device* dev_handle)
{
dev = dev_handle;
@@ -42,7 +39,7 @@ NZXTKrakenController::NZXTKrakenController(libusb_device_handle* dev_handle)
NZXTKrakenController::~NZXTKrakenController()
{
hid_close(dev);
}
std::string NZXTKrakenController::GetFirmwareVersion()
@@ -52,11 +49,17 @@ std::string NZXTKrakenController::GetFirmwareVersion()
void NZXTKrakenController::UpdateStatus()
{
int actual;
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0, sizeof(usb_buf));
libusb_interrupt_transfer(dev, NZXT_KRAKEN_READ_ENDPOINT, usb_buf, sizeof(usb_buf), &actual, 0);
/*-----------------------------------------------------*\
| Read packet |
\*-----------------------------------------------------*/
hid_read(dev, usb_buf, 64);
/*-----------------------------------------------------*\
| Extract cooler information |
@@ -87,14 +90,28 @@ void NZXTKrakenController::UpdateEffect
)
{
unsigned char color_data[9 * 3];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(color_data, 0, sizeof(color_data));
/*-----------------------------------------------------*\
| Fill in color data |
\*-----------------------------------------------------*/
if(!colors.empty() && channel != NZXT_KRAKEN_CHANNEL_RING)
{
colors[0] = ToLogoColor(colors[0]);
}
/*-----------------------------------------------------*\
| Update color data |
\*-----------------------------------------------------*/
SetColor(colors, color_data);
/*-----------------------------------------------------*\
| Send update packet |
\*-----------------------------------------------------*/
SendEffect(channel, mode, direction, color_data, speed, false, seq);
}
@@ -110,8 +127,7 @@ void NZXTKrakenController::SendEffect
int size /* = 0 */
)
{
int actual;
unsigned char usb_buf[65];
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -154,13 +170,5 @@ void NZXTKrakenController::SendEffect
/*-----------------------------------------------------*\
| Send effect |
\*-----------------------------------------------------*/
libusb_interrupt_transfer
(
dev,
NZXT_KRAKEN_WRITE_ENDPOINT,
usb_buf,
sizeof(usb_buf),
&actual,
0
);
hid_write(dev, usb_buf, 64);
}
@@ -9,7 +9,7 @@
#include "RGBController.h"
#include <vector>
#include <string>
#include <libusb-1.0/libusb.h>
#include <hidapi/hidapi.h>
enum NZXTKrakenChannel_t
{
@@ -46,7 +46,7 @@ enum
class NZXTKrakenController
{
public:
NZXTKrakenController(libusb_device_handle* dev_handle);
NZXTKrakenController(hid_device* dev_handle);
~NZXTKrakenController();
std::string GetFirmwareVersion();
@@ -76,7 +76,7 @@ private:
int size = 0
);
libusb_device_handle* dev;
hid_device* dev;
// -- status
std::string firmware_version;
@@ -2,7 +2,7 @@
#include "RGBController.h"
#include "RGBController_NZXTKraken.h"
#include <vector>
#include <libusb-1.0/libusb.h>
#include <hidapi/hidapi.h>
#define NZXT_KRAKEN_VID 0x1E71
#define NZXT_KRAKEN_PID 0x170E
@@ -17,21 +17,35 @@
void DetectNZXTKrakenControllers(std::vector<RGBController*> &rgb_controllers)
{
libusb_context * ctx;
libusb_init(&ctx);
hid_device_info* info;
hid_device* dev;
libusb_device_handle * dev = libusb_open_device_with_vid_pid(ctx, NZXT_KRAKEN_VID, NZXT_KRAKEN_PID);
hid_init();
if( dev )
for(std::size_t device_idx = 0; device_idx < 1; device_idx++)
{
libusb_detach_kernel_driver(dev, 0);
libusb_claim_interface(dev, 0);
dev = NULL;
NZXTKrakenController* controller = new NZXTKrakenController(dev);
info = hid_enumerate(NZXT_KRAKEN_VID, NZXT_KRAKEN_PID);
RGBController_NZXTKraken* rgb_controller = new RGBController_NZXTKraken(controller);
//Look for NZXT Kraken devices
while(info)
{
if((info->vendor_id == NZXT_KRAKEN_VID)
&&(info->product_id == NZXT_KRAKEN_PID))
{
dev = hid_open_path(info->path);
if( dev )
{
NZXTKrakenController* controller = new NZXTKrakenController(dev);
rgb_controllers.push_back(rgb_controller);
RGBController_NZXTKraken* rgb_controller = new RGBController_NZXTKraken(controller);
rgb_controllers.push_back(rgb_controller);
}
}
info = info->next;
}
}
}
@@ -6,16 +6,7 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
using namespace std::chrono_literals;
/******************************************************************************************\
* *
@@ -44,13 +35,13 @@ void DetectPatriotViperControllers(std::vector<i2c_smbus_interface*> &busses, st
// Tests SPD addresses in order: 0x00, 0x40, 0x41, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68
busses[bus]->i2c_smbus_write_byte_data(0x36, 0x00, 0xFF);
Sleep(1);
std::this_thread::sleep_for(1ms);
if(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x00) == 0x23)
{
busses[bus]->i2c_smbus_write_byte_data(0x37, 0x00, 0xFF);
Sleep(1);
std::this_thread::sleep_for(1ms);
if((busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x40) == 0x85)
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x41) == 0x02)
@@ -67,7 +58,7 @@ void DetectPatriotViperControllers(std::vector<i2c_smbus_interface*> &busses, st
}
}
Sleep(1);
std::this_thread::sleep_for(1ms);
}
if(slots_valid != 0)
@@ -15,49 +15,33 @@ PolychromeController::PolychromeController(i2c_smbus_interface* bus, polychrome_
this->bus = bus;
this->dev = dev;
switch (GetFirmwareVersion())
unsigned short fw_version = GetFirmwareVersion();
unsigned char major_version = fw_version >> 8;
unsigned char minor_version = fw_version & 0xFF;
/*-----------------------------------------------------*\
| Determine whether the device uses ASR LED or |
| Polychrome protocol by checking firmware version. |
| Versions 1.xx and 2.xx use ASR LED, 3.xx uses |
| Polychrome |
\*-----------------------------------------------------*/
if((major_version < 0x03) && (major_version > 0x00))
{
case FIRMWARE_VER_1_PT_10:
led_count = 1;
asr_led = true;
strcpy(device_name, "ASRock ASR LED FW 1.10");
break;
case FIRMWARE_VER_2_PT_00:
led_count = 1;
asr_led = true;
strcpy(device_name, "ASRock ASR LED FW 2.00");
break;
case FIRMWARE_VER_2_PT_08:
led_count = 1;
asr_led = true;
strcpy(device_name, "ASRock ASR LED FW 2.08");
break;
case FIRMWARE_VER_2_PT_10:
led_count = 1;
asr_led = true;
strcpy(device_name, "ASRock ASR LED FW 2.10");
break;
case FIRMWARE_VER_3_PT_00:
led_count = 1;
asr_led = false;
strcpy(device_name, "ASRock Polychrome FW 3.00");
break;
case FIRMWARE_VER_3_PT_04:
led_count = 1;
asr_led = false;
strcpy(device_name, "ASRock Polychrome FW 3.04");
break;
default:
led_count = 0;
strcpy(device_name, "");
break;
snprintf(device_name, 32, "ASRock ASR LED FW %d.%02d", major_version, minor_version);
led_count = 1;
asr_led = true;
}
else if(major_version == 0x03)
{
snprintf(device_name, 32, "ASRock Polychrome FW %d.%02d", major_version, minor_version);
led_count = 1;
asr_led = false;
}
else
{
led_count = 0;
}
}
PolychromeController::~PolychromeController()
@@ -102,17 +86,71 @@ bool PolychromeController::IsAsrLed()
return(asr_led);
}
void PolychromeController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
void PolychromeController::SetColorsAndSpeed(unsigned char red, unsigned char green, unsigned char blue, unsigned char speed)
{
unsigned char colors[3] = { red, green, blue };
unsigned char color_speed_pkt[4] = { red, green, blue, speed };
if (asr_led)
{
bus->i2c_smbus_write_block_data(dev, active_mode, 3, colors);
switch(active_mode)
{
/*-----------------------------------------------------*\
| These modes take 4 bytes in R/G/B/S order |
\*-----------------------------------------------------*/
case ASRLED_MODE_BREATHING:
case ASRLED_MODE_FLASHING:
case ASRLED_MODE_SPECTRUM_CYCLE:
bus->i2c_smbus_write_block_data(dev, active_mode, 4, color_speed_pkt);
break;
/*-----------------------------------------------------*\
| These modes take 3 bytes in R/G/B order |
\*-----------------------------------------------------*/
default:
case ASRLED_MODE_STATIC:
case ASRLED_MODE_MUSIC:
bus->i2c_smbus_write_block_data(dev, active_mode, 3, color_speed_pkt);
break;
/*-----------------------------------------------------*\
| These modes take 1 byte - speed |
\*-----------------------------------------------------*/
case ASRLED_MODE_RANDOM:
case ASRLED_MODE_WAVE:
bus->i2c_smbus_write_block_data(dev, active_mode, 1, &speed);
break;
/*-----------------------------------------------------*\
| These modes take no bytes |
\*-----------------------------------------------------*/
case ASRLED_MODE_OFF:
break;
}
}
else
{
bus->i2c_smbus_write_block_data(dev, POLYCHROME_REG_COLOR, 3, colors);
/*-----------------------------------------------------*\
| Polychrome firmware always writes color to fixed reg |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, POLYCHROME_REG_COLOR, 3, color_speed_pkt);
switch(active_mode)
{
/*-----------------------------------------------------*\
| These modes don't take a speed |
\*-----------------------------------------------------*/
POLYCHROME_MODE_OFF:
POLYCHROME_MODE_STATIC:
break;
/*-----------------------------------------------------*\
| All other modes, write speed to active mode register |
\*-----------------------------------------------------*/
default:
bus->i2c_smbus_write_block_data(dev, active_mode, 1, &speed);
break;
}
}
}
@@ -128,4 +166,4 @@ void PolychromeController::SetMode(unsigned char mode)
{
bus->i2c_smbus_write_block_data(dev, POLYCHROME_REG_MODE, 1, &active_mode);
}
}
}
@@ -14,16 +14,6 @@
typedef unsigned char polychrome_dev_id;
enum
{
FIRMWARE_VER_1_PT_10 = 0x010A, /* Firmware nu51_1.10 */
FIRMWARE_VER_2_PT_00 = 0x0200, /* Firmware nu51_2.00 */
FIRMWARE_VER_2_PT_08 = 0x0208, /* Firmware nu51_2.08 */
FIRMWARE_VER_2_PT_10 = 0x020A, /* Firmware nu51_2.10 */
FIRMWARE_VER_3_PT_00 = 0x0300, /* Firmware nu51_3.00 */
FIRMWARE_VER_3_PT_04 = 0x0304, /* Firmware nu51_3.04 */
};
enum
{
ASRLED_REG_FIRMWARE_VER = 0x00, /* Firmware version Major.Minor */
@@ -44,6 +34,13 @@ enum
ASRLED_MODE_WAVE = 0x18, /* Wave effect mode */
};
enum
{
ASRLED_SPEED_MIN = 0x05, /* Slowest speed */
ASRLED_SPEED_DEFAULT = 0x03, /* Default speed */
ASRLED_SPEED_MAX = 0x00, /* Fastest speed */
};
enum
{
POLYCHROME_REG_FIRMWARE_VER = 0x00, /* Firmware version Major.Minor */
@@ -71,6 +68,13 @@ enum
POLYCHROME_MODE_RAINBOW = 0x1E, /* Rainbow effect mode */
};
enum
{
POLYCHROME_SPEED_MIN = 0x05, /* Slowest speed */
POLYCHROME_SPEED_DEFAULT = 0x03, /* Default speed */
POLYCHROME_SPEED_MAX = 0x00, /* Fastest speed */
};
class PolychromeController
{
public:
@@ -81,7 +85,7 @@ public:
unsigned int GetLEDCount();
unsigned int GetMode();
bool IsAsrLed();
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
void SetColorsAndSpeed(unsigned char red, unsigned char green, unsigned char blue, unsigned char speed);
void SetMode(unsigned char mode);
unsigned short GetFirmwareVersion();
@@ -11,16 +11,7 @@
#include <cstring>
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
using namespace std::chrono_literals;
static unsigned int keys[] = {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x15,
0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
@@ -57,7 +48,7 @@ void PoseidonZRGBController::SetMode(unsigned char mode, unsigned char direction
active_speed
);
Sleep(200);
std::this_thread::sleep_for(200ms);
}
void PoseidonZRGBController::SetLEDsDirect(std::vector<RGBColor> colors)
@@ -107,7 +98,7 @@ void PoseidonZRGBController::SetLEDsDirect(std::vector<RGBColor> colors)
\*-----------------------------------------------------*/
hid_send_feature_report(dev, red_grn_buf, 264);
Sleep(5);
std::this_thread::sleep_for(5ms);
hid_send_feature_report(dev, blu_buf, 264);
}
@@ -132,7 +123,7 @@ void PoseidonZRGBController::SetLEDs(std::vector<RGBColor> colors)
red_color_data
);
Sleep(10);
std::this_thread::sleep_for(10ms);
SendColor
(
@@ -141,7 +132,7 @@ void PoseidonZRGBController::SetLEDs(std::vector<RGBColor> colors)
grn_color_data
);
Sleep(10);
std::this_thread::sleep_for(10ms);
SendColor
(
@@ -150,7 +141,7 @@ void PoseidonZRGBController::SetLEDs(std::vector<RGBColor> colors)
blu_color_data
);
Sleep(10);
std::this_thread::sleep_for(10ms);
SendControl
(
@@ -30,23 +30,25 @@ void DetectPoseidonZRGBControllers(std::vector<RGBController*>& rgb_controllers)
{
if((info->vendor_id == TT_POSEIDON_Z_RGB_VID)
&&(info->product_id == TT_POSEIDON_Z_RGB_PID)
&&(info->interface_number == 2))
#ifdef USE_HID_USAGE
&&(info->interface_number == 1)
&&(info->usage_page == 0xFF01))
#else
&&(info->interface_number == 1))
#endif
{
dev = hid_open_path(info->path);
break;
if( dev )
{
PoseidonZRGBController* controller = new PoseidonZRGBController(dev);
RGBController_PoseidonZRGB* rgb_controller = new RGBController_PoseidonZRGB(controller);
rgb_controllers.push_back(rgb_controller);
}
}
else
{
info = info->next;
}
}
if( dev )
{
PoseidonZRGBController* controller = new PoseidonZRGBController(dev);
RGBController_PoseidonZRGB* rgb_controller = new RGBController_PoseidonZRGB(controller);
rgb_controllers.push_back(rgb_controller);
}
}
@@ -0,0 +1,78 @@
/*-----------------------------------------*\
| RGBFusion2DRAMController.cpp |
| |
| Driver for Gigabyte Aorus RGB Fusion 2 |
| DRAM lighting controller |
| |
| Adam Honse (CalcProgrammer1) 6/7/2020 |
\*-----------------------------------------*/
#include "RGBFusion2DRAMController.h"
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
RGBFusion2DRAMController::RGBFusion2DRAMController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev)
{
/*-----------------------------------------------------*\
| Initialize pointers |
\*-----------------------------------------------------*/
this->bus = bus;
this->dev = dev;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(led_data, 0, sizeof(led_data));
/*-----------------------------------------------------*\
| Initialize controller with 6 LEDs and mask 0x3B |
| This is hard coded for Aorus RGB RAM |
\*-----------------------------------------------------*/
led_data[RGB_FUSION_2_DRAM_LED_EN_MASK] = 0x3B;
led_count = 6;
/*-----------------------------------------------------*\
| Initialize brightness to 100% |
\*-----------------------------------------------------*/
led_data[RGB_FUSION_2_DRAM_IDX_BRIGHTNESS] = 0x64;
}
unsigned int RGBFusion2DRAMController::GetLEDCount()
{
return(led_count);
}
std::string RGBFusion2DRAMController::GetDeviceLocation()
{
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
return_string.append(addr);
return(return_string);
}
void RGBFusion2DRAMController::Apply()
{
bus->i2c_smbus_write_byte_data(dev, RGB_FUSION_2_DRAM_APPLY_ADDR, RGB_FUSION_2_DRAM_ACTION_APPLY);
}
void RGBFusion2DRAMController::SetLEDEffect
(
unsigned int led,
int mode,
unsigned int speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
led_data[RGB_FUSION_2_DRAM_IDX_MODE] = mode;
led_data[RGB_FUSION_2_DRAM_IDX_RED] = red;
led_data[RGB_FUSION_2_DRAM_IDX_GREEN] = green;
led_data[RGB_FUSION_2_DRAM_IDX_BLUE] = blue;
bus->i2c_smbus_write_block_data(dev, RGB_FUSION_2_DRAM_LED_START_ADDR, 32, led_data);
}
@@ -0,0 +1,72 @@
/*-----------------------------------------*\
| RGBFusion2DRAMController.h |
| |
| Definitions and types for Gigabyte Aorus |
| RGB Fusion 2 DRAM lighting controller |
| |
| Adam Honse (CalcProgrammer1) 6/7/2020 |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char rgb_fusion_dev_id;
enum
{
RGB_FUSION_2_DRAM_LED_EN_MASK = 0x00, /* LED enable bitfield */
RGB_FUSION_2_DRAM_IDX_MODE = 0x09, /* Mode index */
RGB_FUSION_2_DRAM_IDX_BRIGHTNESS = 0x0A, /* Brightness index */
RGB_FUSION_2_DRAM_IDX_BLUE = 0x0C, /* Blue index */
RGB_FUSION_2_DRAM_IDX_GREEN = 0x0D, /* Green index */
RGB_FUSION_2_DRAM_IDX_RED = 0x0E, /* Red index */
// RGB_FUSION_2_DRAM_TIMER_1_LSB = 0x08, /* Timer 1 LSB. Valid timer values [0-65535] */
// RGB_FUSION_2_DRAM_TIMER_1_MSB = 0x09, /* Timer 1 MSB. Timer unis are milliseconds */
// RGB_FUSION_2_DRAM_TIMER_2_LSB = 0x0A, /* Timer 2 LSB */
// RGB_FUSION_2_DRAM_TIMER_2_MSB = 0x0B, /* Timer 2 MSB */
// RGB_FUSION_2_DRAM_TIMER_3_LSB = 0x0C, /* Timer 3 LSB */
// RGB_FUSION_2_DRAM_TIMER_3_MSB = 0x0D, /* Timer 3 MSB */
// RGB_FUSION_2_DRAM_IDX_OPT_1 = 0x0E, /* Option 1. Use case varies by mode */
// RGB_FUSION_2_DRAM_IDX_OPT_2 = 0x0F, /* Option 2. Use case varies by mode */
};
enum
{
RGB_FUSION_2_DRAM_LED_START_ADDR = 0x20,
RGB_FUSION_2_DRAM_APPLY_ADDR = 0x28,
};
enum
{
RGB_FUSION_2_DRAM_ACTION_APPLY = 0x0F,
};
class RGBFusion2DRAMController
{
public:
RGBFusion2DRAMController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev);
~RGBFusion2DRAMController();
std::string GetDeviceLocation();
unsigned int GetLEDCount();
void Apply();
void SetLEDEffect
(
unsigned int led,
int mode,
unsigned int speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
unsigned int led_count;
i2c_smbus_interface* bus;
rgb_fusion_dev_id dev;
unsigned char led_data[32];
};
@@ -0,0 +1,67 @@
#include "RGBFusion2DRAMController.h"
#include "RGBController.h"
#include "RGBController_RGBFusion2DRAM.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string>
/******************************************************************************************\
* *
* TestForRGBFusion2DRAMController *
* *
* Tests the given address to see if an RGB 2 Fusion DRAMcontroller exists there. *
* First does a quick write to test for a response *
* *
\******************************************************************************************/
bool TestForRGBFusion2DRAMController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
if (res >= 0)
{
pass = true;
// res = bus->i2c_smbus_read_byte_data(address, 0xF2);
// if (res != 0xC4)
// {
// pass = false;
// }
}
return(pass);
} /* TestForRGBFusion2DRAMController() */
/******************************************************************************************\
* *
* DetectRGBFusion2DRAMControllers *
* *
* Detect RGB Fusion 2 controllers on the enumerated I2C busses at address 0x67. *
* *
* bus - pointer to i2c_smbus_interface where RGB Fusion device is connected *
* dev - I2C address of RGB Fusion device *
* *
\******************************************************************************************/
void DetectRGBFusion2DRAMControllers(std::vector<i2c_smbus_interface*>& busses, std::vector<RGBController*>& rgb_controllers)
{
RGBFusion2DRAMController* new_rgb_fusion;
RGBController_RGBFusion2DRAM* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Check for RGB Fusion 2 DRAM controller at 0x67
if (TestForRGBFusion2DRAMController(busses[bus], 0x67))
{
new_rgb_fusion = new RGBFusion2DRAMController(busses[bus], 0x67);
new_controller = new RGBController_RGBFusion2DRAM(new_rgb_fusion);
rgb_controllers.push_back(new_controller);
}
}
} /* DetectRGBFusion2DRAMControllers() */
@@ -0,0 +1,139 @@
/*-----------------------------------------*\
| RGBFusion2SMBusController.cpp |
| |
| Driver for Gigabyte Aorus RGB Fusion 2 |
| SMBus lighting controller |
| |
| Adam Honse (CalcProgrammer1) 3/12/2020 |
| Matt Harper 5/5/2020 |
\*-----------------------------------------*/
#include "RGBFusion2SMBusController.h"
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#ifdef DEBUG
#include <iostream>
#include <iomanip>
#endif
RGBFusion2SMBusController::RGBFusion2SMBusController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev)
{
this->bus = bus;
this->dev = dev;
memset(led_data, 0, 10*16);
led_count = 10; // Protocol supports 10 'slots'
}
unsigned int RGBFusion2SMBusController::GetLEDCount()
{
return(led_count);
}
std::string RGBFusion2SMBusController::GetDeviceLocation()
{
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
return_string.append(addr);
return(return_string);
}
/* Writes are performed in 32 byte chunks. If we need to write the second 16 bytes,
* we must necessarily write the first 16 as well. Given that reading the existing state
* from the device is not yet possible, unfortunately we may overwrite existing device
* states if the state transition did not occur within in the same OpenRGB instance.
* That is to say, the current behavior is non-deal but the best we have
*/
void RGBFusion2SMBusController::WriteLED(int led)
{
unsigned short register_offset = led / 2; // Relying on integer division to truncate
unsigned short write_register = RGB_FUSION_2_LED_START_ADDR + 2*register_offset;
// Adjust if we are writing the second 16 bytes
if(led % 2)
{
led -= 1;
}
#ifdef DEBUG
std::cout << std::hex << write_register << "\t";
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 16; j++)
{
std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)led_data[led+i][j] << " ";
}
std::cout << " ";
}
std::cout << std::endl;
#endif
bus->i2c_smbus_write_block_data(RGB_FUSION_2_SMBUS_ADDR, write_register, 32, led_data[led]);
}
void RGBFusion2SMBusController::Apply()
{
// Protocol expects terminating sequence 0x01ff written to register 0x17
bus->i2c_smbus_write_word_data(RGB_FUSION_2_SMBUS_ADDR,
RGB_FUSION_2_APPLY_ADDR,
RGB_FUSION_2_ACTION_APPLY);
}
void RGBFusion2SMBusController::SetLEDEffect
(
unsigned int led,
int mode,
unsigned int speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
led_data[led][RGB_FUSION_2_IDX_MODE] = mode;
led_data[led][RGB_FUSION_2_IDX_RED] = red;
led_data[led][RGB_FUSION_2_IDX_GREEN] = green;
led_data[led][RGB_FUSION_2_IDX_BLUE] = blue;
led_data[led][RGB_FUSION_2_IDX_BRIGHTNESS] = 0x64;
switch (mode)
{
case RGB_FUSION_2_MODE_PULSE:
// Timer 1: On time
// Timer 2: Off time
led_data[led][RGB_FUSION_2_TIMER_1_LSB] = 0x20 * speed;
led_data[led][RGB_FUSION_2_TIMER_1_MSB] = 0x03 * speed;
led_data[led][RGB_FUSION_2_TIMER_2_LSB] = 0x20 * speed;
led_data[led][RGB_FUSION_2_TIMER_2_MSB] = 0x03 * speed;
break;
case RGB_FUSION_2_MODE_COLOR_CYCLE:
// Timer 1: Cycle time
led_data[led][RGB_FUSION_2_TIMER_1_LSB] = 0x00;
led_data[led][RGB_FUSION_2_TIMER_1_MSB] = 0x03 * speed;
led_data[led][RGB_FUSION_2_IDX_OPT_1] = 0x07; // Number of colors to cycle through. Valid range [1-7]
led_data[led][RGB_FUSION_2_IDX_OPT_2] = 0x00; // Color cycle, or color cycle and pulse. [0,1]
break;
case RGB_FUSION_2_MODE_FLASHING:
/* Timer 1: On time
* Timer 2: Interval
* Timer 3: Cycle time */
led_data[led][RGB_FUSION_2_TIMER_1_LSB] = 0x64;
led_data[led][RGB_FUSION_2_TIMER_1_MSB] = 0;
led_data[led][RGB_FUSION_2_TIMER_2_LSB] = 0xc8;
led_data[led][RGB_FUSION_2_TIMER_2_MSB] = 0;
led_data[led][RGB_FUSION_2_TIMER_3_LSB] = 0xd0;
led_data[led][RGB_FUSION_2_TIMER_3_MSB] = 0x07;
led_data[led][RGB_FUSION_2_IDX_OPT_1] = speed; // Controls number of flashes
break;
}
WriteLED(led);
}
@@ -0,0 +1,103 @@
/*-----------------------------------------*\
| RGBFusion2SMBusController.h |
| |
| Definitions and types for Gigabyte Aorus |
| RGB Fusion 2 SMBus lighting controller |
| |
| Adam Honse (CalcProgrammer1) 3/12/2020 |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char rgb_fusion_dev_id;
enum
{
RGB_FUSION_2_IDX_MODE = 0x01, /* Mode index */
RGB_FUSION_2_IDX_BRIGHTNESS = 0x02, /* Brightness index */
RGB_FUSION_2_IDX_MAX_BRIGHTNESS = 0x02, /* Max brightness index */
RGB_FUSION_2_IDX_MIN_BRIGHTNESS = 0x03, /* Minimum brightness index */
RGB_FUSION_2_IDX_BLUE = 0x04, /* Blue index */
RGB_FUSION_2_IDX_GREEN = 0x05, /* Green index */
RGB_FUSION_2_IDX_RED = 0x06, /* Red index */
RGB_FUSION_2_IDX_WHITE = 0x07, /* White index */
RGB_FUSION_2_TIMER_1_LSB = 0x08, /* Timer 1 LSB. Valid timer values [0-65535] */
RGB_FUSION_2_TIMER_1_MSB = 0x09, /* Timer 1 MSB. Timer unis are milliseconds */
RGB_FUSION_2_TIMER_2_LSB = 0x0A, /* Timer 2 LSB */
RGB_FUSION_2_TIMER_2_MSB = 0x0B, /* Timer 2 MSB */
RGB_FUSION_2_TIMER_3_LSB = 0x0C, /* Timer 3 LSB */
RGB_FUSION_2_TIMER_3_MSB = 0x0D, /* Timer 3 MSB */
RGB_FUSION_2_IDX_OPT_1 = 0x0E, /* Option 1. Use case varies by mode */
RGB_FUSION_2_IDX_OPT_2 = 0x0F, /* Option 2. Use case varies by mode */
};
enum
{
RGB_FUSION_2_APPLY_ADDR = 0x17,
RGB_FUSION_2_LED_START_ADDR = 0x20,
RGB_FUSION_2_SMBUS_ADDR = 0x68,
};
enum
{
RGB_FUSION_2_ACTION_APPLY = 0x01ff,
};
enum
{
RGB_FUSION_2_MODE_PULSE = 0x01, /* Pulse mode */
RGB_FUSION_2_MODE_MUSIC = 0x02, /* Music mode */
RGB_FUSION_2_MODE_COLOR_CYCLE = 0x03, /* Color cycle mode */
RGB_FUSION_2_MODE_STATIC = 0x04, /* Static color mode */
RGB_FUSION_2_MODE_FLASHING = 0x05, /* Flashing / Double Flashing mode */
RGB_FUSION_2_MODE_TRANSITION = 0x09, /* Gradual transition from current */
RGB_FUSION_2_MODE_DIGITAL_A = 0x0A, /* Wave mode */
RGB_FUSION_2_MODE_DIGITAL_B = 0x0B, /* */
RGB_FUSION_2_MODE_DIGITAL_C = 0x0C, /* */
RGB_FUSION_2_MODE_DIGITAL_D = 0x0D, /* */
RGB_FUSION_2_MODE_DIGITAL_E = 0x0E, /* */
RGB_FUSION_2_MODE_DIGITAL_F = 0x0F, /* */
RGB_FUSION_2_MODE_DIGITAL_G = 0x10, /* */
RGB_FUSION_2_MODE_DIGITAL_H = 0x11, /* */
RGB_FUSION_2_MODE_DIGITAL_I = 0x12, /* */
};
enum
{
RGB_FUSION_2_SPEED_FAST = 0x01,
RGB_FUSION_2_SPEED_NORMAL = 0x02,
RGB_FUSION_2_SPEED_SLOW = 0x04,
};
class RGBFusion2SMBusController
{
public:
RGBFusion2SMBusController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev);
~RGBFusion2SMBusController();
std::string GetDeviceLocation();
unsigned int GetLEDCount();
void Apply();
void SetLEDEffect
(
unsigned int led,
int mode,
unsigned int speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
unsigned int led_count;
i2c_smbus_interface* bus;
rgb_fusion_dev_id dev;
unsigned char led_data[10][16];
void WriteLED(int);
};
@@ -0,0 +1,73 @@
#include "RGBFusion2SMBusController.h"
#include "RGBController.h"
#include "RGBController_RGBFusion2SMBus.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string>
/******************************************************************************************\
* *
* TestForRGBFusion2SMBusController *
* *
* Tests the given address to see if an RGB 2 Fusion controller exists there. First *
* does a quick write to test for a response *
* *
\******************************************************************************************/
bool TestForRGBFusion2SMBusController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
if (res >= 0)
{
pass = true;
// res = bus->i2c_smbus_read_byte_data(address, 0xF2);
// if (res != 0xC4)
// {
// pass = false;
// }
}
return(pass);
} /* TestForRGBFusion2SMBusController() */
/******************************************************************************************\
* *
* DetectRGBFusion2SMBusControllers *
* *
* Detect RGB Fusion 2 controllers on the enumerated I2C busses at address 0x68. *
* *
* bus - pointer to i2c_smbus_interface where RGB Fusion device is connected *
* dev - I2C address of RGB Fusion device *
* *
\******************************************************************************************/
void DetectRGBFusion2SMBusControllers(std::vector<i2c_smbus_interface*>& busses, std::vector<RGBController*>& rgb_controllers)
{
RGBFusion2SMBusController* new_rgb_fusion;
RGBController_RGBFusion2SMBus* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// TODO - Is this necessary? Or an artifact of my own system?
// Skip dmcd devices
std::string device_name = std::string(busses[bus]->device_name);
if (device_name.find("dmdc") == std::string::npos)
{
// Check for RGB Fusion 2 controller at 0x68
if (TestForRGBFusion2SMBusController(busses[bus], 0x68))
{
new_rgb_fusion = new RGBFusion2SMBusController(busses[bus], 0x68);
new_controller = new RGBController_RGBFusion2SMBus(new_rgb_fusion);
rgb_controllers.push_back(new_controller);
}
}
}
} /* DetectRGBFusion2SMBusControllers() */
@@ -27,16 +27,17 @@ static LEDCount LedCountToEnum(unsigned int c)
return(LEDS_1024);
}
RGBFusion2USBController::RGBFusion2USBController(hid_device* handle, const char *path) : dev(handle)
RGBFusion2USBController::RGBFusion2USBController(hid_device* handle, const char *path, std::string mb_name) : dev(handle)
{
int res = 0;
char text[64] {};
unsigned char buffer[64] {};
if( dev ) {
int res = 0;
char text[64] = { 0x00 };
unsigned char buffer[64] = { 0x00 };
if( dev )
{
SetCalibration();
name = mb_name;
// hid report read needs 0x60 packet or it gives IO error
SendPacket(0x60, 0x00);
@@ -46,8 +47,8 @@ RGBFusion2USBController::RGBFusion2USBController(hid_device* handle, const char
{
report = *reinterpret_cast<IT8297Report*>(buffer);
name = std::string(report.str_product, 32);
name.erase(std::find(name.begin(), name.end(), '\0'), name.end());
description = std::string(report.str_product, 32);
//description.erase(std::find(description.begin(), description.end(), '\0'), name.end());
snprintf(text, 11, "0x%08X", report.fw_ver);
version = text;
@@ -55,7 +56,6 @@ RGBFusion2USBController::RGBFusion2USBController(hid_device* handle, const char
snprintf(text, 11, "0x%08X", report.chip_id);
chip_id = text;
}
loc = path;
EnableBeat(false);
@@ -84,13 +84,13 @@ void RGBFusion2USBController::SetCalibration()
buffer[0] = report_id;
buffer[1] = 0x33;
// D_LED1 WS2812 GRB, 0x00RRGGBB to 0x00GGRRBB
// D_LED1 WS2812 GRB, 0x00RRGGBB to 0x00GGRRBB
buffer[2] = 0x02; // B
buffer[3] = 0x00; // G
buffer[4] = 0x01; // R
buffer[5] = 0x00;
// D_LED2 WS2812 GRB
// D_LED2 WS2812 GRB
buffer[6] = 0x02;
buffer[7] = 0x00;
buffer[8] = 0x01;
@@ -102,6 +102,12 @@ void RGBFusion2USBController::SetCalibration()
buffer[12] = 0x02;
buffer[13] = 0x00;
// Spare set seen in some Motherboard models
buffer[14] = 0x00;
buffer[15] = 0x01;
buffer[16] = 0x02;
buffer[17] = 0x00;
SendPacket(buffer);
}
@@ -135,6 +141,11 @@ std::string RGBFusion2USBController::GetDeviceName()
return(name);
}
std::string RGBFusion2USBController::GetDeviceDescription()
{
return(description);
}
std::string RGBFusion2USBController::GetFWVersion()
{
return(version);
@@ -157,7 +157,7 @@ struct IT8297Report
class RGBFusion2USBController
{
public:
RGBFusion2USBController(hid_device* handle, const char *path);
RGBFusion2USBController(hid_device* handle, const char *path, std::string mb_name);
~RGBFusion2USBController();
void SetStripColors
@@ -175,6 +175,7 @@ public:
bool DisableBuiltinEffect(int enable_bit, int mask);
void SetCalibration();
std::string GetDeviceName();
std::string GetDeviceDescription();
std::string GetDeviceLocation();
std::string GetFWVersion();
std::string GetSerial();
@@ -188,6 +189,7 @@ private:
int mode;
IT8297Report report;
std::string name;
std::string description;
std::string loc;
std::string version;
std::string chip_id;
@@ -1,8 +1,18 @@
#include "RGBFusion2USBController.h"
#include "RGBController_RGBFusion2USB.h"
#include "dependencies/dmiinfo.h"
#define IT8297_VID 0x048D
#define IT8297_PID 0x8297
#define IT8297_VID 0x048D
#define IT8297_IFC 0
#define IT8297_U 0xCC
#define IT8297_UPG 0xFF89
#define COUNT_RGBFUSION2_PIDS (sizeof(RGBFusion2_pids) / sizeof(RGBFusion2_pids[ 0 ]))
static const unsigned short RGBFusion2_pids[] =
{
0x8297, //PID for the ITE 8595 found on the X570
0x5702 //PID for the ITE 8595 found on the B550
};
/******************************************************************************************\
* *
@@ -14,24 +24,47 @@
void DetectRGBFusion2USBControllers(std::vector<RGBController*> &rgb_controllers)
{
hid_device_info* info;
hid_device* dev;
DMIInfo MB_info;
unsigned short tmpPID;
if (hid_init() < 0)
return;
hid_device_info * device_list = hid_enumerate(IT8297_VID, IT8297_PID);
if (!device_list)
return;
hid_device_info * device = device_list;
while (device)
{
hid_device * dev = hid_open_path(device->path);
if (dev) {
RGBFusion2USBController * controller = new RGBFusion2USBController(dev, device_list->path);
RGBController_RGBFusion2USB * rgb_controller = new RGBController_RGBFusion2USB(controller);
rgb_controllers.push_back(rgb_controller);
}
device = device->next;
return;
}
hid_free_enumeration(device_list);
for(int dev_idx = 0; dev_idx < COUNT_RGBFUSION2_PIDS; dev_idx++)
{
dev = NULL;
tmpPID = RGBFusion2_pids[dev_idx];
info = hid_enumerate(IT8297_VID, tmpPID);
while(info)
{
if((info->vendor_id == IT8297_VID)
#ifdef USE_HID_USAGE
&&(info->product_id == tmpPID)
&&(info->usage == IT8297_U) //Usage and usage page required to get the correct interface
&&(info->usage_page == IT8297_UPG))
#else
&&(info->interface_number == IT8297_IFC) //Interface is only valid on Windows where there is > 1 interface
&&(info->product_id == tmpPID))
#endif
{
hid_device * dev = hid_open_path(info->path);
if (dev)
{
RGBFusion2USBController * controller = new RGBFusion2USBController(dev, info->path, MB_info.getMainboard());
RGBController_RGBFusion2USB * rgb_controller = new RGBController_RGBFusion2USB(controller);
rgb_controllers.push_back(rgb_controller);
break;
}
}
info = info->next;
}
}
hid_free_enumeration(info);
}
@@ -10,14 +10,18 @@
| Keyboard product IDs |
\*-----------------------------------------------------*/
#define REDRAGON_KEYBOARD_VID 0x0C45
#define REDRAGON_KEYBOARD_USAGE_PAGE 0xFF1C
#define REDRAGON_K550_PID 0x5204
#define REDRAGON_K552_PID 0x5104
#define REDRAGON_K556_PID 0x5004
#define TECWARE_PHANTOM_ELITE_PID 0x652F
#define WARRIOR_KANE_TC235 0x8520
/*-----------------------------------------------------*\
| Mouse product IDs |
\*-----------------------------------------------------*/
#define REDRAGON_MOUSE_VID 0x04D9
#define REDRAGON_MOUSE_USAGE_PAGE 0xFFA0
#define REDRAGON_M711_PID 0xFC30
#define REDRAGON_M715_PID 0xFC39
@@ -26,6 +30,7 @@ typedef struct
unsigned short usb_vid;
unsigned short usb_pid;
unsigned char usb_interface;
unsigned short usb_usage_page;
device_type type;
const char * name;
} redragon_device;
@@ -34,19 +39,22 @@ typedef struct
static const redragon_device device_list[] =
{
/*-----------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-----------------------------------------------------------------------------------------------------*/
{ REDRAGON_KEYBOARD_VID, REDRAGON_K550_PID, 1, DEVICE_TYPE_KEYBOARD, "Redragon K550 Yama" },
{ REDRAGON_KEYBOARD_VID, REDRAGON_K556_PID, 1, DEVICE_TYPE_KEYBOARD, "Redragon K556 Devarajas" },
/*-----------------------------------------------------------------------------------------------------*\
| Mice |
\*-----------------------------------------------------------------------------------------------------*/
{ REDRAGON_MOUSE_VID, REDRAGON_M711_PID, 2, DEVICE_TYPE_MOUSE, "Redragon M711 Cobra" },
{ REDRAGON_MOUSE_VID, REDRAGON_M715_PID, 2, DEVICE_TYPE_MOUSE, "Redragon M715 Dagger" },
/*-----------------------------------------------------------------------------------------------------*\
| Mousemats |
\*-----------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------------------------------------------*\
| Keyboards |
\*---------------------------------------------------------------------------------------------------------------------------------------------*/
{ REDRAGON_KEYBOARD_VID, REDRAGON_K550_PID, 1, REDRAGON_KEYBOARD_USAGE_PAGE, DEVICE_TYPE_KEYBOARD, "Redragon K550 Yama" },
{ REDRAGON_KEYBOARD_VID, REDRAGON_K552_PID, 1, REDRAGON_KEYBOARD_USAGE_PAGE, DEVICE_TYPE_KEYBOARD, "Redragon K552 Kumara" },
{ REDRAGON_KEYBOARD_VID, REDRAGON_K556_PID, 1, REDRAGON_KEYBOARD_USAGE_PAGE, DEVICE_TYPE_KEYBOARD, "Redragon K556 Devarajas" },
{ REDRAGON_KEYBOARD_VID, TECWARE_PHANTOM_ELITE_PID, 1, REDRAGON_KEYBOARD_USAGE_PAGE, DEVICE_TYPE_KEYBOARD, "Tecware Phantom Elite" },
{ REDRAGON_KEYBOARD_VID, WARRIOR_KANE_TC235, 1, REDRAGON_KEYBOARD_USAGE_PAGE, DEVICE_TYPE_KEYBOARD, "Warrior Kane TC235" },
/*---------------------------------------------------------------------------------------------------------------------------------------------*\
| Mice |
\*---------------------------------------------------------------------------------------------------------------------------------------------*/
{ REDRAGON_MOUSE_VID, REDRAGON_M711_PID, 2, REDRAGON_MOUSE_USAGE_PAGE, DEVICE_TYPE_MOUSE, "Redragon M711 Cobra" },
{ REDRAGON_MOUSE_VID, REDRAGON_M715_PID, 2, REDRAGON_MOUSE_USAGE_PAGE, DEVICE_TYPE_MOUSE, "Redragon M715 Dagger" },
/*---------------------------------------------------------------------------------------------------------------------------------------------*\
| Mousemats |
\*---------------------------------------------------------------------------------------------------------------------------------------------*/
};
/******************************************************************************************\
@@ -73,45 +81,46 @@ void DetectRedragonControllers(std::vector<RGBController*>& rgb_controllers)
//Look for Redragon RGB Peripheral
while(info)
{
if((info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid)
if((info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid)
#ifdef USE_HID_USAGE
&&(info->interface_number == device_list[device_idx].usb_interface)
&&(info->usage_page == device_list[device_idx].usb_usage_page))
#else
&&(info->interface_number == device_list[device_idx].usb_interface))
#endif
{
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
if( dev )
{
switch(device_list[device_idx].type)
{
case DEVICE_TYPE_KEYBOARD:
if( dev )
{
switch(device_list[device_idx].type)
{
RedragonK556Controller* controller = new RedragonK556Controller(dev);
case DEVICE_TYPE_KEYBOARD:
{
RedragonK556Controller* controller = new RedragonK556Controller(dev);
RGBController_RedragonK556* rgb_controller = new RGBController_RedragonK556(controller);
RGBController_RedragonK556* rgb_controller = new RGBController_RedragonK556(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
break;
case DEVICE_TYPE_MOUSE:
{
RedragonM711Controller* controller = new RedragonM711Controller(dev);
RGBController_RedragonM711* rgb_controller = new RGBController_RedragonM711(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
break;
}
break;
case DEVICE_TYPE_MOUSE:
{
RedragonM711Controller* controller = new RedragonM711Controller(dev);
RGBController_RedragonM711* rgb_controller = new RGBController_RedragonM711(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
break;
}
}
info = info->next;
}
}
}
@@ -63,7 +63,7 @@ enum
enum
{
REDRAGON_K556_BRIGHTNESS_LOWEST = 0x00, /* Lowest brightness (off) */
REDRAGON_K556_BRIGHTNESS_HIGHEST = 0x05, /* Highest brightness */
REDRAGON_K556_BRIGHTNESS_HIGHEST = 0x04, /* Highest brightness */
};
enum
@@ -2,24 +2,66 @@
#include <cstring>
static void send_usb_msg(hid_device* dev, char * data_pkt, unsigned int size)
{
char* usb_pkt = new char[size + 1];
usb_pkt[0] = 0x00;
for(int i = 1; i < size + 1; i++)
{
usb_pkt[i] = data_pkt[i-1];
}
hid_send_feature_report(dev, (unsigned char *)usb_pkt, size + 1);
delete usb_pkt;
}
RedragonM711Controller::RedragonM711Controller(hid_device* dev_handle)
{
dev = dev_handle;
unsigned char active_profile = 0x00;
SendWritePacket(0x002C, 1, &active_profile);
SendMouseApply();
}
void RedragonM711Controller::SendMouseColor
(
unsigned char red,
unsigned char green,
unsigned char blue
)
{
unsigned char color_buf[3];
color_buf[0] = red;
color_buf[1] = green;
color_buf[2] = blue;
SendWritePacket(0x0449, 3, color_buf);
}
void RedragonM711Controller::SendMouseMode
(
unsigned char mode,
unsigned char speed
)
{
unsigned char mode_buf[3];
mode_buf[0] = 0x01; //On
mode_buf[1] = speed;
mode_buf[2] = mode;
SendWritePacket(0x044C, 3, mode_buf);
}
void RedragonM711Controller::SendMouseMode
(
unsigned char mode,
unsigned char speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
unsigned char color_mode_buf[6];
color_mode_buf[0] = red;
color_mode_buf[1] = green;
color_mode_buf[2] = blue;
color_mode_buf[3] = 0x01; //On
color_mode_buf[4] = speed;
color_mode_buf[5] = mode;
SendWritePacket(0x0449, 6, color_mode_buf);
}
/*-------------------------------------------------------------------------------------------------*\
@@ -46,16 +88,14 @@ void RedragonM711Controller::SendMouseApply()
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf, 16);
hid_send_feature_report(dev, (unsigned char *)usb_buf, 16);
}
void RedragonM711Controller::SendMouseMode
void RedragonM711Controller::SendWritePacket
(
unsigned char mode,
unsigned char speed,
unsigned char red,
unsigned char green,
unsigned char blue
unsigned short address,
unsigned char data_size,
unsigned char * data
)
{
char usb_buf[16];
@@ -70,21 +110,17 @@ void RedragonM711Controller::SendMouseMode
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x02;
usb_buf[0x01] = 0xF3;
usb_buf[0x02] = 0x49;
usb_buf[0x03] = 0x04;
usb_buf[0x04] = 0x06;
usb_buf[0x08] = red;
usb_buf[0x09] = green;
usb_buf[0x0A] = blue;
usb_buf[0x0B] = 0x01; //on
usb_buf[0x0C] = speed;
usb_buf[0x0D] = mode;
usb_buf[0x02] = address & 0xFF;
usb_buf[0x03] = address >> 8;
usb_buf[0x04] = data_size;
/*-----------------------------------------------------*\
| Copy in data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x08], data, data_size);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf, 16);
hid_send_feature_report(dev, (unsigned char *)usb_buf, 16);
}
@@ -32,6 +32,19 @@ public:
void SendMouseApply();
void SendMouseColor
(
unsigned char red,
unsigned char green,
unsigned char blue
);
void SendMouseMode
(
unsigned char mode,
unsigned char speed
);
void SendMouseMode
(
unsigned char mode,
@@ -43,4 +56,11 @@ public:
private:
hid_device* dev;
void SendWritePacket
(
unsigned short address,
unsigned char data_size,
unsigned char * data
);
};
@@ -0,0 +1,58 @@
/*-----------------------------------------*\
| SapphireGPUController.cpp |
| |
| Driver for Sapphire Nitro Glow GPU RGB |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 7/15/2020 |
\*-----------------------------------------*/
#include "SapphireGPUController.h"
SapphireGPUController::SapphireGPUController(i2c_smbus_interface* bus, sapphire_dev_id dev)
{
this->bus = bus;
this->dev = dev;
}
SapphireGPUController::~SapphireGPUController()
{
}
std::string SapphireGPUController::GetDeviceLocation()
{
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
return_string.append(addr);
return(return_string);
}
unsigned char SapphireGPUController::GetRed()
{
return(bus->i2c_smbus_read_byte_data(dev, SAPPHIRE_GPU_REG_RED));
}
unsigned char SapphireGPUController::GetGreen()
{
return(bus->i2c_smbus_read_byte_data(dev, SAPPHIRE_GPU_REG_GREEN));
}
unsigned char SapphireGPUController::GetBlue()
{
return(bus->i2c_smbus_read_byte_data(dev, SAPPHIRE_GPU_REG_BLUE));
}
void SapphireGPUController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
{
bus->i2c_smbus_write_byte_data(dev, SAPPHIRE_GPU_REG_RED, red);
bus->i2c_smbus_write_byte_data(dev, SAPPHIRE_GPU_REG_GREEN, green);
bus->i2c_smbus_write_byte_data(dev, SAPPHIRE_GPU_REG_BLUE, blue);
}
void SapphireGPUController::SetMode(unsigned char mode, unsigned char speed)
{
bus->i2c_smbus_write_byte_data(dev, SAPPHIRE_GPU_REG_MODE, mode);
}
@@ -0,0 +1,55 @@
/*-----------------------------------------*\
| SapphireGPUController.h |
| |
| Definitions and types for Sapphire Nitro |
| Glow GPU RGB lighting controller |
| |
| Adam Honse (CalcProgrammer1) 7/15/2020 |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char sapphire_dev_id;
enum
{
SAPPHIRE_GPU_REG_MODE = 0x00,
SAPPHIRE_GPU_REG_BRIGHTNESS = 0x01,
SAPPHIRE_GPU_REG_RED = 0x03,
SAPPHIRE_GPU_REG_GREEN = 0x04,
SAPPHIRE_GPU_REG_BLUE = 0x05,
};
enum
{
SAPPHIRE_GPU_MODE_SAPPHIRE_BLUE = 0x00,
SAPPHIRE_GPU_MODE_RAINBOW = 0x01,
SAPPHIRE_GPU_MODE_BOARD_TEMPERATURE = 0x02,
SAPPHIRE_GPU_MODE_FAN_SPEED = 0x03,
SAPPHIRE_GPU_MODE_CUSTOM = 0x04,
SAPPHIRE_GPU_MODE_OFF = 0x05,
};
class SapphireGPUController
{
public:
SapphireGPUController(i2c_smbus_interface* bus, sapphire_dev_id dev);
~SapphireGPUController();
std::string GetDeviceLocation();
unsigned char GetRed();
unsigned char GetGreen();
unsigned char GetBlue();
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
void SetMode(unsigned char mode, unsigned char speed);
private:
i2c_smbus_interface* bus;
sapphire_dev_id dev;
};
@@ -0,0 +1,59 @@
#include "SapphireGPUController.h"
#include "RGBController.h"
#include "RGBController_SapphireGPU.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
/******************************************************************************************\
* *
* TestForSapphireGPUController *
* *
* Tests the given address to see if a Sapphire GPU controller exists there. First *
* does a quick write to test for a response *
* *
\******************************************************************************************/
bool TestForSapphireGPUController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
int res;
if(bus->i2c_smbus_read_byte_data(address, 0x06) == 0xCC)
{
pass = true;
}
return(false); //TODO - better detection, leaving disabled for now
} /* TestForSapphireGPUController() */
/******************************************************************************************\
* *
* DetectSapphireGPUControllers *
* *
* Detect Sapphire GPU controllers on the enumerated I2C busses at address 0x55. *
* *
* bus - pointer to i2c_smbus_interface where Sapphire GPU device is connected *
* dev - I2C address of Sapphire GPU device *
* *
\******************************************************************************************/
void DetectSapphireGPUControllers(std::vector<i2c_smbus_interface*>& busses, std::vector<RGBController*>& rgb_controllers)
{
SapphireGPUController* new_sapphire;
RGBController_SapphireGPU* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Check for Sapphire GPU controller at 0x55
if (TestForSapphireGPUController(busses[bus], 0x55))
{
new_sapphire = new SapphireGPUController(busses[bus], 0x55);
new_controller = new RGBController_SapphireGPU(new_sapphire);
rgb_controllers.push_back(new_controller);
}
}
} /* DetectSapphireGPUControllers() */
@@ -0,0 +1,104 @@
/*-----------------------------------------*\
| SteelSeriesApexController.cpp |
| |
| Driver for SteelSeries Apex 7 RGB |
| Keyboard lighting controller |
| |
| Eric Samuelson (edbgon) 7/5/2020 |
\*-----------------------------------------*/
#include "SteelSeriesApexController.h"
#include <cstring>
using namespace std::chrono_literals;
static unsigned int keys[] = {0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,
0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xf0 };
SteelSeriesApexController::SteelSeriesApexController(hid_device* dev_handle)
{
dev = dev_handle;
}
SteelSeriesApexController::~SteelSeriesApexController()
{
}
void SteelSeriesApexController::SetMode
(
unsigned char mode,
std::vector<RGBColor> colors
)
{
unsigned char mode_colors[9];
active_mode = mode;
memset(mode_colors, 0x00, sizeof(mode_colors));
}
void SteelSeriesApexController::SetLEDsDirect(std::vector<RGBColor> colors)
{
unsigned char buf[643];
int num_keys = sizeof(keys)/sizeof(*keys);
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Direct packet |
\*-----------------------------------------------------*/
buf[0x00] = 0;
buf[0x01] = APEX7_PACKET_ID_DIRECT;
buf[0x02] = num_keys;
/*-----------------------------------------------------*\
| Fill in color data |
\*-----------------------------------------------------*/
for(int i = 0; i < num_keys; i++)
{
buf[(i*4)+3] = keys[i];
buf[(i*4)+4] = RGBGetRValue(colors[i]);
buf[(i*4)+5] = RGBGetGValue(colors[i]);
buf[(i*4)+6] = RGBGetBValue(colors[i]);
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 643);
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void SteelSeriesApexController::SelectProfile
(
unsigned char profile
)
{
unsigned char buf[65];
/*-----------------------------------------------------*\
| Zero out buffer, set up packet and send |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
buf[0x00] = 0;
buf[0x01] = 0x89;
buf[0x02] = profile;
hid_send_feature_report(dev, buf, 65);
}
@@ -0,0 +1,44 @@
/*-----------------------------------------*\
| SteelSeriesApexController.h |
| |
| Definitions and types for SteelSeries |
| Apex 7 Keyboard lighting controller |
| |
| Eric Samuelson (edbgon) 7/5/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
APEX7_PACKET_ID_DIRECT = 0x3a, /* Direct mode */
};
class SteelSeriesApexController
{
public:
SteelSeriesApexController(hid_device* dev_handle);
~SteelSeriesApexController();
void SetMode
(
unsigned char mode,
std::vector<RGBColor> colors
);
void SetLEDsDirect(std::vector<RGBColor> colors);
private:
hid_device* dev;
unsigned char active_mode;
void SelectProfile
(
unsigned char profile
);
};
@@ -0,0 +1,156 @@
#include "SteelSeriesRivalController.h"
#include "SteelSeriesSiberiaController.h"
#include "SteelSeriesApexController.h"
#include "SteelSeriesGeneric.h"
#include "RGBController.h"
#include "RGBController_SteelSeriesRival.h"
#include "RGBController_SteelSeriesSiberia.h"
#include "RGBController_SteelSeriesApex.h"
#include <vector>
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| Vendor ID |
\*-----------------------------------------------------*/
#define STEELSERIES_VID 0x1038
/*-----------------------------------------------------*\
| Mouse product IDs |
\*-----------------------------------------------------*/
#define STEELSERIES_RIVAL_100_PID 0x1702
#define STEELSERIES_RIVAL_100_DOTA_PID 0x170c
#define STEELSERIES_RIVAL_105_PID 0x1814
#define STEELSERIES_RIVAL_110_PID 0x1729
#define STEELSERIES_RIVAL_300_PID 0x1710
#define ACER_PREDATOR_RIVAL_300_PID 0x1714
#define STEELSERIES_RIVAL_300_CSGO_PID 0x1394
#define STEELSERIES_RIVAL_300_CSGO_STM32_PID 0x1716
#define STEELSERIES_RIVAL_300_CSGO_HYPERBEAST_PID 0x171a
#define STEELSERIES_RIVAL_300_DOTA_PID 0x1392
#define STEELSERIES_RIVAL_300_HP_PID 0x1718
#define STEELSERIES_RIVAL_300_BLACKOPS_PID 0x1710
/*-----------------------------------------------------*\
| Headset product IDs |
\*-----------------------------------------------------*/
#define STEELSERIES_SIBERIA_350_PID 0x1229
/*-----------------------------------------------------*\
| Keyboard product IDs |
\*-----------------------------------------------------*/
#define STEELSERIES_APEX_7_PID 0x1612
typedef struct
{
unsigned short usb_vid;
unsigned short usb_pid;
unsigned char usb_interface;
device_type type;
steelseries_type proto_type;
const char * name;
} steelseries_device;
#define STEELSERIES_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
static const steelseries_device device_list[] =
{
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------*\
| Mice |
\*-----------------------------------------------------------------------------------------------------------------------------------------------------------------*/
{ STEELSERIES_VID, STEELSERIES_RIVAL_100_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_100, "SteelSeries Rival 100" },
{ STEELSERIES_VID, STEELSERIES_RIVAL_100_DOTA_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_100, "SteelSeries Rival 100 DotA 2 Edition" },
{ STEELSERIES_VID, STEELSERIES_RIVAL_105_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_100, "SteelSeries Rival 105" },
{ STEELSERIES_VID, STEELSERIES_RIVAL_110_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_100, "SteelSeries Rival 110" },
{ STEELSERIES_VID, STEELSERIES_RIVAL_300_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "SteelSeries Rival 300" },
{ STEELSERIES_VID, ACER_PREDATOR_RIVAL_300_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "Acer Predator Gaming Mouse (Rival 300)" },
{ STEELSERIES_VID, STEELSERIES_RIVAL_300_CSGO_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "SteelSeries Rival 300 CS:GO Fade Edition" },
{ STEELSERIES_VID, STEELSERIES_RIVAL_300_CSGO_STM32_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "SteelSeries Rival 300 CS:GO Fade Edition (stm32)" },
{ STEELSERIES_VID, STEELSERIES_RIVAL_300_CSGO_HYPERBEAST_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "SteelSeries Rival 300 CS:GO Hyperbeast Edition" },
{ STEELSERIES_VID, STEELSERIES_RIVAL_300_DOTA_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "SteelSeries Rival 300 Dota 2 Edition" },
{ STEELSERIES_VID, STEELSERIES_RIVAL_300_HP_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "SteelSeries Rival 300 HP Omen Edition" },
{ STEELSERIES_VID, STEELSERIES_RIVAL_300_BLACKOPS_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "SteelSeries Rival 300 Black Ops Edition" },
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------*\
| Headsets |
\*-----------------------------------------------------------------------------------------------------------------------------------------------------------------*/
{ STEELSERIES_VID, STEELSERIES_SIBERIA_350_PID, 3, DEVICE_TYPE_HEADSET, SIBERIA_350, "SteelSeries Siberia 350" },
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-----------------------------------------------------------------------------------------------------------------------------------------------------------------*/
{ STEELSERIES_VID, STEELSERIES_APEX_7_PID, 1, DEVICE_TYPE_KEYBOARD, APEX_7, "SteelSeries Apex 7" },
};
/******************************************************************************************\
* *
* DetectSteelSeriesControllers *
* *
* Tests the USB address to find a SteelSeries Rival Mouse, Headset or Keyboard *
* *
\******************************************************************************************/
void DetectSteelSeriesControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device_info* info;
hid_device* dev;
hid_init();
for(int device_idx = 0; device_idx < STEELSERIES_NUM_DEVICES; device_idx++)
{
dev = NULL;
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for SteelSeries RGB Peripheral
while(info)
{
if((info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid)
&&(info->interface_number == device_list[device_idx].usb_interface))
{
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
if(dev)
{
switch(device_list[device_idx].type)
{
case DEVICE_TYPE_KEYBOARD:
{
SteelSeriesApexController* controller = new SteelSeriesApexController(dev);
RGBController_SteelSeriesApex* rgb_controller = new RGBController_SteelSeriesApex(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
break;
case DEVICE_TYPE_HEADSET:
{
SteelSeriesSiberiaController* controller = new SteelSeriesSiberiaController(dev);
RGBController_SteelSeriesSiberia* rgb_controller = new RGBController_SteelSeriesSiberia(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
break;
case DEVICE_TYPE_MOUSE:
{
SteelSeriesRivalController* controller = new SteelSeriesRivalController(dev, device_list[device_idx].proto_type);
RGBController_SteelSeriesRival* rgb_controller = new RGBController_SteelSeriesRival(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
break;
case DEVICE_TYPE_MOUSEMAT:
/* Not yet supported */
break;
}
}
}
}
@@ -0,0 +1,25 @@
/*-----------------------------------------*\
| SteelSeriesGeneric.h |
| |
| Definitions and types for the SteelSeries|
| Devices. |
| |
| B Horn (bahorn) 17/5/2020 |
\*-----------------------------------------*/
#include <string>
#include <hidapi/hidapi.h>
#pragma once
/* Allows us to handle variation in the protocol.
* Defined in a single enum so we can keep the device_list struct the same
* for every possible device. */
typedef enum
{
RIVAL_100 = 0x00,
RIVAL_300 = 0x01,
SIBERIA_350 = 0x03,
APEX_7 = 0x04,
} steelseries_type;
@@ -0,0 +1,156 @@
/*-----------------------------------------*\
| SteelSeriesRivalController.h |
| |
| Definitions and types for SteelSeries |
| Rival lighting controller |
| |
| B Horn (bahorn) 13/5/2020 |
\*-----------------------------------------*/
#include "SteelSeriesRivalController.h"
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
static void send_usb_msg(hid_device* dev, char * data_pkt, unsigned int size)
{
char* usb_pkt = new char[size + 1];
usb_pkt[0] = 0x00;
for(unsigned int i = 1; i < size + 1; i++)
{
usb_pkt[i] = data_pkt[i-1];
}
hid_write(dev, (unsigned char *)usb_pkt, size + 1);
delete usb_pkt;
}
SteelSeriesRivalController::SteelSeriesRivalController
(
hid_device* dev_handle,
steelseries_type proto_type
)
{
dev = dev_handle;
proto = proto_type;
}
SteelSeriesRivalController::~SteelSeriesRivalController()
{
}
char* SteelSeriesRivalController::GetDeviceName()
{
return device_name;
}
steelseries_type SteelSeriesRivalController::GetMouseType()
{
return proto;
}
/* Saves to the internal configuration */
void SteelSeriesRivalController::Save()
{
char usb_buf[9];
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x00] = 0x09;
send_usb_msg(dev, usb_buf, 9);
}
void SteelSeriesRivalController::SetLightEffect
(
unsigned char zone_id,
unsigned char effect
)
{
char usb_buf[9];
memset(usb_buf, 0x00, sizeof(usb_buf));
switch (proto) {
case RIVAL_100:
usb_buf[0x00] = 0x07;
usb_buf[0x01] = 0x00;
break;
case RIVAL_300:
usb_buf[0x00] = 0x07;
usb_buf[0x01] = zone_id + 1;
break;
}
usb_buf[0x02] = effect;
send_usb_msg(dev, usb_buf, 9);
}
void SteelSeriesRivalController::SetLightEffectAll
(
unsigned char effect
)
{
switch(proto)
{
case RIVAL_100:
SetLightEffect(0, effect);
break;
case RIVAL_300:
SetLightEffect(0, effect);
SetLightEffect(1, effect);
break;
}
}
void SteelSeriesRivalController::SetColor
(
unsigned char zone_id,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
char usb_buf[9];
memset(usb_buf, 0x00, sizeof(usb_buf));
switch (proto)
{
case RIVAL_100:
usb_buf[0x00] = 0x05;
usb_buf[0x01] = 0x00;
break;
case RIVAL_300:
usb_buf[0x00] = 0x08;
usb_buf[0x01] = zone_id + 1;
break;
}
usb_buf[0x02] = red;
usb_buf[0x03] = green;
usb_buf[0x04] = blue;
send_usb_msg(dev, usb_buf, 9);
}
void SteelSeriesRivalController::SetColorAll
(
unsigned char red,
unsigned char green,
unsigned char blue
)
{
switch(proto)
{
case RIVAL_100:
SetColor(0, red, green, blue);
break;
case RIVAL_300:
SetColor(0, red, green, blue);
SetColor(1, red, green, blue);
break;
}
}
@@ -0,0 +1,79 @@
/*-----------------------------------------*\
| SteelSeriesRivalController.h |
| |
| Definitions and types for SteelSeries |
| Rival lighting controller |
| |
| B Horn (bahorn) 13/5/2020 |
\*-----------------------------------------*/
#include <string>
#include <hidapi/hidapi.h>
#include "SteelSeriesGeneric.h"
#pragma once
/* Mode, we then use these to set actual effect based on speed. */
enum
{
STEELSERIES_RIVAL_STATIC = 0x00,
STEELSERIES_RIVAL_PULSATE = 0x01
};
/* Effects */
enum
{
STEELSERIES_RIVAL_EFFECT_STATIC = 0x01,
STEELSERIES_RIVAL_EFFECT_PULSATE_MIN = 0x02,
STEELSERIES_RIVAL_EFFECT_PULSATE_MID = 0x03,
STEELSERIES_RIVAL_EFFECT_PULSATE_MAX = 0x04
};
class SteelSeriesRivalController
{
public:
SteelSeriesRivalController
(
hid_device* dev_handle,
steelseries_type proto_type
);
~SteelSeriesRivalController();
char* GetDeviceName();
steelseries_type GetMouseType();
void Save();
void SetLightEffect
(
unsigned char zone_id,
unsigned char effect
);
void SetLightEffectAll
(
unsigned char effect
);
void SetColor
(
unsigned char zone_id,
unsigned char red,
unsigned char green,
unsigned char blue
);
void SetColorAll
(
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
char device_name[32];
hid_device* dev;
steelseries_type proto;
};
@@ -0,0 +1,92 @@
/*-----------------------------------------*\
| SteelSeriesSiberiaController.cpp |
| |
| Definitions and types for SteelSeries |
| Siberia lighting controller |
| |
| E Karlsson (pilophae) 18/6/2020 |
|
\*-----------------------------------------*/
#include "SteelSeriesSiberiaController.h"
#include <cstring>
static void send_usb_msg(hid_device* dev, char * data_pkt, unsigned int size)
{
char* usb_pkt = new char[16];
memset(usb_pkt, 0x00, sizeof(usb_pkt));
// Report number
usb_pkt[0] = 0x01;
// Magic
usb_pkt[1] = 0x00;
// Command
usb_pkt[2] = data_pkt[0];
// Payload length
usb_pkt[3] = size - 1;
for(unsigned int i = 0; i < (size - 1); i++)
{
usb_pkt[4 + i] = data_pkt[1 + i];
}
hid_write(dev, (unsigned char *)usb_pkt, 16);
delete[] usb_pkt;
}
SteelSeriesSiberiaController::SteelSeriesSiberiaController
(
hid_device* dev_handle
)
{
dev = dev_handle;
}
SteelSeriesSiberiaController::~SteelSeriesSiberiaController()
{
}
char* SteelSeriesSiberiaController::GetDeviceName()
{
return device_name;
}
void SteelSeriesSiberiaController::SetColor
(
unsigned char red,
unsigned char green,
unsigned char blue
)
{
char usb_buf[4];
memset(usb_buf, 0x00, sizeof(usb_buf));
// Command 1
usb_buf[0] = 0x95;
usb_buf[1] = 0x80;
usb_buf[2] = 0xbf;
send_usb_msg(dev, usb_buf, 3);
// Command 2
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0] = 0x80;
usb_buf[1] = 0x52;
usb_buf[2] = 0x20;
send_usb_msg(dev, usb_buf, 3);
// Command 3 (Set color)
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0] = 0x83;
usb_buf[1] = red;
usb_buf[2] = green;
usb_buf[3] = blue;
send_usb_msg(dev, usb_buf, 4);
// Command 4
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0] = 0x93;
usb_buf[1] = 0x03;
usb_buf[2] = 0x80;
send_usb_msg(dev, usb_buf, 3);
}
@@ -0,0 +1,37 @@
/*-----------------------------------------*\
| SteelSeriesSiberiaController.h |
| |
| Definitions and types for SteelSeries |
| Siberia lighting controller |
| |
| E Karlsson (pilophae) 18/6/2020 |
\*-----------------------------------------*/
#include <string>
#include <hidapi/hidapi.h>
#pragma once
class SteelSeriesSiberiaController
{
public:
SteelSeriesSiberiaController
(
hid_device* dev_handle
);
~SteelSeriesSiberiaController();
char* GetDeviceName();
void SetColor
(
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
char device_name[32];
hid_device* dev;
};
@@ -11,7 +11,7 @@
#include <cstring>
ThermaltakeRiingController::ThermaltakeRiingController(libusb_device_handle* dev_handle)
ThermaltakeRiingController::ThermaltakeRiingController(hid_device* dev_handle)
{
dev = dev_handle;
@@ -52,8 +52,7 @@ void ThermaltakeRiingController::SetMode(unsigned char mode, unsigned char speed
void ThermaltakeRiingController::SendInit()
{
unsigned char usb_buf[64];
int actual;
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -63,14 +62,15 @@ void ThermaltakeRiingController::SendInit()
/*-----------------------------------------------------*\
| Set up Init packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xFE;
usb_buf[0x01] = 0x33;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0xFE;
usb_buf[0x02] = 0x33;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x81, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 65);
}
void ThermaltakeRiingController::SendRGB
@@ -82,8 +82,7 @@ void ThermaltakeRiingController::SendRGB
unsigned char* color_data
)
{
unsigned char usb_buf[64];
int actual;
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -93,19 +92,20 @@ void ThermaltakeRiingController::SendRGB
/*-----------------------------------------------------*\
| Set up RGB packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x32;
usb_buf[0x01] = 0x52;
usb_buf[0x02] = port;
usb_buf[0x03] = mode + ( speed & 0x03 );
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x32;
usb_buf[0x02] = 0x52;
usb_buf[0x03] = port;
usb_buf[0x04] = mode + ( speed & 0x03 );
/*-----------------------------------------------------*\
| Copy in GRB color data |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x04], color_data, (num_colors * 3));
memcpy(&usb_buf[0x05], color_data, (num_colors * 3));
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x81, usb_buf, 64, &actual, 0);
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 65);
}
@@ -9,7 +9,7 @@
#include "RGBController.h"
#include <vector>
#include <libusb-1.0/libusb.h>
#include <hidapi/hidapi.h>
#pragma once
@@ -47,14 +47,14 @@ enum
class ThermaltakeRiingController
{
public:
ThermaltakeRiingController(libusb_device_handle* dev_handle);
ThermaltakeRiingController(hid_device* dev_handle);
~ThermaltakeRiingController();
void SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors);
void SetMode(unsigned char mode, unsigned char speed);
private:
libusb_device_handle* dev;
hid_device* dev;
unsigned char current_mode;
unsigned char current_speed;
@@ -2,7 +2,7 @@
#include "RGBController.h"
#include "RGBController_ThermaltakeRiing.h"
#include <vector>
#include <libusb-1.0/libusb.h>
#include <hidapi/hidapi.h>
#define THERMALTAKE_RIING_VID 0x264A
#define THERMALTAKE_RIING_PID_BEGIN 0x1FA5
@@ -18,19 +18,34 @@
void DetectThermaltakeRiingControllers(std::vector<RGBController*>& rgb_controllers)
{
libusb_context * ctx;
libusb_init(&ctx);
hid_device_info* info;
hid_device* dev;
hid_init();
for(int pid = THERMALTAKE_RIING_PID_BEGIN; pid <= THERMALTAKE_RIING_PID_END; pid++)
{
dev = NULL;
info = hid_enumerate(THERMALTAKE_RIING_VID, pid);
//Look for Thermaltake Riing device
libusb_device_handle * dev = libusb_open_device_with_vid_pid(ctx, THERMALTAKE_RIING_VID, pid);
if( dev )
while(info)
{
libusb_detach_kernel_driver(dev, 0);
libusb_claim_interface(dev, 0);
if((info->vendor_id == THERMALTAKE_RIING_VID)
&&(info->product_id == pid))
{
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
if(dev)
{
ThermaltakeRiingController* controller = new ThermaltakeRiingController(dev);
RGBController_ThermaltakeRiing* rgb_controller = new RGBController_ThermaltakeRiing(controller);

Some files were not shown because too many files have changed in this diff Show More