Compare commits
194
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e81e26fcc | ||
|
|
b97b429684 | ||
|
|
9f06fc63a1 | ||
|
|
d2dd9dcc73 | ||
|
|
6fbcf62d76 | ||
|
|
1a6943fe17 | ||
|
|
cde2343d09 | ||
|
|
c746b30287 | ||
|
|
3582b96dd9 | ||
|
|
d258065e36 | ||
|
|
7627466891 | ||
|
|
c476ee46f8 | ||
|
|
6fc68f4e62 | ||
|
|
75bac1fd4e | ||
|
|
94042375a7 | ||
|
|
103306c6c8 | ||
|
|
6d37d262ea | ||
|
|
473331dd3a | ||
|
|
bc9d03ef48 | ||
|
|
740c88fe0c | ||
|
|
684ef09168 | ||
|
|
e3b08fc15d | ||
|
|
5c931a61b4 | ||
|
|
ad7534d00d | ||
|
|
c81f8699f1 | ||
|
|
2af03eb0dc | ||
|
|
5064ba3f1d | ||
|
|
c5abe47859 | ||
|
|
8fdd0e40f8 | ||
|
|
a6a07ba0d7 | ||
|
|
614fef4189 | ||
|
|
d3e7dba2b7 | ||
|
|
39343c3e9e | ||
|
|
73865fec59 | ||
|
|
b508818f23 | ||
|
|
bef8ae0a2f | ||
|
|
cce2d41500 | ||
|
|
175f3ed338 | ||
|
|
c2cc7c6163 | ||
|
|
8fee041fad | ||
|
|
dfc1f8524a | ||
|
|
752bd2e35a | ||
|
|
01fe0b4630 | ||
|
|
e7f8bc0136 | ||
|
|
370918e07f | ||
|
|
133966677b | ||
|
|
44f84e4781 | ||
|
|
a8354ee046 | ||
|
|
4550e3073a | ||
|
|
abe7a49092 | ||
|
|
82a486bfb6 | ||
|
|
ad06e733f8 | ||
|
|
4306603a28 | ||
|
|
554f834a90 | ||
|
|
7236bec61f | ||
|
|
c799f1bfe9 | ||
|
|
f15c3c1420 | ||
|
|
aa67045330 | ||
|
|
736640f38d | ||
|
|
e9caf663bc | ||
|
|
8afbea53de | ||
|
|
c3d496ad5b | ||
|
|
06501f528d | ||
|
|
f6a678c1a4 | ||
|
|
30690d0ebd | ||
|
|
7a830cddf9 | ||
|
|
3dc1365d39 | ||
|
|
b03cd94ae8 | ||
|
|
bbf348d273 | ||
|
|
dce48eb415 | ||
|
|
decf14635d | ||
|
|
db4f49bbba | ||
|
|
26824fcb6e | ||
|
|
8afad91b33 | ||
|
|
69de0b13c4 | ||
|
|
967153bc10 | ||
|
|
971d9be1bd | ||
|
|
7a3faef886 | ||
|
|
f67030fcc7 | ||
|
|
7353e99449 | ||
|
|
91d9597c89 | ||
|
|
2eb569912b | ||
|
|
9410d9c066 | ||
|
|
29d8788e25 | ||
|
|
0304c50bc6 | ||
|
|
dd22150cfe | ||
|
|
07e7feca56 | ||
|
|
a93eec8f50 | ||
|
|
88bad762e5 | ||
|
|
18dfe6ca8b | ||
|
|
96dfa7009f | ||
|
|
92a9d8ad11 | ||
|
|
2ab9094b41 | ||
|
|
f6154ccbc4 | ||
|
|
0be01dde19 | ||
|
|
e113e91423 | ||
|
|
28c63b8b9d | ||
|
|
c5aac4c44f | ||
|
|
42e7f2a5c3 | ||
|
|
ae9ae18d31 | ||
|
|
f89cdac198 | ||
|
|
e8f345ff77 | ||
|
|
aff0610df9 | ||
|
|
9199d062d1 | ||
|
|
0ec4aaa629 | ||
|
|
9fca99b4ef | ||
|
|
14853895f3 | ||
|
|
d79a400c8c | ||
|
|
f741385e43 | ||
|
|
840bd92afb | ||
|
|
96e1fb0b10 | ||
|
|
388557e5f9 | ||
|
|
3f32817272 | ||
|
|
056b383536 | ||
|
|
0691f40588 | ||
|
|
800ca0aa7c | ||
|
|
a91679609b | ||
|
|
19f9408990 | ||
|
|
0eea0c9aca | ||
|
|
9f95aa8271 | ||
|
|
0ee04c497b | ||
|
|
2847270c97 | ||
|
|
b98174afba | ||
|
|
3416980849 | ||
|
|
c171bfbf3b | ||
|
|
583a737cb5 | ||
|
|
d2af6289dd | ||
|
|
44e6f455e9 | ||
|
|
b3a50d669e | ||
|
|
0092ea22e2 | ||
|
|
58fb35a9bb | ||
|
|
9a6ff77545 | ||
|
|
c4e0164479 | ||
|
|
f872f1c591 | ||
|
|
03e64da845 | ||
|
|
3150f64895 | ||
|
|
8b36e9c317 | ||
|
|
c5c5fc6c02 | ||
|
|
c7d9992a3d | ||
|
|
0d8f2c6b14 | ||
|
|
c1800f2a6f | ||
|
|
d41a115a07 | ||
|
|
2640a3b93f | ||
|
|
984c18cb11 | ||
|
|
23db15dfb9 | ||
|
|
9426f954b0 | ||
|
|
133b64778b | ||
|
|
a8a97fa38d | ||
|
|
da6061bbde | ||
|
|
dfad607697 | ||
|
|
5d7565bc59 | ||
|
|
ab962ca98f | ||
|
|
dbbf9858f8 | ||
|
|
51edb35e3f | ||
|
|
81c6ee6270 | ||
|
|
9ad37cc98f | ||
|
|
c76864dd4b | ||
|
|
e3889508c0 | ||
|
|
22d908b9a3 | ||
|
|
13d3e09f1a | ||
|
|
9ec15673d1 | ||
|
|
3a00a803e9 | ||
|
|
4a12a0db90 | ||
|
|
b4940e3a75 | ||
|
|
ffe07bbe3b | ||
|
|
7fdb006465 | ||
|
|
99da577c41 | ||
|
|
0f6fdd6c3b | ||
|
|
52ec58d67f | ||
|
|
c55fc59d18 | ||
|
|
b68b63e8c9 | ||
|
|
84bb05d504 | ||
|
|
f33a7ba870 | ||
|
|
93830c12ee | ||
|
|
b8b50f6651 | ||
|
|
8f331090f9 | ||
|
|
7ec1e8ddfa | ||
|
|
880dc1450d | ||
|
|
801e655c09 | ||
|
|
5e269dd089 | ||
|
|
476f81d5e8 | ||
|
|
66dfb5f6fd | ||
|
|
a2f2991192 | ||
|
|
cfedcd2180 | ||
|
|
cc06c62164 | ||
|
|
b4ca000402 | ||
|
|
b78a6f4418 | ||
|
|
d5693b7a08 | ||
|
|
cae0670065 | ||
|
|
f2d1188fdd | ||
|
|
70be81c92d | ||
|
|
5d5af93401 | ||
|
|
74cbdcce55 | ||
|
|
96d19a76cc |
+8
-20
@@ -14,9 +14,9 @@
|
||||
# run only if manually started to save CI minutes if #
|
||||
# GitLab hosted runners #
|
||||
# * For commits to the CalcProgrammer1/OpenRGB repository, #
|
||||
# automatically run all jobs on the default branch, #
|
||||
# otherwise run them if the source is part of a merge #
|
||||
# request #
|
||||
# automatically run all jobs on the default branch or #
|
||||
# tag builds, otherwise run them if the source is part #
|
||||
# of a merge request #
|
||||
#-----------------------------------------------------------#
|
||||
.downstream_rules:
|
||||
rules:
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
.upstream_rules:
|
||||
rules:
|
||||
- if: '$CI_PROJECT_PATH == "CalcProgrammer1/OpenRGB" && ($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_PIPELINE_SOURCE == "merge_request_event")'
|
||||
- if: '$CI_PROJECT_PATH == "CalcProgrammer1/OpenRGB" && ($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_TAG || $CI_PIPELINE_SOURCE == "merge_request_event")'
|
||||
when: on_success
|
||||
- !reference [.downstream_rules, rules]
|
||||
|
||||
@@ -516,10 +516,7 @@ before_script:
|
||||
- macos
|
||||
stage: build
|
||||
script:
|
||||
- eval $(/opt/homebrew/bin/brew shellenv)
|
||||
- /opt/homebrew/opt/qt@5/bin/qmake OpenRGB.pro
|
||||
- make -j16
|
||||
- /opt/homebrew/opt/qt@5/bin/macdeployqt OpenRGB.app -codesign=OpenRGB
|
||||
- ./scripts/build-macos.sh qt5 arm
|
||||
|
||||
artifacts:
|
||||
name: "${CI_PROJECT_NAME}_MacOS_ARM64_${CI_COMMIT_SHORT_SHA}"
|
||||
@@ -535,10 +532,7 @@ before_script:
|
||||
- macos
|
||||
stage: build
|
||||
script:
|
||||
- eval $(/opt/homebrew/bin/brew shellenv)
|
||||
- qmake OpenRGB.pro
|
||||
- make -j16
|
||||
- macdeployqt OpenRGB.app -codesign=OpenRGB
|
||||
- ./scripts/build-macos.sh qt6 arm
|
||||
|
||||
artifacts:
|
||||
name: "${CI_PROJECT_NAME}_MacOS_ARM64_Qt6_${CI_COMMIT_SHORT_SHA}"
|
||||
@@ -554,10 +548,7 @@ before_script:
|
||||
- macos
|
||||
stage: build
|
||||
script:
|
||||
- eval $(/usr/local/bin/brew shellenv)
|
||||
- arch -x86_64 /usr/local/opt/qt@5/bin/qmake OpenRGB.pro
|
||||
- arch -x86_64 make -j16
|
||||
- arch -x86_64 /usr/local/opt/qt@5/bin/macdeployqt OpenRGB.app -codesign=OpenRGB
|
||||
- ./scripts/build-macos.sh qt5 intel
|
||||
|
||||
artifacts:
|
||||
name: "${CI_PROJECT_NAME}_MacOS_Intel_${CI_COMMIT_SHORT_SHA}"
|
||||
@@ -573,10 +564,7 @@ before_script:
|
||||
- macos
|
||||
stage: build
|
||||
script:
|
||||
- eval $(/usr/local/bin/brew shellenv)
|
||||
- arch -x86_64 /usr/local/bin/qmake OpenRGB.pro
|
||||
- arch -x86_64 make -j16
|
||||
- arch -x86_64 /usr/local/bin/macdeployqt OpenRGB.app -codesign=OpenRGB
|
||||
- ./scripts/build-macos.sh qt6 intel
|
||||
|
||||
artifacts:
|
||||
name: "${CI_PROJECT_NAME}_MacOS_Intel_Qt6_${CI_COMMIT_SHORT_SHA}"
|
||||
|
||||
+1
-2
@@ -22,13 +22,12 @@ CODEOWNERS @Calcprogrammer1
|
||||
/Controllers/BlinkyTapeController/
|
||||
/Controllers/CoolerMasterController/ @Dr_No
|
||||
/Controllers/CorsairCommanderCoreController/
|
||||
/Controllers/CorsairDominatorPlatinumController/
|
||||
/Controllers/CorsairDRAMController/
|
||||
/Controllers/CorsairHydroController/
|
||||
/Controllers/CorsairHydroPlatinumController/
|
||||
/Controllers/CorsairLightingNodeController/
|
||||
/Controllers/CorsairPeripheralController/
|
||||
/Controllers/CorsairVengeanceController/
|
||||
/Controllers/CorsairVengeanceProController/
|
||||
/Controllers/CorsairWirelessController/
|
||||
/Controllers/CreativeController/
|
||||
/Controllers/CrucialController/
|
||||
|
||||
@@ -69,3 +69,7 @@ OpenRGB is written in C++, uses the Qt framework for UI, and uses the QMake buil
|
||||
|
||||
Translation files are located in [`OpenRGB/qt/i18n/`](https://gitlab.com/CalcProgrammer1/OpenRGB/-/tree/master/qt/i18n), where languages are formatted using ISO 639-1 format: `OpenRGB_xx_XX.ts` — `xx_XX` representing the language code.
|
||||
In order to translate a file, you need to [fork](https://gitlab.com/CalcProgrammer1/OpenRGB/-/forks/new) the project, create a new file for your language with `lupdate` (or edit an exisiting one), edit the file with `qtlinguist`, commit, push, and create a merge request.
|
||||
|
||||
## AI Guidelines
|
||||
|
||||
OpenRGB is an open source project developed by humans for humans. As a general rule, AI generated submissions are not permitted. The licensing behind AI generated code is problematic. If you choose to use AI for assistance in your development process, we can't stop you, but do not credit the AI in commits (no AI authorship/co-authorship). Ultimately, you as a human developer are responsible for the code you submit and it is expected that any code you submit you fully understand and have manually vetted before submission. Merge requests that appear to be straight from an AI output, commits with AI tool authorship or co-authorship tags, or otherwise AI generated submissions are subject to closure.
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define AURA_ROG_GLADIUS_II_WIRELESS_1_PID 0x189E
|
||||
#define AURA_ROG_GLADIUS_II_WIRELESS_2_PID 0x18A0
|
||||
#define AURA_ROG_GLADIUS_III_PID 0x197B
|
||||
#define AURA_ROG_GLADIUS_III_CORE_PID 0x1C8D
|
||||
#define AURA_ROG_GLADIUS_III_WIRELESS_USB_PID 0x197D
|
||||
#define AURA_ROG_GLADIUS_III_WIRELESS_2_4_PID 0x197F
|
||||
#define AURA_ROG_GLADIUS_III_WIRELESS_BT_PID 0x1981
|
||||
@@ -217,6 +218,20 @@ static std::map<int,mouse_type> aura_mouse_devices =
|
||||
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_WAVE, AURA_MOUSE_MODE_REACTIVE, AURA_MOUSE_MODE_COMET, AURA_MOUSE_MODE_BATTERY }
|
||||
}
|
||||
},
|
||||
{
|
||||
AURA_ROG_GLADIUS_III_CORE_PID, // ROG Gladius III Core
|
||||
{
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
false,
|
||||
1,
|
||||
false,
|
||||
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL },
|
||||
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_NONE, AURA_MOUSE_MODE_REACTIVE }
|
||||
}
|
||||
},
|
||||
{
|
||||
AURA_ROG_GLADIUS_III_WIRELESS_USB_PID, // ROG Gladius III Wireless USB
|
||||
{
|
||||
|
||||
+4
-1
@@ -19,7 +19,10 @@ AsusAuraRyuoAIOController::AsusAuraRyuoAIOController(hid_device* dev_handle, con
|
||||
| Manually adding device info for now |
|
||||
| TODO: Implement config table accurately |
|
||||
\*-----------------------------------------------------*/
|
||||
device_info.push_back({0x00, 0x00, 12, 0, AuraDeviceType::FIXED});
|
||||
uint8_t leds = (dev_name.find("Ryujin") != std::string::npos) ? 5 : 12;
|
||||
|
||||
device_info.push_back({0x00, 0x00, leds, 0, AuraDeviceType::FIXED});
|
||||
|
||||
}
|
||||
|
||||
AsusAuraRyuoAIOController::~AsusAuraRyuoAIOController()
|
||||
|
||||
@@ -120,6 +120,7 @@
|
||||
#define AURA_TERMINAL_PID 0x1889
|
||||
#define ROG_STRIX_LC120_PID 0x879E
|
||||
#define AURA_RYUO_AIO_PID 0x1887
|
||||
#define AURA_RYUJIN_AIO_PID 0x18AE
|
||||
#define ASUS_ROG_ALLY_PID 0x1ABE
|
||||
#define ASUS_ROG_ALLY_X_PID 0x1B4C
|
||||
|
||||
@@ -393,6 +394,7 @@ REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Origin COD",
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Wireless", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_WIRELESS_1_PID, 1, 0xFF13);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Wireless", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_WIRELESS_2_PID, 2, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius III", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_III_PID, 0, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius III Core", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_III_CORE_PID, 0, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius III Wireless USB", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_III_WIRELESS_USB_PID, 0, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius III Wireless 2.4Ghz", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_III_WIRELESS_2_4_PID, 0, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius III Wireless Bluetooth", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_III_WIRELESS_BT_PID, 0, 0xFF01);
|
||||
@@ -453,6 +455,7 @@ REGISTER_HID_DETECTOR_PU("ASUS ROG PG32UQ", DetectAs
|
||||
REGISTER_HID_DETECTOR ("ASUS ROG AURA Terminal", DetectAsusAuraUSBTerminal, AURA_USB_VID, AURA_TERMINAL_PID);
|
||||
REGISTER_HID_DETECTOR_PU ("ASUS ROG Strix LC", DetectAsusAuraUSBROGStrixLC, AURA_USB_VID, ROG_STRIX_LC120_PID, 0x00FF, 1);
|
||||
REGISTER_HID_DETECTOR_PU ("ASUS ROG Ryuo AIO", DetectAsusAuraUSBRyuoAIO, AURA_USB_VID, AURA_RYUO_AIO_PID, 0xFF72, 0x00A1);
|
||||
REGISTER_HID_DETECTOR_PU ("ASUS ROG Ryujin AIO", DetectAsusAuraUSBRyuoAIO, AURA_USB_VID, AURA_RYUJIN_AIO_PID, 0xFF72, 0x00A1);
|
||||
REGISTER_HID_DETECTOR_I ("ASUS ROG Throne", DetectAsusAuraUSBHeadsetStand, AURA_USB_VID, AURA_ROG_THRONE_PID, 0);
|
||||
REGISTER_HID_DETECTOR_I ("ASUS ROG Throne QI", DetectAsusAuraUSBHeadsetStand, AURA_USB_VID, AURA_ROG_THRONE_QI_PID, 0);
|
||||
REGISTER_HID_DETECTOR_I ("ASUS ROG Throne QI GUNDAM", DetectAsusAuraUSBHeadsetStand, AURA_USB_VID, AURA_ROG_THRONE_QI_GUNDAM_PID, 0);
|
||||
|
||||
@@ -89,7 +89,7 @@ void AsusMonitorController::SetDirect(std::vector<RGBColor> colors)
|
||||
usb_buf[0x00] = 0xEC;
|
||||
usb_buf[0x01] = 0x40;
|
||||
usb_buf[0x02] = 0x84;
|
||||
usb_buf[0x04] = colors.size();
|
||||
usb_buf[0x04] = (uint8_t)colors.size();
|
||||
|
||||
for(size_t i = 0; i < colors.size(); i++)
|
||||
{
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "ClevoKeyboardController.h"
|
||||
#include <cstring>
|
||||
#include "ClevoKeyboardController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
ClevoKeyboardController::ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info)
|
||||
{
|
||||
@@ -40,10 +41,7 @@ std::string ClevoKeyboardController::GetSerialString()
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
return(return_string);
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string ClevoKeyboardController::GetFirmwareVersion()
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "ClevoLightbarController.h"
|
||||
#include <cstring>
|
||||
#include "ClevoLightbarController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
ClevoLightbarController::ClevoLightbarController(hid_device* dev_handle, const hid_device_info& info)
|
||||
{
|
||||
@@ -40,10 +41,7 @@ std::string ClevoLightbarController::GetSerialString()
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
return(return_string);
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string ClevoLightbarController::GetFirmwareVersion()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*---------------------------------------------------------*\
|
||||
/*---------------------------------------------------------*\
|
||||
| ColorfulGPUControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Colorful GPU |
|
||||
@@ -48,7 +48,7 @@ REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Advanced OC 12G L-V", Detec
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ultra W OC 12G L-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ultra W OC 12G L-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_GA106_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ultra W OC 12G L-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G_2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Ultra W OC LHR-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Ultra W OC LHR-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Ultra W OC LHR-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G_2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3070_ADVANCED_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060TI_ADVANCED_OC, 0x61);
|
||||
@@ -72,3 +72,9 @@ REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4080 Ultra W OC-V", Detec
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4080 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4080_ULTRAW_OCV2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4090 Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4090_ADVANCED_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4090 Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4090_ADVANCED_OCV2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5060 Ultra W OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5060_ULTRAW_OC, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5060 Ultra W OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5060_ULTRAW_OC_2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5060 Ti Ultra W DUO OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060TI_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5060TI_ULTRAW_DUO_OC, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5060 Ti Ultra W DUO OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060TI_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5060TI_ULTRAW_DUO_OC_2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5070 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5070_ULTRAW_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5070 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5070_ULTRAW_OCV2, 0x61);
|
||||
@@ -12,16 +12,27 @@
|
||||
#include "CMARGBController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
CMARGBController::CMARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx, std::shared_ptr<std::mutex> cm_mutex)
|
||||
/*---------------------------------------------------------*\
|
||||
| Map to convert port index to port ID used in protocol |
|
||||
\*---------------------------------------------------------*/
|
||||
static unsigned char cm_argb_port_index_to_id[5] =
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = _path;
|
||||
zone_index = _zone_idx;
|
||||
mutex_ptr = cm_mutex;
|
||||
CM_ARGB_PORT_ARGB_1,
|
||||
CM_ARGB_PORT_ARGB_2,
|
||||
CM_ARGB_PORT_ARGB_3,
|
||||
CM_ARGB_PORT_ARGB_4,
|
||||
CM_ARGB_PORT_RGB
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get device name from HID manufacturer and product strings |
|
||||
\*---------------------------------------------------------*/
|
||||
CMARGBController::CMARGBController(hid_device* dev_handle, char *path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get device name from HID manufacturer and product |
|
||||
| strings |
|
||||
\*-----------------------------------------------------*/
|
||||
wchar_t name_string[HID_MAX_STR];
|
||||
|
||||
hid_get_manufacturer_string(dev, name_string, HID_MAX_STR);
|
||||
@@ -29,57 +40,11 @@ CMARGBController::CMARGBController(hid_device* dev_handle, char *_path, unsigned
|
||||
|
||||
hid_get_product_string(dev, name_string, HID_MAX_STR);
|
||||
device_name.append(" ").append(StringUtils::wstring_to_string(name_string));
|
||||
|
||||
GetStatus();
|
||||
}
|
||||
|
||||
CMARGBController::~CMARGBController()
|
||||
{
|
||||
if(mutex_ptr.use_count() <= 1)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
}
|
||||
|
||||
void CMARGBController::GetStatus()
|
||||
{
|
||||
unsigned char buffer[CM_ARGB_PACKET_SIZE] = { 0x00, 0x80, 0x0B, 0x01 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
int rgb_offset = 0;
|
||||
int zone;
|
||||
|
||||
if (argb_header_data[zone_index].digital)
|
||||
{
|
||||
zone = argb_header_data[zone_index].header;
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = 0x0B;
|
||||
}
|
||||
else
|
||||
{
|
||||
zone = 0x00;
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = 0x0A;
|
||||
rgb_offset = 1;
|
||||
}
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Guard the writes to the controller until the |
|
||||
| for loop has completed to avoid collisons |
|
||||
\*---------------------------------------------*/
|
||||
std::lock_guard<std::mutex> guard(*mutex_ptr);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| If this is the group then just return the first status |
|
||||
\*---------------------------------------------------------*/
|
||||
buffer[CM_ARGB_ZONE_BYTE] = ( zone > 0x08 ) ? 0x01 : zone;
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
|
||||
|
||||
current_mode = buffer[4 - rgb_offset];
|
||||
bool_random = ( buffer[5 - rgb_offset] == 0x00 );
|
||||
current_speed = buffer[6 - rgb_offset];
|
||||
current_brightness = buffer[7 - rgb_offset];
|
||||
current_red = buffer[8 - rgb_offset];
|
||||
current_green = buffer[9 - rgb_offset];
|
||||
current_blue = buffer[10 - rgb_offset];
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string CMARGBController::GetDeviceName()
|
||||
@@ -87,6 +52,33 @@ std::string CMARGBController::GetDeviceName()
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string CMARGBController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string CMARGBController::GetVersion()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| This device uses the serial value to determine the |
|
||||
| version. It does not report a proper unique serial. |
|
||||
\*-----------------------------------------------------*/
|
||||
std::string serial_string = GetSerial();
|
||||
|
||||
if(serial_string == CM_ARGB_FW0023)
|
||||
{
|
||||
return("0023");
|
||||
}
|
||||
else if(serial_string == CM_ARGB_FW0028)
|
||||
{
|
||||
return("0028");
|
||||
}
|
||||
else
|
||||
{
|
||||
return("Unsupported");
|
||||
}
|
||||
}
|
||||
|
||||
std::string CMARGBController::GetSerial()
|
||||
{
|
||||
wchar_t serial_string[HID_MAX_STR];
|
||||
@@ -100,118 +92,187 @@ std::string CMARGBController::GetSerial()
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string CMARGBController::GetLocation()
|
||||
void CMARGBController::GetPortStatus
|
||||
(
|
||||
unsigned char port_idx,
|
||||
unsigned char* port_mode,
|
||||
unsigned char* port_speed,
|
||||
unsigned char* port_brightness,
|
||||
bool* port_random,
|
||||
unsigned char* port_red,
|
||||
unsigned char* port_green,
|
||||
unsigned char* port_blue
|
||||
)
|
||||
{
|
||||
return("HID: " + location);
|
||||
unsigned char buffer[CM_ARGB_PACKET_SIZE] = {0x00, 0x80, 0x0B, 0x01};
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
int rgb_offset = 0;
|
||||
int zone;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| RGB port is handled differently from ARGB ports |
|
||||
\*-----------------------------------------------------*/
|
||||
if(cm_argb_port_index_to_id[port_idx] != CM_ARGB_PORT_RGB)
|
||||
{
|
||||
zone = cm_argb_port_index_to_id[port_idx];
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = 0x0B;
|
||||
}
|
||||
else
|
||||
{
|
||||
zone = 0x00;
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = 0x0A;
|
||||
rgb_offset = 1;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| If this is the group then just return the first |
|
||||
| status |
|
||||
\*-----------------------------------------------------*/
|
||||
buffer[CM_ARGB_ZONE_BYTE] = ( zone > 0x08 ) ? 0x01 : zone;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send the command and read the response |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read data out of response |
|
||||
\*-----------------------------------------------------*/
|
||||
*port_mode = buffer[4 - rgb_offset];
|
||||
*port_random = (buffer[5 - rgb_offset] == 0x00);
|
||||
*port_speed = buffer[6 - rgb_offset];
|
||||
*port_brightness = buffer[7 - rgb_offset];
|
||||
*port_red = buffer[8 - rgb_offset];
|
||||
*port_green = buffer[9 - rgb_offset];
|
||||
*port_blue = buffer[10 - rgb_offset];
|
||||
}
|
||||
|
||||
unsigned char CMARGBController::GetZoneIndex()
|
||||
void CMARGBController::SetPortLEDCount(unsigned char port_idx, unsigned char led_count)
|
||||
{
|
||||
return(zone_index);
|
||||
}
|
||||
|
||||
unsigned char CMARGBController::GetMode()
|
||||
{
|
||||
return(current_mode);
|
||||
}
|
||||
|
||||
unsigned char CMARGBController::GetLedRed()
|
||||
{
|
||||
return(current_red);
|
||||
}
|
||||
|
||||
unsigned char CMARGBController::GetLedGreen()
|
||||
{
|
||||
return(current_green);
|
||||
}
|
||||
|
||||
unsigned char CMARGBController::GetLedBlue()
|
||||
{
|
||||
return(current_blue);
|
||||
}
|
||||
|
||||
unsigned char CMARGBController::GetLedSpeed()
|
||||
{
|
||||
return(current_speed);
|
||||
}
|
||||
|
||||
bool CMARGBController::GetRandomColours()
|
||||
{
|
||||
return(bool_random);
|
||||
}
|
||||
|
||||
void CMARGBController::SetLedCount(int zone, int led_count)
|
||||
{
|
||||
unsigned char buffer[CM_ARGB_PACKET_SIZE] = { 0x00, 0x80, 0x0D, 0x02 };
|
||||
unsigned char buffer[CM_ARGB_PACKET_SIZE] = {0x00, 0x80, 0x0D, 0x02};
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
|
||||
buffer[CM_ARGB_ZONE_BYTE] = zone;
|
||||
buffer[CM_ARGB_ZONE_BYTE] = cm_argb_port_index_to_id[port_idx];
|
||||
buffer[CM_ARGB_MODE_BYTE] = led_count;
|
||||
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = (0x0F - led_count > 0) ? 0x0F - led_count : 0x01;
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Guard the writes to the controller until the |
|
||||
| for loop has completed to avoid collisons |
|
||||
\*---------------------------------------------*/
|
||||
std::lock_guard<std::mutex> guard(*mutex_ptr);
|
||||
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = 1;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send the command |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
}
|
||||
|
||||
void CMARGBController::SetMode(uint8_t mode, uint8_t speed, uint8_t brightness, RGBColor colour, bool random_colours)
|
||||
void CMARGBController::SetPortMode
|
||||
(
|
||||
unsigned char port_idx,
|
||||
unsigned char port_mode,
|
||||
unsigned char port_speed,
|
||||
unsigned char port_brightness,
|
||||
bool port_random,
|
||||
unsigned char port_red,
|
||||
unsigned char port_green,
|
||||
unsigned char port_blue
|
||||
)
|
||||
{
|
||||
bool needs_update = !( (current_mode == mode) && (current_speed == speed) && (current_brightness == brightness) && (ToRGBColor(current_red, current_green, current_blue) == colour));
|
||||
unsigned char buffer[CM_ARGB_PACKET_SIZE] = {0x00};
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
bool boolARGB_header = (cm_argb_port_index_to_id[port_idx] != CM_ARGB_PORT_RGB);
|
||||
bool boolPassthru = (port_mode == CM_ARGB_MODE_PASSTHRU) || (port_mode == CM_RGB_MODE_PASSTHRU);
|
||||
bool boolDirect = (port_mode == CM_ARGB_MODE_DIRECT);
|
||||
unsigned char function = boolPassthru ? (boolARGB_header ? 0x02 : 0x04) : (boolARGB_header ? 0x01 : 0x03);
|
||||
buffer[CM_ARGB_REPORT_BYTE] = 0x80;
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = 0x01;
|
||||
|
||||
if (needs_update)
|
||||
if(boolDirect)
|
||||
{
|
||||
current_mode = mode;
|
||||
current_speed = speed;
|
||||
current_brightness = brightness;
|
||||
current_red = RGBGetRValue(colour);
|
||||
current_green = RGBGetGValue(colour);
|
||||
current_blue = RGBGetBValue(colour);
|
||||
bool_random = random_colours;
|
||||
buffer[CM_ARGB_FUNCTION_BYTE] = 0x01;
|
||||
buffer[CM_ARGB_ZONE_BYTE] = 0x02;
|
||||
|
||||
SendUpdate();
|
||||
/*-------------------------------------------------*\
|
||||
| Send the command |
|
||||
\*-------------------------------------------------*/
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Direct mode is now set up and no other mode |
|
||||
| packet is required |
|
||||
\*-------------------------------------------------*/
|
||||
return;
|
||||
}
|
||||
|
||||
buffer[CM_ARGB_FUNCTION_BYTE] = function;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send the command |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| ARGB ports send command 0x0B, RGB port sends 0x04 |
|
||||
\*-----------------------------------------------------*/
|
||||
if(boolARGB_header)
|
||||
{
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = 0x0B;
|
||||
buffer[CM_ARGB_FUNCTION_BYTE] = (false) ? 0x01 : 0x02;
|
||||
buffer[CM_ARGB_ZONE_BYTE] = cm_argb_port_index_to_id[port_idx];
|
||||
buffer[CM_ARGB_MODE_BYTE] = port_mode;
|
||||
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = port_random ? 0x00 : 0x10;
|
||||
buffer[CM_ARGB_SPEED_BYTE] = port_speed;
|
||||
buffer[CM_ARGB_BRIGHTNESS_BYTE] = port_brightness;
|
||||
buffer[CM_ARGB_RED_BYTE] = port_red;
|
||||
buffer[CM_ARGB_GREEN_BYTE] = port_green;
|
||||
buffer[CM_ARGB_BLUE_BYTE] = port_blue;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = boolPassthru ? 0x01 : 0x04;
|
||||
buffer[CM_ARGB_MODE_BYTE + CM_RGB_OFFSET] = port_mode;
|
||||
buffer[CM_ARGB_COLOUR_INDEX_BYTE + CM_RGB_OFFSET] = port_random ? 0x00 : 0x10;
|
||||
buffer[CM_ARGB_SPEED_BYTE + CM_RGB_OFFSET] = port_speed;
|
||||
buffer[CM_ARGB_BRIGHTNESS_BYTE + CM_RGB_OFFSET] = port_brightness;
|
||||
buffer[CM_ARGB_RED_BYTE + CM_RGB_OFFSET] = port_red;
|
||||
buffer[CM_ARGB_GREEN_BYTE + CM_RGB_OFFSET] = port_green;
|
||||
buffer[CM_ARGB_BLUE_BYTE + CM_RGB_OFFSET] = port_blue;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send the command and wait for response |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
}
|
||||
|
||||
void CMARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_count)
|
||||
void CMARGBController::SetPortLEDsDirect(unsigned char port_idx, RGBColor *led_colours, unsigned int led_count)
|
||||
{
|
||||
const unsigned char buffer_size = CM_ARGB_PACKET_SIZE;
|
||||
unsigned char buffer[buffer_size] = { 0x00, 0x00, 0x07, 0x02 };
|
||||
unsigned char packet_count = 0;
|
||||
std::vector<uint8_t> colours;
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Set up the RGB triplets to send |
|
||||
\*---------------------------------------------*/
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up the RGB triplets to send |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int i = 0; i < led_count; i++)
|
||||
{
|
||||
RGBColor colour = led_colours[i];
|
||||
|
||||
colours.push_back( RGBGetRValue(colour) );
|
||||
colours.push_back( RGBGetGValue(colour) );
|
||||
colours.push_back( RGBGetBValue(colour) );
|
||||
colours.push_back(RGBGetRValue(colour));
|
||||
colours.push_back(RGBGetGValue(colour));
|
||||
colours.push_back(RGBGetBValue(colour));
|
||||
}
|
||||
|
||||
buffer[CM_ARGB_FUNCTION_BYTE] = zone_index - 1;
|
||||
buffer[CM_ARGB_FUNCTION_BYTE] = port_idx;
|
||||
buffer[CM_ARGB_ZONE_BYTE] = led_count;
|
||||
unsigned char buffer_idx = CM_ARGB_MODE_BYTE;
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Guard the writes to the controller until the |
|
||||
| for loop has completed to avoid collisons |
|
||||
\*---------------------------------------------*/
|
||||
std::lock_guard<std::mutex> guard(*mutex_ptr);
|
||||
|
||||
for(std::vector<unsigned char>::iterator it = colours.begin(); it != colours.end(); buffer_idx = CM_ARGB_COMMAND_BYTE)
|
||||
{
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Fill the write buffer till its full or the colour buffer is empty |
|
||||
\*-----------------------------------------------------------------*/
|
||||
/*-------------------------------------------------*\
|
||||
| Fill the write buffer till its full or the |
|
||||
| colour buffer is empty |
|
||||
\*-------------------------------------------------*/
|
||||
buffer[CM_ARGB_REPORT_BYTE] = packet_count;
|
||||
while (( buffer_idx < buffer_size) && ( it != colours.end() ))
|
||||
while((buffer_idx < buffer_size) && (it != colours.end()))
|
||||
{
|
||||
buffer[buffer_idx] = *it;
|
||||
buffer_idx++;
|
||||
@@ -223,76 +284,15 @@ void CMARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_cou
|
||||
buffer[CM_ARGB_REPORT_BYTE] += 0x80;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Send the buffer |
|
||||
\*-------------------------------------------------*/
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Reset the write buffer |
|
||||
\*-----------------------------------------------------------------*/
|
||||
/*-------------------------------------------------*\
|
||||
| Reset the write buffer |
|
||||
\*-------------------------------------------------*/
|
||||
memset(buffer, 0x00, buffer_size );
|
||||
packet_count++;
|
||||
}
|
||||
}
|
||||
|
||||
void CMARGBController::SendUpdate()
|
||||
{
|
||||
/*---------------------------------------------*\
|
||||
| Guard the writes to the controller |
|
||||
\*---------------------------------------------*/
|
||||
std::lock_guard<std::mutex> guard(*mutex_ptr);
|
||||
|
||||
unsigned char buffer[CM_ARGB_PACKET_SIZE] = { 0x00 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
bool boolARGB_header = argb_header_data[zone_index].digital;
|
||||
bool boolPassthru = ( current_mode == CM_ARGB_MODE_PASSTHRU ) || ( current_mode == CM_RGB_MODE_PASSTHRU );
|
||||
bool boolDirect = ( current_mode == CM_ARGB_MODE_DIRECT );
|
||||
unsigned char function = boolPassthru ? (boolARGB_header ? 0x02 : 0x04) : (boolARGB_header ? 0x01 : 0x03);
|
||||
buffer[CM_ARGB_REPORT_BYTE] = 0x80;
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = 0x01;
|
||||
|
||||
if(boolDirect)
|
||||
{
|
||||
buffer[CM_ARGB_FUNCTION_BYTE] = 0x01;
|
||||
buffer[CM_ARGB_ZONE_BYTE] = 0x02;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Direct mode is now set up and no other mode packet is required |
|
||||
\*-----------------------------------------------------------------*/
|
||||
return;
|
||||
}
|
||||
|
||||
buffer[CM_ARGB_FUNCTION_BYTE] = function;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
|
||||
|
||||
if(boolARGB_header)
|
||||
{
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = 0x0B; //ARGB sends 0x0B (1011) RGB sends 0x04 (0100)
|
||||
buffer[CM_ARGB_FUNCTION_BYTE] = (false) ? 0x01 : 0x02; //This controls direct mode TODO
|
||||
buffer[CM_ARGB_ZONE_BYTE] = argb_header_data[zone_index].header;
|
||||
buffer[CM_ARGB_MODE_BYTE] = current_mode;
|
||||
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = bool_random ? 0x00 : 0x10;
|
||||
buffer[CM_ARGB_SPEED_BYTE] = current_speed;
|
||||
buffer[CM_ARGB_BRIGHTNESS_BYTE] = current_brightness;
|
||||
buffer[CM_ARGB_RED_BYTE] = current_red;
|
||||
buffer[CM_ARGB_GREEN_BYTE] = current_green;
|
||||
buffer[CM_ARGB_BLUE_BYTE] = current_blue;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = boolPassthru ? 0x01 : 0x04; //ARGB sends 0x0b (1011) RGB sends 0x04 (0100)
|
||||
buffer[CM_ARGB_MODE_BYTE + CM_RGB_OFFSET] = current_mode;
|
||||
buffer[CM_ARGB_COLOUR_INDEX_BYTE + CM_RGB_OFFSET] = bool_random ? 0x00 : 0x10;
|
||||
buffer[CM_ARGB_SPEED_BYTE + CM_RGB_OFFSET] = current_speed;
|
||||
buffer[CM_ARGB_BRIGHTNESS_BYTE + CM_RGB_OFFSET] = current_brightness;
|
||||
buffer[CM_ARGB_RED_BYTE + CM_RGB_OFFSET] = current_red;
|
||||
buffer[CM_ARGB_GREEN_BYTE + CM_RGB_OFFSET] = current_green;
|
||||
buffer[CM_ARGB_BLUE_BYTE + CM_RGB_OFFSET] = current_blue;
|
||||
}
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
@@ -16,19 +16,20 @@
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h" //Needed to set the direct mode
|
||||
#include "RGBController.h"
|
||||
|
||||
#define CM_ARGB_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
|
||||
#define CM_ARGB_HEADER_DATA_SIZE (sizeof(argb_header_data) / sizeof(argb_headers) )
|
||||
#define CM_ARGB_INTERRUPT_TIMEOUT 250
|
||||
#define CM_ARGB_PACKET_SIZE 65
|
||||
#define CM_ARGB_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
|
||||
#define CM_RGB_OFFSET -2
|
||||
#define HID_MAX_STR 255
|
||||
#define CM_ARGB_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
|
||||
#define CM_ARGB_HEADER_DATA_SIZE (sizeof(argb_header_data) / sizeof(argb_headers) )
|
||||
#define CM_ARGB_INTERRUPT_TIMEOUT 250
|
||||
#define CM_ARGB_PACKET_SIZE 65
|
||||
#define CM_ARGB_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
|
||||
#define CM_RGB_OFFSET -2
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
#define CM_ARGB_BRIGHTNESS_MAX 255
|
||||
#define CM_ARGB_FW0023 std::string("A202011171238")
|
||||
#define CM_ARGB_FW0028 std::string("A202105291658")
|
||||
#define CM_ARGB_BRIGHTNESS_MAX 255
|
||||
#define CM_ARGB_FW0000 std::string("A201804091608")
|
||||
#define CM_ARGB_FW0023 std::string("A202011171238")
|
||||
#define CM_ARGB_FW0028 std::string("A202105291658")
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -45,22 +46,13 @@ enum
|
||||
CM_ARGB_BLUE_BYTE = 11
|
||||
};
|
||||
|
||||
struct argb_headers
|
||||
enum
|
||||
{
|
||||
const char* name;
|
||||
unsigned char header;
|
||||
bool digital;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
static argb_headers argb_header_data[] =
|
||||
{
|
||||
{ "RGB Header", 0xFE, false, 1 },
|
||||
{ "Digital ARGB1", 0x01, true, 12 },
|
||||
{ "Digital ARGB2", 0x02, true, 12 },
|
||||
{ "Digital ARGB3", 0x04, true, 12 },
|
||||
{ "Digital ARGB4", 0x08, true, 12 },
|
||||
//{ "All Digital ARGB", 0xFF, true, 12 }
|
||||
CM_ARGB_PORT_ARGB_1 = 0x01,
|
||||
CM_ARGB_PORT_ARGB_2 = 0x02,
|
||||
CM_ARGB_PORT_ARGB_3 = 0x04,
|
||||
CM_ARGB_PORT_ARGB_4 = 0x08,
|
||||
CM_ARGB_PORT_RGB = 0xFE,
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -101,40 +93,44 @@ enum
|
||||
class CMARGBController
|
||||
{
|
||||
public:
|
||||
CMARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx, std::shared_ptr<std::mutex> cm_mutex);
|
||||
CMARGBController(hid_device* dev_handle, char* path);
|
||||
~CMARGBController();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetSerial();
|
||||
std::string GetLocation();
|
||||
std::string GetVersion();
|
||||
|
||||
unsigned char GetZoneIndex();
|
||||
unsigned char GetMode();
|
||||
unsigned char GetLedRed();
|
||||
unsigned char GetLedGreen();
|
||||
unsigned char GetLedBlue();
|
||||
unsigned char GetLedSpeed();
|
||||
bool GetRandomColours();
|
||||
void SetLedCount(int zone, int led_count);
|
||||
void SetMode(uint8_t mode, uint8_t speed, uint8_t brightness, RGBColor colour, bool random_colours);
|
||||
void SetLedsDirect(RGBColor * led_colours, unsigned int led_count);
|
||||
void GetPortStatus
|
||||
(
|
||||
unsigned char port_idx,
|
||||
unsigned char* port_mode,
|
||||
unsigned char* port_speed,
|
||||
unsigned char* port_brightness,
|
||||
bool* port_random,
|
||||
unsigned char* port_red,
|
||||
unsigned char* port_green,
|
||||
unsigned char* port_blue
|
||||
);
|
||||
|
||||
void SetPortLEDCount(unsigned char port_idx, unsigned char led_count);
|
||||
|
||||
void SetPortMode
|
||||
(
|
||||
unsigned char port_idx,
|
||||
unsigned char port_mode,
|
||||
unsigned char port_speed,
|
||||
unsigned char port_brightness,
|
||||
bool port_random,
|
||||
unsigned char port_red,
|
||||
unsigned char port_green,
|
||||
unsigned char port_blue
|
||||
);
|
||||
|
||||
void SetPortLEDsDirect(unsigned char port_idx, RGBColor *led_colours, unsigned int led_count);
|
||||
|
||||
private:
|
||||
std::string device_name;
|
||||
std::string location;
|
||||
hid_device* dev;
|
||||
std::shared_ptr<std::mutex> mutex_ptr;
|
||||
|
||||
unsigned char zone_index;
|
||||
unsigned char current_mode;
|
||||
unsigned char current_speed;
|
||||
|
||||
unsigned char current_red;
|
||||
unsigned char current_green;
|
||||
unsigned char current_blue;
|
||||
unsigned char current_brightness;
|
||||
bool bool_random;
|
||||
|
||||
void GetStatus();
|
||||
void SendUpdate();
|
||||
hid_device* dev;
|
||||
std::string device_name;
|
||||
std::string location;
|
||||
};
|
||||
|
||||
+327
-315
@@ -27,268 +27,220 @@
|
||||
RGBController_CMARGBController::RGBController_CMARGBController(CMARGBController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
unsigned char speed = controller->GetLedSpeed();
|
||||
|
||||
name = argb_header_data[controller->GetZoneIndex()].name;
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Cooler Master";
|
||||
type = DEVICE_TYPE_LEDSTRIP;
|
||||
description = controller->GetDeviceName();
|
||||
version = "3.0 for FW0028";
|
||||
description = "Cooler Master ARGB Controller Device";
|
||||
version = controller->GetVersion();
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
if(argb_header_data[controller->GetZoneIndex()].digital)
|
||||
{
|
||||
mode Off;
|
||||
Off.name = "Turn Off";
|
||||
Off.value = CM_ARGB_MODE_OFF;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
/*-----------------------------------------------------*\
|
||||
| The ARGB ports support more modes than the RGB port. |
|
||||
| Define all of the modes the ARGB ports support and |
|
||||
| map RGB modes to them as best as we can. Per-zone |
|
||||
| support will be added in the future. |
|
||||
\*-----------------------------------------------------*/
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = CM_ARGB_MODE_OFF;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Reload;
|
||||
Reload.name = "Reload";
|
||||
Reload.value = CM_ARGB_MODE_RELOAD;
|
||||
Reload.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Reload.colors_min = 1;
|
||||
Reload.colors_max = 1;
|
||||
Reload.colors.resize(Reload.colors_max);
|
||||
Reload.brightness_min = 0;
|
||||
Reload.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Reload.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Reload.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Reload.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Reload.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Reload.speed = speed;
|
||||
modes.push_back(Reload);
|
||||
mode Reload;
|
||||
Reload.name = "Reload";
|
||||
Reload.value = CM_ARGB_MODE_RELOAD;
|
||||
Reload.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Reload.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Reload.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Reload.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Reload.brightness_min = 0;
|
||||
Reload.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Reload.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Reload.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Reload.colors_min = 1;
|
||||
Reload.colors_max = 1;
|
||||
Reload.colors.resize(Reload.colors_max);
|
||||
modes.push_back(Reload);
|
||||
|
||||
mode Recoil;
|
||||
Recoil.name = "Recoil";
|
||||
Recoil.value = CM_ARGB_MODE_RECOIL;
|
||||
Recoil.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Recoil.colors_min = 1;
|
||||
Recoil.colors_max = 1;
|
||||
Recoil.colors.resize(Recoil.colors_max);
|
||||
Recoil.brightness_min = 0;
|
||||
Recoil.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Recoil.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Recoil.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Recoil.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Recoil.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Recoil.speed = speed;
|
||||
modes.push_back(Recoil);
|
||||
mode Recoil;
|
||||
Recoil.name = "Recoil";
|
||||
Recoil.value = CM_ARGB_MODE_RECOIL;
|
||||
Recoil.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Recoil.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Recoil.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Recoil.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Recoil.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Recoil.brightness_min = 0;
|
||||
Recoil.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Recoil.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Recoil.colors_min = 1;
|
||||
Recoil.colors_max = 1;
|
||||
Recoil.colors.resize(Recoil.colors_max);
|
||||
modes.push_back(Recoil);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CM_ARGB_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(Breathing.colors_max);
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Breathing.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Breathing.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Breathing.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.speed = speed;
|
||||
modes.push_back(Breathing);
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CM_ARGB_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Breathing.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Breathing.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Breathing.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(Breathing.colors_max);
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Refill;
|
||||
Refill.name = "Refill";
|
||||
Refill.value = CM_ARGB_MODE_REFILL;
|
||||
Refill.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Refill.colors_min = 1;
|
||||
Refill.colors_max = 1;
|
||||
Refill.colors.resize(Refill.colors_max);
|
||||
Refill.brightness_min = 0;
|
||||
Refill.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Refill.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Refill.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Refill.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Refill.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Refill.speed = speed;
|
||||
modes.push_back(Refill);
|
||||
mode Refill;
|
||||
Refill.name = "Refill";
|
||||
Refill.value = CM_ARGB_MODE_REFILL;
|
||||
Refill.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Refill.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Refill.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Refill.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Refill.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Refill.brightness_min = 0;
|
||||
Refill.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Refill.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Refill.colors_min = 1;
|
||||
Refill.colors_max = 1;
|
||||
Refill.colors.resize(Refill.colors_max);
|
||||
modes.push_back(Refill);
|
||||
|
||||
mode Demo;
|
||||
Demo.name = "Demo";
|
||||
Demo.value = CM_ARGB_MODE_DEMO;
|
||||
Demo.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Demo.brightness_min = 0;
|
||||
Demo.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Demo.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Demo.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Demo.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Demo.color_mode = MODE_COLORS_NONE;
|
||||
Demo.speed = speed;
|
||||
modes.push_back(Demo);
|
||||
mode Demo;
|
||||
Demo.name = "Demo";
|
||||
Demo.value = CM_ARGB_MODE_DEMO;
|
||||
Demo.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Demo.color_mode = MODE_COLORS_NONE;
|
||||
Demo.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Demo.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Demo.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Demo.brightness_min = 0;
|
||||
Demo.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Demo.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
modes.push_back(Demo);
|
||||
|
||||
mode Spectrum;
|
||||
Spectrum.name = "Spectrum";
|
||||
Spectrum.value = CM_ARGB_MODE_SPECTRUM;
|
||||
Spectrum.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Spectrum.brightness_min = 0;
|
||||
Spectrum.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Spectrum.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Spectrum.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Spectrum.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Spectrum.color_mode = MODE_COLORS_NONE;
|
||||
Spectrum.speed = speed;
|
||||
modes.push_back(Spectrum);
|
||||
mode Spectrum;
|
||||
Spectrum.name = "Rainbow Wave";
|
||||
Spectrum.value = CM_ARGB_MODE_SPECTRUM;
|
||||
Spectrum.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Spectrum.color_mode = MODE_COLORS_NONE;
|
||||
Spectrum.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Spectrum.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Spectrum.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Spectrum.brightness_min = 0;
|
||||
Spectrum.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Spectrum.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
modes.push_back(Spectrum);
|
||||
|
||||
mode FillFlow;
|
||||
FillFlow.name = "Fill Flow";
|
||||
FillFlow.value = CM_ARGB_MODE_FILLFLOW;
|
||||
FillFlow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
FillFlow.brightness_min = 0;
|
||||
FillFlow.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
FillFlow.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
FillFlow.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
FillFlow.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
FillFlow.color_mode = MODE_COLORS_NONE;
|
||||
FillFlow.speed = speed;
|
||||
modes.push_back(FillFlow);
|
||||
mode FillFlow;
|
||||
FillFlow.name = "Fill Flow";
|
||||
FillFlow.value = CM_ARGB_MODE_FILLFLOW;
|
||||
FillFlow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
FillFlow.color_mode = MODE_COLORS_NONE;
|
||||
FillFlow.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
FillFlow.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
FillFlow.speed = CM_ARGB_SPEED_NORMAL;
|
||||
FillFlow.brightness_min = 0;
|
||||
FillFlow.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
FillFlow.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
modes.push_back(FillFlow);
|
||||
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.value = CM_ARGB_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Rainbow.brightness_min = 0;
|
||||
Rainbow.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Rainbow.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Rainbow.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Rainbow.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
Rainbow.speed = speed;
|
||||
modes.push_back(Rainbow);
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.value = CM_ARGB_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
Rainbow.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Rainbow.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Rainbow.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Rainbow.brightness_min = 0;
|
||||
Rainbow.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Rainbow.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = CM_ARGB_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(Static.colors_max);
|
||||
Static.brightness_min = 0;
|
||||
Static.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Static.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Static.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Static.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.speed = speed;
|
||||
modes.push_back(Static);
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = CM_ARGB_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Static.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Static.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Static.brightness_min = 0;
|
||||
Static.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Static.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(Static.colors_max);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Direct;
|
||||
Direct.name = (serial >= CM_ARGB_FW0028) ? "Direct" : "Custom";
|
||||
Direct.value = CM_ARGB_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
mode Direct;
|
||||
Direct.name = (serial >= CM_ARGB_FW0028) ? "Direct" : "Custom";
|
||||
Direct.value = CM_ARGB_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode PassThru;
|
||||
PassThru.name = "Pass Thru";
|
||||
PassThru.value = CM_ARGB_MODE_PASSTHRU;
|
||||
PassThru.flags = 0;
|
||||
PassThru.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(PassThru);
|
||||
}
|
||||
else
|
||||
{
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = CM_RGB_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(Static.colors_max);
|
||||
Static.brightness_min = 0;
|
||||
Static.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Static.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.speed = 0;
|
||||
modes.push_back(Static);
|
||||
mode PassThru;
|
||||
PassThru.name = "Pass Thru";
|
||||
PassThru.value = CM_ARGB_MODE_PASSTHRU;
|
||||
PassThru.flags = 0;
|
||||
PassThru.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(PassThru);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CM_RGB_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(Breathing.colors_max);
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Breathing.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Breathing.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Breathing.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.speed = CM_ARGB_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Flash;
|
||||
Flash.name = "Flash";
|
||||
Flash.value = CM_RGB_MODE_FLASH;
|
||||
Flash.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Flash.colors_min = 1;
|
||||
Flash.colors_max = 1;
|
||||
Flash.colors.resize(Flash.colors_max);
|
||||
Flash.brightness_min = 0;
|
||||
Flash.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Flash.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Flash.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Flash.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Flash.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Flash.speed = CM_ARGB_SPEED_NORMAL;
|
||||
modes.push_back(Flash);
|
||||
|
||||
mode Mirage;
|
||||
Mirage.name = "Mirage";
|
||||
Mirage.value = CM_RGB_MODE_MIRAGE;
|
||||
Mirage.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Mirage.colors_min = 1;
|
||||
Mirage.colors_max = 1;
|
||||
Mirage.colors.resize(Mirage.colors_max);
|
||||
Mirage.brightness_min = 0;
|
||||
Mirage.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Mirage.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Mirage.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Mirage.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Mirage.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Mirage.speed = CM_ARGB_SPEED_NORMAL;
|
||||
modes.push_back(Mirage);
|
||||
|
||||
mode PassThru;
|
||||
PassThru.name = "Pass Thru";
|
||||
PassThru.value = CM_RGB_MODE_PASSTHRU;
|
||||
PassThru.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(PassThru);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Turn Off";
|
||||
Off.value = CM_RGB_MODE_OFF;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
}
|
||||
|
||||
Init_Controller();
|
||||
SetupZones();
|
||||
|
||||
int temp_mode = controller->GetMode();
|
||||
for(int mode_idx = 0; mode_idx < (int)modes.size() ; mode_idx++)
|
||||
/*-----------------------------------------------------*\
|
||||
| Initialize the active mode to port 0 |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char port_mode;
|
||||
unsigned char port_speed;
|
||||
unsigned char port_brightness;
|
||||
bool port_random;
|
||||
unsigned char port_red;
|
||||
unsigned char port_green;
|
||||
unsigned char port_blue;
|
||||
|
||||
controller->GetPortStatus(0, &port_mode, &port_speed, &port_brightness, &port_random, &port_red, &port_green, &port_blue);
|
||||
|
||||
for(std::size_t mode_idx = 0; mode_idx < modes.size(); mode_idx++)
|
||||
{
|
||||
if (temp_mode == modes[mode_idx].value)
|
||||
if(modes[mode_idx].value == port_mode)
|
||||
{
|
||||
active_mode = mode_idx;
|
||||
active_mode = (int)mode_idx;
|
||||
|
||||
if((modes[mode_idx].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR) && (modes[mode_idx].colors.size() > 0))
|
||||
{
|
||||
modes[mode_idx].colors[0] = ToRGBColor(port_red, port_green, port_blue);
|
||||
}
|
||||
|
||||
if(modes[mode_idx].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
modes[mode_idx].speed = port_speed;
|
||||
}
|
||||
|
||||
if(modes[mode_idx].flags & MODE_FLAG_HAS_BRIGHTNESS)
|
||||
{
|
||||
modes[mode_idx].brightness = port_brightness;
|
||||
}
|
||||
|
||||
if(modes[mode_idx].flags & MODE_FLAG_HAS_RANDOM_COLOR)
|
||||
{
|
||||
if(port_random)
|
||||
{
|
||||
modes[mode_idx].color_mode = MODE_COLORS_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (modes[active_mode].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
|
||||
{
|
||||
modes[active_mode].colors[0] = ToRGBColor(controller->GetLedRed(), controller->GetLedGreen(), controller->GetLedBlue());
|
||||
modes[active_mode].color_mode = (controller->GetRandomColours()) ? MODE_COLORS_RANDOM : MODE_COLORS_MODE_SPECIFIC;
|
||||
}
|
||||
if (modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
modes[active_mode].speed = controller->GetLedSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
RGBController_CMARGBController::~RGBController_CMARGBController()
|
||||
@@ -296,68 +248,76 @@ RGBController_CMARGBController::~RGBController_CMARGBController()
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CMARGBController::Init_Controller()
|
||||
{
|
||||
int zone_idx = controller->GetZoneIndex();
|
||||
int zone_led_count = argb_header_data[zone_idx].count;
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| If argb_header_data[zone_idx].count == 1 then the |
|
||||
| zone is ZONE_TYPE_SINGLE |
|
||||
\*-------------------------------------------------*/
|
||||
bool boolSingleLED = ( zone_led_count == 1 );
|
||||
|
||||
zone ARGB_zone;
|
||||
ARGB_zone.name = std::to_string(zone_idx);
|
||||
ARGB_zone.type = (boolSingleLED) ? ZONE_TYPE_SINGLE : ZONE_TYPE_LINEAR;
|
||||
ARGB_zone.leds_min = 4;
|
||||
ARGB_zone.leds_max = 48;
|
||||
ARGB_zone.leds_count = zone_led_count;
|
||||
ARGB_zone.matrix_map = NULL;
|
||||
zones.push_back(ARGB_zone);
|
||||
}
|
||||
|
||||
void RGBController_CMARGBController::SetupZones()
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Clear any existing color/LED configuration |
|
||||
\*-------------------------------------------------*/
|
||||
/*-----------------------------------------------------*\
|
||||
| Only set LED count on the first run |
|
||||
\*-----------------------------------------------------*/
|
||||
bool first_run = false;
|
||||
|
||||
if(zones.size() == 0)
|
||||
{
|
||||
first_run = true;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Clear any existing color/LED configuration |
|
||||
\*-----------------------------------------------------*/
|
||||
leds.clear();
|
||||
colors.clear();
|
||||
zones.resize(5);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up addressable zones |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int channel_idx = 0; channel_idx < 4; channel_idx++)
|
||||
{
|
||||
bool boolSingleLED = (zones[zone_idx].type == ZONE_TYPE_SINGLE);
|
||||
char ch_idx_string[2];
|
||||
snprintf(ch_idx_string, 2, "%d", channel_idx + 1);
|
||||
|
||||
if (!boolSingleLED)
|
||||
zones[channel_idx].name = "Addressable RGB Header ";
|
||||
zones[channel_idx].name.append(ch_idx_string);
|
||||
zones[channel_idx].type = ZONE_TYPE_LINEAR;
|
||||
zones[channel_idx].leds_min = 0;
|
||||
zones[channel_idx].leds_max = 48;
|
||||
|
||||
if(first_run)
|
||||
{
|
||||
controller->SetLedCount( std::stoi(zones[zone_idx].name), zones[zone_idx].leds_count);
|
||||
zones[channel_idx].leds_count = 0;
|
||||
}
|
||||
|
||||
for(unsigned int lp_idx = 0; lp_idx < zones[zone_idx].leds_count; lp_idx++)
|
||||
{
|
||||
led new_led;
|
||||
unsigned int i = std::stoi(zones[zone_idx].name);
|
||||
zones[channel_idx].matrix_map = NULL;
|
||||
|
||||
if(boolSingleLED)
|
||||
{
|
||||
new_led.name = i;
|
||||
new_led.value = argb_header_data[i].header;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_led.name = i;
|
||||
new_led.name.append(" LED " + std::to_string(lp_idx));
|
||||
new_led.value = argb_header_data[i].header;
|
||||
}
|
||||
for(unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++)
|
||||
{
|
||||
char led_idx_string[4];
|
||||
snprintf(led_idx_string, 4, "%d", led_ch_idx + 1);
|
||||
|
||||
led new_led;
|
||||
new_led.name = zones[channel_idx].name;
|
||||
new_led.name.append(", LED ");
|
||||
new_led.name.append(led_idx_string);
|
||||
new_led.value = channel_idx;
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up RGB zone |
|
||||
\*-----------------------------------------------------*/
|
||||
zones[4].name = "RGB Header";
|
||||
zones[4].type = ZONE_TYPE_SINGLE;
|
||||
zones[4].leds_min = 1;
|
||||
zones[4].leds_max = 1;
|
||||
zones[4].leds_count = 1;
|
||||
zones[4].matrix_map = NULL;
|
||||
|
||||
led new_led;
|
||||
new_led.name = "RGB Header";
|
||||
new_led.value = 4;
|
||||
leds.push_back(new_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
@@ -367,62 +327,114 @@ void RGBController_CMARGBController::ResizeZone(int zone, int new_size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint8_t end_zone = last_zone(zone);
|
||||
|
||||
for(std::size_t zone_idx = first_zone(zone); zone_idx < end_zone; zone_idx++)
|
||||
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
|
||||
{
|
||||
if(((unsigned int)new_size >= zones[zone_idx].leds_min) && ((unsigned int)new_size <= zones[zone_idx].leds_max))
|
||||
{
|
||||
zones[zone_idx].leds_count = new_size;
|
||||
}
|
||||
}
|
||||
zones[zone].leds_count = new_size;
|
||||
|
||||
SetupZones();
|
||||
controller->SetPortLEDCount(zone, zones[zone].leds_count);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMARGBController::DeviceUpdateLEDs()
|
||||
{
|
||||
uint8_t end_zone = last_zone(cmargb->GetZoneIndex());
|
||||
|
||||
for(int zone_idx = first_zone(cmargb->GetZoneIndex()); zone_idx < end_zone; zone_idx++)
|
||||
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
UpdateZoneLEDs(zone_idx);
|
||||
UpdateZoneLEDs((int)zone_idx);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMARGBController::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
controller->SetLedsDirect( zones[zone].colors, zones[zone].leds_count );
|
||||
/*-----------------------------------------------------*\
|
||||
| The RGB zone doesn't have a separate Direct mode, so |
|
||||
| use static mode with the per-LED color for it |
|
||||
\*-----------------------------------------------------*/
|
||||
if(zone < 4)
|
||||
{
|
||||
controller->SetPortLEDsDirect(zone, zones[zone].colors, zones[zone].leds_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetPortMode(zone, CM_RGB_MODE_STATIC, 0, 255, false, RGBGetRValue(zones[zone].colors[0]), RGBGetGValue(zones[zone].colors[0]), RGBGetBValue(zones[zone].colors[0]));
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMARGBController::UpdateSingleLED(int led)
|
||||
{
|
||||
UpdateZoneLEDs(GetLED_Zone(led));
|
||||
unsigned int zone_idx = leds[led].value;
|
||||
|
||||
UpdateZoneLEDs(zone_idx);
|
||||
}
|
||||
|
||||
void RGBController_CMARGBController::DeviceUpdateMode()
|
||||
{
|
||||
bool random_colours = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
|
||||
RGBColor colour = (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) ? modes[active_mode].colors[0] : 0;
|
||||
/*-----------------------------------------------------*\
|
||||
| Determine mode parameters |
|
||||
\*-----------------------------------------------------*/
|
||||
bool random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
|
||||
RGBColor color = (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) ? modes[active_mode].colors[0] : 0;
|
||||
int rgb_mode;
|
||||
bool rgb_random = random;
|
||||
|
||||
controller->SetMode( modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, colour, random_colours );
|
||||
}
|
||||
|
||||
int RGBController_CMARGBController::GetLED_Zone(int led_idx)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This may be more useful in the abstract RGBController.cpp |
|
||||
\*---------------------------------------------------------*/
|
||||
for(int zone_idx = 0; zone_idx < (int)zones.size(); zone_idx++)
|
||||
/*-----------------------------------------------------*\
|
||||
| Map ARGB modes with the equivalent RGB modes |
|
||||
\*-----------------------------------------------------*/
|
||||
switch(modes[active_mode].value)
|
||||
{
|
||||
int zone_start = zones[zone_idx].start_idx;
|
||||
int zone_end = zone_start + zones[zone_idx].leds_count - 1;
|
||||
case CM_ARGB_MODE_SPECTRUM:
|
||||
case CM_ARGB_MODE_FILLFLOW:
|
||||
case CM_ARGB_MODE_RAINBOW:
|
||||
rgb_mode = CM_RGB_MODE_MIRAGE;
|
||||
rgb_random = true;
|
||||
break;
|
||||
|
||||
if(zone_start <= led_idx && zone_end >= led_idx)
|
||||
{
|
||||
return(zone_idx);
|
||||
}
|
||||
case CM_ARGB_MODE_RELOAD:
|
||||
case CM_ARGB_MODE_RECOIL:
|
||||
rgb_mode = CM_RGB_MODE_FLASH;
|
||||
break;
|
||||
|
||||
case CM_ARGB_MODE_BREATHING:
|
||||
rgb_mode = CM_RGB_MODE_BREATHING;
|
||||
break;
|
||||
|
||||
case CM_ARGB_MODE_REFILL:
|
||||
case CM_ARGB_MODE_STATIC:
|
||||
rgb_mode = CM_RGB_MODE_STATIC;
|
||||
break;
|
||||
|
||||
case CM_ARGB_MODE_DEMO:
|
||||
rgb_mode = CM_RGB_MODE_FLASH;
|
||||
rgb_random = true;
|
||||
break;
|
||||
|
||||
case CM_ARGB_MODE_OFF:
|
||||
default:
|
||||
rgb_mode = CM_RGB_MODE_OFF;
|
||||
break;
|
||||
|
||||
case CM_ARGB_MODE_PASSTHRU:
|
||||
rgb_mode = CM_RGB_MODE_PASSTHRU;
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
/*-----------------------------------------------------*\
|
||||
| Apply mode to all zones |
|
||||
\*-----------------------------------------------------*/
|
||||
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
controller->SetPortMode
|
||||
(
|
||||
(unsigned char)zone_idx,
|
||||
(zone_idx == 4) ? rgb_mode : modes[active_mode].value,
|
||||
modes[active_mode].speed,
|
||||
modes[active_mode].brightness,
|
||||
(zone_idx == 4) ? rgb_random : random,
|
||||
RGBGetRValue(color),
|
||||
RGBGetGValue(color),
|
||||
RGBGetBValue(color)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-9
@@ -12,11 +12,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "RGBController.h"
|
||||
#include "CMARGBController.h"
|
||||
|
||||
#define first_zone(zn) ((zones.size() > 1) ? 1 : 0)
|
||||
#define last_zone(zn) ((zones.size() > 1) ? 4 : 1)
|
||||
#include "RGBController.h"
|
||||
|
||||
class RGBController_CMARGBController : public RGBController
|
||||
{
|
||||
@@ -34,9 +31,6 @@ public:
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
void Init_Controller();
|
||||
int GetDeviceMode();
|
||||
int GetLED_Zone(int led_idx);
|
||||
|
||||
CMARGBController* controller;
|
||||
CMARGBController* controller;
|
||||
std::vector<unsigned int> leds_channel;
|
||||
};
|
||||
|
||||
@@ -96,19 +96,18 @@ void DetectCoolerMasterARGB(hid_device_info* info, const std::string&)
|
||||
|
||||
if(dev)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Create mutex to prevent the controllers sharing a |
|
||||
| receiver from interfering with each other |
|
||||
\*-------------------------------------------------*/
|
||||
std::shared_ptr<std::mutex> cm_mutex = std::make_shared<std::mutex>();
|
||||
CMARGBController* controller = new CMARGBController(dev, info->path);
|
||||
|
||||
for(unsigned char i = 0; i < CM_ARGB_HEADER_DATA_SIZE; i++)
|
||||
if(controller->GetVersion() != "Unsupported")
|
||||
{
|
||||
CMARGBController* controller = new CMARGBController(dev, info->path, i, cm_mutex);
|
||||
RGBController_CMARGBController* rgb_controller = new RGBController_CMARGBController(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("[CMARGBController] Unsupported firmware version");
|
||||
delete controller;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,489 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairDRAMController.cpp |
|
||||
| |
|
||||
| Driver for Corsair DRAM RGB controllers |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 30 Jun 2019 |
|
||||
| Erik Gilling (konkers) 25 Sep 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "CRC.h"
|
||||
#include "CorsairDRAMController.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
#define CORSAIR_DRAM_NAME "Corsair DRAM"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
CorsairDRAMController::CorsairDRAMController(i2c_smbus_interface *bus, corsair_dev_id dev)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Initialize class variables |
|
||||
\*-----------------------------------------------------*/
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
device_index = 0;
|
||||
direct_mode = true;
|
||||
pid = 0;
|
||||
vid = 0;
|
||||
protocol_version = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read device information |
|
||||
\*-----------------------------------------------------*/
|
||||
ReadDeviceInfo();
|
||||
}
|
||||
|
||||
CorsairDRAMController::~CorsairDRAMController()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int CorsairDRAMController::GetLEDCount()
|
||||
{
|
||||
return(corsair_dram_device_list[device_index]->led_count);
|
||||
}
|
||||
|
||||
unsigned char CorsairDRAMController::GetProtocolVersion()
|
||||
{
|
||||
return(protocol_version);
|
||||
}
|
||||
|
||||
std::string CorsairDRAMController::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("I2C: " + return_string);
|
||||
}
|
||||
|
||||
std::string CorsairDRAMController::GetDeviceName()
|
||||
{
|
||||
return(corsair_dram_device_list[device_index]->name);
|
||||
}
|
||||
|
||||
std::string CorsairDRAMController::GetDeviceVersion()
|
||||
{
|
||||
return(firmware_version);
|
||||
}
|
||||
|
||||
void CorsairDRAMController::SetColorsPerLED(RGBColor* colors)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Get LED count from device list |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned int led_count = corsair_dram_device_list[device_index]->led_count;
|
||||
|
||||
if(direct_mode)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Sanity check - Direct mode can only be used on |
|
||||
| protocol 4+ |
|
||||
\*-------------------------------------------------*/
|
||||
if(protocol_version < 4)
|
||||
{
|
||||
LOG_ERROR("[%s] Protocol version %d tried to use direct mode, ignoring", CORSAIR_DRAM_NAME, protocol_version);
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Packet format: |
|
||||
| Size n is (LED count * 3) + 2 |
|
||||
| 0: Command byte (0x0A or 0x0C) |
|
||||
| 1 to (n-2): LED color data in R/G/B order |
|
||||
| (n-1): CRC8 of bytes 0 to (n-2) |
|
||||
\*-------------------------------------------------*/
|
||||
unsigned int direct_packet_size = (led_count * 3) + 2;
|
||||
unsigned char* direct_packet = new unsigned char[direct_packet_size];
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| First byte in packet is LED count |
|
||||
\*-------------------------------------------------*/
|
||||
direct_packet[0] = led_count;
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Fill in LED data |
|
||||
\*-------------------------------------------------*/
|
||||
for(unsigned int led_idx = 0; led_idx < led_count; led_idx++)
|
||||
{
|
||||
unsigned int color_index = led_idx;
|
||||
unsigned int offset = (led_idx * 3) + 1;
|
||||
|
||||
if(corsair_dram_device_list[device_index]->reverse)
|
||||
{
|
||||
color_index = (led_count -1) - led_idx;
|
||||
}
|
||||
|
||||
direct_packet[offset + 0] = RGBGetRValue(colors[color_index]);
|
||||
direct_packet[offset + 1] = RGBGetGValue(colors[color_index]);
|
||||
direct_packet[offset + 2] = RGBGetBValue(colors[color_index]);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Last byte in packet is CRC of all data up to it |
|
||||
\*-------------------------------------------------*/
|
||||
direct_packet[direct_packet_size - 1] = CRCPP::CRC::Calculate(direct_packet, (direct_packet_size - 1), CRCPP::CRC::CRC_8());
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Write using block writes, if packet exceeds 32 |
|
||||
| bytes, use a second block write to the second |
|
||||
| block write address for the remaining data |
|
||||
\*-------------------------------------------------*/
|
||||
s32 ret = bus->i2c_smbus_write_block_data(dev, CORSAIR_DRAM_REG_COLOR_BUFFER_BLOCK_1, 32, direct_packet);
|
||||
|
||||
if((ret >= 0) && (direct_packet_size > 32))
|
||||
{
|
||||
bus->i2c_smbus_write_block_data(dev, CORSAIR_DRAM_REG_COLOR_BUFFER_BLOCK_2, direct_packet_size - 32, direct_packet + 32);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Corsair DRAM supports an alternate means of |
|
||||
| writing block data without using SMBus block |
|
||||
| operations. If block operations are not |
|
||||
| available, fall back to this scheme. |
|
||||
| |
|
||||
| Blocks are split up into word data writes. |
|
||||
| Some data bytes are packed into the lower nibble |
|
||||
| of the register address byte. |
|
||||
\*-------------------------------------------------*/
|
||||
if(ret < 0)
|
||||
{
|
||||
unsigned int block_index = 0;
|
||||
bool even_frame = true;
|
||||
bool first_frame = true;
|
||||
|
||||
while(block_index < direct_packet_size)
|
||||
{
|
||||
unsigned char reg_value_0 = 0xA0;
|
||||
unsigned char reg_value_1 = 0x00;
|
||||
unsigned short word_value_0 = 0;
|
||||
unsigned short word_value_1 = 0;
|
||||
|
||||
if(block_index == 0)
|
||||
{
|
||||
reg_value_0 = 0x90;
|
||||
}
|
||||
|
||||
word_value_0 = (direct_packet[block_index]);
|
||||
block_index++;
|
||||
|
||||
if(block_index < direct_packet_size)
|
||||
{
|
||||
word_value_0 |= (direct_packet[block_index] << 8);
|
||||
block_index++;
|
||||
}
|
||||
|
||||
if(block_index < direct_packet_size)
|
||||
{
|
||||
reg_value_1 = 0xA0;
|
||||
reg_value_0 |= (direct_packet[block_index] & 0x0F);
|
||||
reg_value_1 |= (direct_packet[block_index] & 0xF0) >> 4;
|
||||
block_index++;
|
||||
}
|
||||
|
||||
if(block_index < direct_packet_size)
|
||||
{
|
||||
word_value_1 = (direct_packet[block_index]);
|
||||
block_index++;
|
||||
}
|
||||
|
||||
if(block_index < direct_packet_size)
|
||||
{
|
||||
word_value_1 |= (direct_packet[block_index] << 8);
|
||||
block_index++;
|
||||
}
|
||||
|
||||
bus->i2c_smbus_write_word_data(dev, reg_value_0, word_value_0);
|
||||
|
||||
if(reg_value_1 > 0)
|
||||
{
|
||||
bus->i2c_smbus_write_word_data(dev, reg_value_1, word_value_1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Remember to delete the data buffer |
|
||||
\*-------------------------------------------------*/
|
||||
delete[] direct_packet;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Local variables |
|
||||
\*-------------------------------------------------*/
|
||||
unsigned char device_crc;
|
||||
unsigned char calc_crc;
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Packet format: |
|
||||
| Size n is (LED count * 4) |
|
||||
| Format is 0xRR, 0xGG, 0xBB, 0xFF for each LED |
|
||||
\*-------------------------------------------------*/
|
||||
unsigned int color_data_size = (led_count * 4);
|
||||
unsigned char* color_data_packet = new unsigned char[color_data_size];
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < led_count; led_idx++)
|
||||
{
|
||||
unsigned int color_index = led_idx;
|
||||
|
||||
if(corsair_dram_device_list[device_index]->reverse)
|
||||
{
|
||||
color_index = (led_count -1) - led_idx;
|
||||
}
|
||||
|
||||
color_data_packet[(led_idx * 4) + 0] = RGBGetRValue(colors[color_index]);
|
||||
color_data_packet[(led_idx * 4) + 1] = RGBGetGValue(colors[color_index]);
|
||||
color_data_packet[(led_idx * 4) + 2] = RGBGetBValue(colors[color_index]);
|
||||
color_data_packet[(led_idx * 4) + 3] = 0xFF;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Write LED color data packet |
|
||||
\*-------------------------------------------------*/
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_DRAM_REG_RESET_BUFFER, 0x00);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_DRAM_REG_BINARY_START, 0x00);
|
||||
|
||||
for(unsigned int i = 0; i < color_data_size; i++)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_DRAM_REG_SET_BINARY_DATA, color_data_packet[i]);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Calculate CRC and read CRC reported by device |
|
||||
\*-------------------------------------------------*/
|
||||
calc_crc = CRCPP::CRC::Calculate(color_data_packet, color_data_size, CRCPP::CRC::CRC_8());
|
||||
device_crc = bus->i2c_smbus_read_byte_data(dev, CORSAIR_DRAM_REG_GET_CHECKSUM);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Write effect configuration only if CRCs match |
|
||||
\*-------------------------------------------------*/
|
||||
if(calc_crc == device_crc)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_DRAM_REG_WRITE_CONFIGURATION, CORSAIR_DRAM_ID_COLOR_DATA);
|
||||
WaitReady();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Remember to delete the data buffer |
|
||||
\*-------------------------------------------------*/
|
||||
delete[] color_data_packet;
|
||||
}
|
||||
}
|
||||
|
||||
void CorsairDRAMController::SetDirect(bool direct)
|
||||
{
|
||||
direct_mode = direct;
|
||||
}
|
||||
|
||||
void CorsairDRAMController::SetEffect
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char direction,
|
||||
bool random,
|
||||
unsigned char brightness,
|
||||
unsigned char red1,
|
||||
unsigned char grn1,
|
||||
unsigned char blu1,
|
||||
unsigned char red2,
|
||||
unsigned char grn2,
|
||||
unsigned char blu2
|
||||
)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Local variables |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char effect_data[20];
|
||||
unsigned char device_crc;
|
||||
unsigned char calc_crc;
|
||||
unsigned char random_byte;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| If mode is direct (which is a dummy value not |
|
||||
| understood by the hardware), return. Direct mode is |
|
||||
| not set in the effect configuration. |
|
||||
\*-----------------------------------------------------*/
|
||||
direct_mode = (mode == CORSAIR_DRAM_MODE_DIRECT);
|
||||
|
||||
if(direct_mode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Determine random byte |
|
||||
\*-----------------------------------------------------*/
|
||||
if(random)
|
||||
{
|
||||
random_byte = CORSAIR_DRAM_EFFECT_RANDOM_COLORS;
|
||||
}
|
||||
else
|
||||
{
|
||||
random_byte = CORSAIR_DRAM_EFFECT_CUSTOM_COLORS;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in effect packet |
|
||||
\*-----------------------------------------------------*/
|
||||
effect_data[0] = mode; // Mode
|
||||
effect_data[1] = speed; // Speed
|
||||
effect_data[2] = random_byte; // Custom color
|
||||
effect_data[3] = direction; // Direction
|
||||
effect_data[4] = red1; // Custom color 1 red
|
||||
effect_data[5] = grn1; // Custom color 1 green
|
||||
effect_data[6] = blu1; // Custom color 1 blue
|
||||
effect_data[7] = brightness;
|
||||
effect_data[8] = red2; // Custom color 2 red
|
||||
effect_data[9] = grn2; // Custom color 2 green
|
||||
effect_data[10] = blu2; // Custom color 2 blue
|
||||
effect_data[11] = brightness;
|
||||
effect_data[12] = 0x00;
|
||||
effect_data[13] = 0x00;
|
||||
effect_data[14] = 0x00;
|
||||
effect_data[15] = 0x00;
|
||||
effect_data[16] = 0x00;
|
||||
effect_data[17] = 0x00;
|
||||
effect_data[18] = 0x00;
|
||||
effect_data[19] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Write effect packet |
|
||||
\*-----------------------------------------------------*/
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_DRAM_REG_RESET_BUFFER, 0x00);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_DRAM_REG_BINARY_START, 0x00);
|
||||
|
||||
for(unsigned int i = 0; i < 20; i++)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_DRAM_REG_SET_BINARY_DATA, effect_data[i]);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Calculate CRC and read CRC reported by device |
|
||||
\*-----------------------------------------------------*/
|
||||
calc_crc = CRCPP::CRC::Calculate(effect_data, sizeof(effect_data), CRCPP::CRC::CRC_8());
|
||||
device_crc = bus->i2c_smbus_read_byte_data(dev, CORSAIR_DRAM_REG_GET_CHECKSUM);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Write effect configuration only if CRCs match |
|
||||
\*-----------------------------------------------------*/
|
||||
if(calc_crc == device_crc)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_DRAM_REG_WRITE_CONFIGURATION, CORSAIR_DRAM_ID_EFFECT_CONFIGURATION);
|
||||
WaitReady();
|
||||
}
|
||||
}
|
||||
|
||||
bool CorsairDRAMController::WaitReady()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Poll status register 0x30; bit 3 (0x08) = busy. |
|
||||
| Device is ready when bit 3 is clear. |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int retry = 0; retry < 5; retry++)
|
||||
{
|
||||
int status = bus->i2c_smbus_read_byte_data(dev, CORSAIR_DRAM_REG_STATUS);
|
||||
|
||||
if(status >= 0 && (status & 0x08) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CorsairDRAMController::ReadDeviceInfo()
|
||||
{
|
||||
unsigned char device_information_data[32];
|
||||
unsigned char device_crc;
|
||||
unsigned char calc_crc;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Request Device Information Data |
|
||||
\*-----------------------------------------------------*/
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_DRAM_REG_GET_DEVICE_INFO, 0x00);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_DRAM_REG_BINARY_START, 0x00);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read Device Information Data |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int i = 0; i < 32; i++)
|
||||
{
|
||||
device_information_data[i] = bus->i2c_smbus_read_byte_data(dev, CORSAIR_DRAM_REG_GET_BINARY_DATA);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Compare CRC |
|
||||
\*-----------------------------------------------------*/
|
||||
calc_crc = CRCPP::CRC::Calculate(device_information_data, sizeof(device_information_data), CRCPP::CRC::CRC_8());
|
||||
device_crc = bus->i2c_smbus_read_byte_data(dev, CORSAIR_DRAM_REG_GET_CHECKSUM);
|
||||
|
||||
if(calc_crc != device_crc)
|
||||
{
|
||||
LOG_ERROR("[%s] ReadDeviceInfo CRC Mismatch", CORSAIR_DRAM_NAME);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Log Device Information Data |
|
||||
\*-----------------------------------------------------*/
|
||||
if(LogManager::get()->getLoglevel() >= LL_TRACE)
|
||||
{
|
||||
char device_info_buf[256];
|
||||
unsigned int pos;
|
||||
|
||||
pos = snprintf(device_info_buf, sizeof(device_info_buf), "%02X: ", dev);
|
||||
|
||||
for(unsigned int i = 0; i < 32; i++)
|
||||
{
|
||||
pos += snprintf(&device_info_buf[pos], sizeof(device_info_buf) - pos, "%02X ", device_information_data[i]);
|
||||
}
|
||||
|
||||
LOG_TRACE("[%s] Device Info: %s", CORSAIR_DRAM_NAME, device_info_buf);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read VID |
|
||||
\*-----------------------------------------------------*/
|
||||
vid = (device_information_data[1] << 8) | device_information_data[0];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read PID |
|
||||
\*-----------------------------------------------------*/
|
||||
pid = (device_information_data[3] << 8) | device_information_data[2];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Format Firwmare Version |
|
||||
\*-----------------------------------------------------*/
|
||||
firmware_version = std::to_string(device_information_data[9]) + "." + std::to_string(device_information_data[8]) + "." + std::to_string((device_information_data[11] << 8) | device_information_data[10]);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read Protocol Version |
|
||||
\*-----------------------------------------------------*/
|
||||
protocol_version = device_information_data[28];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Loop through all known devices to look for a PID |
|
||||
| match |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int i = 0; i < CORSAIR_DRAM_NUM_DEVICES; i++)
|
||||
{
|
||||
for(unsigned int j = 0; j < CORSAIR_DRAM_MAX_PIDS; j++)
|
||||
{
|
||||
if(corsair_dram_device_list[i]->pids[j] == pid)
|
||||
{
|
||||
/*-----------------------------------------*\
|
||||
| Set device ID |
|
||||
\*-----------------------------------------*/
|
||||
device_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairDRAMController.h |
|
||||
| |
|
||||
| Driver for Corsair DRAM RGB controllers |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 30 Jun 2019 |
|
||||
| Erik Gilling (konkers) 25 Sep 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
#include "CorsairDRAMDevices.h"
|
||||
#include "RGBController.h"
|
||||
|
||||
typedef unsigned char corsair_dev_id;
|
||||
|
||||
enum
|
||||
{ /* (*) indicates deprecated registers no longer used by iCue */
|
||||
CORSAIR_DRAM_REG_RESET_BUFFER = 0x0B, /* Reset buffer by writing 0x00 */
|
||||
CORSAIR_DRAM_REG_SET_BINARY_DATA = 0x20, /* Write byte to active binary data buffer */
|
||||
CORSAIR_DRAM_REG_BINARY_START = 0x21, /* Start binary data transfer by writing 0x00 */
|
||||
CORSAIR_DRAM_REG_SWITCH_MODE = 0x23, /* Switch between Bootloader(0x00) and Normal(0x01) */
|
||||
CORSAIR_DRAM_REG_SET_BUFFER = 0x26, /* Select configuration buffer to write by ID (*) */
|
||||
CORSAIR_DRAM_REG_STATUS = 0x30, /* Status register */
|
||||
CORSAIR_DRAM_REG_COLOR_BUFFER_BLOCK_1 = 0x31, /* Direct color buffer block register 1 */
|
||||
CORSAIR_DRAM_REG_COLOR_BUFFER_BLOCK_2 = 0x32, /* Direct color buffer block register 2 */
|
||||
CORSAIR_DRAM_REG_GET_BINARY_DATA = 0x40, /* Read byte from active binary data buffer */
|
||||
CORSAIR_DRAM_REG_BUSY_STATUS = 0x41, /* Reads nonzero while busy, zero when ready(*) */
|
||||
CORSAIR_DRAM_REG_GET_CHECKSUM = 0x42, /* Get checksum (CRC8) of active binary data buffer */
|
||||
CORSAIR_DRAM_REG_GET_DEVICE_INFO = 0x61, /* Select device info buffer */
|
||||
CORSAIR_DRAM_REG_GET_CONFIGURATION = 0x63, /* Select configuration buffer to read by ID */
|
||||
CORSAIR_DRAM_REG_WRITE_CONFIGURATION = 0x82, /* Write/Apply configuration by writing buffer ID */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_DRAM_ID_COMMAND_LIST = 0, /* Command list */
|
||||
CORSAIR_DRAM_ID_EFFECT_CONFIGURATION = 1, /* Effect configuration */
|
||||
CORSAIR_DRAM_ID_COLOR_DATA = 2, /* Color data */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_DRAM_MODE_DIRECT = 0xDD, /* Arbitrary value to compare against later. Not the actual packet */
|
||||
CORSAIR_DRAM_MODE_COLOR_SHIFT = 0x00, /* Color Shift mode */
|
||||
CORSAIR_DRAM_MODE_COLOR_PULSE = 0x01, /* Color Pulse mode */
|
||||
CORSAIR_DRAM_MODE_RAINBOW_WAVE = 0x03, /* Rainbow Wave mode */
|
||||
CORSAIR_DRAM_MODE_COLOR_WAVE = 0x04, /* Color Wave mode */
|
||||
CORSAIR_DRAM_MODE_VISOR = 0x05, /* Visor mode */
|
||||
CORSAIR_DRAM_MODE_RAIN = 0x06, /* Rain mode */
|
||||
CORSAIR_DRAM_MODE_MARQUEE = 0x07, /* Marquee mode */
|
||||
CORSAIR_DRAM_MODE_RAINBOW = 0x08, /* Rainbow mode */
|
||||
CORSAIR_DRAM_MODE_SEQUENTIAL = 0x09, /* Sequential mode */
|
||||
CORSAIR_DRAM_MODE_STATIC = 0x10, /* Static mode */
|
||||
|
||||
CORSAIR_DRAM_NUMBER_MODES = 10, /* Number of Corsair Pro modes */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_DRAM_SPEED_SLOW = 0x00, /* Slow speed */
|
||||
CORSAIR_DRAM_SPEED_MEDIUM = 0x01, /* Medium speed */
|
||||
CORSAIR_DRAM_SPEED_FAST = 0x02, /* Fast speed */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_DRAM_EFFECT_RANDOM_COLORS = 0x00, /* Random colors */
|
||||
CORSAIR_DRAM_EFFECT_CUSTOM_COLORS = 0x01, /* Custom colors */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_DRAM_DIRECTION_UP = 0x00, /* Up direction */
|
||||
CORSAIR_DRAM_DIRECTION_DOWN = 0x01, /* Down direction */
|
||||
CORSAIR_DRAM_DIRECTION_LEFT = 0x02, /* Left direction */
|
||||
CORSAIR_DRAM_DIRECTION_RIGHT = 0x03, /* Right direction */
|
||||
CORSAIR_DRAM_DIRECTION_VERTICAL = 0x01, /* Vertical direction */
|
||||
CORSAIR_DRAM_DIRECTION_HORIZONTAL = 0x03, /* Horizontal direction */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_DRAM_BRIGHTNESS_MIN = 0, /* Minimum brightness */
|
||||
CORSAIR_DRAM_BRIGHTNESS_MAX = 255, /* Maximum brightness */
|
||||
CORSAIR_DRAM_BRIGHTNESS_DEFAULT = 255, /* Default brightness */
|
||||
};
|
||||
|
||||
class CorsairDRAMController
|
||||
{
|
||||
public:
|
||||
CorsairDRAMController(i2c_smbus_interface *bus, corsair_dev_id dev);
|
||||
~CorsairDRAMController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceVersion();
|
||||
|
||||
unsigned int GetLEDCount();
|
||||
unsigned char GetProtocolVersion();
|
||||
|
||||
void SetColorsPerLED(RGBColor* colors);
|
||||
void SetDirect(bool direct);
|
||||
void SetEffect(unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char direction,
|
||||
bool random,
|
||||
unsigned char brightness,
|
||||
unsigned char red1,
|
||||
unsigned char grn1,
|
||||
unsigned char blu1,
|
||||
unsigned char red2,
|
||||
unsigned char grn2,
|
||||
unsigned char blu2);
|
||||
|
||||
bool WaitReady();
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------*\
|
||||
| I2C |
|
||||
\*-----------------------------------------------------*/
|
||||
i2c_smbus_interface* bus;
|
||||
corsair_dev_id dev;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| State tracking |
|
||||
\*-----------------------------------------------------*/
|
||||
bool direct_mode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Corsair DRAM information |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned short vid;
|
||||
unsigned short pid;
|
||||
std::string firmware_version;
|
||||
unsigned char protocol_version;
|
||||
|
||||
unsigned int device_index;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Private functions |
|
||||
\*-----------------------------------------------------*/
|
||||
void ReadDeviceInfo();
|
||||
};
|
||||
@@ -0,0 +1,89 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairDRAMControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Corsair DRAM RGB controllers |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 30 Jun 2019 |
|
||||
| Erik Gilling (konkers) 25 Sep 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <vector>
|
||||
#include "Detector.h"
|
||||
#include "CorsairDRAMController.h"
|
||||
#include "RGBController_CorsairDRAM.h"
|
||||
#include "LogManager.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include "pci_ids.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
#define CORSAIR_DRAM_NAME "Corsair DRAM"
|
||||
|
||||
bool TestForCorsairDRAMController(i2c_smbus_interface *bus, unsigned char address)
|
||||
{
|
||||
LOG_DEBUG("[%s] Trying address %02X", CORSAIR_DRAM_NAME, address);
|
||||
|
||||
int res = bus->i2c_smbus_read_byte_data(address, 0x43);
|
||||
|
||||
if(res < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!(res == 0x1A || res == 0x1B || res == 0x1C))
|
||||
{
|
||||
LOG_DEBUG("[%s] Failed: expected 0x1A, 0x1B, or 0x1C, got %04X", CORSAIR_DRAM_NAME, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x44);
|
||||
|
||||
if(!(res == 0x01 || res == 0x03 || res == 0x04))
|
||||
{
|
||||
LOG_DEBUG("[%s] Failed: expected 0x01, 0x03, or 0x04, got %04X", CORSAIR_DRAM_NAME, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DetectCorsairDRAMControllers(std::vector<i2c_smbus_interface *> &busses)
|
||||
{
|
||||
for(unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
IF_DRAM_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
|
||||
{
|
||||
LOG_DEBUG("[%s] Testing bus %d", CORSAIR_DRAM_NAME, bus);
|
||||
|
||||
std::vector<unsigned char> addresses;
|
||||
|
||||
for(unsigned char addr = 0x58; addr <= 0x5F; addr++)
|
||||
{
|
||||
addresses.push_back(addr);
|
||||
}
|
||||
|
||||
for(unsigned char addr = 0x18; addr <= 0x1F; addr++)
|
||||
{
|
||||
addresses.push_back(addr);
|
||||
}
|
||||
|
||||
for(unsigned char addr : addresses)
|
||||
{
|
||||
if(TestForCorsairDRAMController(busses[bus], addr))
|
||||
{
|
||||
CorsairDRAMController* controller = new CorsairDRAMController(busses[bus], addr);
|
||||
RGBController_CorsairDRAM* rgb_controller = new RGBController_CorsairDRAM(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_I2C_DETECTOR(CORSAIR_DRAM_NAME, DetectCorsairDRAMControllers);
|
||||
@@ -0,0 +1,163 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairDRAMDevices.cpp |
|
||||
| |
|
||||
| Device list for Corsair DRAM RGB controllers |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 07 Apr 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "CorsairDRAMDevices.h"
|
||||
|
||||
static const corsair_dram_device corsair_vengeance_pro_ddr4_device =
|
||||
{
|
||||
"Corsair Vengeance RGB Pro DDR4",
|
||||
{
|
||||
CORSAIR_VENGEANCE_PRO_DDR4_PID_1,
|
||||
CORSAIR_VENGEANCE_PRO_DDR4_PID_2,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
10,
|
||||
false
|
||||
};
|
||||
|
||||
static const corsair_dram_device corsair_dominator_platinum_ddr4_device =
|
||||
{
|
||||
"Corsair Dominator Platinum RGB DDR4",
|
||||
{
|
||||
CORSAIR_DOMINATOR_PLATINUM_DDR4_PID_1,
|
||||
CORSAIR_DOMINATOR_PLATINUM_DDR4_PID_2,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
12,
|
||||
true
|
||||
};
|
||||
|
||||
static const corsair_dram_device corsair_vengeance_pro_sl_ddr4_device =
|
||||
{
|
||||
"Corsair Vengeance RGB Pro SL DDR4",
|
||||
{
|
||||
CORSAIR_VENGEANCE_PRO_SL_DDR4_PID_1,
|
||||
CORSAIR_VENGEANCE_PRO_SL_DDR4_PID_2,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
10,
|
||||
false
|
||||
};
|
||||
|
||||
static const corsair_dram_device corsair_vengeance_rs_ddr4_device =
|
||||
{
|
||||
"Corsair Vengeance RGB RS DDR4",
|
||||
{
|
||||
CORSAIR_VENGEANCE_RS_DDR4_PID_1,
|
||||
CORSAIR_VENGEANCE_RS_DDR4_PID_2,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
6,
|
||||
false
|
||||
};
|
||||
|
||||
static const corsair_dram_device corsair_dominator_platinum_ddr5_device =
|
||||
{
|
||||
"Corsair Dominator Platinum RGB DDR5",
|
||||
{
|
||||
CORSAIR_DOMINATOR_PLATINUM_DDR5_PID_1,
|
||||
CORSAIR_DOMINATOR_PLATINUM_DDR5_PID_2,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
12,
|
||||
true
|
||||
};
|
||||
|
||||
static const corsair_dram_device corsair_dominator_titanium_ddr5_device =
|
||||
{
|
||||
"Corsair Dominator Titanium RGB DDR5",
|
||||
{
|
||||
CORSAIR_DOMINATOR_TITANIUM_DDR5_PID_1,
|
||||
CORSAIR_DOMINATOR_TITANIUM_DDR5_PID_2,
|
||||
CORSAIR_DOMINATOR_TITANIUM_DDR5_PID_3,
|
||||
CORSAIR_DOMINATOR_TITANIUM_DDR5_PID_4,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
12,
|
||||
true
|
||||
};
|
||||
|
||||
static const corsair_dram_device corsair_vengeance_ddr5_device =
|
||||
{
|
||||
"Corsair Vengeance RGB DDR5",
|
||||
{
|
||||
CORSAIR_VENGEANCE_DDR5_PID_1,
|
||||
CORSAIR_VENGEANCE_DDR5_PID_2,
|
||||
CORSAIR_VENGEANCE_DDR5_PID_3,
|
||||
CORSAIR_VENGEANCE_DDR5_PID_4,
|
||||
CORSAIR_VENGEANCE_DDR5_PID_5,
|
||||
CORSAIR_VENGEANCE_DDR5_PID_6,
|
||||
},
|
||||
10,
|
||||
false
|
||||
};
|
||||
|
||||
static const corsair_dram_device corsair_vengeance_shugo_series_ddr5_device =
|
||||
{
|
||||
"Corsair Vengeance Shugo Series DDR5",
|
||||
{
|
||||
CORSAIR_VENGEANCE_SHUGO_SERIES_DDR5_PID_1,
|
||||
CORSAIR_VENGEANCE_SHUGO_SERIES_DDR5_PID_2,
|
||||
CORSAIR_VENGEANCE_SHUGO_SERIES_DDR5_PID_3,
|
||||
CORSAIR_VENGEANCE_SHUGO_SERIES_DDR5_PID_4,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
10,
|
||||
false
|
||||
};
|
||||
|
||||
static const corsair_dram_device corsair_vengeance_rs_ddr5_device =
|
||||
{
|
||||
"Corsair Vengeance RGB RS DDR5",
|
||||
{
|
||||
CORSAIR_VENGEANCE_RS_DDR5_PID_1,
|
||||
CORSAIR_VENGEANCE_RS_DDR5_PID_2,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
6,
|
||||
false
|
||||
};
|
||||
|
||||
static const corsair_dram_device* device_list[] =
|
||||
{
|
||||
&corsair_vengeance_pro_ddr4_device,
|
||||
&corsair_dominator_platinum_ddr4_device,
|
||||
&corsair_vengeance_pro_sl_ddr4_device,
|
||||
&corsair_vengeance_rs_ddr4_device,
|
||||
&corsair_dominator_platinum_ddr5_device,
|
||||
&corsair_dominator_titanium_ddr5_device,
|
||||
&corsair_vengeance_ddr5_device,
|
||||
&corsair_vengeance_shugo_series_ddr5_device,
|
||||
&corsair_vengeance_rs_ddr5_device,
|
||||
};
|
||||
|
||||
const unsigned int CORSAIR_DRAM_NUM_DEVICES = (sizeof(device_list) / sizeof(device_list[ 0 ]));
|
||||
const corsair_dram_device** corsair_dram_device_list = device_list;
|
||||
@@ -0,0 +1,68 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairDRAMDevices.h |
|
||||
| |
|
||||
| Device list for Corsair DRAM RGB controllers |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 07 Apr 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Maximum number of PIDs for a given DRAM model |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CORSAIR_DRAM_MAX_PIDS 6
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Corsair DRAM vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CORSAIR_DRAM_VID 0x1B1C
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Corsair DRAM product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CORSAIR_VENGEANCE_PRO_DDR4_PID_1 0x0100
|
||||
#define CORSAIR_VENGEANCE_PRO_DDR4_PID_2 0x0101
|
||||
#define CORSAIR_DOMINATOR_PLATINUM_DDR4_PID_1 0x0200
|
||||
#define CORSAIR_DOMINATOR_PLATINUM_DDR4_PID_2 0x0201
|
||||
#define CORSAIR_VENGEANCE_PRO_SL_DDR4_PID_1 0x0300
|
||||
#define CORSAIR_VENGEANCE_PRO_SL_DDR4_PID_2 0x0301
|
||||
#define CORSAIR_VENGEANCE_RS_DDR4_PID_1 0x0400
|
||||
#define CORSAIR_VENGEANCE_RS_DDR4_PID_2 0x0401
|
||||
#define CORSAIR_DOMINATOR_PLATINUM_DDR5_PID_1 0x0600
|
||||
#define CORSAIR_DOMINATOR_PLATINUM_DDR5_PID_2 0x0601
|
||||
#define CORSAIR_DOMINATOR_TITANIUM_DDR5_PID_1 0x0800
|
||||
#define CORSAIR_DOMINATOR_TITANIUM_DDR5_PID_2 0x0801
|
||||
#define CORSAIR_DOMINATOR_TITANIUM_DDR5_PID_3 0x0810
|
||||
#define CORSAIR_DOMINATOR_TITANIUM_DDR5_PID_4 0x0811
|
||||
#define CORSAIR_VENGEANCE_DDR5_PID_1 0x0700
|
||||
#define CORSAIR_VENGEANCE_DDR5_PID_2 0x0701
|
||||
#define CORSAIR_VENGEANCE_DDR5_PID_3 0x0900
|
||||
#define CORSAIR_VENGEANCE_DDR5_PID_4 0x0901
|
||||
#define CORSAIR_VENGEANCE_DDR5_PID_5 0x0910
|
||||
#define CORSAIR_VENGEANCE_DDR5_PID_6 0x0911
|
||||
#define CORSAIR_VENGEANCE_SHUGO_SERIES_DDR5_PID_1 0x0A00
|
||||
#define CORSAIR_VENGEANCE_SHUGO_SERIES_DDR5_PID_2 0x0A01
|
||||
#define CORSAIR_VENGEANCE_SHUGO_SERIES_DDR5_PID_3 0x0A10
|
||||
#define CORSAIR_VENGEANCE_SHUGO_SERIES_DDR5_PID_4 0x0A11
|
||||
#define CORSAIR_VENGEANCE_RS_DDR5_PID_1 0x0B00
|
||||
#define CORSAIR_VENGEANCE_RS_DDR5_PID_2 0x0B01
|
||||
|
||||
typedef struct
|
||||
{
|
||||
std::string name;
|
||||
unsigned short pids[CORSAIR_DRAM_MAX_PIDS];
|
||||
unsigned int led_count;
|
||||
bool reverse;
|
||||
} corsair_dram_device;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| These constant values are defined in RazerDevices.cpp |
|
||||
\*-----------------------------------------------------*/
|
||||
extern const unsigned int CORSAIR_DRAM_NUM_DEVICES;
|
||||
extern const corsair_dram_device** corsair_dram_device_list;
|
||||
@@ -0,0 +1,330 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CorsairDRAM.cpp |
|
||||
| |
|
||||
| RGBController for Corsair DRAM RGB controllers |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 30 Jun 2019 |
|
||||
| Erik Gilling (konkers) 25 Sep 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_CorsairDRAM.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Corsair DRAM
|
||||
@category RAM
|
||||
@type SMBus
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectCorsairDRAMControllers
|
||||
@comment
|
||||
The Corsair DRAM RGB controller chip can be found on several
|
||||
Corsair memory sticks which have different LED counts. This can be controlled
|
||||
by editing the Part Number in OpenRGB.json with values in the below table.
|
||||
|
||||
| Part Number | LED Count |
|
||||
| :---------: | --------: |
|
||||
| CMG | 6 |
|
||||
| CMH | 10 |
|
||||
| CMN | 10 |
|
||||
| CMT | 12 |
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CorsairDRAM::RGBController_CorsairDRAM(CorsairDRAMController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Corsair";
|
||||
type = DEVICE_TYPE_DRAM;
|
||||
description = "Corsair DRAM RGB Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
version = controller->GetDeviceVersion();
|
||||
|
||||
if(controller->GetProtocolVersion() >= 4)
|
||||
{
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = CORSAIR_DRAM_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
}
|
||||
|
||||
mode Custom;
|
||||
Custom.name = "Custom";
|
||||
Custom.value = CORSAIR_DRAM_MODE_STATIC;
|
||||
Custom.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Custom.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Custom);
|
||||
|
||||
mode ColorShift;
|
||||
ColorShift.name = "Color Shift";
|
||||
ColorShift.value = CORSAIR_DRAM_MODE_COLOR_SHIFT;
|
||||
ColorShift.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
ColorShift.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
ColorShift.speed_min = CORSAIR_DRAM_SPEED_SLOW;
|
||||
ColorShift.speed_max = CORSAIR_DRAM_SPEED_FAST;
|
||||
ColorShift.speed = CORSAIR_DRAM_SPEED_SLOW;
|
||||
ColorShift.brightness_min = CORSAIR_DRAM_BRIGHTNESS_MIN;
|
||||
ColorShift.brightness_max = CORSAIR_DRAM_BRIGHTNESS_MAX;
|
||||
ColorShift.brightness = CORSAIR_DRAM_BRIGHTNESS_DEFAULT;
|
||||
ColorShift.colors_min = 2;
|
||||
ColorShift.colors_max = 2;
|
||||
ColorShift.colors.resize(2);
|
||||
modes.push_back(ColorShift);
|
||||
|
||||
mode ColorPulse;
|
||||
ColorPulse.name = "Color Pulse";
|
||||
ColorPulse.value = CORSAIR_DRAM_MODE_COLOR_PULSE;
|
||||
ColorPulse.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
ColorPulse.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
ColorPulse.speed_min = CORSAIR_DRAM_SPEED_SLOW;
|
||||
ColorPulse.speed_max = CORSAIR_DRAM_SPEED_FAST;
|
||||
ColorPulse.speed = CORSAIR_DRAM_SPEED_SLOW;
|
||||
ColorPulse.brightness_min = CORSAIR_DRAM_BRIGHTNESS_MIN;
|
||||
ColorPulse.brightness_max = CORSAIR_DRAM_BRIGHTNESS_MAX;
|
||||
ColorPulse.brightness = CORSAIR_DRAM_BRIGHTNESS_DEFAULT;
|
||||
ColorPulse.colors_min = 2;
|
||||
ColorPulse.colors_max = 2;
|
||||
ColorPulse.colors.resize(2);
|
||||
modes.push_back(ColorPulse);
|
||||
|
||||
mode RainbowWave;
|
||||
RainbowWave.name = "Rainbow Wave";
|
||||
RainbowWave.value = CORSAIR_DRAM_MODE_RAINBOW_WAVE;
|
||||
RainbowWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
RainbowWave.color_mode = MODE_COLORS_NONE;
|
||||
RainbowWave.speed_min = CORSAIR_DRAM_SPEED_SLOW;
|
||||
RainbowWave.speed_max = CORSAIR_DRAM_SPEED_FAST;
|
||||
RainbowWave.speed = CORSAIR_DRAM_SPEED_SLOW;
|
||||
RainbowWave.direction = MODE_DIRECTION_DOWN;
|
||||
modes.push_back(RainbowWave);
|
||||
|
||||
mode ColorWave;
|
||||
ColorWave.name = "Color Wave";
|
||||
ColorWave.value = CORSAIR_DRAM_MODE_COLOR_WAVE;
|
||||
ColorWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
ColorWave.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
ColorWave.speed_min = CORSAIR_DRAM_SPEED_SLOW;
|
||||
ColorWave.speed_max = CORSAIR_DRAM_SPEED_FAST;
|
||||
ColorWave.speed = CORSAIR_DRAM_SPEED_SLOW;
|
||||
ColorWave.direction = MODE_DIRECTION_DOWN;
|
||||
ColorWave.brightness_min = CORSAIR_DRAM_BRIGHTNESS_MIN;
|
||||
ColorWave.brightness_max = CORSAIR_DRAM_BRIGHTNESS_MAX;
|
||||
ColorWave.brightness = CORSAIR_DRAM_BRIGHTNESS_DEFAULT;
|
||||
ColorWave.colors_min = 2;
|
||||
ColorWave.colors_max = 2;
|
||||
ColorWave.colors.resize(2);
|
||||
modes.push_back(ColorWave);
|
||||
|
||||
mode Visor;
|
||||
Visor.name = "Visor";
|
||||
Visor.value = CORSAIR_DRAM_MODE_VISOR;
|
||||
Visor.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_HV | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Visor.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Visor.speed_min = CORSAIR_DRAM_SPEED_SLOW;
|
||||
Visor.speed_max = CORSAIR_DRAM_SPEED_FAST;
|
||||
Visor.speed = CORSAIR_DRAM_SPEED_SLOW;
|
||||
Visor.direction = MODE_DIRECTION_VERTICAL;
|
||||
Visor.brightness_min = CORSAIR_DRAM_BRIGHTNESS_MIN;
|
||||
Visor.brightness_max = CORSAIR_DRAM_BRIGHTNESS_MAX;
|
||||
Visor.brightness = CORSAIR_DRAM_BRIGHTNESS_DEFAULT;
|
||||
Visor.colors_min = 2;
|
||||
Visor.colors_max = 2;
|
||||
Visor.colors.resize(2);
|
||||
modes.push_back(Visor);
|
||||
|
||||
mode Rain;
|
||||
Rain.name = "Rain";
|
||||
Rain.value = CORSAIR_DRAM_MODE_RAIN;
|
||||
Rain.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Rain.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Rain.speed_min = CORSAIR_DRAM_SPEED_SLOW;
|
||||
Rain.speed_max = CORSAIR_DRAM_SPEED_FAST;
|
||||
Rain.speed = CORSAIR_DRAM_SPEED_SLOW;
|
||||
Rain.direction = MODE_DIRECTION_DOWN;
|
||||
Rain.brightness_min = CORSAIR_DRAM_BRIGHTNESS_MIN;
|
||||
Rain.brightness_max = CORSAIR_DRAM_BRIGHTNESS_MAX;
|
||||
Rain.brightness = CORSAIR_DRAM_BRIGHTNESS_DEFAULT;
|
||||
Rain.colors_min = 2;
|
||||
Rain.colors_max = 2;
|
||||
Rain.colors.resize(2);
|
||||
modes.push_back(Rain);
|
||||
|
||||
mode Marquee;
|
||||
Marquee.name = "Marquee";
|
||||
Marquee.value = CORSAIR_DRAM_MODE_MARQUEE;
|
||||
Marquee.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Marquee.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Marquee.speed_min = CORSAIR_DRAM_SPEED_SLOW;
|
||||
Marquee.speed_max = CORSAIR_DRAM_SPEED_FAST;
|
||||
Marquee.speed = CORSAIR_DRAM_SPEED_SLOW;
|
||||
Marquee.brightness_min = CORSAIR_DRAM_BRIGHTNESS_MIN;
|
||||
Marquee.brightness_max = CORSAIR_DRAM_BRIGHTNESS_MAX;
|
||||
Marquee.brightness = CORSAIR_DRAM_BRIGHTNESS_DEFAULT;
|
||||
Marquee.colors_min = 1;
|
||||
Marquee.colors_max = 1;
|
||||
Marquee.colors.resize(1);
|
||||
modes.push_back(Marquee);
|
||||
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.value = CORSAIR_DRAM_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
Rainbow.speed_min = CORSAIR_DRAM_SPEED_SLOW;
|
||||
Rainbow.speed_max = CORSAIR_DRAM_SPEED_FAST;
|
||||
Rainbow.speed = CORSAIR_DRAM_SPEED_SLOW;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
mode Sequential;
|
||||
Sequential.name = "Sequential";
|
||||
Sequential.value = CORSAIR_DRAM_MODE_SEQUENTIAL;
|
||||
Sequential.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Sequential.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Sequential.speed_min = CORSAIR_DRAM_SPEED_SLOW;
|
||||
Sequential.speed_max = CORSAIR_DRAM_SPEED_FAST;
|
||||
Sequential.speed = CORSAIR_DRAM_SPEED_SLOW;
|
||||
Sequential.direction = MODE_DIRECTION_DOWN;
|
||||
Sequential.brightness_min = CORSAIR_DRAM_BRIGHTNESS_MIN;
|
||||
Sequential.brightness_max = CORSAIR_DRAM_BRIGHTNESS_MAX;
|
||||
Sequential.brightness = CORSAIR_DRAM_BRIGHTNESS_DEFAULT;
|
||||
Sequential.colors_min = 1;
|
||||
Sequential.colors_max = 1;
|
||||
Sequential.colors.resize(1);
|
||||
modes.push_back(Sequential);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_CorsairDRAM::~RGBController_CorsairDRAM()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CorsairDRAM::SetupZones()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up zone |
|
||||
\*-----------------------------------------------------*/
|
||||
zone new_zone;
|
||||
new_zone.name = "Corsair DRAM";
|
||||
new_zone.type = ZONE_TYPE_LINEAR;
|
||||
new_zone.leds_min = controller->GetLEDCount();
|
||||
new_zone.leds_max = controller->GetLEDCount();
|
||||
new_zone.leds_count = controller->GetLEDCount();
|
||||
new_zone.matrix_map = NULL;
|
||||
zones.push_back(new_zone);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up LEDs |
|
||||
\*-----------------------------------------------------*/
|
||||
for(std::size_t led_idx = 0; led_idx < zones[0].leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = "Corsair DRAM LED ";
|
||||
new_led.name.append(std::to_string(led_idx));
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CorsairDRAM::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*-----------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_CorsairDRAM::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetColorsPerLED(colors.data());
|
||||
}
|
||||
|
||||
void RGBController_CorsairDRAM::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CorsairDRAM::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CorsairDRAM::DeviceUpdateMode()
|
||||
{
|
||||
unsigned int corsair_direction = 0;
|
||||
bool random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
|
||||
unsigned char mode_colors[6];
|
||||
|
||||
switch(modes[active_mode].direction)
|
||||
{
|
||||
case MODE_DIRECTION_LEFT:
|
||||
corsair_direction = CORSAIR_DRAM_DIRECTION_LEFT;
|
||||
break;
|
||||
case MODE_DIRECTION_RIGHT:
|
||||
corsair_direction = CORSAIR_DRAM_DIRECTION_RIGHT;
|
||||
break;
|
||||
case MODE_DIRECTION_UP:
|
||||
corsair_direction = CORSAIR_DRAM_DIRECTION_UP;
|
||||
break;
|
||||
case MODE_DIRECTION_DOWN:
|
||||
corsair_direction = CORSAIR_DRAM_DIRECTION_DOWN;
|
||||
break;
|
||||
case MODE_DIRECTION_HORIZONTAL:
|
||||
corsair_direction = CORSAIR_DRAM_DIRECTION_HORIZONTAL;
|
||||
break;
|
||||
case MODE_DIRECTION_VERTICAL:
|
||||
corsair_direction = CORSAIR_DRAM_DIRECTION_VERTICAL;
|
||||
break;
|
||||
}
|
||||
|
||||
mode_colors[0] = 0;
|
||||
mode_colors[1] = 0;
|
||||
mode_colors[2] = 0;
|
||||
mode_colors[3] = 0;
|
||||
mode_colors[4] = 0;
|
||||
mode_colors[5] = 0;
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
mode_colors[0] = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
mode_colors[1] = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
mode_colors[2] = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
|
||||
if(modes[active_mode].colors.size() == 2)
|
||||
{
|
||||
mode_colors[3] = RGBGetRValue(modes[active_mode].colors[1]);
|
||||
mode_colors[4] = RGBGetGValue(modes[active_mode].colors[1]);
|
||||
mode_colors[5] = RGBGetBValue(modes[active_mode].colors[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if(modes[active_mode].name == "Direct")
|
||||
{
|
||||
controller->SetDirect(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetDirect(false);
|
||||
}
|
||||
|
||||
controller->SetEffect(modes[active_mode].value,
|
||||
modes[active_mode].speed,
|
||||
corsair_direction,
|
||||
random,
|
||||
(unsigned char)modes[active_mode].brightness,
|
||||
mode_colors[0],
|
||||
mode_colors[1],
|
||||
mode_colors[2],
|
||||
mode_colors[3],
|
||||
mode_colors[4],
|
||||
mode_colors[5]);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(15));
|
||||
}
|
||||
+8
-7
@@ -1,8 +1,9 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CorsairDominatorPlatinum.h |
|
||||
| RGBController_CorsairDRAM.h |
|
||||
| |
|
||||
| RGBController for Corsair Dominator Platinum RAM |
|
||||
| RGBController for Corsair DRAM RGB controllers |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 30 Jun 2019 |
|
||||
| Erik Gilling (konkers) 25 Sep 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
@@ -12,13 +13,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "CorsairDominatorPlatinumController.h"
|
||||
#include "CorsairDRAMController.h"
|
||||
|
||||
class RGBController_CorsairDominatorPlatinum : public RGBController
|
||||
class RGBController_CorsairDRAM : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CorsairDominatorPlatinum(CorsairDominatorPlatinumController* controller_ptr);
|
||||
~RGBController_CorsairDominatorPlatinum();
|
||||
RGBController_CorsairDRAM(CorsairDRAMController* controller_ptr);
|
||||
~RGBController_CorsairDRAM();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
@@ -31,5 +32,5 @@ public:
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
CorsairDominatorPlatinumController* controller;
|
||||
CorsairDRAMController* controller;
|
||||
};
|
||||
-134
@@ -1,134 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairDominatorPlatinumController.cpp |
|
||||
| |
|
||||
| Driver for Corsair Dominator Platinum RAM |
|
||||
| |
|
||||
| Erik Gilling (konkers) 25 Sep 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include <chrono>
|
||||
#include "CorsairDominatorPlatinumController.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
CorsairDominatorPlatinumController::CorsairDominatorPlatinumController(i2c_smbus_interface *bus, corsair_dev_id dev, unsigned int leds_count, std::string dev_name)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
this->leds_count = leds_count;
|
||||
this->name = dev_name;
|
||||
|
||||
led_data[0] = 0xc;
|
||||
}
|
||||
|
||||
CorsairDominatorPlatinumController::~CorsairDominatorPlatinumController()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int CorsairDominatorPlatinumController::GetLEDCount()
|
||||
{
|
||||
return leds_count;
|
||||
}
|
||||
|
||||
std::string CorsairDominatorPlatinumController::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("I2C: " + return_string);
|
||||
}
|
||||
|
||||
std::string CorsairDominatorPlatinumController::GetDeviceName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
void CorsairDominatorPlatinumController::SetAllColors
|
||||
(
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
for(unsigned int led = 0; led < leds_count; led++)
|
||||
{
|
||||
SetLEDColor(led, red, green, blue);
|
||||
}
|
||||
}
|
||||
|
||||
void CorsairDominatorPlatinumController::SetLEDColor
|
||||
(
|
||||
unsigned int led,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
if(led >= leds_count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int offset = (led * 3) + 1;
|
||||
led_data[offset] = red;
|
||||
led_data[offset + 1] = green;
|
||||
led_data[offset + 2] = blue;
|
||||
}
|
||||
|
||||
unsigned char CorsairDominatorPlatinumController::crc8
|
||||
(
|
||||
unsigned char init,
|
||||
unsigned char poly,
|
||||
unsigned char* data,
|
||||
unsigned char len
|
||||
)
|
||||
{
|
||||
unsigned char crc = init;
|
||||
|
||||
for(unsigned int i = 0; i < len; i++)
|
||||
{
|
||||
unsigned char val = data[i];
|
||||
for(unsigned char mask = 0x80; mask != 0; mask >>= 1)
|
||||
{
|
||||
unsigned char bit;
|
||||
if ((val & mask) != 0)
|
||||
{
|
||||
bit = (crc & 0x80) ^ 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit = crc & 0x80;
|
||||
}
|
||||
|
||||
if (bit == 0)
|
||||
{
|
||||
crc <<= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc = (crc << 1) ^ poly;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
void CorsairDominatorPlatinumController::ApplyColors()
|
||||
{
|
||||
unsigned char data[sizeof(led_data)];
|
||||
memcpy(data, led_data, sizeof(led_data));
|
||||
unsigned char crc = crc8(0x0, 0x7, data, sizeof(data) - 1);
|
||||
data[sizeof(data) - 1] = crc;
|
||||
|
||||
bus->i2c_smbus_write_block_data(dev, 0x31, 0x20, data);
|
||||
std::this_thread::sleep_for(800us);
|
||||
bus->i2c_smbus_write_block_data(dev, 0x32, sizeof(data) - 0x20, data + 0x20);
|
||||
std::this_thread::sleep_for(200us);
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairDominatorPlatinumController.h |
|
||||
| |
|
||||
| Driver for Corsair Dominator Platinum RAM |
|
||||
| |
|
||||
| Erik Gilling (konkers) 25 Sep 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
#define CORSAIR_DOMINATOR_PLATINUM_DATA_SIZE 38
|
||||
|
||||
typedef unsigned char corsair_dev_id;
|
||||
|
||||
class CorsairDominatorPlatinumController
|
||||
{
|
||||
public:
|
||||
CorsairDominatorPlatinumController(i2c_smbus_interface *bus, corsair_dev_id dev, unsigned int leds_count, std::string dev_name);
|
||||
~CorsairDominatorPlatinumController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetDeviceName();
|
||||
unsigned int GetLEDCount();
|
||||
|
||||
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 ApplyColors();
|
||||
bool WaitReady();
|
||||
|
||||
private:
|
||||
unsigned char led_data[CORSAIR_DOMINATOR_PLATINUM_DATA_SIZE];
|
||||
i2c_smbus_interface* bus;
|
||||
corsair_dev_id dev;
|
||||
unsigned int leds_count;
|
||||
std::string name;
|
||||
|
||||
static unsigned char crc8(unsigned char init, unsigned char poly, unsigned char *data, unsigned char len);
|
||||
};
|
||||
-176
@@ -1,176 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairDominatorPlatinumControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Corsair Dominator Platinum RAM |
|
||||
| |
|
||||
| Erik Gilling (konkers) 25 Sep 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <vector>
|
||||
#include "Detector.h"
|
||||
#include "CorsairDominatorPlatinumController.h"
|
||||
#include "RGBController_CorsairDominatorPlatinum.h"
|
||||
#include "SettingsManager.h"
|
||||
#include "LogManager.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include "pci_ids.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
json corsair_dominator_models =
|
||||
{
|
||||
{
|
||||
"CMT",
|
||||
{
|
||||
{"name", "Corsair Dominator Platinum"},
|
||||
{"leds", 12}
|
||||
}
|
||||
},
|
||||
{
|
||||
"CMH",
|
||||
{
|
||||
{"name", "Corsair Vengeance Pro SL"},
|
||||
{"leds", 10}
|
||||
}
|
||||
},
|
||||
{
|
||||
"CMN",
|
||||
{
|
||||
{"name", "Corsair Vengeance RGB RT"},
|
||||
{"leds", 10}
|
||||
}
|
||||
},
|
||||
{
|
||||
"CMG",
|
||||
{
|
||||
{"name", "Corsair Vengeance RGB RS"},
|
||||
{"leds", 6}
|
||||
}
|
||||
},
|
||||
{
|
||||
"CMP",
|
||||
{
|
||||
{"name", "Corsair Dominator Titanium"},
|
||||
{"leds", 11}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define CORSAIR_DOMINATOR_PLATINUM_NAME "Corsair Dominator Platinum"
|
||||
|
||||
bool TestForCorsairDominatorPlatinumController(i2c_smbus_interface *bus, unsigned char address)
|
||||
{
|
||||
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
|
||||
|
||||
LOG_DEBUG("[%s] Trying address %02X", CORSAIR_DOMINATOR_PLATINUM_NAME, address);
|
||||
|
||||
if(res < 0)
|
||||
{
|
||||
LOG_DEBUG("[%s] Failed: res was %04X", CORSAIR_DOMINATOR_PLATINUM_NAME, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x43);
|
||||
|
||||
if(!(res == 0x1A || res == 0x1B))
|
||||
{
|
||||
LOG_DEBUG("[%s] Failed: expected 0x1a or 0x1b, got %04X", CORSAIR_DOMINATOR_PLATINUM_NAME, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x44);
|
||||
|
||||
if(res != 0x04)
|
||||
{
|
||||
LOG_DEBUG("[%s] Failed: expected 0x04, got %04X", CORSAIR_DOMINATOR_PLATINUM_NAME, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectCorsairDominatorPlatinumControllers *
|
||||
* *
|
||||
* Detect Corsair Dominator Platinum controllers on the enumerated I2C busses. *
|
||||
* *
|
||||
* bus - pointer to i2c_smbus_interface where Aura device is connected *
|
||||
* dev - I2C address of Aura device *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectCorsairDominatorPlatinumControllers(std::vector<i2c_smbus_interface *> &busses)
|
||||
{
|
||||
SettingsManager* settings_manager = ResourceManager::get()->GetSettingsManager();
|
||||
|
||||
json corsair_dominator_settings = settings_manager->GetSettings("CorsairDominatorSettings");
|
||||
|
||||
if(!corsair_dominator_settings.contains("model"))
|
||||
{
|
||||
// Set default value
|
||||
corsair_dominator_settings["model"] = "CMT";
|
||||
settings_manager->SetSettings("CorsairDominatorSettings", corsair_dominator_settings);
|
||||
settings_manager->SaveSettings();
|
||||
}
|
||||
|
||||
std::string model = corsair_dominator_settings["model"];
|
||||
|
||||
for(unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
IF_DRAM_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
|
||||
{
|
||||
LOG_DEBUG("[%s] Testing bus %d", CORSAIR_DOMINATOR_PLATINUM_NAME, bus);
|
||||
|
||||
std::vector<unsigned char> addresses;
|
||||
|
||||
for(unsigned char addr = 0x58; addr <= 0x5F; addr++)
|
||||
{
|
||||
addresses.push_back(addr);
|
||||
}
|
||||
|
||||
for(unsigned char addr = 0x18; addr <= 0x1F; addr++)
|
||||
{
|
||||
addresses.push_back(addr);
|
||||
}
|
||||
|
||||
for(unsigned char addr : addresses)
|
||||
{
|
||||
if(TestForCorsairDominatorPlatinumController(busses[bus], addr))
|
||||
{
|
||||
unsigned int leds;
|
||||
std::string name;
|
||||
|
||||
if(corsair_dominator_models.contains(model))
|
||||
{
|
||||
leds = corsair_dominator_models[model]["leds"];
|
||||
name = corsair_dominator_models[model]["name"];
|
||||
}
|
||||
else
|
||||
{
|
||||
leds = corsair_dominator_models["CMT"]["leds"];
|
||||
name = corsair_dominator_models["CMT"]["name"];
|
||||
}
|
||||
|
||||
LOG_DEBUG("[%s] Model: %s, Leds: %d", CORSAIR_DOMINATOR_PLATINUM_NAME, name.c_str(), leds);
|
||||
|
||||
CorsairDominatorPlatinumController* controller = new CorsairDominatorPlatinumController(busses[bus], addr, leds, name);
|
||||
RGBController_CorsairDominatorPlatinum* rgbcontroller = new RGBController_CorsairDominatorPlatinum(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgbcontroller);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("[%s] Bus %d is not a DRAM bus", CORSAIR_DOMINATOR_PLATINUM_NAME, bus);
|
||||
}
|
||||
}
|
||||
} /* DetectCorsairDominatorPlatinumControllers() */
|
||||
|
||||
REGISTER_I2C_DETECTOR(CORSAIR_DOMINATOR_PLATINUM_NAME, DetectCorsairDominatorPlatinumControllers);
|
||||
-134
@@ -1,134 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CorsairDominatorPlatinum.cpp |
|
||||
| |
|
||||
| RGBController for Corsair Dominator Platinum RAM |
|
||||
| |
|
||||
| Erik Gilling (konkers) 25 Sep 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_CorsairDominatorPlatinum.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Corsair Dominator Platinum
|
||||
@category RAM
|
||||
@type SMBus
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectCorsairDominatorPlatinumControllers
|
||||
@comment
|
||||
The Corsair Dominator controller chip can be found on several
|
||||
Corsair memory sticks which have different LED counts. This can be controlled
|
||||
by editing the Part Number in OpenRGB.json with values in the below table.
|
||||
|
||||
| Part Number | LED Count |
|
||||
| :---------: | --------: |
|
||||
| CMG | 6 |
|
||||
| CMH | 10 |
|
||||
| CMN | 10 |
|
||||
| CMT | 12 |
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CorsairDominatorPlatinum::RGBController_CorsairDominatorPlatinum(CorsairDominatorPlatinumController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Corsair";
|
||||
type = DEVICE_TYPE_DRAM;
|
||||
description = "Corsair RAM RGB Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.speed_min = 0;
|
||||
Direct.speed_max = 0;
|
||||
Direct.speed = 0;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
|
||||
active_mode = 0;
|
||||
}
|
||||
|
||||
RGBController_CorsairDominatorPlatinum::~RGBController_CorsairDominatorPlatinum()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CorsairDominatorPlatinum::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zone |
|
||||
\*---------------------------------------------------------*/
|
||||
zone new_zone;
|
||||
new_zone.name = "Corsair RAM Zone";
|
||||
new_zone.type = ZONE_TYPE_LINEAR;
|
||||
new_zone.leds_min = controller->GetLEDCount();
|
||||
new_zone.leds_max = controller->GetLEDCount();
|
||||
new_zone.leds_count = controller->GetLEDCount();
|
||||
new_zone.matrix_map = NULL;
|
||||
zones.push_back(new_zone);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
for(std::size_t led_idx = 0; led_idx < zones[0].leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = "Corsair RAM LED ";
|
||||
new_led.name.append(std::to_string(led_idx));
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CorsairDominatorPlatinum::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_CorsairDominatorPlatinum::DeviceUpdateLEDs()
|
||||
{
|
||||
for(unsigned int led = 0; led < (unsigned int)colors.size(); led++)
|
||||
{
|
||||
RGBColor color = colors[led];
|
||||
unsigned char red = RGBGetRValue(color);
|
||||
unsigned char grn = RGBGetGValue(color);
|
||||
unsigned char blu = RGBGetBValue(color);
|
||||
|
||||
controller->SetLEDColor(led, red, grn, blu);
|
||||
}
|
||||
|
||||
controller->ApplyColors();
|
||||
}
|
||||
|
||||
void RGBController_CorsairDominatorPlatinum::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CorsairDominatorPlatinum::UpdateSingleLED(int led)
|
||||
{
|
||||
RGBColor color = colors[led];
|
||||
unsigned char red = RGBGetRValue(color);
|
||||
unsigned char grn = RGBGetGValue(color);
|
||||
unsigned char blu = RGBGetBValue(color);
|
||||
|
||||
controller->SetLEDColor(led, red, grn, blu);
|
||||
controller->ApplyColors();
|
||||
}
|
||||
|
||||
void RGBController_CorsairDominatorPlatinum::DeviceUpdateMode()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -96,7 +96,16 @@ void RGBController_CorsairICueLink::SetupZones()
|
||||
lcd_zone.leds_min = controller->GetEndpoints()[lcd_idx]->led_channels;
|
||||
lcd_zone.leds_max = lcd_zone.leds_min;
|
||||
lcd_zone.leds_count = lcd_zone.leds_min;
|
||||
|
||||
zones.push_back(lcd_zone);
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < lcd_zone.leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = "LED " + std::to_string(led_idx + 1);
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,12 @@ CorsairPeripheralV2Controller::CorsairPeripheralV2Controller(hid_device* dev_han
|
||||
write_cmd = CORSAIR_V2_WRITE_WIRELESS_ID;
|
||||
pid = GetAddress(0x12);
|
||||
break;
|
||||
|
||||
case CORSAIR_K57_RGB_WIRED_PID:
|
||||
write_cmd = 0x80;
|
||||
light_ctrl = CORSAIR_V2_LIGHT_CTRL1;
|
||||
skip_reads = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
@@ -93,14 +99,17 @@ CorsairPeripheralV2Controller::CorsairPeripheralV2Controller(hid_device* dev_han
|
||||
| If lighting control endpoint 2 is unavailable |
|
||||
| then use endpoint 1. |
|
||||
\*---------------------------------------------------------*/
|
||||
result = StartTransaction(0);
|
||||
if(result > 0)
|
||||
if(light_ctrl == CORSAIR_V2_LIGHT_CTRL2)
|
||||
{
|
||||
light_ctrl = CORSAIR_V2_LIGHT_CTRL1;
|
||||
StartTransaction(0);
|
||||
result = StartTransaction(0);
|
||||
if(result > 0)
|
||||
{
|
||||
light_ctrl = CORSAIR_V2_LIGHT_CTRL1;
|
||||
StartTransaction(0);
|
||||
}
|
||||
StopTransaction(0);
|
||||
LOG_DEBUG("[%s] Lighting Endpoint set to %02X", device_name.c_str(), light_ctrl);
|
||||
}
|
||||
StopTransaction(0);
|
||||
LOG_DEBUG("[%s] Lighting Endpoint set to %02X", device_name.c_str(), light_ctrl);
|
||||
}
|
||||
|
||||
CorsairPeripheralV2Controller::~CorsairPeripheralV2Controller()
|
||||
@@ -171,7 +180,11 @@ void CorsairPeripheralV2Controller::SetRenderMode(corsair_v2_device_mode mode)
|
||||
buffer[5] = mode;
|
||||
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2Controller::LightingControl(uint8_t opt1)
|
||||
@@ -191,7 +204,11 @@ void CorsairPeripheralV2Controller::LightingControl(uint8_t opt1)
|
||||
buffer[5] = 0x00;
|
||||
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CorsairPeripheralV2Controller::GetKeyboardLayout()
|
||||
@@ -240,7 +257,11 @@ unsigned char CorsairPeripheralV2Controller::StartTransaction(uint8_t opt1)
|
||||
buffer[4] = light_ctrl;
|
||||
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
|
||||
return buffer[2];
|
||||
}
|
||||
@@ -257,11 +278,20 @@ void CorsairPeripheralV2Controller::StopTransaction(uint8_t opt1)
|
||||
buffer[4] = opt1;
|
||||
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2Controller::ClearPacketBuffer()
|
||||
{
|
||||
if(skip_reads)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t result = 0;
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
|
||||
@@ -304,7 +334,11 @@ void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
|
||||
memcpy(&buffer[offset1], &data[0], copy_bytes);
|
||||
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
|
||||
}
|
||||
|
||||
remaining -= copy_bytes;
|
||||
buffer[2] = CORSAIR_V2_CMD_BLK_WN;
|
||||
@@ -325,7 +359,11 @@ void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
|
||||
memcpy(&buffer[offset2], &data[index], copy_bytes);
|
||||
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
|
||||
}
|
||||
|
||||
remaining -= copy_bytes;
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ private:
|
||||
|
||||
uint8_t write_cmd = CORSAIR_V2_WRITE_WIRED_ID;
|
||||
uint16_t pkt_sze = CORSAIR_V2_WRITE_SIZE;
|
||||
bool skip_reads = false;
|
||||
std::string firmware_version;
|
||||
std::string location;
|
||||
};
|
||||
|
||||
@@ -57,11 +57,14 @@ void DetectCorsairV2SoftwareControllers(hid_device_info* info, const std::string
|
||||
| Keyboards |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K55 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K55_RGB_PRO_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K57 RGB (Wired)", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K57_RGB_WIRED_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO Low Profile", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_LP_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO TKL Black", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_TKL_B_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO TKL White", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_TKL_W_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K70 Core RGB", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K70_CORE_RGB_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K70 Core RGB TKL", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K70_CORE_RGB_TKL_PID, 1, 0xFF42);
|
||||
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB PRO", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K70_RGB_PRO_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB PRO V2", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K70_RGB_PRO_V2_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB TKL", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K70_RGB_TKL_PID, 1, 0xFF42);
|
||||
|
||||
@@ -48,6 +48,31 @@ std::vector<unsigned int> corsair_full_size_values =
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| KEYMAPS |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
keyboard_keymap_overlay_values corsair_K57_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_FULL,
|
||||
{
|
||||
corsair_full_size_values,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Name, Alternate Name, OpCode |
|
||||
\*-------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 0, 17, 0, "Power/Wireless Indicator", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_ROW, }, // Insert Profile into new row
|
||||
{ 0, 0, 18, 1, "Lock/Macro Indicator", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Light key
|
||||
{ 0, 1, 0, 131, "Key: G1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert G1 key
|
||||
{ 0, 2, 0, 132, "Key: G2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert G2 key
|
||||
{ 0, 3, 0, 133, "Key: G3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert G3 key
|
||||
{ 0, 4, 0, 134, "Key: G4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert G4 key
|
||||
{ 0, 5, 0, 135, "Key: G5", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert G5 key
|
||||
{ 0, 6, 0, 136, "Key: G6", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert G6 key
|
||||
}
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values corsair_K60_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_FULL,
|
||||
@@ -116,12 +141,14 @@ keyboard_keymap_overlay_values corsair_k70_pro_layout
|
||||
{ 0, 0, 0, 128, "Profile", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_ROW, }, // Insert Profile into new row
|
||||
{ 0, 0, 1, 113, "Light", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Light key
|
||||
{ 0, 0, 2, 114, "Lock", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Lock Key
|
||||
{ 0, 0, 10, 191, "Logo", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Logo
|
||||
{ 0, 0, 10, 138, "Logo", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Logo
|
||||
{ 0, 0, 18, 102, KEY_EN_MEDIA_MUTE, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Mute Key
|
||||
{ 0, 1, 17, 123, KEY_EN_MEDIA_STOP, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Stop Key
|
||||
{ 0, 1, 18, 126, KEY_EN_MEDIA_PREVIOUS, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Previous Track Key
|
||||
{ 0, 1, 19, 124, KEY_EN_MEDIA_PLAY_PAUSE, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Play Pause Key
|
||||
{ 0, 1, 20, 125, KEY_EN_MEDIA_NEXT, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Next Tack Key
|
||||
{ 0, 6, 5, 140, KEY_EN_SPACE, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert spacebar L
|
||||
{ 0, 6, 7, 141, KEY_EN_SPACE, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert spacebar R
|
||||
}
|
||||
};
|
||||
|
||||
@@ -152,6 +179,28 @@ keyboard_keymap_overlay_values corsair_K70_TKL_cs_layout
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
keyboard_keymap_overlay_values corsair_K70_CORE_TKL_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_TKL,
|
||||
{
|
||||
corsair_tkl_values,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Name, Alternate Name, OpCode, |
|
||||
\*-------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 0, 14, 70, KEY_EN_MEDIA_MUTE, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Swap PRSC with Mute
|
||||
{ 0, 0, 15, 71, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Remove SCLK
|
||||
{ 0, 0, 16, 72, KEY_EN_MEDIA_VOLUME_UP, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Swap PSBK with Volume Potion Up
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values corsair_k95_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_FULL,
|
||||
@@ -750,6 +799,38 @@ static const corsair_v2_device k55_rgb_pro_device =
|
||||
nullptr
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Corsair K57 RGB (Wired) 1B1C:1B6E |
|
||||
| |
|
||||
| Zone "Keyboard" |
|
||||
| Matrix |
|
||||
| 7 Rows, 22 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_zone k57_rgb_wired_zone =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
ZONE_TYPE_MATRIX,
|
||||
7,
|
||||
22
|
||||
};
|
||||
|
||||
static const corsair_v2_device k57_rgb_wired_device =
|
||||
{
|
||||
CORSAIR_K57_RGB_WIRED_PID,
|
||||
DEVICE_TYPE_KEYBOARD,
|
||||
7,
|
||||
22,
|
||||
{
|
||||
&k57_rgb_wired_zone,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr
|
||||
},
|
||||
&corsair_K57_layout
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Corsair K60 RGB Pro 1B1C:1BA0 |
|
||||
| |
|
||||
@@ -929,6 +1010,39 @@ static const corsair_v2_device k70_rgb_tkl_device =
|
||||
&corsair_K70_TKL_cs_layout
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Corsair K70 Core RGB TKL 1B1C:2B01 |
|
||||
| |
|
||||
| Zone "Keyboard" |
|
||||
| Matrix |
|
||||
| 6 Rows, 1 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_zone k70_core_rgb_tkl_zone =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
ZONE_TYPE_MATRIX,
|
||||
6,
|
||||
17
|
||||
};
|
||||
|
||||
static const corsair_v2_device k70_core_rgb_tkl_device =
|
||||
{
|
||||
CORSAIR_K70_CORE_RGB_TKL_PID,
|
||||
DEVICE_TYPE_KEYBOARD,
|
||||
6,
|
||||
17,
|
||||
{
|
||||
&k70_core_rgb_tkl_zone,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr
|
||||
},
|
||||
&corsair_K70_CORE_TKL_layout
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Corsair K70 RGB TKL Champion Series 1B1C:1BB9 |
|
||||
| |
|
||||
@@ -1406,11 +1520,13 @@ const corsair_v2_device* corsair_v2_device_list_data[] =
|
||||
| KEYBOARDS |
|
||||
\*-----------------------------------------------------------------*/
|
||||
&k55_rgb_pro_device,
|
||||
&k57_rgb_wired_device,
|
||||
&k60_rgb_pro_device,
|
||||
&k60_rgb_pro_lp_device,
|
||||
&k60_rgb_pro_tkl_device_b,
|
||||
&k60_rgb_pro_tkl_device_w,
|
||||
&k70_core_rgb_device,
|
||||
&k70_core_rgb_tkl_device,
|
||||
&k70_rgb_pro_device,
|
||||
&k70_rgb_pro_v2_device,
|
||||
&k70_rgb_tkl_device,
|
||||
|
||||
@@ -69,11 +69,14 @@ typedef struct
|
||||
| Corsair V2 Protocol Keyboards |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_K55_RGB_PRO_PID 0x1BA4
|
||||
#define CORSAIR_K57_RGB_WIRED_PID 0x1B6E
|
||||
#define CORSAIR_K57_RGB_WIRELESS_PID 0x1B62
|
||||
#define CORSAIR_K60_RGB_PRO_PID 0x1BA0
|
||||
#define CORSAIR_K60_RGB_PRO_LP_PID 0x1BAD
|
||||
#define CORSAIR_K60_RGB_PRO_TKL_B_PID 0x1BC7
|
||||
#define CORSAIR_K60_RGB_PRO_TKL_W_PID 0x1BED
|
||||
#define CORSAIR_K70_CORE_RGB_PID 0x1BFD
|
||||
#define CORSAIR_K70_CORE_RGB_TKL_PID 0x2B01
|
||||
#define CORSAIR_K70_RGB_PRO_PID 0x1BC4
|
||||
#define CORSAIR_K70_RGB_PRO_V2_PID 0x1BB3
|
||||
#define CORSAIR_K70_RGB_TKL_PID 0x1B73
|
||||
|
||||
@@ -1,213 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairVengeanceProController.cpp |
|
||||
| |
|
||||
| Driver for Corsair Vengeance Pro RGB RAM |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 30 Jun 2019 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include <chrono>
|
||||
#include "CorsairVengeanceProController.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
CorsairVengeanceProController::CorsairVengeanceProController(i2c_smbus_interface* bus, corsair_dev_id dev)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
|
||||
strcpy(device_name, "Corsair Vengeance Pro RGB");
|
||||
led_count = CORSAIR_PRO_LED_COUNT;
|
||||
|
||||
direct_mode = false;
|
||||
effect_mode = CORSAIR_PRO_MODE_STATIC;
|
||||
|
||||
for (unsigned int i = 0; i < led_count; i++)
|
||||
{
|
||||
led_red[i] = 0;
|
||||
led_green[i] = 0;
|
||||
led_blue[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CorsairVengeanceProController::~CorsairVengeanceProController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string CorsairVengeanceProController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
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("I2C: " + return_string);
|
||||
}
|
||||
|
||||
unsigned int CorsairVengeanceProController::GetLEDCount()
|
||||
{
|
||||
return(led_count);
|
||||
}
|
||||
|
||||
unsigned char CorsairVengeanceProController::GetEffect()
|
||||
{
|
||||
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;
|
||||
led_blue[i] = 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 CorsairVengeanceProController::ApplyColors()
|
||||
{
|
||||
if(direct_mode)
|
||||
{
|
||||
unsigned char full_packet[32];
|
||||
unsigned char crc_packet[31];
|
||||
|
||||
full_packet[0] = 0x0A;
|
||||
crc_packet[0] = 0x0A;
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
crc_packet[(i * 3) + 1] = led_red[i];
|
||||
full_packet[(i * 3) + 1] = led_red[i];
|
||||
|
||||
crc_packet[(i * 3) + 2] = led_green[i];
|
||||
full_packet[(i * 3) + 2] = led_green[i];
|
||||
|
||||
crc_packet[(i * 3) + 3] = led_blue[i];
|
||||
full_packet[(i * 3) + 3] = led_blue[i];
|
||||
}
|
||||
|
||||
uint8_t footer = CRCPP::CRC::Calculate(crc_packet, 31, CRCPP::CRC::CRC_8());
|
||||
|
||||
full_packet[31] = footer;
|
||||
|
||||
bus->i2c_smbus_write_block_data(dev, CORSAIR_PRO_DIRECT_COMMAND, 32, full_packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x26, 0x02);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x21, 0x00);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, led_red[i]);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, led_green[i]);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, led_blue[i]);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0xFF);
|
||||
}
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x82, 0x02);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
)
|
||||
{
|
||||
if(mode == effect_mode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
effect_mode = mode;
|
||||
|
||||
direct_mode = (effect_mode == CORSAIR_PRO_MODE_DIRECT);
|
||||
|
||||
if(direct_mode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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, 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);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00);
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x82, 0x01);
|
||||
WaitReady();
|
||||
}
|
||||
|
||||
bool CorsairVengeanceProController::WaitReady()
|
||||
{
|
||||
int i = 0;
|
||||
while (bus->i2c_smbus_read_byte_data(dev, 0x41) != 0x00)
|
||||
{
|
||||
i++;
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CorsairVengeanceProController::SetDirect(bool direct)
|
||||
{
|
||||
direct_mode = direct;
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairVengeanceProController.h |
|
||||
| |
|
||||
| Driver for Corsair Vengeance Pro RGB RAM |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 30 Jun 2019 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
#include "CRC.h"
|
||||
|
||||
typedef unsigned char corsair_dev_id;
|
||||
|
||||
#define CORSAIR_PRO_LED_COUNT ( 10 )
|
||||
#define CORSAIR_VENGEANCE_RGB_PRO_NAME "Corsair Vengeance RGB PRO"
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_PRO_REG_COMMAND = 0x20, /* Command write register */
|
||||
CORSAIR_PRO_DIRECT_COMMAND = 0x31, /* Where it writes direct mode colors */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_PRO_MODE_DIRECT = 0xDD, /* Arbitrary value to compare against later. Not the actual packet */
|
||||
CORSAIR_PRO_MODE_COLOR_SHIFT = 0x00, /* Color Shift mode */
|
||||
CORSAIR_PRO_MODE_COLOR_PULSE = 0x01, /* Color Pulse mode */
|
||||
CORSAIR_PRO_MODE_RAINBOW_WAVE = 0x03, /* Rainbow Wave mode */
|
||||
CORSAIR_PRO_MODE_COLOR_WAVE = 0x04, /* Color Wave mode */
|
||||
CORSAIR_PRO_MODE_VISOR = 0x05, /* Visor mode */
|
||||
CORSAIR_PRO_MODE_RAIN = 0x06, /* Rain mode */
|
||||
CORSAIR_PRO_MODE_MARQUEE = 0x07, /* Marquee mode */
|
||||
CORSAIR_PRO_MODE_RAINBOW = 0x08, /* Rainbow mode */
|
||||
CORSAIR_PRO_MODE_SEQUENTIAL = 0x09, /* Sequential mode */
|
||||
CORSAIR_PRO_MODE_STATIC = 0x10, /* Static mode */
|
||||
|
||||
CORSAIR_PRO_NUMBER_MODES = 10, /* Number of Corsair Pro modes */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_PRO_SPEED_SLOW = 0x00, /* Slow speed */
|
||||
CORSAIR_PRO_SPEED_MEDIUM = 0x01, /* Medium speed */
|
||||
CORSAIR_PRO_SPEED_FAST = 0x02, /* Fast speed */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_PRO_EFFECT_RANDOM_COLORS = 0x00, /* Random colors */
|
||||
CORSAIR_PRO_EFFECT_CUSTOM_COLORS = 0x01, /* Custom colors */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_PRO_DIRECTION_UP = 0x00, /* Up direction */
|
||||
CORSAIR_PRO_DIRECTION_DOWN = 0x01, /* Down direction */
|
||||
CORSAIR_PRO_DIRECTION_LEFT = 0x02, /* Left direction */
|
||||
CORSAIR_PRO_DIRECTION_RIGHT = 0x03, /* Right direction */
|
||||
CORSAIR_PRO_DIRECTION_VERTICAL = 0x01, /* Vertical direction */
|
||||
CORSAIR_PRO_DIRECTION_HORIZONTAL = 0x03, /* Horizontal direction */
|
||||
};
|
||||
|
||||
class CorsairVengeanceProController
|
||||
{
|
||||
public:
|
||||
CorsairVengeanceProController(i2c_smbus_interface* bus, corsair_dev_id dev);
|
||||
~CorsairVengeanceProController();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceLocation();
|
||||
unsigned int GetLEDCount();
|
||||
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);
|
||||
void ApplyColors();
|
||||
bool WaitReady();
|
||||
|
||||
void SetDirect(bool direct);
|
||||
|
||||
private:
|
||||
char device_name[32];
|
||||
unsigned int led_count;
|
||||
bool direct_mode;
|
||||
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;
|
||||
};
|
||||
@@ -1,107 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairVengeanceProControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Corsair Vengeance Pro RGB RAM |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 30 Jun 2019 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <vector>
|
||||
#include "Detector.h"
|
||||
#include "CorsairVengeanceProController.h"
|
||||
#include "RGBController_CorsairVengeancePro.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include "pci_ids.h"
|
||||
#include "LogManager.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);
|
||||
|
||||
LOG_DEBUG("[%s] Trying address %02X", CORSAIR_VENGEANCE_RGB_PRO_NAME, address);
|
||||
|
||||
if(res >= 0)
|
||||
{
|
||||
pass = true;
|
||||
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x43);
|
||||
|
||||
if (res != 0x1C)
|
||||
{
|
||||
pass = false;
|
||||
LOG_DEBUG("[%s] Failed: was expecting 0x1C got %02X", CORSAIR_VENGEANCE_RGB_PRO_NAME, res);
|
||||
}
|
||||
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x44);
|
||||
|
||||
if(!((res == 0x03) || (res == 0x04)))
|
||||
{
|
||||
pass = false;
|
||||
LOG_DEBUG("[%s] Failed: was expecting 0x03 or 0x04 got %02X", CORSAIR_VENGEANCE_RGB_PRO_NAME, res);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("[%s] Failed: res was %04X", CORSAIR_VENGEANCE_RGB_PRO_NAME, res);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
for(unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
LOG_DEBUG("[%s] Testing bus %d", CORSAIR_VENGEANCE_RGB_PRO_NAME, bus);
|
||||
|
||||
IF_DRAM_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
|
||||
{
|
||||
for(unsigned char addr = 0x58; addr <= 0x5F; addr++)
|
||||
{
|
||||
if(TestForCorsairVengeanceProController(busses[bus], addr))
|
||||
{
|
||||
CorsairVengeanceProController* new_controller = new CorsairVengeanceProController(busses[bus], addr);
|
||||
RGBController_CorsairVengeancePro* new_rgbcontroller = new RGBController_CorsairVengeancePro(new_controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(new_rgbcontroller);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("[%s] Bus %d is not a DRAM bus", CORSAIR_VENGEANCE_RGB_PRO_NAME, bus);
|
||||
}
|
||||
}
|
||||
|
||||
} /* DetectCorsairVengeanceProControllers() */
|
||||
|
||||
REGISTER_I2C_DETECTOR("Corsair Vengeance Pro", DetectCorsairVengeanceProControllers);
|
||||
@@ -1,316 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CorsairVengeancePro.cpp |
|
||||
| |
|
||||
| RGBController for Corsair Vengeance Pro RGB RAM |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 30 Jun 2019 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_CorsairVengeancePro.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Corsair Vengeance Pro
|
||||
@category RAM
|
||||
@type SMBus
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectCorsairVengeanceProControllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CorsairVengeancePro::RGBController_CorsairVengeancePro(CorsairVengeanceProController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Corsair";
|
||||
type = DEVICE_TYPE_DRAM;
|
||||
description = "Corsair Vengeance Pro RGB Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = CORSAIR_PRO_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.speed_min = 0;
|
||||
Direct.speed_max = 0;
|
||||
Direct.speed = 0;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = CORSAIR_PRO_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Static.speed_min = 0;
|
||||
Static.speed_max = 0;
|
||||
Static.speed = 0;
|
||||
Static.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode ColorShift;
|
||||
ColorShift.name = "Color Shift";
|
||||
ColorShift.value = CORSAIR_PRO_MODE_COLOR_SHIFT;
|
||||
ColorShift.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
ColorShift.speed_min = CORSAIR_PRO_SPEED_SLOW;
|
||||
ColorShift.speed_max = CORSAIR_PRO_SPEED_FAST;
|
||||
ColorShift.colors_min = 2;
|
||||
ColorShift.colors_max = 2;
|
||||
ColorShift.speed = CORSAIR_PRO_SPEED_SLOW;
|
||||
ColorShift.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
ColorShift.colors.resize(2);
|
||||
modes.push_back(ColorShift);
|
||||
|
||||
mode ColorPulse;
|
||||
ColorPulse.name = "Color Pulse";
|
||||
ColorPulse.value = CORSAIR_PRO_MODE_COLOR_PULSE;
|
||||
ColorPulse.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
ColorPulse.speed_min = CORSAIR_PRO_SPEED_SLOW;
|
||||
ColorPulse.speed_max = CORSAIR_PRO_SPEED_FAST;
|
||||
ColorPulse.colors_min = 2;
|
||||
ColorPulse.colors_max = 2;
|
||||
ColorPulse.speed = CORSAIR_PRO_SPEED_SLOW;
|
||||
ColorPulse.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
ColorPulse.colors.resize(2);
|
||||
modes.push_back(ColorPulse);
|
||||
|
||||
mode RainbowWave;
|
||||
RainbowWave.name = "Rainbow Wave";
|
||||
RainbowWave.value = CORSAIR_PRO_MODE_RAINBOW_WAVE;
|
||||
RainbowWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD;
|
||||
RainbowWave.speed_min = CORSAIR_PRO_SPEED_SLOW;
|
||||
RainbowWave.speed_max = CORSAIR_PRO_SPEED_FAST;
|
||||
RainbowWave.speed = CORSAIR_PRO_SPEED_SLOW;
|
||||
RainbowWave.direction = MODE_DIRECTION_DOWN;
|
||||
RainbowWave.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(RainbowWave);
|
||||
|
||||
mode ColorWave;
|
||||
ColorWave.name = "Color Wave";
|
||||
ColorWave.value = CORSAIR_PRO_MODE_COLOR_WAVE;
|
||||
ColorWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
ColorWave.speed_min = CORSAIR_PRO_SPEED_SLOW;
|
||||
ColorWave.speed_max = CORSAIR_PRO_SPEED_FAST;
|
||||
ColorWave.colors_min = 2;
|
||||
ColorWave.colors_max = 2;
|
||||
ColorWave.speed = CORSAIR_PRO_SPEED_SLOW;
|
||||
ColorWave.direction = MODE_DIRECTION_DOWN;
|
||||
ColorWave.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
ColorWave.colors.resize(2);
|
||||
modes.push_back(ColorWave);
|
||||
|
||||
mode Visor;
|
||||
Visor.name = "Visor";
|
||||
Visor.value = CORSAIR_PRO_MODE_VISOR;
|
||||
Visor.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_HV | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Visor.speed_min = CORSAIR_PRO_SPEED_SLOW;
|
||||
Visor.speed_max = CORSAIR_PRO_SPEED_FAST;
|
||||
Visor.colors_min = 2;
|
||||
Visor.colors_max = 2;
|
||||
Visor.speed = CORSAIR_PRO_SPEED_SLOW;
|
||||
Visor.direction = MODE_DIRECTION_VERTICAL;
|
||||
Visor.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Visor.colors.resize(2);
|
||||
modes.push_back(Visor);
|
||||
|
||||
mode Rain;
|
||||
Rain.name = "Rain";
|
||||
Rain.value = CORSAIR_PRO_MODE_RAIN;
|
||||
Rain.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Rain.speed_min = CORSAIR_PRO_SPEED_SLOW;
|
||||
Rain.speed_max = CORSAIR_PRO_SPEED_FAST;
|
||||
Rain.colors_min = 2;
|
||||
Rain.colors_max = 2;
|
||||
Rain.speed = CORSAIR_PRO_SPEED_SLOW;
|
||||
Rain.direction = MODE_DIRECTION_DOWN;
|
||||
Rain.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Rain.colors.resize(2);
|
||||
modes.push_back(Rain);
|
||||
|
||||
mode Marquee;
|
||||
Marquee.name = "Marquee";
|
||||
Marquee.value = CORSAIR_PRO_MODE_MARQUEE;
|
||||
Marquee.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Marquee.speed_min = CORSAIR_PRO_SPEED_SLOW;
|
||||
Marquee.speed_max = CORSAIR_PRO_SPEED_FAST;
|
||||
Marquee.colors_min = 1;
|
||||
Marquee.colors_max = 1;
|
||||
Marquee.speed = CORSAIR_PRO_SPEED_SLOW;
|
||||
Marquee.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Marquee.colors.resize(1);
|
||||
modes.push_back(Marquee);
|
||||
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.value = CORSAIR_PRO_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED;
|
||||
Rainbow.speed_min = CORSAIR_PRO_SPEED_SLOW;
|
||||
Rainbow.speed_max = CORSAIR_PRO_SPEED_FAST;
|
||||
Rainbow.speed = CORSAIR_PRO_SPEED_SLOW;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
mode Sequential;
|
||||
Sequential.name = "Sequential";
|
||||
Sequential.value = CORSAIR_PRO_MODE_SEQUENTIAL;
|
||||
Sequential.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Sequential.speed_min = CORSAIR_PRO_SPEED_SLOW;
|
||||
Sequential.speed_max = CORSAIR_PRO_SPEED_FAST;
|
||||
Sequential.colors_min = 1;
|
||||
Sequential.colors_max = 1;
|
||||
Sequential.speed = CORSAIR_PRO_SPEED_SLOW;
|
||||
Sequential.direction = MODE_DIRECTION_DOWN;
|
||||
Sequential.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Sequential.colors.resize(1);
|
||||
modes.push_back(Sequential);
|
||||
|
||||
SetupZones();
|
||||
|
||||
active_mode = 9;
|
||||
}
|
||||
|
||||
RGBController_CorsairVengeancePro::~RGBController_CorsairVengeancePro()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CorsairVengeancePro::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zone |
|
||||
\*---------------------------------------------------------*/
|
||||
zone new_zone;
|
||||
new_zone.name = "Corsair Pro Zone";
|
||||
new_zone.type = ZONE_TYPE_LINEAR;
|
||||
new_zone.leds_min = controller->GetLEDCount();
|
||||
new_zone.leds_max = controller->GetLEDCount();
|
||||
new_zone.leds_count = controller->GetLEDCount();
|
||||
new_zone.matrix_map = NULL;
|
||||
zones.push_back(new_zone);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
for(std::size_t led_idx = 0; led_idx < zones[0].leds_count; led_idx++)
|
||||
{
|
||||
led* new_led = new led();
|
||||
new_led->name = "Corsair Pro LED ";
|
||||
new_led->name.append(std::to_string(led_idx));
|
||||
leds.push_back(*new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CorsairVengeancePro::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_CorsairVengeancePro::DeviceUpdateLEDs()
|
||||
{
|
||||
for(unsigned int led = 0; led < (unsigned int)colors.size(); led++)
|
||||
{
|
||||
RGBColor color = colors[led];
|
||||
unsigned char red = RGBGetRValue(color);
|
||||
unsigned char grn = RGBGetGValue(color);
|
||||
unsigned char blu = RGBGetBValue(color);
|
||||
controller->SetLEDColor(led, red, grn, blu);
|
||||
}
|
||||
|
||||
controller->ApplyColors();
|
||||
}
|
||||
|
||||
void RGBController_CorsairVengeancePro::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CorsairVengeancePro::UpdateSingleLED(int led)
|
||||
{
|
||||
RGBColor color = colors[led];
|
||||
unsigned char red = RGBGetRValue(color);
|
||||
unsigned char grn = RGBGetGValue(color);
|
||||
unsigned char blu = RGBGetBValue(color);
|
||||
|
||||
controller->SetLEDColor(led, red, grn, blu);
|
||||
controller->ApplyColors();
|
||||
}
|
||||
|
||||
void RGBController_CorsairVengeancePro::DeviceUpdateMode()
|
||||
{
|
||||
unsigned int corsair_direction = 0;
|
||||
bool random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
|
||||
unsigned char mode_colors[6];
|
||||
|
||||
switch(modes[active_mode].direction)
|
||||
{
|
||||
case MODE_DIRECTION_LEFT:
|
||||
corsair_direction = CORSAIR_PRO_DIRECTION_LEFT;
|
||||
break;
|
||||
case MODE_DIRECTION_RIGHT:
|
||||
corsair_direction = CORSAIR_PRO_DIRECTION_RIGHT;
|
||||
break;
|
||||
case MODE_DIRECTION_UP:
|
||||
corsair_direction = CORSAIR_PRO_DIRECTION_UP;
|
||||
break;
|
||||
case MODE_DIRECTION_DOWN:
|
||||
corsair_direction = CORSAIR_PRO_DIRECTION_DOWN;
|
||||
break;
|
||||
case MODE_DIRECTION_HORIZONTAL:
|
||||
corsair_direction = CORSAIR_PRO_DIRECTION_HORIZONTAL;
|
||||
break;
|
||||
case MODE_DIRECTION_VERTICAL:
|
||||
corsair_direction = CORSAIR_PRO_DIRECTION_VERTICAL;
|
||||
break;
|
||||
}
|
||||
|
||||
mode_colors[0] = 0;
|
||||
mode_colors[1] = 0;
|
||||
mode_colors[2] = 0;
|
||||
mode_colors[3] = 0;
|
||||
mode_colors[4] = 0;
|
||||
mode_colors[5] = 0;
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
mode_colors[0] = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
mode_colors[1] = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
mode_colors[2] = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
|
||||
if(modes[active_mode].colors.size() == 2)
|
||||
{
|
||||
mode_colors[3] = RGBGetRValue(modes[active_mode].colors[1]);
|
||||
mode_colors[4] = RGBGetGValue(modes[active_mode].colors[1]);
|
||||
mode_colors[5] = RGBGetBValue(modes[active_mode].colors[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (modes[active_mode].name == "Direct")
|
||||
{
|
||||
controller->SetDirect(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetDirect(false);
|
||||
}
|
||||
|
||||
controller->SetEffect(modes[active_mode].value,
|
||||
modes[active_mode].speed,
|
||||
corsair_direction,
|
||||
random,
|
||||
mode_colors[0],
|
||||
mode_colors[1],
|
||||
mode_colors[2],
|
||||
mode_colors[3],
|
||||
mode_colors[4],
|
||||
mode_colors[5]);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(15));
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairWirelessController.cpp |
|
||||
| |
|
||||
| Driver for Corsair wireless keyboard |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 08 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "CorsairWirelessController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
CorsairWirelessController::CorsairWirelessController(hid_device* dev_handle, const char* path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
|
||||
EnterDirectMode();
|
||||
}
|
||||
|
||||
CorsairWirelessController::~CorsairWirelessController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
device_type CorsairWirelessController::GetDeviceType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
std::string CorsairWirelessController::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string CorsairWirelessController::GetFirmwareString()
|
||||
{
|
||||
return firmware_version;
|
||||
}
|
||||
|
||||
std::string CorsairWirelessController::GetName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string CorsairWirelessController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void CorsairWirelessController::SetLEDs(std::vector<RGBColor>colors)
|
||||
{
|
||||
unsigned char buf[3 * 137];
|
||||
|
||||
for(int color = 0; color < 137; color++)
|
||||
{
|
||||
buf[0 + color] = RGBGetRValue(colors[color]);
|
||||
buf[137 + color] = RGBGetGValue(colors[color]);
|
||||
buf[274+color] = RGBGetBValue(colors[color]);
|
||||
}
|
||||
|
||||
StartDirectMode();
|
||||
|
||||
SendDirectFrame(true, &buf[0]);
|
||||
SendDirectFrame(false, &buf[57]);
|
||||
SendDirectFrame(false, &buf[118]);
|
||||
SendDirectFrame(false, &buf[179]);
|
||||
SendDirectFrame(false, &buf[240]);
|
||||
SendDirectFrame(false, &buf[301]);
|
||||
SendDirectFrame(false, &buf[362]);
|
||||
}
|
||||
|
||||
void CorsairWirelessController::SetName(std::string device_name)
|
||||
{
|
||||
name = device_name;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void CorsairWirelessController::EnterDirectMode()
|
||||
{
|
||||
unsigned 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] = 0x80;
|
||||
usb_buf[0x02] = 0x01;
|
||||
usb_buf[0x03] = 0x03;
|
||||
usb_buf[0x04] = 0x00;
|
||||
usb_buf[0x05] = 0x02;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet using feature reports, as headset stand |
|
||||
| seems to not update completely using HID writes |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
|
||||
}
|
||||
|
||||
void CorsairWirelessController::StartDirectMode()
|
||||
{
|
||||
unsigned 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] = 0x80;
|
||||
usb_buf[0x02] = 0x0D;
|
||||
usb_buf[0x03] = 0x00;
|
||||
usb_buf[0x04] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet using feature reports, as headset stand |
|
||||
| seems to not update completely using HID writes |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
|
||||
}
|
||||
|
||||
void CorsairWirelessController::ExitDirectMode()
|
||||
{
|
||||
unsigned 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] = 0x80;
|
||||
usb_buf[0x02] = 0x01;
|
||||
usb_buf[0x03] = 0x03;
|
||||
usb_buf[0x04] = 0x00;
|
||||
usb_buf[0x05] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet using feature reports, as headset stand |
|
||||
| seems to not update completely using HID writes |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
|
||||
}
|
||||
|
||||
void CorsairWirelessController::SendDirectFrame(bool first_frame, unsigned char* data)
|
||||
{
|
||||
unsigned 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] = 0x80;
|
||||
usb_buf[0x02] = first_frame ? 0x06 : 0x07;
|
||||
usb_buf[0x03] = 0x00;
|
||||
|
||||
if(first_frame)
|
||||
{
|
||||
usb_buf[0x04] = 0x9B;
|
||||
usb_buf[0x05] = 0x01;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in colors in <RED> <GREEN> <BLUE> order |
|
||||
\*-----------------------------------------------------*/
|
||||
if(first_frame)
|
||||
{
|
||||
memcpy(&usb_buf[0x08], data, 57);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&usb_buf[0x04], data, 61);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet using feature reports, as headset stand |
|
||||
| seems to not update completely using HID writes |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairWirelessController.h |
|
||||
| |
|
||||
| Driver for Corsair wireless keyboard |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 08 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
class CorsairWirelessController
|
||||
{
|
||||
public:
|
||||
CorsairWirelessController(hid_device* dev_handle, const char* path);
|
||||
~CorsairWirelessController();
|
||||
|
||||
device_type GetDeviceType();
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetFirmwareString();
|
||||
std::string GetName();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SetLEDs(std::vector<RGBColor> colors);
|
||||
void SetName(std::string device_name);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
|
||||
std::string firmware_version;
|
||||
std::string location;
|
||||
std::string name;
|
||||
device_type type;
|
||||
|
||||
void EnterDirectMode();
|
||||
void ExitDirectMode();
|
||||
void StartDirectMode();
|
||||
void SendDirectFrame(bool first_frame, unsigned char* data);
|
||||
};
|
||||
@@ -1,62 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairWirelessControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Corsair wireless keyboard |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 08 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "Detector.h"
|
||||
#include "CorsairWirelessController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_CorsairWireless.h"
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Corsair vendor ID |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_VID 0x1B1C
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_K57_RGB_WIRED_PID 0x1B6E
|
||||
#define CORSAIR_K57_RGB_WIRELESS_PID 0x1B62
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectCorsairWirelessControllers *
|
||||
* *
|
||||
* Tests the USB address to see if a Corsair RGB Keyboard controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectCorsairWirelessControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CorsairWirelessController* controller = new CorsairWirelessController(dev, info->path);
|
||||
controller->SetName(name);
|
||||
|
||||
if(controller->GetDeviceType() != DEVICE_TYPE_UNKNOWN)
|
||||
{
|
||||
RGBController_CorsairWireless* rgb_controller = new RGBController_CorsairWireless(controller);
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
}
|
||||
} /* DetectCorsairWirelessControllers() */
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IPU("Corsair K57 RGB (Wired)", DetectCorsairWirelessControllers, CORSAIR_VID, CORSAIR_K57_RGB_WIRED_PID, 1, 0xFF42, 1);
|
||||
//REGISTER_HID_DETECTOR_IPU("Corsair K57 RGB (Wireless)", DetectCorsairWirelessControllers, CORSAIR_VID, CORSAIR_K57_RGB_WIRELESS_PID, 1, 0xFF42, 1);
|
||||
@@ -1,342 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CorsairWireless.cpp |
|
||||
| |
|
||||
| RGBController for Corsair wireless keyboard |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 08 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "RGBController_CorsairWireless.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
//0xFFFFFFFF indicates an unused entry in matrix
|
||||
#define NA 0xFFFFFFFF
|
||||
|
||||
static unsigned int matrix_map[7][24] =
|
||||
{ { NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 0, 1, NA, NA, NA },
|
||||
{ 131, 41, NA, 58, 59, 60, 61, NA, 62, 63, 64, 65, NA, 66, 67, 68, 69, 70, 71, 72, NA, NA, NA, NA },
|
||||
{ 132, 53, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, NA, 45, 46, 42, NA, 73, 74, 75, 83, 84, 85, 86 },
|
||||
{ 133, 43, NA, 20, 26, 8, 21, NA, 23, 28, 24, 12, 18, 19, 47, 48, 49, 76, 77, 78, 95, 96, 97, 87 },
|
||||
{ 134, 57, NA, 4, 22, 7, 9, NA, 10, 11, 13, 14, 15, 51, 52, NA, 40, NA, NA, NA, 92, 93, 94, NA },
|
||||
{ 135, 106, NA, 29, 27, 6, 25, NA, 5, NA, 17, 16, 54, 55, 56, 110, NA, NA, 82, NA, 89, 90, 91, 88 },
|
||||
{ 136, 105, 108, 107, NA, NA, NA, NA, 44, NA, NA, NA, NA, 111, 122, 101, 109, 80, 81, 79, 98, NA, 99, NA } };
|
||||
|
||||
static const char* zone_names[] =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
};
|
||||
|
||||
static const unsigned int zone_sizes[] =
|
||||
{
|
||||
137
|
||||
};
|
||||
|
||||
static const zone_type zone_types[] =
|
||||
{
|
||||
ZONE_TYPE_MATRIX,
|
||||
};
|
||||
|
||||
static const char* led_names[] =
|
||||
{
|
||||
"Power/Wireless Indicator",
|
||||
"Lock/Macro Indicator",
|
||||
"N/A",
|
||||
"N/A",
|
||||
KEY_EN_A,
|
||||
KEY_EN_B,
|
||||
KEY_EN_C,
|
||||
KEY_EN_D,
|
||||
KEY_EN_E,
|
||||
KEY_EN_F,
|
||||
KEY_EN_G,
|
||||
KEY_EN_H,
|
||||
KEY_EN_I,
|
||||
KEY_EN_J,
|
||||
KEY_EN_K,
|
||||
KEY_EN_L,
|
||||
KEY_EN_M,
|
||||
KEY_EN_N,
|
||||
KEY_EN_O,
|
||||
KEY_EN_P,
|
||||
KEY_EN_Q,
|
||||
KEY_EN_R,
|
||||
KEY_EN_S,
|
||||
KEY_EN_T,
|
||||
KEY_EN_U,
|
||||
KEY_EN_V,
|
||||
KEY_EN_W,
|
||||
KEY_EN_X,
|
||||
KEY_EN_Y,
|
||||
KEY_EN_Z,
|
||||
KEY_EN_1,
|
||||
KEY_EN_2,
|
||||
KEY_EN_3,
|
||||
KEY_EN_4,
|
||||
KEY_EN_5,
|
||||
KEY_EN_6,
|
||||
KEY_EN_7,
|
||||
KEY_EN_8,
|
||||
KEY_EN_9,
|
||||
KEY_EN_0,
|
||||
KEY_EN_ANSI_ENTER,
|
||||
KEY_EN_ESCAPE,
|
||||
KEY_EN_BACKSPACE,
|
||||
KEY_EN_TAB,
|
||||
KEY_EN_SPACE,
|
||||
KEY_EN_MINUS,
|
||||
KEY_EN_EQUALS,
|
||||
KEY_EN_LEFT_BRACKET,
|
||||
KEY_EN_RIGHT_BRACKET,
|
||||
KEY_EN_ANSI_BACK_SLASH,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_SEMICOLON,
|
||||
KEY_EN_QUOTE,
|
||||
KEY_EN_BACK_TICK,
|
||||
KEY_EN_COMMA,
|
||||
KEY_EN_PERIOD,
|
||||
KEY_EN_FORWARD_SLASH,
|
||||
KEY_EN_CAPS_LOCK,
|
||||
KEY_EN_F1,
|
||||
KEY_EN_F2,
|
||||
KEY_EN_F3,
|
||||
KEY_EN_F4,
|
||||
KEY_EN_F5,
|
||||
KEY_EN_F6,
|
||||
KEY_EN_F7,
|
||||
KEY_EN_F8,
|
||||
KEY_EN_F9,
|
||||
KEY_EN_F10,
|
||||
KEY_EN_F11,
|
||||
KEY_EN_F12,
|
||||
KEY_EN_PRINT_SCREEN,
|
||||
KEY_EN_SCROLL_LOCK,
|
||||
KEY_EN_PAUSE_BREAK,
|
||||
KEY_EN_INSERT,
|
||||
KEY_EN_HOME,
|
||||
KEY_EN_PAGE_UP,
|
||||
KEY_EN_DELETE,
|
||||
KEY_EN_END,
|
||||
KEY_EN_PAGE_DOWN,
|
||||
KEY_EN_RIGHT_ARROW,
|
||||
KEY_EN_LEFT_ARROW,
|
||||
KEY_EN_DOWN_ARROW,
|
||||
KEY_EN_UP_ARROW,
|
||||
KEY_EN_NUMPAD_LOCK,
|
||||
KEY_EN_NUMPAD_DIVIDE,
|
||||
KEY_EN_NUMPAD_TIMES,
|
||||
KEY_EN_NUMPAD_MINUS,
|
||||
KEY_EN_NUMPAD_PLUS,
|
||||
KEY_EN_NUMPAD_ENTER,
|
||||
KEY_EN_NUMPAD_1,
|
||||
KEY_EN_NUMPAD_2,
|
||||
KEY_EN_NUMPAD_3,
|
||||
KEY_EN_NUMPAD_4,
|
||||
KEY_EN_NUMPAD_5,
|
||||
KEY_EN_NUMPAD_6,
|
||||
KEY_EN_NUMPAD_7,
|
||||
KEY_EN_NUMPAD_8,
|
||||
KEY_EN_NUMPAD_9,
|
||||
KEY_EN_NUMPAD_0,
|
||||
KEY_EN_NUMPAD_PERIOD,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_MENU,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_LEFT_CONTROL,
|
||||
KEY_EN_LEFT_SHIFT,
|
||||
KEY_EN_LEFT_ALT,
|
||||
KEY_EN_LEFT_WINDOWS,
|
||||
KEY_EN_RIGHT_CONTROL,
|
||||
KEY_EN_RIGHT_SHIFT,
|
||||
KEY_EN_RIGHT_ALT,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_RIGHT_FUNCTION,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
"Key: G1",
|
||||
"Key: G2",
|
||||
"Key: G3",
|
||||
"Key: G4",
|
||||
"Key: G5",
|
||||
"Key: G6",
|
||||
};
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Corsair Wireless Peripheral
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectCorsairWirelessControllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CorsairWireless::RGBController_CorsairWireless(CorsairWirelessController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetName();
|
||||
vendor = "Corsair";
|
||||
description = "Corsair RGB Peripheral Device";
|
||||
type = controller->GetDeviceType();
|
||||
version = controller->GetFirmwareString();
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| 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 |
|
||||
\*-----------------------------------------------------*/
|
||||
keepalive_thread_run = true;
|
||||
keepalive_thread = new std::thread(&RGBController_CorsairWireless::KeepaliveThread, this);
|
||||
}
|
||||
|
||||
RGBController_CorsairWireless::~RGBController_CorsairWireless()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Close keepalive thread |
|
||||
\*-----------------------------------------------------*/
|
||||
keepalive_thread_run = false;
|
||||
keepalive_thread->join();
|
||||
delete keepalive_thread;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Delete the matrix map |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
|
||||
{
|
||||
if(zones[zone_index].matrix_map != NULL)
|
||||
{
|
||||
delete zones[zone_index].matrix_map;
|
||||
}
|
||||
}
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CorsairWireless::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Determine number of zones |
|
||||
| For now, keyboard has 2 zones and mousemat has 1 |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int num_zones = 1;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int total_led_count = 0;
|
||||
for(unsigned int zone_idx = 0; zone_idx < num_zones; zone_idx++)
|
||||
{
|
||||
zone new_zone;
|
||||
|
||||
new_zone.name = zone_names[zone_idx];
|
||||
new_zone.type = zone_types[zone_idx];
|
||||
new_zone.leds_min = zone_sizes[zone_idx];
|
||||
new_zone.leds_max = zone_sizes[zone_idx];
|
||||
new_zone.leds_count = zone_sizes[zone_idx];
|
||||
|
||||
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
|
||||
{
|
||||
new_zone.matrix_map = new matrix_map_type;
|
||||
new_zone.matrix_map->height = 7;
|
||||
new_zone.matrix_map->width = 24;
|
||||
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_zone.matrix_map = NULL;
|
||||
}
|
||||
|
||||
zones.push_back(new_zone);
|
||||
total_led_count += new_zone.leds_count;
|
||||
}
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
|
||||
new_led.name = led_names[led_idx];
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CorsairWireless::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_CorsairWireless::DeviceUpdateLEDs()
|
||||
{
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
|
||||
controller->SetLEDs(colors);
|
||||
}
|
||||
|
||||
void RGBController_CorsairWireless::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
controller->SetLEDs(colors);
|
||||
}
|
||||
|
||||
void RGBController_CorsairWireless::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
controller->SetLEDs(colors);
|
||||
}
|
||||
|
||||
void RGBController_CorsairWireless::DeviceUpdateMode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_CorsairWireless::KeepaliveThread()
|
||||
{
|
||||
while(keepalive_thread_run.load())
|
||||
{
|
||||
if(active_mode == 0)
|
||||
{
|
||||
if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(5000))
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(1000ms);
|
||||
}
|
||||
}
|
||||
@@ -134,7 +134,14 @@ void CrucialController::CrucialRegisterWriteBlock(crucial_register reg, unsigned
|
||||
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
|
||||
|
||||
//Write Crucial block data
|
||||
bus->i2c_smbus_write_block_data(dev, 0x03, sz, data);
|
||||
if(bus->i2c_smbus_write_block_data(dev, 0x03, sz, data) == -1)
|
||||
{
|
||||
//Fall back to individual byte operations if the block operation fails
|
||||
for(unsigned int block_byte = 0; block_byte < sz; block_byte++)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x01, data[block_byte]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CrucialController::SendEffectColor
|
||||
|
||||
@@ -27,12 +27,6 @@ using namespace std::chrono_literals;
|
||||
|
||||
static const unsigned char crucial_addresses[] =
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| These addresses have been disabled due to conflict |
|
||||
| with ASUS Aura DRAM. Since the detection scheme is |
|
||||
| the same, Aura RAM will be detected as Crucial. |
|
||||
| We need to improve the Crucial detection scheme. |
|
||||
\*-----------------------------------------------------*/
|
||||
0x39,
|
||||
0x3A,
|
||||
0x3B,
|
||||
@@ -81,7 +75,7 @@ unsigned char CrucialRegisterRead(i2c_smbus_interface* bus, crucial_dev_id dev,
|
||||
* 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 *
|
||||
* byte read 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 *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
@@ -90,19 +84,19 @@ bool TestForCrucialController(i2c_smbus_interface* bus, unsigned char address)
|
||||
{
|
||||
bool pass = false;
|
||||
|
||||
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
|
||||
int res = bus->i2c_smbus_read_byte(address);
|
||||
|
||||
if (res >= 0)
|
||||
if(res >= 0)
|
||||
{
|
||||
pass = true;
|
||||
|
||||
LOG_DEBUG("[%s] Detected an I2C device at address %02X", CRUCIAL_CONTROLLER_NAME, address);
|
||||
|
||||
for (int i = 0xA0; i < 0xB0; i++)
|
||||
for(int i = 0xA0; i < 0xB0; i++)
|
||||
{
|
||||
res = bus->i2c_smbus_read_byte_data(address, i);
|
||||
|
||||
if (res != (i - 0xA0))
|
||||
if(res != (i - 0xA0))
|
||||
{
|
||||
LOG_VERBOSE("[%s] Detection failed testing register %02X. Expected %02X, got %02X.", CRUCIAL_CONTROLLER_NAME, i, (i - 0xA0), res);
|
||||
|
||||
@@ -178,7 +172,7 @@ void DetectCrucialControllers(std::vector<i2c_smbus_interface*> &busses)
|
||||
{
|
||||
for(unsigned int slot = 0; slot < 4; slot++)
|
||||
{
|
||||
int res = busses[bus]->i2c_smbus_write_quick(0x27, I2C_SMBUS_WRITE);
|
||||
int res = busses[bus]->i2c_smbus_read_byte(0x27);
|
||||
|
||||
if(res < 0)
|
||||
{
|
||||
@@ -192,7 +186,7 @@ void DetectCrucialControllers(std::vector<i2c_smbus_interface*> &busses)
|
||||
|
||||
if(address_list_idx < CRUCIAL_ADDRESS_COUNT)
|
||||
{
|
||||
res = busses[bus]->i2c_smbus_write_quick(crucial_addresses[address_list_idx], I2C_SMBUS_WRITE);
|
||||
res = busses[bus]->i2c_smbus_read_byte(crucial_addresses[address_list_idx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -38,6 +38,8 @@ REGISTER_HID_DETECTOR("DeepRGB SIG V4F", DetectDRGBControllers, DRGBV
|
||||
|
||||
REGISTER_HID_DETECTOR("Airgoo AG-DRGB04", DetectDRGBControllers, DRGBV4_VID, DRGB_AG_04_V4F_PID);
|
||||
REGISTER_HID_DETECTOR("Airgoo AG-DRGB16", DetectDRGBControllers, DRGBV4_VID, DRGB_AG_16_V4F_PID);
|
||||
REGISTER_HID_DETECTOR("Airgoo AG-DRGB08", DetectDRGBControllers, DRGBV4_VID, DRGB_AG_08_PID);
|
||||
REGISTER_HID_DETECTOR("Airgoo AG-F8-DRGB08", DetectDRGBControllers, DRGBV4_VID, DRGB_AG_08_F08_PID);
|
||||
REGISTER_HID_DETECTOR("Airgoo AG-F12-DRGB16", DetectDRGBControllers, DRGBV4_VID, DRGB_AG_16_F12_PID);
|
||||
|
||||
REGISTER_HID_DETECTOR("DeepRGB L8 V5", DetectDRGBControllers, DRGBV4_VID, DRGB_L8_V5_PID);
|
||||
|
||||
@@ -93,6 +93,16 @@ void RGBController_DRGB::SetupZones()
|
||||
NUM_Channel_led = 256;
|
||||
Version = 4;
|
||||
break;
|
||||
case DRGB_AG_08_PID:
|
||||
NUM_CHANNELS = 8;
|
||||
NUM_Channel_led = 256;
|
||||
Version = 4;
|
||||
break;
|
||||
case DRGB_AG_08_F08_PID:
|
||||
NUM_CHANNELS = 8;
|
||||
NUM_Channel_led = 256;
|
||||
Version = 4;
|
||||
break;
|
||||
case DRGB_AG_16_V4F_PID:
|
||||
NUM_CHANNELS = 16;
|
||||
NUM_Channel_led = 256;
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#define DRGB_SIG_V4F_PID 0x3636
|
||||
#define DRGB_AG_04_V4F_PID 0x3204
|
||||
#define DRGB_AG_16_V4F_PID 0x3216
|
||||
#define DRGB_AG_08_PID 0x3F08
|
||||
#define DRGB_AG_08_F08_PID 0x3F16
|
||||
#define DRGB_AG_16_F12_PID 0x3F28
|
||||
|
||||
#define DRGB_L8_V5_PID 0x3208
|
||||
|
||||
@@ -65,7 +65,7 @@ void DygmaRaiseController::SendDirect(std::vector<RGBColor>colors, size_t led_nu
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up led theme packet |
|
||||
\*-----------------------------------------------------*/
|
||||
sprintf(serial_buf,"led.theme");
|
||||
snprintf(serial_buf, MAX_LEN, "led.theme");
|
||||
int actual_length=9;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
@@ -77,20 +77,20 @@ void DygmaRaiseController::SendDirect(std::vector<RGBColor>colors, size_t led_nu
|
||||
int g = RGBGetGValue(colors[led_idx]);
|
||||
int b = RGBGetBValue(colors[led_idx]);
|
||||
|
||||
sprintf(serial_buf+actual_length," %d",r);
|
||||
snprintf(serial_buf + actual_length, MAX_LEN - actual_length, " %d", r);
|
||||
actual_length += val_char_len(r) + 1;
|
||||
|
||||
sprintf(serial_buf+actual_length," %d",g);
|
||||
snprintf(serial_buf + actual_length, MAX_LEN - actual_length, " %d", g);
|
||||
actual_length += val_char_len(g) + 1;
|
||||
|
||||
sprintf(serial_buf+actual_length," %d",b);
|
||||
snprintf(serial_buf + actual_length, MAX_LEN - actual_length, " %d", b);
|
||||
actual_length += val_char_len(b) + 1;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Add the final newline |
|
||||
\*-----------------------------------------------------*/
|
||||
sprintf(serial_buf+actual_length,"\n");
|
||||
snprintf(serial_buf + actual_length, MAX_LEN - actual_length, "\n");
|
||||
actual_length++;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
|
||||
@@ -266,6 +266,21 @@ ENESMBusController::ENESMBusController(ENESMBusInterface* interface, ene_dev_id
|
||||
led_count = config_table[ENE_CONFIG_LED_COUNT_0107];
|
||||
}
|
||||
/*-----------------------------------------------------*\
|
||||
| AUMA0-E6K5-1114 |
|
||||
| Found on ASUS ROG MATRIX PLATINUM 5090 |
|
||||
\*-----------------------------------------------------*/
|
||||
else if(strcmp(device_version, "AUMA0-E6K5-1114") == 0)
|
||||
{
|
||||
direct_reg = ENE_REG_COLORS_DIRECT_V2;
|
||||
effect_reg = ENE_REG_COLORS_EFFECT_V2;
|
||||
channel_cfg = ENE_CONFIG_CHANNEL_V2;
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Read LED count from configuration table |
|
||||
\*-------------------------------------------------*/
|
||||
led_count = config_table[ENE_CONFIG_LED_COUNT_0107];
|
||||
}
|
||||
/*-----------------------------------------------------*\
|
||||
| ROG ARION - ASUS ROG Arion external SSD enclosure |
|
||||
| This device does not support ENE read, so we fake the |
|
||||
| device name string if the interface is ROG Arion type.|
|
||||
|
||||
@@ -30,10 +30,11 @@ using namespace std::chrono_literals;
|
||||
#undef interface
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------*\
|
||||
| This list contains the available SMBus addresses for mapping ENE RAM |
|
||||
\*----------------------------------------------------------------------*/
|
||||
#define ENE_RAM_ADDRESS_COUNT 23
|
||||
/*---------------------------------------------------------*\
|
||||
| This list contains the available SMBus addresses for |
|
||||
| mapping ENE RAM |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ENE_RAM_ADDRESS_COUNT (sizeof(ene_ram_addresses) / sizeof(ene_ram_addresses[0]))
|
||||
|
||||
static const unsigned char ene_ram_addresses[] =
|
||||
{
|
||||
@@ -44,14 +45,7 @@ static const unsigned char ene_ram_addresses[] =
|
||||
0x74,
|
||||
0x75,
|
||||
0x76,
|
||||
0x78,
|
||||
0x79,
|
||||
0x7A,
|
||||
0x7B,
|
||||
0x7C,
|
||||
0x7D,
|
||||
0x7E,
|
||||
0x7F,
|
||||
0x77,
|
||||
0x4F,
|
||||
0x66,
|
||||
0x67,
|
||||
@@ -62,10 +56,11 @@ static const unsigned char ene_ram_addresses[] =
|
||||
0x3D
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------*\
|
||||
| This list contains the available SMBus addresses for mapping Aura motherboards |
|
||||
\*---------------------------------------------------------------------------------*/
|
||||
#define AURA_MOBO_ADDRESS_COUNT 3
|
||||
/*---------------------------------------------------------*\
|
||||
| This list contains the available SMBus addresses for |
|
||||
| mapping Aura motherboards |
|
||||
\*---------------------------------------------------------*/
|
||||
#define AURA_MOBO_ADDRESS_COUNT (sizeof(aura_mobo_addresses) / sizeof(aura_mobo_addresses[0]))
|
||||
|
||||
static const unsigned char aura_mobo_addresses[] =
|
||||
{
|
||||
@@ -117,7 +112,7 @@ static void ENERegisterWrite(i2c_smbus_interface* bus, ene_dev_id dev, ene_regis
|
||||
* TestForENESMBusController *
|
||||
* *
|
||||
* Tests the given address to see if an ENE controller exists there. First does a *
|
||||
* quick write to test for a response, and if so does a simple read at 0xA0 to test *
|
||||
* byte read 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 *
|
||||
* *
|
||||
* Also tests for the string "Micron" in the ENE register space. Crucial (Micron) *
|
||||
@@ -207,7 +202,7 @@ void DetectENESMBusDRAMControllers(std::vector<i2c_smbus_interface*> &busses)
|
||||
|
||||
for (unsigned int slot = 0; slot < 8; slot++)
|
||||
{
|
||||
int res = busses[bus]->i2c_smbus_write_quick(0x77, I2C_SMBUS_WRITE);
|
||||
int res = busses[bus]->i2c_smbus_read_byte(0x77);
|
||||
|
||||
if(res < 0)
|
||||
{
|
||||
@@ -220,11 +215,11 @@ void DetectENESMBusDRAMControllers(std::vector<i2c_smbus_interface*> &busses)
|
||||
{
|
||||
address_list_idx++;
|
||||
|
||||
if(address_list_idx < ENE_RAM_ADDRESS_COUNT)
|
||||
if(address_list_idx < (int)ENE_RAM_ADDRESS_COUNT)
|
||||
{
|
||||
LOG_DEBUG("[ENE SMBus DRAM] Testing address %02X to see if there is a device there", ene_ram_addresses[address_list_idx]);
|
||||
|
||||
res = busses[bus]->i2c_smbus_write_quick(ene_ram_addresses[address_list_idx], I2C_SMBUS_WRITE);
|
||||
res = busses[bus]->i2c_smbus_read_byte(ene_ram_addresses[address_list_idx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -232,7 +227,7 @@ void DetectENESMBusDRAMControllers(std::vector<i2c_smbus_interface*> &busses)
|
||||
}
|
||||
} while (res >= 0);
|
||||
|
||||
if(address_list_idx < ENE_RAM_ADDRESS_COUNT)
|
||||
if(address_list_idx < (int)ENE_RAM_ADDRESS_COUNT)
|
||||
{
|
||||
LOG_DEBUG("[ENE SMBus DRAM] Remapping slot %d to address %02X", slot, ene_ram_addresses[address_list_idx]);
|
||||
|
||||
@@ -355,6 +350,7 @@ REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3060 Ti Gaming OC",
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3060 Ti OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3060TI_O8G_OC, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3060 Ti OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3060TI_O8G_OC_V2, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3060 Ti V2 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3060TI_O8G_V2_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3060 Ti V2 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3060TI_O8G_V2_2_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3070 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3070_OC, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3070 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3070_O8G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3070 White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3070_O8G_WHITE, 0x67);
|
||||
@@ -462,8 +458,11 @@ REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming White",
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_O24G_GAMING_WHITE, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_O24G_GAMING_WHITE_2, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG MATRIX PLATINUM GeForce RTX 4090", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_MATRIX_PLATINUM_RTX_4090_24G, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5070 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5070_O12G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5060 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5060_O8G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5070 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5070_O12G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5070 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5070TI_O16G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5070 Ti Gaming BTF White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5070TI_O16G_GAMING_BTF_WHITE, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5070 Ti Gaming White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5070TI_O16G_GAMING_WHITE, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 5070 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_5070TI_O16G_GAMING_OC, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5080 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5080_O16G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5090 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5090_O32G_GAMING, 0x67);
|
||||
@@ -471,7 +470,9 @@ REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5090 Gaming",
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5080 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5080_O16G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5080 OC WHITE", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5080_O16G_GAMING_WHITE, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5080", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5080_16G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5080 WHITE", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5080_16G_GAMING_WHITE, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5090 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5090_O32G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5090", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5090_O32G_GAMING_2, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5090 OC BTF", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5090_O32G_GAMING_BTF, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5090 OC WHITE", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5090_O32G_GAMING_WHITE, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL LC GeForce RTX 5090 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_LC_RTX_5090_O32G_GAMING, 0x67);
|
||||
@@ -502,6 +503,7 @@ REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 7700 XT Gaming OC",
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 7800 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI32_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7800XT_O16G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 7800 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI32_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7800XT_O16G_GAMING_0606, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 7800 XT Gaming White OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI32_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7800XT_O16G_WHITE_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 7900 GRE Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI31_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7900GRE_O16G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 7900 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI31_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7900XT_020G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 7900 XTX Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI31_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7900XTX_O24G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 9070 Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_9070_016G_GAMING, 0x67);
|
||||
|
||||
@@ -61,5 +61,12 @@ void ENESMBusInterface_i2c_smbus::ENERegisterWriteBlock(ene_dev_id dev, ene_regi
|
||||
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
|
||||
|
||||
//Write ENE block data
|
||||
bus->i2c_smbus_write_block_data(dev, 0x03, sz, data);
|
||||
if(bus->i2c_smbus_write_block_data(dev, 0x03, sz, data) == -1)
|
||||
{
|
||||
//Fall back to individual byte operations if the block operation fails
|
||||
for(unsigned int block_byte = 0; block_byte < sz; block_byte++)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x01, data[block_byte]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ FnaticStreakController::~FnaticStreakController()
|
||||
|
||||
std::string FnaticStreakController::GetDeviceLocation()
|
||||
{
|
||||
return("HID " + location);
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string FnaticStreakController::GetNameString()
|
||||
@@ -230,16 +230,41 @@ void FnaticStreakController::SetLEDsDirect(std::vector<led> leds, std::vector<RG
|
||||
|
||||
void FnaticStreakController::SendRGBToDevice()
|
||||
{
|
||||
unsigned int total_leds = GetLEDCount();
|
||||
unsigned int data_size = total_leds * 3;
|
||||
if(keyboard_type == FNATIC_STREAK_TYPE_65)
|
||||
{
|
||||
unsigned char data[64];
|
||||
memset(data, 0x00, sizeof(data));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| For direct/software control, use command 0x0f |
|
||||
| This bypasses the profile and allows immediate update |
|
||||
| The 0x03 subcommand indicates per-key color data |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char prefix[] = { 0x0f, 0x03 };
|
||||
SendRequest(prefix, sizeof(prefix), color_buf, data_size);
|
||||
data[0] = 0x0F;
|
||||
data[1] = 0x15;
|
||||
|
||||
data[7] = 0x0F;
|
||||
data[8] = 0x03;
|
||||
|
||||
for(unsigned int i = 9; i < 25; i++)
|
||||
{
|
||||
data[i] = 0xFF;
|
||||
}
|
||||
|
||||
data[25] = color_buf[0];
|
||||
data[26] = color_buf[1];
|
||||
data[27] = color_buf[2];
|
||||
|
||||
hid_write(dev, data, sizeof(data));
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int total_leds = GetLEDCount();
|
||||
unsigned int data_size = total_leds * 3;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| For direct/software control, use command 0x0f |
|
||||
| This bypasses the profile and allows immediate update |
|
||||
| The 0x03 subcommand indicates per-key color data |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char prefix[] = { 0x0f, 0x03 };
|
||||
SendRequest(prefix, sizeof(prefix), color_buf, data_size);
|
||||
}
|
||||
}
|
||||
|
||||
void FnaticStreakController::SetPulse(unsigned char color_mode, unsigned char r, unsigned char g, unsigned char b, unsigned char speed)
|
||||
|
||||
@@ -51,7 +51,8 @@
|
||||
enum FnaticStreakType
|
||||
{
|
||||
FNATIC_STREAK_TYPE_FULL,
|
||||
FNATIC_STREAK_TYPE_MINI
|
||||
FNATIC_STREAK_TYPE_MINI,
|
||||
FNATIC_STREAK_TYPE_65
|
||||
};
|
||||
|
||||
class FnaticStreakController
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#define FNATIC_STREAK_PID 0x0101
|
||||
#define FNATIC_MINISTREAK_PID 0x0102
|
||||
#define FNATIC_STREAK65_PID 0x0105
|
||||
|
||||
void DetectFnaticStreakKeyboard(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
@@ -39,6 +40,10 @@ void DetectFnaticStreakKeyboard(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
kb_type = FNATIC_STREAK_TYPE_MINI;
|
||||
}
|
||||
else if(info->product_id == FNATIC_STREAK65_PID)
|
||||
{
|
||||
kb_type = FNATIC_STREAK_TYPE_65;
|
||||
}
|
||||
else
|
||||
{
|
||||
kb_type = FNATIC_STREAK_TYPE_FULL;
|
||||
@@ -53,3 +58,4 @@ void DetectFnaticStreakKeyboard(hid_device_info* info, const std::string& name)
|
||||
|
||||
REGISTER_HID_DETECTOR_I("Fnatic Streak", DetectFnaticStreakKeyboard, FNATIC_VID, FNATIC_STREAK_PID, 1);
|
||||
REGISTER_HID_DETECTOR_I("Fnatic miniStreak", DetectFnaticStreakKeyboard, FNATIC_VID, FNATIC_MINISTREAK_PID, 1);
|
||||
REGISTER_HID_DETECTOR_I("Fnatic Streak65", DetectFnaticStreakKeyboard, FNATIC_VID, FNATIC_STREAK65_PID, 1);
|
||||
|
||||
@@ -37,19 +37,22 @@ bool TestForGalaxGPUController(i2c_smbus_interface* bus, unsigned char address)
|
||||
\*-----------------------------------------------------------------*/
|
||||
case 0x32:
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x00);
|
||||
if(res == 0x27 || res == 0x26) {
|
||||
if(res == 0x27 || res == 0x26)
|
||||
{
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x01);
|
||||
if (res == 0x10 || res == 0x20)
|
||||
if(res == 0x10 || res == 0x20)
|
||||
{
|
||||
pass = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| V1 Controller - RTX 3080 |
|
||||
| V1 Controller |
|
||||
\*-----------------------------------------------------------------*/
|
||||
case 0x23:
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x00);
|
||||
if(res == 0x30)
|
||||
if(res == 0x27 || res == 0x30)
|
||||
{
|
||||
pass = true;
|
||||
}
|
||||
@@ -60,8 +63,10 @@ bool TestForGalaxGPUController(i2c_smbus_interface* bus, unsigned char address)
|
||||
\*-----------------------------------------------------------------*/
|
||||
case 0x51:
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x00);
|
||||
if (res == 0x80)
|
||||
if(res == 0x80)
|
||||
{
|
||||
pass = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| GigabyteCastor3Controller.cpp |
|
||||
| |
|
||||
| Driver for Gigabyte Aorus Waterforce X II 360 AIO |
|
||||
| (Castor3 USB HID controller) |
|
||||
| |
|
||||
| RGB ring control only — LCD not implemented |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "GigabyteCastor3Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
GigabyteCastor3Controller::GigabyteCastor3Controller(hid_device* dev_handle, const char* path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Query firmware version via de 00 |
|
||||
| Response: de [version_byte] |
|
||||
| Observed: de 02 -> version 2 |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char de_payload[] = { 0xDE, 0x00 };
|
||||
SendPacket(de_payload, 2);
|
||||
|
||||
unsigned char response[CASTOR3_IN_SIZE];
|
||||
int bytes_read = hid_read_timeout(dev, response, CASTOR3_IN_SIZE, CASTOR3_IN_TIMEOUT_MS);
|
||||
|
||||
if(bytes_read > 1)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Strip report ID 0x99 if present on IN packets |
|
||||
\*-----------------------------------------------------*/
|
||||
int offset = 0;
|
||||
if(response[0] == CASTOR3_REPORT_ID)
|
||||
{
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
if(response[offset] == 0xDE && bytes_read > offset + 1)
|
||||
{
|
||||
firmware_version = std::to_string(response[offset + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GigabyteCastor3Controller::~GigabyteCastor3Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string GigabyteCastor3Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string GigabyteCastor3Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string GigabyteCastor3Controller::GetFirmwareVersion()
|
||||
{
|
||||
return firmware_version;
|
||||
}
|
||||
|
||||
void GigabyteCastor3Controller::SetEffect
|
||||
(
|
||||
unsigned char style,
|
||||
unsigned char speed,
|
||||
unsigned char brightness,
|
||||
unsigned char b4,
|
||||
unsigned char b5,
|
||||
castor3_color_type color_type,
|
||||
std::vector<RGBColor> colors
|
||||
)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Wire protocol for LED effect apply |
|
||||
| (from castor3.py led_set_effect, confirmed from |
|
||||
| led_profile.pcapng + .cled.dat cross-reference) |
|
||||
| |
|
||||
| Step 1: c9 [Style] [Speed*20] [Bright] [b4] [b5] |
|
||||
| Step 2: cd [R] [G] [B] (single-color only) |
|
||||
| -OR- b0..b3 palette registers (palette effects) |
|
||||
| Step 3: b6 (commit) |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Step 1: c9 — effect select + parameters |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char c9_payload[] =
|
||||
{
|
||||
0xC9,
|
||||
style,
|
||||
(unsigned char)(speed * 20),
|
||||
brightness,
|
||||
b4,
|
||||
b5
|
||||
};
|
||||
SendPacket(c9_payload, sizeof(c9_payload));
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Step 2a: cd — primary color for single-color effects |
|
||||
| Effects: static, pulse, flash, dflash, gradient, off |
|
||||
\*---------------------------------------------------------*/
|
||||
if(color_type == CASTOR3_COLORS_SINGLE)
|
||||
{
|
||||
unsigned char r = 0xFF, g = 0x66, b = 0x00;
|
||||
|
||||
if(colors.size() > 0)
|
||||
{
|
||||
r = RGBGetRValue(colors[0]);
|
||||
g = RGBGetGValue(colors[0]);
|
||||
b = RGBGetBValue(colors[0]);
|
||||
}
|
||||
|
||||
unsigned char cd_payload[] = { 0xCD, r, g, b };
|
||||
SendPacket(cd_payload, sizeof(cd_payload));
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| Step 2b: b0..b3 — palette registers for multi-color |
|
||||
| Each register carries 2 colors (6 bytes RGB + 1 pad): |
|
||||
| bN [Style] [R1 G1 B1] [R2 G2 B2] 0x00 |
|
||||
| b0=colors 1+2, b1=colors 3+4, b2=colors 5+6, b3=7+8 |
|
||||
| |
|
||||
| Effects: colorshift(8), tricolor(3), spin(3), switch(2) |
|
||||
\*---------------------------------------------------------*/
|
||||
else if(color_type == CASTOR3_COLORS_PALETTE)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Build palette: pad to 8 colors by repeating last |
|
||||
\*-----------------------------------------------------*/
|
||||
RGBColor palette[8];
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
if(i < (int)colors.size())
|
||||
{
|
||||
palette[i] = colors[i];
|
||||
}
|
||||
else if(colors.size() > 0)
|
||||
{
|
||||
palette[i] = colors[colors.size() - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
palette[i] = ToRGBColor(0xFF, 0x00, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char regs[] = { 0xB0, 0xB1, 0xB2, 0xB3 };
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
RGBColor c1 = palette[i * 2];
|
||||
RGBColor c2 = palette[i * 2 + 1];
|
||||
|
||||
unsigned char bN_payload[] =
|
||||
{
|
||||
regs[i],
|
||||
style,
|
||||
(unsigned char)RGBGetRValue(c1), (unsigned char)RGBGetGValue(c1), (unsigned char)RGBGetBValue(c1),
|
||||
(unsigned char)RGBGetRValue(c2), (unsigned char)RGBGetGValue(c2), (unsigned char)RGBGetBValue(c2),
|
||||
0x00
|
||||
};
|
||||
SendPacket(bN_payload, sizeof(bN_payload));
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Step 3: b6 — commit/apply |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char b6_payload[] = { 0xB6 };
|
||||
SendPacket(b6_payload, sizeof(b6_payload));
|
||||
}
|
||||
|
||||
void GigabyteCastor3Controller::SetOff()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Off = Style 0x01 (Static) with Speed=0 |
|
||||
| From castor3.py: off uses style 0x01, speed_wire=0 |
|
||||
\*---------------------------------------------------------*/
|
||||
std::vector<RGBColor> black;
|
||||
black.push_back(ToRGBColor(0x00, 0x00, 0x00));
|
||||
|
||||
unsigned char c9_payload[] =
|
||||
{
|
||||
0xC9,
|
||||
CASTOR3_STYLE_STATIC,
|
||||
0x00, /* speed_wire = 0 for off */
|
||||
CASTOR3_BRIGHTNESS_DEFAULT,
|
||||
0x02, /* b4 */
|
||||
0x01 /* b5 */
|
||||
};
|
||||
SendPacket(c9_payload, sizeof(c9_payload));
|
||||
|
||||
unsigned char cd_payload[] = { 0xCD, 0x00, 0x00, 0x00 };
|
||||
SendPacket(cd_payload, sizeof(cd_payload));
|
||||
|
||||
unsigned char b6_payload[] = { 0xB6 };
|
||||
SendPacket(b6_payload, sizeof(b6_payload));
|
||||
}
|
||||
|
||||
void GigabyteCastor3Controller::SendPacket(const unsigned char* payload, unsigned int payload_len)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Castor3 HID OUT transport: |
|
||||
| - Byte 0: Report ID (0x99) |
|
||||
| - Bytes 1..6143: payload, zero-padded |
|
||||
| Total write size: 6144 bytes |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char buf[CASTOR3_OUT_TOTAL];
|
||||
memset(buf, 0x00, CASTOR3_OUT_TOTAL);
|
||||
|
||||
buf[0] = CASTOR3_REPORT_ID;
|
||||
|
||||
if(payload_len > CASTOR3_OUT_PAYLOAD)
|
||||
{
|
||||
payload_len = CASTOR3_OUT_PAYLOAD;
|
||||
}
|
||||
|
||||
memcpy(&buf[1], payload, payload_len);
|
||||
|
||||
hid_write(dev, buf, CASTOR3_OUT_TOTAL);
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| GigabyteCastor3Controller.h |
|
||||
| |
|
||||
| Driver for Gigabyte Aorus Waterforce X II 360 AIO |
|
||||
| (Castor3 USB HID controller) |
|
||||
| |
|
||||
| RGB ring control only — LCD not implemented |
|
||||
| |
|
||||
| Protocol reference: castor3.py reverse engineering |
|
||||
| VID=0x0414 PID=0x7A5E Report ID=0x99 |
|
||||
| OUT size: 6144 (report ID + 6143 payload) |
|
||||
| IN size: 255 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Castor3 USB IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#define CASTOR3_VID 0x0414
|
||||
#define CASTOR3_PID 0x7A5E
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Castor3 HID transport |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#define CASTOR3_REPORT_ID 0x99
|
||||
#define CASTOR3_OUT_PAYLOAD 6143 /* payload after report ID */
|
||||
#define CASTOR3_OUT_TOTAL 6144 /* report ID + payload */
|
||||
#define CASTOR3_IN_SIZE 255
|
||||
#define CASTOR3_IN_TIMEOUT_MS 2000
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| LED effect style IDs (c9 byte[1]) |
|
||||
| From castor3.py LED_EFFECTS, cross-referenced with |
|
||||
| .cled.dat profile files and led_profile.pcapng |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#define CASTOR3_STYLE_STATIC 0x01
|
||||
#define CASTOR3_STYLE_PULSE 0x02
|
||||
#define CASTOR3_STYLE_CYCLE 0x03
|
||||
#define CASTOR3_STYLE_FLASH 0x04
|
||||
#define CASTOR3_STYLE_DFLASH 0x05
|
||||
#define CASTOR3_STYLE_GRADIENT 0x06
|
||||
#define CASTOR3_STYLE_COLORSHIFT 0x07
|
||||
#define CASTOR3_STYLE_WAVE 0x08
|
||||
#define CASTOR3_STYLE_RAINBOW 0x0A
|
||||
#define CASTOR3_STYLE_TRICOLOR 0x0B
|
||||
#define CASTOR3_STYLE_SPIN 0x0C
|
||||
#define CASTOR3_STYLE_SWITCH 0x0D
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| LED speed range: 1-5 (wire value = speed * 20) |
|
||||
| LED brightness range: 1-10 (direct on wire) |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#define CASTOR3_SPEED_MIN 1
|
||||
#define CASTOR3_SPEED_MAX 5
|
||||
#define CASTOR3_SPEED_DEFAULT 5
|
||||
#define CASTOR3_BRIGHTNESS_MIN 1
|
||||
#define CASTOR3_BRIGHTNESS_MAX 10
|
||||
#define CASTOR3_BRIGHTNESS_DEFAULT 10
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Color type for effects |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
enum castor3_color_type
|
||||
{
|
||||
CASTOR3_COLORS_NONE = 0, /* cycle, wave, rainbow */
|
||||
CASTOR3_COLORS_SINGLE = 1, /* static, pulse, flash... */
|
||||
CASTOR3_COLORS_PALETTE = 2, /* colorshift, tricolor... */
|
||||
};
|
||||
|
||||
class GigabyteCastor3Controller
|
||||
{
|
||||
public:
|
||||
GigabyteCastor3Controller(hid_device* dev_handle, const char* path);
|
||||
~GigabyteCastor3Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetSerialString();
|
||||
std::string GetFirmwareVersion();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| LED effect application |
|
||||
| |
|
||||
| Wire sequence per effect apply: |
|
||||
| c9 [Style] [Speed*20] [Bright] [b4] [b5] |
|
||||
| cd [R] [G] [B] — single-color only |
|
||||
| b0 [Style] [R1G1B1] [R2G2B2] 00 — palette colors 1+2 |
|
||||
| b1 [Style] [R3G3B3] [R4G4B4] 00 — colors 3+4 |
|
||||
| b2 [Style] [R5G5B5] [R6G6B6] 00 — colors 5+6 |
|
||||
| b3 [Style] [R7G7B7] [R8G8B8] 00 — colors 7+8 |
|
||||
| b6 — commit/apply |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
void SetEffect(unsigned char style,
|
||||
unsigned char speed,
|
||||
unsigned char brightness,
|
||||
unsigned char b4,
|
||||
unsigned char b5,
|
||||
castor3_color_type color_type,
|
||||
std::vector<RGBColor> colors);
|
||||
|
||||
void SetOff();
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string firmware_version;
|
||||
|
||||
void SendPacket(const unsigned char* payload, unsigned int payload_len);
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| GigabyteCastor3ControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Gigabyte Aorus Waterforce X II 360 AIO |
|
||||
| (Castor3 USB HID controller) |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "Detector.h"
|
||||
#include "GigabyteCastor3Controller.h"
|
||||
#include "RGBController_GigabyteCastor3.h"
|
||||
|
||||
#define GIGABYTE_CASTOR3_VID 0x0414
|
||||
#define GIGABYTE_CASTOR3_PID 0x7A5E
|
||||
|
||||
void DetectGigabyteCastor3Controllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
GigabyteCastor3Controller* controller = new GigabyteCastor3Controller(dev, info->path);
|
||||
RGBController_GigabyteCastor3* rgb_controller = new RGBController_GigabyteCastor3(controller);
|
||||
rgb_controller->name = name;
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Gigabyte Aorus Waterforce X II 360",
|
||||
DetectGigabyteCastor3Controllers,
|
||||
GIGABYTE_CASTOR3_VID,
|
||||
GIGABYTE_CASTOR3_PID,
|
||||
0, /* interface 0 */
|
||||
0x0000, /* usage_page */
|
||||
0x0002); /* usage */
|
||||
@@ -0,0 +1,446 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_GigabyteCastor3.cpp |
|
||||
| |
|
||||
| RGBController for Gigabyte Aorus Waterforce X II 360 |
|
||||
| AIO Cooler (Castor3 controller) |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_GigabyteCastor3.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Gigabyte Aorus Waterforce X II 360
|
||||
@category Cooler
|
||||
@type USB
|
||||
@save :o:
|
||||
@direct :o:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectGigabyteCastor3Controllers
|
||||
@comment Controls the LED ring on the pump head of the
|
||||
Gigabyte Aorus Waterforce X II 360 AIO cooler.
|
||||
Uses the Castor3 USB HID controller (VID 0x0414, PID 0x7A5E).
|
||||
The LED ring and fans share the same controller — they are
|
||||
not independently addressable and follow the same effect.
|
||||
LCD display control is not implemented.
|
||||
No direct/per-LED mode available — all modes are hardware
|
||||
effects with a single color or palette.
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_GigabyteCastor3::RGBController_GigabyteCastor3(GigabyteCastor3Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = "Gigabyte Aorus Waterforce X II 360";
|
||||
vendor = "Gigabyte";
|
||||
type = DEVICE_TYPE_COOLER;
|
||||
description = "Gigabyte Aorus Waterforce X II 360 AIO Cooler";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
version = controller->GetFirmwareVersion();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| All modes from castor3.py LED_EFFECTS (12 effects + off) |
|
||||
| |
|
||||
| The Castor3 has no direct/per-LED mode. All effects are |
|
||||
| hardware-driven, either single-color, palette, or |
|
||||
| firmware-color (no user color). |
|
||||
| |
|
||||
| Speed: 1-5 mapped to MODE_FLAG_HAS_SPEED |
|
||||
| Brightness: 1-10 mapped to MODE_FLAG_HAS_BRIGHTNESS |
|
||||
| |
|
||||
| mode.value stores the style byte for the c9 command. |
|
||||
| mode.speed stores 1-5 (scaled to speed*20 on wire). |
|
||||
| mode.brightness stores 1-10 (direct on wire). |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Off |
|
||||
| Wire: Style=0x01 (Static) with speed_wire=0 |
|
||||
\*---------------------------------------------------------*/
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = 0xFF; /* sentinel — handled specially */
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Static — single color, no speed |
|
||||
\*---------------------------------------------------------*/
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = CASTOR3_STYLE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.brightness_min = CASTOR3_BRIGHTNESS_MIN;
|
||||
Static.brightness_max = CASTOR3_BRIGHTNESS_MAX;
|
||||
Static.brightness = CASTOR3_BRIGHTNESS_DEFAULT;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Pulse — single color, speed + brightness |
|
||||
\*---------------------------------------------------------*/
|
||||
mode Pulse;
|
||||
Pulse.name = "Pulse";
|
||||
Pulse.value = CASTOR3_STYLE_PULSE;
|
||||
Pulse.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Pulse.speed_min = CASTOR3_SPEED_MIN;
|
||||
Pulse.speed_max = CASTOR3_SPEED_MAX;
|
||||
Pulse.speed = CASTOR3_SPEED_DEFAULT;
|
||||
Pulse.colors_min = 1;
|
||||
Pulse.colors_max = 1;
|
||||
Pulse.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Pulse.brightness_min = CASTOR3_BRIGHTNESS_MIN;
|
||||
Pulse.brightness_max = CASTOR3_BRIGHTNESS_MAX;
|
||||
Pulse.brightness = CASTOR3_BRIGHTNESS_DEFAULT;
|
||||
Pulse.colors.resize(1);
|
||||
modes.push_back(Pulse);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Flash — single color, speed + brightness |
|
||||
\*---------------------------------------------------------*/
|
||||
mode Flash;
|
||||
Flash.name = "Flash";
|
||||
Flash.value = CASTOR3_STYLE_FLASH;
|
||||
Flash.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Flash.speed_min = CASTOR3_SPEED_MIN;
|
||||
Flash.speed_max = CASTOR3_SPEED_MAX;
|
||||
Flash.speed = CASTOR3_SPEED_DEFAULT;
|
||||
Flash.colors_min = 1;
|
||||
Flash.colors_max = 1;
|
||||
Flash.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Flash.brightness_min = CASTOR3_BRIGHTNESS_MIN;
|
||||
Flash.brightness_max = CASTOR3_BRIGHTNESS_MAX;
|
||||
Flash.brightness = CASTOR3_BRIGHTNESS_DEFAULT;
|
||||
Flash.colors.resize(1);
|
||||
modes.push_back(Flash);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Double Flash — single color, speed + brightness |
|
||||
\*---------------------------------------------------------*/
|
||||
mode DFlash;
|
||||
DFlash.name = "Double Flash";
|
||||
DFlash.value = CASTOR3_STYLE_DFLASH;
|
||||
DFlash.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
DFlash.speed_min = CASTOR3_SPEED_MIN;
|
||||
DFlash.speed_max = CASTOR3_SPEED_MAX;
|
||||
DFlash.speed = CASTOR3_SPEED_DEFAULT;
|
||||
DFlash.colors_min = 1;
|
||||
DFlash.colors_max = 1;
|
||||
DFlash.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
DFlash.brightness_min = CASTOR3_BRIGHTNESS_MIN;
|
||||
DFlash.brightness_max = CASTOR3_BRIGHTNESS_MAX;
|
||||
DFlash.brightness = CASTOR3_BRIGHTNESS_DEFAULT;
|
||||
DFlash.colors.resize(1);
|
||||
modes.push_back(DFlash);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Cycle — firmware colors, speed only |
|
||||
\*---------------------------------------------------------*/
|
||||
mode Cycle;
|
||||
Cycle.name = "Spectrum Cycle";
|
||||
Cycle.value = CASTOR3_STYLE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Cycle.speed_min = CASTOR3_SPEED_MIN;
|
||||
Cycle.speed_max = CASTOR3_SPEED_MAX;
|
||||
Cycle.speed = CASTOR3_SPEED_DEFAULT;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.brightness_min = CASTOR3_BRIGHTNESS_MIN;
|
||||
Cycle.brightness_max = CASTOR3_BRIGHTNESS_MAX;
|
||||
Cycle.brightness = CASTOR3_BRIGHTNESS_DEFAULT;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Gradient — single color, speed + brightness |
|
||||
| Note: b4 = brightness on wire (special case) |
|
||||
\*---------------------------------------------------------*/
|
||||
mode Gradient;
|
||||
Gradient.name = "Gradient";
|
||||
Gradient.value = CASTOR3_STYLE_GRADIENT;
|
||||
Gradient.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Gradient.speed_min = CASTOR3_SPEED_MIN;
|
||||
Gradient.speed_max = CASTOR3_SPEED_MAX;
|
||||
Gradient.speed = CASTOR3_SPEED_DEFAULT;
|
||||
Gradient.colors_min = 1;
|
||||
Gradient.colors_max = 1;
|
||||
Gradient.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Gradient.brightness_min = CASTOR3_BRIGHTNESS_MIN;
|
||||
Gradient.brightness_max = CASTOR3_BRIGHTNESS_MAX;
|
||||
Gradient.brightness = CASTOR3_BRIGHTNESS_DEFAULT;
|
||||
Gradient.colors.resize(1);
|
||||
modes.push_back(Gradient);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Color Shift — 8-color palette, speed + brightness |
|
||||
\*---------------------------------------------------------*/
|
||||
mode ColorShift;
|
||||
ColorShift.name = "Color Shift";
|
||||
ColorShift.value = CASTOR3_STYLE_COLORSHIFT;
|
||||
ColorShift.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
ColorShift.speed_min = CASTOR3_SPEED_MIN;
|
||||
ColorShift.speed_max = CASTOR3_SPEED_MAX;
|
||||
ColorShift.speed = CASTOR3_SPEED_DEFAULT;
|
||||
ColorShift.colors_min = 1;
|
||||
ColorShift.colors_max = 8;
|
||||
ColorShift.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
ColorShift.brightness_min = CASTOR3_BRIGHTNESS_MIN;
|
||||
ColorShift.brightness_max = CASTOR3_BRIGHTNESS_MAX;
|
||||
ColorShift.brightness = CASTOR3_BRIGHTNESS_DEFAULT;
|
||||
ColorShift.colors.resize(8);
|
||||
ColorShift.colors[0] = ToRGBColor(0xFF, 0x00, 0x00);
|
||||
ColorShift.colors[1] = ToRGBColor(0xFF, 0x72, 0x00);
|
||||
ColorShift.colors[2] = ToRGBColor(0xFF, 0xFF, 0x00);
|
||||
ColorShift.colors[3] = ToRGBColor(0x00, 0xFF, 0x00);
|
||||
ColorShift.colors[4] = ToRGBColor(0x00, 0xFF, 0xFF);
|
||||
ColorShift.colors[5] = ToRGBColor(0x00, 0x00, 0xFF);
|
||||
ColorShift.colors[6] = ToRGBColor(0xFF, 0x00, 0xFF);
|
||||
ColorShift.colors[7] = ToRGBColor(0xFF, 0x80, 0x80);
|
||||
modes.push_back(ColorShift);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Wave — firmware colors, speed only |
|
||||
\*---------------------------------------------------------*/
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = CASTOR3_STYLE_WAVE;
|
||||
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Wave.speed_min = CASTOR3_SPEED_MIN;
|
||||
Wave.speed_max = CASTOR3_SPEED_MAX;
|
||||
Wave.speed = CASTOR3_SPEED_DEFAULT;
|
||||
Wave.color_mode = MODE_COLORS_NONE;
|
||||
Wave.brightness_min = CASTOR3_BRIGHTNESS_MIN;
|
||||
Wave.brightness_max = CASTOR3_BRIGHTNESS_MAX;
|
||||
Wave.brightness = CASTOR3_BRIGHTNESS_DEFAULT;
|
||||
modes.push_back(Wave);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Rainbow — firmware colors, speed only |
|
||||
\*---------------------------------------------------------*/
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.value = CASTOR3_STYLE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Rainbow.speed_min = CASTOR3_SPEED_MIN;
|
||||
Rainbow.speed_max = CASTOR3_SPEED_MAX;
|
||||
Rainbow.speed = CASTOR3_SPEED_DEFAULT;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
Rainbow.brightness_min = CASTOR3_BRIGHTNESS_MIN;
|
||||
Rainbow.brightness_max = CASTOR3_BRIGHTNESS_MAX;
|
||||
Rainbow.brightness = CASTOR3_BRIGHTNESS_DEFAULT;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Tri-Color — 3-color palette, speed + brightness |
|
||||
\*---------------------------------------------------------*/
|
||||
mode TriColor;
|
||||
TriColor.name = "Tri-Color";
|
||||
TriColor.value = CASTOR3_STYLE_TRICOLOR;
|
||||
TriColor.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
TriColor.speed_min = CASTOR3_SPEED_MIN;
|
||||
TriColor.speed_max = CASTOR3_SPEED_MAX;
|
||||
TriColor.speed = CASTOR3_SPEED_DEFAULT;
|
||||
TriColor.colors_min = 1;
|
||||
TriColor.colors_max = 3;
|
||||
TriColor.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
TriColor.brightness_min = CASTOR3_BRIGHTNESS_MIN;
|
||||
TriColor.brightness_max = CASTOR3_BRIGHTNESS_MAX;
|
||||
TriColor.brightness = CASTOR3_BRIGHTNESS_DEFAULT;
|
||||
TriColor.colors.resize(3);
|
||||
TriColor.colors[0] = ToRGBColor(0x00, 0x00, 0xFF);
|
||||
TriColor.colors[1] = ToRGBColor(0x7D, 0x00, 0xFF);
|
||||
TriColor.colors[2] = ToRGBColor(0xFF, 0x00, 0xFF);
|
||||
modes.push_back(TriColor);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Spin — 3-color palette, speed + brightness |
|
||||
\*---------------------------------------------------------*/
|
||||
mode Spin;
|
||||
Spin.name = "Spin";
|
||||
Spin.value = CASTOR3_STYLE_SPIN;
|
||||
Spin.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Spin.speed_min = CASTOR3_SPEED_MIN;
|
||||
Spin.speed_max = CASTOR3_SPEED_MAX;
|
||||
Spin.speed = CASTOR3_SPEED_DEFAULT;
|
||||
Spin.colors_min = 1;
|
||||
Spin.colors_max = 3;
|
||||
Spin.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Spin.brightness_min = CASTOR3_BRIGHTNESS_MIN;
|
||||
Spin.brightness_max = CASTOR3_BRIGHTNESS_MAX;
|
||||
Spin.brightness = CASTOR3_BRIGHTNESS_DEFAULT;
|
||||
Spin.colors.resize(3);
|
||||
Spin.colors[0] = ToRGBColor(0xFF, 0x00, 0xFE);
|
||||
Spin.colors[1] = ToRGBColor(0x00, 0xFF, 0xFB);
|
||||
Spin.colors[2] = ToRGBColor(0xFF, 0xFF, 0x00);
|
||||
modes.push_back(Spin);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Switch — 2-color palette, speed + brightness |
|
||||
\*---------------------------------------------------------*/
|
||||
mode Switch;
|
||||
Switch.name = "Switch";
|
||||
Switch.value = CASTOR3_STYLE_SWITCH;
|
||||
Switch.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Switch.speed_min = CASTOR3_SPEED_MIN;
|
||||
Switch.speed_max = CASTOR3_SPEED_MAX;
|
||||
Switch.speed = CASTOR3_SPEED_DEFAULT;
|
||||
Switch.colors_min = 1;
|
||||
Switch.colors_max = 2;
|
||||
Switch.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Switch.brightness_min = CASTOR3_BRIGHTNESS_MIN;
|
||||
Switch.brightness_max = CASTOR3_BRIGHTNESS_MAX;
|
||||
Switch.brightness = CASTOR3_BRIGHTNESS_DEFAULT;
|
||||
Switch.colors.resize(2);
|
||||
Switch.colors[0] = ToRGBColor(0xFF, 0x00, 0xFE);
|
||||
Switch.colors[1] = ToRGBColor(0x00, 0xFF, 0xFB);
|
||||
modes.push_back(Switch);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_GigabyteCastor3::~RGBController_GigabyteCastor3()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_GigabyteCastor3::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Single zone: LED ring + fans (not independently |
|
||||
| addressable — fans follow the pump ring effect) |
|
||||
| |
|
||||
| This is a SINGLE zone because the protocol does not |
|
||||
| expose per-LED addressing. All LEDs display the same |
|
||||
| hardware effect simultaneously. |
|
||||
\*---------------------------------------------------------*/
|
||||
zone led_ring;
|
||||
led_ring.name = "LED Ring";
|
||||
led_ring.type = ZONE_TYPE_SINGLE;
|
||||
led_ring.leds_min = 1;
|
||||
led_ring.leds_max = 1;
|
||||
led_ring.leds_count = 1;
|
||||
led_ring.matrix_map = NULL;
|
||||
zones.push_back(led_ring);
|
||||
|
||||
led new_led;
|
||||
new_led.name = "LED Ring";
|
||||
leds.push_back(new_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_GigabyteCastor3::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Fixed zone size — not resizable |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_GigabyteCastor3::DeviceUpdateLEDs()
|
||||
{
|
||||
DeviceUpdateMode();
|
||||
}
|
||||
|
||||
void RGBController_GigabyteCastor3::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_GigabyteCastor3::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_GigabyteCastor3::DeviceUpdateMode()
|
||||
{
|
||||
unsigned char style = (unsigned char)modes[active_mode].value;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Handle Off mode (sentinel value 0xFF) |
|
||||
\*---------------------------------------------------------*/
|
||||
if(style == 0xFF)
|
||||
{
|
||||
controller->SetOff();
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Determine speed, brightness, b4, b5, and color type |
|
||||
| from the effect lookup table matching castor3.py |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char speed = CASTOR3_SPEED_DEFAULT;
|
||||
unsigned char brightness = CASTOR3_BRIGHTNESS_DEFAULT;
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
speed = (unsigned char)modes[active_mode].speed;
|
||||
}
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_BRIGHTNESS)
|
||||
{
|
||||
brightness = (unsigned char)modes[active_mode].brightness;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Look up b4, b5, and color_type per effect |
|
||||
| These match the LED_EFFECTS dict in castor3.py |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char b4 = 0x02;
|
||||
unsigned char b5 = 0x01;
|
||||
castor3_color_type color_type = CASTOR3_COLORS_NONE;
|
||||
|
||||
switch(style)
|
||||
{
|
||||
case CASTOR3_STYLE_STATIC:
|
||||
case CASTOR3_STYLE_PULSE:
|
||||
case CASTOR3_STYLE_FLASH:
|
||||
case CASTOR3_STYLE_DFLASH:
|
||||
b4 = 0x02;
|
||||
b5 = 0x01;
|
||||
color_type = CASTOR3_COLORS_SINGLE;
|
||||
break;
|
||||
|
||||
case CASTOR3_STYLE_GRADIENT:
|
||||
/*-------------------------------------------------*\
|
||||
| Gradient: b4 = brightness on wire (special case) |
|
||||
\*-------------------------------------------------*/
|
||||
b4 = brightness;
|
||||
b5 = 0x01;
|
||||
color_type = CASTOR3_COLORS_SINGLE;
|
||||
break;
|
||||
|
||||
case CASTOR3_STYLE_CYCLE:
|
||||
case CASTOR3_STYLE_WAVE:
|
||||
case CASTOR3_STYLE_RAINBOW:
|
||||
b4 = 0x02;
|
||||
b5 = 0x01;
|
||||
color_type = CASTOR3_COLORS_NONE;
|
||||
break;
|
||||
|
||||
case CASTOR3_STYLE_COLORSHIFT:
|
||||
b4 = 0x08; /* ClrCount=8 */
|
||||
b5 = 0x02; /* CmbIndex+1=2 */
|
||||
color_type = CASTOR3_COLORS_PALETTE;
|
||||
break;
|
||||
|
||||
case CASTOR3_STYLE_TRICOLOR:
|
||||
case CASTOR3_STYLE_SPIN:
|
||||
b4 = 0x02;
|
||||
b5 = 0x01;
|
||||
color_type = CASTOR3_COLORS_PALETTE;
|
||||
break;
|
||||
|
||||
case CASTOR3_STYLE_SWITCH:
|
||||
b4 = 0x02;
|
||||
b5 = 0x01;
|
||||
color_type = CASTOR3_COLORS_PALETTE;
|
||||
break;
|
||||
}
|
||||
|
||||
controller->SetEffect(style, speed, brightness, b4, b5,
|
||||
color_type, modes[active_mode].colors);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_GigabyteCastor3.h |
|
||||
| |
|
||||
| RGBController for Gigabyte Aorus Waterforce X II 360 |
|
||||
| AIO Cooler (Castor3 controller) |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "GigabyteCastor3Controller.h"
|
||||
|
||||
class RGBController_GigabyteCastor3 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_GigabyteCastor3(GigabyteCastor3Controller* controller_ptr);
|
||||
~RGBController_GigabyteCastor3();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
GigabyteCastor3Controller* controller;
|
||||
};
|
||||
-203
@@ -1,203 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| GigabyteRGBFusion2AorusMasterGPUController.cpp |
|
||||
| |
|
||||
| Driver for Gigabyte AORUS MASTER GPU with fan ring LEDs |
|
||||
| |
|
||||
| Protocol reverse engineered from GCC on Windows |
|
||||
| Verified on Linux with i2ctransfer 2025-12-30 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "GigabyteRGBFusion2AorusMasterGPUController.h"
|
||||
#include "LogManager.h"
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
RGBFusion2AorusMasterGPUController::RGBFusion2AorusMasterGPUController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev, std::string dev_name)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
this->name = dev_name;
|
||||
}
|
||||
|
||||
RGBFusion2AorusMasterGPUController::~RGBFusion2AorusMasterGPUController()
|
||||
{
|
||||
}
|
||||
|
||||
std::string RGBFusion2AorusMasterGPUController::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("I2C: " + return_string);
|
||||
}
|
||||
|
||||
std::string RGBFusion2AorusMasterGPUController::GetDeviceName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Send mode command to select a fan zone |
|
||||
| Format: 88 01 06 63 08 <zone_id> 00 00 |
|
||||
| Byte 0: Mode register (0x88) |
|
||||
| Byte 1: Static mode (0x01) |
|
||||
| Byte 2: Unknown constant (0x06) |
|
||||
| Byte 3: Brightness (0x00-0x63) |
|
||||
| Byte 4: Unknown constant (0x08) |
|
||||
| Byte 5: Zone selector (0x02/0x05/0x06) |
|
||||
| Byte 6-7: Padding (0x00) |
|
||||
\*---------------------------------------------------------*/
|
||||
void RGBFusion2AorusMasterGPUController::SendModeCommand(uint8_t zone_id, uint8_t brightness)
|
||||
{
|
||||
uint8_t data_pkt[8] = {
|
||||
RGB_FUSION2_AORUS_MASTER_REG_MODE,
|
||||
RGB_FUSION2_AORUS_MASTER_MODE_STATIC,
|
||||
0x06,
|
||||
brightness,
|
||||
0x08,
|
||||
zone_id,
|
||||
0x00,
|
||||
0x00
|
||||
};
|
||||
|
||||
bus->i2c_write_block(dev, sizeof(data_pkt), data_pkt);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Send color to a register (controls 2 LEDs) |
|
||||
| Format: <reg> <mode> R1 G1 B1 R2 G2 B2 |
|
||||
| Byte 0: Register (0xB0-0xBC) |
|
||||
| Byte 1: Mode byte (0x01 for fans, 0x00 for logo) |
|
||||
| Byte 2-4: First LED RGB |
|
||||
| Byte 5-7: Second LED RGB |
|
||||
\*---------------------------------------------------------*/
|
||||
void RGBFusion2AorusMasterGPUController::SendColorRegister(uint8_t reg, uint8_t mode_byte, RGBColor color1, RGBColor color2)
|
||||
{
|
||||
uint8_t data_pkt[8] = {
|
||||
reg,
|
||||
mode_byte,
|
||||
(uint8_t)RGBGetRValue(color1),
|
||||
(uint8_t)RGBGetGValue(color1),
|
||||
(uint8_t)RGBGetBValue(color1),
|
||||
(uint8_t)RGBGetRValue(color2),
|
||||
(uint8_t)RGBGetGValue(color2),
|
||||
(uint8_t)RGBGetBValue(color2)
|
||||
};
|
||||
|
||||
bus->i2c_write_block(dev, sizeof(data_pkt), data_pkt);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set colors for a fan zone (8 LEDs = 4 registers) |
|
||||
| Must send mode command before color commands |
|
||||
| |
|
||||
| fan_index: 0=left, 1=middle, 2=right |
|
||||
| colors: Array of 8 RGB colors for the 8 LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
void RGBFusion2AorusMasterGPUController::SetFanColors(uint8_t fan_index, RGBColor colors[8], uint8_t brightness)
|
||||
{
|
||||
uint8_t zone_id;
|
||||
uint8_t base_reg;
|
||||
|
||||
switch(fan_index)
|
||||
{
|
||||
case 0:
|
||||
zone_id = RGB_FUSION2_AORUS_MASTER_ZONE_LEFT;
|
||||
base_reg = RGB_FUSION2_AORUS_MASTER_REG_LEFT_FAN;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
zone_id = RGB_FUSION2_AORUS_MASTER_ZONE_MIDDLE;
|
||||
base_reg = RGB_FUSION2_AORUS_MASTER_REG_MIDDLE_FAN;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
zone_id = RGB_FUSION2_AORUS_MASTER_ZONE_RIGHT;
|
||||
base_reg = RGB_FUSION2_AORUS_MASTER_REG_RIGHT_FAN;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_ERROR("[%s] Invalid fan index: %d", name.c_str(), fan_index);
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| CRITICAL: Send mode command with zone ID first |
|
||||
| Without this, color commands have no effect |
|
||||
\*---------------------------------------------------------*/
|
||||
SendModeCommand(zone_id, brightness);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Delay after mode command - firmware needs time to process |
|
||||
| the zone selection before accepting color data |
|
||||
\*---------------------------------------------------------*/
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Send 4 color registers (2 LEDs each) |
|
||||
| Register Bx+0: LEDs 0,1 (colors[0], colors[1]) |
|
||||
| Register Bx+1: LEDs 2,3 (colors[2], colors[3]) |
|
||||
| Register Bx+2: LEDs 4,5 (colors[4], colors[5]) |
|
||||
| Register Bx+3: LEDs 6,7 (colors[6], colors[7]) |
|
||||
\*---------------------------------------------------------*/
|
||||
for(int reg_offset = 0; reg_offset < 4; reg_offset++)
|
||||
{
|
||||
uint8_t reg = base_reg + reg_offset;
|
||||
int color_idx = reg_offset * 2;
|
||||
|
||||
SendColorRegister(reg, 0x01, colors[color_idx], colors[color_idx + 1]);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Apply after each zone - required for multi-zone update |
|
||||
\*---------------------------------------------------------*/
|
||||
ApplyChanges();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set logo color |
|
||||
| Format: BC 00 R G B 00 00 00 |
|
||||
| Note: Logo uses mode byte 0x00, not 0x01 |
|
||||
\*---------------------------------------------------------*/
|
||||
void RGBFusion2AorusMasterGPUController::SetLogoColor(RGBColor color)
|
||||
{
|
||||
uint8_t data_pkt[8] = {
|
||||
RGB_FUSION2_AORUS_MASTER_REG_LOGO,
|
||||
0x00,
|
||||
(uint8_t)RGBGetRValue(color),
|
||||
(uint8_t)RGBGetGValue(color),
|
||||
(uint8_t)RGBGetBValue(color),
|
||||
0x00,
|
||||
0x00,
|
||||
0x00
|
||||
};
|
||||
|
||||
bus->i2c_write_block(dev, sizeof(data_pkt), data_pkt);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Apply all pending changes |
|
||||
| Format: AA 00 00 00 00 00 00 00 |
|
||||
\*---------------------------------------------------------*/
|
||||
void RGBFusion2AorusMasterGPUController::ApplyChanges()
|
||||
{
|
||||
uint8_t data_pkt[8] = {
|
||||
RGB_FUSION2_AORUS_MASTER_REG_APPLY,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00
|
||||
};
|
||||
|
||||
bus->i2c_write_block(dev, sizeof(data_pkt), data_pkt);
|
||||
}
|
||||
-97
@@ -1,97 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| GigabyteRGBFusion2AorusMasterGPUController.h |
|
||||
| |
|
||||
| Driver for Gigabyte AORUS MASTER GPU with fan ring LEDs |
|
||||
| |
|
||||
| Protocol reverse engineered from GCC on Windows |
|
||||
| Fan LEDs only illuminate when fans are spinning |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
#include "RGBController.h"
|
||||
|
||||
typedef unsigned char rgb_fusion_dev_id;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Fan zone configuration |
|
||||
| Each fan has 8 LEDs controlled by 4 registers |
|
||||
| Each register controls 2 LEDs with dual RGB values |
|
||||
\*---------------------------------------------------------*/
|
||||
struct aorus_master_zone_colors
|
||||
{
|
||||
RGBColor led_colors[8]; // 8 LEDs per fan (or 1 for logo)
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Register definitions |
|
||||
\*---------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
RGB_FUSION2_AORUS_MASTER_REG_MODE = 0x88,
|
||||
RGB_FUSION2_AORUS_MASTER_REG_APPLY = 0xAA,
|
||||
RGB_FUSION2_AORUS_MASTER_REG_LEFT_FAN = 0xB0, // B0-B3
|
||||
RGB_FUSION2_AORUS_MASTER_REG_MIDDLE_FAN = 0xB4, // B4-B7
|
||||
RGB_FUSION2_AORUS_MASTER_REG_RIGHT_FAN = 0xB8, // B8-BB
|
||||
RGB_FUSION2_AORUS_MASTER_REG_LOGO = 0xBC,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Fan zone ID values for mode command (byte 5) |
|
||||
\*---------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
RGB_FUSION2_AORUS_MASTER_ZONE_LEFT = 0x02, // IO side fan
|
||||
RGB_FUSION2_AORUS_MASTER_ZONE_MIDDLE = 0x05, // Center fan
|
||||
RGB_FUSION2_AORUS_MASTER_ZONE_RIGHT = 0x06, // Far side fan
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Mode definitions |
|
||||
\*---------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
RGB_FUSION2_AORUS_MASTER_MODE_STATIC = 0x01,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Speed and brightness |
|
||||
\*---------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
RGB_FUSION2_AORUS_MASTER_BRIGHTNESS_MIN = 0x00,
|
||||
RGB_FUSION2_AORUS_MASTER_BRIGHTNESS_MAX = 0x63, // 99
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Zone count: 3 fans x 8 LEDs + 1 logo = 25 zones |
|
||||
\*---------------------------------------------------------*/
|
||||
#define RGB_FUSION_2_AORUS_MASTER_FAN_LEDS 8
|
||||
#define RGB_FUSION_2_AORUS_MASTER_TOTAL_ZONES 25
|
||||
|
||||
class RGBFusion2AorusMasterGPUController
|
||||
{
|
||||
public:
|
||||
RGBFusion2AorusMasterGPUController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev, std::string dev_name);
|
||||
~RGBFusion2AorusMasterGPUController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetDeviceName();
|
||||
|
||||
void SetFanColors(uint8_t fan_index, RGBColor colors[8], uint8_t brightness);
|
||||
void SetLogoColor(RGBColor color);
|
||||
void ApplyChanges();
|
||||
|
||||
private:
|
||||
i2c_smbus_interface* bus;
|
||||
rgb_fusion_dev_id dev;
|
||||
std::string name;
|
||||
|
||||
void SendModeCommand(uint8_t zone_id, uint8_t brightness);
|
||||
void SendColorRegister(uint8_t reg, uint8_t mode_byte, RGBColor color1, RGBColor color2);
|
||||
};
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| GigabyteRGBFusion2AorusMasterGPUControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Gigabyte AORUS MASTER GPU |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "Detector.h"
|
||||
#include "GigabyteRGBFusion2AorusMasterGPUController.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include "LogManager.h"
|
||||
#include "pci_ids.h"
|
||||
#include "RGBController_GigabyteRGBFusion2AorusMasterGPU.h"
|
||||
|
||||
|
||||
#define GIGABYTEGPU_CONTROLLER_NAME_AORUS_MASTER "Gigabyte RGB Fusion2 AORUS MASTER GPU"
|
||||
|
||||
bool TestForGigabyteRGBFusion2AorusMasterGPUController(i2c_smbus_interface* bus, unsigned char address)
|
||||
{
|
||||
bool pass = false;
|
||||
int res, pktsz;
|
||||
const int read_sz = 4;
|
||||
const int write_sz = 8;
|
||||
uint8_t data_pkt[write_sz] = { 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t data_readpkt[read_sz] = {};
|
||||
|
||||
res = bus->i2c_write_block(address, write_sz, data_pkt);
|
||||
|
||||
if(res < 0)
|
||||
{
|
||||
LOG_DEBUG("[%s] Write probe failed at address 0x%02X", GIGABYTEGPU_CONTROLLER_NAME_AORUS_MASTER, address);
|
||||
return false;
|
||||
}
|
||||
|
||||
pktsz = read_sz;
|
||||
res = bus->i2c_read_block(address, &pktsz, data_readpkt);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| All RGB Fusion 2 responses start with 0xAB |
|
||||
| RTX 5080 AORUS MASTER response: 0xAB 0x10 0x52 0x0B |
|
||||
\*-----------------------------------------------------*/
|
||||
if(res >= 0 && data_readpkt[0] == 0xAB)
|
||||
{
|
||||
pass = true;
|
||||
LOG_DEBUG("[%s] Detected at address 0x%02X with response: 0x%02X 0x%02X 0x%02X 0x%02X",
|
||||
GIGABYTEGPU_CONTROLLER_NAME_AORUS_MASTER, address,
|
||||
data_readpkt[0], data_readpkt[1], data_readpkt[2], data_readpkt[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string text = "";
|
||||
for(int idx = 0; idx < read_sz; ++idx)
|
||||
{
|
||||
char str[6];
|
||||
snprintf(str, 6, " 0x%02X", data_readpkt[idx]);
|
||||
text.append(str);
|
||||
}
|
||||
LOG_DEBUG("[%s] at address 0x%02X invalid. Expected 0xAB [0x*] but received:%s",
|
||||
GIGABYTEGPU_CONTROLLER_NAME_AORUS_MASTER, address, text.c_str());
|
||||
}
|
||||
|
||||
return(pass);
|
||||
}
|
||||
|
||||
void DetectGigabyteRGBFusion2AorusMasterGPUControllers(i2c_smbus_interface* bus, uint8_t i2c_addr, const std::string& name)
|
||||
{
|
||||
if(TestForGigabyteRGBFusion2AorusMasterGPUController(bus, i2c_addr))
|
||||
{
|
||||
RGBFusion2AorusMasterGPUController* controller = new RGBFusion2AorusMasterGPUController(bus, i2c_addr, name);
|
||||
RGBController_RGBFusion2AorusMasterGPU* rgb_controller = new RGBController_RGBFusion2AorusMasterGPU(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Nvidia GPUs |
|
||||
\*---------------------------------------------------------*/
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 5080 MASTER", DetectGigabyteRGBFusion2AorusMasterGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX5080_MASTER_16G_SUB_DEV, 0x71);
|
||||
-180
@@ -1,180 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_GigabyteRGBFusion2AorusMasterGPU.cpp |
|
||||
| |
|
||||
| RGBController for Gigabyte AORUS MASTER GPU |
|
||||
| |
|
||||
| Each fan has 8 individually addressable LEDs |
|
||||
| Plus 1 logo LED = 25 total LEDs |
|
||||
| |
|
||||
| Note: Fan LEDs only illuminate when fans are spinning |
|
||||
| Use nvidia-settings to force fans on for testing |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_GigabyteRGBFusion2AorusMasterGPU.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Gigabyte AORUS MASTER GPU
|
||||
@category GPU
|
||||
@type I2C
|
||||
@save :white_check_mark:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectGigabyteRGBFusion2AorusMasterGPUControllers
|
||||
@comment Fan LEDs only work when fans are spinning. Each fan has 8
|
||||
individually addressable LEDs. Protocol uses zone-based
|
||||
mode commands before color commands.
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_RGBFusion2AorusMasterGPU::RGBController_RGBFusion2AorusMasterGPU(RGBFusion2AorusMasterGPUController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Gigabyte";
|
||||
description = "Gigabyte AORUS MASTER GPU with Fan Ring LEDs";
|
||||
location = controller->GetDeviceLocation();
|
||||
type = DEVICE_TYPE_GPU;
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = RGB_FUSION2_AORUS_MASTER_MODE_STATIC;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
Direct.brightness_min = RGB_FUSION2_AORUS_MASTER_BRIGHTNESS_MIN;
|
||||
Direct.brightness_max = RGB_FUSION2_AORUS_MASTER_BRIGHTNESS_MAX;
|
||||
Direct.brightness = RGB_FUSION2_AORUS_MASTER_BRIGHTNESS_MAX;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_RGBFusion2AorusMasterGPU::~RGBController_RGBFusion2AorusMasterGPU()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_RGBFusion2AorusMasterGPU::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Create 3 fan zones with 8 LEDs each (linear zones) |
|
||||
\*---------------------------------------------------------*/
|
||||
const char* fan_names[] = { "Left Fan", "Middle Fan", "Right Fan" };
|
||||
|
||||
for(int fan_idx = 0; fan_idx < 3; fan_idx++)
|
||||
{
|
||||
zone fan_zone;
|
||||
fan_zone.name = fan_names[fan_idx];
|
||||
fan_zone.type = ZONE_TYPE_LINEAR;
|
||||
fan_zone.leds_min = 8;
|
||||
fan_zone.leds_max = 8;
|
||||
fan_zone.leds_count = 8;
|
||||
fan_zone.matrix_map = NULL;
|
||||
|
||||
zones.push_back(fan_zone);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Create 8 LEDs for this fan zone |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int led_idx = 0; led_idx < 8; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = fan_names[fan_idx];
|
||||
new_led.name.append(" LED ");
|
||||
new_led.name.append(std::to_string(led_idx + 1));
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create logo zone with 1 LED |
|
||||
\*---------------------------------------------------------*/
|
||||
zone logo_zone;
|
||||
logo_zone.name = "Logo";
|
||||
logo_zone.type = ZONE_TYPE_SINGLE;
|
||||
logo_zone.leds_min = 1;
|
||||
logo_zone.leds_max = 1;
|
||||
logo_zone.leds_count = 1;
|
||||
logo_zone.matrix_map = NULL;
|
||||
|
||||
zones.push_back(logo_zone);
|
||||
|
||||
led logo_led;
|
||||
logo_led.name = "Logo";
|
||||
leds.push_back(logo_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_RGBFusion2AorusMasterGPU::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_RGBFusion2AorusMasterGPU::DeviceUpdateLEDs()
|
||||
{
|
||||
uint8_t brightness = modes[active_mode].brightness;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Update each fan zone |
|
||||
| LED indices: 0-7 (left), 8-15 (middle), 16-23 (right) |
|
||||
\*---------------------------------------------------------*/
|
||||
for(int fan_idx = 0; fan_idx < 3; fan_idx++)
|
||||
{
|
||||
RGBColor fan_colors[8];
|
||||
int base_led_idx = fan_idx * 8;
|
||||
|
||||
for(int led_idx = 0; led_idx < 8; led_idx++)
|
||||
{
|
||||
fan_colors[led_idx] = colors[base_led_idx + led_idx];
|
||||
}
|
||||
|
||||
controller->SetFanColors(fan_idx, fan_colors, brightness);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Update logo (LED index 24) |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->SetLogoColor(colors[24]);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Apply all changes |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->ApplyChanges();
|
||||
}
|
||||
|
||||
void RGBController_RGBFusion2AorusMasterGPU::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| For simplicity, update all LEDs when any zone changes |
|
||||
| The protocol requires sequential updates anyway |
|
||||
\*---------------------------------------------------------*/
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_RGBFusion2AorusMasterGPU::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| For simplicity, update all LEDs when any LED changes |
|
||||
| The protocol requires mode command + color sequence |
|
||||
\*---------------------------------------------------------*/
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_RGBFusion2AorusMasterGPU::DeviceUpdateMode()
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_RGBFusion2AorusMasterGPU::DeviceSaveMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Apply command also saves to device memory |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->ApplyChanges();
|
||||
}
|
||||
+26
-5
@@ -15,11 +15,12 @@
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
RGBFusion2BlackwellGPUController::RGBFusion2BlackwellGPUController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev, std::string dev_name)
|
||||
RGBFusion2BlackwellGPUController::RGBFusion2BlackwellGPUController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev, std::string dev_name, int gpu_layout)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
this->name = dev_name;
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
this->name = dev_name;
|
||||
this->gpu_layout = gpu_layout;
|
||||
}
|
||||
|
||||
RGBFusion2BlackwellGPUController::~RGBFusion2BlackwellGPUController()
|
||||
@@ -51,7 +52,7 @@ void RGBFusion2BlackwellGPUController::SaveConfig()
|
||||
void RGBFusion2BlackwellGPUController::SetMode(uint8_t type, uint8_t zone, uint8_t mode, fusion2_config zone_config)
|
||||
{
|
||||
if(zone_config.numberOfColors == 0 && zone < RGB_FUSION_2_BLACKWELL_GPU_NUMBER_OF_ZONES)
|
||||
this->zone_color[zone] = zone_config.colors[zone];
|
||||
this->zone_color[zone] = zone_config.colors[0];
|
||||
|
||||
/************************************************************************************\
|
||||
* *
|
||||
@@ -67,6 +68,16 @@ void RGBFusion2BlackwellGPUController::SetMode(uint8_t type, uint8_t zone, uint8
|
||||
if(zone_config.numberOfColors > 0)
|
||||
{
|
||||
int currentPos = 12;
|
||||
switch(gpu_layout)
|
||||
{
|
||||
case RGB_FUSION2_BLACKWELL_GPU_AORUS_MASTER_5080_LAYOUT:
|
||||
case RGB_FUSION2_BLACKWELL_GPU_AORUS_MASTER_5090D_V2_ICE_LAYOUT:
|
||||
currentPos = 11;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for(uint8_t i = 0; i < zone_config.numberOfColors; i++)
|
||||
{
|
||||
zone_pkt[currentPos + 0] = RGBGetRValue(zone_config.colors[i]);
|
||||
@@ -84,6 +95,16 @@ void RGBFusion2BlackwellGPUController::SetZone(uint8_t zone, uint8_t mode, fusio
|
||||
if(mode == RGB_FUSION2_BLACKWELL_GPU_MODE_BREATHING)
|
||||
zone_config.brightness = RGB_FUSION2_BLACKWELL_GPU_BRIGHTNESS_MAX;
|
||||
|
||||
switch(gpu_layout)
|
||||
{
|
||||
case RGB_FUSION2_BLACKWELL_GPU_AORUS_MASTER_5090D_V2_ICE_LAYOUT:
|
||||
if(mode == RGB_FUSION2_BLACKWELL_GPU_MODE_DIRECT)
|
||||
mode = RGB_FUSION2_BLACKWELL_GPU_MODE_STATIC;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t type = RGB_FUSION2_BLACKWELL_GPU_REG_COLOR;
|
||||
if(mode != RGB_FUSION2_BLACKWELL_GPU_MODE_DIRECT)
|
||||
type = RGB_FUSION2_BLACKWELL_GPU_REG_MODE;
|
||||
|
||||
+10
-5
@@ -44,6 +44,7 @@ enum
|
||||
RGB_FUSION2_BLACKWELL_GPU_MODE_COLOR_SHIFT = 0x08, // Not available to Eagle/Aero
|
||||
RGB_FUSION2_BLACKWELL_GPU_MODE_TRICOLOR = 0x09, // Available to Waterforce
|
||||
RGB_FUSION2_BLACKWELL_GPU_MODE_DAZZLE = 0x0A, // Not available to Eagle/Aero/Waterforce
|
||||
RGB_FUSION2_BLACKWELL_GPU_MODE_CLAWS = 0x0C, // Available to AORUS 5080 MASTER
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -61,16 +62,18 @@ enum
|
||||
|
||||
enum
|
||||
{
|
||||
RGB_FUSION2_BLACKWELL_GPU_SINGLE_ZONE = 0,
|
||||
RGB_FUSION2_BLACKWELL_GPU_GAMING_LAYOUT = 1,
|
||||
RGB_FUSION2_BLACKWELL_GPU_WATERFORCE_LAYOUT = 2,
|
||||
RGB_FUSION2_BLACKWELL_GPU_AORUS_WATERFORCE_LAYOUT = 3,
|
||||
RGB_FUSION2_BLACKWELL_GPU_SINGLE_ZONE = 0,
|
||||
RGB_FUSION2_BLACKWELL_GPU_GAMING_LAYOUT = 1,
|
||||
RGB_FUSION2_BLACKWELL_GPU_WATERFORCE_LAYOUT = 2,
|
||||
RGB_FUSION2_BLACKWELL_GPU_AORUS_WATERFORCE_LAYOUT = 3,
|
||||
RGB_FUSION2_BLACKWELL_GPU_AORUS_MASTER_5080_LAYOUT = 4,
|
||||
RGB_FUSION2_BLACKWELL_GPU_AORUS_MASTER_5090D_V2_ICE_LAYOUT = 5,
|
||||
};
|
||||
|
||||
class RGBFusion2BlackwellGPUController
|
||||
{
|
||||
public:
|
||||
RGBFusion2BlackwellGPUController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev, std::string dev_name);
|
||||
RGBFusion2BlackwellGPUController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev, std::string dev_name, int gpu_layout);
|
||||
~RGBFusion2BlackwellGPUController();
|
||||
|
||||
RGBColor zone_color[RGB_FUSION_2_BLACKWELL_GPU_NUMBER_OF_ZONES];
|
||||
@@ -87,4 +90,6 @@ private:
|
||||
i2c_smbus_interface* bus;
|
||||
rgb_fusion_dev_id dev;
|
||||
std::string name;
|
||||
int gpu_layout;
|
||||
|
||||
};
|
||||
|
||||
+59
-19
@@ -1,4 +1,4 @@
|
||||
/*---------------------------------------------------------*\
|
||||
/*---------------------------------------------------------*\
|
||||
| GigabyteRGBFusion2BlackwellGPUControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Gigabyte RGB Fusion 2 Blackwell GPU |
|
||||
@@ -52,6 +52,7 @@ bool TestForGigabyteRGBFusion2BlackwellGPUController(i2c_smbus_interface* bus, u
|
||||
//GeForce RTX 5070 Ti Eagle OC 16G 0x01 0x01 0x01 0x00
|
||||
//GeForce RTX 5070 Ti Gaming OC 16G 0x01 0x01 0x01 0x00
|
||||
//GeForce RTX 5070 Gaming OC 12G 0x01 0x01 0x01 0x00
|
||||
//GeForce RTX 5080 AORUS MASTER 16G 0x01 0x01 0x01 0x10
|
||||
|
||||
if(res < 0 || data_readpkt[0] != 0x01 || data_readpkt[1] != 0x01 || data_readpkt[2] != 0x01)
|
||||
{
|
||||
@@ -89,7 +90,7 @@ void DetectGigabyteRGBFusion2BlackwellGPUControllers(i2c_smbus_interface* bus, u
|
||||
// Check for RGB Fusion2 controller
|
||||
if(TestForGigabyteRGBFusion2BlackwellGPUController(bus, i2c_addr))
|
||||
{
|
||||
RGBFusion2BlackwellGPUController* controller = new RGBFusion2BlackwellGPUController(bus, i2c_addr, name);
|
||||
RGBFusion2BlackwellGPUController* controller = new RGBFusion2BlackwellGPUController(bus, i2c_addr, name, led_zones);
|
||||
RGBController_RGBFusion2BlackwellGPU* rgb_controller = new RGBController_RGBFusion2BlackwellGPU(controller, led_zones);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
@@ -163,27 +164,65 @@ void DetectGigabyteRGBFusion2BlackwellAorusWaterforceLayoutGPUControllers(i2c_sm
|
||||
DetectGigabyteRGBFusion2BlackwellGPUControllers(bus, i2c_addr, name, RGB_FUSION2_BLACKWELL_GPU_AORUS_WATERFORCE_LAYOUT);
|
||||
} /* DetectGigabyteRGBFusion2BlackwellAorusWaterforceLayoutGPUControllers() */
|
||||
|
||||
/*******************************************************************************************\
|
||||
* *
|
||||
* DetectGigabyteRGBFusion2BlackwellAorusMaster5080LayoutGPUControllers *
|
||||
* *
|
||||
* Detect GigabyteRGB Fusion2 controllers with AORUS waterforce layout on the *
|
||||
* enumerated I2C busses. *
|
||||
* *
|
||||
* bus - pointer to i2c_smbus_interface where RGB Fusion2 device is connected *
|
||||
* dev - I2C address of RGB Fusion2 device *
|
||||
* *
|
||||
\*******************************************************************************************/
|
||||
|
||||
void DetectGigabyteRGBFusion2BlackwellAorusMaster5080LayoutGPUControllers(i2c_smbus_interface* bus, uint8_t i2c_addr, const std::string& name)
|
||||
{
|
||||
DetectGigabyteRGBFusion2BlackwellGPUControllers(bus, i2c_addr, name, RGB_FUSION2_BLACKWELL_GPU_AORUS_MASTER_5080_LAYOUT);
|
||||
} /* DetectGigabyteRGBFusion2BlackwellAorusMaster5080LayoutGPUControllers() */
|
||||
|
||||
/*******************************************************************************************\
|
||||
* *
|
||||
* DetectGigabyteRGBFusion2BlackwellAorusMaster5090DV2IceLayoutGPUControllers *
|
||||
* *
|
||||
* Detect GigabyteRGB Fusion2 controllers with AORUS master 5090 D V2 ICE layout on *
|
||||
* enumerated I2C busses. *
|
||||
* *
|
||||
* bus - pointer to i2c_smbus_interface where RGB Fusion2 device is connected *
|
||||
* dev - I2C address of RGB Fusion2 device *
|
||||
* *
|
||||
\*******************************************************************************************/
|
||||
|
||||
void DetectGigabyteRGBFusion2BlackwellAorusMaster5090DV2IceLayoutGPUControllers(i2c_smbus_interface* bus, uint8_t i2c_addr, const std::string& name)
|
||||
{
|
||||
DetectGigabyteRGBFusion2BlackwellGPUControllers(bus, i2c_addr, name, RGB_FUSION2_BLACKWELL_GPU_AORUS_MASTER_5090D_V2_ICE_LAYOUT);
|
||||
} /* DetectGigabyteRGBFusion2BlackwellAorusMaster5090DV2IceLayoutGPUControllers() */
|
||||
|
||||
/*-----------------------------------------*\
|
||||
| Nvidia GPUs |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5060 Ti Gaming OC", DetectGigabyteRGBFusion2BlackwellSingleZoneGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5060TI_GAMING_OC_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5070 Aero OC", DetectGigabyteRGBFusion2BlackwellSingleZoneGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5070_AERO_OC_12G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5070 Eagle OC", DetectGigabyteRGBFusion2BlackwellSingleZoneGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5070_EAGLE_OC_12G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5070 Gaming OC", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5070_GAMING_OC_12G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5070 Ti Eagle OC", DetectGigabyteRGBFusion2BlackwellSingleZoneGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5070TI_EAGLE_OC_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5070 Ti Eagle OC ICE", DetectGigabyteRGBFusion2BlackwellSingleZoneGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5070TI_EAGLE_OC_ICE_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5070 Ti Aero OC", DetectGigabyteRGBFusion2BlackwellSingleZoneGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5070TI_AERO_OC_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5070 Ti Gaming OC", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5070TI_GAMING_OC_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5080 Aero OC", DetectGigabyteRGBFusion2BlackwellSingleZoneGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5080_AERO_OC_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5080 Gaming OC", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5080_GAMING_OC_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 5080 XTREME WATERFORCE", DetectGigabyteRGBFusion2BlackwellAorusWaterforceLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX5080_XTREME_WATERFORCE_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5080 XTREME WATERFORCE", DetectGigabyteRGBFusion2BlackwellWaterforceLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5080_XTREME_WATERFORCE_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5090 Gaming OC", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5090_GAMING_OC_32G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5090 XTREME WATERFORCE", DetectGigabyteRGBFusion2BlackwellWaterforceLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5090_XTREME_WATERFORCE_32G_SUB_DEV1, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5090 XTREME WATERFORCE", DetectGigabyteRGBFusion2BlackwellWaterforceLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5090_XTREME_WATERFORCE_32G_SUB_DEV2, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 5090 MASTER", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX5090_MASTER_32G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 5090 MASTER ICE", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX5090_MASTER_ICE_32G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5060 Ti Gaming OC", DetectGigabyteRGBFusion2BlackwellSingleZoneGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5060TI_GAMING_OC_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5070 Aero OC", DetectGigabyteRGBFusion2BlackwellSingleZoneGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5070_AERO_OC_12G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5070 Eagle OC", DetectGigabyteRGBFusion2BlackwellSingleZoneGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5070_EAGLE_OC_12G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5070 Eagle OC ICE", DetectGigabyteRGBFusion2BlackwellSingleZoneGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5070_EAGLE_OC_ICE_12G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5070 Gaming OC", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5070_GAMING_OC_12G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5070 Ti Eagle OC", DetectGigabyteRGBFusion2BlackwellSingleZoneGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5070TI_EAGLE_OC_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5070 Ti Eagle OC ICE", DetectGigabyteRGBFusion2BlackwellSingleZoneGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5070TI_EAGLE_OC_ICE_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5070 Ti Aero OC", DetectGigabyteRGBFusion2BlackwellSingleZoneGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5070TI_AERO_OC_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5070 Ti Gaming OC", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5070TI_GAMING_OC_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5080 Aero OC", DetectGigabyteRGBFusion2BlackwellSingleZoneGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5080_AERO_OC_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5080 Gaming OC", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5080_GAMING_OC_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 5080 MASTER", DetectGigabyteRGBFusion2BlackwellAorusMaster5080LayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX5080_MASTER_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 5080 XTREME WATERFORCE", DetectGigabyteRGBFusion2BlackwellAorusWaterforceLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX5080_XTREME_WATERFORCE_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5080 XTREME WATERFORCE", DetectGigabyteRGBFusion2BlackwellWaterforceLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5080_XTREME_WATERFORCE_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 5080 MASTER ICE", DetectGigabyteRGBFusion2BlackwellAorusMaster5080LayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX5080_MASTER_ICE_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5090 Gaming OC", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5090_GAMING_OC_32G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5090 XTREME WATERFORCE", DetectGigabyteRGBFusion2BlackwellWaterforceLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5090_XTREME_WATERFORCE_32G_SUB_DEV1, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5090 XTREME WATERFORCE", DetectGigabyteRGBFusion2BlackwellWaterforceLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5090_XTREME_WATERFORCE_32G_SUB_DEV2, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 5090 MASTER", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX5090_MASTER_32G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 5090 MASTER ICE", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX5090_MASTER_ICE_32G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 5090 D V2 MASTER ICE", DetectGigabyteRGBFusion2BlackwellAorusMaster5090DV2IceLayoutGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090D_V2_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX5090D_V2_MASTER_ICE_24G_SUB_DEV, 0x75);
|
||||
|
||||
/*-----------------------------------------*\
|
||||
| AMD GPUs |
|
||||
@@ -193,6 +232,7 @@ REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 9060 XT GAMING",
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 9060 XT GAMING OC", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, AMD_GPU_VEN, AMD_NAVI44_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX9060XT_GAMING_OC_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS Radeon RX 9070 XT Elite", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RX9070XT_ELITE_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 9070 XT GAMING OC", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX9070XT_GAMING_OC_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 9070 XT GAMING OC ICE", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX9070XT_GAMING_OC_ICE_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 9070 XT GAMING", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX9070XT_GAMING_16G_SUB_DEV, 0x75);
|
||||
|
||||
|
||||
|
||||
+1
@@ -10,3 +10,4 @@
|
||||
#pragma once
|
||||
|
||||
#define RGB_FUSION_2_BLACKWELL_GPU_NUMBER_OF_ZONES 6
|
||||
#define RGB_FUSION_2_BLACKWELL_AORUS_MASTER_FAN_LEDS 8
|
||||
|
||||
+187
-24
@@ -106,7 +106,7 @@ RGBController_RGBFusion2BlackwellGPU::RGBController_RGBFusion2BlackwellGPU(RGBFu
|
||||
SpectrumCycle.brightness = RGB_FUSION2_BLACKWELL_GPU_BRIGHTNESS_MAX;
|
||||
modes.push_back(SpectrumCycle);
|
||||
|
||||
if(led_layout == RGB_FUSION2_BLACKWELL_GPU_GAMING_LAYOUT || led_layout == RGB_FUSION2_BLACKWELL_GPU_WATERFORCE_LAYOUT || led_layout == RGB_FUSION2_BLACKWELL_GPU_AORUS_WATERFORCE_LAYOUT)
|
||||
if(led_layout != RGB_FUSION2_BLACKWELL_GPU_SINGLE_ZONE)
|
||||
{
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
@@ -150,26 +150,53 @@ RGBController_RGBFusion2BlackwellGPU::RGBController_RGBFusion2BlackwellGPU(RGBFu
|
||||
ColorShift.brightness = RGB_FUSION2_BLACKWELL_GPU_BRIGHTNESS_MAX;
|
||||
modes.push_back(ColorShift);
|
||||
|
||||
/* Disabled Dazzle as it seems to only execute once, would need to loop it maybe?
|
||||
* Not for Waterforce
|
||||
mode Dazzle;
|
||||
Dazzle.name = "Dazzle";
|
||||
Dazzle.value = RGB_FUSION2_BLACKWELL_GPU_MODE_DAZZLE;
|
||||
Dazzle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Dazzle.speed_min = RGB_FUSION2_BLACKWELL_GPU_SPEED_SLOWEST;
|
||||
Dazzle.speed_max = RGB_FUSION2_BLACKWELL_GPU_SPEED_FASTEST;
|
||||
Dazzle.speed = RGB_FUSION2_BLACKWELL_GPU_SPEED_NORMAL;
|
||||
Dazzle.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Dazzle.colors_min = 1;
|
||||
Dazzle.colors_max = 8;
|
||||
Dazzle.colors.resize(8);
|
||||
Dazzle.brightness_min = RGB_FUSION2_BLACKWELL_GPU_BRIGHTNESS_MIN;
|
||||
Dazzle.brightness_max = RGB_FUSION2_BLACKWELL_GPU_BRIGHTNESS_MAX;
|
||||
Dazzle.brightness = RGB_FUSION2_BLACKWELL_GPU_BRIGHTNESS_MAX;
|
||||
modes.push_back(Dazzle);*/
|
||||
if(led_layout != RGB_FUSION2_BLACKWELL_GPU_AORUS_WATERFORCE_LAYOUT)
|
||||
{
|
||||
mode Dazzle;
|
||||
Dazzle.name = "Dazzle";
|
||||
Dazzle.value = RGB_FUSION2_BLACKWELL_GPU_MODE_DAZZLE;
|
||||
Dazzle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Dazzle.speed_min = RGB_FUSION2_BLACKWELL_GPU_SPEED_SLOWEST;
|
||||
Dazzle.speed_max = RGB_FUSION2_BLACKWELL_GPU_SPEED_FASTEST;
|
||||
Dazzle.speed = RGB_FUSION2_BLACKWELL_GPU_SPEED_NORMAL;
|
||||
Dazzle.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Dazzle.colors_min = 1;
|
||||
Dazzle.colors_max = 8;
|
||||
Dazzle.colors.resize(8);
|
||||
Dazzle.brightness_min = RGB_FUSION2_BLACKWELL_GPU_BRIGHTNESS_MIN;
|
||||
Dazzle.brightness_max = RGB_FUSION2_BLACKWELL_GPU_BRIGHTNESS_MAX;
|
||||
Dazzle.brightness = RGB_FUSION2_BLACKWELL_GPU_BRIGHTNESS_MAX;
|
||||
modes.push_back(Dazzle);
|
||||
}
|
||||
}
|
||||
|
||||
SetupZones();
|
||||
if(led_layout == RGB_FUSION2_BLACKWELL_GPU_AORUS_MASTER_5080_LAYOUT)
|
||||
{
|
||||
mode Claws;
|
||||
Claws.name = "Claws";
|
||||
Claws.value = RGB_FUSION2_BLACKWELL_GPU_MODE_CLAWS;
|
||||
Claws.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Claws.speed_min = RGB_FUSION2_BLACKWELL_GPU_SPEED_SLOWEST;
|
||||
Claws.speed_max = RGB_FUSION2_BLACKWELL_GPU_SPEED_FASTEST;
|
||||
Claws.speed = RGB_FUSION2_BLACKWELL_GPU_SPEED_NORMAL;
|
||||
Claws.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Claws.brightness_min = RGB_FUSION2_BLACKWELL_GPU_BRIGHTNESS_MIN;
|
||||
Claws.brightness_max = RGB_FUSION2_BLACKWELL_GPU_BRIGHTNESS_MAX;
|
||||
Claws.brightness = RGB_FUSION2_BLACKWELL_GPU_BRIGHTNESS_MAX;
|
||||
modes.push_back(Claws);
|
||||
|
||||
for(size_t i = 0; i < modes.size(); i++)
|
||||
{
|
||||
if(modes[i].color_mode == MODE_COLORS_PER_LED)
|
||||
{
|
||||
modes[i].colors_min = 1;
|
||||
modes[i].colors_max = RGB_FUSION_2_BLACKWELL_AORUS_MASTER_FAN_LEDS;
|
||||
modes[i].colors.resize(RGB_FUSION_2_BLACKWELL_AORUS_MASTER_FAN_LEDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RGBController_RGBFusion2BlackwellGPU::SetupZones();
|
||||
}
|
||||
|
||||
RGBController_RGBFusion2BlackwellGPU::~RGBController_RGBFusion2BlackwellGPU()
|
||||
@@ -322,6 +349,102 @@ void RGBController_RGBFusion2BlackwellGPU::SetupZones()
|
||||
zones.push_back(new_zone);
|
||||
}
|
||||
}
|
||||
else if(gpu_layout == RGB_FUSION2_BLACKWELL_GPU_AORUS_MASTER_5080_LAYOUT)
|
||||
{
|
||||
const char * fan_names[] = { "Right Fan", "Left Fan", "Middle Fan" };
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
zone fan_zone;
|
||||
fan_zone.name = fan_names[i];
|
||||
fan_zone.type = ZONE_TYPE_LINEAR;
|
||||
fan_zone.leds_min = RGB_FUSION_2_BLACKWELL_AORUS_MASTER_FAN_LEDS;
|
||||
fan_zone.leds_max = RGB_FUSION_2_BLACKWELL_AORUS_MASTER_FAN_LEDS;
|
||||
fan_zone.leds_count = RGB_FUSION_2_BLACKWELL_AORUS_MASTER_FAN_LEDS;
|
||||
fan_zone.matrix_map = NULL;
|
||||
zones.push_back(fan_zone);
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < fan_zone.leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = fan_names[i];
|
||||
new_led.name.append(" LED ");
|
||||
new_led.name.append(std::to_string(led_idx + 1));
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
|
||||
zone side_logo;
|
||||
side_logo.name = "Side Logo";
|
||||
side_logo.type = ZONE_TYPE_SINGLE;
|
||||
side_logo.leds_min = 1;
|
||||
side_logo.leds_max = 1;
|
||||
side_logo.leds_count = 1;
|
||||
side_logo.matrix_map = NULL;
|
||||
zones.push_back(side_logo);
|
||||
|
||||
led logo_led;
|
||||
logo_led.name = "Side Logo";
|
||||
leds.push_back(logo_led);
|
||||
|
||||
zone top_logo;
|
||||
top_logo.name = "Top Logo";
|
||||
top_logo.type = ZONE_TYPE_SINGLE;
|
||||
top_logo.leds_min = 1;
|
||||
top_logo.leds_max = 1;
|
||||
top_logo.leds_count = 1;
|
||||
top_logo.matrix_map = NULL;
|
||||
zones.push_back(top_logo);
|
||||
|
||||
led top_led;
|
||||
top_led.name = "Top Logo";
|
||||
leds.push_back(top_led);
|
||||
}
|
||||
|
||||
else if(gpu_layout == RGB_FUSION2_BLACKWELL_GPU_AORUS_MASTER_5090D_V2_ICE_LAYOUT)
|
||||
{
|
||||
const char * fan_names[] = { "Right Fan", "Left Fan", "Middle Fan" };
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
zone fan_zone;
|
||||
fan_zone.name = fan_names[i];
|
||||
fan_zone.type = ZONE_TYPE_SINGLE;
|
||||
fan_zone.leds_min = 1;
|
||||
fan_zone.leds_max = 1;
|
||||
fan_zone.leds_count = 1;
|
||||
fan_zone.matrix_map = NULL;
|
||||
zones.push_back(fan_zone);
|
||||
|
||||
led new_led;
|
||||
new_led.name = fan_names[i];
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
zone backplate;
|
||||
backplate.name = "Backplate";
|
||||
backplate.type = ZONE_TYPE_SINGLE;
|
||||
backplate.leds_min = 1;
|
||||
backplate.leds_max = 1;
|
||||
backplate.leds_count = 1;
|
||||
backplate.matrix_map = NULL;
|
||||
zones.push_back(backplate);
|
||||
|
||||
led bp_led;
|
||||
bp_led.name = "Backplate";
|
||||
leds.push_back(bp_led);
|
||||
|
||||
zone side_logo;
|
||||
side_logo.name = "Side Logo";
|
||||
side_logo.type = ZONE_TYPE_SINGLE;
|
||||
side_logo.leds_min = 1;
|
||||
side_logo.leds_max = 1;
|
||||
side_logo.leds_count = 1;
|
||||
side_logo.matrix_map = NULL;
|
||||
zones.push_back(side_logo);
|
||||
|
||||
led sl_led;
|
||||
sl_led.name = "Side Logo";
|
||||
leds.push_back(sl_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
@@ -336,7 +459,6 @@ void RGBController_RGBFusion2BlackwellGPU::ResizeZone(int /*zone*/, int /*new_si
|
||||
void RGBController_RGBFusion2BlackwellGPU::DeviceUpdateLEDs()
|
||||
{
|
||||
fusion2_config zone_config;
|
||||
|
||||
zone_config.brightness = modes[active_mode].brightness;
|
||||
zone_config.speed = modes[active_mode].speed;
|
||||
zone_config.direction = modes[active_mode].direction;
|
||||
@@ -366,6 +488,14 @@ void RGBController_RGBFusion2BlackwellGPU::DeviceUpdateLEDs()
|
||||
gpu_zones = 5; // Hardware zones 0-4, but zone 0 is skipped
|
||||
break;
|
||||
|
||||
case RGB_FUSION2_BLACKWELL_GPU_AORUS_MASTER_5080_LAYOUT:
|
||||
gpu_zones = 6; // Zones 4 and 5 refer to ui zone 4
|
||||
break;
|
||||
|
||||
case RGB_FUSION2_BLACKWELL_GPU_AORUS_MASTER_5090D_V2_ICE_LAYOUT:
|
||||
gpu_zones = 6;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_TRACE("[%s] Invalid GPU layout (%d) when updating LEDs.", name.c_str(), gpu_layout);
|
||||
return; // should not happen
|
||||
@@ -392,19 +522,52 @@ void RGBController_RGBFusion2BlackwellGPU::DeviceUpdateLEDs()
|
||||
}
|
||||
ui_zone_idx = zone_idx - 1; // Map: HW zone 1->UI zone 0, HW zone 2->UI zone 1, HW zone 3->UI zone 2, HW zone 4->UI zone 3
|
||||
}
|
||||
else if(gpu_layout == RGB_FUSION2_BLACKWELL_GPU_AORUS_MASTER_5080_LAYOUT ||
|
||||
gpu_layout == RGB_FUSION2_BLACKWELL_GPU_AORUS_MASTER_5090D_V2_ICE_LAYOUT)
|
||||
{
|
||||
if(zone_idx == 5)
|
||||
{
|
||||
ui_zone_idx = zone_idx - 1; // Map: HW zone 5->UI zone 4
|
||||
}
|
||||
}
|
||||
|
||||
if(ui_zone_idx >= zones.size())
|
||||
{
|
||||
zone_config.colors[hardware_zone_idx] = colors.back();
|
||||
zone_config.colors[0] = colors.back();
|
||||
}
|
||||
else
|
||||
{
|
||||
zone_config.colors[hardware_zone_idx] = colors[ui_zone_idx];
|
||||
/*---------------------------------------------------------*\
|
||||
| Equivalent of: |
|
||||
| zone_config.colors[0] = colors[ui_zone_idx]; |
|
||||
| when all zones have 1 led. |
|
||||
\*---------------------------------------------------------*/
|
||||
uint8_t led_start = 0;
|
||||
for(uint8_t i = 0; i < ui_zone_idx; i++)
|
||||
{
|
||||
led_start += zones[i].leds_count;
|
||||
}
|
||||
for(unsigned int i = 0; i < zones[ui_zone_idx].leds_count; i++)
|
||||
{
|
||||
zone_config.colors[i] = colors[led_start + i];
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| If not all led are the same color, then we must pass all |
|
||||
| led colors in the i2c write. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(!std::all_of(zone_config.colors, zone_config.colors + zones[ui_zone_idx].leds_count, [first = zone_config.colors[0]](RGBColor x) { return x == first; }))
|
||||
{
|
||||
zone_config.numberOfColors = zones[ui_zone_idx].leds_count;
|
||||
}
|
||||
}
|
||||
|
||||
for(uint8_t i = 0; i < zone_config.numberOfColors; i++) // specific for MODE_COLORS_MODE_SPECIFIC
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
zone_config.colors[i] = modes[active_mode].colors[i];
|
||||
for(uint8_t i = 0; i < zone_config.numberOfColors; i++) // specific for MODE_COLORS_MODE_SPECIFIC
|
||||
{
|
||||
zone_config.colors[i] = modes[active_mode].colors[i];
|
||||
}
|
||||
}
|
||||
|
||||
controller->SetZone(hardware_zone_idx, modes[active_mode].value, zone_config);
|
||||
|
||||
@@ -152,6 +152,7 @@ REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 3090 XTREME WATERFORCE",
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 3090 XTREME WATERFORCE WB", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX3090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX3090_XTREME_WATERFORCE_WB_SUB_DEV, 0x64);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4070 GAMING OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070_GAMING_OC_12G, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4070 GAMING OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070_GAMING_OC_12G_V2, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4070 GAMING OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_AD103_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070_GAMING_OC_12G_V2, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Geforce RTX 4070 Aero OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070_AERO_OC_12G_SUB_DEV, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4070 SUPER GAMING OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070S_GAMING_OC_12G, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4070 SUPER Aero OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070S_AERO_OC_12G, 0x71);
|
||||
@@ -188,13 +189,17 @@ REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 7600 GAMING OC 8G",
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 7600 GAMING OC 8G", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI33_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX7600_GAMING_OC_8G_SUB_DEV2, 0x55);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 7600 XT GAMING OC 16G", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI33_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX7600XT_GAMING_OC_16G_SUB_DEV, 0x55);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 6700 XT GAMING OC 12G", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI22_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX6700XT_GAMING_OC_12G_SUB_DEV, 0x62);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 6800 XT GAMING OC", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV1, GIGABYTE_SUB_VEN, GIGABYTE_RX6800XT_GAMING_OC_SUB_DEV, 0x62);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 6900 XT GAMING OC", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV1, GIGABYTE_SUB_VEN, GIGABYTE_RX6900XT_GAMING_OC_SUB_DEV, 0x62);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 7700 XT GAMING OC", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI32_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX7700XT_GAMING_OC_SUB_DEV, 0x62);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 7800 XT GAMING OC", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI32_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX7800XT_GAMING_OC_16G_SUB_DEV, 0x62);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 7900 GRE GAMING OC", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI31_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX7900GRE_GAMING_OC_16G_SUB_DEV, 0x62);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 7900 XT GAMING OC", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI31_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX7900XT_GAMING_OC_20G_SUB_DEV, 0x62);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 7900 XTX GAMING OC", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI31_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX7900XTX_GAMING_OC_24G_SUB_DEV, 0x62);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS Radeon RX 7900 XTX ELITE 24G", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI31_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RX7900XTX_ELITE_24G_SUB_DEV, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS RX 6750 XT ELITE 12G", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI22_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RX_6750_XT_ELITE_12G_SUB_DEV, 0x70);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS RX 6900 XT EXTREME WATERFORCE WB", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV2, GIGABYTE_SUB_VEN, GIGABYTE_RX6900XT_XTREME_WATERFORCE_WB_SUB_DEV, 0x70);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS Radeon RX 9070 XT Elite", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RX9070XT_ELITE_16G_SUB_DEV, 0x73);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 9070 XT GAMING OC", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX9070XT_GAMING_OC_16G_SUB_DEV, 0x73);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 9070 XT GAMING OC ICE", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX9070XT_GAMING_OC_ICE_16G_SUB_DEV, 0x73);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 9070 GAMING OC", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX9070_GAMING_OC_16G_SUB_DEV, 0x73);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,7 @@
|
||||
#include <map>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define GB_FUSION2_ZONES_MAX 8
|
||||
#define GB_FUSION2_ZONES_MAX 12
|
||||
|
||||
/*--------------------------------------------------------*\
|
||||
| Base LED mappings found on all controllers. |
|
||||
@@ -89,6 +89,23 @@ const FwdLedHeaders LedLookup =
|
||||
\*-------------------------------------------------*/
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------*\
|
||||
| The layout_id masks for supported effects. |
|
||||
\*--------------------------------------------------------*/
|
||||
enum GB_LID_EFFECTS_MASKS : uint32_t
|
||||
{
|
||||
GB_EFF_BREATH = 0x001,
|
||||
GB_EFF_BEAT = 0x002,
|
||||
GB_EFF_CYCLE = 0x004,
|
||||
GB_EFF_FLASH = 0x008,
|
||||
GB_EFF_RANDOM = 0x010,
|
||||
GB_EFF_WAVE = 0x020,
|
||||
GB_EFF_DFLASH = 0x040,
|
||||
GB_EFF_WAVE1 = 0x080,
|
||||
GB_EFF_WAVE2 = 0x100,
|
||||
GB_EFF_CORE_MASK = 0x1FF
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GB_FUSION2_LED_IDX idx;
|
||||
|
||||
@@ -95,10 +95,9 @@ bool RGBFusion2USBController::RefreshHardwareInfo()
|
||||
return false;
|
||||
}
|
||||
|
||||
IT8297Report report;
|
||||
std::memcpy(&report, buffer, sizeof(IT8297Report));
|
||||
report_loaded = true;
|
||||
|
||||
device_num = report.device_num;
|
||||
description = std::string(report.str_product, 28);
|
||||
if(std::string::iterator nul = std::find(description.begin(), description.end(), '\0');
|
||||
nul != description.end())
|
||||
@@ -318,7 +317,7 @@ bool RGBFusion2USBController::SetCalibration(const EncodedCalibration& cal, bool
|
||||
cal_data.mainboard = desired.c.rgb_cali;
|
||||
cal_data.spare[0] = desired.c.c_spare0;
|
||||
cal_data.spare[1] = desired.c.c_spare1;
|
||||
|
||||
|
||||
if(product_id == 0x5711)
|
||||
{
|
||||
cal_data.dled[2] = desired.c.d_strip_c2;
|
||||
@@ -362,7 +361,6 @@ void RGBFusion2USBController::SetLedCount(unsigned int c0, unsigned int c1, unsi
|
||||
\*---------------------------------------------------------*/
|
||||
bool RGBFusion2USBController::SetStripBuiltinEffectState(int hdr, bool enable)
|
||||
{
|
||||
static bool first_call = true;
|
||||
int bitmask = 0;
|
||||
|
||||
if(hdr == -1)
|
||||
@@ -392,16 +390,16 @@ bool RGBFusion2USBController::SetStripBuiltinEffectState(int hdr, bool enable)
|
||||
}
|
||||
}
|
||||
|
||||
int new_effect_disabled = enable
|
||||
? (effect_disabled & ~bitmask)
|
||||
: (effect_disabled | bitmask);
|
||||
int base_mask = (effect_disabled < 0) ? 0 : effect_disabled;
|
||||
int new_effect_disabled = enable
|
||||
? (base_mask & ~bitmask)
|
||||
: (base_mask | bitmask);
|
||||
|
||||
if(!first_call && new_effect_disabled == effect_disabled)
|
||||
// Skip redundant writes only after we have synchronized at least once
|
||||
if(effect_disabled >= 0 && new_effect_disabled == effect_disabled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
first_call = false;
|
||||
effect_disabled = new_effect_disabled;
|
||||
int res = SendCCReport(0x32, effect_disabled);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
@@ -439,7 +437,7 @@ bool RGBFusion2USBController::EnableLampArray(bool enable)
|
||||
{
|
||||
return SendCCReport(0x48, enable ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
std::string RGBFusion2USBController::GetDeviceName()
|
||||
{
|
||||
return(name);
|
||||
@@ -703,3 +701,115 @@ void RGBFusion2USBController::ResetController()
|
||||
}
|
||||
ApplyEffect(true);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Check controller for gen2 ARGB support |
|
||||
| Checks for supported device number |
|
||||
| Then checks for supported controllers |
|
||||
| Then checks for supported feature bit (SaveLEDState) |
|
||||
| Finally checks for strip detection value. |
|
||||
\*---------------------------------------------------------*/
|
||||
bool RGBFusion2USBController::SupportsGen2() const
|
||||
{
|
||||
bool supports_gen2 = false;
|
||||
|
||||
supports_gen2 = (device_num == 0x00)
|
||||
&& (product_id == 0x5702 || product_id==0x5711 || product_id==0x8950)
|
||||
&& (report.support_cmd_flag & 0x01)
|
||||
&& (report.strip_detect == 0x01);
|
||||
|
||||
return supports_gen2;
|
||||
}
|
||||
|
||||
std::vector<Gen2StripInfo> RGBFusion2USBController::ExportGen2Strips() const
|
||||
{
|
||||
size_t count = (product_id == 0x5711) ? 4u : 2u;
|
||||
std::vector<Gen2StripInfo> out;
|
||||
out.reserve(count);
|
||||
for(size_t i = 0; i < count; ++i)
|
||||
{
|
||||
out.push_back(g2_strip_info[i]);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Scan Headers for Gen2 Devices |
|
||||
\*---------------------------------------------------------*/
|
||||
bool RGBFusion2USBController::ScanGen2Strips()
|
||||
{
|
||||
for(unsigned i = 0; i < 4; ++i)
|
||||
{
|
||||
if(g2_strip_info[i].LedsOfStrip.capacity() < 15)
|
||||
{
|
||||
g2_strip_info[i].LedsOfStrip.reserve(15);
|
||||
}
|
||||
g2_strip_info[i].numStrip = 0;
|
||||
g2_strip_info[i].totalLeds = 0;
|
||||
g2_strip_info[i].LedsOfStrip.resize(0);
|
||||
}
|
||||
|
||||
const unsigned int hdr_lim = (product_id == 0x5711) ? 4u : 2u;
|
||||
|
||||
for(unsigned int slot = 0; slot < hdr_lim; ++slot)
|
||||
{
|
||||
static constexpr uint8_t delta[4] = {4, 5, 0, 1};
|
||||
uint8_t scan_cmd = static_cast<uint8_t>(GEN2_LED_BASE_SCAN + delta[slot]);
|
||||
uint8_t info_cmd = static_cast<uint8_t>(scan_cmd + 2);
|
||||
|
||||
if(!SendCCReport(scan_cmd, 0x00, 0x00))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(700));
|
||||
|
||||
if(!SendCCReport(info_cmd, 0x00, 0x00))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char feature_buf[64] = {0};
|
||||
feature_buf[0] = report_id;
|
||||
int recv_len = hid_get_feature_report(dev, feature_buf, sizeof(feature_buf));
|
||||
if(recv_len < 64)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int seg_count = static_cast<int>(feature_buf[1]);
|
||||
if(seg_count < 0)
|
||||
{
|
||||
seg_count = 0;
|
||||
}
|
||||
if(seg_count > 15)
|
||||
{
|
||||
seg_count = 15;
|
||||
}
|
||||
Gen2StripInfo& dst = g2_strip_info[slot];
|
||||
dst.numStrip = static_cast<uint8_t>(seg_count);
|
||||
dst.LedsOfStrip.resize(static_cast<size_t>(seg_count));
|
||||
|
||||
uint32_t total_leds = 0;
|
||||
const int counts_base = 2;
|
||||
|
||||
for(int k = 0; k < seg_count; ++k)
|
||||
{
|
||||
const int off = counts_base + (k * 2);
|
||||
uint16_t lo = static_cast<uint16_t>(feature_buf[off + 0]);
|
||||
uint16_t hi = static_cast<uint16_t>(feature_buf[off + 1]);
|
||||
uint16_t cnt = static_cast<uint16_t>(lo | (hi << 8));
|
||||
|
||||
dst.LedsOfStrip[static_cast<size_t>(k)] = cnt;
|
||||
total_leds += cnt;
|
||||
}
|
||||
|
||||
dst.totalLeds = total_leds;
|
||||
|
||||
SetLedCount(0, 0, 0, 0);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
SaveLEDState(false);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
|
||||
#define FUSION2_USB_BUFFER_SIZE 64
|
||||
|
||||
/*--------------------------------------------------------*\
|
||||
| Gen2 scan/info opcode base |
|
||||
\*--------------------------------------------------------*/
|
||||
#define GEN2_LED_BASE_SCAN 0x38
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Effects mode list |
|
||||
\*---------------------------------------------------------*/
|
||||
@@ -83,6 +88,16 @@ struct EncodedCalibration
|
||||
std::string mainboard;
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| High level struct to contain Gen2 Header Data |
|
||||
\*---------------------------------------------------------*/
|
||||
struct Gen2StripInfo
|
||||
{
|
||||
uint8_t numStrip = 0;
|
||||
std::vector<uint16_t> LedsOfStrip;
|
||||
uint32_t totalLeds = 0;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
@@ -321,6 +336,8 @@ public:
|
||||
void SetLEDEffect(int led, int mode, unsigned int speed, unsigned char brightness, bool random, uint32_t* color);
|
||||
bool SetStripBuiltinEffectState(int hdr, bool enable);
|
||||
void SetStripColors(unsigned int hdr, RGBColor * colors, unsigned int num_colors, int single_led = -1);
|
||||
bool SupportsGen2() const;
|
||||
bool ScanGen2Strips();
|
||||
|
||||
EncodedCalibration GetCalibration(bool refresh_from_hw = false);
|
||||
std::string GetDeviceName();
|
||||
@@ -330,6 +347,8 @@ public:
|
||||
std::string GetFWVersion();
|
||||
uint16_t GetProductID();
|
||||
std::string GetSerial();
|
||||
std::vector<Gen2StripInfo> ExportGen2Strips() const;
|
||||
Gen2StripInfo g2_strip_info[4];
|
||||
|
||||
private:
|
||||
std::string DecodeCalibrationBuffer(uint32_t value) const;
|
||||
@@ -345,7 +364,7 @@ private:
|
||||
int SendPacket(unsigned char* packet);
|
||||
|
||||
hid_device* dev;
|
||||
int device_num;
|
||||
uint8_t device_num;
|
||||
uint16_t product_id;
|
||||
uint32_t effect_zone_mask = 0;
|
||||
int mode;
|
||||
@@ -356,7 +375,7 @@ private:
|
||||
std::string location;
|
||||
std::string version;
|
||||
std::string chip_id;
|
||||
int effect_disabled = 0;
|
||||
int effect_disabled = -1;
|
||||
int report_id = 0xCC;
|
||||
bool report_loaded = false;
|
||||
bool cali_loaded = false;
|
||||
|
||||
+197
-59
@@ -25,7 +25,7 @@
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectGigabyteRGBFusion2USBControllers
|
||||
@comment The Fusion 2 USB controller applies to most AMD and
|
||||
Intel mainboards from the x570 and z390 chipsets onwards.
|
||||
Intel mainboards from the X570 and z390 chipsets onwards.
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController* controller_ptr, std::string detector)
|
||||
@@ -39,8 +39,10 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
|
||||
version = controller->GetFWVersion();
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerial();
|
||||
product_id = controller->GetProductID();
|
||||
device_num = controller->GetDeviceNum();
|
||||
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFFFF;
|
||||
@@ -206,6 +208,13 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
|
||||
|
||||
RGBController_RGBFusion2USB::~RGBController_RGBFusion2USB()
|
||||
{
|
||||
// Free any zones we allocated for the per-instance layout
|
||||
for(gb_fusion2_zone* z : allocated_zones)
|
||||
{
|
||||
delete z;
|
||||
}
|
||||
allocated_zones.clear();
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
@@ -214,94 +223,125 @@ RGBController_RGBFusion2USB::~RGBController_RGBFusion2USB()
|
||||
\*---------------------------------------------------------*/
|
||||
void RGBController_RGBFusion2USB::Init_Controller()
|
||||
{
|
||||
const std::string SectionCustom = "CustomLayout";
|
||||
|
||||
const gb_fusion2_device* src_layout = gb_fusion2_device_list[device_index];
|
||||
const std::string SectionGen2 = "Gigabyte-Gen2-ARGB";
|
||||
const std::string SectionCustomBase = "CustomLayout";
|
||||
const std::string SectionCustom = SectionCustomBase + std::to_string(device_num);
|
||||
const std::string SectionCalibration = "Calibration";
|
||||
RvrseLedHeaders ReverseLedLookup = reverse_map(LedLookup);
|
||||
SettingsManager* settings_manager = ResourceManager::get()->GetSettingsManager();
|
||||
nlohmann::json device_settings = settings_manager->GetSettings(detector_name);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create the custom layout from the generic_device |
|
||||
| Checks for Gen2 support and adds flag to json. |
|
||||
\*---------------------------------------------------------*/
|
||||
gb_fusion2_device* layout = const_cast<gb_fusion2_device*>(gb_fusion2_device_list[device_index]);
|
||||
if(controller->SupportsGen2())
|
||||
{
|
||||
if(!device_settings.contains(SectionGen2))
|
||||
{
|
||||
device_settings[SectionGen2]["Enabled"] = false;
|
||||
settings_manager->SetSettings(detector_name, device_settings);
|
||||
settings_manager->SaveSettings();
|
||||
}
|
||||
|
||||
supports_gen2 = device_settings[SectionGen2]["Enabled"];
|
||||
|
||||
if(supports_gen2)
|
||||
{
|
||||
controller->ScanGen2Strips();
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create the custom layout from the generic layout |
|
||||
\*---------------------------------------------------------*/
|
||||
switch(product_id)
|
||||
{
|
||||
case 0x8950:
|
||||
src_layout = gb_fusion2_device_list[device_index + 1];
|
||||
break;
|
||||
case 0x5711:
|
||||
src_layout = gb_fusion2_device_list[device_index + 2];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(!device_settings.contains(SectionCustom))
|
||||
{
|
||||
device_settings[SectionCustom]["Enabled"] = false;
|
||||
device_settings[SectionCustom]["Data"] = BuildCustomLayoutJson(layout, ReverseLedLookup);
|
||||
device_settings[SectionCustom]["Data"] = BuildCustomLayoutJson(src_layout, ReverseLedLookup);
|
||||
settings_manager->SetSettings(detector_name, device_settings);
|
||||
settings_manager->SaveSettings();
|
||||
}
|
||||
|
||||
bool custom_layout = device_settings[SectionCustom]["Enabled"];
|
||||
|
||||
if(custom_layout)
|
||||
{
|
||||
LoadCustomLayoutFromJson(device_settings[SectionCustom]["Data"], LedLookup, layout);
|
||||
}
|
||||
|
||||
EncodedCalibration hw_cal = controller->GetCalibration(false);
|
||||
|
||||
if(!device_settings.contains(SectionCalibration))
|
||||
if(device_num == 0)
|
||||
{
|
||||
device_settings[SectionCalibration]["Enabled"] = false;
|
||||
device_settings[SectionCalibration]["Data"] = WriteCalJsonFrom(hw_cal);
|
||||
settings_manager->SetSettings(detector_name, device_settings);
|
||||
settings_manager->SaveSettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
nlohmann::json& cal_sec = device_settings[SectionCalibration];
|
||||
bool cal_enable = cal_sec.value("Enabled", false);
|
||||
|
||||
if(!cal_sec.contains("Data") || !cal_sec["Data"].is_object())
|
||||
if(!device_settings.contains(SectionCalibration))
|
||||
{
|
||||
cal_sec["Data"] = WriteCalJsonFrom(hw_cal);
|
||||
device_settings[SectionCalibration]["Enabled"] = false;
|
||||
device_settings[SectionCalibration]["Data"] = WriteCalJsonFrom(hw_cal);
|
||||
settings_manager->SetSettings(detector_name, device_settings);
|
||||
settings_manager->SaveSettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
nlohmann::json& cdata = cal_sec["Data"];
|
||||
FillMissingWith(cdata, hw_cal);
|
||||
nlohmann::json& cal_sec = device_settings[SectionCalibration];
|
||||
bool cal_enable = cal_sec.value("Enabled", false);
|
||||
|
||||
if(!cal_enable)
|
||||
if(!cal_sec.contains("Data") || !cal_sec["Data"].is_object())
|
||||
{
|
||||
cal_sec["Data"] = WriteCalJsonFrom(hw_cal);
|
||||
settings_manager->SetSettings(detector_name, device_settings);
|
||||
settings_manager->SaveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
if(cal_enable)
|
||||
{
|
||||
const nlohmann::json& cdata = cal_sec["Data"];
|
||||
|
||||
EncodedCalibration desired;
|
||||
desired.dled[0] = GET_JSON_VAL_ELSE_OFF(cdata, "HDR_D_LED1");
|
||||
desired.dled[1] = GET_JSON_VAL_ELSE_OFF(cdata, "HDR_D_LED2");
|
||||
desired.mainboard = GET_JSON_VAL_ELSE_OFF(cdata, "Mainboard");
|
||||
desired.spare[0] = GET_JSON_VAL_ELSE_OFF(cdata, "Spare0");
|
||||
desired.spare[1] = GET_JSON_VAL_ELSE_OFF(cdata, "Spare1");
|
||||
|
||||
if(controller->GetProductID() == 0x5711)
|
||||
{
|
||||
desired.dled[2] = GET_JSON_VAL_ELSE_OFF(cdata, "HDR_D_LED3");
|
||||
desired.dled[3] = GET_JSON_VAL_ELSE_OFF(cdata, "HDR_D_LED4");
|
||||
desired.spare[2] = GET_JSON_VAL_ELSE_OFF(cdata, "Spare2");
|
||||
desired.spare[3] = GET_JSON_VAL_ELSE_OFF(cdata, "Spare3");
|
||||
}
|
||||
else
|
||||
{
|
||||
desired.dled[2] = "OFF";
|
||||
desired.dled[3] = "OFF";
|
||||
desired.spare[2] = "OFF";
|
||||
desired.spare[3] = "OFF";
|
||||
nlohmann::json& cdata = cal_sec["Data"];
|
||||
FillMissingWith(cdata, hw_cal);
|
||||
|
||||
if(!cal_enable)
|
||||
{
|
||||
cal_sec["Data"] = WriteCalJsonFrom(hw_cal);
|
||||
settings_manager->SetSettings(detector_name, device_settings);
|
||||
settings_manager->SaveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
if(cal_enable)
|
||||
{
|
||||
const nlohmann::json& cdata = cal_sec["Data"];
|
||||
|
||||
EncodedCalibration desired;
|
||||
desired.dled[0] = GET_JSON_VAL_ELSE_OFF(cdata, "HDR_D_LED1");
|
||||
desired.dled[1] = GET_JSON_VAL_ELSE_OFF(cdata, "HDR_D_LED2");
|
||||
desired.mainboard = GET_JSON_VAL_ELSE_OFF(cdata, "Mainboard");
|
||||
desired.spare[0] = GET_JSON_VAL_ELSE_OFF(cdata, "Spare0");
|
||||
desired.spare[1] = GET_JSON_VAL_ELSE_OFF(cdata, "Spare1");
|
||||
|
||||
if(controller->GetProductID() == 0x5711)
|
||||
{
|
||||
desired.dled[2] = GET_JSON_VAL_ELSE_OFF(cdata, "HDR_D_LED3");
|
||||
desired.dled[3] = GET_JSON_VAL_ELSE_OFF(cdata, "HDR_D_LED4");
|
||||
desired.spare[2] = GET_JSON_VAL_ELSE_OFF(cdata, "Spare2");
|
||||
desired.spare[3] = GET_JSON_VAL_ELSE_OFF(cdata, "Spare3");
|
||||
}
|
||||
else
|
||||
{
|
||||
desired.dled[2] = "OFF";
|
||||
desired.dled[3] = "OFF";
|
||||
desired.spare[2] = "OFF";
|
||||
desired.spare[3] = "OFF";
|
||||
}
|
||||
controller->SetCalibration(desired, false);
|
||||
}
|
||||
controller->SetCalibration(desired, false);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*\
|
||||
| When no match found the first entry (generic_device) will be used |
|
||||
| otherwise look up channel map based on device name |
|
||||
@@ -315,35 +355,81 @@ void RGBController_RGBFusion2USB::Init_Controller()
|
||||
\*-----------------------------------------------------------------*/
|
||||
for(unsigned int i = 0; i < GB_FUSION2_DEVICE_COUNT; i++)
|
||||
{
|
||||
if(gb_fusion2_device_list[i]->name == name)
|
||||
if(gb_fusion2_device_list[i]->name == name &&
|
||||
gb_fusion2_device_list[i]->device_num == device_num)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set device ID |
|
||||
\*---------------------------------------------------------*/
|
||||
device_index = i;
|
||||
layout = const_cast<gb_fusion2_device*>(gb_fusion2_device_list[i]);
|
||||
src_layout = gb_fusion2_device_list[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------*\
|
||||
| Creates per instance copy of layouts. |
|
||||
\*---------------------------------------------------------------------*/
|
||||
instance_layout.zones = &instance_zones;
|
||||
instance_layout.layout_id = src_layout->layout_id;
|
||||
instance_layout.device_num = src_layout->device_num;
|
||||
instance_layout.name = src_layout->name;
|
||||
|
||||
for(uint8_t zi = 0; zi < GB_FUSION2_ZONES_MAX; ++zi)
|
||||
{
|
||||
(*instance_layout.zones)[zi] = (*src_layout->zones)[zi];
|
||||
}
|
||||
|
||||
if(custom_layout)
|
||||
{
|
||||
LoadCustomLayoutFromJson(device_settings[SectionCustom]["Data"], LedLookup, &instance_layout);
|
||||
}
|
||||
/*---------------------------------------------------------------------*\
|
||||
| Culls the mode support based on layout_id. |
|
||||
\*---------------------------------------------------------------------*/
|
||||
const uint32_t effect_mask = instance_layout.layout_id & GB_EFF_CORE_MASK;
|
||||
modes.erase(std::remove_if(modes.begin(), modes.end(),
|
||||
[effect_mask](const mode& m)
|
||||
{
|
||||
if(m.value == 0xFFFF /* Direct */) { return false; }
|
||||
if(m.value == EFFECT_STATIC) { return false; }
|
||||
|
||||
uint32_t bit = 0u;
|
||||
switch(m.value)
|
||||
{
|
||||
case EFFECT_PULSE: bit = GB_EFF_BREATH; break;
|
||||
case EFFECT_COLORCYCLE: bit = GB_EFF_CYCLE; break;
|
||||
case EFFECT_BLINKING: bit = GB_EFF_FLASH; break;
|
||||
case EFFECT_RANDOM: bit = GB_EFF_RANDOM; break;
|
||||
case EFFECT_WAVE: bit = GB_EFF_WAVE; break;
|
||||
case EFFECT_DFLASH: bit = GB_EFF_DFLASH; break;
|
||||
case EFFECT_WAVE1: bit = GB_EFF_WAVE1; break;
|
||||
case EFFECT_WAVE2: bit = GB_EFF_WAVE2; break;
|
||||
case EFFECT_WAVE3: bit = GB_EFF_WAVE1; break;
|
||||
case EFFECT_WAVE4: bit = GB_EFF_WAVE2; break;
|
||||
default: bit = 0u; break;
|
||||
}
|
||||
return (bit == 0u) || ((effect_mask & bit) == 0u);
|
||||
}),
|
||||
modes.end());
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Iterate through layout and process each zone |
|
||||
\*---------------------------------------------------------*/
|
||||
for(uint8_t zone_idx = 0; zone_idx < GB_FUSION2_ZONES_MAX; zone_idx++)
|
||||
{
|
||||
if(!layout->zones[0][zone_idx])
|
||||
if(!(*instance_layout.zones)[zone_idx])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const gb_fusion2_zone* zone_at_idx = layout->zones[0][zone_idx];
|
||||
const gb_fusion2_zone* zone_at_idx = (*instance_layout.zones)[zone_idx];
|
||||
|
||||
zone new_zone;
|
||||
new_zone.name = zone_at_idx->name;
|
||||
new_zone.leds_min = zone_at_idx->leds_min;
|
||||
new_zone.leds_max = zone_at_idx->leds_max;
|
||||
new_zone.leds_count = new_zone.leds_min;
|
||||
new_zone.type = (new_zone.leds_min == new_zone.leds_max) ? ZONE_TYPE_SINGLE : ZONE_TYPE_LINEAR;
|
||||
new_zone.type = ((new_zone.leds_min == 1) && (new_zone.leds_max == 1)) ? ZONE_TYPE_SINGLE : ZONE_TYPE_LINEAR;
|
||||
new_zone.matrix_map = NULL;
|
||||
zones.emplace_back(new_zone);
|
||||
}
|
||||
@@ -363,17 +449,68 @@ void RGBController_RGBFusion2USB::SetupZones()
|
||||
| Set up zones (Fixed so as to not spam the controller) |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
std::vector<Gen2StripInfo> strips = controller->ExportGen2Strips();
|
||||
|
||||
for(uint8_t zone_idx = 0; zone_idx < GB_FUSION2_ZONES_MAX; zone_idx++)
|
||||
{
|
||||
const gb_fusion2_zone* zone_at_idx = gb_fusion2_device_list[device_index]->zones[0][zone_idx];
|
||||
const gb_fusion2_zone* zone_at_idx = (*instance_layout.zones)[zone_idx];
|
||||
if(!zone_at_idx)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
bool single_zone = (zone_at_idx->leds_min == zone_at_idx->leds_max);
|
||||
bool single_zone = ((zone_at_idx->leds_min == 1) && (zone_at_idx->leds_max == 1));
|
||||
|
||||
if(!single_zone)
|
||||
{
|
||||
if(supports_gen2)
|
||||
{
|
||||
int slot = 0;
|
||||
switch(zone_at_idx->idx)
|
||||
{
|
||||
case LED4:
|
||||
case HDR_D_LED2:
|
||||
slot = 1;
|
||||
break;
|
||||
case HDR_D_LED3:
|
||||
slot = 2;
|
||||
break;
|
||||
case HDR_D_LED4:
|
||||
slot = 3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(slot >= 0 && static_cast<size_t>(slot) < strips.size())
|
||||
{
|
||||
const Gen2StripInfo& info = strips[static_cast<size_t>(slot)];
|
||||
if(info.totalLeds > 0u)
|
||||
{
|
||||
zones[zone_idx].leds_count = static_cast<unsigned int>(info.totalLeds);
|
||||
zones[zone_idx].leds_min = static_cast<unsigned int>(info.totalLeds);
|
||||
zones[zone_idx].leds_max = static_cast<unsigned int>(info.totalLeds);
|
||||
zones[zone_idx].segments.clear();
|
||||
|
||||
zones[zone_idx].segments.reserve(info.LedsOfStrip.size());
|
||||
unsigned int offset = 0;
|
||||
for(size_t si = 0; si < info.LedsOfStrip.size(); ++si)
|
||||
{
|
||||
const uint16_t cnt = info.LedsOfStrip[si];
|
||||
if(cnt == 0) continue;
|
||||
|
||||
segment seg;
|
||||
seg.name = std::string("Segment ") + std::to_string(si);
|
||||
seg.type = ZONE_TYPE_LINEAR;
|
||||
seg.start_idx = offset;
|
||||
seg.leds_count = static_cast<unsigned int>(cnt);
|
||||
|
||||
zones[zone_idx].segments.push_back(seg);
|
||||
offset += static_cast<unsigned int>(cnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(zone_at_idx->idx)
|
||||
{
|
||||
case LED4:
|
||||
@@ -826,6 +963,7 @@ void RGBController_RGBFusion2USB::LoadCustomLayoutFromJson(
|
||||
&& new_zone->idx <= GB_FUSION2_LED_IDX::LED11)
|
||||
{
|
||||
layout->zones[0][zone_idx] = new_zone;
|
||||
allocated_zones.push_back(new_zone);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -62,17 +62,26 @@ private:
|
||||
std::string detector_name;
|
||||
|
||||
RGBFusion2USBController* controller;
|
||||
int device_num;
|
||||
uint8_t device_num;
|
||||
RGBColor null_color = 0;
|
||||
bool supports_gen2 = 0;
|
||||
/*---------------------------------------------------------*\
|
||||
| The intial value of device_index should point to the |
|
||||
| layout for the generic_device |
|
||||
\*---------------------------------------------------------*/
|
||||
uint32_t device_index = 0;
|
||||
|
||||
uint16_t product_id = 0;
|
||||
uint32_t effects_mask = 0;
|
||||
void Init_Controller();
|
||||
int GetLED_Zone(int led_idx);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Per instance layout lookup tables. |
|
||||
\*---------------------------------------------------------*/
|
||||
gb_fusion2_device instance_layout{};
|
||||
gb_fusion2_layout instance_zones{};
|
||||
std::vector<gb_fusion2_zone*> allocated_zones;
|
||||
|
||||
nlohmann::json WriteCalJsonFrom(
|
||||
const EncodedCalibration& src);
|
||||
void FillMissingWith(
|
||||
|
||||
@@ -105,6 +105,7 @@ void DetectGigabyteRGBFusionGPUControllers(i2c_smbus_interface* bus, uint8_t i2c
|
||||
}
|
||||
} /* DetectGigabyteRGBFusionGPUControllers() */
|
||||
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GTX 1050 G1 Gaming", DetectGigabyteRGBFusionGPUControllers, NVIDIA_VEN, NVIDIA_GTX1050_DEV, GIGABYTE_SUB_VEN, GIGABYTE_GTX1050_G1_GAMING_SUB_DEV, 0x47);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce GTX 1050 Ti G1 Gaming Rev A1", DetectGigabyteRGBFusionGPUControllers, NVIDIA_VEN, NVIDIA_GTX1050TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_GTX1050TI_G1_GAMING_SUB_DEV, 0x47);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce GTX 1050 Ti G1 Gaming", DetectGigabyteRGBFusionGPUControllers, NVIDIA_VEN, NVIDIA_GTX1050TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_GTX1050TI_G1_GAMING_SUB_DEV, 0x48);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce GTX 1060 G1 Gaming", DetectGigabyteRGBFusionGPUControllers, NVIDIA_VEN, NVIDIA_GTX1060_DEV, GIGABYTE_SUB_VEN, GIGABYTE_GTX1060_G1_GAMING_SUB_DEV, 0x48);
|
||||
|
||||
@@ -16,10 +16,21 @@
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
static std::map<std::string, unsigned int> govee_led_counts
|
||||
struct GoveeHardwareInfo
|
||||
{
|
||||
{ "H619A", 20 },
|
||||
{ "H70B1", 20 },
|
||||
unsigned int led_count;
|
||||
unsigned int matrix_row_len; // 0 = linear
|
||||
};
|
||||
|
||||
const unsigned int GOVEE_FALLBACK_LED_COUNT = 20;
|
||||
|
||||
static std::map<std::string, GoveeHardwareInfo> govee_hardware_info
|
||||
{
|
||||
{ "H6022", { 132, 12 } }, // Govee Smart Table Lamp 2
|
||||
{ "H612F", { 12, 0 } }, // Govee Strip Light S (3m)
|
||||
{ "H619A", { 20, 0 } }, // Govee RGBIC Led Strip Lights
|
||||
{ "H70B1", { 20, 0 } }, // Govee LED Curtain Lights
|
||||
{ "H607C", { 174, 0 } }, // Govee Floor Lamp 2
|
||||
};
|
||||
|
||||
RGBController_Govee::RGBController_Govee(GoveeController* controller_ptr)
|
||||
@@ -67,39 +78,64 @@ RGBController_Govee::~RGBController_Govee()
|
||||
|
||||
void RGBController_Govee::SetupZones()
|
||||
{
|
||||
unsigned int led_count = 0;
|
||||
std::map<std::string, unsigned int>::iterator it = govee_led_counts.find(controller->GetSku());
|
||||
if(it != govee_led_counts.end())
|
||||
GoveeHardwareInfo hw = { GOVEE_FALLBACK_LED_COUNT, 0 };
|
||||
bool resizable = true;
|
||||
|
||||
std::map<std::string, GoveeHardwareInfo>::iterator it = govee_hardware_info.find(controller->GetSku());
|
||||
if(it != govee_hardware_info.end())
|
||||
{
|
||||
led_count = it->second;
|
||||
}
|
||||
/*-----------------------------------------------------*\
|
||||
| Fallback so Direct mode is usable even if SKU isn't |
|
||||
| in the table |
|
||||
\*-----------------------------------------------------*/
|
||||
if(led_count == 0)
|
||||
{
|
||||
led_count = 20; /* safe default; user can resize in UI */
|
||||
hw = it->second;
|
||||
resizable = false;
|
||||
}
|
||||
|
||||
zone strip;
|
||||
strip.name = "Govee Strip";
|
||||
strip.type = ZONE_TYPE_LINEAR;
|
||||
strip.leds_count = led_count;
|
||||
/*-----------------------------------------------------*\
|
||||
| Only make resizable for unknown SKUs |
|
||||
\*-----------------------------------------------------*/
|
||||
if(govee_led_counts.find(controller->GetSku()) == govee_led_counts.end())
|
||||
strip.leds_count = hw.led_count;
|
||||
strip.leds_min = resizable ? 0 : hw.led_count;
|
||||
strip.leds_max = resizable ? 255 : hw.led_count;
|
||||
|
||||
if(hw.matrix_row_len == 0)
|
||||
{
|
||||
strip.leds_min = 1;
|
||||
strip.leds_max = 255;
|
||||
strip.name = "Govee Strip";
|
||||
strip.type = ZONE_TYPE_LINEAR;
|
||||
strip.matrix_map = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
strip.leds_min = led_count;
|
||||
strip.leds_max = led_count;
|
||||
strip.name = "Govee Matrix";
|
||||
strip.type = ZONE_TYPE_MATRIX;
|
||||
|
||||
unsigned int width = hw.matrix_row_len;
|
||||
unsigned int height = hw.led_count / width;
|
||||
|
||||
strip.matrix_map = new matrix_map_type;
|
||||
strip.matrix_map->height = height;
|
||||
strip.matrix_map->width = width;
|
||||
strip.matrix_map->map = new unsigned int[hw.led_count];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| On H6022, LEDs indexed bottom to top, alternating |
|
||||
| clockwise and counterclockwise for each row. |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int y = 0; y < height; y++)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| LEDs numbered bottom to top, opposite of matrix |
|
||||
| clockwise and counterclockwise for each row. |
|
||||
\*-------------------------------------------------*/
|
||||
unsigned int led_y = (height - 1) - y;
|
||||
|
||||
for(unsigned int x = 0; x < width; x++)
|
||||
{
|
||||
/*---------------------------------------------*\
|
||||
| LED is right-to-left for even rows, including |
|
||||
| first one |
|
||||
\*---------------------------------------------*/
|
||||
unsigned int led_x = led_y & 1 ? x : (width - 1) - x;
|
||||
strip.matrix_map->map[y * width + x] = led_y * width + led_x;
|
||||
}
|
||||
}
|
||||
}
|
||||
strip.matrix_map = NULL;
|
||||
|
||||
zones.push_back(strip);
|
||||
|
||||
for(std::size_t led_idx = 0; led_idx < strip.leds_count; led_idx++)
|
||||
@@ -114,6 +150,11 @@ void RGBController_Govee::SetupZones()
|
||||
|
||||
void RGBController_Govee::ResizeZone(int zone, int new_size)
|
||||
{
|
||||
if(zones[zone].type == ZONE_TYPE_MATRIX)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(zone < 0 || zone >= (int)zones.size() || new_size <= 0)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -91,7 +91,7 @@ void RGBController_HPOmenLaptopWMI_Windows::SetupZones()
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_HPOmenLaptopWMI_Windows::ResizeZone(int zone, int new_size)
|
||||
void RGBController_HPOmenLaptopWMI_Windows::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Not Supported |
|
||||
@@ -106,7 +106,7 @@ void RGBController_HPOmenLaptopWMI_Windows::DeviceUpdateLEDs()
|
||||
controller->setColors(this->colors);
|
||||
}
|
||||
|
||||
void RGBController_HPOmenLaptopWMI_Windows::UpdateZoneLEDs(int zone)
|
||||
void RGBController_HPOmenLaptopWMI_Windows::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Set new colors |
|
||||
@@ -114,7 +114,7 @@ void RGBController_HPOmenLaptopWMI_Windows::UpdateZoneLEDs(int zone)
|
||||
controller->setColors(this->colors);
|
||||
}
|
||||
|
||||
void RGBController_HPOmenLaptopWMI_Windows::UpdateSingleLED(int led)
|
||||
void RGBController_HPOmenLaptopWMI_Windows::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Set new colors |
|
||||
|
||||
@@ -30,28 +30,9 @@ using namespace std::chrono_literals;
|
||||
|
||||
bool TestForHyperXDRAMController(i2c_smbus_interface* bus, unsigned char address)
|
||||
{
|
||||
bool pass = false;
|
||||
int res = bus->i2c_smbus_read_byte(address);
|
||||
|
||||
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
|
||||
|
||||
LOG_DEBUG("[%s] Writing at address %02X, res=%02X", HYPERX_CONTROLLER_NAME, address, res);
|
||||
|
||||
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);
|
||||
return(res >= 0);
|
||||
|
||||
} /* TestForHyperXDRAMController() */
|
||||
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ HyperXAlloyOrigins60and65Controller::HyperXAlloyOrigins60and65Controller(hid_dev
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
dev_name = name;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
HyperXAlloyOrigins60and65Controller::~HyperXAlloyOrigins60and65Controller()
|
||||
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperXEve1800Controller.cpp |
|
||||
| |
|
||||
| Driver for HyperX Eve 1800 keyboard |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "HyperXEve1800Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
HyperXEve1800Controller::HyperXEve1800Controller(hid_device* dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
HyperXEve1800Controller::~HyperXEve1800Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string HyperXEve1800Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string HyperXEve1800Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string HyperXEve1800Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void HyperXEve1800Controller::SetBrightness(unsigned int brightness)
|
||||
{
|
||||
unsigned char buf[65];
|
||||
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
buf[0x00] = 0x40;
|
||||
buf[0x01] = 0x01;
|
||||
buf[0x02] = 0x00;
|
||||
buf[0x03] = 0x00;
|
||||
buf[0x04] = brightness & 0xFF;
|
||||
|
||||
hid_write(dev, buf, 65);
|
||||
}
|
||||
|
||||
void HyperXEve1800Controller::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
{
|
||||
SendDirectInitialization();
|
||||
|
||||
if(colors.empty())
|
||||
{
|
||||
RGBColor temp = 0x00000000;
|
||||
SendDirectColorPacket(&temp, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendDirectColorPacket(&colors[0], (unsigned int)colors.size());
|
||||
}
|
||||
}
|
||||
|
||||
void HyperXEve1800Controller::SendDirectInitialization()
|
||||
{
|
||||
unsigned char buf[65];
|
||||
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
buf[0x00] = 0x44;
|
||||
buf[0x01] = 0x01;
|
||||
buf[0x02] = 0x04;
|
||||
buf[0x03] = 0x00;
|
||||
|
||||
hid_write(dev, buf, 65);
|
||||
}
|
||||
|
||||
void HyperXEve1800Controller::SendDirectColorPacket(RGBColor* color_data, unsigned int color_count)
|
||||
{
|
||||
unsigned char buf[65];
|
||||
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
buf[0x00] = 0x44;
|
||||
buf[0x01] = 0x02;
|
||||
buf[0x02] = 0x00;
|
||||
buf[0x03] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| The Eve 1800 exposes 10 lighting zones, but this |
|
||||
| report format can carry up to 20 RGB triplets. |
|
||||
\*-----------------------------------------------------*/
|
||||
if(color_count > 20)
|
||||
{
|
||||
color_count = 20;
|
||||
}
|
||||
|
||||
for(unsigned int color_idx = 0; color_idx < color_count; color_idx++)
|
||||
{
|
||||
buf[4 + (color_idx * 3)] = RGBGetRValue(color_data[color_idx]);
|
||||
buf[4 + (color_idx * 3) + 1] = RGBGetGValue(color_data[color_idx]);
|
||||
buf[4 + (color_idx * 3) + 2] = RGBGetBValue(color_data[color_idx]);
|
||||
}
|
||||
|
||||
hid_write(dev, buf, 65);
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperXEve1800Controller.h |
|
||||
| |
|
||||
| Driver for HyperX Eve 1800 keyboard |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
class HyperXEve1800Controller
|
||||
{
|
||||
public:
|
||||
HyperXEve1800Controller(hid_device* dev_handle, const char* path, std::string dev_name);
|
||||
~HyperXEve1800Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SetBrightness(unsigned int brightness);
|
||||
void SetLEDsDirect(std::vector<RGBColor> colors);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
|
||||
void SendDirectInitialization();
|
||||
void SendDirectColorPacket(RGBColor* color_data, unsigned int color_count);
|
||||
};
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_HyperXEve1800.cpp |
|
||||
| |
|
||||
| RGBController for HyperX Eve 1800 keyboard |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_HyperXEve1800.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
#define HYPERX_EVE_1800_BRIGHTNESS_MIN 0x00
|
||||
#define HYPERX_EVE_1800_BRIGHTNESS_MAX 0xFF
|
||||
#define HYPERX_EVE_1800_ZONE_COUNT 10
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name HyperX Eve 1800
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectHyperXEve1800
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_HyperXEve1800::RGBController_HyperXEve1800(HyperXEve1800Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "HyperX";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "HyperX Eve 1800 Keyboard Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFFFF;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Direct.brightness_min = HYPERX_EVE_1800_BRIGHTNESS_MIN;
|
||||
Direct.brightness_max = HYPERX_EVE_1800_BRIGHTNESS_MAX;
|
||||
Direct.brightness = HYPERX_EVE_1800_BRIGHTNESS_MAX;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
|
||||
keepalive_thread_run = 1;
|
||||
keepalive_thread = new std::thread(&RGBController_HyperXEve1800::KeepaliveThread, this);
|
||||
}
|
||||
|
||||
RGBController_HyperXEve1800::~RGBController_HyperXEve1800()
|
||||
{
|
||||
keepalive_thread_run = 0;
|
||||
keepalive_thread->join();
|
||||
delete keepalive_thread;
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_HyperXEve1800::SetupZones()
|
||||
{
|
||||
zone new_zone;
|
||||
new_zone.name = "Keyboard";
|
||||
new_zone.type = ZONE_TYPE_LINEAR;
|
||||
new_zone.leds_min = HYPERX_EVE_1800_ZONE_COUNT;
|
||||
new_zone.leds_max = HYPERX_EVE_1800_ZONE_COUNT;
|
||||
new_zone.leds_count = HYPERX_EVE_1800_ZONE_COUNT;
|
||||
new_zone.matrix_map = NULL;
|
||||
zones.push_back(new_zone);
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < zones[0].leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = "Zone ";
|
||||
new_led.name.append(std::to_string(led_idx + 1));
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_HyperXEve1800::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_HyperXEve1800::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetLEDsDirect(colors);
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
void RGBController_HyperXEve1800::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_HyperXEve1800::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_HyperXEve1800::DeviceUpdateMode()
|
||||
{
|
||||
controller->SetBrightness(modes[active_mode].brightness);
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_HyperXEve1800::KeepaliveThread()
|
||||
{
|
||||
while(keepalive_thread_run.load())
|
||||
{
|
||||
if(active_mode == 0)
|
||||
{
|
||||
if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(50))
|
||||
{
|
||||
UpdateLEDs();
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_HyperXEve1800.h |
|
||||
| |
|
||||
| RGBController for HyperX Eve 1800 keyboard |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include "RGBController.h"
|
||||
#include "HyperXEve1800Controller.h"
|
||||
|
||||
class RGBController_HyperXEve1800 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_HyperXEve1800(HyperXEve1800Controller* controller_ptr);
|
||||
~RGBController_HyperXEve1800();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
void KeepaliveThread();
|
||||
|
||||
private:
|
||||
HyperXEve1800Controller* controller;
|
||||
std::thread* keepalive_thread;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
|
||||
};
|
||||
@@ -15,12 +15,16 @@
|
||||
#include "HyperXAlloyOriginsController.h"
|
||||
#include "HyperXAlloyOriginsCoreController.h"
|
||||
#include "HyperXAlloyOrigins60and65Controller.h"
|
||||
#include "HyperXEve1800Controller.h"
|
||||
#include "HyperXOrigins2_65Controller.h"
|
||||
#include "RGBController_HyperXAlloyElite.h"
|
||||
#include "RGBController_HyperXAlloyElite2.h"
|
||||
#include "RGBController_HyperXAlloyFPS.h"
|
||||
#include "RGBController_HyperXAlloyOrigins.h"
|
||||
#include "RGBController_HyperXAlloyOriginsCore.h"
|
||||
#include "RGBController_HyperXAlloyOrigins60and65.h"
|
||||
#include "RGBController_HyperXEve1800.h"
|
||||
#include "RGBController_HyperXOrigins2_65.h"
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| HyperX keyboard vendor and product IDs |
|
||||
@@ -44,6 +48,8 @@
|
||||
#define HYPERX_ALLOY_ORIGINS_65_HP_PID 0x038F
|
||||
#define HYPERX_ALLOY_ORIGINS_CORE_HP_PID 0x098F
|
||||
#define HYPERX_ALLOY_ORIGINS_HP_PID 0x0591
|
||||
#define HYPERX_EVE_1800_HP_PID 0x08C2
|
||||
#define HYPERX_ORIGINS_2_65_HP_PID 0x0CC2
|
||||
|
||||
AlloyOrigins60and65MappingLayoutType GetAlloyOrigins60and65MappingLayoutType(int pid)
|
||||
{
|
||||
@@ -140,12 +146,41 @@ void DetectHyperXAlloyOrigins60and65(hid_device_info* info, const std::string& n
|
||||
}
|
||||
}
|
||||
|
||||
void DetectHyperXOrigins2_65(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXOrigins2_65Controller* controller = new HyperXOrigins2_65Controller(dev, info->path, name);
|
||||
RGBController_HyperXOrigins2_65* rgb_controller = new RGBController_HyperXOrigins2_65(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectHyperXEve1800(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXEve1800Controller* controller = new HyperXEve1800Controller(dev, info->path, name);
|
||||
RGBController_HyperXEve1800* rgb_controller = new RGBController_HyperXEve1800(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IP("HyperX Alloy Elite RGB", DetectHyperXAlloyElite, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ELITE_PID, 2, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_IP("HyperX Alloy FPS RGB", DetectHyperXAlloyFPS, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_FPS_RGB_PID, 2, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins Core", DetectHyperXAlloyOriginsCore, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_CORE_PID, 2);
|
||||
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins Core (HP)", DetectHyperXAlloyOriginsCore, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_CORE_HP_PID, 2);
|
||||
|
||||
REGISTER_HID_DETECTOR_I("HyperX Origins 2 65 (HP)", DetectHyperXOrigins2_65, HP_KEYBOARD_VID, HYPERX_ORIGINS_2_65_HP_PID, 3);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Eve 1800 (HP)", DetectHyperXEve1800, HP_KEYBOARD_VID, HYPERX_EVE_1800_HP_PID, 2);
|
||||
|
||||
#ifdef _WIN32
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins", DetectHyperXAlloyOrigins, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_PID, 3);
|
||||
REGISTER_HID_DETECTOR_IP("HyperX Alloy Elite 2", DetectHyperXAlloyElite2, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ELITE_2_PID, 3, 0xFF90);
|
||||
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperXOrigins2_65Controller.cpp |
|
||||
| |
|
||||
| Driver for HyperX Origins 2 65 keyboard |
|
||||
| |
|
||||
| Ricardo Amorim 28 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "HyperXOrigins2_65Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
HyperXOrigins2_65Controller::HyperXOrigins2_65Controller(hid_device* dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
HyperXOrigins2_65Controller::~HyperXOrigins2_65Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string HyperXOrigins2_65Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID " + location);
|
||||
}
|
||||
|
||||
std::string HyperXOrigins2_65Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string HyperXOrigins2_65Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return ("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void HyperXOrigins2_65Controller::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up variables to track progress of color transmit |
|
||||
| Do this after inserting blanks |
|
||||
\*-----------------------------------------------------*/
|
||||
int colors_to_send = (int)colors.size();
|
||||
int colors_sent = 0;
|
||||
|
||||
SendDirectInitialization();
|
||||
|
||||
for(int pkt_idx = 0; pkt_idx < 4; pkt_idx++)
|
||||
{
|
||||
if(colors_to_send > 20)
|
||||
{
|
||||
SendDirectColorPacket(&colors[colors_sent], 20, pkt_idx);
|
||||
colors_sent += 20;
|
||||
colors_to_send -= 20;
|
||||
}
|
||||
else if(colors_to_send > 0)
|
||||
{
|
||||
SendDirectColorPacket(&colors[colors_sent], colors_to_send, pkt_idx);
|
||||
colors_sent += colors_to_send;
|
||||
colors_to_send -= colors_to_send;
|
||||
}
|
||||
else
|
||||
{
|
||||
RGBColor temp = 0x00000000;
|
||||
SendDirectColorPacket(&temp, 1, pkt_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HyperXOrigins2_65Controller::SendDirectInitialization()
|
||||
{
|
||||
unsigned char buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Direct Initialization packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0x44;
|
||||
buf[0x01] = 0x01;
|
||||
buf[0x02] = 0x04;
|
||||
buf[0x03] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, buf, 65);
|
||||
}
|
||||
|
||||
void HyperXOrigins2_65Controller::SendDirectColorPacket
|
||||
(
|
||||
RGBColor* color_data,
|
||||
unsigned int color_count,
|
||||
unsigned int seq
|
||||
)
|
||||
{
|
||||
unsigned char buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Direct Initialization packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0x44;
|
||||
buf[0x01] = 0x02;
|
||||
buf[0x02] = (unsigned char)seq;
|
||||
buf[0x03] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| The maximum number of colors per packet is 20 |
|
||||
\*-----------------------------------------------------*/
|
||||
if(color_count > 20)
|
||||
{
|
||||
color_count = 20;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int color_idx = 0; color_idx < color_count; color_idx++)
|
||||
{
|
||||
buf[4 + (color_idx * 3)] = RGBGetRValue(color_data[color_idx]);
|
||||
buf[4 + (color_idx * 3) + 1] = RGBGetGValue(color_data[color_idx]);
|
||||
buf[4 + (color_idx * 3) + 2] = RGBGetBValue(color_data[color_idx]);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, buf, 65);
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperXOrigins2_65Controller.h |
|
||||
| |
|
||||
| Driver for HyperX Origins 2 65 keyboard |
|
||||
| |
|
||||
| Ricardo Amorim 28 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
class HyperXOrigins2_65Controller
|
||||
{
|
||||
public:
|
||||
HyperXOrigins2_65Controller(hid_device* dev_handle, const char* path, std::string dev_name);
|
||||
~HyperXOrigins2_65Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SetLEDsDirect(std::vector<RGBColor> colors);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
|
||||
void SendDirectInitialization();
|
||||
void SendDirectColorPacket
|
||||
(
|
||||
RGBColor* color_data,
|
||||
unsigned int color_count,
|
||||
unsigned int seq
|
||||
);
|
||||
};
|
||||
|
||||
+257
@@ -0,0 +1,257 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_HyperXOrigins2_65.cpp |
|
||||
| |
|
||||
| RGBController for HyperX Origins 2 65 keyboard |
|
||||
| |
|
||||
| Ricardo Amorim 28 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "RGBController_HyperXOrigins2_65.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
//0xFFFFFFFF indicates an unused entry in matrix
|
||||
#define NA 0xFFFFFFFF
|
||||
|
||||
static unsigned int matrix_map[5][15] =
|
||||
{ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 },
|
||||
{ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, NA, 29 },
|
||||
{ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44 },
|
||||
{ 45, 61, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 59 },
|
||||
{ 60, 62, 63, 65, NA, NA, 66, NA, NA, 68, 69, 70, 71, 72, 73 } };
|
||||
|
||||
static const char* zone_names[] =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
};
|
||||
|
||||
static zone_type zone_types[] =
|
||||
{
|
||||
ZONE_TYPE_MATRIX,
|
||||
};
|
||||
|
||||
static const unsigned int zone_sizes[] =
|
||||
{
|
||||
74,
|
||||
};
|
||||
|
||||
static const char *led_names[] =
|
||||
{
|
||||
KEY_EN_ESCAPE,
|
||||
KEY_EN_1,
|
||||
KEY_EN_2,
|
||||
KEY_EN_3,
|
||||
KEY_EN_4,
|
||||
KEY_EN_5,
|
||||
KEY_EN_6,
|
||||
KEY_EN_7,
|
||||
KEY_EN_8,
|
||||
KEY_EN_9,
|
||||
KEY_EN_0,
|
||||
KEY_EN_MINUS,
|
||||
KEY_EN_EQUALS,
|
||||
KEY_EN_BACKSPACE,
|
||||
KEY_EN_DELETE,
|
||||
KEY_EN_TAB,
|
||||
KEY_EN_Q,
|
||||
KEY_EN_W,
|
||||
KEY_EN_E,
|
||||
KEY_EN_R,
|
||||
KEY_EN_T,
|
||||
KEY_EN_Y,
|
||||
KEY_EN_U,
|
||||
KEY_EN_I,
|
||||
KEY_EN_O,
|
||||
KEY_EN_P,
|
||||
KEY_EN_LEFT_BRACKET,
|
||||
KEY_EN_RIGHT_BRACKET,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_HOME,
|
||||
KEY_EN_CAPS_LOCK,
|
||||
KEY_EN_A,
|
||||
KEY_EN_S,
|
||||
KEY_EN_D,
|
||||
KEY_EN_F,
|
||||
KEY_EN_G,
|
||||
KEY_EN_H,
|
||||
KEY_EN_J,
|
||||
KEY_EN_K,
|
||||
KEY_EN_L,
|
||||
KEY_EN_SEMICOLON,
|
||||
KEY_EN_QUOTE,
|
||||
KEY_EN_POUND,
|
||||
KEY_EN_ISO_ENTER,
|
||||
KEY_EN_PAGE_UP,
|
||||
KEY_EN_LEFT_SHIFT,
|
||||
KEY_EN_Z,
|
||||
KEY_EN_X,
|
||||
KEY_EN_C,
|
||||
KEY_EN_V,
|
||||
KEY_EN_B,
|
||||
KEY_EN_N,
|
||||
KEY_EN_M,
|
||||
KEY_EN_COMMA,
|
||||
KEY_EN_PERIOD,
|
||||
KEY_EN_FORWARD_SLASH,
|
||||
KEY_EN_RIGHT_SHIFT,
|
||||
KEY_EN_UP_ARROW,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_PAGE_DOWN,
|
||||
KEY_EN_LEFT_CONTROL,
|
||||
KEY_EN_ISO_BACK_SLASH,
|
||||
KEY_EN_LEFT_WINDOWS,
|
||||
KEY_EN_LEFT_ALT,
|
||||
KEY_EN_UNUSED,
|
||||
"Left Space",
|
||||
KEY_EN_SPACE,
|
||||
"Right Space",
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_RIGHT_ALT,
|
||||
KEY_EN_RIGHT_FUNCTION,
|
||||
KEY_EN_LEFT_ARROW,
|
||||
KEY_EN_DOWN_ARROW,
|
||||
KEY_EN_RIGHT_ARROW
|
||||
};
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name HyperX Origins 2 65
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectHyperXOrigins2_65
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_HyperXOrigins2_65::RGBController_HyperXOrigins2_65(HyperXOrigins2_65Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "HyperX";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFFFF;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
|
||||
keepalive_thread_run = 1;
|
||||
keepalive_thread = new std::thread(&RGBController_HyperXOrigins2_65::KeepaliveThread, this);
|
||||
}
|
||||
|
||||
RGBController_HyperXOrigins2_65::~RGBController_HyperXOrigins2_65()
|
||||
{
|
||||
keepalive_thread_run = 0;
|
||||
keepalive_thread->join();
|
||||
delete keepalive_thread;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Delete the matrix map |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
|
||||
{
|
||||
if(zones[zone_index].matrix_map != NULL)
|
||||
{
|
||||
delete zones[zone_index].matrix_map;
|
||||
}
|
||||
}
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_HyperXOrigins2_65::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int total_led_count = 0;
|
||||
for(unsigned int zone_idx = 0; zone_idx < 1; zone_idx++)
|
||||
{
|
||||
zone new_zone;
|
||||
new_zone.name = zone_names[zone_idx];
|
||||
new_zone.type = zone_types[zone_idx];
|
||||
new_zone.leds_min = zone_sizes[zone_idx];
|
||||
new_zone.leds_max = zone_sizes[zone_idx];
|
||||
new_zone.leds_count = zone_sizes[zone_idx];
|
||||
|
||||
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
|
||||
{
|
||||
new_zone.matrix_map = new matrix_map_type;
|
||||
new_zone.matrix_map->height = 5;
|
||||
new_zone.matrix_map->width = 15;
|
||||
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_zone.matrix_map = NULL;
|
||||
}
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
total_led_count += zone_sizes[zone_idx];
|
||||
}
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = led_names[led_idx];
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_HyperXOrigins2_65::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_HyperXOrigins2_65::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetLEDsDirect(colors);
|
||||
}
|
||||
|
||||
void RGBController_HyperXOrigins2_65::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_HyperXOrigins2_65::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_HyperXOrigins2_65::DeviceUpdateMode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_HyperXOrigins2_65::KeepaliveThread()
|
||||
{
|
||||
while(keepalive_thread_run.load())
|
||||
{
|
||||
if(active_mode == 0)
|
||||
{
|
||||
if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(50))
|
||||
{
|
||||
UpdateLEDs();
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(10ms);;
|
||||
}
|
||||
}
|
||||
|
||||
+42
-43
@@ -1,43 +1,42 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CorsairWireless.h |
|
||||
| |
|
||||
| RGBController for Corsair wireless keyboard |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 08 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "CorsairWirelessController.h"
|
||||
|
||||
class RGBController_CorsairWireless : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CorsairWireless(CorsairWirelessController* controller_ptr);
|
||||
~RGBController_CorsairWireless();
|
||||
|
||||
int physical_layout;
|
||||
int logical_layout;
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
void KeepaliveThread();
|
||||
|
||||
private:
|
||||
CorsairWirelessController* controller;
|
||||
std::thread* keepalive_thread;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_HyperXOrigins2_65.h |
|
||||
| |
|
||||
| RGBController for HyperX Origins 2 65 keyboard |
|
||||
| |
|
||||
| Ricardo Amorim 28 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include "RGBController.h"
|
||||
#include "HyperXOrigins2_65Controller.h"
|
||||
|
||||
class RGBController_HyperXOrigins2_65 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_HyperXOrigins2_65(HyperXOrigins2_65Controller* controller_ptr);
|
||||
~RGBController_HyperXOrigins2_65();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
void KeepaliveThread();
|
||||
|
||||
private:
|
||||
HyperXOrigins2_65Controller* controller;
|
||||
std::thread* keepalive_thread;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
|
||||
};
|
||||
|
||||
@@ -118,7 +118,7 @@ void RGBController_IntelArcA770LE::SetupZones()
|
||||
for(unsigned int led_idx = 0; led_idx < 16; led_idx++)
|
||||
{
|
||||
led fan_1_led;
|
||||
fan_1_led.name = "Fan 1 LED";
|
||||
fan_1_led.name = "Fan 1 LED " + std::to_string(led_idx + 1);
|
||||
fan_1_led.value = fan_1_leds[led_idx];
|
||||
leds.push_back(fan_1_led);
|
||||
}
|
||||
@@ -126,7 +126,7 @@ void RGBController_IntelArcA770LE::SetupZones()
|
||||
for(unsigned int led_idx = 0; led_idx < 16; led_idx++)
|
||||
{
|
||||
led fan_2_led;
|
||||
fan_2_led.name = "Fan 2 LED";
|
||||
fan_2_led.name = "Fan 2 LED " + std::to_string(led_idx + 1);
|
||||
fan_2_led.value = fan_2_leds[led_idx];
|
||||
leds.push_back(fan_2_led);
|
||||
}
|
||||
@@ -134,7 +134,7 @@ void RGBController_IntelArcA770LE::SetupZones()
|
||||
for(unsigned int led_idx = 0; led_idx < 8; led_idx++)
|
||||
{
|
||||
led back_led;
|
||||
back_led.name = "Back LED";
|
||||
back_led.name = "Back LED " + std::to_string(led_idx + 1);
|
||||
back_led.value = back_leds[led_idx];
|
||||
leds.push_back(back_led);
|
||||
}
|
||||
@@ -142,7 +142,7 @@ void RGBController_IntelArcA770LE::SetupZones()
|
||||
for(unsigned int led_idx = 0; led_idx < 50; led_idx++)
|
||||
{
|
||||
led ring_led;
|
||||
ring_led.name = "Ring LED";
|
||||
ring_led.name = "Ring LED " + std::to_string(led_idx + 1);
|
||||
ring_led.value = ring_leds[led_idx];
|
||||
leds.push_back(ring_led);
|
||||
}
|
||||
@@ -150,7 +150,7 @@ void RGBController_IntelArcA770LE::SetupZones()
|
||||
for(unsigned int led_idx = 0; led_idx < 1; led_idx++)
|
||||
{
|
||||
led logo_led;
|
||||
logo_led.name = "Logo LED";
|
||||
logo_led.name = "Logo LED " + std::to_string(led_idx + 1);
|
||||
logo_led.value = logo_leds[led_idx];
|
||||
leds.push_back(logo_led);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "ResourceManager.h"
|
||||
#include "SettingsManager.h"
|
||||
#include "JGINYUEInternalUSBV2Controller.h"
|
||||
|
||||
#include "LogManager.h"
|
||||
#include "dmiinfo.h"
|
||||
|
||||
#define JGINYUE_V2_HID_GENERAL_COMMAND_HEADER 0x01
|
||||
@@ -55,8 +55,10 @@ JGINYUEInternalUSBV2Controller::JGINYUEInternalUSBV2Controller(hid_device* jy_hi
|
||||
JGINYUEInternalUSBV2Controller::~JGINYUEInternalUSBV2Controller()
|
||||
{
|
||||
hid_close(jy_hid_interface);
|
||||
delete jy_cdc_interface;
|
||||
|
||||
if(jy_cdc_interface != nullptr)
|
||||
{
|
||||
delete jy_cdc_interface;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int JGINYUEInternalUSBV2Controller::GetZoneCount()
|
||||
@@ -91,14 +93,26 @@ void JGINYUEInternalUSBV2Controller::Init_device()
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
usb_buf[0] = JGINYUE_V2_HID_GENERAL_COMMAND_HEADER;
|
||||
usb_buf[1] = 0x0F;
|
||||
hid_write(jy_hid_interface, usb_buf, 64);
|
||||
std::this_thread::sleep_for(20ms);
|
||||
hid_read(jy_hid_interface, usb_buf, 64);
|
||||
if(usb_buf[1] != 0x0F)
|
||||
|
||||
int write_result = hid_write(jy_hid_interface, usb_buf, 64);
|
||||
if(write_result < 0)
|
||||
{
|
||||
LOG_ERROR("[JGINYUEInternalUSBV2Controller] Failed to write to JGINYUE device during initialization");
|
||||
ZoneCount = 0x00;
|
||||
memset(device_config, 0x00, sizeof(device_config));
|
||||
memset (&device_config_Global, 0x00, sizeof(device_config_Global));
|
||||
memset(&device_config_Global, 0x00, sizeof(device_config_Global));
|
||||
return;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(20ms);
|
||||
|
||||
int bytes_read = hid_read_timeout(jy_hid_interface, usb_buf, 64, 1000);
|
||||
if(bytes_read <= 0 || usb_buf[1] != 0x0F)
|
||||
{
|
||||
LOG_ERROR("[JGINYUEInternalUSBV2Controller] JGINYUE device did not respond or invalid response (bytes read: %d)", bytes_read);
|
||||
ZoneCount = 0x00;
|
||||
memset(device_config, 0x00, sizeof(device_config));
|
||||
memset(&device_config_Global, 0x00, sizeof(device_config_Global));
|
||||
return;
|
||||
}
|
||||
unsigned char Zone_Info = usb_buf[4];
|
||||
@@ -135,13 +149,25 @@ void JGINYUEInternalUSBV2Controller::Init_Zone(int zone)
|
||||
usb_buf[1] = JGINYUE_V2_HID_REQUEST_ARGB_SETTING;
|
||||
usb_buf[2] = Area_ID;
|
||||
|
||||
hid_write(jy_hid_interface, usb_buf, 64);
|
||||
int write_result = hid_write(jy_hid_interface, usb_buf, 64);
|
||||
if(write_result < 0)
|
||||
{
|
||||
LOG_ERROR("[JGINYUEInternalUSBV2Controller] Failed to write to JGINYUE device for zone %d", zone);
|
||||
return;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(20ms);
|
||||
|
||||
hid_read(jy_hid_interface, usb_buf, 64);
|
||||
|
||||
if((usb_buf[1] != JGINYUE_V2_HID_REQUEST_ARGB_SETTING)|(usb_buf[2] != Area_ID))
|
||||
int bytes_read = hid_read_timeout(jy_hid_interface, usb_buf, 64, 1000);
|
||||
if(bytes_read <= 0)
|
||||
{
|
||||
LOG_ERROR("[JGINYUEInternalUSBV2Controller] Failed to read zone %d config from JGINYUE device (bytes read: %d)", zone, bytes_read);
|
||||
return;
|
||||
}
|
||||
|
||||
if((usb_buf[1] != JGINYUE_V2_HID_REQUEST_ARGB_SETTING) || (usb_buf[2] != Area_ID))
|
||||
{
|
||||
LOG_ERROR("[JGINYUEInternalUSBV2Controller] Invalid response for zone %d from JGINYUE device", zone);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -200,6 +226,16 @@ void JGINYUEInternalUSBV2Controller::DirectLEDControl
|
||||
unsigned char Area
|
||||
)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Direct mode requires CDC interface |
|
||||
| If CDC is not available, log error and return |
|
||||
\*-----------------------------------------------------*/
|
||||
if(jy_cdc_interface == nullptr)
|
||||
{
|
||||
LOG_WARNING("[JGINYUEInternalUSBV2Controller] Direct mode requires serial port (CDC) which is not available. Use other modes instead.");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char cdc_buf[512];
|
||||
memset(cdc_buf, 0x00, sizeof(cdc_buf));
|
||||
cdc_buf[0] = JGINYUE_V2_CDC_COMMAND_HEADER;
|
||||
|
||||
+30
-11
@@ -46,30 +46,49 @@ void DetectJGINYUEInternalUSBV2Controller(hid_device_info* info,const std::strin
|
||||
std::transform(manufacturer.begin(), manufacturer.end(), manufacturer.begin(), ::toupper);
|
||||
if(manufacturer.find("JGINYUE") == std::string::npos)
|
||||
{
|
||||
LOG_INFO("JGINYUE Internal USB ControllerV2 not found,error manufacturer name:%s",manufacturer.c_str());
|
||||
LOG_INFO("[JGINYUEInternalUSBV2ControllerDetect] JGINYUE Internal USB ControllerV2 not found,error manufacturer name:%s",manufacturer.c_str());
|
||||
hid_close(hid_dev);
|
||||
return;
|
||||
}
|
||||
LOG_INFO("Pass manufacture name check.Start to init HID and CDC interface");
|
||||
LOG_INFO("[JGINYUEInternalUSBV2ControllerDetect] Pass manufacture name check.Start to init HID and CDC interface");
|
||||
|
||||
|
||||
if(hid_dev != nullptr )
|
||||
{
|
||||
serial_port *port = nullptr;
|
||||
std::vector<std::string*> serial_ports = find_usb_serial_port(JGINYUE_VID_V2, JGINYUE_MOTHERBOARD_PID_V2);
|
||||
if(serial_ports.size() ==1)
|
||||
|
||||
if(serial_ports.size() == 0)
|
||||
{
|
||||
serial_port *port = new serial_port();
|
||||
LOG_WARNING("[JGINYUEInternalUSBV2ControllerDetect] JGINYUE device found but no serial port detected - Direct mode will be unavailable");
|
||||
}
|
||||
else if(serial_ports.size() > 1)
|
||||
{
|
||||
LOG_WARNING("[JGINYUEInternalUSBV2ControllerDetect] Multiple serial ports found for JGINYUE device, using first one");
|
||||
}
|
||||
|
||||
if(serial_ports.size() >= 1)
|
||||
{
|
||||
port = new serial_port();
|
||||
if(!port->serial_open(serial_ports[0]->c_str(), 115200))
|
||||
{
|
||||
LOG_ERROR("Failed to open serial port %s", serial_ports[0]->c_str());
|
||||
LOG_WARNING("[JGINYUEInternalUSBV2ControllerDetect] Failed to open serial port %s - Direct mode will be unavailable. HID modes will still work.", serial_ports[0]->c_str());
|
||||
delete port;
|
||||
hid_close(hid_dev);
|
||||
return;
|
||||
port = nullptr;
|
||||
}
|
||||
JGINYUEInternalUSBV2Controller *controller = new JGINYUEInternalUSBV2Controller(hid_dev, info->path,port);
|
||||
RGBController_JGINYUEInternalUSBV2 *rgb_controller = new RGBController_JGINYUEInternalUSBV2(controller);
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
LOG_INFO("JGINYUE Internal USB ControllerV2 found");
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Clean up serial port string vector |
|
||||
\*-----------------------------------------------------*/
|
||||
for(std::string* str_ptr : serial_ports)
|
||||
{
|
||||
delete str_ptr;
|
||||
}
|
||||
|
||||
JGINYUEInternalUSBV2Controller *controller = new JGINYUEInternalUSBV2Controller(hid_dev, info->path, port);
|
||||
RGBController_JGINYUEInternalUSBV2 *rgb_controller = new RGBController_JGINYUEInternalUSBV2(controller);
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#define LEGION_7GEN9 0xC997
|
||||
#define LEGION_7GEN9_H 0xC998
|
||||
#define LEGION_7GEN10 0xC197
|
||||
#define LEGION_5GEN10 0xC195
|
||||
|
||||
enum LENOVO_KEYBOARD
|
||||
{
|
||||
|
||||
+1
-1
@@ -318,7 +318,7 @@ void RGBController_LenovoK510::ReadAndUpdateCurrentDeviceState()
|
||||
current_active_mode.direction = current_active_mode.direction ? MODE_DIRECTION_UP : MODE_DIRECTION_DOWN;
|
||||
}
|
||||
|
||||
active_mode = i;
|
||||
active_mode = (int)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,3 +67,4 @@ REGISTER_HID_DETECTOR_PU("Lenovo Legion 7S Gen 8", DetectLenovoLegionUSBControl
|
||||
REGISTER_HID_DETECTOR_PU("Lenovo Legion 7 Gen 9", DetectLenovoLegionUSBControllersGen7And8, ITE_VID, LEGION_7GEN9, LENOVO_PAGE, LENOVO_USAGE);
|
||||
REGISTER_HID_DETECTOR_PU("Lenovo Legion 7 Gen 9", DetectLenovoLegionUSBControllersGen7And8, ITE_VID, LEGION_7GEN9_H, LENOVO_PAGE, LENOVO_USAGE);
|
||||
REGISTER_HID_DETECTOR_PU("Lenovo Legion 7 Gen 10", DetectLenovoLegionUSBControllersGen7And8, ITE_VID, LEGION_7GEN10, LENOVO_PAGE, LENOVO_USAGE);
|
||||
REGISTER_HID_DETECTOR_PU("Lenovo Legion 5 Gen 10", DetectLenovoLegionUSBControllersGen7And8, ITE_VID, LEGION_5GEN10, LENOVO_PAGE, LENOVO_USAGE);
|
||||
|
||||
+8
-3
@@ -17,7 +17,7 @@ using namespace std;
|
||||
|
||||
static void SetGen10PayloadLength(uint16_t pid, uint8_t* buffer, uint16_t payload_length)
|
||||
{
|
||||
if(pid != LEGION_7GEN10)
|
||||
if(pid != LEGION_7GEN10 && pid != LEGION_5GEN10)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -26,6 +26,11 @@ static void SetGen10PayloadLength(uint16_t pid, uint8_t* buffer, uint16_t payloa
|
||||
buffer[3] = (payload_length >> 8) & 0xFF;
|
||||
}
|
||||
|
||||
static bool UsesGen10PacketFormat(uint16_t pid)
|
||||
{
|
||||
return pid == LEGION_7GEN10 || pid == LEGION_5GEN10;
|
||||
}
|
||||
|
||||
LenovoGen7And8USBController::LenovoGen7And8USBController(hid_device* dev_handle, const char* path, uint16_t in_pid, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
@@ -114,7 +119,7 @@ void LenovoGen7And8USBController::setLedsByGroup(uint8_t profile_id, vector<led_
|
||||
i+= led_count * sizeof(uint16_t);
|
||||
}
|
||||
|
||||
if(pid == LEGION_7GEN10)
|
||||
if(UsesGen10PacketFormat(pid))
|
||||
{
|
||||
SetGen10PayloadLength(pid, buffer, static_cast<uint16_t>(i - 4));
|
||||
}
|
||||
@@ -162,7 +167,7 @@ void LenovoGen7And8USBController::setLedsDirectOff(uint8_t profile_id)
|
||||
|
||||
void LenovoGen7And8USBController::setLedsDirect(std::vector<led> &leds, std::vector<RGBColor> &colors)
|
||||
{
|
||||
if(pid == LEGION_7GEN10)
|
||||
if(UsesGen10PacketFormat(pid))
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Gen10 uses 0x07/A1 direct updates, with payload length |
|
||||
|
||||
+229
-106
@@ -13,6 +13,78 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
static bool UsesGen10PacketFormat(uint16_t pid)
|
||||
{
|
||||
return pid == LEGION_7GEN10 || pid == LEGION_5GEN10;
|
||||
}
|
||||
|
||||
static bool Is24ZoneDevice(uint16_t pid)
|
||||
{
|
||||
return pid == LEGION_5GEN10;
|
||||
}
|
||||
|
||||
static bool IsKeyboardOnlyDevice(uint16_t pid)
|
||||
{
|
||||
return pid == LEGION_5GEN10;
|
||||
}
|
||||
|
||||
static const lenovo_led legion_5gen10_24zone_leds[] =
|
||||
{
|
||||
{0x01, "Zone R1C1"},
|
||||
{0x02, "Zone R1C2"},
|
||||
{0x03, "Zone R1C3"},
|
||||
{0x04, "Zone R1C4"},
|
||||
{0x05, "Zone R1C5"},
|
||||
{0x06, "Zone R1C6"},
|
||||
{0x07, "Zone R2C1"},
|
||||
{0x08, "Zone R2C2"},
|
||||
{0x09, "Zone R2C3"},
|
||||
{0x0A, "Zone R2C4"},
|
||||
{0x0B, "Zone R2C5"},
|
||||
{0x0C, "Zone R2C6"},
|
||||
{0x0D, "Zone R3C1"},
|
||||
{0x0E, "Zone R3C2"},
|
||||
{0x0F, "Zone R3C3"},
|
||||
{0x10, "Zone R3C4"},
|
||||
{0x11, "Zone R3C5"},
|
||||
{0x12, "Zone R3C6"},
|
||||
{0x13, "Zone R4C1"},
|
||||
{0x14, "Zone R4C2"},
|
||||
{0x15, "Zone R4C3"},
|
||||
{0x16, "Zone R4C4"},
|
||||
{0x17, "Zone R4C5"},
|
||||
{0x18, "Zone R4C6"},
|
||||
};
|
||||
|
||||
static const unsigned int legion_5gen10_24zone_matrix_map[] =
|
||||
{
|
||||
0, 1, 2, 3, 4, 5,
|
||||
6, 7, 8, 9, 10, 11,
|
||||
12, 13, 14, 15, 16, 17,
|
||||
18, 19, 20, 21, 22, 23,
|
||||
};
|
||||
|
||||
static const lenovo_zone legion_5gen10_kbd_24zone =
|
||||
{
|
||||
"Keyboard (24-zone)",
|
||||
ZONE_TYPE_MATRIX,
|
||||
0,
|
||||
4,
|
||||
6,
|
||||
legion_5gen10_24zone_matrix_map,
|
||||
legion_5gen10_24zone_leds,
|
||||
0,
|
||||
23,
|
||||
};
|
||||
|
||||
static const RGBColor legion_5gen10_zone_visualization_colors[24] =
|
||||
{
|
||||
0xFF0000, 0x00FFFF, 0xFFFF00, 0x0000FF, 0x00FF00, 0xFF00FF,
|
||||
0xFF7F00, 0x007FFF, 0x7FFF00, 0x7F00FF, 0xFF007F, 0x00FF7F,
|
||||
0xFFD700, 0x0055FF, 0x55FF00, 0xFF0055, 0x00BFFF, 0xBF00FF,
|
||||
0xFF3B00, 0x00FF3B, 0x3B00FF, 0xFF1493, 0x14FF93, 0x9314FF,
|
||||
};
|
||||
|
||||
LenovoRGBController_Gen7_8::LenovoRGBController_Gen7_8(LenovoGen7And8USBController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
@@ -139,72 +211,79 @@ LenovoRGBController_Gen7_8::LenovoRGBController_Gen7_8(LenovoGen7And8USBControll
|
||||
Smooth.brightness = brightness;
|
||||
modes.push_back(Smooth);
|
||||
|
||||
mode Rain;
|
||||
Rain.name = "Rain";
|
||||
Rain.value = LENOVO_LEGION_GEN7_8_MODE_RAIN;
|
||||
Rain.flags = MODE_FLAG_HAS_SPEED |
|
||||
MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
|
||||
MODE_FLAG_HAS_RANDOM_COLOR |
|
||||
MODE_FLAG_HAS_BRIGHTNESS |
|
||||
MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Rain.speed_min = 0x01;
|
||||
Rain.speed_max = 0x03;
|
||||
Rain.speed = 2;
|
||||
Rain.colors_min = 1;
|
||||
Rain.colors_max = 4;
|
||||
Rain.colors.resize(4);
|
||||
Rain.colors[0] = 0xFFF500;
|
||||
Rain.color_mode = MODE_COLORS_RANDOM;
|
||||
Rain.brightness_min = 0;
|
||||
Rain.brightness_max = 9;
|
||||
Rain.brightness = brightness;
|
||||
modes.push_back(Rain);
|
||||
if(!Is24ZoneDevice(controller->getPid()))
|
||||
{
|
||||
mode Rain;
|
||||
Rain.name = "Rain";
|
||||
Rain.value = LENOVO_LEGION_GEN7_8_MODE_RAIN;
|
||||
Rain.flags = MODE_FLAG_HAS_SPEED |
|
||||
MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
|
||||
MODE_FLAG_HAS_RANDOM_COLOR |
|
||||
MODE_FLAG_HAS_BRIGHTNESS |
|
||||
MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Rain.speed_min = 0x01;
|
||||
Rain.speed_max = 0x03;
|
||||
Rain.speed = 2;
|
||||
Rain.colors_min = 1;
|
||||
Rain.colors_max = 4;
|
||||
Rain.colors.resize(4);
|
||||
Rain.colors[0] = 0xFFF500;
|
||||
Rain.color_mode = MODE_COLORS_RANDOM;
|
||||
Rain.brightness_min = 0;
|
||||
Rain.brightness_max = 9;
|
||||
Rain.brightness = brightness;
|
||||
modes.push_back(Rain);
|
||||
}
|
||||
|
||||
mode Ripple;
|
||||
Ripple.name = "Ripple";
|
||||
Ripple.value = LENOVO_LEGION_GEN7_8_MODE_RIPPLE;
|
||||
Ripple.flags = MODE_FLAG_HAS_SPEED |
|
||||
MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
|
||||
MODE_FLAG_HAS_RANDOM_COLOR |
|
||||
MODE_FLAG_HAS_BRIGHTNESS |
|
||||
MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Ripple.speed_min = 0x01;
|
||||
Ripple.speed_max = 0x03;
|
||||
Ripple.speed = 2;
|
||||
Ripple.colors_min = 1;
|
||||
Ripple.colors_max = 4;
|
||||
Ripple.colors.resize(4);
|
||||
Ripple.colors[0] = 0xFFF500;
|
||||
Ripple.color_mode = MODE_COLORS_RANDOM;
|
||||
Ripple.brightness_min = 0;
|
||||
Ripple.brightness_max = 9;
|
||||
Ripple.brightness = brightness;
|
||||
modes.push_back(Ripple);
|
||||
if(!IsKeyboardOnlyDevice(controller->getPid()))
|
||||
{
|
||||
mode Ripple;
|
||||
Ripple.name = "Ripple";
|
||||
Ripple.value = LENOVO_LEGION_GEN7_8_MODE_RIPPLE;
|
||||
Ripple.flags = MODE_FLAG_HAS_SPEED |
|
||||
MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
|
||||
MODE_FLAG_HAS_RANDOM_COLOR |
|
||||
MODE_FLAG_HAS_BRIGHTNESS |
|
||||
MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Ripple.speed_min = 0x01;
|
||||
Ripple.speed_max = 0x03;
|
||||
Ripple.speed = 2;
|
||||
Ripple.colors_min = 1;
|
||||
Ripple.colors_max = 4;
|
||||
Ripple.colors.resize(4);
|
||||
Ripple.colors[0] = 0xFFF500;
|
||||
Ripple.color_mode = MODE_COLORS_RANDOM;
|
||||
Ripple.brightness_min = 0;
|
||||
Ripple.brightness_max = 9;
|
||||
Ripple.brightness = brightness;
|
||||
modes.push_back(Ripple);
|
||||
|
||||
mode AudioBounce;
|
||||
AudioBounce.name = "Audio Bounce Lighting";
|
||||
AudioBounce.value = LENOVO_LEGION_GEN7_8_MODE_AUDIO_BOUNCE;
|
||||
AudioBounce.flags = MODE_FLAG_HAS_BRIGHTNESS;
|
||||
AudioBounce.color_mode = MODE_COLORS_NONE;
|
||||
AudioBounce.brightness_min = 0;
|
||||
AudioBounce.brightness_max = 9;
|
||||
AudioBounce.brightness = brightness;
|
||||
modes.push_back(AudioBounce);
|
||||
mode AudioBounce;
|
||||
AudioBounce.name = "Audio Bounce Lighting";
|
||||
AudioBounce.value = LENOVO_LEGION_GEN7_8_MODE_AUDIO_BOUNCE;
|
||||
AudioBounce.flags = MODE_FLAG_HAS_BRIGHTNESS;
|
||||
AudioBounce.color_mode = MODE_COLORS_NONE;
|
||||
AudioBounce.brightness_min = 0;
|
||||
AudioBounce.brightness_max = 9;
|
||||
AudioBounce.brightness = brightness;
|
||||
modes.push_back(AudioBounce);
|
||||
|
||||
mode AudioRipple;
|
||||
AudioRipple.name = "Audio Ripple Lighting";
|
||||
AudioRipple.value = LENOVO_LEGION_GEN7_8_MODE_AUDIO_RIPPLE;
|
||||
AudioRipple.flags = MODE_FLAG_HAS_BRIGHTNESS;
|
||||
AudioRipple.color_mode = MODE_COLORS_NONE;
|
||||
AudioRipple.brightness_min = 0;
|
||||
AudioRipple.brightness_max = 9;
|
||||
AudioRipple.brightness = brightness;
|
||||
modes.push_back(AudioRipple);
|
||||
mode AudioRipple;
|
||||
AudioRipple.name = "Audio Ripple Lighting";
|
||||
AudioRipple.value = LENOVO_LEGION_GEN7_8_MODE_AUDIO_RIPPLE;
|
||||
AudioRipple.flags = MODE_FLAG_HAS_BRIGHTNESS;
|
||||
AudioRipple.color_mode = MODE_COLORS_NONE;
|
||||
AudioRipple.brightness_min = 0;
|
||||
AudioRipple.brightness_max = 9;
|
||||
AudioRipple.brightness = brightness;
|
||||
modes.push_back(AudioRipple);
|
||||
}
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = LENOVO_LEGION_GEN7_8_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR |
|
||||
MODE_FLAG_HAS_RANDOM_COLOR |
|
||||
MODE_FLAG_HAS_BRIGHTNESS |
|
||||
MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Static.color_mode = MODE_COLORS_PER_LED;
|
||||
@@ -213,37 +292,43 @@ LenovoRGBController_Gen7_8::LenovoRGBController_Gen7_8(LenovoGen7And8USBControll
|
||||
Static.brightness = brightness;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Type;
|
||||
Type.name = "Type Lighting";
|
||||
Type.value = LENOVO_LEGION_GEN7_8_MODE_TYPE;
|
||||
Type.flags = MODE_FLAG_HAS_SPEED |
|
||||
MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
|
||||
MODE_FLAG_HAS_RANDOM_COLOR |
|
||||
MODE_FLAG_HAS_BRIGHTNESS |
|
||||
MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Type.speed_min = 0x01;
|
||||
Type.speed_max = 0x03;
|
||||
Type.speed = 2;
|
||||
Type.colors_min = 1;
|
||||
Type.colors_max = 4;
|
||||
Type.colors.resize(4);
|
||||
Type.colors[0] = 0xFFF500;
|
||||
Type.color_mode = MODE_COLORS_RANDOM;
|
||||
Type.brightness_min = 0;
|
||||
Type.brightness_max = 9;
|
||||
Type.brightness = brightness;
|
||||
modes.push_back(Type);
|
||||
if(!Is24ZoneDevice(controller->getPid()))
|
||||
{
|
||||
mode Type;
|
||||
Type.name = "Type Lighting";
|
||||
Type.value = LENOVO_LEGION_GEN7_8_MODE_TYPE;
|
||||
Type.flags = MODE_FLAG_HAS_SPEED |
|
||||
MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
|
||||
MODE_FLAG_HAS_RANDOM_COLOR |
|
||||
MODE_FLAG_HAS_BRIGHTNESS |
|
||||
MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Type.speed_min = 0x01;
|
||||
Type.speed_max = 0x03;
|
||||
Type.speed = 2;
|
||||
Type.colors_min = 1;
|
||||
Type.colors_max = 4;
|
||||
Type.colors.resize(4);
|
||||
Type.colors[0] = 0xFFF500;
|
||||
Type.color_mode = MODE_COLORS_RANDOM;
|
||||
Type.brightness_min = 0;
|
||||
Type.brightness_max = 9;
|
||||
Type.brightness = brightness;
|
||||
modes.push_back(Type);
|
||||
}
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = LENOVO_LEGION_GEN7_8_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR |
|
||||
MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
Direct.brightness_min = 0;
|
||||
Direct.brightness_max = 9;
|
||||
Direct.brightness = brightness;
|
||||
modes.push_back(Direct);
|
||||
if(!IsKeyboardOnlyDevice(controller->getPid()))
|
||||
{
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = LENOVO_LEGION_GEN7_8_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR |
|
||||
MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
Direct.brightness_min = 0;
|
||||
Direct.brightness_max = 9;
|
||||
Direct.brightness = brightness;
|
||||
modes.push_back(Direct);
|
||||
}
|
||||
|
||||
name = controller->getName();
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
@@ -275,6 +360,10 @@ LenovoRGBController_Gen7_8::LenovoRGBController_Gen7_8(LenovoGen7And8USBControll
|
||||
case LEGION_7GEN10:
|
||||
description = "Lenovo Legion 7 Generation 10";
|
||||
break;
|
||||
|
||||
case LEGION_5GEN10:
|
||||
description = "Lenovo Legion 5 Gen 10";
|
||||
break;
|
||||
}
|
||||
|
||||
brightness = controller->getCurrentBrightness();
|
||||
@@ -286,15 +375,15 @@ LenovoRGBController_Gen7_8::LenovoRGBController_Gen7_8(LenovoGen7And8USBControll
|
||||
|
||||
SetupZones();
|
||||
|
||||
/*-----------------*\
|
||||
| Initiliaze Static |
|
||||
\*-----------------*/
|
||||
/*-----------------------------------------------------*\
|
||||
| Initiliaze Static |
|
||||
\*-----------------------------------------------------*/
|
||||
active_mode = 0;
|
||||
for(size_t i = 0; i < modes.size(); i++)
|
||||
{
|
||||
if(modes[i].value == LENOVO_LEGION_GEN7_8_MODE_STATIC)
|
||||
{
|
||||
active_mode = i;
|
||||
active_mode = (int)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -307,12 +396,22 @@ LenovoRGBController_Gen7_8::~LenovoRGBController_Gen7_8()
|
||||
delete controller;
|
||||
}
|
||||
|
||||
|
||||
void LenovoRGBController_Gen7_8::SetupZones()
|
||||
{
|
||||
vector<lenovo_zone> lenovo_zones;
|
||||
lenovo_zones.push_back(legion7_gen7and8_kbd_ansi);
|
||||
lenovo_zones.push_back(legion7_gen7and8_neon);
|
||||
if(Is24ZoneDevice(controller->getPid()))
|
||||
{
|
||||
lenovo_zones.push_back(legion_5gen10_kbd_24zone);
|
||||
}
|
||||
else
|
||||
{
|
||||
lenovo_zones.push_back(legion7_gen7and8_kbd_ansi);
|
||||
}
|
||||
|
||||
if(!IsKeyboardOnlyDevice(controller->getPid()))
|
||||
{
|
||||
lenovo_zones.push_back(legion7_gen7and8_neon);
|
||||
}
|
||||
|
||||
if (controller->getPid() == LEGION_7GEN7)
|
||||
{
|
||||
@@ -363,9 +462,9 @@ void LenovoRGBController_Gen7_8::SetupZones()
|
||||
new_led.value = lenovo_zones[i].id << 8 | lenovo_zones[i].leds[led_idx].led_num ;
|
||||
leds.push_back(new_led);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| create led id to index map for fast look up |
|
||||
\*---------------------------------------------------------*/
|
||||
/*---------------------------------------------*\
|
||||
| create led id to index map for fast look up |
|
||||
\*---------------------------------------------*/
|
||||
led_id_to_index[new_led.value]=leds.size() - 1;
|
||||
}
|
||||
}
|
||||
@@ -423,7 +522,7 @@ void LenovoRGBController_Gen7_8::DeviceUpdateMode()
|
||||
{
|
||||
controller->setLedsDirectOn(profile_id);
|
||||
direct_enabled = true;
|
||||
if(controller->getPid() != LEGION_7GEN10)
|
||||
if(!UsesGen10PacketFormat(controller->getPid()))
|
||||
{
|
||||
controller->setLedsByGroup(profile_id, GetLedGroups());
|
||||
}
|
||||
@@ -447,11 +546,12 @@ void LenovoRGBController_Gen7_8::DeviceUpdateLEDs()
|
||||
{
|
||||
if(modes[active_mode].value == LENOVO_LEGION_GEN7_8_MODE_DIRECT)
|
||||
{
|
||||
if(controller->getPid() == LEGION_7GEN10)
|
||||
if(UsesGen10PacketFormat(controller->getPid()))
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Gen10 may ignore A1 updates unless D0 is reasserted. |
|
||||
\*---------------------------------------------------------*/
|
||||
/*---------------------------------------------*\
|
||||
| Gen10 may ignore A1 updates unless D0 is |
|
||||
| reasserted. |
|
||||
\*---------------------------------------------*/
|
||||
controller->setLedsDirectOn(profile_id);
|
||||
direct_enabled = true;
|
||||
}
|
||||
@@ -570,6 +670,29 @@ void LenovoRGBController_Gen7_8::ReadDeviceSettings()
|
||||
|
||||
std::vector<led_group> LenovoRGBController_Gen7_8::GetLedGroups()
|
||||
{
|
||||
if(Is24ZoneDevice(controller->getPid()) &&
|
||||
modes[active_mode].value == LENOVO_LEGION_GEN7_8_MODE_STATIC &&
|
||||
modes[active_mode].color_mode == MODE_COLORS_RANDOM)
|
||||
{
|
||||
vector<led_group> led_groups;
|
||||
led_groups.reserve(leds.size());
|
||||
|
||||
for(size_t i = 0; i < leds.size(); i++)
|
||||
{
|
||||
led_group group;
|
||||
group.mode = modes[active_mode].value;
|
||||
group.speed = modes[active_mode].speed;
|
||||
group.spin = 0x00;
|
||||
group.direction = 0x00;
|
||||
group.color_mode = 0x02;
|
||||
group.colors.push_back(legion_5gen10_zone_visualization_colors[i % 24]);
|
||||
group.leds.push_back(leds[i].value);
|
||||
led_groups.push_back(group);
|
||||
}
|
||||
|
||||
return led_groups;
|
||||
}
|
||||
|
||||
std::unordered_map<RGBColor, vector<uint16_t>> led_map;
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_PER_LED &&
|
||||
@@ -585,9 +708,9 @@ std::vector<led_group> LenovoRGBController_Gen7_8::GetLedGroups()
|
||||
size_t start = 0;
|
||||
size_t end = leds.size();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Riplle and Type only apply to keyboard |
|
||||
\*---------------------------------------------------------*/
|
||||
/*-------------------------------------------------*\
|
||||
| Riplle and Type only apply to keyboard |
|
||||
\*-------------------------------------------------*/
|
||||
if(modes[active_mode].value == LENOVO_LEGION_GEN7_8_MODE_RIPPLE ||
|
||||
modes[active_mode].value == LENOVO_LEGION_GEN7_8_MODE_TYPE)
|
||||
{
|
||||
|
||||
@@ -291,7 +291,7 @@ void LianLiUniHubSLController::SendActivate(size_t channel, unsigned char num_fa
|
||||
buf[0x00] = UNIHUB_SL_REPORT_ID;
|
||||
buf[0x01] = 0x10;
|
||||
buf[0x02] = 0x32;
|
||||
buf[0x03] = 0x10 * channel + num_fans;
|
||||
buf[0x03] = 0x10 * (unsigned char)channel + num_fans;
|
||||
|
||||
this->LogBuffer("SendActivate", buf, sizeof(buf));
|
||||
|
||||
@@ -329,10 +329,10 @@ void LianLiUniHubSLController::SendMerge()
|
||||
void LianLiUniHubSLController::SendColor(size_t channel, const unsigned char *colors, size_t num_colors)
|
||||
{
|
||||
unsigned char* buf = new unsigned char[2 + num_colors];
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
memset(buf, 0x00, (2 + num_colors));
|
||||
|
||||
buf[0x00] = UNIHUB_SL_REPORT_ID;
|
||||
buf[0x01] = 0x30 + channel; // Channel 1: 0x30, Channel 2: 0x31, etc.
|
||||
buf[0x01] = 0x30 + (unsigned char)channel; // Channel 1: 0x30, Channel 2: 0x31, etc.
|
||||
|
||||
memcpy(&buf[0x02], colors, num_colors);
|
||||
|
||||
@@ -350,7 +350,7 @@ void LianLiUniHubSLController::SendMode(size_t channel, const mode &active)
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
buf[0x00] = UNIHUB_SL_REPORT_ID;
|
||||
buf[0x01] = 0x10 + channel; // Channel 1: 0x10, Channel 2: 0x11, etc.
|
||||
buf[0x01] = 0x10 + (unsigned char)channel; // Channel 1: 0x10, Channel 2: 0x11, etc.
|
||||
buf[0x02] = active.value;
|
||||
buf[0x03] = this->ConvertSpeed(active.speed);
|
||||
buf[0x04] = this->ConvertDirection(active.direction);
|
||||
|
||||
+1
-1
@@ -321,7 +321,7 @@ void RGBController_LianLiUniHubSL::SetupZones()
|
||||
new_led.name = zones[zone_idx].name;
|
||||
new_led.name.append(", Fan ");
|
||||
new_led.name.append(std::to_string(led_idx + 1));
|
||||
new_led.value = zone_idx;
|
||||
new_led.value = (unsigned int)zone_idx;
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
+2
-2
@@ -235,7 +235,7 @@ void LianLiUniHubSLV2Controller::SetChannelMode(unsigned char channel, const mod
|
||||
|
||||
void LianLiUniHubSLV2Controller::SendStartAction(unsigned char channel, unsigned int num_fans)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
unsigned char usb_buf[353];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -291,7 +291,7 @@ void LianLiUniHubSLV2Controller::SendColorData(unsigned char channel, unsigned
|
||||
|
||||
void LianLiUniHubSLV2Controller::SendCommitAction(unsigned char channel, unsigned char effect, unsigned char speed, unsigned int direction, unsigned int brightness)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
unsigned char usb_buf[353];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
|
||||
+2
-2
@@ -66,7 +66,7 @@ std::string LianLiUniversalScreenController::GetVersion()
|
||||
|
||||
void LianLiUniversalScreenController::SetLedColors(RGBColor* colors, size_t count)
|
||||
{
|
||||
unsigned char leds_in_packet = 20;
|
||||
std::size_t leds_in_packet = 20;
|
||||
unsigned char offset = 0;
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
@@ -91,7 +91,7 @@ void LianLiUniversalScreenController::SetLedColors(RGBColor* colors, size_t coun
|
||||
usb_buf[6 + (led_idx * 3)] = RGBGetBValue(colors[offset + led_idx]);
|
||||
}
|
||||
|
||||
offset += leds_in_packet;
|
||||
offset += (unsigned char)leds_in_packet;
|
||||
|
||||
int actual_length = sizeof(usb_buf);
|
||||
libusb_bulk_transfer(dev, 1, usb_buf, sizeof(usb_buf), &actual_length, 25);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user