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
Adam Honse 2dc443ff1e Add 0x18A3 to Aura addressable PID list (Z390-F) 2020-05-01 15:28:49 -05:00
Adam Honse 0ab0586dfa Update OpenRazer-Win32 DLLs to openrazer commit 134d7bf 2020-05-01 13:41:42 -05:00
Adam Honse 88fa6bf25a Hide SMBus tools panel, will add a settings option to show it 2020-04-29 16:36:37 -05:00
Adam Honse 9346490e4a Fix memory leak in OpenRazer controller 2020-04-28 20:08:43 -05:00
Adam Honse 7d4e5d6122 Add Redragon M715 support 2020-04-28 17:07:59 -05:00
Adam Honse d4a03b23c8 Add Redragon K550 support 2020-04-28 16:55:39 -05:00
Adam Honse 47b5c94310 Add WinUSB/Zadig info to README 2020-04-23 19:32:57 -05:00
Adam Honse 079a984f8d Add some information to the README and update the formatting a bit 2020-04-23 19:24:27 -05:00
Adam Honse b6e35c4155 Add Mamba 2012 and fix Mamba (wireless Chroma version) device string 2020-04-21 20:02:32 -05:00
Adam Honse c9d1ac5d8f Update OpenRazerWindows to support DeathAdder Chroma command format 2020-04-21 19:40:09 -05:00
Adam Honse 427c635ed8 Update to OpenRazer-Win32 API, device attribute pointers are now filled in by the driver during device probe, so we don't need to fill them in manually by device type anymore 2020-04-21 16:22:39 -05:00
Chris 0703bcd0a8 Several improvements to the controller
Corrected syntax errors
Corrected logical errors
Readability improvements
Build no longer segfaults changing zone
2020-04-21 15:51:54 -05:00
Adam Honse 984c6bb7f5 Fix naming convention 2020-04-21 15:27:46 -05:00
Adam Honse d27095dacd Fix duplicate strings in OpenRazer device list 2020-04-21 15:26:22 -05:00
Chris 9228b5c4cd Added missing RGB devices found in upstream Openrazer
Sections sorted alphabetically

Added Razer Keyboards
    anansi_device
    cynosa_chroma_device
    blackwidow_2019_device
    blackwidow_chroma_v2_device
    blackwidow_chroma_overwatch_device
    blackwidow_elite_device
    blackwidow_x_chroma_device
    huntsman_device
    huntsman_te_device

Added Razer Mice
    abyssus_elite_dva_edition_device
    abyssus_essential_device
    basilisk_device
    lancehead_te_device
    mamba_chroma_wired_device
    mamba_chroma_wireless_device
    mamba_wireless_wired_device
    naga_hex_v2_device
    naga_trintiy_device
    viper_ultimate_device

Added Mousepad
    firefly_device_hyperflux
    goliathus_device
2020-04-21 00:38:55 -05:00
Chris 7fe87703e5 Initial addition for the CoolerMaster MP750 Controller 2020-04-19 03:12:31 -05:00
Adam Honse c65edbeebc Fix UpdateLEDs for non-matrix OpenRazer devices 2020-04-19 01:22:40 -05:00
Adam Honse b6bf34279c Add disclaimer and warning about SMBus access functionality 2020-04-19 01:08:00 -05:00
Adam Honse 68e444aa3b Fix Naga Epic Chroma definition in device list 2020-04-19 00:58:02 -05:00
Adam Honse 3d12930067 Add Razer Naga Epic Chroma support (requires support in OpenRazer) 2020-04-19 00:56:42 -05:00
Adam Honse 3de7f32a3a Get Naga Chroma working 2020-04-19 00:13:06 -05:00
Adam Honse 216fe063e0 Fix apply all for Razer devices that don't have custom mode 2020-04-18 23:34:32 -05:00
Adam Honse ef6195271e Add support for OpenRazer mice with _led_effect and _led_rgb control scheme (DeathAdder Chroma) 2020-04-18 23:30:10 -05:00
Adam Honse 86eb273e46 Pull in OpenRazer improvements to OpenRazerWindows and fix some minor issues with OpenRazer controller code for both platforms 2020-04-18 20:47:34 -05:00
chris 22813c06dc Added Blackwidow X TE and Deathadder Elite + associated modes 2020-04-18 20:28:19 -05:00
Adam Honse 9840f0a8b6 Initial driver for ROG Aura Core laptop keyboards. Untested. 2020-04-18 00:24:35 -05:00
Adam Honse 69539432b5 Treat direct control as a mode in Aura Addressable controller 2020-04-16 13:53:25 -05:00
Adam Honse 4433760cab Set mode to all Aura addressable channels 2020-04-16 09:36:26 -05:00
Adam Honse ba2ce98a3e Add support for multiple addressable channels in Aura addressable controller. Direct mode only for now 2020-04-15 20:39:58 -05:00
Adam Honse 1e171fcfb0 Store and print configuration table for Aura Addressable controller 2020-04-14 19:09:27 -05:00
Adam Honse dc88b1a752 Add Aura Terminal PID to addressable controller and implement firmware string retrieval 2020-04-14 18:46:54 -05:00
Adam Honse 3f2a118a39 Add referenced projects to README 2020-04-13 12:03:43 -05:00
Adam Honse b8c80e6ba5 Fix infinite for loop in Aura Addressable controller 2020-04-11 12:43:31 -05:00
Adam Honse 405bbc5464 Remove unused variable 2020-04-11 02:34:16 -05:00
Adam Honse 5371fe1cc2 Fix infinite loop in Aura Addressable controller direct mode 2020-04-11 02:29:51 -05:00
Juri Berlanda cdce79bd07 [README] Fix typo on apt install. 2020-04-10 15:15:37 -05:00
Adam Honse 87395d0b0d Update name string for Razer Blade 15 (Mid 2019) Mercury 2020-04-10 03:27:17 -05:00
Adam Honse 7050a0dac1 Use mode specific colors for RGB Fusion 2 USB effect modes 2020-04-10 02:04:16 -05:00
Adam Honse bc01b53de5 Add Razer Tiamat 7.1 V2 to OpenRazer device list 2020-04-09 13:33:50 -05:00
Adam Honse 680c143ad7 Add the rest of the OpenRazer supported laptops to the device list 2020-04-09 12:45:13 -05:00
Adam Honse 38c3f2d94c Add Blade 15 mid-2019 (Mercury) to OpenRazer supported device list 2020-04-09 10:22:33 -05:00
Adam Honse 5344806a85 Remove submodule update steps from instructions 2020-04-09 09:34:04 -05:00
Adam Honse 21f29a1a56 Remove libe131 submodule and add necessary files to main repo. Fixes Gitlab automatic packaging issue 2020-04-09 09:29:54 -05:00
Adam Honse c5149b2521 Add links to third party projects used in OpenRGB to the README 2020-04-09 08:55:47 -05:00
Nagy Tam?s (T-bond) f9a25c9612 + Added to get current mode of zone
+ Option to get/set cycle num
 + Option to read device settings
 + Option to set/get sync settings
 * Fix GUI max led count

Signed-off-by: Nagy Tam?s (T-bond) <[email protected]>
2020-04-09 00:19:35 -05:00
Nagy Tam?s (T-bond) 4b4d3bf790 + Added read all settings data
+ Added option to configure Corsair zone settings
+ Added option to set volumes (?)

Signed-off-by: Nagy Tam?s (T-bond) <[email protected]>
2020-04-09 00:12:22 -05:00
Nagy Tam?s (T-bond) 3a11ed4e43 + Read controller ID, ROM versions, and Manufacturer + Product name. 2020-04-09 00:02:57 -05:00
Nagy Tam?s (T-bond) 238dc0f0ae + Save settings on system power off. 2020-04-08 23:25:59 -05:00
Nagy Tam?s (T-bond) 0568fc5ed2 + Added all effect to the GUI list. 2020-04-08 23:13:34 -05:00
Nagy Tam?s (T-bond) 37241ee6f2 + Started implementation of MSI Mystic Light USB controllers. 2020-04-08 23:09:21 -05:00
Martin Hartl 1f91dd227f NZXT Kraken: Add a default logo mode 2020-04-08 16:42:42 -05:00
Martin Hartl facfa05062 Add NZXT Kraken driver
Driver should work for NZXT Kraken X42/X52/X62/X72. Most of the color
modes and settings are already working. However, there are currently
some limitations in settings different ring and logo modes.
2020-04-08 16:35:41 -05:00
Adam Honse 6fd6c7f176 Initial support for addressable headers on Asus Aura motherboards. 2020-04-08 14:21:07 -05:00
Adam Honse d947cc2499 Add description to devices that were missing a description 2020-04-06 20:44:52 -05:00
Adam Honse 5db52e5dc2 Add resizing to RGB Fusion 2 USB controller addressable headers 2020-04-06 16:31:09 -05:00
Adam Honse 1249814e93 Fix segfault in Linux USB serial port auto-detection 2020-04-06 14:42:15 -05:00
Adam Honse dda8e9470f Update README 2020-04-06 11:42:43 -05:00
Adam Honse 72482d4ff9 Remove 0x66 from the Aura motherboard list as it is also in the Aura RAM list and gets double-detected if it exists 2020-04-04 20:48:16 -05:00
Adam Honse a50049e63b Add NCT6798D to Super-IO list in Windows 2020-04-04 18:41:38 -05:00
Nagy Tam?s (T-bond) 2970e56324 * Fixed Exit action on system tray icon 2020-04-04 17:08:48 -05:00
Adam Honse aa1ad8db85 Add zone resizing to CLI 2020-04-04 02:53:55 -05:00
Adam Honse 7f865cfee9 Allow up to 200 LEDs per channel on Corsair Lighting Node devices 2020-04-02 16:24:21 -05:00
Adam Honse c7b9fe90a6 Detect serial devices behind USB hubs 2020-04-01 16:57:56 -05:00
Adam Honse 0c7009b973 Update color wheel when choosing an LED from the LED selection box 2020-03-31 16:34:55 -05:00
Adam Honse d791361f22 Fix filename case to get ColorWheel building in Linux 2020-03-30 19:23:50 -05:00
Adam Honse 5719956441 Add color wheel color picker to UI 2020-03-30 17:54:25 -05:00
Adam Honse eba9fc0213 Add check to ensure we have a valid SMBus index before detecting/dumping, prevents segfaults when clicking detect on an invalid bus 2020-03-29 17:31:29 -05:00
Adam Honse 556fb634bb Clean up Redragon K556 code and add speed and color control 2020-03-29 14:54:39 -05:00
Adam Honse e39617a665 Compute checksum for Redragon K556 packets 2020-03-29 02:14:59 -05:00
Adam Honse 9f6c3819bd Increment version number post-release 2020-03-28 15:29:49 -05:00
Adam Honse 91c8ec0cb0 OpenRGB version 0.1 2020-03-28 15:06:37 -05:00
cip91sk 314283a37c add missing aura ram address 2020-03-28 14:46:02 -05:00
Adam Honse c3e5d91b6b Allow manual resizing of Hue+ channels 2020-03-28 14:37:27 -05:00
Adam Honse c769c20af1 Move static mode to top of Redragon M711 mode list 2020-03-28 14:35:14 -05:00
Adam Honse 2a43cefbe6 Add Redragon K556 modes, though grouped modes and colors aren't implemented yet 2020-03-27 23:24:16 -05:00
Adam Honse 68960b7b14 Add RGBController for Redragon K556 keyboard, only supports custom mode for now 2020-03-27 23:24:16 -05:00
Adam Honse ad85efcb14 Update Redragon code, split mouse and keyboard into their own controllers, and get mouse control working 2020-03-27 23:24:16 -05:00
Adam Honse 7c221416cc Redragon M709 and K556 development 2020-03-27 23:24:16 -05:00
Adam Honse 9ba1b2fc57 Bring in nct6775 SMBus driver improvements from updated patch to Windows 2020-03-24 18:07:23 -05:00
Adam Honse caf1e5c7f0 Update OpenRazer-win32 DLLs to openrazer commit bd864c8 2020-03-24 17:58:03 -05:00
Adam Honse 2b660a47c7 Fix wrong index being used in profile lookup that would cause segfaults if there are more controllers detected than in profile 2020-03-23 23:40:18 -05:00
Adam Honse 0c45e26c98 Add timeouts to i2c-nct6775 driver and fix kernel segfault caused by byte access with no data 2020-03-23 23:22:25 -05:00
Adam Honse fdbaf9bf63 Fix segfault in CLI 2020-03-22 22:18:30 -05:00
Adam Honse 08a1197b7e Fix arguments not parsing in CLI, add mode specific color support to CLI 2020-03-22 16:22:59 -05:00
Adam Honse 87a9ea5b14 Add some comments to the CLI code and clean up some warnings 2020-03-22 03:49:08 -05:00
Adam Honse 2b8d25559a Move help and version functions to the same place as the other arguments 2020-03-22 01:48:57 -05:00
Adam Honse 3db9189cbb Fix current device ID in CLI 2020-03-22 01:01:01 -05:00
Adam Honse a0c379e8c7 Add profile saving to command line 2020-03-22 00:26:06 -05:00
Adam Honse 0ae4964545 Clean up some of the CLI code and add option to load a profile from the command line 2020-03-22 00:04:27 -05:00
Adam Honse 69651b3f91 Load sizes for variable-size controllers in CLI mode 2020-03-20 13:50:54 -05:00
Adam Honse ce9508aa88 Allow 0x03 or 0x04 for detecting Corsair Pro DRAM 2020-03-20 13:05:49 -05:00
Adam Honse aa182936ba Clean up warnings, except in hidapi and cli files 2020-03-20 12:10:18 -05:00
Adam Honse 745bbac93b Fix i2c bus names on Linux 2020-03-20 10:20:46 -05:00
Adam Honse 5c3c15f930 Remove Synchronized Effects tab as the effects engine has been postponed until after 1.0 2020-03-20 00:39:29 -05:00
Adam Honse 4919b03bd1 Remove controller-side LED count from Corsair Lighting Node and ThermalTake Riing controllers, initialize them to zero LED count 2020-03-19 20:55:57 -05:00
Adam Honse 18c18e3999 Automatically save a sizes.ors profile when resizing a zone, then automatically load zone sizes from sizes.ors on start 2020-03-19 14:24:39 -05:00
Adam Honse 01020b50d9 Set default number of LEDs per strip in RGB Fusion 2 controller 2020-03-18 22:49:35 -05:00
Adam Honse 00f422375b Initial Corsair mouse support, tested on M65 RGB Elite. Shows as mousemat with 15 zones for now as zone mapping isn't supported yet 2020-03-13 18:55:07 -05:00
Adam Honse 25807902c9 Set each LED independently for Crucial effect modes 2020-03-13 21:41:23 +00:00
Adam Honse 0bbef425a4 Enable effects on Crucial controller, but color modes unimplemented 2020-03-13 17:20:32 +00:00
Adam Honse ec65d8a2a9 Update OpenRazer-win32 DLLs to openrazer commit 692e36b 2020-03-12 17:37:26 -05:00
Adam Honse 47df8f3414 Fix leftover un-renamed types 2020-03-12 14:53:32 -05:00
Adam Honse c560ee4b7e Rename RGBFusion2Controller to RGBFusion2USBController 2020-03-12 18:58:28 +00:00
Adam Honse 74080150e0 Rename AuraController to AuraSMBusController 2020-03-12 17:27:52 +00:00
Adam Honse ab7ddc1629 Rename HyperXController to HyperXDRAMController 2020-03-11 19:37:10 -05:00
Adam Honse 000bef969c Add more Corsair keyboards to the detection list 2020-03-11 19:19:37 -05:00
Adam Honse c8e0aec596 Use 24-bit color protocol for Corsair keyboards 2020-03-11 17:31:30 -05:00
Adam Honse ecf4427c76 Rename CorsairController to CorsairVengeanceController, CorsairProController to CorsairVengeanceProController 2020-03-11 21:15:05 +00:00
Adam Honse d299e90954 Fix 24-bit keyboard color set function 2020-03-11 12:18:24 -05:00
Adam Honse 98bb92acdb Add 24-bit color set function for keyboards 2020-03-11 15:15:43 +00:00
Adam Honse 0e77149444 Rename CorsairKeyboardController to CorsairPeripheralController 2020-03-10 21:26:36 -05:00
Adam Honse e6c21f0a72 Add firmware version to Corsair Lighting Node driver 2020-03-10 15:57:46 -05:00
Adam Honse da9f6d7c72 Add description for ASUS Aura device driver 2020-03-10 14:09:43 -05:00
Adam Honse 97975b6d36 Update description on Corsair Lighting Node driver 2020-03-10 13:59:17 -05:00
Adam Honse ad98cc173b Update description on Corsair peripheral driver 2020-03-10 11:35:16 -05:00
Adam Honse 5a33c80d65 Fix build issue in Linux in Corsair Keyboard driver 2020-03-09 20:47:07 -05:00
Adam Honse f661bf66f1 Fix button sizes a bit, it's not perfect but it's better than it was 2020-03-09 20:41:41 -05:00
Adam Honse f1e1c41d68 Add support for Corsair Polaris MM800 mousemat using CorsairKeyboardController driver 2020-03-09 20:39:55 -05:00
Adam Honse a7ed250c4e Don't initialize pointers on zones with no LEDs 2020-03-09 16:39:38 -05:00
Adam Honse 62c06202e0 Re-enable and update RGBController data block get/set functions for new API parameters. This gets profile savig and loading working again 2020-03-09 12:28:50 -05:00
Adam Honse 23ad5ca244 Fix setting individual LEDs when a specific zone is selected 2020-03-08 20:51:30 -05:00
Adam Honse 5712717ef8 Update maximum number of LEDs for Thermaltake Riing zone to 20 LEDs 2020-03-08 20:25:07 -05:00
Adam Honse da54e89839 Fix Thermaltake Riing controller 2020-03-08 17:07:57 -05:00
Adam Honse 57b8377f5a Disable built in effects before setting strip colors in RGB Fusion 2 controller 2020-03-08 17:01:09 -05:00
Adam Honse fbb718c532 Update RGB Fusion 2 controller to new RGBController API. Reworked some of the RGB Fusion 2 controller code to be more consistent with the rest of the project. 2020-03-08 12:06:21 -05:00
Adam Honse 5a469ea615 Update Corsair Keyboard controller to new RGBController API 2020-03-07 18:06:55 -06:00
Adam Honse 2099abb126 Update Patriot Viper RGB controller to new RGBController API 2020-03-07 18:01:00 -06:00
Adam Honse 4b4e939d10 Update Crucial Ballistix RGB controller to new RGBController API 2020-03-07 17:55:41 -06:00
Adam Honse e0094915fe Update ThermalTake Poseidon Z RGB controller to new RGBController API 2020-03-07 17:46:38 -06:00
Adam Honse aa6e2e611b Update HyperX Keyboard controller to new RGBController API 2020-03-07 17:37:50 -06:00
Adam Honse ce8331b467 Update Faustus controller to new RGBController API 2020-03-07 17:18:44 -06:00
Adam Honse 54ff4d57b0 Fix Hue 2 controller build on Linux 2020-03-07 17:12:31 -06:00
Adam Honse 3abb0c05ba Update Corsair Vengeance RGB Pro controller to new RGBController API 2020-03-07 17:08:04 -06:00
Adam Honse acc84f6a09 Update ASUS Aura GPU controller to new RGBController API. Also update ASUS Aura controller to read colors from hardware during initialization. 2020-03-07 16:55:02 -06:00
Adam Honse 74b0d195d9 Update Corsair Vengeance RGB controller to new RGBController API 2020-03-07 16:41:59 -06:00
Adam Honse 920e001bab Update MSI 3-Zone Keyboard controller to new RGBController API 2020-03-07 16:35:54 -06:00
Adam Honse 4c2ceed5b6 Update ASRock Polychrome controller to new RGBController API 2020-03-07 16:30:00 -06:00
Adam Honse 515c17b8dd Update MSI-RGB controller to new RGBController API 2020-03-07 16:20:35 -06:00
Adam Honse 2ffb02abde Update E1.31 controller to new RGBController API 2020-03-07 16:13:15 -06:00
Adam Honse 3237c8842a Update NZXT Hue+ and Hue 2 controllers to new RGBController API. Fix direct mode not working on Hue 2. 2020-03-07 15:56:07 -06:00
Adam Honse fde468a162 Update LED Strip controller to new RGBController API 2020-03-07 01:38:32 -06:00
Adam Honse f854441cf7 Update HyperX RGB RAM controller to new RGBController API 2020-03-07 01:28:26 -06:00
Adam Honse 408020c244 Update Gigabyte RGB Fusion 1.0 controller to new RGBController API 2020-03-07 01:10:26 -06:00
Adam Honse f806f3ad66 Update AMD Wraith Prism controller to new RGBController API 2020-03-07 01:00:58 -06:00
Adam Honse 7c1c9a7979 Update OpenRazer (Windows and Linux) controllers for new RGBController API 2020-03-07 00:38:42 -06:00
Adam Honse 283cb5a8ac Update RGB Fusion GPU controller to new RGBController API 2020-03-06 16:54:53 -06:00
Adam Honse 5f21674b8f Update Aura controller for RGBController API changes 2020-03-06 14:20:17 -06:00
Adam Honse fe6a84d6c9 Rename NodePro to LightingNode 2020-03-06 12:11:53 -06:00
Adam Honse f7cb8ca969 Delete CorsairCmdrProController files now that Corsair Pro is merged into Lighting Node driver 2020-03-05 22:26:29 -06:00
Adam Honse 64dad049f9 Set endpoint based on Corsair Lighting Node device table 2020-03-05 22:04:30 -06:00
Adam Honse 1115213d5a Consolidate Corsair Lighting Node and compatible device drivers 2020-03-05 21:12:17 -06:00
Adam Honse bc01ec0e4b Update Thermaltake Riing controller for resizable channels 2020-03-05 12:29:17 -06:00
Adam Honse 62518b5163 Update RGBController API and GUI to handle resizable zones. All controllers except for CorsairNodePro have been disabled pending rework 2020-03-04 19:29:58 -06:00
Adam Honse 736e624366 Resize button. Resizes mode specific color lists. Partial implementation of resizing zones 2020-03-04 17:53:44 -06:00
Adam Honse d7298cafd0 Fix build on Linux 2020-03-03 22:06:46 -06:00
Adam Honse 70783fb28f Add button to delete profiles and confirmation dialog 2020-03-03 21:15:33 -06:00
Adam Honse 45a5f629e5 Do a complete refresh of profile list when saving profile 2020-03-03 21:02:50 -06:00
Adam Honse ec73337929 Update OpenRazer-Win32 DLLs to fix corrupt serial and version strings, enable reading these in OpenRGB. 2020-03-03 13:22:23 -06:00
Adam Honse 148b84b7d1 Add support for ASRock Polychrome FW 3.04 (X570 Taichi) 2020-03-03 12:15:55 -06:00
Adam Honse 3cf855bd10 Search through controller list for each controller when loading profile, allows controller order to change without breaking the profile 2020-03-03 12:11:21 -06:00
Adam Honse 9deb0f8fff Move profile code from Qt UI to new ProfileManager class 2020-03-02 16:05:07 -06:00
Adam Honse 8c86686d01 Delay 200ms after changing Poseidon Z RGB mode so that direct colors are set correctly 2020-03-01 22:12:51 -06:00
Adam Honse c451487401 Change direct effects mode back to Direct mode on HyperX keyboard 2020-03-01 22:04:52 -06:00
Adam Honse 5defbc1580 Fix color mode for Thermaltake Riing direct mode 2020-03-01 22:00:24 -06:00
Adam Honse b5af840dcc Fix possible out of bounds access when initializing Aura RAM addresses 2020-03-01 21:50:08 -06:00
Adam Honse 1b170ff664 Update libusb DLLs to include a small change to fix detection of some composite HID devices such as RGB keyboards. Source for this new DLL at my libusb fork - https://github.com/CalcProgrammer1/libusb 2020-03-01 21:42:43 -06:00
Adam Honse 31a6da1b21 Build hidapi from source using libusb backend. This requires installation of WinUSB driver on Windows but fixes issues with Windows-specific HID implementation 2020-03-01 21:16:22 -06:00
Adam Honse cb6dfd83d8 Add refreshing thread for HyperX keyboard Direct mode 2020-03-01 20:57:04 -06:00
Adam Honse 50ea274205 Add timeouts to fix HyperX and Poseidon Z RGB in Linux 2020-03-01 20:56:07 -06:00
Adam Honse c7960c090a Add software version information to CLI 2020-02-29 14:01:06 -06:00
Adam Honse 85b2545409 Fill in software information and set version to 0.0 for now 2020-02-29 13:45:43 -06:00
Adam Honse e10881db3e Add empty software information tab to information UI 2020-02-28 12:31:32 -06:00
Adam Honse 977feabe6e Add profile selection to system tray icon menu 2020-02-27 13:16:10 -06:00
Adam Honse a6c9d1232a Don't apply colors unless per LED mode 2020-02-26 21:16:02 -06:00
Adam Honse 4024e6de85 Fix build on Linux 2020-02-26 19:40:25 -06:00
Adam Honse f3df584d3a Don't update devices if the profile could not be loaded 2020-02-26 19:36:00 -06:00
Adam Honse 60a0ab5c93 Populate profile list with .orp files and load profile selected in list 2020-02-26 19:36:00 -06:00
Adam Honse c908847577 Add dialog to name profile. Save all controllers to a single file. Add a file header with version number and use extension .orp for OpenRgb Profile 2020-02-26 19:36:00 -06:00
Adam Honse bd027e596e Set colors when updating mode 2020-02-26 19:36:00 -06:00
Adam Honse 51c3568f7a Profile save and load test 2020-02-26 19:36:00 -06:00
Adam Honse 4f8db7d63f Add cstring include to fix build on Linux 2020-02-25 21:07:06 -06:00
Adam Honse f844c2fb07 Add functions to get/set RGBController parameters to/from a binary data buffer. Add a dummy RGBController object to load data into. 2020-02-25 18:09:14 -06:00
Adam Honse f7041988e4 Fix off-by-one errors in Aura RAM address assignment 2020-02-25 14:20:59 -06:00
Stefan Reiter 71c650cd45 Add cli.cpp and make it build at least
Not confirmed working as of yet, but at least it builds and
--list-devices works.

Code originally taken from Sam Lewis (@sam-masaki on gitlab.com), see:
https://gitlab.com/CalcProgrammer1/OpenRGB/-/merge_requests/9
2020-02-24 00:03:07 -06:00
Stefan Reiter 3c6ac31eab Introduce device_type_to_str 2020-02-23 23:40:26 -06:00
Stefan Reiter 20a99ef7ef Append LED number to Aura devices' LEDs
Makes identifying them easier then just 'Unknown' 8 times in a row.
2020-02-23 23:40:11 -06:00
Stefan Reiter c69a98096b Remove debug print
Annoying when in CLI mode
2020-02-23 23:39:13 -06:00
Adam Honse 92afebe2c7 Fix Windows build 2020-02-23 19:09:03 -06:00
jackun 5b82eb39a8 RGB Fusion 2 (IT8297BX) support based on Gigabyte X570 Elite. 2020-02-23 18:26:48 -06:00
Adam Honse 7b120515d8 Fix include path for NvAPI 2020-02-23 15:54:23 -06:00
Adam Honse b480bbd666 Clean up NvAPI I2C code and allow multiple GPUs 2020-02-23 15:54:14 -06:00
Adam Honse 5e5ac81f53 Get detection working (tested on nouveau in Linux) 2020-02-23 15:54:06 -06:00
Adam Honse adcd59848a Add RGB Fusion GPU controller and NVAPI I1C interface 2020-02-23 15:53:54 -06:00
Adam Honse 937cbc656e Add Windows application icon 2020-02-20 00:37:31 -06:00
Jan Rettig aead384282 Aura GPU Support 2020-02-19 21:24:36 -06:00
Adam Honse b717600c37 Add name, description, and type information to MSI-RGB controller 2020-02-19 21:05:04 -06:00
Adam Honse f38be5119e MSI-RGB driver based on https://github.com/nagisa/msi-rgb 2020-02-19 20:19:12 -06:00
Adam Honse f8de686296 Add LED numbers to Linux OpenRazer controller 2020-02-19 19:42:49 -06:00
Adam Honse 0703fb8c68 Support 64-bit Windows builds 2020-02-19 10:24:56 -06:00
Adam Honse 8d0915de6e Add support for mode specific colors in HyperX keyboard breathing mode 2020-02-18 11:01:43 -06:00
Adam Honse ef33d7e2c4 Firmware 2.x seems to use ASR LED protocol, confirmed on 2.08 2020-02-16 13:43:57 -06:00
Adam Honse bba88eb1f2 Update mode color description to add mode-specific colors. 2020-02-16 12:09:11 -06:00
Adam Honse 7b35cf72f7 Add zone numbers to Chroma HDK and add LED numbers for all OpenRazer zones. 2020-02-13 12:36:57 -06:00
Adam Honse 9603489f4a Get rid of razerchromahdk driver as it was never merged and use razeraccessory instead 2020-02-13 12:36:57 -06:00
Adam Honse d4cd2a6853 Add direction control to OpenRazer Wave mode 2020-02-13 12:36:57 -06:00
Adam Honse c4d2f72df1 Clean up Linux OpenRazer code to match Windows and break out device list into a shared header file 2020-02-13 12:36:57 -06:00
Adam Honse 1a07aee7a6 Add OpenRazer-Win32 driver to support Razer devices on Windows without official software 2020-02-13 12:36:57 -06:00
Adam Honse 415d79a3ef Remove Razer Chroma SDK backend 2020-02-13 12:33:31 -06:00
Adam Honse fd59f83556 Update Crucial controller to new RGBController format 2020-02-12 14:51:07 -06:00
Adam Honse 7adcfa77fa Add function for setting Crucial Ballistix RGB colors in direct mode 2020-02-12 14:39:44 -06:00
Adam Honse b338fbca3c Initial driver for Crucial Ballistix RGB 2020-02-12 14:39:44 -06:00
Adam Honse aba3a3fd23 Add 0x39, 0x3B, 0x3C, and 0x3D to Aura DRAM search addresses list 2020-02-12 13:23:35 -06:00
Adam Honse cb680508a5 Add Polychrome firmware 2.08 to supported firmware list 2020-02-12 13:02:28 -06:00
Adam Honse 2104c975be Update RGB Fusion 2 to build with latest RGBController format 2020-02-12 12:27:15 -06:00
Adam Honse 339e1e14c2 Swap red and blue channels in RGB Fusion 2.0 packet after it was found that they were reversed 2020-02-12 12:20:50 -06:00
Adam Honse dca3b0d733 Forgot to send the apply packet 2020-02-12 12:20:30 -06:00
Adam Honse c52eb528ea RGB Fusion 2.0 driver based on summerblind's code 2020-02-12 12:20:30 -06:00
Adam Honse 3948e74711 Use /dev/port to make Super IO functions work on Linux 2020-02-11 20:25:28 -06:00
Adam Honse 4672d4a686 Move Super IO functionality to its own file to make it easier to write an MSI-RGB driver 2020-02-11 19:58:13 -06:00
Adam Honse befa9baf20 Update the ThermaltakeRiing driver to just set the active_mode variable instead of actually sending mode updates on SetCustomMode 2020-02-11 18:07:57 -06:00
Adam Honse 077cda545e Clean up the Corsair keyboard driver with some private packet sending functions 2020-02-11 18:01:31 -06:00
Adam Honse e934ce2c23 Add addresses 0x5E and 0x5F to Corsair DRAM detection 2020-02-11 16:18:39 -06:00
Adam Honse b10ff42df2 Add addresses 0x5E and 0x5F to Corsair Pro DRAM detection 2020-02-11 16:18:38 -06:00
Adam Honse afb6ff6a74 Update the rest of the RGBController drivers to just set the active_mode variable instead of actually sending mode updates on SetCustomMode 2020-02-10 00:26:18 -06:00
Adam Honse 6828335dc5 Just set active_mode rather than call SetMode for SetCustomModefunction. Implement for a few tested devices only for now. Fix some user interface issues with custom mode selection. 2020-02-10 00:17:02 -06:00
Adam Honse 966297710b Fix custom mode setting in UI 2020-02-09 19:55:26 -06:00
Adam Honse 443d558ac2 Remove compiler warning that is treated as error on some systems 2020-02-09 19:06:50 -06:00
Adam Honse 2cd0b64251 Add mode control to Thermaltake Riing controller 2020-02-09 15:26:20 -06:00
Adam Honse 7ad3c18e3f Remove unused declarations 2020-02-09 14:43:24 -06:00
Adam Honse fc11427019 Remove serial port include for USB controllers that were copied from the Hue+ driver 2020-02-09 14:37:50 -06:00
Adam Honse 2f00fb9186 Add initial driver for Thermaltake Riing controller. Fixed configuration has 9 LEDs for channels 1, 2, and 3 but will make this configurable in the future. Only direct mode supported so far 2020-02-09 14:34:26 -06:00
Adam Honse ea1f21106c Fix Linux build of CorsairKeyboardController (missing include for memset) 2020-02-06 16:37:21 -06:00
Adam Honse 47ca068628 Number the LEDs in E131 and LEDStrip controllers 2020-02-06 12:26:14 -06:00
Adam Honse f07cc134bb Add zones and LEDs to Corsair keyboard controller, but keys don't line up with zones yet 2020-02-05 21:05:55 -06:00
Adam Honse 1d98ce063c Add zones and LEDs to Poseidon Z RGB controller 2020-02-05 17:34:08 -06:00
Adam Honse 9ddb9f04ce Add zones and LEDs to HyperX Keyboard controller 2020-02-05 13:09:39 -06:00
Adam Honse 8aee3c427b Fix segfault 2020-02-04 20:22:01 -06:00
Adam Honse 6a6ad0dda6 Keyboard fixes for Linux 2020-02-04 20:20:45 -06:00
Adam Honse 12116c70ee Big Keyboard Update! HyperX Alloy Elite support, Poseidon Z RGB modes, and Corsair K70 RGB 2020-02-04 20:17:09 -06:00
Adam Honse 7d6699cf9c Use ASR LED mode for Polychrome 2.10 firmware 2020-02-02 00:34:11 -06:00
Adam Honse 48b9be3f76 Add Polychrome firmware 2.10 to list 2020-02-01 20:38:52 -06:00
Adam Honse 760c57c29c Only show LEDs for selected Zone, add an All Zones option to Zone box 2020-02-01 12:54:51 -06:00
Adam Honse c6cc88ba7b The color boxes got moved around during the UI rework. Move them back to their proper rainbow order 2020-01-31 18:32:22 -06:00
Adam Honse 779471e3e4 Detect NZXT Smart Device V2 and use the Hue 2 driver for it 2020-01-31 11:08:33 -06:00
Adam Honse adb9a6e59f Add support for Aer 2 140mm fan on Hue 2 2020-01-30 10:42:43 -06:00
Adam Honse d48bcec5ba Block write Polychrome mode value instead of byte write 2020-01-29 13:02:00 -06:00
Adam Honse 80d2282313 Add modes and additional set functions to Polychrome controller 2020-01-29 12:32:32 -06:00
k1-801 a4474602d8 Add basic support for Asus TUF laptop keyboards through Faustus 2020-01-28 09:10:34 -06:00
Marco Zanin (B--B) d28be0640e Qt: fix layout issues on KDE
Use GridLayout and allow app resize when user resize/expand the window
Also fixes some buttons size

