From f4c4d13f6d914e8a2837fb6ae306f7fa87de9caa Mon Sep 17 00:00:00 2001 From: morg Date: Thu, 30 Dec 2021 13:48:53 +0100 Subject: [PATCH] Add support for Corsair K55 RGB PRO keyboard --- .../CorsairK55RGBPROController.cpp | 106 ++++++++++++++ .../CorsairK55RGBPROController.h | 35 +++++ .../CorsairPeripheralControllerDetect.cpp | 26 ++++ .../RGBController_CorsairK55RGBPRO.cpp | 135 ++++++++++++++++++ .../RGBController_CorsairK55RGBPRO.h | 33 +++++ OpenRGB.pro | 6 +- 6 files changed, 340 insertions(+), 1 deletion(-) create mode 100644 Controllers/CorsairPeripheralController/CorsairK55RGBPROController.cpp create mode 100644 Controllers/CorsairPeripheralController/CorsairK55RGBPROController.h create mode 100644 Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPRO.cpp create mode 100644 Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPRO.h diff --git a/Controllers/CorsairPeripheralController/CorsairK55RGBPROController.cpp b/Controllers/CorsairPeripheralController/CorsairK55RGBPROController.cpp new file mode 100644 index 00000000..fbfe9eac --- /dev/null +++ b/Controllers/CorsairPeripheralController/CorsairK55RGBPROController.cpp @@ -0,0 +1,106 @@ +#include "CorsairK55RGBPROController.h" +/*-----------------------------------------*\ +| CorsairK55RGBPROController.cpp | +| | +| Driver for Corsair K55 RGB PRO Keyboard | +\*-----------------------------------------*/ + +#include "LogManager.h" + +CorsairK55RGBPROController::CorsairK55RGBPROController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; + + LightingControl(); +} + +CorsairK55RGBPROController::~CorsairK55RGBPROController() +{ + hid_close(dev); +} + +std::string CorsairK55RGBPROController::GetDeviceLocation() +{ + return("HID: " + location); +} + +std::string CorsairK55RGBPROController::GetFirmwareString() +{ + return ""; +} + +std::string CorsairK55RGBPROController::GetName() +{ + return name; +} + +void CorsairK55RGBPROController::SetName(std::string device_name) +{ + name = device_name; +} + +std::string CorsairK55RGBPROController::GetSerialString() +{ + wchar_t serial_string[128]; + int ret = hid_get_serial_number_string(dev, serial_string, 128); + + if(ret != 0) + { + return(""); + } + + std::wstring return_wstring = serial_string; + std::string return_string(return_wstring.begin(), return_wstring.end()); + + return(return_string); +} + +void CorsairK55RGBPROController::LightingControl() +{ + unsigned char usb_buf[65]; + memset(usb_buf, 0x00, sizeof(usb_buf)); + //This is requered + usb_buf[0x01] = 0x08; + usb_buf[0x02] = 0x01; + usb_buf[0x03] = 0x03; + usb_buf[0x05] = 0x02; + + hid_write(dev, (unsigned char *)usb_buf, 65); + + memset(usb_buf, 0x00, sizeof(usb_buf)); + + usb_buf[0x01] = 0x08; + usb_buf[0x02] = 0x02; + usb_buf[0x03] = 0x5F; + + hid_write(dev, (unsigned char *)usb_buf, 65); + + memset(usb_buf, 0x00, sizeof(usb_buf)); + + usb_buf[0x01] = 0x08; + usb_buf[0x02] = 0x0D; + usb_buf[0x04] = 0x01; + + hid_write(dev, (unsigned char *)usb_buf, 65); +} + +void CorsairK55RGBPROController::SetLEDs(std::vectorcolors) +{ + unsigned char usb_buf[65]; + memset(usb_buf, 0x00, sizeof(usb_buf)); + + usb_buf[0x01] = 0x08; + usb_buf[0x02] = 0x06; + usb_buf[0x04] = 0x12; + + for(std::size_t color_idx = 0; color_idx < colors.size(); color_idx++) + { + RGBColor color = colors[color_idx]; + usb_buf[9 + color_idx] = RGBGetRValue(color); + usb_buf[15 + color_idx] = RGBGetGValue(color); + usb_buf[21 + color_idx] = RGBGetBValue(color); + } + + hid_write(dev, (unsigned char *)usb_buf, 65); +} diff --git a/Controllers/CorsairPeripheralController/CorsairK55RGBPROController.h b/Controllers/CorsairPeripheralController/CorsairK55RGBPROController.h new file mode 100644 index 00000000..e2370c43 --- /dev/null +++ b/Controllers/CorsairPeripheralController/CorsairK55RGBPROController.h @@ -0,0 +1,35 @@ +#ifndef CORSAIRK55RGBPROCONTROLLER_H +#define CORSAIRK55RGBPROCONTROLLER_H + +#include "RGBController.h" + +#include +#include + +class CorsairK55RGBPROController +{ +public: + CorsairK55RGBPROController(hid_device* dev_handle, const char* path); + ~CorsairK55RGBPROController(); + std::string GetDeviceLocation(); + std::string GetFirmwareString(); + std::string GetName(); + std::string GetSerialString(); + + void SetLEDs(std::vector colors); + void SetLEDsKeyboardLimited(std::vector 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 LightingControl(); + void SetLEDsKeyboardFull(std::vector colors); +}; + +#endif // CORSAIRK55RGBPROCONTROLLER_H diff --git a/Controllers/CorsairPeripheralController/CorsairPeripheralControllerDetect.cpp b/Controllers/CorsairPeripheralController/CorsairPeripheralControllerDetect.cpp index f382bf0f..aa02086c 100644 --- a/Controllers/CorsairPeripheralController/CorsairPeripheralControllerDetect.cpp +++ b/Controllers/CorsairPeripheralController/CorsairPeripheralControllerDetect.cpp @@ -1,10 +1,12 @@ #include "Detector.h" #include "CorsairPeripheralController.h" #include "CorsairK100Controller.h" +#include "CorsairK55RGBPROController.h" #include "LogManager.h" #include "RGBController.h" #include "RGBController_CorsairPeripheral.h" #include "RGBController_CorsairK100.h" +#include "RGBController_CorsairK55RGBPRO.h" #include #define CORSAIR_PERIPHERAL_CONTROLLER_NAME "Corsair peripheral" @@ -95,6 +97,25 @@ void DetectCorsairK100Controllers(hid_device_info* info, const std::string& name } } /* DetectCorsairPeripheralControllers() */ +/*-----------------------------------------------------*\ +| Corsair K55 RGB PRO Keyboard product ID | +| This keyboard uses a separate driver | +\*-----------------------------------------------------*/ +#define CORSAIR_K55_RGB_PRO_PID 0x1BA4 + +void DetectCorsairK55RGBPROControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + CorsairK55RGBPROController* controller = new CorsairK55RGBPROController(dev, info->path); + controller->SetName(name); + RGBController_CorsairK55RGBPRO* rgb_controller = new RGBController_CorsairK55RGBPRO(controller); + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} /* DetectCorsairK55RGBPROControllers() */ + /******************************************************************************************\ * * * DetectCorsairPeripheralControllers * @@ -180,3 +201,8 @@ REGISTER_HID_DETECTOR_I("Corsair ST100 RGB", DetectCorsairPeriphe | Corsair K100 Keyboard | \*-----------------------------------------------------------------------------------------------------*/ REGISTER_HID_DETECTOR_IP("Corsair K100", DetectCorsairK100Controllers, CORSAIR_VID, CORSAIR_K100_PID, 1, 0xFF42); + +/*-----------------------------------------------------------------------------------------------------*\ +| Corsair K55 RGB PRO Keyboard | +\*-----------------------------------------------------------------------------------------------------*/ +REGISTER_HID_DETECTOR_IP("Corsair K55 RGB PRO", DetectCorsairK55RGBPROControllers, CORSAIR_VID, CORSAIR_K55_RGB_PRO_PID, 1, 0xFF42); diff --git a/Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPRO.cpp b/Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPRO.cpp new file mode 100644 index 00000000..979165db --- /dev/null +++ b/Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPRO.cpp @@ -0,0 +1,135 @@ +#include "RGBController_CorsairK55RGBPRO.h" +/*-----------------------------------------*\ +| RGBController_CorsairK55RGBPRO.cpp | +| | +| Driver for Corsair K55 RGB PRO0 Keyboard | +\*-----------------------------------------*/ + +#include "LogManager.h" + +using namespace std::chrono_literals; + +RGBController_CorsairK55RGBPRO::RGBController_CorsairK55RGBPRO(CorsairK55RGBPROController* corsair_ptr) +{ + corsair = corsair_ptr; + + name = corsair->GetName(); + vendor = "Corsair"; + description = "Corsair K55 RGB PRO Keyboard Device"; + type = DEVICE_TYPE_KEYBOARD; + version = corsair->GetFirmwareString(); + location = corsair->GetDeviceLocation(); + serial = corsair->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 K55 RGB PRO requires a packet within | + | 1 minutes of sending the lighting change in order | + | to not revert back into rainbow mode. Start a thread | + | to continuously send a keepalive packet every 50 sec | + \*-----------------------------------------------------*/ + keepalive_thread_run = true; + keepalive_thread = new std::thread(&RGBController_CorsairK55RGBPRO::KeepaliveThread, this); +} + +RGBController_CorsairK55RGBPRO::~RGBController_CorsairK55RGBPRO() +{ + /*-----------------------------------------------------*\ + | 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].type == ZONE_TYPE_MATRIX) + { + delete zones[zone_index].matrix_map; + } + } + + delete corsair; +} + +void RGBController_CorsairK55RGBPRO::SetupZones() +{ + zone new_zone; + + new_zone.name = "Keyboard"; + new_zone.type = ZONE_TYPE_LINEAR; + new_zone.leds_min = 5; + new_zone.leds_max = 5; + new_zone.leds_count = 5; + new_zone.matrix_map = NULL; + + for(unsigned int led_idx = 0; led_idx < new_zone.leds_count; led_idx++) + { + led new_led; + new_led.name = "Zone " + std::to_string( led_idx ); + leds.push_back(new_led); + } + + zones.push_back(new_zone); + + SetupColors(); +} + +void RGBController_CorsairK55RGBPRO::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_CorsairK55RGBPRO::DeviceUpdateLEDs() +{ + last_update_time = std::chrono::steady_clock::now(); + + corsair->SetLEDs(colors); +} + +void RGBController_CorsairK55RGBPRO::UpdateZoneLEDs(int /*zone*/) +{ + corsair->SetLEDs(colors); +} + +void RGBController_CorsairK55RGBPRO::UpdateSingleLED(int /*led*/) +{ + corsair->SetLEDs(colors); +} + +void RGBController_CorsairK55RGBPRO::SetCustomMode() +{ + active_mode = 0; +} + +void RGBController_CorsairK55RGBPRO::DeviceUpdateMode() +{ + +} + +void RGBController_CorsairK55RGBPRO::KeepaliveThread() +{ + while(keepalive_thread_run.load()) + { + if(active_mode == 0) + { + if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(50000)) + { + DeviceUpdateLEDs(); + } + } + std::this_thread::sleep_for(3000ms); + } +} diff --git a/Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPRO.h b/Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPRO.h new file mode 100644 index 00000000..8c3284fe --- /dev/null +++ b/Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPRO.h @@ -0,0 +1,33 @@ +#ifndef RGBCONTROLLER_CORSAIRK55RGBPRO_H +#define RGBCONTROLLER_CORSAIRK55RGBPRO_H + +#include "RGBController.h" +#include "CorsairK55RGBPROController.h" + +class RGBController_CorsairK55RGBPRO : public RGBController +{ +public: + RGBController_CorsairK55RGBPRO(CorsairK55RGBPROController* corsair_ptr); + ~RGBController_CorsairK55RGBPRO(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + void SetCustomMode(); + void KeepaliveThread(); + +private: + CorsairK55RGBPROController* corsair; + + std::thread* keepalive_thread; + std::atomic keepalive_thread_run; + std::chrono::time_point last_update_time; + +}; + +#endif // RGBCONTROLLER_CORSAIRK55RGBPRO_H diff --git a/OpenRGB.pro b/OpenRGB.pro index a555464b..e7750083 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -268,9 +268,11 @@ HEADERS += Controllers/CorsairLightingNodeController/CorsairLightingNodeController.h \ Controllers/CorsairLightingNodeController/RGBController_CorsairLightingNode.h \ Controllers/CorsairPeripheralController/CorsairPeripheralController.h \ - Controllers/CorsairPeripheralController/CorsairK100Controller.h \ + Controllers/CorsairPeripheralController/CorsairK100Controller.h \ + Controllers/CorsairPeripheralController/CorsairK55RGBPROController.h \ Controllers/CorsairPeripheralController/RGBController_CorsairPeripheral.h \ Controllers/CorsairPeripheralController/RGBController_CorsairK100.h \ + Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPRO.h \ Controllers/CorsairVengeanceController/CorsairVengeanceController.h \ Controllers/CorsairVengeanceController/RGBController_CorsairVengeance.h \ Controllers/CorsairVengeanceProController/CorsairVengeanceProController.h \ @@ -648,8 +650,10 @@ SOURCES += Controllers/CorsairPeripheralController/CorsairPeripheralController.cpp \ Controllers/CorsairPeripheralController/CorsairPeripheralControllerDetect.cpp \ Controllers/CorsairPeripheralController/CorsairK100Controller.cpp \ + Controllers/CorsairPeripheralController/CorsairK55RGBPROController.cpp \ Controllers/CorsairPeripheralController/RGBController_CorsairPeripheral.cpp \ Controllers/CorsairPeripheralController/RGBController_CorsairK100.cpp \ + Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPRO.cpp \ Controllers/CorsairVengeanceController/CorsairVengeanceController.cpp \ Controllers/CorsairVengeanceController/CorsairVengeanceControllerDetect.cpp \ Controllers/CorsairVengeanceController/RGBController_CorsairVengeance.cpp \