TEST: compiled on KDE 5.17.90, after this commit all pages
      resize correctly when window is resized

Signed-off-by: Marco Zanin (B--B) <[email protected]>
2020-01-27 19:41:31 -06:00
Adam Honse 5b17833c6e Remove some detection checks for Corsair Vengeance RGB Pro detection as it was no longer detecting my modules with them 2020-01-25 17:37:32 -06:00
Adam Honse e8e9a1e7e5 Set custom mode when applying color to all devices 2020-01-25 17:37:32 -06:00
Adam Honse d7740c2d28 Move Get/Set mode functions to generic RGBController.cpp functions and add device-specific UpdateMode function to use active_mode value 2020-01-25 17:37:32 -06:00
Adam Honse f110589f91 Fix some small issues with AMD Wraith Prism driver 2020-01-25 17:37:32 -06:00
Adam Honse b3c1cdf63d Fix issues with inverted speed and random flag 2020-01-25 17:37:32 -06:00
Adam Honse 6b789be1e1 Add speed control to HyperX driver 2020-01-25 17:37:32 -06:00
Adam Honse 12f307228b Clean up speed values for Patriot Viper RGB 2020-01-25 17:37:32 -06:00
Adam Honse 848ea8b064 Shifted the wrong way... 2020-01-25 17:37:32 -06:00
Adam Honse 438c3840a7 Add speed control to RGB Fusion 1.0 driver 2020-01-25 17:37:32 -06:00
Adam Honse fef6f4cba3 Add delay to improve Corsair Pro detection, default modes to down instead of left, clean up Wraith Prism initialization 2020-01-25 17:37:32 -06:00
Adam Honse d38543a820 Finish AMD Wraith Prism mode updates including working speed table, working random color flag, and appropriate fan/logo modes for ring-specific effects 2020-01-25 17:37:32 -06:00
Adam Honse 2a76201ca4 Implement a speed table for AMD Wraith Prism to use the values taken from the official software. Interpolation was causing strange issues. 2020-01-25 17:37:32 -06:00
Adam Honse 2e84e9808c Start adding modes to AMD Wraith Prism driver. Speed and random bit implemented, but it seems to have issues. Speeds way too fast 2020-01-25 17:37:32 -06:00
Adam Honse ee492632ac Prepare AMD Wraith Prism driver for mode control 2020-01-25 17:37:32 -06:00
Adam Honse fd16bc3053 Add direction support to Corsair Vengeance RGB Pro 2020-01-25 17:37:32 -06:00
Adam Honse 64f11b42f4 Add direction support for NZXT Hue 2 2020-01-25 17:37:32 -06:00
Adam Honse 7ba610df77 Add direction support to Corsair Commander/Lighting Node Pro 2020-01-25 17:37:32 -06:00
Adam Honse a76bd7b974 Add direction support for NZXT Hue+ 2020-01-25 17:37:32 -06:00
Adam Honse 7999620db2 Fix Corsair Commander Pro/Lighting Node Pro on Linux 2020-01-25 17:37:32 -06:00
Adam Honse 585eb8a5a3 Add direction support 2020-01-25 17:37:32 -06:00
Adam Honse f1523adcdf Add the rest of the Corsair Commander/Lighting Node Pro modes 2020-01-25 17:37:32 -06:00
Adam Honse 1113c7874f Add label to Speed slider 2020-01-25 17:37:32 -06:00
Adam Honse ab03311717 Copy Corsair Commander Pro updates to Lighting Node Pro driver. Need to consolidate these eventually 2020-01-25 17:37:32 -06:00
Adam Honse d13971b7ce Add inverted speed flag to device UI to handle devices where slowest speed is a larger value than fastest speed 2020-01-25 17:37:32 -06:00
Adam Honse 5bc94fd677 Speed values are reversed on Corsair Commander Pro. Removed all references to SendKeepalive function. 2020-01-25 17:37:32 -06:00
Adam Honse 90dfa5678b Clean up Corsair Commander Pro code and get effects mode working 2020-01-25 17:37:32 -06:00
Adam Honse 48ba8435b1 Initial Corsair Commander Pro support, it's the same protocol as the Lighting Node Pro but on a different endpoint 2020-01-25 17:37:32 -06:00
Adam Honse cf2c2d6b93 Add speed control to Hue 2 2020-01-25 17:37:32 -06:00
Adam Honse 4b8668e0ef Add speed control for Hue+ and add support for Wings mode 2020-01-25 17:37:32 -06:00
Adam Honse 0bc5982970 Add random color modes for HyperX Predator RGB 2020-01-25 17:37:32 -06:00
Adam Honse 2ae74c1e7f Add slider for speed control, add min/max speed parameters to mode information, update Corsair Pro and Patriot Viper drivers to include speed control 2020-01-25 17:37:32 -06:00
Adam Honse abd4c87b1e Fix Corsair Pro mode initialization 2020-01-25 17:37:32 -06:00
Adam Honse fb3103e458 Add mode parameters to Corsair Vengeance RGB Pro controller 2020-01-25 17:37:32 -06:00
Adam Honse c70943da18 Add Random Color checkbox and combine Aura fixed-color and cycling ("random") modes to use this new checkbox 2020-01-25 17:37:32 -06:00
Adam Honse 2efd0dc81d Add additional mode parameters to RGBController API and update most of the RGBController drivers' mode specifications to match 2020-01-25 17:37:32 -06:00
Adam Honse 8b8012a431 Update README.md 2020-01-15 22:43:22 +00:00
Adam Honse 0716f55880 Remove debug printout that was left in Hue code 2020-01-12 23:10:25 -06:00
Adam Honse bcc95abe53 Add keepalive thread to Corsair Lighting Node Pro driver 2020-01-12 22:57:30 -06:00
Adam Honse bb7852a3e4 Remove list of devices from README and replace it with a link to the wiki. The wiki is more up to date. 2020-01-13 04:33:00 +00:00
Adam Honse d79c7e9c04 Initial driver for Corsair Lighting Node Pro 2020-01-12 14:04:01 -06:00
Adam Honse fa4d9ebbf6 Get hidapi stuff building on Linux 2020-01-09 19:13:19 -06:00
Adam Honse ec8cdf1e26 Bring in USB HID device support with hidapi and add support for two new HID devices - MSI/SteelSeries 3-zone laptop keyboard and Thermaltake TtEsports Poseidon Z RGB keyboard 2020-01-09 19:00:08 -06:00
Adam Honse 1d6e0cf6a4 Fix mode initialization, fix mode map for Corsair Pro 2020-01-09 13:36:06 -06:00
Adam Honse b06d56bb2d Add Aer 1 fan support to NZXT Hue 2 and Hue+ 2020-01-08 21:21:11 -06:00
Adam Honse 50c9f7b84b More color vector initialization improvements 2020-01-08 21:20:54 -06:00
Adam Honse dd6a6ca85a Increase timeout after sending Hue+ packet so it works in Linux as well as Windows 2020-01-07 23:17:13 -06:00
Adam Honse 4d5003f49d Some code cleanup - set colors vector size for improved performance and add sleep to fix Hue Plus device update 2020-01-07 21:00:02 -06:00
Adam Honse 7226a4164f Hue 2 channel is a bitfield rather than a value 2020-01-06 23:01:51 -06:00
Adam Honse c7030ad47d Rework the RGBController API to handle the colors vector outside of device specific implementations 2020-01-06 21:23:26 -06:00
Adam Honse 11770aaa3a Add Quick Colors to tray icon 2020-01-06 16:25:01 -06:00
Adam Honse f8212ca59e Add Lights Off option to tray icon menu 2020-01-06 15:30:45 -06:00
Adam Honse dbf3dd86b4 Add tray icon with options to show/hide and exit 2020-01-06 12:31:37 -06:00
Adam Honse 0fe3adc267 Add UpdateLEDs function support to HyperX controller 2020-01-05 18:29:40 -06:00
Adam Honse f45b20602b Add UpdateLEDs function support for Viper, Hue2, Hue+, Wraith Prism 2020-01-05 18:07:47 -06:00
Adam Honse f6bf044ba0 Add functions for setting Hue+ and Hue 2 effect modes 2020-01-05 17:22:43 -06:00
Adam Honse 420e4dc077 Fix bug in NZXT Hue 2 code 2020-01-05 13:49:30 -06:00
Adam Honse 3c77c1a9a8 Add support on Hue 2 for Aer 2 fans 2020-01-05 13:38:57 -06:00
Adam Honse 5074a923d1 Add functions to get serial port path from USB VID/PID for both Windows and Linux. Use this function to automatically detect the presence of an NZXT Hue+. 2020-01-05 12:52:33 -06:00
Adam Honse bfd8030438 Send apply command on AMD Wraith Prism to enable ring LEDs 2020-01-05 02:49:44 -06:00
Adam Honse af84c5bb00 Add Aorus GPU detect file to Windows build 2020-01-05 01:28:15 -06:00
Adam Honse 3de7150408 Add effect mode and effect color controls to Patriot Viper RGB driver 2020-01-05 01:16:03 -06:00
Adam Honse 6fdf34e16f Update README to reflect need to initialize submodules for Windows now that E131 is used on both 2020-01-02 21:28:19 -06:00
Adam Honse 7bdf19387d Add Windows support for E1.31 Streaming ACN protocol devices 2020-01-02 21:23:56 -06:00
Adam Honse a27c614a8b Fix some issues with the Aura initialization and detection and add a new driver for Patriot Viper RGB RAM 2020-01-01 23:32:58 -06:00
Adam Honse b7b93ad606 Fix build error in windows 2020-01-01 18:26:08 -06:00
Steven Franzen dbf796256b Fix most compiler warnings 2019-12-31 19:18:24 -06:00
Adam Honse f38b90ad52 Use a list of motherboard addresses to detect Aura motherboards 2019-12-31 18:44:09 -06:00
Adam Honse 5f3fe509a4 Fix unbounded array access in Aura RAM detection that caused segfaults on certain systems 2019-12-31 18:37:09 -06:00
Adam Honse 189bf0d7a4 Support for original Hue Plus strips on Hue 2, fix bug when less than 20 LEDs connected to channel 2019-12-29 15:21:30 -06:00
Adam Honse 60531bbf07 Initial driver for NZXT Hue 2 2019-12-29 12:29:29 -06:00
Adam Honse fd9134c911 Rename OpenAuraSDK.cpp to OpenRGB.cpp and remove old unused code 2019-12-28 15:24:40 -06:00
Adam Honse f33f00d8a9 Fix bank IDs in RGB Fusion code and set 0x02 register which seems to enable device if disabled. 2019-12-27 19:53:02 -06:00
Adam Honse f2d35466a5 Get Aura address skipping working 2019-12-27 16:23:37 -06:00
Adam Honse bce9fc929e Skip in-use addresses for Aura RAM initialization 2019-12-27 15:53:49 -06:00
Adam Honse cdaae5fb9f Fix previous commit 2019-12-27 12:28:18 -06:00
Adam Honse 9fc9059b0b Add detection code for ASRock ASR LED and Polychrome controllers 2019-12-27 12:24:04 -06:00
Adam Honse 2c1fe31211 Update README 2019-12-27 12:08:20 -06:00
Adam Honse 13f53ae4f8 Remove 0x67 and 0x68 checks from HyperX detection - should allow detection of Fury RGB RAM. Change suggested by Sam Cheng of Kingston/HyperX 2019-12-27 12:06:04 -06:00
Adam Honse eac739fdb4 Get libusb-1.0 building on Windows, pull in libusb-1.0.22 dependency. You need Zadig to set up individual devices for use 2019-12-25 02:26:18 -06:00
Adam Honse 5ae3de993d Add capability to set ring color 2019-12-25 01:21:18 -06:00
Adam Honse e79c97c4d0 RGBController interface for Wraith Prism now can change static colors for logo and fan 2019-12-25 01:08:28 -06:00
Adam Honse 45c7bc8008 Add an RGBController interface for AMD Wraith Prism 2019-12-25 00:54:45 -06:00
Adam Honse 7de0b2549b Add function to retrieve firmware version string on Wraith Prism 2019-12-24 19:26:40 -06:00
Adam Honse 39b52326b6 Add function to set all ring LEDs to a given effect channel 2019-12-24 15:04:30 -06:00
Adam Honse b35c900fae Add function to get effect string for a channel 2019-12-24 14:56:49 -06:00
Adam Honse 7cea74e466 AMD Wraith Prism controller file with some statically coded packets 2019-12-24 01:13:25 -06:00
Adam Honse 5f3e43e7b8 Only build Aorus GPU files on Windows 2019-12-23 17:37:31 -06:00
Adam Honse a84407b609 Bring PolychromeController into the build 2019-12-23 17:12:18 -06:00
Adam Honse 000511deff Update Aorus GPU files 2019-12-23 17:08:44 -06:00
Adam Honse fe37c261a2 Move Set Color buttons up for better alignment 2019-12-23 16:51:10 -06:00
Adam Honse cbdbb71d79 Add Set All Devices button 2019-12-23 16:17:00 -06:00
Adam Honse 5f786e649a Fix Hue+ initialization on Windows 2019-12-23 15:37:15 -06:00
Adam Honse f76bf34d8d HyperX zones per slot, set Hue Plus zones as linear type 2019-12-23 12:35:42 -06:00
Adam Honse e799574730 Add additional information to OpenRazer, set SPD to page 1 for proper HyperX detection 2019-12-23 02:52:09 -06:00
Adam Honse 1a5b12c7a0 OAdd strip autodetection to NZXT Hue+ interface, group zones into channels 2019-12-23 02:21:20 -06:00
Adam Honse d2acc75ba8 Report correct device types on OpenRazer interface 2019-12-22 23:11:11 -06:00
Adam Honse 74bcfbd940 Make Sleep function static on linux to avoid compile errors 2019-12-22 22:44:28 -06:00
Adam Honse 1db45f2cf2 Update slot addresses for HyperX Predator RGB and set brightness on effect modes 2019-12-22 21:27:27 -06:00
Adam Honse 6e467fe8cd Initial work on direct mode for HyperX Predator RGB 2019-12-22 02:18:20 -06:00
Adam Honse 441c462e59 Add SMBus/I2C dumping tool to System Information page 2019-12-22 00:02:08 -06:00
Adam Honse 89b4716012 Fix Aura DRAM detection and move firmware name to Version field 2019-12-20 14:28:42 -06:00
Adam Honse e51e9a71a0 Add name and serial number information fields to UI 2019-12-20 14:03:37 -06:00
Adam Honse 02273a3601 Exclude SMBus addresses from detection matching upstream i2c-tools code 2019-12-20 13:07:21 -06:00
Adam Honse e0018b23aa Use monospace font in system information box 2019-12-20 12:45:29 -06:00
Adam Honse b06f384350 System information page with i2c detect 2019-12-20 12:22:14 -06:00
Adam Honse 7dddb9d111 Start work on Information page and add information fields to RGBController API 2019-12-20 00:54:37 -06:00
Adam Honse 0d38154134 Fix DRAM type detection for some Aura based RAM Modules 2019-12-18 23:08:48 -06:00
Adam Honse 7dd84c7ac8 First round of user interface rework changes 2019-12-18 20:33:55 -06:00
Adam Honse ffd0088378 Rename dialog components from OpenAuraSDK to OpenRGB 2019-12-17 20:23:36 -06:00
Adam Honse f0c486c30d Rename OpenAuraSDK to OpenRGB for kernel patch and project file 2019-12-17 20:11:43 -06:00
Adam Honse 010ab1182d Move OpenAuraSDK_Win.pro to OpenAuraSDK.pro to unify the two project files for good 2019-12-17 19:57:06 -06:00
Adam Honse 7e64ca1f83 Merge QT project files in OpenAuraSDK_Win.pro 2019-12-17 19:51:34 -06:00
Adam Honse 2fcff92523 Add icon to Windows Qt project 2019-12-17 19:00:07 -06:00
Adam Honse 8beeb5f7b2 Get Qt project building on Windows, remove Visual Studio files 2019-12-17 18:57:53 -06:00
Adam Honse 7d2b5f285f More work on ASR LED/Polychrome support 2019-12-15 02:12:12 -06:00
Adam Honse b8eb4e9bcb Initial work on ASRock Polychrome/ASR LED interface. Does not function yet. 2019-12-14 11:15:55 -06:00
Adam Honse 733b904ec4 Undo commenting out of custom mode set function 2019-12-11 21:43:51 -06:00
Adam Honse 59a3b41480 Initial support for Gigabyte Aorus RGB Fusion motherboards 2019-12-11 20:19:21 -06:00
Adam Honse 28b41451f8 Fix typo in Aura header 2019-12-11 19:38:28 -06:00
Adam Honse 126c9295ac Add OpenRGB icon 2019-10-26 22:47:21 -05:00
Steven Franzen 0e4a162667 Change search path for i2c devices on linux
Looking for devices by bus instead of class should fix issues where the
class is named differently, e.g. i2c-dev instead of i2c-adapter.
2019-10-26 21:46:10 -05:00
Adam Honse 15fd537fa8 Add support for RGB E1.31 Streaming ACN multicast devices using libe131. Linux only for now. 2019-10-26 21:34:25 -05:00
Adam Honse 557c9df9a0 Rewrite OpenRazer support to use static constant device mapping table instead of big switch/case. Add support for some extra Razer devices. Use "ledstrip.txt" for LED strip settings 2019-10-26 18:21:02 -05:00
435 changed files with 61358 additions and 6230 deletions
+8
View File
@@ -0,0 +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
+3
View File
@@ -0,0 +1,3 @@
[submodule "razer-drivers-win32"]
path = razer-drivers-win32
url = https://github.com/rsandoz/razer-drivers-win32
+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"
@@ -0,0 +1,343 @@
/*-----------------------------------------*\
| AMDWraithPrismController.h |
| |
| Driver for AMD Wraith Prism RGB lighting |
| controller |
| |
| Adam Honse (CalcProgrammer1) 12/6/2019 |
\*-----------------------------------------*/
#include "AMDWraithPrismController.h"
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
AMDWraithPrismController::AMDWraithPrismController(hid_device* dev_handle)
{
dev = dev_handle;
strcpy(device_name, "AMD Wraith Prism");
current_fan_mode = AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC;
current_fan_speed = 0xFF;
current_fan_random_color = false;
current_logo_mode = AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC;
current_logo_speed = 0xFF;
current_logo_random_color = false;
current_ring_mode = AMD_WRAITH_PRISM_EFFECT_CHANNEL_STATIC;
current_ring_speed = 0xFF;
current_ring_direction = false;
SendEnableCommand();
}
AMDWraithPrismController::~AMDWraithPrismController()
{
}
char* AMDWraithPrismController::GetDeviceName()
{
return device_name;
}
std::string AMDWraithPrismController::GetEffectChannelString(unsigned char channel)
{
std::string ret_string = "";
unsigned char usb_buf[] =
{
0x00,
0x40, 0x21, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
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[0x03] = channel;
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
ret_string.append((char *)&usb_buf[0x08]);
return(ret_string);
}
std::string AMDWraithPrismController::GetFirmwareVersionString()
{
std::string ret_string = "";
unsigned char usb_buf[] =
{
0x00,
0x12, 0x20, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
unsigned char fw_buf[16] = {0x00};
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
for(int char_idx = 0; char_idx < 16; char_idx+=2)
{
if(usb_buf[char_idx + 0x08] != 0)
{
fw_buf[char_idx / 2] = usb_buf[char_idx + 0x08];
}
else
{
break;
}
}
ret_string.append((char *)fw_buf);
return(ret_string);
}
void AMDWraithPrismController::SetFanMode(unsigned char mode, unsigned char speed, bool random_color)
{
current_fan_mode = mode;
current_fan_speed = speed_values_fan_logo[mode][speed];
current_fan_random_color = random_color;
}
void AMDWraithPrismController::SetFanColor(unsigned char red, unsigned char green, unsigned char blue)
{
SendEffectChannelUpdate
(
AMD_WRAITH_PRISM_EFFECT_CHANNEL_FAN_LED,
current_fan_speed,
false,
current_fan_random_color,
current_fan_mode,
max_brightness_fan_logo[current_fan_mode],
red,
green,
blue
);
}
void AMDWraithPrismController::SetLogoMode(unsigned char mode, unsigned char speed, bool random_color)
{
current_logo_mode = mode;
current_logo_speed = speed_values_fan_logo[mode][speed];
current_logo_random_color = random_color;
}
void AMDWraithPrismController::SetLogoColor(unsigned char red, unsigned char green, unsigned char blue)
{
SendEffectChannelUpdate
(
AMD_WRAITH_PRISM_EFFECT_CHANNEL_LOGO_LED,
current_logo_speed,
false,
current_logo_random_color,
current_logo_mode,
max_brightness_fan_logo[current_logo_mode],
red,
green,
blue
);
}
void AMDWraithPrismController::SetRingMode(unsigned char mode, unsigned char speed, bool direction, bool random_color)
{
current_ring_mode = mode;
current_ring_speed = speed_values_ring[mode][speed];
current_ring_direction = direction;
current_ring_random_color = random_color;
}
void AMDWraithPrismController::SetRingColor(unsigned char red, unsigned char green, unsigned char blue)
{
SetRingEffectChannel(current_ring_mode);
SendEffectChannelUpdate
(
current_ring_mode,
current_ring_speed,
current_ring_direction,
current_ring_random_color,
mode_value_ring[current_ring_mode],
max_brightness_ring[current_ring_mode],
red,
green,
blue
);
SendApplyCommand();
}
void AMDWraithPrismController::SetRingEffectChannel(unsigned char channel)
{
SendChannelRemap(channel, AMD_WRAITH_PRISM_EFFECT_CHANNEL_LOGO_LED, AMD_WRAITH_PRISM_EFFECT_CHANNEL_FAN_LED);
}
void AMDWraithPrismController::SendEnableCommand()
{
unsigned char usb_buf[] =
{
0x00,
0x41, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
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,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
}
void AMDWraithPrismController::SendEffectChannelUpdate
(
unsigned char effect_channel,
unsigned char speed,
bool direction,
bool random_color,
unsigned char mode,
unsigned char brightness,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
unsigned char usb_buf[] =
{
0x00,
0x51, 0x2C, 0x01, 0x00,
0x05, 0xFF, 0x00, 0x01,
0xFF, 0xFF, 0x00, 0xFF,
0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF
};
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[0x0A] = brightness;
usb_buf[0x0B] = red;
usb_buf[0x0C] = green;
usb_buf[0x0D] = blue;
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,
0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07,
0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
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[0x09] = logo_channel;
usb_buf[0x0A] = fan_channel;
for(int led = 0x0B; led <= 0x19; led++)
{
usb_buf[led] = ring_channel;
}
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
}
@@ -0,0 +1,166 @@
/*-----------------------------------------*\
| AMDWraithPrismController.h |
| |
| Definitions and types for AMD Wraith |
| Prism lighting controller |
| |
| Adam Honse (CalcProgrammer1) 12/6/2019 |
\*-----------------------------------------*/
#include <string>
#include <hidapi/hidapi.h>
#pragma once
static const unsigned char max_brightness_fan_logo[] =
{
0x00,
0xFF,
0x7F,
0xFF
};
static const unsigned char speed_values_fan_logo[][5] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, /* Static */
{ 0x96, 0x8C, 0x80, 0x6E, 0x68 }, /* Color Cycle */
{ 0x3C, 0x37, 0x31, 0x2C, 0x26 }, /* Breathing */
};
static const unsigned char max_brightness_ring[] =
{
0xFF,
0xFF,
0x7F,
0x00,
0x00,
0x00,
0x00,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF
};
static const unsigned char mode_value_ring[] =
{
0xFF,
0x03,
0xFF,
0x00,
0x00,
0x00,
0x00,
0x05,
0xFF,
0xC3,
0x4A,
0x05
};
static const unsigned char speed_values_ring[][5] =
{
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, /* Static */
{ 0x3C, 0x37, 0x31, 0x2C, 0x26 }, /* Breathing */
{ 0x96, 0x8C, 0x80, 0x6E, 0x68 }, /* Color Cycle */
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
{ 0x72, 0x68, 0x64, 0x62, 0x61 }, /* Rainbow */
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Bounce */
{ 0x77, 0x74, 0x6E, 0x6B, 0x67 }, /* Chase */
{ 0x77, 0x74, 0x6E, 0x6B, 0x67 }, /* Swirl */
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Morse Code */
};
enum
{
AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC = 0x01, /* Fan/Logo Static Mode */
AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE = 0x02, /* Fan/Logo Color Cycle Mode */
AMD_WRAITH_PRISM_FAN_LOGO_MODE_BREATHING = 0x03, /* Fan/Logo Breathing Mode */
};
enum
{
AMD_WRAITH_PRISM_EFFECT_CHANNEL_STATIC = 0x00, /* Static effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_BREATHING = 0x01, /* Breathing effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_COLOR_CYCLE = 0x02, /* Color cycle effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_LOGO_LED = 0x05, /* Logo LED effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_FAN_LED = 0x06, /* Fan LED effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_RAINBOW = 0x07, /* Rainbow effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_BOUNCE = 0x08, /* Bounce effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_CHASE = 0x09, /* Chase effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_SWIRL = 0x0A, /* Swirl effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_MORSE = 0x0B, /* Morse code effect channel */
};
enum
{
AMD_WRAITH_PRISM_SPEED_SLOWEST = 0x00, /* Slowest speed */
AMD_WRAITH_PRISM_SPEED_SLOW = 0x01, /* Slow speed */
AMD_WRAITH_PRISM_SPEED_NORMAL = 0x02, /* Normal speed */
AMD_WRAITH_PRISM_SPEED_FAST = 0x03, /* Fast speed */
AMD_WRAITH_PRISM_SPEED_FASTEST = 0x04, /* Fastest speed */
};
class AMDWraithPrismController
{
public:
AMDWraithPrismController(hid_device* dev_handle);
~AMDWraithPrismController();
char* GetDeviceName();
std::string GetEffectChannelString(unsigned char channel);
std::string GetFirmwareVersionString();
void SetRingEffectChannel(unsigned char channel);
void SetFanMode(unsigned char mode, unsigned char speed, bool random_color);
void SetFanColor(unsigned char red, unsigned char green, unsigned char blue);
void SetLogoMode(unsigned char mode, unsigned char speed, bool random_color);
void SetLogoColor(unsigned char red, unsigned char green, unsigned char blue);
void SetRingMode(unsigned char mode, unsigned char speed, bool direction, bool random_color);
void SetRingColor(unsigned char red, unsigned char green, unsigned char blue);
private:
char device_name[32];
hid_device* dev;
unsigned char current_fan_mode;
unsigned char current_fan_speed;
bool current_fan_random_color;
unsigned char current_logo_mode;
unsigned char current_logo_speed;
bool current_logo_random_color;
unsigned char current_ring_mode;
unsigned char current_ring_speed;
bool current_ring_direction;
bool current_ring_random_color;
void SendEnableCommand();
void SendApplyCommand();
void SendEffectChannelUpdate
(
unsigned char effect_channel,
unsigned char speed,
bool direction,
bool random_color,
unsigned char mode,
unsigned char brightness,
unsigned char red,
unsigned char green,
unsigned char blue
);
void SendChannelRemap(unsigned char ring_channel, unsigned char logo_channel, unsigned char fan_channel);
};
@@ -0,0 +1,51 @@
#include "AMDWraithPrismController.h"
#include "RGBController.h"
#include "RGBController_AMDWraithPrism.h"
#include <vector>
#include <hidapi/hidapi.h>
#define AMD_WRAITH_PRISM_VID 0x2516
#define AMD_WRAITH_PRISM_PID 0x0051
/******************************************************************************************\
* *
* DetectAMDWraithPrismControllers *
* *
* Tests the USB address to see if an AMD Wraith Prism controller exists there. *
* *
\******************************************************************************************/
void DetectAMDWraithPrismControllers(std::vector<RGBController*>& rgb_controllers)
{
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
while(info)
{
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);
RGBController_AMDWraithPrism* rgb_controller = new RGBController_AMDWraithPrism(controller);
rgb_controllers.push_back(rgb_controller);
}
}
info = info->next;
}
}
@@ -1,125 +0,0 @@
#include "AuraController.h"
#include "RGBController.h"
#include "RGBController_Aura.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
/******************************************************************************************\
* *
* TestForAuraController *
* *
* Tests the given address to see if an Aura controller exists there. First does a *
* quick write to test for a response, and if so does a simple read at 0xA0 to test *
* for incrementing values 0...F which was observed at this location during data dump *
* *
\******************************************************************************************/
bool TestForAuraController(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;
for (int i = 0xA0; i < 0xB0; i++)
{
res = bus->i2c_smbus_read_byte_data(address, i);
if (res != (i - 0xA0))
{
pass = false;
}
}
}
return(pass);
} /* TestForAuraController() */
/******************************************************************************************\
* *
* DetectAuraControllers *
* *
* Detect Aura controllers on the enumerated I2C busses. Searches for Aura-enabled *
* RAM at 0x77 and tries to initialize their slot addresses, then searches for them *
* at their correct initialized addresses. Also looks for motherboard controller at *
* address 0x4E. *
* *
* bus - pointer to i2c_smbus_interface where Aura device is connected *
* dev - I2C address of Aura device *
* *
\******************************************************************************************/
void DetectAuraControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
AuraController* new_aura;
RGBController_Aura* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Remap Aura-enabled RAM modules on 0x77
for (unsigned int slot = 0; slot < 8; slot++)
{
int res = busses[bus]->i2c_smbus_write_quick(0x77, I2C_SMBUS_WRITE);
if (res < 0)
{
break;
}
AuraController temp_controller(busses[bus], 0x77);
temp_controller.AuraRegisterWrite(AURA_REG_SLOT_INDEX, slot);
temp_controller.AuraRegisterWrite(AURA_REG_I2C_ADDRESS, 0xE0 + (slot << 1));
}
// Add Aura-enabled controllers at their remapped addresses
for (unsigned int slot = 0; slot < 8; slot++)
{
if (TestForAuraController(busses[bus], 0x70 + slot))
{
new_aura = new AuraController(busses[bus], 0x70 + slot);
new_controller = new RGBController_Aura(new_aura);
rgb_controllers.push_back(new_controller);
}
}
// Check for Aura controller at 0x40
if (TestForAuraController(busses[bus], 0x40))
{
new_aura = new AuraController(busses[bus], 0x40);
new_controller = new RGBController_Aura(new_aura);
rgb_controllers.push_back(new_controller);
}
// Check for Aura controller at 0x4E
if (TestForAuraController(busses[bus], 0x4E))
{
new_aura = new AuraController(busses[bus], 0x4E);
new_controller = new RGBController_Aura(new_aura);
rgb_controllers.push_back(new_controller);
}
// Check for Aura controller at 0x4F
if (TestForAuraController(busses[bus], 0x4F))
{
new_aura = new AuraController(busses[bus], 0x4F);
new_controller = new RGBController_Aura(new_aura);
rgb_controllers.push_back(new_controller);
}
// Check for Aura controller at 0x66
if (TestForAuraController(busses[bus], 0x66))
{
new_aura = new AuraController(busses[bus], 0x66);
new_controller = new RGBController_Aura(new_aura);
rgb_controllers.push_back(new_controller);
}
}
} /* DetectAuraControllers() */
@@ -0,0 +1,125 @@
/*-----------------------------------------*\
| AuraCoreController.cpp |
| |
| Driver for ASUS ROG Aura Core RGB |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 4/13/2020 |
\*-----------------------------------------*/
#include "AuraCoreController.h"
#include <cstring>
AuraCoreController::AuraCoreController(hid_device* dev_handle)
{
dev = dev_handle;
}
AuraCoreController::~AuraCoreController()
{
}
void AuraCoreController::SendBrightness
(
unsigned char brightness
)
{
unsigned char usb_buf[17];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x5A;
usb_buf[0x01] = AURA_CORE_COMMAND_BRIGHTNESS;
usb_buf[0x02] = 0xC5;
usb_buf[0x03] = 0xC4;
usb_buf[0x04] = brightness;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, 17);
}
void AuraCoreController::SendUpdate
(
unsigned char zone,
unsigned char mode,
unsigned char speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
unsigned char usb_buf[17];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x5D;
usb_buf[0x01] = AURA_CORE_COMMAND_UPDATE;
usb_buf[0x02] = zone;
usb_buf[0x03] = mode;
usb_buf[0x04] = red;
usb_buf[0x05] = green;
usb_buf[0x06] = blue;
usb_buf[0x07] = speed;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, 17);
}
void AuraCoreController::SendSet()
{
unsigned char usb_buf[17];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x5D;
usb_buf[0x01] = AURA_CORE_COMMAND_SET;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, 17);
}
void AuraCoreController::SendApply()
{
unsigned char usb_buf[17];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x5D;
usb_buf[0x01] = AURA_CORE_COMMAND_APPLY;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, 17);
}
@@ -0,0 +1,76 @@
/*-----------------------------------------*\
| AuraCoreController.h |
| |
| Definitions and types for ASUS ROG Aura |
| Core RGB lighting controller |
| |
| Adam Honse (CalcProgrammer1) 4/13/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
AURA_CORE_MODE_STATIC = 0, /* Static color mode */
AURA_CORE_MODE_BREATHING = 1, /* Breathing effect mode */
AURA_CORE_MODE_SPECTRUM_CYCLE = 2, /* Spectrum Cycle mode */
};
enum
{
AURA_CORE_COMMAND_UPDATE = 0xB3, /* Update mode and color */
AURA_CORE_COMMAND_SET = 0xB5, /* Set command */
AURA_CORE_COMMAND_APPLY = 0xB4, /* Apply command */
AURA_CORE_COMMAND_BRIGHTNESS = 0xBA, /* Brightness command */
};
enum
{
AURA_CORE_ZONE_IDX_ALL = 0x00, /* Update all zones */
AURA_CORE_ZONE_IDX_1 = 0x01, /* Update zone 1 */
AURA_CORE_ZONE_IDX_2 = 0x02, /* Update zone 2 */
AURA_CORE_ZONE_IDX_3 = 0x03, /* Update zone 3 */
AURA_CORE_ZONE_IDX_4 = 0x04, /* Update zone 4 */
};
enum
{
AURA_CORE_SPEED_SLOW = 0xE1, /* Slowest speed */
AURA_CORE_SPEED_NORMAL = 0xEB, /* Normal speed */
AURA_CORE_SPEED_FAST = 0xF5, /* Fastest speed */
};
class AuraCoreController
{
public:
AuraCoreController(hid_device* dev_handle);
~AuraCoreController();
void SendBrightness
(
unsigned char brightness
);
void SendUpdate
(
unsigned char zone,
unsigned char mode,
unsigned char speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
void SendSet();
void SendApply();
private:
hid_device* dev;
};
@@ -0,0 +1,45 @@
#include "AuraCoreController.h"
#include "RGBController.h"
#include "RGBController_AuraCore.h"
#include <vector>
#include <hidapi/hidapi.h>
#define AURA_CORE_VID 0x0B05
#define NUM_PIDS 3
static const unsigned short pid_table[] =
{
0x1854,
0x1869,
0x1866
};
/******************************************************************************************\
* *
* DetectAuraCoreControllers *
* *
* Tests the USB address to see if an Asus ROG Aura Core controller exists there *
* *
\******************************************************************************************/
void DetectAuraCoreControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device* dev;
//Look for Asus ROG Aura Core RGB controller
hid_init();
for(int pid_idx = 0; pid_idx < NUM_PIDS; pid_idx++)
{
dev = hid_open(AURA_CORE_VID, pid_table[pid_idx], 0);
if( dev )
{
AuraCoreController* controller = new AuraCoreController(dev);
RGBController_AuraCore* rgb_controller = new RGBController_AuraCore(controller);
rgb_controllers.push_back(rgb_controller);
}
}
}
@@ -0,0 +1,84 @@
/*-----------------------------------------*\
| AuraGPUController.cpp |
| |
| Driver for ASUS Aura RGB on GPUs |
| |
| Jan Rettig (Klapstuhl) 14.02.2020 |
\*-----------------------------------------*/
#include "AuraGPUController.h"
#include <cstring>
AuraGPUController::AuraGPUController(i2c_smbus_interface* bus, aura_gpu_dev_id dev)
{
this->bus = bus;
this->dev = dev;
strcpy(device_name, "ASUS Aura GPU"); // Would be nice to get the actual GPU name. Using this as a placeholder.
}
AuraGPUController::~AuraGPUController()
{
}
std::string AuraGPUController::GetDeviceName()
{
return(device_name);
}
std::string AuraGPUController::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 AuraGPUController::GetLEDRed()
{
return(AuraGPURegisterRead(AURA_GPU_REG_RED));
}
unsigned char AuraGPUController::GetLEDGreen()
{
return(AuraGPURegisterRead(AURA_GPU_REG_GREEN));
}
unsigned char AuraGPUController::GetLEDBlue()
{
return(AuraGPURegisterRead(AURA_GPU_REG_BLUE));
}
void AuraGPUController::SetLEDColorsDirect(unsigned char red, unsigned char green, unsigned char blue) // Direct Mode is just Static Mode without applying color changes
{
AuraGPURegisterWrite(AURA_GPU_REG_RED, red);
AuraGPURegisterWrite(AURA_GPU_REG_GREEN, green);
AuraGPURegisterWrite(AURA_GPU_REG_BLUE, blue);
}
void AuraGPUController::SetLEDColorsEffect(unsigned char red, unsigned char green, unsigned char blue)
{
AuraGPURegisterWrite(AURA_GPU_REG_RED, red);
AuraGPURegisterWrite(AURA_GPU_REG_GREEN, green);
AuraGPURegisterWrite(AURA_GPU_REG_BLUE, blue);
AuraGPURegisterWrite(AURA_GPU_REG_APPLY, AURA_GPU_APPLY_VAL);
}
void AuraGPUController::SetMode(unsigned char mode)
{
AuraGPURegisterWrite(AURA_GPU_REG_MODE, mode);
AuraGPURegisterWrite(AURA_GPU_REG_APPLY, AURA_GPU_APPLY_VAL);
}
unsigned char AuraGPUController::AuraGPURegisterRead(unsigned char reg)
{
return(bus->i2c_smbus_read_byte_data(dev, reg));
}
void AuraGPUController::AuraGPURegisterWrite(unsigned char reg, unsigned char val)
{
bus->i2c_smbus_write_byte_data(dev, reg, val);
}
@@ -0,0 +1,64 @@
/*-----------------------------------------*\
| AuraGPUController.h |
| |
| Definitions for ASUS Aura RGB on GPUs |
| |
| Jan Rettig (Klapstuhl) 14.02.2020 |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char aura_gpu_dev_id;
#define AURA_GPU_MAGIC_VAL 0x1589 /* This magic value is present in all Aura GPU controllers */
#define AURA_GPU_APPLY_VAL 0x01 /* Value for Apply Changes Register */
enum
{
AURA_GPU_REG_RED = 0x04, /* AURA GPU RED Register */
AURA_GPU_REG_GREEN = 0x05, /* AURA GPU GREEN Register */
AURA_GPU_REG_BLUE = 0x06, /* AURA GPU BLUE Register */
AURA_GPU_REG_MODE = 0x07, /* AURA GPU Mode Selection Register */
AURA_GPU_REG_SYNC = 0x0C, /* AURA GPU "Sync" Register */
AURA_GPU_REG_APPLY = 0x0E, /* AURA GPU Apply Chnages Register */
};
enum
{
AURA_GPU_MODE_OFF = 0, /* OFF mode (not a real Mode! Doesn't do anything!) */
AURA_GPU_MODE_STATIC = 1, /* Static color mode */
AURA_GPU_MODE_BREATHING = 2, /* Breathing effect mode */
AURA_GPU_MODE_FLASHING = 3, /* Flashing effect mode */
AURA_GPU_MODE_SPECTRUM_CYCLE = 4, /* Spectrum Cycle mode */
AURA_GPU_MODE_DIRECT = 5, /* Direct mode (not a real Mode! Doesn't do anything!) */
AURA_GPU_NUMBER_MODES
};
class AuraGPUController
{
public:
AuraGPUController(i2c_smbus_interface* bus, aura_gpu_dev_id);
~AuraGPUController();
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 AuraGPURegisterRead(unsigned char reg);
void AuraGPURegisterWrite(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;
aura_gpu_dev_id dev;
};
@@ -0,0 +1,85 @@
/*-----------------------------------------*\
| AuraGPUControllerDetect.cpp |
| |
| Driver for ASUS Aura RGB on GPUs |
| |
| Jan Rettig (Klapstuhl) 14.02.2020 |
\*-----------------------------------------*/
#include "AuraGPUController.h"
#include "RGBController.h"
#include "RGBController_AuraGPU.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std::chrono_literals;
/*-------------------------------------------------------------*\
| This list contains the available I2C addresses for Aura GPUs |
\*-------------------------------------------------------------*/
#define AURA_GPU_ADDRESS_COUNT 3
static const unsigned char aura_gpu_addresses[] =
{
0x29,
0x2A,
0x60
};
/******************************************************************************************\
* *
* TestForAuraGPUController *
* *
* Tests the given address to see if an Aura GPU controller exists there. *
* *
\******************************************************************************************/
bool TestForAuraGPUController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
unsigned char aura_gpu_magic_high = bus->i2c_smbus_read_byte_data(address, 0x20); // High Byte of magic (0x15)
unsigned char aura_gpu_magic_low = bus->i2c_smbus_read_byte_data(address, 0x21); // Low Byte of magic (0x89)
if((aura_gpu_magic_high << 8) + aura_gpu_magic_low == AURA_GPU_MAGIC_VAL)
{
pass = true;
}
return(pass);
} /* TestForAuraGPUController() */
/******************************************************************************************\
* *
* DetectAuraGPUControllers *
* *
* Detect Aura GPU controllers on the enumerated I2C busses. *
* *
\******************************************************************************************/
void DetectAuraGPUControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
AuraGPUController* new_aura_gpu;
RGBController_AuraGPU* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Add Aura-enabled GPU controllers
for (unsigned int address_list_idx = 0; address_list_idx < AURA_GPU_ADDRESS_COUNT; address_list_idx++)
{
if (TestForAuraGPUController(busses[bus], aura_gpu_addresses[address_list_idx]))
{
new_aura_gpu = new AuraGPUController(busses[bus], aura_gpu_addresses[address_list_idx]);
new_controller = new RGBController_AuraGPU(new_aura_gpu);
rgb_controllers.push_back(new_controller);
}
std::this_thread::sleep_for(1ms);
}
}
} /* DetectAuraGPUControllers() */
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| AuraController.h |
| AuraSMBusController.cpp |
| |
| Driver for ASUS Aura RGB lighting |
| controller |
@@ -7,10 +7,10 @@
| Adam Honse (CalcProgrammer1) 8/19/2018 |
\*-----------------------------------------*/
#include "AuraController.h"
#include "AuraSMBusController.h"
#include <cstring>
AuraController::AuraController(i2c_smbus_interface* bus, aura_dev_id dev)
AuraSMBusController::AuraSMBusController(i2c_smbus_interface* bus, aura_dev_id dev)
{
this->bus = bus;
this->dev = dev;
@@ -77,22 +77,32 @@ AuraController::AuraController(i2c_smbus_interface* bus, aura_dev_id dev)
}
}
AuraController::~AuraController()
AuraSMBusController::~AuraSMBusController()
{
}
char * AuraController::GetDeviceName()
std::string AuraSMBusController::GetDeviceName()
{
return(device_name);
}
unsigned char AuraController::GetChannel(unsigned int led)
std::string AuraSMBusController::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 AuraSMBusController::GetChannel(unsigned int led)
{
return(config_table[channel_cfg + led]);
}
const char * AuraController::GetChannelName(unsigned int led)
const char * AuraSMBusController::GetChannelName(unsigned int led)
{
switch (config_table[channel_cfg + led])
{
@@ -142,16 +152,31 @@ const char * AuraController::GetChannelName(unsigned int led)
}
}
unsigned int AuraController::GetLEDCount()
unsigned int AuraSMBusController::GetLEDCount()
{
return(led_count);
}
void AuraController::SetAllColorsDirect(unsigned char red, unsigned char green, unsigned char blue)
unsigned char AuraSMBusController::GetLEDRed(unsigned int led)
{
return(AuraRegisterRead(direct_reg + ( 3 * led )));
}
unsigned char AuraSMBusController::GetLEDGreen(unsigned int led)
{
return(AuraRegisterRead(direct_reg + ( 3 * led ) + 2));
}
unsigned char AuraSMBusController::GetLEDBlue(unsigned int led)
{
return(AuraRegisterRead(direct_reg + ( 3 * led ) + 1));
}
void AuraSMBusController::SetAllColorsDirect(unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char* colors = new unsigned char[led_count * 3];
for (int i = 0; i < (led_count * 3); i += 3)
for (unsigned int i = 0; i < (led_count * 3); i += 3)
{
colors[i + 0] = red;
colors[i + 1] = blue;
@@ -163,11 +188,11 @@ void AuraController::SetAllColorsDirect(unsigned char red, unsigned char green,
delete colors;
}
void AuraController::SetAllColorsEffect(unsigned char red, unsigned char green, unsigned char blue)
void AuraSMBusController::SetAllColorsEffect(unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char* colors = new unsigned char[led_count * 3];
for (int i = 0; i < (led_count * 3); i += 3)
for (unsigned int i = 0; i < (led_count * 3); i += 3)
{
colors[i + 0] = red;
colors[i + 1] = blue;
@@ -178,23 +203,23 @@ void AuraController::SetAllColorsEffect(unsigned char red, unsigned char green,
AuraRegisterWrite(AURA_REG_APPLY, AURA_APPLY_VAL);
delete colors;
delete[] colors;
}
void AuraController::SetDirect(unsigned char direct)
void AuraSMBusController::SetDirect(unsigned char direct)
{
AuraRegisterWrite(AURA_REG_DIRECT, direct);
AuraRegisterWrite(AURA_REG_APPLY, AURA_APPLY_VAL);
}
void AuraController::SetLEDColorDirect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
void AuraSMBusController::SetLEDColorDirect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char colors[3] = { red, blue, green };
AuraRegisterWriteBlock(direct_reg + ( 3 * led ), colors, 3);
}
void AuraController::SetLEDColorEffect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
void AuraSMBusController::SetLEDColorEffect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char colors[3] = { red, blue, green };
@@ -203,13 +228,13 @@ void AuraController::SetLEDColorEffect(unsigned int led, unsigned char red, unsi
AuraRegisterWrite(AURA_REG_APPLY, AURA_APPLY_VAL);
}
void AuraController::SetMode(unsigned char mode)
void AuraSMBusController::SetMode(unsigned char mode)
{
AuraRegisterWrite(AURA_REG_MODE, mode);
AuraRegisterWrite(AURA_REG_APPLY, AURA_APPLY_VAL);
}
void AuraController::AuraUpdateDeviceName()
void AuraSMBusController::AuraUpdateDeviceName()
{
for (int i = 0; i < 16; i++)
{
@@ -217,7 +242,7 @@ void AuraController::AuraUpdateDeviceName()
}
}
unsigned char AuraController::AuraRegisterRead(aura_register reg)
unsigned char AuraSMBusController::AuraRegisterRead(aura_register reg)
{
//Write Aura register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
@@ -227,7 +252,7 @@ unsigned char AuraController::AuraRegisterRead(aura_register reg)
}
void AuraController::AuraRegisterWrite(aura_register reg, unsigned char val)
void AuraSMBusController::AuraRegisterWrite(aura_register reg, unsigned char val)
{
//Write Aura register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
@@ -237,7 +262,7 @@ void AuraController::AuraRegisterWrite(aura_register reg, unsigned char val)
}
void AuraController::AuraRegisterWriteBlock(aura_register reg, unsigned char * data, unsigned char sz)
void AuraSMBusController::AuraRegisterWriteBlock(aura_register reg, unsigned char * data, unsigned char sz)
{
//Write Aura register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
@@ -245,4 +270,4 @@ void AuraController::AuraRegisterWriteBlock(aura_register reg, unsigned char * d
//Write Aura block data
bus->i2c_smbus_write_block_data(dev, 0x03, sz, data);
}
}
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| AuraController.h |
| AuraSMBusController.h |
| |
| Definitions and types for ASUS Aura RGB |
| lighting controller |
@@ -7,6 +7,7 @@
| Adam Honse (CalcProgrammer1) 8/19/2018 |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
@@ -87,16 +88,20 @@ enum
AURA_CONFIG_CHANNEL_V2 = 0x1B, /* LED Channel V2 configuration offset */
};
class AuraController
class AuraSMBusController
{
public:
AuraController(i2c_smbus_interface* bus, aura_dev_id dev);
~AuraController();
AuraSMBusController(i2c_smbus_interface* bus, aura_dev_id dev);
~AuraSMBusController();
char* GetDeviceName();
std::string GetDeviceName();
std::string GetDeviceLocation();
unsigned char GetChannel(unsigned int led);
const char* GetChannelName(unsigned int led);
unsigned int GetLEDCount();
unsigned char GetLEDRed(unsigned int led);
unsigned char GetLEDGreen(unsigned int led);
unsigned char GetLEDBlue(unsigned int led);
void SetAllColorsDirect(unsigned char red, unsigned char green, unsigned char blue);
void SetAllColorsEffect(unsigned char red, unsigned char green, unsigned char blue);
void SetDirect(unsigned char direct);
@@ -120,4 +125,4 @@ private:
i2c_smbus_interface * bus;
aura_dev_id dev;
};
};
@@ -0,0 +1,190 @@
#include "AuraSMBusController.h"
#include "RGBController.h"
#include "RGBController_AuraSMBus.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std::chrono_literals;
/*----------------------------------------------------------------------*\
| This list contains the available SMBus addresses for mapping Aura RAM |
\*----------------------------------------------------------------------*/
#define AURA_RAM_ADDRESS_COUNT 23
static const unsigned char aura_ram_addresses[] =
{
0x70,
0x71,
0x72,
0x73,
0x74,
0x75,
0x76,
0x78,
0x79,
0x7A,
0x7B,
0x7C,
0x7D,
0x7E,
0x7F,
0x4F,
0x66,
0x67,
0x39,
0x3A,
0x3B,
0x3C,
0x3D
};
/*---------------------------------------------------------------------------------*\
| This list contains the available SMBus addresses for mapping Aura motherboards |
\*---------------------------------------------------------------------------------*/
#define AURA_MOBO_ADDRESS_COUNT 3
static const unsigned char aura_mobo_addresses[] =
{
0x40,
0x4E,
0x4F
};
/******************************************************************************************\
* *
* AuraRegisterWrite *
* *
* A standalone version of the AuraSMBusController::AuraRegisterWrite function for *
* access to Aura devices without instancing the AuraSMBusController class or reading *
* the config table from the device. *
* *
\******************************************************************************************/
void AuraRegisterWrite(i2c_smbus_interface* bus, aura_dev_id dev, aura_register reg, unsigned char val)
{
//Write Aura register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
//Write Aura value
bus->i2c_smbus_write_byte_data(dev, 0x01, val);
}
/******************************************************************************************\
* *
* TestForAuraSMBusController *
* *
* Tests the given address to see if an Aura controller exists there. First does a *
* quick write to test for a response, and if so does a simple read at 0xA0 to test *
* for incrementing values 0...F which was observed at this location during data dump *
* *
\******************************************************************************************/
bool TestForAuraSMBusController(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;
for (int i = 0xA0; i < 0xB0; i++)
{
res = bus->i2c_smbus_read_byte_data(address, i);
if (res != (i - 0xA0))
{
pass = false;
}
}
}
return(pass);
} /* TestForAuraSMBusController() */
/******************************************************************************************\
* *
* DetectAuraSMBusControllers *
* *
* Detect Aura controllers on the enumerated I2C busses. Searches for Aura-enabled *
* RAM at 0x77 and tries to initialize their slot addresses, then searches for them *
* at their correct initialized addresses. Also looks for motherboard controller at *
* address 0x4E. *
* *
* bus - pointer to i2c_smbus_interface where Aura device is connected *
* dev - I2C address of Aura device *
* *
\******************************************************************************************/
void DetectAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
AuraSMBusController* new_aura;
RGBController_AuraSMBus* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
int address_list_idx = -1;
// Remap Aura-enabled RAM modules on 0x77
for (unsigned int slot = 0; slot < 8; slot++)
{
int res = busses[bus]->i2c_smbus_write_quick(0x77, I2C_SMBUS_WRITE);
if (res < 0)
{
break;
}
do
{
address_list_idx++;
if(address_list_idx < AURA_RAM_ADDRESS_COUNT)
{
res = busses[bus]->i2c_smbus_write_quick(aura_ram_addresses[address_list_idx], I2C_SMBUS_WRITE);
}
else
{
break;
}
} while (res >= 0);
if(address_list_idx < AURA_RAM_ADDRESS_COUNT)
{
AuraRegisterWrite(busses[bus], 0x77, AURA_REG_SLOT_INDEX, slot);
AuraRegisterWrite(busses[bus], 0x77, AURA_REG_I2C_ADDRESS, (aura_ram_addresses[address_list_idx] << 1));
}
}
// Add Aura-enabled controllers at their remapped addresses
for (unsigned int address_list_idx = 0; address_list_idx < AURA_RAM_ADDRESS_COUNT; address_list_idx++)
{
if (TestForAuraSMBusController(busses[bus], aura_ram_addresses[address_list_idx]))
{
new_aura = new AuraSMBusController(busses[bus], aura_ram_addresses[address_list_idx]);
new_controller = new RGBController_AuraSMBus(new_aura);
rgb_controllers.push_back(new_controller);
}
std::this_thread::sleep_for(1ms);
}
// Add Aura-enabled motherboard controllers
for (unsigned int address_list_idx = 0; address_list_idx < AURA_MOBO_ADDRESS_COUNT; address_list_idx++)
{
if (TestForAuraSMBusController(busses[bus], aura_mobo_addresses[address_list_idx]))
{
new_aura = new AuraSMBusController(busses[bus], aura_mobo_addresses[address_list_idx]);
new_controller = new RGBController_AuraSMBus(new_aura);
rgb_controllers.push_back(new_controller);
}
std::this_thread::sleep_for(1ms);
}
}
} /* DetectAuraSMBusControllers() */
@@ -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);
}
@@ -0,0 +1,107 @@
/*-----------------------------------------*\
| AuraUSBController.h |
| |
| Definitions and types for ASUS Aura |
| USB RGB lighting controller |
| |
| Martin Hartl (inlart) 4/25/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
enum
{
AURA_MODE_OFF = 0, /* OFF mode */
AURA_MODE_STATIC = 1, /* Static color mode */
AURA_MODE_BREATHING = 2, /* Breathing effect mode */
AURA_MODE_FLASHING = 3, /* Flashing effect mode */
AURA_MODE_SPECTRUM_CYCLE = 4, /* Spectrum Cycle mode */
AURA_MODE_RAINBOW = 5, /* Rainbow effect mode */
AURA_MODE_SPECTRUM_CYCLE_BREATHING = 6, /* Rainbow Breathing effect mode */
AURA_MODE_CHASE_FADE = 7, /* Chase with Fade effect mode */
AURA_MODE_SPECTRUM_CYCLE_CHASE_FADE = 8, /* Chase with Fade, Rainbow effect mode */
AURA_MODE_CHASE = 9, /* Chase effect mode */
AURA_MODE_SPECTRUM_CYCLE_CHASE = 10, /* Chase with Rainbow effect mode */
AURA_MODE_SPECTRUM_CYCLE_WAVE = 11, /* Wave effect mode */
AURA_MODE_CHASE_RAINBOW_PULSE = 12, /* Chase with Rainbow Pulse effect mode*/
AURA_MODE_RANDOM_FLICKER = 13, /* Random flicker effect mode */
AURA_MODE_MUSIC = 14, /* Music effect mode */
AURA_MODE_DIRECT = 0xFF, /* Direct control mode */
};
enum
{
AURA_REQUEST_FIRMWARE_VERSION = 0x82, /* Request firmware string */
AURA_REQUEST_CONFIG_TABLE = 0xB0, /* Request configuration table */
AURA_CONTROL_MODE_DIRECT = 0x40, /* Direct control mode */
};
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:
AuraUSBController(hid_device* dev_handle);
virtual ~AuraUSBController();
unsigned int GetChannelCount();
std::string GetDeviceName();
const std::vector<AuraDeviceInfo>& GetAuraDevices() const;
virtual void SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
unsigned int num_colors
) = 0;
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,
bool apply = false
);
private:
char device_name[16];
unsigned int led_count;
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
}
}
}
}
@@ -0,0 +1,145 @@
/*-------------------------------------------------------------------*\
| CMMP750Controller.cpp |
| |
| Driver for Coolermaster MP750 mousepad |
| |
| Chris M (Dr_No) 16th Apr 2020 |
| |
\*-------------------------------------------------------------------*/
#include "CMMP750Controller.h"
CMMP750Controller::CMMP750Controller(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path)
{
int tmp_size = wcslen(_vendor);
dev = dev_handle;
location = _path;
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];
GetStatus(); //When setting up device get current status
}
CMMP750Controller::~CMMP750Controller()
{
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()
{
return device_name;
}
char* CMMP750Controller::GetSerial()
{
return serial;
}
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;
current_speed = speed;
SendUpdate();
}
void CMMP750Controller::SetColor(unsigned char red, unsigned char green, unsigned char blue)
{
current_red = red;
current_green = green;
current_blue = blue;
SendUpdate();
}
void CMMP750Controller::SendUpdate()
{
unsigned char buffer[0x40] = { 0x00 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
for(int i = 0; i < CM_COLOUR_MODE_DATA_SIZE; i++)
{
buffer[i] = colour_mode_data[current_mode][i];
}
if(current_mode > MP750_MODE_BREATHING)
{
//If the mode is random colours set SPEED at BYTE2
buffer[CM_RED_BYTE] = speed_mode_data[current_mode][current_speed];
}
else
{
//Otherwise SPEED is BYTE5
buffer[CM_RED_BYTE] = current_red;
buffer[CM_GREEN_BYTE] = current_green;
buffer[CM_BLUE_BYTE] = current_blue;
buffer[CM_SPEED_BYTE] = speed_mode_data[current_mode][current_speed];
}
hid_write(dev, buffer, buffer_size);
}
@@ -0,0 +1,111 @@
/*-------------------------------------------------------------------*\
| CMMP750Controller.h |
| |
| Driver for Coolermaster MP750 mousepad |
| |
| Chris M (Dr_No) 16th Apr 2020 |
| |
| Simple RGB device with 5 modes |
| BYTE0 = Mode (0x01 thru 0x05 |
| BYTE1 = ?? Must be set to 0x04 for colour modes otherwise ignored |
| BYTE2 = Colour Modes: RED else Cycle SPEED |
| BYTE3 = Colour Modes: GREEN else ignored |
| BYTE4 = Colour Modes: BLUE else ignored |
| BYTE5 = Colour Modes: SPEED else ignored |
\*-------------------------------------------------------------------*/
#include <string>
#include <array>
#include <hidapi/hidapi.h>
#pragma once
#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
{
CM_MODE_BYTE = 0,
CM_RED_BYTE = 2,
CM_GREEN_BYTE = 3,
CM_BLUE_BYTE = 4,
CM_SPEED_BYTE = 5
};
enum
{
MP750_MODE_STATIC = 0x00, //Static Mode
MP750_MODE_BLINK = 0x01, //Blinking Mode
MP750_MODE_BREATHING = 0x02, //Breathing Mode
MP750_MODE_COLOR_CYCLE = 0x03, //Color Cycle Mode
MP750_MODE_BREATH_CYCLE = 0x04 //Breathing Cycle Mode
};
static unsigned char colour_mode_data[][6] =
{
{ 0x01, 0x04, 0xFF, 0x00, 0xFF, 0x00 }, /* Static */
{ 0x02, 0x04, 0xFF, 0x00, 0xFF, 0x80 }, /* Blinking */
{ 0x03, 0x04, 0xFF, 0x00, 0xFF, 0x80 }, /* Breathing */
{ 0x04, 0x04, 0x80, 0x00, 0x00, 0x00 }, /* Colour Cycle */
{ 0x05, 0x04, 0x80, 0x00, 0x00, 0x00 } /* Colour Breath */
};
static unsigned char speed_mode_data[][9] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },/* Static */
{ 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
{
MP750_SPEED_SLOWEST = 0x00, /* Slowest speed */
MP750_SPEED_SLOWER = 0x01, /* Slower speed */
MP750_SPEED_SLOW = 0x02, /* Slow speed */
MP750_SPEED_SLOWISH = 0x03, /* Slowish speed */
MP750_SPEED_NORMAL = 0x04, /* Normal speed */
MP750_SPEED_FASTISH = 0x05, /* Fastish speed */
MP750_SPEED_FAST = 0x06, /* Fast speed */
MP750_SPEED_FASTER = 0x07, /* Faster speed */
MP750_SPEED_FASTEST = 0x08, /* Fastest speed */
};
class CMMP750Controller
{
public:
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);
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 GetStatus();
void SendUpdate();
};
@@ -0,0 +1,66 @@
#include "CMMP750Controller.h"
#include "RGBController.h"
#include "RGBController_CMMP750Controller.h"
#include <hidapi/hidapi.h>
#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_INTERFACE = 1
};
static const unsigned int cm_pids[][4] =
{ // PID, Interface
{ COOLERMASTER_MP750_XL_PID, 0x00 }, //Coolermaster MP750 (Extra Large)
{ COOLERMASTER_MP750_MEDIUM_PID, 0x00 } //Coolermaster MP750 (Medium)
};
/******************************************************************************************\
* *
* DetectCoolerMasterControllers *
* *
* Tests the USB address to see if any CoolerMaster controllers exists there. *
* *
\******************************************************************************************/
void DetectCoolerMasterControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device_info* info;
//Look for the passed in cm_pids
hid_init();
info = hid_enumerate(COOLERMASTER_VID, 0x0);
while(info)
{
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)
{
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);
}
@@ -0,0 +1,468 @@
/*---------------------------------------------------------*\
| Processing Code for Corsair Lighting Node Pro |
| |
| Adam Honse ([email protected]), 1/12/2020 |
\*---------------------------------------------------------*/
#include "CorsairLightingNodeController.h"
#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
//Include thread libraries for Windows or Linux
#ifdef WIN32
#include <process.h>
#else
#include "pthread.h"
#include "unistd.h"
#endif
//Thread functions have different types in Windows and Linux
#ifdef WIN32
#define THREAD static void
#define THREADRETURN
#else
#define THREAD static void*
#define THREADRETURN return(NULL);
#endif
using namespace std::chrono_literals;
THREAD keepalive_thread(void *param)
{
CorsairLightingNodeController* corsair = static_cast<CorsairLightingNodeController*>(param);
corsair->KeepaliveThread();
THREADRETURN
}
CorsairLightingNodeController::CorsairLightingNodeController(hid_device* dev_handle)
{
dev = dev_handle;
SendFirmwareRequest();
/*-----------------------------------------------------*\
| The Corsair Lighting Node Pro requires a packet within|
| 20 seconds of sending the lighting change in order |
| to not revert back into rainbow mode. Start a thread |
| to continuously send a keepalive packet every 5s |
\*-----------------------------------------------------*/
#ifdef WIN32
_beginthread(keepalive_thread, 0, this);
#else
pthread_t thread;
pthread_create(&thread, NULL, &keepalive_thread, this);
#endif
}
CorsairLightingNodeController::~CorsairLightingNodeController()
{
}
void CorsairLightingNodeController::KeepaliveThread()
{
while(1)
{
if((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::seconds(5))
{
SendCommit();
}
std::this_thread::sleep_for(1s);
}
}
std::string CorsairLightingNodeController::GetFirmwareString()
{
return(firmware_version);
}
void CorsairLightingNodeController::SetChannelEffect(unsigned char channel,
unsigned char num_leds,
unsigned char mode,
unsigned char speed,
unsigned char direction,
bool random,
unsigned char red1,
unsigned char grn1,
unsigned char blu1,
unsigned char red2,
unsigned char grn2,
unsigned char blu2,
unsigned char red3,
unsigned char grn3,
unsigned char blu3
)
{
/*-----------------------------------------------------*\
| Send Reset packet |
\*-----------------------------------------------------*/
SendReset(channel);
/*-----------------------------------------------------*\
| Send Begin packet |
\*-----------------------------------------------------*/
SendBegin(channel);
/*-----------------------------------------------------*\
| Set Port State packet |
\*-----------------------------------------------------*/
SendPortState(channel, CORSAIR_LIGHTING_NODE_PORT_STATE_HARDWARE);
/*-----------------------------------------------------*\
| Set Effect Configuration packet |
\*-----------------------------------------------------*/
SendEffectConfig
(
channel,
0,
num_leds,
mode,
speed,
direction,
random,
red1,
grn1,
blu1,
red2,
grn2,
blu2,
red3,
grn3,
blu3,
0,
0,
0
);
/*-----------------------------------------------------*\
| Send Commit packet |
\*-----------------------------------------------------*/
SendCommit();
}
void CorsairLightingNodeController::SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors)
{
unsigned char red_color_data[50];
unsigned char grn_color_data[50];
unsigned char blu_color_data[50];
unsigned char pkt_offset = 0;
unsigned char pkt_size = 0;
unsigned int colors_remaining = num_colors;
/*-----------------------------------------------------*\
| Send Port State packet |
\*-----------------------------------------------------*/
SendPortState(channel, CORSAIR_LIGHTING_NODE_PORT_STATE_SOFTWARE);
/*-----------------------------------------------------*\
| Loop through colors and send 50 at a time |
\*-----------------------------------------------------*/
while(colors_remaining > 0)
{
if(colors_remaining < 50)
{
pkt_size = colors_remaining;
}
else
{
pkt_size = 50;
}
for(int color_idx = 0; color_idx < pkt_size; color_idx++)
{
red_color_data[color_idx] = RGBGetRValue(colors[pkt_offset + color_idx]);
grn_color_data[color_idx] = RGBGetGValue(colors[pkt_offset + color_idx]);
blu_color_data[color_idx] = RGBGetBValue(colors[pkt_offset + color_idx]);
}
SendDirect(channel, pkt_offset, pkt_size, CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_RED, red_color_data);
SendDirect(channel, pkt_offset, pkt_size, CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_GREEN, grn_color_data);
SendDirect(channel, pkt_offset, pkt_size, CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_BLUE, blu_color_data);
colors_remaining -= pkt_size;
pkt_offset += pkt_size;
}
/*-----------------------------------------------------*\
| Send Commit packet |
\*-----------------------------------------------------*/
SendCommit();
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void CorsairLightingNodeController::SendFirmwareRequest()
{
int actual;
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Firmware Version Request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_FIRMWARE;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
actual = hid_read(dev, usb_buf, 17);
if(actual > 0)
{
firmware_version = std::to_string(usb_buf[0x01]) + "." + std::to_string(usb_buf[0x02]) + "." + std::to_string(usb_buf[0x03]);
}
}
void CorsairLightingNodeController::SendDirect
(
unsigned char channel,
unsigned char start,
unsigned char count,
unsigned char color_channel,
unsigned char* color_data
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Direct packet |
\*-----------------------------------------------------*/
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[0x06], color_data, count);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SendCommit()
{
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] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_COMMIT;
usb_buf[0x02] = 0xFF;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SendBegin
(
unsigned char channel
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Begin packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_BEGIN;
usb_buf[0x02] = channel;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SendEffectConfig
(
unsigned char channel,
unsigned char count,
unsigned char led_type,
unsigned char mode,
unsigned char speed,
unsigned char direction,
unsigned char change_style,
unsigned char color_0_red,
unsigned char color_0_green,
unsigned char color_0_blue,
unsigned char color_1_red,
unsigned char color_1_green,
unsigned char color_1_blue,
unsigned char color_2_red,
unsigned char color_2_green,
unsigned char color_2_blue,
unsigned short temperature_0,
unsigned short temperature_1,
unsigned short temperature_2
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Effect Config packet |
\*-----------------------------------------------------*/
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[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[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[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 |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SendTemperature()
{
}
void CorsairLightingNodeController::SendReset
(
unsigned char channel
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Reset packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_RESET;
usb_buf[0x02] = channel;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SendPortState
(
unsigned char channel,
unsigned char state
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Port State packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_PORT_STATE;
usb_buf[0x02] = channel;
usb_buf[0x03] = state;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SendBrightness()
{
}
void CorsairLightingNodeController::SendLEDCount()
{
}
void CorsairLightingNodeController::SendProtocol()
{
}
@@ -0,0 +1,174 @@
/*---------------------------------------------------------*\
| Definitions for Corsair Lighting Node Pro |
| |
| Adam Honse ([email protected]), 1/12/2020 |
\*---------------------------------------------------------*/
#include "RGBController.h"
#include <chrono>
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
enum
{
CORSAIR_LIGHTING_NODE_PACKET_ID_FIRMWARE = 0x02, /* Get firmware version */
CORSAIR_LIGHTING_NODE_PACKET_ID_DIRECT = 0x32, /* Direct mode LED update packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_COMMIT = 0x33, /* Commit changes packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_BEGIN = 0x34, /* Begin effect packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_EFFECT_CONFIG = 0x35, /* Effect mode configuration packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_TEMPERATURE = 0x36, /* Update temperature value packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_RESET = 0x37, /* Reset channel packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_PORT_STATE = 0x38, /* Set port state packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_BRIGHTNESS = 0x39, /* Set brightness packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_LED_COUNT = 0x3A, /* Set LED count packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_PROTOCOL = 0x3B, /* Set protocol packet */
};
enum
{
CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_RED = 0x00, /* Red channel for direct update */
CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_GREEN = 0x01, /* Green channel for direct update */
CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_BLUE = 0x02, /* Blue channel for direct update */
};
enum
{
CORSAIR_LIGHTING_NODE_PORT_STATE_HARDWARE = 0x01, /* Effect hardware control of channel */
CORSAIR_LIGHTING_NODE_PORT_STATE_SOFTWARE = 0x02, /* Direct software control of channel */
};
enum
{
CORSAIR_LIGHTING_NODE_LED_TYPE_LED_STRIP = 0x0A, /* Corsair LED Strip Type */
CORSAIR_LIGHTING_NODE_LED_TYPE_HD_FAN = 0x0C, /* Corsair HD-series Fan Type */
CORSAIR_LIGHTING_NODE_LED_TYPE_SP_FAN = 0x01, /* Corsair SP-series Fan Type */
CORSAIR_LIGHTING_NODE_LED_TYPE_ML_FAN = 0x02, /* Corsair ML-series Fan Type */
};
enum
{
CORSAIR_LIGHTING_NODE_CHANNEL_1 = 0x00, /* Channel 1 */
CORSAIR_LIGHTING_NODE_CHANNEL_2 = 0x01, /* Channel 2 */
CORSAIR_LIGHTING_NODE_NUM_CHANNELS = 0x02, /* Number of channels */
};
enum
{
CORSAIR_LIGHTING_NODE_SPEED_FAST = 0x00, /* Fast speed */
CORSAIR_LIGHTING_NODE_SPEED_MEDIUM = 0x01, /* Medium speed */
CORSAIR_LIGHTING_NODE_SPEED_SLOW = 0x02, /* Slow speed */
};
enum
{
CORSAIR_LIGHTING_NODE_MODE_RAINBOW_WAVE = 0x00, /* Rainbow Wave mode */
CORSAIR_LIGHTING_NODE_MODE_COLOR_SHIFT = 0x01, /* Color Shift mode */
CORSAIR_LIGHTING_NODE_MODE_COLOR_PULSE = 0x02, /* Color Pulse mode */
CORSAIR_LIGHTING_NODE_MODE_COLOR_WAVE = 0x03, /* Color Wave mode */
CORSAIR_LIGHTING_NODE_MODE_STATIC = 0x04, /* Static mode */
CORSAIR_LIGHTING_NODE_MODE_TEMPERATURE = 0x05, /* Temperature mode */
CORSAIR_LIGHTING_NODE_MODE_VISOR = 0x06, /* Visor mode */
CORSAIR_LIGHTING_NODE_MODE_MARQUEE = 0x07, /* Marquee mode */
CORSAIR_LIGHTING_NODE_MODE_BLINK = 0x08, /* Blink mode */
CORSAIR_LIGHTING_NODE_MODE_SEQUENTIAL = 0x09, /* Sequential mode */
CORSAIR_LIGHTING_NODE_MODE_RAINBOW = 0x0A, /* Rainbow mode */
};
class CorsairLightingNodeController
{
public:
CorsairLightingNodeController(hid_device* dev_handle);
~CorsairLightingNodeController();
std::string GetFirmwareString();
unsigned int GetStripsOnChannel(unsigned int channel);
void SetChannelEffect(unsigned char channel,
unsigned char num_leds,
unsigned char mode,
unsigned char speed,
unsigned char direction,
bool random,
unsigned char red1,
unsigned char grn1,
unsigned char blu1,
unsigned char red2,
unsigned char grn2,
unsigned char blu2,
unsigned char red3,
unsigned char grn3,
unsigned char blu3
);
void SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors);
void KeepaliveThread();
private:
hid_device* dev;
std::string firmware_version;
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
void SendFirmwareRequest();
void SendDirect
(
unsigned char channel,
unsigned char start,
unsigned char count,
unsigned char color_channel,
unsigned char* color_data
);
void SendCommit();
void SendBegin
(
unsigned char channel
);
void SendEffectConfig
(
unsigned char channel,
unsigned char count,
unsigned char led_type,
unsigned char mode,
unsigned char speed,
unsigned char direction,
unsigned char change_style,
unsigned char color_0_red,
unsigned char color_0_green,
unsigned char color_0_blue,
unsigned char color_1_red,
unsigned char color_1_green,
unsigned char color_1_blue,
unsigned char color_2_red,
unsigned char color_2_green,
unsigned char color_2_blue,
unsigned short temperature_0,
unsigned short temperature_1,
unsigned short temperature_2
);
void SendTemperature();
void SendReset
(
unsigned char channel
);
void SendPortState
(
unsigned char channel,
unsigned char state
);
void SendBrightness();
void SendLEDCount();
void SendProtocol();
};
@@ -0,0 +1,79 @@
#include "CorsairLightingNodeController.h"
#include "RGBController.h"
#include "RGBController_CorsairLightingNode.h"
#include <vector>
#include <hidapi/hidapi.h>
#define CORSAIR_VID 0x1B1C
#define CORSAIR_LIGHTING_NODE_CORE_PID 0x0C1A
#define CORSAIR_LIGHTING_NODE_PRO_PID 0x0C0B
#define CORSAIR_COMMANDER_PRO_PID 0x0C10
#define CORSAIR_LS100_PID 0x0C1E
#define CORSAIR_1000D_OBSIDIAN_PID 0x1D00
#define CORSAIR_SPEC_OMEGA_RGB_PID 0x1D04
typedef struct
{
unsigned short usb_vid;
unsigned short usb_pid;
unsigned char channel_count;
const char * name;
} corsair_node_device;
#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" }
};
/******************************************************************************************\
* *
* DetectCorsairLightingNodeControllers *
* *
* Detect devices supported by the Corsair Lighting Node Pro driver *
* *
\******************************************************************************************/
void DetectCorsairLightingNodeControllers(std::vector<RGBController*> &rgb_controllers)
{
hid_device_info* info;
hid_device* dev;
hid_init();
for(std::size_t device_idx = 0; device_idx < CORSAIR_NUM_DEVICES; device_idx++)
{
dev = NULL;
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for Corsair Lighting Node 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 )
{
CorsairLightingNodeController* controller = new CorsairLightingNodeController(dev);
RGBController_CorsairLightingNode* rgb_controller = new RGBController_CorsairLightingNode(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
info = info->next;
}
}
} /* DetectCorsairLightingNodeControllers() */
@@ -0,0 +1,549 @@
/*-----------------------------------------*\
| CorsairPeripheralController.cpp |
| |
| Driver for Corsair RGB keyboard, mouse, |
| and mousemat lighting controller |
| |
| Adam Honse (CalcProgrammer1) 1/9/2020 |
\*-----------------------------------------*/
#include "CorsairPeripheralController.h"
#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,
0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x42, 0x43, 0x44, 0x45, 0x48, 73, 74, 75, 76, 78,
79, 80, 81, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 96, 97,
98, 99, 100, 101, 102, 103, 104, 105, 108, 109, 110, 111, 112, 113, 115,
116, 117, 120, 121, 122, 123, 124, 126, 127, 128, 129, 132, 133, 134, 135,
136, 137, 139, 140, 141};
static unsigned int st100[] = { 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x04 };
CorsairPeripheralController::CorsairPeripheralController(hid_device* dev_handle)
{
dev = dev_handle;
ReadFirmwareInfo();
LightingControl();
}
CorsairPeripheralController::~CorsairPeripheralController()
{
}
device_type CorsairPeripheralController::GetDeviceType()
{
return type;
}
std::string CorsairPeripheralController::GetFirmwareString()
{
return firmware_version;
}
void CorsairPeripheralController::SetLEDs(std::vector<RGBColor>colors)
{
switch(type)
{
case DEVICE_TYPE_KEYBOARD:
SetLEDsKeyboardFull(colors);
break;
case DEVICE_TYPE_MOUSE:
SetLEDsMouse(colors);
break;
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;
}
}
void CorsairPeripheralController::SetLEDsKeyboardFull(std::vector<RGBColor> colors)
{
unsigned char red_val[144];
unsigned char grn_val[144];
unsigned char blu_val[144];
/*-----------------------------------------------------*\
| Zero out buffers |
\*-----------------------------------------------------*/
memset(red_val, 0x00, sizeof( red_val ));
memset(grn_val, 0x00, sizeof( grn_val ));
memset(blu_val, 0x00, sizeof( blu_val ));
/*-----------------------------------------------------*\
| Copy red, green, and blue components into buffers |
\*-----------------------------------------------------*/
for(std::size_t color_idx = 0; color_idx < colors.size(); color_idx++)
{
RGBColor color = colors[color_idx];
red_val[keys[color_idx]] = RGBGetRValue(color);
grn_val[keys[color_idx]] = RGBGetGValue(color);
blu_val[keys[color_idx]] = RGBGetBValue(color);
}
/*-----------------------------------------------------*\
| Send red bytes |
\*-----------------------------------------------------*/
StreamPacket(1, 60, &red_val[0]);
StreamPacket(2, 60, &red_val[60]);
StreamPacket(3, 24, &red_val[120]);
SubmitKeyboardFullColors(1, 3, 1);
/*-----------------------------------------------------*\
| Send green bytes |
\*-----------------------------------------------------*/
StreamPacket(1, 60, &grn_val[0]);
StreamPacket(2, 60, &grn_val[60]);
StreamPacket(3, 24, &grn_val[120]);
SubmitKeyboardFullColors(2, 3, 1);
/*-----------------------------------------------------*\
| Send blue bytes |
\*-----------------------------------------------------*/
StreamPacket(1, 60, &blu_val[0]);
StreamPacket(2, 60, &blu_val[60]);
StreamPacket(3, 24, &blu_val[120]);
SubmitKeyboardFullColors(3, 3, 2);
}
void CorsairPeripheralController::SetLEDsMouse(std::vector<RGBColor> colors)
{
SubmitMouseColors(colors.size(), &colors[0]);
}
void CorsairPeripheralController::SetLEDsMousemat(std::vector<RGBColor> colors)
{
SubmitMousematColors(colors.size(), &colors[0]);
}
void CorsairPeripheralController::SetLEDsKeyboardLimited(std::vector<RGBColor> colors)
{
unsigned char data_pkt[216];
unsigned char red_val[144];
unsigned char grn_val[144];
unsigned char blu_val[144];
/*-----------------------------------------------------*\
| Zero out buffers |
\*-----------------------------------------------------*/
memset(data_pkt, 0x00, sizeof( data_pkt ));
memset(red_val, 0x00, sizeof( red_val ));
memset(grn_val, 0x00, sizeof( grn_val ));
memset(blu_val, 0x00, sizeof( blu_val ));
/*-----------------------------------------------------*\
| Scale color values to 9-bit |
\*-----------------------------------------------------*/
for(std::size_t color_idx = 0; color_idx < colors.size(); color_idx++)
{
RGBColor color = colors[color_idx];
unsigned char red = RGBGetRValue(color);
unsigned char grn = RGBGetGValue(color);
unsigned char blu = RGBGetBValue(color);
if( red > 7 ) red = 7;
if( grn > 7 ) grn = 7;
if( blu > 7 ) blu = 7;
red = 7 - red;
grn = 7 - grn;
blu = 7 - blu;
red_val[keys[color_idx]] = red;
grn_val[keys[color_idx]] = grn;
blu_val[keys[color_idx]] = blu;
}
/*-----------------------------------------------------*\
| Pack the color values, 2 values per byte |
\*-----------------------------------------------------*/
for(int red_idx = 0; red_idx < 72; red_idx++)
{
data_pkt[red_idx] = red_val[(red_idx * 2) + 1] << 4 | red_val[red_idx * 2];
}
for(int grn_idx = 0; grn_idx < 72; grn_idx++)
{
data_pkt[grn_idx + 72] = grn_val[(grn_idx * 2) + 1] << 4 | grn_val[grn_idx * 2];
}
for(int blu_idx = 0; blu_idx < 72; blu_idx++)
{
data_pkt[blu_idx + 144] = blu_val[(blu_idx * 2) + 1] << 4 | blu_val[blu_idx * 2];
}
/*-----------------------------------------------------*\
| Send the packets |
\*-----------------------------------------------------*/
StreamPacket(1, 60, &data_pkt[0]);
StreamPacket(2, 60, &data_pkt[60]);
StreamPacket(3, 60, &data_pkt[120]);
StreamPacket(4, 36, &data_pkt[180]);
SubmitKeyboardLimitedColors(216);
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void CorsairPeripheralController::LightingControl()
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
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 and |
| headset stand, 1 for mice and mousepads |
\*-----------------------------------------------------*/
switch(type)
{
default:
case DEVICE_TYPE_KEYBOARD:
usb_buf[0x05] = 0x03;
break;
case DEVICE_TYPE_MOUSE:
usb_buf[0x05] = 0x01;
break;
case DEVICE_TYPE_MOUSEMAT:
usb_buf[0x05] = 0x04;
break;
case DEVICE_TYPE_HEADSET_STAND:
usb_buf[0x05] = 0x03;
break;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void CorsairPeripheralController::SpecialFunctionControl()
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
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 |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void CorsairPeripheralController::ReadFirmwareInfo()
{
int actual;
char usb_buf[65];
char offset = 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;
/*-----------------------------------------------------*\
| Send packet and try reading it using an HID read |
| If that fails, repeat the send and read the reply as |
| a feature report. |
\*-----------------------------------------------------*/
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 or headset stand |
\*-----------------------------------------------------*/
switch((unsigned char)usb_buf[0x14 + offset])
{
case 0xC0:
type = DEVICE_TYPE_KEYBOARD;
break;
case 0xC1:
type = DEVICE_TYPE_MOUSE;
SpecialFunctionControl();
break;
case 0xC2:
{
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:
type = DEVICE_TYPE_UNKNOWN;
break;
}
/*-----------------------------------------------------*\
| Format firmware version string if device type is valid|
\*-----------------------------------------------------*/
if(type != DEVICE_TYPE_UNKNOWN)
{
firmware_version = std::to_string(usb_buf[0x09 + offset]) + "." + std::to_string(usb_buf[0x08 + offset]);
}
}
void CorsairPeripheralController::StreamPacket
(
unsigned char packet_id,
unsigned char data_sz,
unsigned char* data_ptr
)
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Stream packet |
\*-----------------------------------------------------*/
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[0x05], data_ptr, data_sz);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void CorsairPeripheralController::SubmitKeyboardFullColors
(
unsigned char color_channel,
unsigned char packet_count,
unsigned char finish_val
)
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Keyboard 24-Bit Colors packet |
\*-----------------------------------------------------*/
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 |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void CorsairPeripheralController::SubmitKeyboardLimitedColors
(
unsigned char byte_count
)
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Keyboard 9-Bit Colors packet |
\*-----------------------------------------------------*/
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 |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void CorsairPeripheralController::SubmitMouseColors
(
unsigned char num_zones,
RGBColor * color_data
)
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Mouse Colors packet |
\*-----------------------------------------------------*/
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) + 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 |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void CorsairPeripheralController::SubmitMousematColors
(
unsigned char num_zones,
RGBColor * color_data
)
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Mouse Colors packet |
\*-----------------------------------------------------*/
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 <RED> <GREEN> <BLUE> order |
\*-----------------------------------------------------*/
for(unsigned int zone_idx = 0; zone_idx < num_zones; 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 using feature reports, as headset stand |
| seems to not update completely using HID writes |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
@@ -0,0 +1,106 @@
/*-----------------------------------------*\
| CorsairPeripheralController.h |
| |
| Definitions and types for Corsair RGB |
| keyboard, mouse, and mousemat lighting |
| controller |
| |
| Adam Honse (CalcProgrammer1) 1/9/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
CORSAIR_COMMAND_WRITE = 0x07,
CORSAIR_COMMAND_READ = 0x0E,
CORSAIR_COMMAND_STREAM = 0x7F
};
enum
{
CORSAIR_PROPERTY_FIRMWARE_INFO = 0x01,
CORSAIR_PROPERTY_RESET = 0x02,
CORSAIR_PROPERTY_SPECIAL_FUNCTION = 0x04,
CORSAIR_PROPERTY_LIGHTING_CONTROL = 0x05,
CORSAIR_PROPERTY_HARDWARE_PROFILE = 0x13,
CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR = 0x22,
CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_9 = 0x27,
CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_24 = 0x28,
};
enum
{
CORSAIR_LIGHTING_CONTROL_HARDWARE = 0x01,
CORSAIR_LIGHTING_CONTROL_SOFTWARE = 0x02
};
enum
{
CORSAIR_COLOR_CHANNEL_RED = 0x01,
CORSAIR_COLOR_CHANNEL_GREEN = 0x02,
CORSAIR_COLOR_CHANNEL_BLUE = 0x03
};
class CorsairPeripheralController
{
public:
CorsairPeripheralController(hid_device* dev_handle);
~CorsairPeripheralController();
device_type GetDeviceType();
std::string GetFirmwareString();
void SetLEDs(std::vector<RGBColor> colors);
void SetLEDsKeyboardFull(std::vector<RGBColor> colors);
void SetLEDsKeyboardLimited(std::vector<RGBColor> colors);
void SetLEDsMouse(std::vector<RGBColor> colors);
void SetLEDsMousemat(std::vector<RGBColor> colors);
private:
hid_device* dev;
std::string firmware_version;
device_type type;
void LightingControl();
void SpecialFunctionControl();
void ReadFirmwareInfo();
void StreamPacket
(
unsigned char packet_id,
unsigned char data_sz,
unsigned char* data_ptr
);
void SubmitKeyboardFullColors
(
unsigned char color_channel,
unsigned char packet_count,
unsigned char finish_val
);
void SubmitKeyboardLimitedColors
(
unsigned char byte_count
);
void SubmitMouseColors
(
unsigned char num_zones,
RGBColor * color_data
);
void SubmitMousematColors
(
unsigned char num_zones,
RGBColor * color_data
);
};
@@ -0,0 +1,160 @@
#include "CorsairPeripheralController.h"
#include "RGBController.h"
#include "RGBController_CorsairPeripheral.h"
#include <vector>
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| Corsair vendor ID |
\*-----------------------------------------------------*/
#define CORSAIR_VID 0x1B1C
/*-----------------------------------------------------*\
| Keyboard product IDs |
| List taken from ckb-next |
| Non-RGB keyboards were omitted from this list |
\*-----------------------------------------------------*/
#define CORSAIR_K55_RGB_PID 0x1B3D
#define CORSAIR_K65_RGB_PID 0x1B17
#define CORSAIR_K65_LUX_RGB_PID 0x1B37
#define CORSAIR_K65_RGB_RAPIDFIRE_PID 0x1B39
#define CORSAIR_K68_RGB 0x1B4F
#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 0x1B49
#define CORSAIR_K70_RGB_MK2_SE_PID 0x1B6B
#define CORSAIR_K70_RGB_MK2_LP_PID 0x1B55
#define CORSAIR_K95_RGB_PID 0x1B11
#define CORSAIR_K95_PLATINUM_PID 0x1B2D
#define CORSAIR_STRAFE_PID 0x1B20
#define CORSAIR_STRAFE_MK2_PID 0x1B48
/*-----------------------------------------------------*\
| 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
/*-----------------------------------------------------*\
| Mousepad product IDs |
| List taken from ckb-next |
\*-----------------------------------------------------*/
#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;
unsigned short usb_pid;
unsigned char usb_interface;
const char * name;
} corsair_node_device;
#define CORSAIR_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
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" },
{ CORSAIR_VID, CORSAIR_K70_RGB_RAPIDFIRE_PID, 1, "Corsair K70 RGB RAPIDFIRE" },
{ CORSAIR_VID, CORSAIR_K70_RGB_MK2_PID, 1, "Corsair K70 RGB MK.2" },
{ CORSAIR_VID, CORSAIR_K70_RGB_MK2_SE_PID, 1, "Corsair K70 RGB MK.2 SE" },
{ 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" },
/*-----------------------------------------------------------------------------------------------------*\
| Headset Stands |
\*-----------------------------------------------------------------------------------------------------*/
{ CORSAIR_VID, CORSAIR_ST100_PID, 0, "Corsair ST100 RGB" }
};
/******************************************************************************************\
* *
* DetectCorsairPeripheralControllers *
* *
* Tests the USB address to see if a Corsair RGB Keyboard controller exists there. *
* *
\******************************************************************************************/
void DetectCorsairPeripheralControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device_info* info;
hid_device* dev;
hid_init();
for(std::size_t device_idx = 0; device_idx < CORSAIR_NUM_DEVICES; device_idx++)
{
dev = NULL;
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for Corsair RGB Peripheral
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);
if( dev )
{
CorsairPeripheralController* controller = new CorsairPeripheralController(dev);
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);
}
}
}
info = info->next;
}
}
}
@@ -1,127 +0,0 @@
#include "CorsairProController.h"
#include "RGBController.h"
#include "RGBController_CorsairPro.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
/******************************************************************************************\
* *
* TestForCorsairProController *
* *
* Tests the given address to see if a Corsair Pro controller exists there. *
* *
\******************************************************************************************/
bool TestForCorsairProController(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, 0x24);
if (res != 0x02)
{
pass = false;
}
res = bus->i2c_smbus_read_byte_data(address, 0x25);
if (res != 0x02)
{
pass = false;
}
res = bus->i2c_smbus_read_byte_data(address, 0x43);
if (res != 0x1C)
{
pass = false;
}
res = bus->i2c_smbus_read_byte_data(address, 0x44);
if (res != 0x03)
{
pass = false;
}
}
return(pass);
} /* TestForCorsairProController() */
/******************************************************************************************\
* *
* DetectCorsairProControllers *
* *
* Detect Corsair Pro controllers on the enumerated I2C busses. *
* *
* bus - pointer to i2c_smbus_interface where Aura device is connected *
* dev - I2C address of Aura device *
* *
\******************************************************************************************/
void DetectCorsairProControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
CorsairProController* new_corsair_pro;
RGBController_CorsairPro* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Check for Corsair controller at 0x58
if (TestForCorsairProController(busses[bus], 0x58))
{
new_corsair_pro = new CorsairProController(busses[bus], 0x58);
new_controller = new RGBController_CorsairPro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x59
if (TestForCorsairProController(busses[bus], 0x59))
{
new_corsair_pro = new CorsairProController(busses[bus], 0x59);
new_controller = new RGBController_CorsairPro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5A
if (TestForCorsairProController(busses[bus], 0x5A))
{
new_corsair_pro = new CorsairProController(busses[bus], 0x5A);
new_controller = new RGBController_CorsairPro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5B
if (TestForCorsairProController(busses[bus], 0x5B))
{
new_corsair_pro = new CorsairProController(busses[bus], 0x5B);
new_controller = new RGBController_CorsairPro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5C
if (TestForCorsairProController(busses[bus], 0x5C))
{
new_corsair_pro = new CorsairProController(busses[bus], 0x5C);
new_controller = new RGBController_CorsairPro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5D
if (TestForCorsairProController(busses[bus], 0x5D))
{
new_corsair_pro = new CorsairProController(busses[bus], 0x5D);
new_controller = new RGBController_CorsairPro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
}
} /* DetectCorsairProControllers() */
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| CorsairController.h |
| CorsairVengeanceController.h |
| |
| Driver for Corsair Vengeance RGB RAM |
| lighting controller |
@@ -7,10 +7,10 @@
| Adam Honse (CalcProgrammer1) 3/8/2019 |
\*-----------------------------------------*/
#include "CorsairController.h"
#include "CorsairVengeanceController.h"
#include <cstring>
CorsairController::CorsairController(i2c_smbus_interface* bus, corsair_dev_id dev)
CorsairVengeanceController::CorsairVengeanceController(i2c_smbus_interface* bus, corsair_dev_id dev)
{
this->bus = bus;
this->dev = dev;
@@ -19,22 +19,32 @@ CorsairController::CorsairController(i2c_smbus_interface* bus, corsair_dev_id de
led_count = 1;
}
CorsairController::~CorsairController()
CorsairVengeanceController::~CorsairVengeanceController()
{
}
char * CorsairController::GetDeviceName()
std::string CorsairVengeanceController::GetDeviceName()
{
return(device_name);
}
unsigned int CorsairController::GetLEDCount()
std::string CorsairVengeanceController::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 int CorsairVengeanceController::GetLEDCount()
{
return(led_count);
}
void CorsairController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
void CorsairVengeanceController::SetLEDColor(unsigned char red, unsigned char green, unsigned char blue)
{
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_FADE_TIME, 0x00);
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_RED_VAL, red);
@@ -43,16 +53,7 @@ void CorsairController::SetAllColors(unsigned char red, unsigned char green, uns
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_MODE, CORSAIR_VENGEANCE_RGB_MODE_SINGLE);
}
void CorsairController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
void CorsairVengeanceController::SetMode(unsigned char /*mode*/)
{
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_FADE_TIME, 0x00);
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_RED_VAL, red);
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_GREEN_VAL, green);
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_BLUE_VAL, blue);
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_MODE, CORSAIR_VENGEANCE_RGB_MODE_SINGLE);
}
void CorsairController::SetMode(unsigned char mode)
{
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_MODE, CORSAIR_VENGEANCE_RGB_MODE_SINGLE);
}
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| CorsairController.h |
| CorsairVengeanceController.h |
| |
| Definitions and types for Corsair |
| Vengeance RGB RAM lighting controller |
@@ -7,6 +7,7 @@
| Adam Honse (CalcProgrammer1) 3/8/2019 |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
@@ -32,22 +33,22 @@ enum
CORSAIR_NUMBER_MODES /* Number of Corsair modes */
};
class CorsairController
class CorsairVengeanceController
{
public:
CorsairController(i2c_smbus_interface* bus, corsair_dev_id dev);
~CorsairController();
CorsairVengeanceController(i2c_smbus_interface* bus, corsair_dev_id dev);
~CorsairVengeanceController();
char* GetDeviceName();
std::string GetDeviceName();
std::string GetDeviceLocation();
unsigned int GetLEDCount();
void SetMode(unsigned char mode);
void SetAllColors(unsigned char red, unsigned char green, unsigned char blue);
void SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
void SetLEDColor(unsigned char red, unsigned char green, unsigned char blue);
private:
char device_name[32];
unsigned int led_count;
i2c_smbus_interface * bus;
corsair_dev_id dev;
};
};
@@ -1,6 +1,6 @@
#include "CorsairController.h"
#include "CorsairVengeanceController.h"
#include "RGBController.h"
#include "RGBController_Corsair.h"
#include "RGBController_CorsairVengeance.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
@@ -8,13 +8,13 @@
/******************************************************************************************\
* *
* TestForCorsairController *
* TestForCorsairVengeanceController *
* *
* Tests the given address to see if a Corsair controller exists there. *
* *
\******************************************************************************************/
bool TestForCorsairController(i2c_smbus_interface* bus, unsigned char address)
bool TestForCorsairVengeanceController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
@@ -37,11 +37,11 @@ bool TestForCorsairController(i2c_smbus_interface* bus, unsigned char address)
return(pass);
} /* TestForCorsairController() */
} /* TestForCorsairVengeanceController() */
/******************************************************************************************\
* *
* DetectCorsairControllers *
* DetectCorsairVengeanceControllers *
* *
* Detect Corsair controllers on the enumerated I2C busses. *
* *
@@ -50,60 +50,76 @@ bool TestForCorsairController(i2c_smbus_interface* bus, unsigned char address)
* *
\******************************************************************************************/
void DetectCorsairControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
void DetectCorsairVengeanceControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
CorsairController* new_corsair;
RGBController_Corsair* new_controller;
CorsairVengeanceController* new_corsair;
RGBController_CorsairVengeance* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Check for Corsair controller at 0x58
if (TestForCorsairController(busses[bus], 0x58))
if (TestForCorsairVengeanceController(busses[bus], 0x58))
{
new_corsair = new CorsairController(busses[bus], 0x58);
new_controller = new RGBController_Corsair(new_corsair);
new_corsair = new CorsairVengeanceController(busses[bus], 0x58);
new_controller = new RGBController_CorsairVengeance(new_corsair);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x59
if (TestForCorsairController(busses[bus], 0x59))
if (TestForCorsairVengeanceController(busses[bus], 0x59))
{
new_corsair = new CorsairController(busses[bus], 0x59);
new_controller = new RGBController_Corsair(new_corsair);
new_corsair = new CorsairVengeanceController(busses[bus], 0x59);
new_controller = new RGBController_CorsairVengeance(new_corsair);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5A
if (TestForCorsairController(busses[bus], 0x5A))
if (TestForCorsairVengeanceController(busses[bus], 0x5A))
{
new_corsair = new CorsairController(busses[bus], 0x5A);
new_controller = new RGBController_Corsair(new_corsair);
new_corsair = new CorsairVengeanceController(busses[bus], 0x5A);
new_controller = new RGBController_CorsairVengeance(new_corsair);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5B
if (TestForCorsairController(busses[bus], 0x5B))
if (TestForCorsairVengeanceController(busses[bus], 0x5B))
{
new_corsair = new CorsairController(busses[bus], 0x5B);
new_controller = new RGBController_Corsair(new_corsair);
new_corsair = new CorsairVengeanceController(busses[bus], 0x5B);
new_controller = new RGBController_CorsairVengeance(new_corsair);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5C
if (TestForCorsairController(busses[bus], 0x5C))
if (TestForCorsairVengeanceController(busses[bus], 0x5C))
{
new_corsair = new CorsairController(busses[bus], 0x5C);
new_controller = new RGBController_Corsair(new_corsair);
new_corsair = new CorsairVengeanceController(busses[bus], 0x5C);
new_controller = new RGBController_CorsairVengeance(new_corsair);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5D
if (TestForCorsairController(busses[bus], 0x5D))
if (TestForCorsairVengeanceController(busses[bus], 0x5D))
{
new_corsair = new CorsairController(busses[bus], 0x5D);
new_controller = new RGBController_Corsair(new_corsair);
new_corsair = new CorsairVengeanceController(busses[bus], 0x5D);
new_controller = new RGBController_CorsairVengeance(new_corsair);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5E
if (TestForCorsairVengeanceController(busses[bus], 0x5E))
{
new_corsair = new CorsairVengeanceController(busses[bus], 0x5E);
new_controller = new RGBController_CorsairVengeance(new_corsair);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5F
if (TestForCorsairVengeanceController(busses[bus], 0x5F))
{
new_corsair = new CorsairVengeanceController(busses[bus], 0x5F);
new_controller = new RGBController_CorsairVengeance(new_corsair);
rgb_controllers.push_back(new_controller);
}
}
} /* DetectCorsairControllers() */
} /* DetectCorsairVengeanceControllers() */
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| CorsairProController.cpp |
| CorsairVengeanceProController.cpp |
| |
| Definitions and types for Corsair |
| Vengeance Pro RGB RAM lighting controller|
@@ -7,21 +7,12 @@
| Adam Honse (CalcProgrammer1) 6/30/2019 |
\*-----------------------------------------*/
#include "CorsairProController.h"
#include "CorsairVengeanceProController.h"
#include <cstring>
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
using namespace std::chrono_literals;
void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
CorsairProController::CorsairProController(i2c_smbus_interface* bus, corsair_dev_id dev)
CorsairVengeanceProController::CorsairVengeanceProController(i2c_smbus_interface* bus, corsair_dev_id dev)
{
this->bus = bus;
this->dev = dev;
@@ -29,7 +20,9 @@ CorsairProController::CorsairProController(i2c_smbus_interface* bus, corsair_dev
strcpy(device_name, "Corsair Vengeance Pro RGB");
led_count = CORSAIR_PRO_LED_COUNT;
for (int i = 0; i < led_count; i++)
effect_mode = CORSAIR_PRO_MODE_STATIC;
for (unsigned int i = 0; i < led_count; i++)
{
led_red[i] = 0;
led_green[i] = 0;
@@ -37,24 +30,39 @@ CorsairProController::CorsairProController(i2c_smbus_interface* bus, corsair_dev
}
}
CorsairProController::~CorsairProController()
CorsairVengeanceProController::~CorsairVengeanceProController()
{
}
char* CorsairProController::GetDeviceName()
std::string CorsairVengeanceProController::GetDeviceName()
{
return(device_name);
}
unsigned int CorsairProController::GetLEDCount()
std::string CorsairVengeanceProController::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 int CorsairVengeanceProController::GetLEDCount()
{
return(led_count);
}
void CorsairProController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
unsigned char CorsairVengeanceProController::GetEffect()
{
for (int i = 0; i < led_count; i++)
return(effect_mode);
}
void CorsairVengeanceProController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
{
for (unsigned int i = 0; i < led_count; i++)
{
led_red[i] = red;
led_green[i] = green;
@@ -62,19 +70,19 @@ void CorsairProController::SetAllColors(unsigned char red, unsigned char green,
}
}
void CorsairProController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
void CorsairVengeanceProController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
led_red[led] = red;
led_green[led] = green;
led_blue[led] = blue;
}
void CorsairProController::ApplyColors()
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++)
{
@@ -87,24 +95,47 @@ void CorsairProController::ApplyColors()
bus->i2c_smbus_write_byte_data(dev, 0x82, 0x02);
}
void CorsairProController::SetEffect(unsigned char mode)
void CorsairVengeanceProController::SetEffect(unsigned char mode,
unsigned char speed,
unsigned char direction,
bool random,
unsigned char red1,
unsigned char grn1,
unsigned char blu1,
unsigned char red2,
unsigned char grn2,
unsigned char blu2
)
{
bus->i2c_smbus_write_byte_data(dev, 0x26, 0x01);
Sleep(1);
bus->i2c_smbus_write_byte_data(dev, 0x21, 0x00);
Sleep(1);
effect_mode = mode;
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, mode); //Mode
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, CORSAIR_PRO_SPEED_MEDIUM); //Speed
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, CORSAIR_PRO_EFFECT_RANDOM_COLORS); //Custom color
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, CORSAIR_PRO_DIRECTION_UP); //Direction
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 1 red
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 1 green
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 1 blue
bus->i2c_smbus_write_byte_data(dev, 0x26, 0x01);
std::this_thread::sleep_for(1ms);
bus->i2c_smbus_write_byte_data(dev, 0x21, 0x00);
std::this_thread::sleep_for(1ms);
unsigned char random_byte;
if(random)
{
random_byte = CORSAIR_PRO_EFFECT_RANDOM_COLORS;
}
else
{
random_byte = CORSAIR_PRO_EFFECT_CUSTOM_COLORS;
}
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, effect_mode); //Mode
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, speed); //Speed
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, random_byte); //Custom color
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, direction); //Direction
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, red1); // Custom color 1 red
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, grn1); // Custom color 1 green
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, blu1); // Custom color 1 blue
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0xFF);
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 2 red
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 2 green
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 2 blue
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, red2); // Custom color 2 red
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, grn2); // Custom color 2 green
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, blu2); // Custom color 2 blue
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0xFF);
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00);
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00);
@@ -119,19 +150,14 @@ void CorsairProController::SetEffect(unsigned char mode)
WaitReady();
}
void CorsairProController::SetCustom()
{
SetEffect(CORSAIR_PRO_MODE_STATIC);
}
bool CorsairProController::WaitReady()
bool CorsairVengeanceProController::WaitReady()
{
int i = 0;
while (bus->i2c_smbus_read_byte_data(dev, 0x41) != 0x00)
{
i++;
Sleep(1);
std::this_thread::sleep_for(1ms);
}
return false;
}
}
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| CorsairProController.h |
| CorsairVengeanceProController.h |
| |
| Definitions and types for Corsair |
| Vengeance Pro RGB RAM lighting controller|
@@ -7,6 +7,7 @@
| Adam Honse (CalcProgrammer1) 6/30/2019 |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
@@ -59,16 +60,27 @@ enum
CORSAIR_PRO_DIRECTION_HORIZONTAL = 0x03, /* Horizontal direction */
};
class CorsairProController
class CorsairVengeanceProController
{
public:
CorsairProController(i2c_smbus_interface* bus, corsair_dev_id dev);
~CorsairProController();
CorsairVengeanceProController(i2c_smbus_interface* bus, corsair_dev_id dev);
~CorsairVengeanceProController();
char* GetDeviceName();
std::string GetDeviceName();
std::string GetDeviceLocation();
unsigned int GetLEDCount();
void SetEffect(unsigned char mode);
void SetCustom();
unsigned char GetEffect();
void SetEffect(unsigned char mode,
unsigned char speed,
unsigned char direction,
bool random,
unsigned char red1,
unsigned char grn1,
unsigned char blu1,
unsigned char red2,
unsigned char grn2,
unsigned char blu2
);
void SetAllColors(unsigned char red, unsigned char green, unsigned char blue);
void SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
@@ -78,11 +90,11 @@ public:
private:
char device_name[32];
unsigned int led_count;
unsigned char effect_mode;
unsigned char led_red[CORSAIR_PRO_LED_COUNT];
unsigned char led_green[CORSAIR_PRO_LED_COUNT];
unsigned char led_blue[CORSAIR_PRO_LED_COUNT];
i2c_smbus_interface* bus;
corsair_dev_id dev;
};
};
@@ -0,0 +1,133 @@
#include "CorsairVengeanceProController.h"
#include "RGBController.h"
#include "RGBController_CorsairVengeancePro.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std::chrono_literals;
/******************************************************************************************\
* *
* TestForCorsairVengeanceProController *
* *
* Tests the given address to see if a Corsair Pro controller exists there. *
* *
\******************************************************************************************/
bool TestForCorsairVengeanceProController(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, 0x43);
if (res != 0x1C)
{
pass = false;
}
res = bus->i2c_smbus_read_byte_data(address, 0x44);
if (!((res == 0x03) || (res == 0x04)))
{
pass = false;
}
}
std::this_thread::sleep_for(10ms);
return(pass);
} /* TestForCorsairVengeanceProController() */
/******************************************************************************************\
* *
* DetectCorsairVengeanceProControllers *
* *
* Detect Corsair Vengeance Pro controllers on the enumerated I2C busses. *
* *
* bus - pointer to i2c_smbus_interface where Aura device is connected *
* dev - I2C address of Aura device *
* *
\******************************************************************************************/
void DetectCorsairVengeanceProControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
CorsairVengeanceProController* new_corsair_pro;
RGBController_CorsairVengeancePro* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Check for Corsair controller at 0x58
if (TestForCorsairVengeanceProController(busses[bus], 0x58))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x58);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x59
if (TestForCorsairVengeanceProController(busses[bus], 0x59))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x59);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5A
if (TestForCorsairVengeanceProController(busses[bus], 0x5A))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5A);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5B
if (TestForCorsairVengeanceProController(busses[bus], 0x5B))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5B);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5C
if (TestForCorsairVengeanceProController(busses[bus], 0x5C))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5C);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5D
if (TestForCorsairVengeanceProController(busses[bus], 0x5D))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5D);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5E
if (TestForCorsairVengeanceProController(busses[bus], 0x5E))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5E);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5F
if (TestForCorsairVengeanceProController(busses[bus], 0x5F))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5F);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
}
} /* DetectCorsairVengeanceProControllers() */
@@ -0,0 +1,150 @@
/*-----------------------------------------*\
| CrucialController.cpp |
| |
| Driver for Crucial Ballistix RGB lighting|
| controller |
| |
| Adam Honse (CalcProgrammer1) 1/19/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include "CrucialController.h"
#include <cstring>
CrucialController::CrucialController(i2c_smbus_interface* bus, crucial_dev_id dev)
{
this->bus = bus;
this->dev = dev;
}
CrucialController::~CrucialController()
{
}
std::string CrucialController::GetDeviceName()
{
return(device_name);
}
std::string CrucialController::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 int CrucialController::GetLEDCount()
{
return(led_count);
}
void CrucialController::SetMode(unsigned char mode)
{
SendEffectMode(mode, 0x10);
}
void CrucialController::SetAllColorsDirect(RGBColor* colors)
{
SendDirectColors(colors);
}
void CrucialController::SetAllColorsEffect(RGBColor* colors)
{
for(int led_idx = 0; led_idx < 8; led_idx++)
{
unsigned char red = RGBGetRValue(colors[led_idx]);
unsigned char grn = RGBGetGValue(colors[led_idx]);
unsigned char blu = RGBGetBValue(colors[led_idx]);
SendEffectColor(led_idx, red, grn, blu);
}
}
void CrucialController::SendBrightness(unsigned char brightness)
{
CrucialRegisterWrite(0x82EE, 0xFF);
CrucialRegisterWrite(0x82EF, brightness);
CrucialRegisterWrite(0x82F0, 0x83);
}
void CrucialController::SendEffectMode(unsigned char mode, unsigned char speed)
{
CrucialRegisterWrite(0x820F, mode);
CrucialRegisterWrite(0x82EE, 0x00);
CrucialRegisterWrite(0x82EF, speed);
CrucialRegisterWrite(0x82F0, 0x84);
}
void CrucialController::SendDirectColors(RGBColor* color_buf)
{
//Red Channels
CrucialRegisterWrite(0x8300, RGBGetRValue(color_buf[0]));
CrucialRegisterWrite(0x8301, RGBGetRValue(color_buf[1]));
CrucialRegisterWrite(0x8302, RGBGetRValue(color_buf[2]));
CrucialRegisterWrite(0x8303, RGBGetRValue(color_buf[3]));
CrucialRegisterWrite(0x8304, RGBGetRValue(color_buf[4]));
CrucialRegisterWrite(0x8305, RGBGetRValue(color_buf[5]));
CrucialRegisterWrite(0x8306, RGBGetRValue(color_buf[6]));
CrucialRegisterWrite(0x8307, RGBGetRValue(color_buf[7]));
//Green Channels
CrucialRegisterWrite(0x8340, RGBGetGValue(color_buf[0]));
CrucialRegisterWrite(0x8341, RGBGetGValue(color_buf[1]));
CrucialRegisterWrite(0x8342, RGBGetGValue(color_buf[2]));
CrucialRegisterWrite(0x8343, RGBGetGValue(color_buf[3]));
CrucialRegisterWrite(0x8344, RGBGetGValue(color_buf[4]));
CrucialRegisterWrite(0x8345, RGBGetGValue(color_buf[5]));
CrucialRegisterWrite(0x8346, RGBGetGValue(color_buf[6]));
CrucialRegisterWrite(0x8347, RGBGetGValue(color_buf[7]));
//Blue Channels
CrucialRegisterWrite(0x8380, RGBGetBValue(color_buf[0]));
CrucialRegisterWrite(0x8381, RGBGetBValue(color_buf[1]));
CrucialRegisterWrite(0x8382, RGBGetBValue(color_buf[2]));
CrucialRegisterWrite(0x8383, RGBGetBValue(color_buf[3]));
CrucialRegisterWrite(0x8384, RGBGetBValue(color_buf[4]));
CrucialRegisterWrite(0x8385, RGBGetBValue(color_buf[5]));
CrucialRegisterWrite(0x8386, RGBGetBValue(color_buf[6]));
CrucialRegisterWrite(0x8387, RGBGetBValue(color_buf[7]));
}
unsigned char CrucialController::CrucialRegisterRead(crucial_register reg)
{
//Write Crucial register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
//Read Crucial value
return(bus->i2c_smbus_read_byte_data(dev, 0x81));
}
void CrucialController::CrucialRegisterWrite(crucial_register reg, unsigned char val)
{
//Write Crucial register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
//Write Crucial value
bus->i2c_smbus_write_byte_data(dev, 0x01, val);
}
void CrucialController::SendEffectColor
(
unsigned int led_idx,
unsigned int red,
unsigned int green,
unsigned int blue
)
{
CrucialRegisterWrite(0x82E9, (1 << led_idx));
CrucialRegisterWrite(0x82EA, 0x00);
CrucialRegisterWrite(0x82EB, 0x00);
CrucialRegisterWrite(0x82EC, 0x00);
CrucialRegisterWrite(0x82ED, red);
CrucialRegisterWrite(0x82EE, green);
CrucialRegisterWrite(0x82EF, blue);
CrucialRegisterWrite(0x82F0, 0x01);
}
@@ -0,0 +1,70 @@
/*-----------------------------------------*\
| CrucialController.h |
| |
| Definitions and types for Crucial |
| Ballistix RGB lighting controller |
| |
| Adam Honse (CalcProgrammer1) 1/19/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char crucial_dev_id;
typedef unsigned short crucial_register;
enum
{
CRUCIAL_MODE_SHIFT = 0x1F, /* Shift effect mode */
CRUCIAL_MODE_GRADIENT_SHIFT = 0x2F, /* Gradient shift mode */
CRUCIAL_MODE_FILL = 0x3F, /* Fill effect mode */
CRUCIAL_MODE_STACK = 0x4F, /* Stack effect mode */
CRUCIAL_MODE_DOUBLE_STACK = 0x5F, /* Double stack effect mode */
CRUCIAL_MODE_BREATHING = 0x6F, /* Breathing effect mode */
CRUCIAL_MODE_MOTION_POINT = 0x7F, /* Motion point effect mode */
CRUCIAL_MODE_INSIDE_OUT = 0x8F, /* Inside out effect mode */
CRUCIAL_MODE_COLOR_STEP = 0x9F, /* Color step effect mode */
CRUCIAL_MODE_WATER_WAVE = 0xAF, /* Water wave effect mode */
CRUCIAL_MODE_FLASHING = 0xBF, /* Flashing effect mode */
CRUCIAL_MODE_STATIC = 0xCF, /* Static effect mode */
};
class CrucialController
{
public:
CrucialController(i2c_smbus_interface* bus, crucial_dev_id dev);
~CrucialController();
std::string GetDeviceName();
std::string GetDeviceLocation();
unsigned int GetLEDCount();
void SetAllColorsDirect(RGBColor* colors);
void SetAllColorsEffect(RGBColor* colors);
void SetMode(unsigned char mode);
unsigned char CrucialRegisterRead(crucial_register reg);
void CrucialRegisterWrite(crucial_register reg, unsigned char val);
private:
char device_name[16];
unsigned char config_table[64];
unsigned int led_count;
unsigned char channel_cfg;
i2c_smbus_interface * bus;
crucial_dev_id dev;
void SendEffectColor
(
unsigned int led_idx,
unsigned int red,
unsigned int green,
unsigned int blue
);
void SendDirectColors(RGBColor* color_buf);
void SendBrightness(unsigned char brightness);
void SendEffectMode(unsigned char mode, unsigned char speed);
};
@@ -0,0 +1,88 @@
#include "CrucialController.h"
#include "RGBController.h"
#include "RGBController_Crucial.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
/*----------------------------------------------------------------------*\
| This list contains the available SMBus addresses for Crucial RAM |
\*----------------------------------------------------------------------*/
#define CRUCIAL_ADDRESS_COUNT 4
static const unsigned char crucial_addresses[] =
{
0x20,
0x21,
0x22,
0x23
};
/******************************************************************************************\
* *
* TestForCrucialController *
* *
* Tests the given address to see if an Crucial controller exists there. First does a*
* quick write to test for a response, and if so does a simple read at 0xA0 to test *
* for incrementing values 0...F which was observed at this location during data dump *
* *
\******************************************************************************************/
bool TestForCrucialController(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;
for (int i = 0xA0; i < 0xB0; i++)
{
res = bus->i2c_smbus_read_byte_data(address, i);
if (res != (i - 0xA0))
{
pass = false;
}
}
}
return(pass);
} /* TestForCrucialController() */
/******************************************************************************************\
* *
* DetectCrucialControllers *
* *
* Detect Crucial controllers on the enumerated I2C busses. *
* *
* bus - pointer to i2c_smbus_interface where Aura device is connected *
* dev - I2C address of Aura device *
* *
\******************************************************************************************/
void DetectCrucialControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
CrucialController* new_crucial;
RGBController_Crucial* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Add Crucial controllers
for (unsigned int address_list_idx = 0; address_list_idx < CRUCIAL_ADDRESS_COUNT; address_list_idx++)
{
if (TestForCrucialController(busses[bus], crucial_addresses[address_list_idx]))
{
new_crucial = new CrucialController(busses[bus], crucial_addresses[address_list_idx]);
new_controller = new RGBController_Crucial(new_crucial);
rgb_controllers.push_back(new_controller);
}
}
}
} /* DetectCrucialControllers() */
@@ -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);
}
}
@@ -9,128 +9,231 @@
#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
using namespace std::chrono_literals;
HuePlusController::HuePlusController()
{
}
HuePlusController::~HuePlusController()
{
}
void HuePlusController::Initialize(char* ledstring)
void HuePlusController::Initialize(char* port)
{
strcpy(led_string, ledstring);
strcpy(port_name, port);
serialport = new serial_port(port_name, HUE_PLUS_BAUD);
LPSTR source = NULL;
LPSTR channels = NULL;
LPSTR numleds = NULL;
LPSTR next = NULL;
channel_leds[HUE_PLUS_CHANNEL_1_IDX] = GetLEDsOnChannel(HUE_PLUS_CHANNEL_1);
channel_leds[HUE_PLUS_CHANNEL_2_IDX] = GetLEDsOnChannel(HUE_PLUS_CHANNEL_2);
}
source = strtok_s(ledstring, ",", &next);
char* HuePlusController::GetLocation()
{
return(port_name);
}
//Check for selected channel 0=both, 1= Ch.1, 2= Ch.2
if (strlen(next))
unsigned int HuePlusController::GetLEDsOnChannel(unsigned int channel)
{
unsigned char serial_buf[] =
{
channels = strtok_s(next, ",", &next);
0x8D, 0x00, 0x00, 0x00, 0x00
};
unsigned int ret_val = 0;
/*-----------------------------------------------------*\
| Set channel in serial packet |
\*-----------------------------------------------------*/
serial_buf[0x01] = channel;
serialport->serial_flush_rx();
serialport->serial_write((char *)serial_buf, 2);
serialport->serial_flush_tx();
std::this_thread::sleep_for(50ms);
int bytes_read = serialport->serial_read((char *)serial_buf, 5);
if(bytes_read == 5)
{
if(serial_buf[3] == 0x01)
{
ret_val = serial_buf[4] * 8;
}
else
{
ret_val += serial_buf[4] * 10;
}
}
switch (atoi(channels))
return(ret_val);
}
void HuePlusController::SetChannelEffect
(
unsigned char channel,
unsigned char mode,
unsigned char speed,
bool direction,
RGBColor * colors,
unsigned int num_colors
)
{
unsigned char color_data[120];
/*-----------------------------------------------------*\
| If mode requires no colors, send packet |
\*-----------------------------------------------------*/
if(num_colors == 0)
{
case 0:
channel = 0x00;
break;
case 1:
channel = 0x01;
break;
case 2:
channel = 0x02;
break;
/*-----------------------------------------------------*\
| Send mode without color data |
\*-----------------------------------------------------*/
SendPacket(channel, mode, direction, 0, speed, 0, NULL);
}
//Check for the number of LEDs, sets the corresponding variable with the counter for the fans
if (strlen(next))
/*-----------------------------------------------------*\
| If mode requires indexed colors, send color index |
| packets for each mode color |
\*-----------------------------------------------------*/
else if(num_colors <= 8)
{
numleds = strtok_s(next, ",", &next);
for(std::size_t color_idx = 0; color_idx < num_colors; color_idx++)
{
/*-----------------------------------------------------*\
| Fill in color data (40 entries per color) |
\*-----------------------------------------------------*/
for (std::size_t idx = 0; idx < 40; idx++)
{
int pixel_idx = idx * 3;
RGBColor color = colors[color_idx];
color_data[pixel_idx + 0x00] = RGBGetGValue(color);
color_data[pixel_idx + 0x01] = RGBGetRValue(color);
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
}
/*-----------------------------------------------------*\
| Send mode and color data |
\*-----------------------------------------------------*/
SendPacket(channel, mode, direction, color_idx, speed, 40, &color_data[0]);
}
}
switch (atoi(numleds) / 8)
/*-----------------------------------------------------*\
| If mode requires per-LED colors, fill colors array |
\*-----------------------------------------------------*/
else
{
case 1:
fans = 0x00;
break;
/*-----------------------------------------------------*\
| Fill in color data (up to 40 colors) |
\*-----------------------------------------------------*/
for (std::size_t idx = 0; idx < num_colors; idx++)
{
int pixel_idx = idx * 3;
RGBColor color = colors[idx];
color_data[pixel_idx + 0x00] = RGBGetGValue(color);
color_data[pixel_idx + 0x01] = RGBGetRValue(color);
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
}
case 2:
fans = 0x01;
break;
case 3:
fans = 0x02;
break;
case 4:
fans = 0x03;
break;
case 5:
fans = 0x04;
break;
}
//Initialize with default baud rate
source = strtok(source, "\r");
strcpy(port_name, source);
baud_rate = 256000;
serialport = new serial_port(port_name, baud_rate);
if (numleds != NULL && strlen(numleds))
{
num_leds = atoi(numleds);
/*-----------------------------------------------------*\
| Send mode and color data |
\*-----------------------------------------------------*/
SendPacket(channel, mode, direction, 0, speed, num_colors, &color_data[0]);
}
}
char* HuePlusController::GetLEDString()
void HuePlusController::SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
unsigned int num_colors
)
{
return(led_string);
}
unsigned char color_data[120];
void HuePlusController::SetLEDs(std::vector<RGBColor> colors)
{
if (serialport != NULL)
/*-----------------------------------------------------*\
| Fill in color data (up to 40 colors) |
\*-----------------------------------------------------*/
for (std::size_t idx = 0; idx < num_colors; idx++)
{
unsigned char *serial_buf;
serial_buf = new unsigned char[hueSize]; //Size of Message always 5 XX Blocks (Mode Selection) + 3 XX for each LED (1 color)
//-> max of 40 LEDs per Channel (or 5 Fans a 8 LEDs) -> 125 Blocks (empty LEDs are written, too
serial_buf[0] = 0x4b;
serial_buf[1] = channel;
serial_buf[2] = 0x0e;
serial_buf[3] = fans;
serial_buf[4] = 0x00;
for (int i = 5; i < hueSize; i++)
{
//clearing the buf otherwise sometimes strange things are written to the COM Port
serial_buf[i] = 0x00;
}
for (int idx = 0; idx < (num_leds * 3); idx += 3)
{
int pixel_idx = idx / 3;
RGBColor color = colors[pixel_idx];
serial_buf[idx + 5] = RGBGetGValue(color);
serial_buf[idx + 6] = RGBGetRValue(color);
serial_buf[idx + 7] = RGBGetBValue(color);
}
serialport->serial_write((char *)serial_buf, hueSize);
serialport->serial_flush_tx();
delete[] serial_buf;
int pixel_idx = idx * 3;
RGBColor color = colors[idx];
color_data[pixel_idx + 0x00] = RGBGetGValue(color);
color_data[pixel_idx + 0x01] = RGBGetRValue(color);
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
}
}
/*-----------------------------------------------------*\
| Send color data |
\*-----------------------------------------------------*/
SendPacket(channel, HUE_PLUS_MODE_FIXED, false, 0, 0, num_colors, &color_data[0]);
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void HuePlusController::SendPacket
(
unsigned char channel,
unsigned char mode,
bool direction,
unsigned char color_idx,
unsigned char speed,
unsigned char color_count,
unsigned char* color_data
)
{
unsigned char serial_buf[125];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(serial_buf, 0x00, sizeof(serial_buf));
/*-----------------------------------------------------*\
| Set up Direct packet |
\*-----------------------------------------------------*/
serial_buf[0x00] = 0x4B;
/*-----------------------------------------------------*\
| Set channel in serial packet |
\*-----------------------------------------------------*/
serial_buf[0x01] = channel + 1;
/*-----------------------------------------------------*\
| Set mode in serial packet |
\*-----------------------------------------------------*/
serial_buf[0x02] = mode;
/*-----------------------------------------------------*\
| Set options bitfield in serial packet |
\*-----------------------------------------------------*/
serial_buf[0x03] = 0;
serial_buf[0x03] |= direction ? ( 1 << 4 ) : 0;
/*-----------------------------------------------------*\
| Set color index and speed in serial packet |
\*-----------------------------------------------------*/
serial_buf[0x04] = ( color_idx << 5 ) | speed;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
memcpy(&serial_buf[0x05], color_data, color_count * 3);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
serialport->serial_write((char *)serial_buf, HUE_PLUS_PACKET_SIZE);
serialport->serial_flush_tx();
/*-----------------------------------------------------*\
| Delay to allow Hue+ device to ready for next packet |
\*-----------------------------------------------------*/
std::this_thread::sleep_for(20ms);
}
@@ -22,27 +22,91 @@
#define strtok_s strtok_r
#endif
#define HUE_PLUS_BAUD 256000
#define HUE_PLUS_PACKET_SIZE 125
enum
{
HUE_PLUS_CHANNEL_BOTH = 0x00, /* Both channels */
HUE_PLUS_CHANNEL_1 = 0x01, /* Channel 1 */
HUE_PLUS_CHANNEL_2 = 0x02, /* Channel 2 */
HUE_PLUS_NUM_CHANNELS = 0x02 /* Number of channels */
};
enum
{
HUE_PLUS_CHANNEL_1_IDX = 0x00, /* Channel 1 array index */
HUE_PLUS_CHANNEL_2_IDX = 0x01, /* Channel 2 array index */
};
enum
{
HUE_PLUS_SPEED_SLOWEST = 0x00, /* Slowest speed */
HUE_PLUS_SPEED_SLOW = 0x01, /* Slow speed */
HUE_PLUS_SPEED_NORMAL = 0x02, /* Normal speed */
HUE_PLUS_SPEED_FAST = 0x03, /* Fast speed */
HUE_PLUS_SPEED_FASTEST = 0x04, /* Fastest speed */
};
enum
{
HUE_PLUS_MODE_FIXED = 0x00, /* Fixed colors mode */
HUE_PLUS_MODE_FADING = 0x01, /* Fading mode */
HUE_PLUS_MODE_SPECTRUM = 0x02, /* Spectrum cycle mode */
HUE_PLUS_MODE_MARQUEE = 0x03, /* Marquee mode */
HUE_PLUS_MODE_COVER_MARQUEE = 0x04, /* Cover marquee mode */
HUE_PLUS_MODE_ALTERNATING = 0x05, /* Alternating mode */
HUE_PLUS_MODE_PULSING = 0x06, /* Pulsing mode */
HUE_PLUS_MODE_BREATHING = 0x07, /* Breathing mode */
HUE_PLUS_MODE_ALERT = 0x08, /* Alert mode */
HUE_PLUS_MODE_CANDLELIGHT = 0x09, /* Candlelight mode */
HUE_PLUS_MODE_WINGS = 0x0C, /* Wings mode */
HUE_PLUS_MODE_WAVE = 0x0D, /* Wave mode */
};
class HuePlusController
{
public:
HuePlusController();
~HuePlusController();
void Initialize(char* ledstring);
char* GetLEDString();
void SetLEDs(std::vector<RGBColor> colors);
void Initialize(char* port);
char* GetLocation();
unsigned int GetLEDsOnChannel(unsigned int channel);
int num_leds;
void SetChannelEffect
(
unsigned char channel,
unsigned char mode,
unsigned char speed,
bool direction,
RGBColor * colors,
unsigned int num_colors
);
void SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
unsigned int num_colors
);
unsigned int channel_leds[HUE_PLUS_NUM_CHANNELS];
private:
int baud_rate;
int fans;
int channel;
const int hueSize = 125;
char port_name[128];
serial_port *serialport;
char led_string[1024];
char port_name[128];
serial_port *serialport;
void SendPacket
(
unsigned char channel,
unsigned char mode,
bool direction,
unsigned char color_idx,
unsigned char speed,
unsigned char color_count,
unsigned char* color_data
);
};
#endif
@@ -1,27 +1,18 @@
#include "HuePlusController.h"
#include "RGBController.h"
#include "RGBController_HuePlus.h"
#include "find_usb_serial_port.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <fstream>
#include <iostream>
#include <string>
#ifndef WIN32
#include <unistd.h>
#include <dirent.h>
#endif
#define NZXT_HUE_PLUS_VID 0x04D8
#define NZXT_HUE_PLUS_PID 0x00DF
/******************************************************************************************\
* *
* DetectHuePlusControllers *
* *
* Detect devices supported by the HuePlus driver *
* * *
* *
\******************************************************************************************/
void DetectHuePlusControllers(std::vector<RGBController*> &rgb_controllers)
@@ -29,61 +20,13 @@ void DetectHuePlusControllers(std::vector<RGBController*> &rgb_controllers)
HuePlusController* new_hueplus;
RGBController_HuePlus* new_controller;
//Get file path in executable directory
std::ifstream infile;
char filename[2048];
char arg1[64];
#ifdef WIN32
GetModuleFileName(NULL, filename, 2048);
strcpy(filename, std::string(filename).substr(0, std::string(filename).find_last_of("\\/")).c_str());
strcat(filename, "\\settings.txt");
#else
snprintf(arg1, 64, "/proc/%d/exe", getpid());
readlink(arg1, filename, 1024);
strcpy(filename, std::string(filename).substr(0, std::string(filename).find_last_of("\\/")).c_str());
#endif
strcat(filename, "/settings.txt");
//Open settings file
infile.open(filename);
if (infile.good())
std::string portname = find_usb_serial_port(NZXT_HUE_PLUS_VID, NZXT_HUE_PLUS_PID);
if( portname != "" )
{
for (std::string line; std::getline(infile, line); )
{
if (line == "")
{
continue;
}
if ((line[0] != ';') && (line[0] != '#') && (line[0] != '/'))
{
char * argument;
char * value;
new_hueplus = new HuePlusController();
new_hueplus->Initialize((char *)portname.c_str());
value = (char *)line.c_str();
argument = strtok_s(value, "=", &value);
//Strip off new line characters if present
argument = strtok(argument, "\r\n");
value = strtok(value, "\r\n");
if(argument)
{
if (strcmp(argument, "hueplus") == 0)
{
new_hueplus = new HuePlusController();
new_hueplus->Initialize(value);
new_controller = new RGBController_HuePlus(new_hueplus);
rgb_controllers.push_back(new_controller);
}
}
}
}
new_controller = new RGBController_HuePlus(new_hueplus);
rgb_controllers.push_back(new_controller);
}
} /* DetectHuePlusControllers() */
} /* DetectHuePlusControllers() */
@@ -1,102 +0,0 @@
/*-----------------------------------------*\
| HyperXController.cpp |
| |
| Definitions and types for HyperX Predator|
| RGB RAM lighting controller |
| |
| Adam Honse (CalcProgrammer1) 6/29/2019 |
\*-----------------------------------------*/
#include "HyperXController.h"
#include <cstring>
HyperXController::HyperXController(i2c_smbus_interface* bus, hyperx_dev_id dev)
{
this->bus = bus;
this->dev = dev;
strcpy(device_name, "HyperX Predator RGB");
led_count = 1;
}
HyperXController::~HyperXController()
{
}
char* HyperXController::GetDeviceName()
{
return(device_name);
}
unsigned int HyperXController::GetLEDCount()
{
return(led_count);
}
void HyperXController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
{
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_RED, red);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_GREEN, green);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_BLUE, blue);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
}
void HyperXController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_RED, red);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_GREEN, green);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_BLUE, blue);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
}
void HyperXController::SetMode(unsigned char mode)
{
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
switch (mode)
{
case HYPERX_MODE_STATIC:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_STATIC);
break;
case HYPERX_MODE_RAINBOW:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE1, HYPERX_MODE1_RAINBOW);
break;
case HYPERX_MODE_COMET:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_COMET);
break;
case HYPERX_MODE_HEARTBEAT:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_HEARTBEAT);
break;
case HYPERX_MODE_CYCLE:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE1, HYPERX_MODE1_CYCLE);
break;
case HYPERX_MODE_BREATHING:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_BREATHING);
break;
case HYPERX_MODE_BOUNCE:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_BOUNCE);
break;
case HYPERX_MODE_BLINK:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_BLINK);
break;
}
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
}
@@ -1,76 +0,0 @@
/*-----------------------------------------*\
| HyperXController.h |
| |
| Definitions and types for HyperX Predator|
| RGB RAM lighting controller |
| |
| Adam Honse (CalcProgrammer1) 6/29/2019 |
\*-----------------------------------------*/
#include "i2c_smbus.h"
#pragma once
typedef unsigned char hyperx_dev_id;
typedef unsigned short hyperx_register;
enum
{
HYPERX_REG_BRIGHTNESS = 0xDD, /* Brightness control register (0-100) */
HYPERX_REG_APPLY = 0xE1, /* Apply changes register */
HYPERX_REG_MODE1 = 0xE3, /* Mode control register 1 */
HYPERX_REG_MODE2 = 0xE4, /* Mode control register 2 */
HYPERX_REG_RED = 0xEC, /* Red color register */
HYPERX_REG_GREEN = 0xED, /* Green color register */
HYPERX_REG_BLUE = 0xEE, /* Blue color register */
};
enum
{
HYPERX_MODE1_RAINBOW = 0x05, /* Mode 1 rainbow effect */
HYPERX_MODE1_CYCLE = 0x04, /* Mode 1 cycle effect */
};
enum
{
HYPERX_MODE2_BOUNCE = 0x02, /* Mode 2 bounce effect */
HYPERX_MODE2_BREATHING = 0x03, /* Mode 2 breathing effect */
HYPERX_MODE2_BLINK = 0x06, /* Mode 2 blink effect */
HYPERX_MODE2_HEARTBEAT = 0x07, /* Mode 2 heartbeat effect */
HYPERX_MODE2_COMET = 0x08, /* Mode 2 comet effect */
HYPERX_MODE2_STATIC = 0x09, /* Mode 2 static effect */
};
enum
{
HYPERX_MODE_STATIC = 0, /* Static color mode */
HYPERX_MODE_RAINBOW = 1, /* Rainbow wave mode */
HYPERX_MODE_COMET = 2, /* Comet (chase) mode */
HYPERX_MODE_HEARTBEAT = 3, /* Heartbeat (pulsing) mode */
HYPERX_MODE_CYCLE = 4, /* Spectrum cycle mode */
HYPERX_MODE_BREATHING = 5, /* Breathing mode */
HYPERX_MODE_BOUNCE = 6, /* Bounce mode */
HYPERX_MODE_BLINK = 7, /* Blinking mode */
HYPERX_NUMBER_MODES /* Number of HyperX modes */
};
class HyperXController
{
public:
HyperXController(i2c_smbus_interface* bus, hyperx_dev_id dev);
~HyperXController();
char* GetDeviceName();
unsigned int GetLEDCount();
void SetMode(unsigned char mode);
void SetAllColors(unsigned char red, unsigned char green, unsigned char blue);
void SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
private:
char device_name[32];
unsigned int led_count;
i2c_smbus_interface* bus;
hyperx_dev_id dev;
};
@@ -0,0 +1,287 @@
/*-----------------------------------------*\
| HyperXDRAMController.cpp |
| |
| Definitions and types for HyperX Predator|
| and Fury RGB RAM lighting controller |
| |
| Adam Honse (CalcProgrammer1) 6/29/2019 |
\*-----------------------------------------*/
#include "HyperXDRAMController.h"
#include <cstring>
HyperXDRAMController::HyperXDRAMController(i2c_smbus_interface* bus, hyperx_dev_id dev, unsigned char slots)
{
this->bus = bus;
this->dev = dev;
slots_valid = slots;
strcpy(device_name, "HyperX Predator RGB");
led_count = 0;
for(int i = 0; i < 8; i++)
{
if((slots_valid & (1 << i)) != 0)
{
led_count += 5;
}
}
mode = HYPERX_MODE_DIRECT;
}
HyperXDRAMController::~HyperXDRAMController()
{
}
std::string HyperXDRAMController::GetDeviceName()
{
return(device_name);
}
std::string HyperXDRAMController::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 int HyperXDRAMController::GetLEDCount()
{
return(led_count);
}
unsigned int HyperXDRAMController::GetSlotCount()
{
unsigned int slot_count = 0;
for(int slot = 0; slot < 4; slot++)
{
if((slots_valid & (1 << slot)) != 0)
{
slot_count++;
}
}
return(slot_count);
}
unsigned int HyperXDRAMController::GetMode()
{
return(mode);
}
void HyperXDRAMController::SetEffectColor(unsigned char red, unsigned char green, unsigned char blue)
{
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_EFFECT_RED, red );
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_EFFECT_GREEN, green);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_EFFECT_BLUE, blue );
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_EFFECT_BRIGHTNESS, 0x64 );
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
}
void HyperXDRAMController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
{
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
/*-----------------------------------------------------*\
| Loop through all slots and only set those which are |
| active. |
\*-----------------------------------------------------*/
for(int slot = 0; slot < 4; slot++)
{
if((slots_valid & (1 << slot)) != 0)
{
unsigned char base = slot_base[slot];
unsigned char red_base = base + 0x00;
unsigned char green_base = base + 0x01;
unsigned char blue_base = base + 0x02;
unsigned char bright_base = base + 0x10;
if(mode == HYPERX_MODE_DIRECT)
{
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE_INDEPENDENT, HYPERX_MODE3_DIRECT);
}
for(int led = 0; led < 5; led++)
{
bus->i2c_smbus_write_byte_data(dev, red_base + (3 * led), red );
bus->i2c_smbus_write_byte_data(dev, green_base + (3 * led), green);
bus->i2c_smbus_write_byte_data(dev, blue_base + (3 * led), blue );
bus->i2c_smbus_write_byte_data(dev, bright_base + (3 * led), 0x64 );
}
}
}
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
}
void HyperXDRAMController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
/*-----------------------------------------------------*\
| led_slot - the unmapped slot ID for the given LED |
| led - the LED ID within that slot |
| slot_id - counts enabled slots |
| slot - the mapped slot ID for the given LED |
\*-----------------------------------------------------*/
int led_slot = led / 5;
int slot_id = -1;
int slot;
led -= (led_slot * 5);
/*-----------------------------------------------------*\
| Loop through all possible slots and only count those |
| which are active. |
\*-----------------------------------------------------*/
for(slot = 0; slot < 4; slot++)
{
if((slots_valid & ( 1 << slot)) != 0)
{
slot_id++;
}
if(slot_id == led_slot)
{
break;
}
}
unsigned char base = slot_base[slot];
unsigned char red_base = base + 0x00;
unsigned char green_base = base + 0x01;
unsigned char blue_base = base + 0x02;
unsigned char bright_base = base + 0x10;
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
bus->i2c_smbus_write_byte_data(dev, red_base + (3 * led), red );
bus->i2c_smbus_write_byte_data(dev, green_base + (3 * led), green);
bus->i2c_smbus_write_byte_data(dev, blue_base + (3 * led), blue );
bus->i2c_smbus_write_byte_data(dev, bright_base + (3 * led), 0x64 );
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
}
void HyperXDRAMController::SetLEDColor(unsigned int slot, unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char base = slot_base[slot];
unsigned char red_base = base + 0x00;
unsigned char green_base = base + 0x01;
unsigned char blue_base = base + 0x02;
unsigned char bright_base = base + 0x10;
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
bus->i2c_smbus_write_byte_data(dev, red_base + (3 * led), red );
bus->i2c_smbus_write_byte_data(dev, green_base + (3 * led), green);
bus->i2c_smbus_write_byte_data(dev, blue_base + (3 * led), blue );
bus->i2c_smbus_write_byte_data(dev, bright_base + (3 * led), 0x64 );
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
}
void HyperXDRAMController::SetMode(unsigned char new_mode, bool random, unsigned short new_speed)
{
mode = new_mode;
speed = new_speed;
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
/*-----------------------------------------------------*\
| Determine which mode register to use. |
| If set to random color mode, use Mode1. |
| If set to fixed color mode, use Mode2. |
\*-----------------------------------------------------*/
unsigned char mode_reg;
if(random)
{
mode_reg = HYPERX_REG_MODE_RANDOM;
}
else
{
mode_reg = HYPERX_REG_MODE_CUSTOM;
}
switch (mode)
{
case HYPERX_MODE_DIRECT:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE_INDEPENDENT, HYPERX_MODE3_DIRECT);
break;
case HYPERX_MODE_STATIC:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE_CUSTOM, HYPERX_MODE2_STATIC);
break;
case HYPERX_MODE_RAINBOW:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE_RANDOM, HYPERX_MODE1_RAINBOW);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_LSB, speed & 0xFF);
break;
case HYPERX_MODE_COMET:
bus->i2c_smbus_write_byte_data(dev, mode_reg, HYPERX_MODE2_COMET);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_LSB, speed & 0xFF);
break;
case HYPERX_MODE_HEARTBEAT:
bus->i2c_smbus_write_byte_data(dev, mode_reg, HYPERX_MODE2_HEARTBEAT);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_DELAY_TIME_MSB, 0x03);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_DELAY_TIME_LSB, 0xE8);
break;
case HYPERX_MODE_CYCLE:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE_RANDOM, HYPERX_MODE1_CYCLE);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_CHANGE_TIME_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_CHANGE_TIME_LSB, speed & 0xFF);
break;
case HYPERX_MODE_BREATHING:
bus->i2c_smbus_write_byte_data(dev, mode_reg, HYPERX_MODE2_BREATHING);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_FADE_IN_TIME_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_FADE_IN_TIME_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_FADE_OUT_TIME_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_FADE_OUT_TIME_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_MSB, 0x00);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_LSB, 0x00);
break;
case HYPERX_MODE_BOUNCE:
bus->i2c_smbus_write_byte_data(dev, mode_reg, HYPERX_MODE2_BOUNCE);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_LSB, speed & 0xFF);
break;
case HYPERX_MODE_BLINK:
bus->i2c_smbus_write_byte_data(dev, mode_reg, HYPERX_MODE2_BLINK);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_MSB, 0x07);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_LSB, 0xD4);
break;
}
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
}
@@ -0,0 +1,222 @@
/*-----------------------------------------*\
| HyperXDRAMController.h |
| |
| Definitions and types for HyperX Predator|
| and Fury RGB RAM lighting controller |
| |
| Adam Honse (CalcProgrammer1) 6/29/2019 |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char hyperx_dev_id;
typedef unsigned short hyperx_register;
enum
{
HYPERX_REG_SLOT0_LED0_RED = 0x11, /* R color register for LED 0, Slot 0 */
HYPERX_REG_SLOT0_LED0_GREEN = 0x12, /* G color register for LED 0, Slot 0 */
HYPERX_REG_SLOT0_LED0_BLUE = 0x13, /* B color register for LED 0, Slot 0 */
HYPERX_REG_SLOT0_LED1_RED = 0x14, /* R color register for LED 1, Slot 0 */
HYPERX_REG_SLOT0_LED1_GREEN = 0x15, /* G color register for LED 1, Slot 0 */
HYPERX_REG_SLOT0_LED1_BLUE = 0x16, /* B color register for LED 1, Slot 0 */
HYPERX_REG_SLOT0_LED2_RED = 0x17, /* R color register for LED 2, Slot 0 */
HYPERX_REG_SLOT0_LED2_GREEN = 0x18, /* G color register for LED 2, Slot 0 */
HYPERX_REG_SLOT0_LED2_BLUE = 0x19, /* B color register for LED 2, Slot 0 */
HYPERX_REG_SLOT0_LED3_RED = 0x1A, /* R color register for LED 3, Slot 0 */
HYPERX_REG_SLOT0_LED3_GREEN = 0x1B, /* G color register for LED 3, Slot 0 */
HYPERX_REG_SLOT0_LED3_BLUE = 0x1C, /* B color register for LED 3, Slot 0 */
HYPERX_REG_SLOT0_LED4_RED = 0x1D, /* R color register for LED 4, Slot 0 */
HYPERX_REG_SLOT0_LED4_GREEN = 0x1E, /* G color register for LED 4, Slot 0 */
HYPERX_REG_SLOT0_LED4_BLUE = 0x1F, /* B color register for LED 4, Slot 0 */
HYPERX_REG_SLOT0_LED0_BRIGHTNESS = 0x21, /* Brightness for LED 0, Slot 0 (0-100) */
HYPERX_REG_SLOT0_LED1_BRIGHTNESS = 0x24, /* Brightness for LED 1, Slot 0 (0-100) */
HYPERX_REG_SLOT0_LED2_BRIGHTNESS = 0x27, /* Brightness for LED 2, Slot 0 (0-100) */
HYPERX_REG_SLOT0_LED3_BRIGHTNESS = 0x2A, /* Brightness for LED 3, Slot 0 (0-100) */
HYPERX_REG_SLOT0_LED4_BRIGHTNESS = 0x2D, /* Brightness for LED 4, Slot 0 (0-100) */
HYPERX_REG_SLOT1_LED0_RED = 0x41, /* R color register for LED 0, Slot 1 */
HYPERX_REG_SLOT1_LED0_GREEN = 0x42, /* G color register for LED 0, Slot 1 */
HYPERX_REG_SLOT1_LED0_BLUE = 0x43, /* B color register for LED 0, Slot 1 */
HYPERX_REG_SLOT1_LED1_RED = 0x44, /* R color register for LED 1, Slot 1 */
HYPERX_REG_SLOT1_LED1_GREEN = 0x45, /* G color register for LED 1, Slot 1 */
HYPERX_REG_SLOT1_LED1_BLUE = 0x46, /* B color register for LED 1, Slot 1 */
HYPERX_REG_SLOT1_LED2_RED = 0x47, /* R color register for LED 2, Slot 1 */
HYPERX_REG_SLOT1_LED2_GREEN = 0x48, /* G color register for LED 2, Slot 1 */
HYPERX_REG_SLOT1_LED2_BLUE = 0x49, /* B color register for LED 2, Slot 1 */
HYPERX_REG_SLOT1_LED3_RED = 0x4A, /* R color register for LED 3, Slot 1 */
HYPERX_REG_SLOT1_LED3_GREEN = 0x4B, /* G color register for LED 3, Slot 1 */
HYPERX_REG_SLOT1_LED3_BLUE = 0x4C, /* B color register for LED 3, Slot 1 */
HYPERX_REG_SLOT1_LED4_RED = 0x4D, /* R color register for LED 4, Slot 1 */
HYPERX_REG_SLOT1_LED4_GREEN = 0x4E, /* G color register for LED 4, Slot 1 */
HYPERX_REG_SLOT1_LED4_BLUE = 0x4F, /* B color register for LED 4, Slot 1 */
HYPERX_REG_SLOT1_LED0_BRIGHTNESS = 0x51, /* Brightness for LED 0, Slot 1 (0-100) */
HYPERX_REG_SLOT1_LED1_BRIGHTNESS = 0x54, /* Brightness for LED 1, Slot 1 (0-100) */
HYPERX_REG_SLOT1_LED2_BRIGHTNESS = 0x57, /* Brightness for LED 2, Slot 1 (0-100) */
HYPERX_REG_SLOT1_LED3_BRIGHTNESS = 0x5A, /* Brightness for LED 3, Slot 1 (0-100) */
HYPERX_REG_SLOT1_LED4_BRIGHTNESS = 0x5D, /* Brightness for LED 4, Slot 1 (0-100) */
HYPERX_REG_SLOT2_LED0_RED = 0x71, /* R color register for LED 0, Slot 2 */
HYPERX_REG_SLOT2_LED0_GREEN = 0x72, /* G color register for LED 0, Slot 2 */
HYPERX_REG_SLOT2_LED0_BLUE = 0x73, /* B color register for LED 0, Slot 2 */
HYPERX_REG_SLOT2_LED1_RED = 0x74, /* R color register for LED 1, Slot 2 */
HYPERX_REG_SLOT2_LED1_GREEN = 0x75, /* G color register for LED 1, Slot 2 */
HYPERX_REG_SLOT2_LED1_BLUE = 0x76, /* B color register for LED 1, Slot 2 */
HYPERX_REG_SLOT2_LED2_RED = 0x77, /* R color register for LED 2, Slot 2 */
HYPERX_REG_SLOT2_LED2_GREEN = 0x78, /* G color register for LED 2, Slot 2 */
HYPERX_REG_SLOT2_LED2_BLUE = 0x79, /* B color register for LED 2, Slot 2 */
HYPERX_REG_SLOT2_LED3_RED = 0x7A, /* R color register for LED 3, Slot 2 */
HYPERX_REG_SLOT2_LED3_GREEN = 0x7B, /* G color register for LED 3, Slot 2 */
HYPERX_REG_SLOT2_LED3_BLUE = 0x7C, /* B color register for LED 3, Slot 2 */
HYPERX_REG_SLOT2_LED4_RED = 0x7D, /* R color register for LED 4, Slot 2 */
HYPERX_REG_SLOT2_LED4_GREEN = 0x7E, /* G color register for LED 4, Slot 2 */
HYPERX_REG_SLOT2_LED4_BLUE = 0x7F, /* B color register for LED 4, Slot 2 */
HYPERX_REG_SLOT2_LED0_BRIGHTNESS = 0x81, /* Brightness for LED 0, Slot 2 (0-100) */
HYPERX_REG_SLOT2_LED1_BRIGHTNESS = 0x84, /* Brightness for LED 1, Slot 2 (0-100) */
HYPERX_REG_SLOT2_LED2_BRIGHTNESS = 0x87, /* Brightness for LED 2, Slot 2 (0-100) */
HYPERX_REG_SLOT2_LED3_BRIGHTNESS = 0x8A, /* Brightness for LED 3, Slot 2 (0-100) */
HYPERX_REG_SLOT2_LED4_BRIGHTNESS = 0x8D, /* Brightness for LED 4, Slot 2 (0-100) */
HYPERX_REG_SLOT3_LED0_RED = 0xA1, /* R color register for LED 0, Slot 3 */
HYPERX_REG_SLOT3_LED0_GREEN = 0xA2, /* G color register for LED 0, Slot 3 */
HYPERX_REG_SLOT3_LED0_BLUE = 0xA3, /* B color register for LED 0, Slot 3 */
HYPERX_REG_SLOT3_LED1_RED = 0xA4, /* R color register for LED 1, Slot 3 */
HYPERX_REG_SLOT3_LED1_GREEN = 0xA5, /* G color register for LED 1, Slot 3 */
HYPERX_REG_SLOT3_LED1_BLUE = 0xA6, /* B color register for LED 1, Slot 3 */
HYPERX_REG_SLOT3_LED2_RED = 0xA7, /* R color register for LED 2, Slot 3 */
HYPERX_REG_SLOT3_LED2_GREEN = 0xA8, /* G color register for LED 2, Slot 3 */
HYPERX_REG_SLOT3_LED2_BLUE = 0xA9, /* B color register for LED 2, Slot 3 */
HYPERX_REG_SLOT3_LED3_RED = 0xAA, /* R color register for LED 3, Slot 3 */
HYPERX_REG_SLOT3_LED3_GREEN = 0xAB, /* G color register for LED 3, Slot 3 */
HYPERX_REG_SLOT3_LED3_BLUE = 0xAC, /* B color register for LED 3, Slot 3 */
HYPERX_REG_SLOT3_LED4_RED = 0xAD, /* R color register for LED 4, Slot 3 */
HYPERX_REG_SLOT3_LED4_GREEN = 0xAE, /* G color register for LED 4, Slot 3 */
HYPERX_REG_SLOT3_LED4_BLUE = 0xAF, /* B color register for LED 4, Slot 3 */
HYPERX_REG_SLOT3_LED0_BRIGHTNESS = 0xB1, /* Brightness for LED 0, Slot 3 (0-100) */
HYPERX_REG_SLOT3_LED1_BRIGHTNESS = 0xB4, /* Brightness for LED 1, Slot 3 (0-100) */
HYPERX_REG_SLOT3_LED2_BRIGHTNESS = 0xB7, /* Brightness for LED 2, Slot 3 (0-100) */
HYPERX_REG_SLOT3_LED3_BRIGHTNESS = 0xBA, /* Brightness for LED 3, Slot 3 (0-100) */
HYPERX_REG_SLOT3_LED4_BRIGHTNESS = 0xBD, /* Brightness for LED 4, Slot 3 (0-100) */
HYPERX_REG_TIMER_MSB = 0xD1, /* Timer MSB */
HYPERX_REG_TIMER_LSB = 0xD2, /* Timer LSB */
HYPERX_REG_ON_TIME_MSB = 0xD3, /* Effect on time MSB */
HYPERX_REG_ON_TIME_LSB = 0xD4, /* Effect on time LSB */
HYPERX_REG_CHANGE_TIME_MSB = 0xD5, /* Change time MSB */
HYPERX_REG_CHANGE_TIME_LSB = 0xD6, /* Change time LSB */
HYPERX_REG_FADE_IN_TIME_MSB = 0xD7, /* Fade in time MSB */
HYPERX_REG_FADE_IN_TIME_LSB = 0xD8, /* Fade in time LSB */
HYPERX_REG_FADE_OUT_TIME_MSB = 0xD9, /* Fade out time MSB */
HYPERX_REG_FADE_OUT_TIME_LSB = 0xDA, /* Fade out time LSB */
HYPERX_REG_OFF_TIME_MSB = 0xDB, /* Effect off time MSB */
HYPERX_REG_OFF_TIME_LSB = 0xDC, /* Effect off time LSB */
HYPERX_REG_EFFECT_BRIGHTNESS = 0xDD, /* Brightness for effects (0-100) */
HYPERX_REG_APPLY = 0xE1, /* Apply changes register */
HYPERX_REG_MODE_RANDOM = 0xE3, /* Mode control register, random colors */
HYPERX_REG_MODE_CUSTOM = 0xE4, /* Mode control register, custom colors */
HYPERX_REG_MODE_INDEPENDENT = 0xE5, /* Mode control register, independent */
HYPERX_REG_DELAY_TIME_MSB = 0xEA, /* Delay time MSB */
HYPERX_REG_DELAY_TIME_LSB = 0xEB, /* Delay time LSB */
HYPERX_REG_EFFECT_RED = 0xEC, /* Red color register for effects */
HYPERX_REG_EFFECT_GREEN = 0xED, /* Green color register for effects */
HYPERX_REG_EFFECT_BLUE = 0xEE, /* Blue color register for effects */
};
enum
{
HYPERX_MODE1_RAINBOW = 0x05, /* Mode 1 rainbow effect */
HYPERX_MODE1_CYCLE = 0x04, /* Mode 1 cycle effect */
};
enum
{
HYPERX_MODE2_BOUNCE = 0x02, /* Mode 2 bounce effect */
HYPERX_MODE2_BREATHING = 0x03, /* Mode 2 breathing effect */
HYPERX_MODE2_BLINK = 0x06, /* Mode 2 blink effect */
HYPERX_MODE2_HEARTBEAT = 0x07, /* Mode 2 heartbeat effect */
HYPERX_MODE2_COMET = 0x08, /* Mode 2 comet effect */
HYPERX_MODE2_STATIC = 0x09, /* Mode 2 static effect */
};
enum
{
HYPERX_MODE3_DIRECT = 0x21, /* Mode 3 direct control */
};
enum
{
HYPERX_MODE_DIRECT = 0, /* Direct control mode */
HYPERX_MODE_STATIC = 1, /* Static color mode */
HYPERX_MODE_RAINBOW = 2, /* Rainbow wave mode */
HYPERX_MODE_COMET = 3, /* Comet (chase) mode */
HYPERX_MODE_HEARTBEAT = 4, /* Heartbeat (pulsing) mode */
HYPERX_MODE_CYCLE = 5, /* Spectrum cycle mode */
HYPERX_MODE_BREATHING = 6, /* Breathing mode */
HYPERX_MODE_BOUNCE = 7, /* Bounce mode */
HYPERX_MODE_BLINK = 8, /* Blinking mode */
HYPERX_NUMBER_MODES /* Number of HyperX modes */
};
enum
{
HYPERX_SPEED_BOUNCE_SLOW = 0x07D0, /* Slowest speed for bounce mode */
HYPERX_SPEED_BOUNCE_NORMAL = 0x07D0, /* Normal speed for bounce mode */
HYPERX_SPEED_BOUNCE_FAST = 0x0064, /* Fastest speed for bounce mode */
HYPERX_SPEED_BREATHING_SLOW = 0x07D0, /* Slowest speed for breathing mode */
HYPERX_SPEED_BREATHING_NORMAL = 0x07D0, /* Normal speed for breathing mode */
HYPERX_SPEED_BREATHING_FAST = 0x0064, /* Fastest speed for breathing mode */
HYPERX_SPEED_CYCLE_SLOW = 0x05DC, /* Slowest speed for cycle mode */
HYPERX_SPEED_CYCLE_NORMAL = 0x05DC, /* Normal speed for cycle mode */
HYPERX_SPEED_CYCLE_FAST = 0x00FA, /* Fastest speed for cycle mode */
HYPERX_SPEED_RAINBOW_SLOW = 0x07D0, /* Slowest speed for rainbow mode */
HYPERX_SPEED_RAINBOW_NORMAL = 0x07D0, /* Normal speed for rainbow mode */
HYPERX_SPEED_RAINBOW_FAST = 0x0064, /* Fastest speed for rainbow mode */
HYPERX_SPEED_BLINK_SLOW = 0x07D0, /* Slowest speed for blink mode */
HYPERX_SPEED_BLINK_NORMAL = 0x07D0, /* Normal speed for blink mode */
HYPERX_SPEED_BLINK_FAST = 0x01F4, /* Fastest speed for blink mode */
HYPERX_SPEED_HEARTBEAT_SLOW = 0x07D0, /* Slowest speed for heartbeat mode */
HYPERX_SPEED_HEARTBEAT_NORMAL = 0x07D0, /* Normal speed for heartbeat mode */
HYPERX_SPEED_HEARTBEAT_FAST = 0x01F4, /* Fastest speed for heartbeat mode */
HYPERX_SPEED_COMET_SLOW = 0x07D0, /* Slowest speed for comet mode */
HYPERX_SPEED_COMET_NORMAL = 0x07D0, /* Normal speed for comet mode */
HYPERX_SPEED_COMET_FAST = 0x0064, /* Fastest speed for comet mode */
};
static const unsigned char slot_base[4] =
{
HYPERX_REG_SLOT0_LED0_RED, /* SPD 0x50 maps to slot 0 */
HYPERX_REG_SLOT1_LED0_RED, /* SPD 0x51 maps to slot 1 */
HYPERX_REG_SLOT2_LED0_RED, /* SPD 0x52 maps to slot 2 */
HYPERX_REG_SLOT3_LED0_RED /* SPD 0x53 maps to slot 3 */
};
class HyperXDRAMController
{
public:
HyperXDRAMController(i2c_smbus_interface* bus, hyperx_dev_id dev, unsigned char slots);
~HyperXDRAMController();
std::string GetDeviceName();
std::string GetDeviceLocation();
unsigned int GetLEDCount();
unsigned int GetSlotCount();
unsigned int GetMode();
void SetMode(unsigned char new_mode, bool random, unsigned short new_speed);
void SetAllColors(unsigned char red, unsigned char green, unsigned char blue);
void SetEffectColor(unsigned char red, unsigned char green, unsigned char blue);
void SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
void SetLEDColor(unsigned int slot, unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
private:
char device_name[32];
unsigned int led_count;
unsigned char slots_valid;
i2c_smbus_interface* bus;
hyperx_dev_id dev;
unsigned int mode;
unsigned short speed;
};
@@ -0,0 +1,95 @@
#include "HyperXDRAMController.h"
#include "RGBController.h"
#include "RGBController_HyperXDRAM.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std::chrono_literals;
/******************************************************************************************\
* *
* TestForHyperXDRAMController *
* *
* Tests the given address to see if a HyperX controller exists there. *
* *
\******************************************************************************************/
bool TestForHyperXDRAMController(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;
for (int i = 0xA0; i < 0xB0; i++)
{
res = bus->i2c_smbus_read_byte_data(address, i);
if (res != i)
{
pass = false;
}
}
}
return(pass);
} /* TestForHyperXDRAMController() */
/******************************************************************************************\
* *
* DetectHyperXDRAMControllers *
* *
* Detect HyperX DRAM controllers on the enumerated I2C busses. *
* *
* bus - pointer to i2c_smbus_interface where Aura device is connected *
* dev - I2C address of Aura device *
* *
\******************************************************************************************/
void DetectHyperXDRAMControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
HyperXDRAMController* new_hyperx;
RGBController_HyperXDRAM* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
unsigned char slots_valid = 0x00;
// Check for HyperX controller at 0x27
if (TestForHyperXDRAMController(busses[bus], 0x27))
{
busses[bus]->i2c_smbus_write_byte_data(0x37, 0x00, 0xFF);
std::this_thread::sleep_for(1ms);
for(int slot_addr = 0x50; slot_addr <= 0x57; slot_addr++)
{
// Test for HyperX SPD at slot_addr
// This test was copied from NGENUITY software
// Tests SPD addresses in order: 0x40, 0x41
if((busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x40) == 0x01)
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x41) == 0x98))
{
slots_valid |= (1 << (slot_addr - 0x50));
}
std::this_thread::sleep_for(1ms);
}
if(slots_valid != 0)
{
new_hyperx = new HyperXDRAMController(busses[bus], 0x27, slots_valid);
new_controller = new RGBController_HyperXDRAM(new_hyperx);
rgb_controllers.push_back(new_controller);
}
}
}
} /* DetectHyperXDRAMControllers() */
@@ -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
);
};
@@ -0,0 +1,482 @@
/*-----------------------------------------*\
| HyperXKeyboardController.cpp |
| |
| Driver for HyperX RGB Keyboard lighting |
| controller |
| |
| Adam Honse (CalcProgrammer1) 1/30/2020 |
\*-----------------------------------------*/
#include "HyperXKeyboardController.h"
#include <cstring>
using namespace std::chrono_literals;
static unsigned int keys[] = {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,
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 };
static unsigned int extended_blu[] = {0x39, 0x38, 0x68, 0x3A, 0x69, 0x2A, 0x6A, 0x2B, 0x6B, 0x2C, 0x6C, 0x2D, 0x6D, 0x2E, 0x5E, 0x5D, 0x2F, 0x5F, 0x72, 0x33, 0x73, 0x32 };
HyperXKeyboardController::HyperXKeyboardController(hid_device* dev_handle)
{
dev = dev_handle;
}
HyperXKeyboardController::~HyperXKeyboardController()
{
}
void HyperXKeyboardController::SetMode
(
unsigned char mode,
unsigned char direction,
unsigned char speed,
std::vector<RGBColor> colors
)
{
unsigned char color_mode;
unsigned char mode_colors[9];
active_mode = mode;
active_direction = direction;
active_speed = speed;
memset(mode_colors, 0x00, sizeof(mode_colors));
switch(colors.size())
{
default:
case 0:
color_mode = HYPERX_COLOR_MODE_SPECTRUM;
break;
case 1:
color_mode = HYPERX_COLOR_MODE_SINGLE;
mode_colors[0] = RGBGetRValue(colors[0]);
mode_colors[1] = RGBGetGValue(colors[0]);
mode_colors[2] = RGBGetBValue(colors[0]);
break;
case 2:
color_mode = HYPERX_COLOR_MODE_DUAL;
mode_colors[3] = RGBGetRValue(colors[0]);
mode_colors[4] = RGBGetGValue(colors[0]);
mode_colors[5] = RGBGetBValue(colors[0]);
mode_colors[6] = RGBGetRValue(colors[1]);
mode_colors[7] = RGBGetGValue(colors[1]);
mode_colors[8] = RGBGetBValue(colors[1]);
break;
}
SendEffect
(
0x01,
active_mode,
active_direction,
HYPERX_REACTIVE_MODE_NONE,
active_speed,
color_mode,
mode_colors[0],
mode_colors[1],
mode_colors[2],
mode_colors[3],
mode_colors[4],
mode_colors[5],
mode_colors[6],
mode_colors[7],
mode_colors[8]
);
std::this_thread::sleep_for(100ms);
}
void HyperXKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
{
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 < 106; i++)
{
red_color_data[i] = RGBGetRValue(colors[i]);
grn_color_data[i] = RGBGetGValue(colors[i]);
blu_color_data[i] = RGBGetBValue(colors[i]);
}
for(std::size_t i = 0; i < 22; i++)
{
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
(
HYPERX_COLOR_CHANNEL_RED,
red_color_data
);
std::this_thread::sleep_for(5ms);
SendDirect
(
HYPERX_COLOR_CHANNEL_GREEN,
grn_color_data
);
std::this_thread::sleep_for(5ms);
SendDirect
(
HYPERX_COLOR_CHANNEL_BLUE,
blu_color_data
);
std::this_thread::sleep_for(5ms);
SendDirectExtended
(
ext_color_data
);
}
void HyperXKeyboardController::SetLEDs(std::vector<RGBColor> colors)
{
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 < 106; i++)
{
red_color_data[i] = RGBGetRValue(colors[i]);
grn_color_data[i] = RGBGetGValue(colors[i]);
blu_color_data[i] = RGBGetBValue(colors[i]);
}
for(std::size_t i = 0; i < 22; i++)
{
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
(
0x01,
HYPERX_COLOR_CHANNEL_RED,
red_color_data
);
std::this_thread::sleep_for(5ms);
SendColor
(
0x01,
HYPERX_COLOR_CHANNEL_GREEN,
grn_color_data
);
std::this_thread::sleep_for(5ms);
SendColor
(
0x01,
HYPERX_COLOR_CHANNEL_BLUE,
blu_color_data
);
std::this_thread::sleep_for(5ms);
SendExtendedColor
(
0x01,
ext_color_data
);
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void HyperXKeyboardController::SelectProfile
(
unsigned char profile
)
{
unsigned char buf[264];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Select Profile packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x07;
buf[0x01] = 0x01;
buf[0x02] = profile;
buf[0x06] = 0x03;
buf[0x07] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 264);
}
void HyperXKeyboardController::SendEffect
(
unsigned char profile,
unsigned char mode,
unsigned char direction,
unsigned char reactive_mode,
unsigned char speed,
unsigned char color_mode,
unsigned char red_single,
unsigned char grn_single,
unsigned char blu_single,
unsigned char red_dual_1,
unsigned char grn_dual_1,
unsigned char blu_dual_1,
unsigned char red_dual_2,
unsigned char grn_dual_2,
unsigned char blu_dual_2
)
{
unsigned char buf[264];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Effect packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x07;
buf[0x01] = HYPERX_PACKET_ID_SET_EFFECT;
buf[0x02] = profile;
/*-----------------------------------------------------*\
| Set mode |
\*-----------------------------------------------------*/
buf[0x09] = 0x01;
buf[0x0A] = mode;
/*-----------------------------------------------------*\
| Set direction |
\*-----------------------------------------------------*/
buf[0x0D] = direction;
buf[0x0E] = direction;
/*-----------------------------------------------------*\
| Set reactive mode |
\*-----------------------------------------------------*/
buf[0x1B] = reactive_mode;
buf[0x1C] = reactive_mode;
buf[0x1D] = reactive_mode;
buf[0x1E] = reactive_mode;
buf[0x1F] = reactive_mode;
buf[0x20] = reactive_mode;
buf[0x21] = reactive_mode;
buf[0x22] = reactive_mode;
/*-----------------------------------------------------*\
| Set mode-specific colors |
\*-----------------------------------------------------*/
buf[0x29] = red_single;
buf[0x41] = grn_single;
buf[0x59] = blu_single;
buf[0x2A] = red_dual_1;
buf[0x42] = grn_dual_1;
buf[0x5A] = blu_dual_1;
buf[0x2B] = red_dual_2;
buf[0x43] = grn_dual_2;
buf[0x5B] = blu_dual_2;
buf[0x6B] = 0x09;
buf[0x6C] = 0x09;
buf[0x6D] = 0x05;
buf[0x6E] = 0x05;
buf[0x6F] = 0x06;
buf[0x70] = 0x05;
/*-----------------------------------------------------*\
| Set speed |
\*-----------------------------------------------------*/
buf[0x71] = speed;
buf[0x72] = 0x09;
/*-----------------------------------------------------*\
| Set color mode |
\*-----------------------------------------------------*/
buf[0x73] = color_mode;
buf[0x74] = color_mode;
buf[0x75] = color_mode;
buf[0x76] = color_mode;
buf[0x77] = color_mode;
buf[0x78] = color_mode;
buf[0x79] = color_mode;
buf[0x7A] = color_mode;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 264);
}
void HyperXKeyboardController::SendColor
(
unsigned char profile,
unsigned char color_channel,
unsigned char* color_data
)
{
unsigned char buf[264];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Color packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x07;
buf[0x01] = HYPERX_PACKET_ID_SET_COLOR;
buf[0x02] = profile;
buf[0x03] = color_channel;
/*-----------------------------------------------------*\
| Fill in color data |
\*-----------------------------------------------------*/
for(int i = 0; i < 106; i++)
{
buf[keys[i]] = color_data[i];
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 264);
}
void HyperXKeyboardController::SendExtendedColor
(
unsigned char profile,
unsigned char* color_data
)
{
unsigned char buf[264];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Color packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x07;
buf[0x01] = HYPERX_PACKET_ID_SET_COLOR;
buf[0x02] = profile;
buf[0x03] = HYPERX_COLOR_CHANNEL_EXTENDED;
/*-----------------------------------------------------*\
| Fill in color data |
\*-----------------------------------------------------*/
for(int i = 0x08; i <= 0x93; i++)
{
buf[i] = color_data[i];
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 264);
}
void HyperXKeyboardController::SendDirect
(
unsigned char color_channel,
unsigned char* color_data
)
{
unsigned char buf[264];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Direct packet |
\*-----------------------------------------------------*/
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 < 106; i++)
{
buf[keys[i]] = color_data[i];
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 264);
}
void HyperXKeyboardController::SendDirectExtended
(
unsigned char* color_data
)
{
unsigned char buf[264];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Direct packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x07;
buf[0x01] = HYPERX_PACKET_ID_DIRECT;
buf[0x02] = HYPERX_COLOR_CHANNEL_EXTENDED;
buf[0x03] = 0xA0;
/*-----------------------------------------------------*\
| Fill in color data |
\*-----------------------------------------------------*/
for(int i = 0x08; i <= 0x93; i++)
{
buf[i] = color_data[i];
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 264);
}
@@ -0,0 +1,135 @@
/*-----------------------------------------*\
| HyperXKeyboardController.h |
| |
| Definitions and types for HyperX RGB |
| Keyboard lighting controller |
| |
| Adam Honse (CalcProgrammer1) 1/30/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
HYPERX_PACKET_ID_SET_EFFECT = 0x02, /* Set profile effect packet */
HYPERX_PACKET_ID_SET_COLOR = 0x06, /* Set profile color packet */
HYPERX_PACKET_ID_DIRECT = 0x16, /* Direct control packet */
};
enum
{
HYPERX_DIRECTION_RIGHT = 0x00,
HYPERX_DIRECTION_LEFT = 0x01,
HYPERX_DIRECTION_UP = 0x02,
HYPERX_DIRECTION_DOWN = 0x03,
HYPERX_DIRECTION_IN = 0x04,
HYPERX_DIRECTION_OUT = 0x05
};
enum
{
HYPERX_MODE_WAVE = 0x00,
HYPERX_MODE_STATIC = 0x01,
HYPERX_MODE_BREATHING = 0x02,
};
enum
{
HYPERX_REACTIVE_MODE_TRIGGER = 0x03,
HYPERX_REACTIVE_MODE_EXPLOSION = 0x04,
HYPERX_REACTIVE_MODE_HYPERX_FLAME = 0x05,
HYPERX_REACTIVE_MODE_NONE = 0xFF
};
enum
{
HYPERX_COLOR_MODE_SINGLE = 0x00,
HYPERX_COLOR_MODE_DUAL = 0x01,
HYPERX_COLOR_MODE_SPECTRUM = 0x02
};
enum
{
HYPERX_COLOR_CHANNEL_RED = 0x01,
HYPERX_COLOR_CHANNEL_GREEN = 0x02,
HYPERX_COLOR_CHANNEL_BLUE = 0x03,
HYPERX_COLOR_CHANNEL_EXTENDED = 0x04
};
class HyperXKeyboardController
{
public:
HyperXKeyboardController(hid_device* dev_handle);
~HyperXKeyboardController();
void SetMode
(
unsigned char mode,
unsigned char direction,
unsigned char speed,
std::vector<RGBColor> colors
);
void SetLEDsDirect(std::vector<RGBColor> colors);
void SetLEDs(std::vector<RGBColor> colors);
private:
hid_device* dev;
unsigned char active_mode;
unsigned char active_direction;
unsigned char active_speed;
void SelectProfile
(
unsigned char profile
);
void SendEffect
(
unsigned char profile,
unsigned char mode,
unsigned char direction,
unsigned char reactive_mode,
unsigned char speed,
unsigned char color_mode,
unsigned char red_single,
unsigned char grn_single,
unsigned char blu_single,
unsigned char red_dual_1,
unsigned char grn_dual_1,
unsigned char blu_dual_1,
unsigned char red_dual_2,
unsigned char grn_dual_2,
unsigned char blu_dual_2
);
void SendColor
(
unsigned char profile,
unsigned char color_channel,
unsigned char* color_data
);
void SendExtendedColor
(
unsigned char profile,
unsigned char* color_data
);
void SendDirect
(
unsigned char color_channel,
unsigned char* color_data
);
void SendDirectExtended
(
unsigned char* color_data
);
};
@@ -0,0 +1,107 @@
#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" },
};
/******************************************************************************************\
* *
* DetectHyperXKeyboardControllers *
* *
* Tests the USB address to see if a HyperX Keyboard controller exists there. *
* *
\******************************************************************************************/
void DetectHyperXKeyboardControllers(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((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;
}
}
}
@@ -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;
};
@@ -37,12 +37,12 @@ void DetectLEDStripControllers(std::vector<RGBController*> &rgb_controllers)
#ifdef WIN32
GetModuleFileName(NULL, filename, 2048);
strcpy(filename, std::string(filename).substr(0, std::string(filename).find_last_of("\\/")).c_str());
strcat(filename, "\\settings.txt");
strcat(filename, "\\ledstrip.txt");
#else
snprintf(arg1, 64, "/proc/%d/exe", getpid());
readlink(arg1, filename, 1024);
strcpy(filename, std::string(filename).substr(0, std::string(filename).find_last_of("\\/")).c_str());
strcat(filename, "/settings.txt");
strcat(filename, "/ledstrip.txt");
#endif
//Open settings file
@@ -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,78 @@
/*-----------------------------------------*\
| MSI3ZoneController.cpp |
| |
| Driver for MSI/Steelseries 3-Zone |
| Keyboard lighting controller |
| |
| Adam Honse (CalcProgrammer1) 12/25/2019 |
\*-----------------------------------------*/
#include "MSI3ZoneController.h"
MSI3ZoneController::MSI3ZoneController(hid_device* dev_handle)
{
dev = dev_handle;
//strcpy(device_name, "MSI 3-Zone Keyboard");
}
MSI3ZoneController::~MSI3ZoneController()
{
}
char* MSI3ZoneController::GetDeviceName()
{
return device_name;
}
void MSI3ZoneController::SetLEDs(std::vector<RGBColor> colors)
{
//Shout out to bparker06 for reverse engineering the MSI keyboard USB protocol!
// https://github.com/bparker06/msi-keyboard/blob/master/keyboard.cpp for original implementation
unsigned char buf[8] = { 0 };
buf[0] = 1;
buf[1] = 2;
buf[2] = 64;
buf[3] = 1;
buf[4] = RGBGetRValue(colors[0]);
buf[5] = RGBGetGValue(colors[0]);
buf[6] = RGBGetBValue(colors[0]);
buf[7] = 236;
hid_send_feature_report(dev, buf, 8);
buf[3] = 2;
buf[4] = RGBGetRValue(colors[1]);
buf[5] = RGBGetGValue(colors[1]);
buf[6] = RGBGetBValue(colors[1]);
hid_send_feature_report(dev, buf, 8);
buf[3] = 3;
buf[4] = RGBGetRValue(colors[2]);
buf[5] = RGBGetGValue(colors[2]);
buf[6] = RGBGetBValue(colors[2]);
hid_send_feature_report(dev, buf, 8);
buf[3] = 4;
buf[4] = RGBGetRValue(colors[3]);
buf[5] = RGBGetGValue(colors[3]);
buf[6] = RGBGetBValue(colors[3]);
hid_send_feature_report(dev, buf, 8);
buf[3] = 5;
hid_send_feature_report(dev, buf, 8);
buf[3] = 6;
hid_send_feature_report(dev, buf, 8);
buf[3] = 7;
hid_send_feature_report(dev, buf, 8);
}
@@ -0,0 +1,30 @@
/*-----------------------------------------*\
| MSI3ZoneController.h |
| |
| Definitions and types for MSI/Steelseries|
| 3-Zone Keyboard lighting controller |
| |
| Adam Honse (CalcProgrammer1) 12/25/2019 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
class MSI3ZoneController
{
public:
MSI3ZoneController(hid_device* dev_handle);
~MSI3ZoneController();
char* GetDeviceName();
void SetLEDs(std::vector<RGBColor> colors);
private:
char device_name[32];
hid_device* dev;
};
@@ -0,0 +1,36 @@
#include "MSI3ZoneController.h"
#include "RGBController.h"
#include "RGBController_MSI3Zone.h"
#include <vector>
#include <hidapi/hidapi.h>
#define MSI_3_ZONE_KEYBOARD_VID 0x1770
#define MSI_3_ZONE_KEYBOARD_PID 0xFF00
/******************************************************************************************\
* *
* DetectMSI3ZoneControllers *
* *
* Tests the USB address to see if an MSI/SteelSeries 3-zone Keyboard controller *
* exists there. *
* *
\******************************************************************************************/
void DetectMSI3ZoneControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device* dev;
//Look for MSI/Steelseries 3-zone Keyboard
hid_init();
dev = hid_open(MSI_3_ZONE_KEYBOARD_VID, MSI_3_ZONE_KEYBOARD_PID, 0);
if( dev )
{
MSI3ZoneController* controller = new MSI3ZoneController(dev);
RGBController_MSI3Zone* rgb_controller = new RGBController_MSI3Zone(controller);
rgb_controllers.push_back(rgb_controller);
}
}
@@ -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() */
@@ -0,0 +1,580 @@
/*-----------------------------------------*\
| MSIMysticLightController.cpp |
| |
| Driver for MSI Mystic Light USB |
| lighting controller |
| |
| T-bond 3/4/2020 |
\*-----------------------------------------*/
#include "MSIMysticLightController.h"
#include <algorithm>
#include <array>
#include <bitset>
MSIMysticLightController::MSIMysticLightController(hid_device* handle, const char *path)
{
dev = handle;
if(dev)
{
loc = path;
ReadName();
ReadSerial();
ReadFwVersion();
ReadSettings();
}
}
MSIMysticLightController::~MSIMysticLightController()
{
if(dev)
{
hid_close(dev);
}
}
unsigned int MSIMysticLightController::GetZoneMinLedCount
(
MSI_ZONE /*zone*/
)
{
return 1;
}
unsigned int MSIMysticLightController::GetZoneMaxLedCount
(
MSI_ZONE zone
)
{
switch(zone)
{
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 1;
}
}
unsigned int MSIMysticLightController::GetZoneLedCount
(
MSI_ZONE zone
)
{
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
if (!requestedZone)
{
return GetZoneMaxLedCount(zone);
}
return requestedZone->cycle_or_led_num;
}
void MSIMysticLightController::SetZoneLedCount
(
MSI_ZONE zone,
unsigned int led_count
)
{
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
if (!requestedZone)
{
return;
}
led_count = std::min(GetZoneMaxLedCount(zone), std::max(GetZoneMinLedCount(zone), led_count));
requestedZone->cycle_or_led_num = led_count;
}
void MSIMysticLightController::SetMode
(
MSI_ZONE zone,
MSI_MODE mode,
MSI_SPEED speed,
MSI_BRIGHTNESS brightness,
bool rainbow_color
)
{
ZoneData* zoneData = GetZoneData(zone);
if(!zoneData)
{
return;
}
zoneData->effect = mode;
zoneData->speedAndBrightnessFlags = (zoneData->speedAndBrightnessFlags & 128u) | brightness << 2u | speed;
zoneData->colorFlags = BitSet(zoneData->colorFlags, !rainbow_color, 7u);
}
std::string MSIMysticLightController::GetDeviceName()
{
return name;
}
std::string MSIMysticLightController::GetFWVersion()
{
return std::string("AP/LD ").append(version_APROM).append(" / ").append(version_LDROM);
}
std::string MSIMysticLightController::GetDeviceLocation()
{
return loc;
}
std::string MSIMysticLightController::GetSerial()
{
return chip_id;
}
bool MSIMysticLightController::ReadSettings()
{
/*-----------------------------------------------------*\
| Read packet from hardware, return true if successful |
\*-----------------------------------------------------*/
return(hid_get_feature_report(dev, (unsigned char *)&data, sizeof(data)) == sizeof data);
}
bool MSIMysticLightController::Update()
{
/*-----------------------------------------------------*\
| 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)
{
data.save_data = save;
}
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 = red1;
zoneData->color.G = grn1;
zoneData->color.B = blu1;
zoneData->color2.R = red2;
zoneData->color2.G = grn2;
zoneData->color2.B = blu2;
}
std::pair<Color, Color> MSIMysticLightController::GetZoneColor
(
MSI_ZONE zone
)
{
ZoneData *zoneData = GetZoneData(zone);
if (!zoneData)
{
return std::make_pair(Color{}, Color{});
}
return std::make_pair(Color{
zoneData->color.R,
zoneData->color.G,
zoneData->color.B},
Color{zoneData->color2.R, zoneData->color2.G, zoneData->color2.B});
}
ZoneData *MSIMysticLightController::GetZoneData
(
MSI_ZONE zone
)
{
switch(zone)
{
case MSI_ZONE_J_RGB_1:
return &data.j_rgb_1;
case MSI_ZONE_J_RGB_2:
return &data.j_rgb_2;
case MSI_ZONE_J_RAINBOW_1:
return &data.j_rainbow_1;
case MSI_ZONE_J_RAINBOW_2:
return &data.j_rainbow_2;
case MSI_ZONE_J_PIPE_1:
return &data.j_pipe_1;
case MSI_ZONE_J_PIPE_2:
return &data.j_pipe_2;
case MSI_ZONE_ON_BOARD_LED:
return &data.on_board_led;
case MSI_ZONE_ON_BOARD_LED_1:
return &data.on_board_led_1;
case MSI_ZONE_ON_BOARD_LED_2:
return &data.on_board_led_2;
case MSI_ZONE_ON_BOARD_LED_3:
return &data.on_board_led_3;
case MSI_ZONE_ON_BOARD_LED_4:
return &data.on_board_led_4;
case MSI_ZONE_ON_BOARD_LED_5:
return &data.on_board_led_5;
case MSI_ZONE_ON_BOARD_LED_6:
return &data.on_board_led_6;
case MSI_ZONE_ON_BOARD_LED_7:
return &data.on_board_led_7;
case MSI_ZONE_ON_BOARD_LED_8:
return &data.on_board_led_8;
case MSI_ZONE_ON_BOARD_LED_9:
return &data.on_board_led_9;
case MSI_ZONE_J_CORSAIR_OUTERLL120:
return &data.j_corsair_outerll120;
default:
case MSI_ZONE_J_CORSAIR:
break;
}
return nullptr;
}
RainbowZoneData *MSIMysticLightController::GetRainbowZoneData
(
MSI_ZONE zone
)
{
switch(zone)
{
case MSI_ZONE_J_RAINBOW_1:
return &data.j_rainbow_1;
case MSI_ZONE_J_RAINBOW_2:
return &data.j_rainbow_2;
case MSI_ZONE_J_CORSAIR:
default:
return nullptr;
}
}
bool MSIMysticLightController::ReadFwVersion()
{
unsigned char request[64];
unsigned char response[64];
int ret_val = 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] & 0x0F;
/*-----------------------------------------------------*\
| Build firmware string <high>.<low> |
\*-----------------------------------------------------*/
version_APROM = std::to_string(static_cast<int>(highValue)).append(".").append(std::to_string(static_cast<int>(lowValue)));
/*-----------------------------------------------------*\
| First read the LDROM |
| Checksum also available at report ID 184, with MSB |
| stored at index 0x08 and LSB at 0x09 |
\*-----------------------------------------------------*/
/*-----------------------------------------------------*\
| 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)));
/*-----------------------------------------------------*\
| 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());
}
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,
MSI_FAN_TYPE fan_type,
unsigned char corsair_device_quantity,
bool is_LL120Outer_individual
)
{
/*-----------------------------------------------------*\
| 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
)
{
unsigned char packet[64];
std::fill_n(packet, sizeof packet, 204u);
if(main > 100u)
{
main = 100u;
}
if(left > 100u)
{
left = 100u;
}
if(right > 100u)
{
right = 100u;
}
packet[0] = 1u;
packet[1] = 192u;
packet[3] = main;
packet[4] = left;
packet[5] = right;
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
)
{
ZoneData &syncZone = data.on_board_led;
/*-----------------------------------------------------*\
| 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
(
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;
}
/*-----------------------------------------------------*\
| 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
)
{
return static_cast<unsigned char>(std::bitset<8>(value).set(position, bit).to_ulong());
}
void MSIMysticLightController::SetCycleCount
(
MSI_ZONE zone,
unsigned char cycle_num
)
{
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
if (!requestedZone)
{
return;
}
requestedZone->cycle_or_led_num = cycle_num;
}
unsigned char MSIMysticLightController::GetCycleCount
(
MSI_ZONE zone
)
{
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
if (!requestedZone)
{
return 0;
}
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
)
{
ZoneData &syncZone = data.on_board_led;
/*-----------------------------------------------------*\
| 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,
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 & 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;
}
@@ -0,0 +1,316 @@
/*-----------------------------------------*\
| MSIMysticLightController.h |
| |
| Definitions and types for MSI Mystic |
| Light USB lighting controllers |
| |
| T-bond 3/4/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <cstring>
#include <hidapi/hidapi.h>
#include <limits>
#pragma once
enum MSI_ZONE
{
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;
MSI_ZONE value;
};
enum MSI_MODE
{
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 MSI_SPEED
{
MSI_SPEED_LOW = 0,
MSI_SPEED_MEDIUM = 1,
MSI_SPEED_HIGH = 2,
};
enum MSI_FAN_TYPE
{
MSI_FAN_TYPE_SP = 0,
MSI_FAN_TYPE_HD = 1,
MSI_FAN_TYPE_LL = 2,
};
enum MSI_BRIGHTNESS
{
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
{
unsigned char R;
unsigned char G;
unsigned char B;
};
struct CorsairZoneData
{
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;
};
struct ZoneData
{
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 = 20;
};
struct FeaturePacket
{
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
};
class MSIMysticLightController
{
public:
MSIMysticLightController(hid_device* handle, const char *path);
~MSIMysticLightController();
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
);
std::pair<Color, Color>
GetZoneColor(MSI_ZONE zone);
bool Update();
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();
std::string GetFWVersion();
std::string GetSerial();
private:
bool ReadSettings();
void SaveOnUpdate(bool send);
bool ReadFwVersion();
void ReadSerial();
void ReadName();
ZoneData* GetZoneData(MSI_ZONE zone);
RainbowZoneData*
GetRainbowZoneData(MSI_ZONE zone);
static unsigned char BitSet(unsigned char value, bool bit, unsigned int position);
hid_device* dev;
std::string name;
std::string loc;
std::string version_APROM;
std::string version_LDROM;
std::string chip_id;
FeaturePacket data;
};
@@ -0,0 +1,101 @@
#include "MSIMysticLightController.h"
#include "RGBController_MSIMysticLight.h"
#define MSI_USB_VID 0x1462
#define NUM_MSI_PIDS 41
static const unsigned short msi_pid_table[] =
{
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
};
/******************************************************************************************\
* *
* DetectMSIMysticLightControllers *
* *
* Detect MSI Mystic Light devices that use NCT6775 RGB controllers *
* *
\******************************************************************************************/
void DetectMSIMysticLightControllers(std::vector<RGBController*> &rgb_controllers)
{
hid_device_info* info;
hid_device* dev;
hid_init();
for(int device_idx = 0; device_idx < NUM_MSI_PIDS; device_idx++)
{
dev = NULL;
info = hid_enumerate(MSI_USB_VID, msi_pid_table[device_idx]);
//Look for MSI Mystic Light Controller
while(info)
{
if((info->vendor_id == MSI_USB_VID)
&&(info->product_id == msi_pid_table[device_idx]))
{
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
if( dev )
{
MSIMysticLightController * controller = new MSIMysticLightController(dev, info->path);
RGBController_MSIMysticLight * rgb_controller = new RGBController_MSIMysticLight(controller);
rgb_controllers.push_back(rgb_controller);
}
}
}
@@ -0,0 +1,99 @@
/*-----------------------------------------*\
| MSIRGBController.cpp |
| |
| Driver for MSI-RGB lighting controller |
| |
| Logic adapted from: |
| https://github.com/nagisa/msi-rgb |
| |
| Adam Honse (CalcProgrammer1) 2/11/2020 |
\*-----------------------------------------*/
#include "MSIRGBController.h"
#include "super_io.h"
MSIRGBController::MSIRGBController(int sioaddr)
{
msi_sioaddr = sioaddr;
/*-----------------------------------------------------*\
| This setup step isn't well documented |
| Without this, pulsing does not work |
\*-----------------------------------------------------*/
superio_outb(msi_sioaddr, SIO_REG_LOGDEV, 0x09);
int val_at_2c = superio_inb(msi_sioaddr, 0x2C);
val_at_2c &= 0b11110111;
val_at_2c |= 0b00010000;
superio_outb(msi_sioaddr, 0x2C, val_at_2c);
/*-----------------------------------------------------*\
| Set logical device register to RGB controller |
\*-----------------------------------------------------*/
superio_outb(msi_sioaddr, SIO_REG_LOGDEV, MSI_SIO_LOGDEV_RGB);
/*-----------------------------------------------------*\
| Test if RGB is enabled. If it is not, enable it. |
\*-----------------------------------------------------*/
int enable = superio_inb(msi_sioaddr, MSI_SIO_RGB_REG_ENABLE);
if((enable & MSI_SIO_RGB_ENABLE_MASK) != MSI_SIO_RGB_ENABLE_MASK)
{
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_ENABLE, MSI_SIO_RGB_ENABLE_MASK & (enable & !MSI_SIO_RGB_ENABLE_MASK));
}
/*-----------------------------------------------------*\
| Lighting enabled, no pulsing or blinking |
\*-----------------------------------------------------*/
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_CFG_1, 0x00);
/*-----------------------------------------------------*\
| Lighting enabled, RGB non-inverted, header on |
\*-----------------------------------------------------*/
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_CFG_3, 0xE2);
}
MSIRGBController::~MSIRGBController()
{
}
void MSIRGBController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
{
/*-----------------------------------------------------*\
| The MSI RGB controller uses 4 bits per color rather |
| than 8. Shift the values by 4 so that the 4 most |
| significant bits of each color are the new color value|
\*-----------------------------------------------------*/
red = red >> 4;
green = green >> 4;
blue = blue >> 4;
/*-----------------------------------------------------*\
| Set logical device register to RGB controller |
\*-----------------------------------------------------*/
superio_outb(msi_sioaddr, SIO_REG_LOGDEV, MSI_SIO_LOGDEV_RGB);
/*-----------------------------------------------------*\
| Write the colors to the color sequence registers |
| Only static mode is supported right now - all colors |
| are the same. |
\*-----------------------------------------------------*/
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_1_0, (red | (red << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_3_2, (red | (red << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_5_4, (red | (red << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_7_6, (red | (red << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_1_0, (green | (green << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_3_2, (green | (green << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_5_4, (green | (green << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_7_6, (green | (green << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_1_0, (blue | (blue << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_3_2, (blue | (blue << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_5_4, (blue | (blue << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_7_6, (blue | (blue << 4)));
}
@@ -0,0 +1,56 @@
/*-----------------------------------------*\
| MSIRGBController.h |
| |
| Definitions and types for MSI-RGB |
| lighting controller |
| |
| Logic adapted from: |
| https://github.com/nagisa/msi-rgb |
| |
| Adam Honse (CalcProgrammer1) 2/11/2020 |
\*-----------------------------------------*/
#include <string>
#pragma once
#define MSI_SIO_LOGDEV_RGB 0x12
enum
{
MSI_SIO_RGB_REG_ENABLE = 0xE0,
MSI_SIO_RGB_REG_CFG_1 = 0xE4,
MSI_SIO_RGB_REG_RED_1_0 = 0xF0,
MSI_SIO_RGB_REG_RED_3_2 = 0xF1,
MSI_SIO_RGB_REG_RED_5_4 = 0xF2,
MSI_SIO_RGB_REG_RED_7_6 = 0xF3,
MSI_SIO_RGB_REG_GREEN_1_0 = 0xF4,
MSI_SIO_RGB_REG_GREEN_3_2 = 0xF5,
MSI_SIO_RGB_REG_GREEN_5_4 = 0xF6,
MSI_SIO_RGB_REG_GREEN_7_6 = 0xF7,
MSI_SIO_RGB_REG_BLUE_1_0 = 0xF8,
MSI_SIO_RGB_REG_BLUE_3_2 = 0xF9,
MSI_SIO_RGB_REG_BLUE_5_4 = 0xFA,
MSI_SIO_RGB_REG_BLUE_7_6 = 0xFB,
MSI_SIO_RGB_REG_CFG_2 = 0xFE,
MSI_SIO_RGB_REG_CFG_3 = 0xFF,
};
#define MSI_SIO_RGB_ENABLE_MASK 0xE0
class MSIRGBController
{
public:
MSIRGBController(int sioaddr);
~MSIRGBController();
std::string GetDeviceName();
std::string GetDeviceLocation();
unsigned int GetMode();
void SetMode(unsigned char new_mode, unsigned char new_speed);
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
private:
int msi_sioaddr;
};
@@ -0,0 +1,40 @@
#include "MSIRGBController.h"
#include "RGBController.h"
#include "RGBController_MSIRGB.h"
#include "super_io.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
/******************************************************************************************\
* *
* DetectMSIRGBControllers *
* *
* Detect MSI-RGB compatible Super-IO chips. *
* *
\******************************************************************************************/
void DetectMSIRGBControllers(std::vector<RGBController*> &rgb_controllers)
{
int sio_addrs[2] = {0x2E, 0x4E};
for(int sioaddr_idx = 0; sioaddr_idx < 2; sioaddr_idx++)
{
int sioaddr = sio_addrs[sioaddr_idx];
superio_enter(sioaddr);
int val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) | superio_inb(sioaddr, SIO_REG_DEVID + 1);
switch (val & SIO_ID_MASK)
{
case SIO_NCT6795_ID:
case SIO_NCT6797_ID:
MSIRGBController* new_msi = new MSIRGBController(sioaddr);
RGBController_MSIRGB* new_rgb = new RGBController_MSIRGB(new_msi);
rgb_controllers.push_back(new_rgb);
break;
}
}
} /* DetectMSIRGBControllers() */
@@ -0,0 +1,417 @@
/*---------------------------------------------------------*\
| Processing Code for NZXT Hue 2 |
| |
| Adam Honse ([email protected]), 12/29/2016 |
\*---------------------------------------------------------*/
#include "NZXTHue2Controller.h"
#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
NZXTHue2Controller::NZXTHue2Controller(hid_device* dev_handle, unsigned int rgb_channels, unsigned int fan_channels)
{
dev = dev_handle;
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();
}
NZXTHue2Controller::~NZXTHue2Controller()
{
}
unsigned char NZXTHue2Controller::GetFanCommand
(
unsigned char fan_channel
)
{
return(fan_cmd[fan_channel]);
}
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
{
ret_val = hid_read(dev, usb_buf, sizeof(usb_buf));
} while( (ret_val != 64) || (usb_buf[0] != 0x21) || (usb_buf[1] != 0x03) );
for(int chan = 0; chan < num_rgb_channels; chan++)
{
unsigned int start = 0x0F + (6 * chan);
unsigned int num_leds_on_channel = 0;
for(int dev = 0; dev < 6; dev++)
{
switch(usb_buf[start + dev])
{
case 0x01: //Hue 1 strip
num_leds_on_channel += 10;
break;
case 0x02: //Aer 1 fan
num_leds_on_channel += 8;
break;
case 0x04: //Hue 2 strip
num_leds_on_channel += 10;
break;
case 0x0B: //Aer 2 fan (120mm)
num_leds_on_channel += 8;
break;
case 0x0C: //Aer 2 fan (140mm)
num_leds_on_channel += 8;
break;
default:
break;
}
}
channel_leds[chan] = num_leds_on_channel;
}
}
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,
unsigned char speed,
bool direction,
RGBColor * colors,
unsigned int num_colors
)
{
unsigned char color_data[24];
/*-----------------------------------------------------*\
| Fill in color data (up to 8 colors) |
\*-----------------------------------------------------*/
for (std::size_t idx = 0; idx < num_colors; idx++)
{
int pixel_idx = idx * 3;
RGBColor color = colors[idx];
color_data[pixel_idx + 0x00] = RGBGetGValue(color);
color_data[pixel_idx + 0x01] = RGBGetRValue(color);
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
}
/*-----------------------------------------------------*\
| Send effect packet |
\*-----------------------------------------------------*/
SendEffect(channel, mode, speed, direction, num_colors, &color_data[0]);
}
void NZXTHue2Controller::SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
unsigned int num_colors
)
{
unsigned char color_data[120];
/*-----------------------------------------------------*\
| Fill in color data (up to 40 colors) |
\*-----------------------------------------------------*/
for (std::size_t idx = 0; idx < num_colors; idx++)
{
int pixel_idx = idx * 3;
RGBColor color = colors[idx];
color_data[pixel_idx + 0x00] = RGBGetGValue(color);
color_data[pixel_idx + 0x01] = RGBGetRValue(color);
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
}
/*-----------------------------------------------------*\
| Send first group of color data |
\*-----------------------------------------------------*/
SendDirect(channel, 0, 20, &color_data[0]);
/*-----------------------------------------------------*\
| Send second group of color data if necessary |
\*-----------------------------------------------------*/
if(num_colors > 20)
{
SendDirect(channel, 1, 20, &color_data[60]);
}
/*-----------------------------------------------------*\
| Send apply packet |
\*-----------------------------------------------------*/
SendApply(channel);
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void NZXTHue2Controller::SendApply
(
unsigned char channel
)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Apply packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x22;
usb_buf[0x01] = 0xA0;
usb_buf[0x02] = (unsigned char)(1 << channel);
usb_buf[0x04] = 0x01;
usb_buf[0x07] = 0x28;
usb_buf[0x0A] = 0x80;
usb_buf[0x0C] = 0x32;
usb_buf[0x0F] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
//hid_read(dev, usb_buf, 64);
}
void NZXTHue2Controller::SendDirect
(
unsigned char channel,
unsigned char group,
unsigned char color_count,
unsigned char* color_data
)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Direct packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x22;
usb_buf[0x01] = 0x10 | group;
usb_buf[0x02] = (unsigned char)(1 << channel);
usb_buf[0x03] = 0x00;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x04], color_data, color_count * 3);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
//hid_read(dev, usb_buf, 64);
}
void NZXTHue2Controller::SendEffect
(
unsigned char channel,
unsigned char mode,
unsigned char speed,
bool direction,
unsigned char color_count,
unsigned char* color_data
)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Effect packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x28;
usb_buf[0x01] = 0x03;
usb_buf[0x02] = (unsigned char)(1 << channel);
usb_buf[0x03] = 0x28;
/*-----------------------------------------------------*\
| Set mode in USB packet |
\*-----------------------------------------------------*/
usb_buf[0x04] = mode;
/*-----------------------------------------------------*\
| Set speed in USB packet |
\*-----------------------------------------------------*/
usb_buf[0x05] = speed;
/*-----------------------------------------------------*\
| Set direction in USB packet |
\*-----------------------------------------------------*/
usb_buf[0x06] = direction ? 0x01 : 0x00;
/*-----------------------------------------------------*\
| Set color count in USB packet |
\*-----------------------------------------------------*/
usb_buf[0x08] = color_count;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x0A], color_data, color_count * 3);
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]);
}
@@ -0,0 +1,140 @@
/*---------------------------------------------------------*\
| Definitions for NZXT Hue 2 |
| |
| Adam Honse ([email protected]), 12/29/2016 |
\*---------------------------------------------------------*/
#include "RGBController.h"
#include <string>
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
enum
{
HUE_2_CHANNEL_ALL = 0x00, /* All channels */
HUE_2_CHANNEL_1 = 0x01, /* Channel 1 */
HUE_2_CHANNEL_2 = 0x02, /* Channel 2 */
HUE_2_CHANNEL_3 = 0x03, /* Channel 3 */
HUE_2_CHANNEL_4 = 0x04, /* Channel 4 */
HUE_2_NUM_CHANNELS = 0x04 /* Number of channels */
};
enum
{
HUE_2_CHANNEL_1_IDX = 0x00, /* Channel 1 array index */
HUE_2_CHANNEL_2_IDX = 0x01, /* Channel 2 array index */
HUE_2_CHANNEL_3_IDX = 0x01, /* Channel 3 array index */
HUE_2_CHANNEL_4_IDX = 0x01, /* Channel 4 array index */
};
enum
{
HUE_2_SPEED_SLOWEST = 0x00, /* Slowest speed */
HUE_2_SPEED_SLOW = 0x01, /* Slow speed */
HUE_2_SPEED_NORMAL = 0x02, /* Normal speed */
HUE_2_SPEED_FAST = 0x03, /* Fast speed */
HUE_2_SPEED_FASTEST = 0x04, /* Fastest speed */
};
enum
{
HUE_2_MODE_FIXED = 0x00, /* Fixed colors mode */
HUE_2_MODE_FADING = 0x01, /* Fading mode */
HUE_2_MODE_SPECTRUM = 0x02, /* Spectrum cycle mode */
HUE_2_MODE_MARQUEE = 0x03, /* Marquee mode */
HUE_2_MODE_COVER_MARQUEE = 0x04, /* Cover marquee mode */
HUE_2_MODE_ALTERNATING = 0x05, /* Alternating mode */
HUE_2_MODE_PULSING = 0x06, /* Pulsing mode */
HUE_2_MODE_BREATHING = 0x07, /* Breathing mode */
HUE_2_NUM_MODES /* Number of Hue 2 modes */
};
class NZXTHue2Controller
{
public:
NZXTHue2Controller(hid_device* dev_handle, unsigned int rgb_channels, unsigned int fan_channels);
~NZXTHue2Controller();
std::string GetFirmwareVersion();
unsigned char GetFanCommand
(
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
(
unsigned char channel,
unsigned char mode,
unsigned char speed,
bool direction,
RGBColor * colors,
unsigned int num_colors
);
void SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
unsigned int num_colors
);
void UpdateDeviceList();
void UpdateStatus();
unsigned int channel_leds[HUE_2_NUM_CHANNELS];
private:
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
(
unsigned char channel
);
void SendDirect
(
unsigned char channel,
unsigned char group,
unsigned char color_count,
unsigned char* color_data
);
void SendEffect
(
unsigned char channel,
unsigned char mode,
unsigned char speed,
bool direction,
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() */
@@ -0,0 +1,174 @@
/*---------------------------------------------------------*\
| Driver for NZXT Kraken |
| |
| Martin Hartl (inlart), 04/04/2020 |
\*---------------------------------------------------------*/
#include "NZXTKrakenController.h"
#include <string>
#include <sstream>
#include <cstring>
static void SetColor(const std::vector<RGBColor>& colors, unsigned char* color_data)
{
for (std::size_t idx = 0; idx < colors.size(); idx++)
{
int pixel_idx = idx * 3;
RGBColor color = colors[idx];
color_data[pixel_idx + 0x00] = RGBGetRValue(color);
color_data[pixel_idx + 0x01] = RGBGetGValue(color);
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
}
}
static RGBColor ToLogoColor(RGBColor rgb)
{
return ToRGBColor(RGBGetGValue(rgb), RGBGetRValue(rgb), RGBGetBValue(rgb));
}
NZXTKrakenController::NZXTKrakenController(hid_device* dev_handle)
{
dev = dev_handle;
/*-----------------------------------------------------*\
| Get the firmware version |
\*-----------------------------------------------------*/
UpdateStatus();
}
NZXTKrakenController::~NZXTKrakenController()
{
hid_close(dev);
}
std::string NZXTKrakenController::GetFirmwareVersion()
{
return firmware_version;
}
void NZXTKrakenController::UpdateStatus()
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Read packet |
\*-----------------------------------------------------*/
hid_read(dev, usb_buf, 64);
/*-----------------------------------------------------*\
| Extract cooler information |
\*-----------------------------------------------------*/
liquid_temperature = usb_buf[0x1] + (usb_buf[0x2] * 0.1);
fan_speed = usb_buf[0x3] << 8 | usb_buf[0x4];
pump_speed = usb_buf[0x5] << 8 | usb_buf[0x6];
/*-----------------------------------------------------*\
| Extract firmware version |
\*-----------------------------------------------------*/
int major = usb_buf[0xb];
int minor = usb_buf[0xc] << 8 | usb_buf[0xd];
int patch = usb_buf[0xe];
std::stringstream ss;
ss << major << '.' << minor << '.' << patch;
firmware_version = ss.str();
}
void NZXTKrakenController::UpdateEffect
(
NZXTKrakenChannel_t channel,
unsigned char mode,
bool direction,
unsigned char speed,
int seq,
std::vector<RGBColor> colors
)
{
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);
}
void NZXTKrakenController::SendEffect
(
unsigned char channel,
unsigned char mode,
bool direction,
unsigned char* color_data,
unsigned char speed /* = 0x02 */,
bool movement /* = false */,
int cis /* = 0 */,
int size /* = 0 */
)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set effect mode |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x02;
usb_buf[0x01] = 0x4c;
/*-----------------------------------------------------*\
| Set effect channel, movement and direction |
\*-----------------------------------------------------*/
usb_buf[0x02] = channel;
usb_buf[0x02] |= movement ? ( 1 << 3 ) : 0;
usb_buf[0x02] |= direction ? ( 1 << 4 ) : 0;
/*-----------------------------------------------------*\
| Set mode |
\*-----------------------------------------------------*/
usb_buf[0x03] = mode;
/*-----------------------------------------------------*\
| Set effect speed, size and color in set |
\*-----------------------------------------------------*/
usb_buf[0x04] = speed;
usb_buf[0x04] |= size << 3;
usb_buf[0x04] |= cis << 5;
/*-----------------------------------------------------*\
| Copy color data bytes |
\*-----------------------------------------------------*/
if(color_data)
{
memcpy(usb_buf + 0x05, color_data, 9 * 3);
}
/*-----------------------------------------------------*\
| Send effect |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
}
@@ -0,0 +1,86 @@
/*---------------------------------------------------------*\
| Definitions for NZXT Kraken |
| |
| Martin Hartl (inlart), 04/04/2020 |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include <vector>
#include <string>
#include <hidapi/hidapi.h>
enum NZXTKrakenChannel_t
{
NZXT_KRAKEN_CHANNEL_SYNC = 0x00, /* Sync Channel */
NZXT_KRAKEN_CHANNEL_LOGO = 0x01, /* Logo Channel */
NZXT_KRAKEN_CHANNEL_RING = 0x02, /* Ring Channel */
};
enum
{
NZXT_KRAKEN_MODE_FIXED = 0x00, /* Fixed colors mode */
NZXT_KRAKEN_MODE_FADING = 0x01, /* Fading mode */
NZXT_KRAKEN_MODE_SPECTRUM = 0x02, /* Spectrum cycle mode */
NZXT_KRAKEN_MODE_MARQUEE = 0x03, /* Marquee mode */
NZXT_KRAKEN_MODE_COVER_MARQUEE = 0x04, /* Cover marquee mode */
NZXT_KRAKEN_MODE_ALTERNATING = 0x05, /* Alternating mode */
NZXT_KRAKEN_MODE_BREATHING = 0x06, /* Breathing mode */
NZXT_KRAKEN_MODE_PULSE = 0x07, /* Pulse mode */
NZXT_KRAKEN_MODE_TAI_CHI = 0x08, /* Tai Chi mode */
NZXT_KRAKEN_MODE_WATER_COOLER = 0x09, /* Water color mode */
NZXT_KRAKEN_MODE_LOADING = 0x0a, /* Loading mode */
NZXT_KRAKEN_MODE_WINGS = 0x0c, /* Wings mode */
};
enum
{
NZXT_KRAKEN_SPEED_SLOWEST = 0x00, /* Slowest speed */
NZXT_KRAKEN_SPEED_SLOW = 0x01, /* Slow speed */
NZXT_KRAKEN_SPEED_NORMAL = 0x02, /* Normal speed */
NZXT_KRAKEN_SPEED_FAST = 0x03, /* Fast speed */
NZXT_KRAKEN_SPEED_FASTEST = 0x04, /* Fastest speed */
};
class NZXTKrakenController
{
public:
NZXTKrakenController(hid_device* dev_handle);
~NZXTKrakenController();
std::string GetFirmwareVersion();
void UpdateEffect
(
NZXTKrakenChannel_t channel,
unsigned char mode,
bool direction,
unsigned char speed,
int seq,
std::vector<RGBColor> colors
);
private:
void UpdateStatus();
void SendEffect
(
unsigned char channel,
unsigned char mode,
bool direction,
unsigned char* color_data,
unsigned char speed = 0x02,
bool movement = false,
int cis = 0 ,
int size = 0
);
hid_device* dev;
// -- status
std::string firmware_version;
double liquid_temperature;
unsigned int fan_speed;
unsigned int pump_speed;
};
@@ -0,0 +1,51 @@
#include "NZXTKrakenController.h"
#include "RGBController.h"
#include "RGBController_NZXTKraken.h"
#include <vector>
#include <hidapi/hidapi.h>
#define NZXT_KRAKEN_VID 0x1E71
#define NZXT_KRAKEN_PID 0x170E
/******************************************************************************************\
* *
* DetectNZXTKrakenControllers *
* *
* Detect devices supported by the NZXTKraken driver *
* * *
\******************************************************************************************/
void DetectNZXTKrakenControllers(std::vector<RGBController*> &rgb_controllers)
{
hid_device_info* info;
hid_device* dev;
hid_init();
for(std::size_t device_idx = 0; device_idx < 1; device_idx++)
{
dev = NULL;
info = hid_enumerate(NZXT_KRAKEN_VID, NZXT_KRAKEN_PID);
//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);
RGBController_NZXTKraken* rgb_controller = new RGBController_NZXTKraken(controller);
rgb_controllers.push_back(rgb_controller);
}
}
info = info->next;
}
}
}
@@ -0,0 +1,176 @@
/*-----------------------------------------*\
| PatriotViperController.cpp |
| |
| Definitions and types for Patriot Viper |
| RGB RAM lighting controller |
| |
| Adam Honse (CalcProgrammer1) 1/1/2020 |
\*-----------------------------------------*/
#include "PatriotViperController.h"
#include <cstring>
PatriotViperController::PatriotViperController(i2c_smbus_interface* bus, viper_dev_id dev, unsigned char slots)
{
this->bus = bus;
this->dev = dev;
slots_valid = slots;
strcpy(device_name, "Patriot Viper RGB");
led_count = 0;
for(int i = 0; i < 8; i++)
{
if((slots_valid & (1 << i)) != 0)
{
led_count += 5;
}
}
}
PatriotViperController::~PatriotViperController()
{
}
std::string PatriotViperController::GetDeviceName()
{
return(device_name);
}
std::string PatriotViperController::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 int PatriotViperController::GetLEDCount()
{
return(led_count);
}
unsigned int PatriotViperController::GetSlotCount()
{
unsigned int slot_count = 0;
for(int slot = 0; slot < 4; slot++)
{
if((slots_valid & (1 << slot)) != 0)
{
slot_count++;
}
}
return(slot_count);
}
unsigned int PatriotViperController::GetMode()
{
return(mode);
}
void PatriotViperController::SetEffectColor(unsigned char red, unsigned char green, unsigned char blue)
{
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_LED0_EFFECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_REG_LED1_EFFECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_REG_LED2_EFFECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_REG_LED3_EFFECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_REG_LED4_EFFECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_REG_MODE, mode, 0x00, speed);
ViperRegisterWrite(VIPER_REG_MODE, 0xAA, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_MODE, 0xFA, 0x00, 0x00);
}
void PatriotViperController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
{
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_LED0_DIRECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_REG_LED1_DIRECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_REG_LED2_DIRECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_REG_LED3_DIRECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_REG_LED4_DIRECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_REG_APPLY, 0x01, 0x00, 0x00);
}
void PatriotViperController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_LED0_DIRECT_COLOR + led, red, blue, green);
ViperRegisterWrite(VIPER_REG_APPLY, 0x01, 0x00, 0x00);
}
void PatriotViperController::SetLEDEffectColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_LED0_EFFECT_COLOR + led, red, blue, green);
ViperRegisterWrite(VIPER_REG_MODE, mode, 0x00, speed);
ViperRegisterWrite(VIPER_REG_MODE, 0xAA, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_MODE, 0xFA, 0x00, 0x00);
}
void PatriotViperController::SetLEDColor(unsigned int /*slot*/, unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_LED0_DIRECT_COLOR + led, red, blue, green);
ViperRegisterWrite(VIPER_REG_APPLY, 0x01, 0x00, 0x00);
}
void PatriotViperController::SetLEDEffectColor(unsigned int /*slot*/, unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_LED0_EFFECT_COLOR + led, red, blue, green);
ViperRegisterWrite(VIPER_REG_MODE, mode, 0x00, speed);
ViperRegisterWrite(VIPER_REG_MODE, 0xAA, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_MODE, 0xFA, 0x00, 0x00);
}
void PatriotViperController::SetMode(unsigned char new_mode, unsigned char new_speed)
{
direct = false;
mode = new_mode;
speed = new_speed;
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_MODE, mode, 0x00, speed);
ViperRegisterWrite(VIPER_REG_MODE, 0xAA, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_MODE, 0xFA, 0x00, 0x00);
}
void PatriotViperController::SetDirect()
{
direct = true;
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_APPLY, 0x01, 0x00, 0x00);
}
void PatriotViperController::ViperRegisterWrite(viper_register reg, unsigned char val0, unsigned char val1, unsigned char val2)
{
bus->i2c_smbus_write_byte_data(dev, reg, val0);
bus->i2c_smbus_write_byte_data(dev, val2, val1);
}
@@ -0,0 +1,90 @@
/*-----------------------------------------*\
| PatriotViperController.h |
| |
| Definitions and types for Patriot Viper |
| RGB RAM lighting controller |
| |
| Adam Honse (CalcProgrammer1) 1/1/2020 |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char viper_dev_id;
typedef unsigned short viper_register;
enum
{
VIPER_REG_STATIC = 0x01, /* Set static mode */
VIPER_REG_MODE = 0x03, /* Mode register */
VIPER_REG_LED0_DIRECT_COLOR = 0x30, /* LED 0 Color (R, B, G) */
VIPER_REG_LED1_DIRECT_COLOR = 0x31, /* LED 1 Color (R, B, G) */
VIPER_REG_LED2_DIRECT_COLOR = 0x32, /* LED 2 Color (R, B, G) */
VIPER_REG_LED3_DIRECT_COLOR = 0x33, /* LED 3 Color (R, B, G) */
VIPER_REG_LED4_DIRECT_COLOR = 0x34, /* LED 4 Color (R, B, G) */
VIPER_REG_APPLY = 0x35, /* Apply Changes (0x01, 0x00, 0x00) */
VIPER_REG_LED0_EFFECT_COLOR = 0x3B, /* LED 0 Color (R, B, G) */
VIPER_REG_LED1_EFFECT_COLOR = 0x3C, /* LED 1 Color (R, B, G) */
VIPER_REG_LED2_EFFECT_COLOR = 0x3D, /* LED 2 Color (R, B, G) */
VIPER_REG_LED3_EFFECT_COLOR = 0x3E, /* LED 3 Color (R, B, G) */
VIPER_REG_LED4_EFFECT_COLOR = 0x3F, /* LED 4 Color (R, B, G) */
VIPER_REG_START = 0xFF, /* Start Frame (0xFF, 0xFF, 0xFF) */
};
enum
{
VIPER_MODE_DARK = 0x00, /* Dark mode */
VIPER_MODE_BREATHING = 0x01, /* Breathing mode */
VIPER_MODE_VIPER = 0x02, /* Viper mode */
VIPER_MODE_HEARTBEAT = 0x03, /* Heartbeat mode */
VIPER_MODE_MARQUEE = 0x04, /* Marquee mode */
VIPER_MODE_RAINDROP = 0x05, /* Raindrop mode */
VIPER_MODE_AURORA = 0x06, /* Aurora mode */
VIPER_MODE_NEON = 0x08, /* Neon mode */
};
enum
{
VIPER_SPEED_MIN = 0xC8, /* Slowest speed for non-breathing mode */
VIPER_SPEED_DEFAULT = 0x64, /* Default speed for non-breathing mode */
VIPER_SPEED_MAX = 0x14, /* Fastest speed for non-breathing mode */
VIPER_SPEED_BREATHING_MIN = 0xFF, /* Slowest speed for breathing mode */
VIPER_SPEED_BREATHING_DEFAULT = 0x0C, /* Default speed for breathing mode */
VIPER_SPEED_BREATHING_MAX = 0x00, /* Fastest speed for breathing mode */
};
class PatriotViperController
{
public:
PatriotViperController(i2c_smbus_interface* bus, viper_dev_id dev, unsigned char slots);
~PatriotViperController();
std::string GetDeviceName();
std::string GetDeviceLocation();
unsigned int GetLEDCount();
unsigned int GetSlotCount();
unsigned int GetMode();
void SetMode(unsigned char new_mode, unsigned char new_speed);
void SetDirect();
void SetAllColors(unsigned char red, unsigned char green, unsigned char blue);
void SetEffectColor(unsigned char red, unsigned char green, unsigned char blue);
void SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
void SetLEDColor(unsigned int slot, unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
void SetLEDEffectColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
void SetLEDEffectColor(unsigned int slot, unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
void ViperRegisterWrite(viper_register reg, unsigned char val0, unsigned char val1, unsigned char val2);
bool direct;
private:
char device_name[32];
unsigned int led_count;
unsigned char slots_valid;
i2c_smbus_interface* bus;
viper_dev_id dev;
unsigned char mode;
unsigned char speed;
};
@@ -0,0 +1,72 @@
#include "PatriotViperController.h"
#include "RGBController.h"
#include "RGBController_PatriotViper.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std::chrono_literals;
/******************************************************************************************\
* *
* DetectPatriotViperControllers *
* *
* Detect Patriot Viper RGB controllers on the enumerated I2C busses. *
* *
* bus - pointer to i2c_smbus_interface where Aura device is connected *
* dev - I2C address of Aura device *
* *
\******************************************************************************************/
void DetectPatriotViperControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
PatriotViperController* new_viper;
RGBController_PatriotViper* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
unsigned char slots_valid = 0x00;
for(int slot_addr = 0x50; slot_addr <= 0x57; slot_addr++)
{
// Test for Patriot Viper RGB SPD at slot_addr
// This test was copied from Viper RGB software
// 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);
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);
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)
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x61) == 0x4D)
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x62) == 0x49)
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x63) == 0x43)
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x64) == 0x53)
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x65) == 0x59)
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x66) == 0x53)
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x67) == 0x5f)
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x68) == 0x44))
{
slots_valid |= (1 << (slot_addr - 0x50));
}
}
std::this_thread::sleep_for(1ms);
}
if(slots_valid != 0)
{
new_viper = new PatriotViperController(busses[bus], 0x77, slots_valid);
new_controller = new RGBController_PatriotViper(new_viper);
rgb_controllers.push_back(new_controller);
}
}
} /* DetectPatriotViperControllers() */

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