Initial commit for the Corsair M55 mouse

* Added config to CorsairPeripheralV2Devices
* Adding device config to CorsairPeripheralV2Devices.cpp
* Extending the base CorsairPeripheralV2Controller to CorsairPeripheralV2HWController to account for HW modes
* Minor adjustments to the CorsairPeripheralV2SWController to accommodate
* Resolves #1951
This commit is contained in:
Chris 2023-03-12 17:40:09 +11:00
parent 549a631541
commit baf5d30b27
12 changed files with 569 additions and 49 deletions

View file

@ -9,6 +9,8 @@
#include "CorsairPeripheralV2Controller.h"
using namespace std::chrono_literals;
CorsairPeripheralV2Controller::CorsairPeripheralV2Controller(hid_device* dev_handle, const char* path, std::string /*name*/, uint16_t pid)
{
const uint8_t sz = HID_MAX_STR;
@ -33,14 +35,29 @@ CorsairPeripheralV2Controller::CorsairPeripheralV2Controller(hid_device* dev_han
| Set device ID |
\*---------------------------------------------------------*/
device_index = i;
write_cmd = CORSAIR_V2_WRITE_ID + corsair_v2_device_list[device_index]->wireless;
}
}
/*---------------------------------------------------------*\
| Possibly is Wireless connected? |
| NB: If the device is not found in the device list |
| then wireless mode may not work reliably |
\*---------------------------------------------------------*/
bool wireless = corsair_v2_device_list[device_index]->wireless;
if(wireless)
{
write_cmd = CORSAIR_V2_WRITE_WIRELESS_ID;
}
LOG_DEBUG("[%s] Setting write CMD to %02X for %s mode", device_name.c_str(),
write_cmd, (wireless) ? "wireless" : "wired" );
/*---------------------------------------------------------*\
| Get VID |
\*---------------------------------------------------------*/
GetAddress(0x11);
/*---------------------------------------------------------*\
| Get PID |
\*---------------------------------------------------------*/
GetAddress(0x12);
}
CorsairPeripheralV2Controller::~CorsairPeripheralV2Controller()
@ -102,6 +119,8 @@ void CorsairPeripheralV2Controller::SetRenderMode(corsair_v2_device_mode mode)
buffer[5] = mode;
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
std::this_thread::sleep_for(2ms);
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
}
void CorsairPeripheralV2Controller::LightingControl(uint8_t opt1, uint8_t opt2)
@ -121,6 +140,8 @@ void CorsairPeripheralV2Controller::LightingControl(uint8_t opt1, uint8_t opt2)
buffer[5] = 0x00;
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
std::this_thread::sleep_for(2ms);
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
/*---------------------------------------------------------*\
| Open a RGB lighting handle |
@ -131,6 +152,8 @@ void CorsairPeripheralV2Controller::LightingControl(uint8_t opt1, uint8_t opt2)
buffer[5] = opt2;
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
std::this_thread::sleep_for(2ms);
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
}
void CorsairPeripheralV2Controller::GetAddress(uint8_t address)
@ -146,7 +169,8 @@ void CorsairPeripheralV2Controller::GetAddress(uint8_t address)
buffer[3] = address;
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
hid_read(dev, read, CORSAIR_V2_WRITE_SIZE);
std::this_thread::sleep_for(2ms);
hid_read_timeout(dev, read, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
LOG_DEBUG("[%s] GetAddress %02X - %02X %02X - %02X %02X %02X %02X %02X %02X %02X %02X", device_name.c_str(),
address, read[0], read[1], read[2], read[3], read[4], read[5], read[6], read[7], read[8], read[9]);
@ -164,6 +188,8 @@ void CorsairPeripheralV2Controller::StartTransaction(uint8_t opt1)
buffer[4] = 0x01;
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
std::this_thread::sleep_for(2ms);
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
}
void CorsairPeripheralV2Controller::StopTransaction(uint8_t opt1)
@ -178,6 +204,8 @@ void CorsairPeripheralV2Controller::StopTransaction(uint8_t opt1)
buffer[4] = opt1;
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
std::this_thread::sleep_for(2ms);
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
}
void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
@ -211,6 +239,8 @@ void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
memcpy(&buffer[offset1], &data[0], copy_bytes);
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
std::this_thread::sleep_for(2ms);
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
remaining -= copy_bytes;
buffer[2] = CORSAIR_V2_CMD_BLK_WN;
@ -231,6 +261,8 @@ void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
memcpy(&buffer[offset2], &data[index], copy_bytes);
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
std::this_thread::sleep_for(2ms);
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
remaining -= copy_bytes;
}

View file

@ -16,48 +16,50 @@
#include "RGBController.h"
#include "CorsairPeripheralV2Devices.h"
#define NA 0xFFFFFFFF
#define HID_MAX_STR 255
#define NA 0xFFFFFFFF
#define HID_MAX_STR 255
#define CORSAIR_V2_WRITE_ID 8
#define CORSAIR_V2_VALUE_MODE 3
#define CORSAIR_V2_WRITE_SIZE 65
#define CORSAIR_V2_TIMEOUT 100
#define CORSAIR_V2_VALUE_MODE 3
#define CORSAIR_V2_WRITE_WIRED_ID 8
#define CORSAIR_V2_WRITE_WIRELESS_ID 9
#define CORSAIR_V2_WRITE_SIZE 65
#define CORSAIR_V2_BRIGHTNESS_MIN 0
#define CORSAIR_V2_BRIGHTNESS_MAX 0xFF
#define CORSAIR_V2_BRIGHTNESS_MIN 0
#define CORSAIR_V2_BRIGHTNESS_MAX 0xFF
enum corsair_v2_cmd
{
CORSAIR_V2_CMD_SET = 0x01, /* Command for setting values */
CORSAIR_V2_CMD_GET = 0x02, /* Command for getting values */
CORSAIR_V2_CMD_STOP_TX = 0x05, /* Finish Transaction */
CORSAIR_V2_CMD_BLK_W1 = 0x06, /* Block write packet 1 */
CORSAIR_V2_CMD_BLK_WN = 0x07, /* Block write remaining packets */
CORSAIR_V2_CMD_START_TX = 0x0D, /* Start Transaction */
CORSAIR_V2_CMD_SET = 0x01, /* Command for setting values */
CORSAIR_V2_CMD_GET = 0x02, /* Command for getting values */
CORSAIR_V2_CMD_STOP_TX = 0x05, /* Finish Transaction */
CORSAIR_V2_CMD_BLK_W1 = 0x06, /* Block write packet 1 */
CORSAIR_V2_CMD_BLK_WN = 0x07, /* Block write remaining packets */
CORSAIR_V2_CMD_START_TX = 0x0D, /* Start Transaction */
};
enum corsair_v2_mode
{
CORSAIR_V2_MODE_DIRECT = 0x0000,
CORSAIR_V2_MODE_STATIC = 0x207E,
CORSAIR_V2_MODE_FLASHING = 0xAD4F,
CORSAIR_V2_MODE_BREATHING = 0xA5FA,
CORSAIR_V2_MODE_SPECTRUM = 0x7BFF,
CORSAIR_V2_MODE_RAINBOW = 0xB94C,
CORSAIR_V2_MODE_RAIN = 0xA07E,
CORSAIR_V2_MODE_SPIRAL = 0xAB87,
CORSAIR_V2_MODE_WATERCOLOR = 0x0022,
CORSAIR_V2_MODE_REACTIVE = 0xB1F9,
CORSAIR_V2_MODE_RIPPLE = 0x09A2,
CORSAIR_V2_MODE_VISOR = 0x90C0
CORSAIR_V2_MODE_DIRECT = 0x0012,
CORSAIR_V2_MODE_STATIC = 0x207E,
CORSAIR_V2_MODE_FLASHING = 0xAD4F,
CORSAIR_V2_MODE_BREATHING = 0xA5FA,
CORSAIR_V2_MODE_SPECTRUM = 0x7BFF,
CORSAIR_V2_MODE_RAINBOW = 0xB94C,
CORSAIR_V2_MODE_RAIN = 0xA07E,
CORSAIR_V2_MODE_SPIRAL = 0xAB87,
CORSAIR_V2_MODE_WATERCOLOR = 0x0022,
CORSAIR_V2_MODE_REACTIVE = 0xB1F9,
CORSAIR_V2_MODE_RIPPLE = 0x09A2,
CORSAIR_V2_MODE_VISOR = 0x90C0
};
enum corsair_v2_color
{
CORSAIR_V2_COLOR_NONE = 0x00,
CORSAIR_V2_COLOR_SPECIFIC = 0x01,
CORSAIR_V2_COLOR_RANDOM = 0x02,
CORSAIR_V2_COLOR_UNKNOWN = 0x03
CORSAIR_V2_COLOR_NONE = 0x00,
CORSAIR_V2_COLOR_SPECIFIC = 0x01,
CORSAIR_V2_COLOR_RANDOM = 0x02,
CORSAIR_V2_COLOR_UNKNOWN = 0x03
};
@ -80,6 +82,11 @@ public:
uint8_t direction, uint8_t brightness, std::vector<RGBColor> colors);
virtual void SetLedsDirect(std::vector<RGBColor *> colors) = 0;
protected:
uint16_t device_index;
std::string device_name;
private:
void GetAddress(uint8_t address);
void StartTransaction(uint8_t opt1);
@ -87,9 +94,7 @@ private:
hid_device* dev;
uint8_t write_cmd;
uint16_t device_index;
uint8_t write_cmd = CORSAIR_V2_WRITE_WIRED_ID;
std::string firmware_version;
std::string location;
std::string device_name;
};

View file

@ -10,6 +10,7 @@
| Corsair Peripheral specific includes |
\*-----------------------------------------------------*/
#include "CorsairPeripheralV2Devices.h"
#include "RGBController_CorsairV2Hardware.h"
#include "RGBController_CorsairV2Software.h"
#define CORSAIR_PERIPHERAL_CONTROLLER_NAME "Corsair V2 Peripheral"
@ -19,6 +20,19 @@
\*-----------------------------------------------------*/
#define CORSAIR_VID 0x1B1C
void DetectCorsairV2HardwareControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CorsairPeripheralV2HWController* controller = new CorsairPeripheralV2HWController(dev, info->path, name, info->product_id);
RGBController_CorsairV2HW* rgb_controller = new RGBController_CorsairV2HW(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
} /* DetectCorsairV2SoftwareControllers() */
void DetectCorsairV2SoftwareControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
@ -41,10 +55,11 @@ REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO", DetectCorsairV2S
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO Low Profile", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_LP_PID, 1, 0xFF42);
/*-----------------------------------------------------------------------------------------------------*\
| Mousemat |
| Mice |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP("Corsair Ironclaw Wireless", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_IRONCLAW_WIRELESS_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair Ironclaw Wireless (Wired)", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_IRONCLAW_WIRELESS_WIRED_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair M55 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_M55_RGB_PRO_PID, 1, 0xFF42);
/*-----------------------------------------------------------------------------------------------------*\
| Mousemat |

View file

@ -176,7 +176,7 @@ static const corsair_v2_device ironclaw_wired_device =
CORSAIR_IRONCLAW_WIRELESS_WIRED_PID,
false,
DEVICE_TYPE_MOUSE,
CORSAIR_V2_MODE_SW,
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK,
1,
6,
{
@ -196,7 +196,7 @@ static const corsair_v2_device ironclaw_wireless_device =
CORSAIR_IRONCLAW_WIRELESS_PID,
true,
DEVICE_TYPE_MOUSE,
CORSAIR_V2_MODE_SW,
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK,
1,
6,
{
@ -231,7 +231,7 @@ static const corsair_v2_device k55_rgb_pro_device =
CORSAIR_K55_RGB_PRO_PID,
false,
DEVICE_TYPE_KEYBOARD,
CORSAIR_V2_MODE_SW,
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK,
1,
6,
{
@ -266,7 +266,7 @@ static const corsair_v2_device k60_rgb_pro_device =
CORSAIR_K60_RGB_PRO_PID,
false,
DEVICE_TYPE_KEYBOARD,
CORSAIR_V2_MODE_SW,
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK,
6,
21,
{
@ -301,7 +301,7 @@ static const corsair_v2_device k60_rgb_pro_lp_device =
CORSAIR_K60_RGB_PRO_LP_PID,
false,
DEVICE_TYPE_KEYBOARD,
CORSAIR_V2_MODE_SW,
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK,
6,
21,
{
@ -316,6 +316,52 @@ static const corsair_v2_device k60_rgb_pro_lp_device =
K60_KEYMAP_SIZE
};
/*-------------------------------------------------------------*\
| Corsair M55 1B1C:1B70 |
| |
| Zone "Logo" |
| Single |
| |
| Zone "Edge" |
| Linear |
| 1 Row, 2 Columns |
\*-------------------------------------------------------------*/
static const corsair_v2_zone m55_mid_zone =
{
"Middle Button",
ZONE_TYPE_SINGLE,
1,
1
};
static const corsair_v2_zone m55_logo_zone =
{
"Logo",
ZONE_TYPE_SINGLE,
1,
1
};
static const corsair_v2_device m55_device =
{
CORSAIR_M55_RGB_PRO_PID,
false,
DEVICE_TYPE_MOUSE,
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK,
1,
2,
{
&m55_mid_zone,
&m55_logo_zone,
nullptr,
nullptr,
nullptr,
nullptr
},
nullptr,
0
};
/*-------------------------------------------------------------*\
| Corsair MM700 1B1C:1B9B |
| |
@ -355,7 +401,7 @@ static const corsair_v2_device mm700_device =
CORSAIR_MM700_PID,
false,
DEVICE_TYPE_MOUSEMAT,
CORSAIR_V2_MODE_SW,
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK,
1,
3,
{
@ -387,6 +433,7 @@ const corsair_v2_device* corsair_v2_device_list_data[] =
\*-----------------------------------------------------------------*/
&ironclaw_wired_device,
&ironclaw_wireless_device,
&m55_device,
/*-----------------------------------------------------------------*\
| MOUSEMATS |

View file

@ -12,6 +12,14 @@ enum corsair_v2_device_mode
CORSAIR_V2_MODE_SW = 0x02, /* Software RGB mode */
};
enum corsair_v2_supports
{
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK = 1,
CORSAIR_V2_TYPE_HW_COLOUR_BLOCK = 2,
CORSAIR_V2_TYPE_SW_TRIPLETS = 3,
CORSAIR_V2_TYPE_HW_TRIPLETS = 4,
};
typedef struct
{
std::string name;
@ -34,7 +42,7 @@ typedef struct
uint16_t pid;
bool wireless;
device_type type;
uint8_t supports;
corsair_v2_supports protocol;
uint8_t rows;
uint8_t cols;
const corsair_v2_zone* zones[CORSAIR_ZONES_MAX];
@ -54,6 +62,7 @@ typedef struct
\*-----------------------------------------------------*/
#define CORSAIR_IRONCLAW_WIRELESS_PID 0x1BA6
#define CORSAIR_IRONCLAW_WIRELESS_WIRED_PID 0x1B4C
#define CORSAIR_M55_RGB_PRO_PID 0x1B70
/*-----------------------------------------------------*\
| Corsair V2 Protocol Mousemats |

View file

@ -0,0 +1,89 @@
/*---------------------------------------------------------------------*\
| CorsairPeripheralV2HardwareController.cpp |
| |
| Driver for the newer Corsair peripherals that use the '08' |
| based USB protocol and support hardware lighting modes. |
| |
| Chris M (Dr_No) 07 Dec 2022 |
\*---------------------------------------------------------------------*/
#include "LogManager.h"
#include "CorsairPeripheralV2HardwareController.h"
CorsairPeripheralV2HWController::CorsairPeripheralV2HWController(hid_device* dev_handle, const char* path, std::string name, uint16_t pid) : CorsairPeripheralV2Controller(dev_handle, path, name, pid)
{
SetRenderMode(CORSAIR_V2_MODE_SW);
LightingControl(0x5F, 0x00);
}
CorsairPeripheralV2HWController::~CorsairPeripheralV2HWController()
{
}
void CorsairPeripheralV2HWController::SetLedsDirect(std::vector<RGBColor *>colors)
{
switch(corsair_v2_device_list[device_index]->protocol)
{
case CORSAIR_V2_TYPE_HW_TRIPLETS:
SetLedsDirectTriplets(colors);
break;
case CORSAIR_V2_TYPE_HW_COLOUR_BLOCK:
SetLedsDirectColourBlocks(colors);
break;
default:
LOG_ERROR("[%s] Error setting Direct mode: Device supportes returned %i", device_name.c_str(),
corsair_v2_device_list[device_index]->protocol);
break;
}
}
void CorsairPeripheralV2HWController::SetLedsDirectColourBlocks(std::vector<RGBColor *>colors)
{
uint16_t count = colors.size();
uint16_t green = count + CORSAIR_V2HW_DATA_OFFSET;
uint16_t blue = (count * 2) + CORSAIR_V2HW_DATA_OFFSET;
uint16_t length = (count * 3) + CORSAIR_V2HW_DATA_OFFSET;
uint8_t* buffer = new uint8_t[length];
memset(buffer, 0, length);
buffer[0] = CORSAIR_V2_MODE_DIRECT & 0xFF;
buffer[1] = CORSAIR_V2_MODE_DIRECT >> 8;
for(std::size_t i = 0; i < count; i++)
{
RGBColor color = *colors[i];
std::size_t idx = i + CORSAIR_V2HW_DATA_OFFSET;
buffer[idx] = RGBGetRValue(color);
buffer[idx + green] = RGBGetGValue(color);
buffer[idx + blue] = RGBGetBValue(color);
}
SetLEDs(buffer, length);
delete[] buffer;
}
void CorsairPeripheralV2HWController::SetLedsDirectTriplets(std::vector<RGBColor *>colors)
{
uint16_t count = colors.size();
uint16_t length = (count * 3) + CORSAIR_V2HW_DATA_OFFSET;
uint8_t* buffer = new uint8_t[length];
memset(buffer, 0, length);
buffer[0] = CORSAIR_V2_MODE_DIRECT & 0xFF;
buffer[1] = CORSAIR_V2_MODE_DIRECT >> 8;
for(std::size_t i = 0; i < count; i++)
{
RGBColor color = *colors[i];
std::size_t idx = (i * 3) + CORSAIR_V2HW_DATA_OFFSET;
buffer[idx] = RGBGetRValue(color);
buffer[idx + 1] = RGBGetGValue(color);
buffer[idx + 2] = RGBGetBValue(color);
}
SetLEDs(buffer, length);
delete[] buffer;
}

View file

@ -0,0 +1,32 @@
/*---------------------------------------------------------------------*\
| CorsairPeripheralV2HardwareController.h |
| |
| Driver for the newer Corsair peripherals that use the '08' |
| based USB protocol and support hardware lighting modes. |
| |
| Chris M (Dr_No) 07 Dec 2022 |
\*---------------------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CorsairPeripheralV2Controller.h"
#include <string>
#include <hidapi/hidapi.h>
#undef CORSAIR_V2_WRITE_SIZE
#define CORSAIR_V2_WRITE_SIZE 1025
#define CORSAIR_V2HW_DATA_OFFSET 2
class CorsairPeripheralV2HWController : public CorsairPeripheralV2Controller
{
public:
CorsairPeripheralV2HWController(hid_device* dev_handle, const char* path, std::string name, uint16_t pid);
~CorsairPeripheralV2HWController();
void SetLedsDirect(std::vector<RGBColor *> colors);
private:
void SetLedsDirectColourBlocks(std::vector<RGBColor *> colors);
void SetLedsDirectTriplets(std::vector<RGBColor *> colors);
};

View file

@ -0,0 +1,247 @@
/*---------------------------------------------------------------------*\
| RGBController_CorsairV2HardwareController.cpp |
| |
| Driver for the newer Corsair peripherals that use the '08' |
| based USB protocol and support hardware lighting modes. |
| |
| Chris M (Dr_No) 10 Dec 2022 |
\*---------------------------------------------------------------------*/
#include "LogManager.h"
#include "RGBController_CorsairV2Hardware.h"
using namespace std::chrono_literals;
/**------------------------------------------------------------------*\
@name Corsair Peripherals V2 Hardware
@category Keyboard
@type USB
@save :robot:
@direct :white_check_mark:
@effects :white_check_mark:
@detectors DetectCorsairV2HardwareControllers
@comment
\*-------------------------------------------------------------------*/
RGBController_CorsairV2HW::RGBController_CorsairV2HW(CorsairPeripheralV2Controller *controller_ptr)
{
controller = controller_ptr;
const corsair_v2_device* corsair = controller->GetDeviceData();
vendor = "Corsair";
description = controller->GetName();
type = corsair->type;
version = controller->GetFirmwareString();
location = controller->GetDeviceLocation();
serial = controller->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = CORSAIR_V2_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Static;
Static.name = "Static";
Static.value = CORSAIR_V2_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 = CORSAIR_V2_BRIGHTNESS_MIN;
Static.brightness_max = CORSAIR_V2_BRIGHTNESS_MAX;
Static.brightness = CORSAIR_V2_BRIGHTNESS_MAX;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
modes.push_back(Static);
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_CorsairV2HW::KeepaliveThread, this);
}
RGBController_CorsairV2HW::~RGBController_CorsairV2HW()
{
/*-----------------------------------------------------*\
| 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 controller;
}
void RGBController_CorsairV2HW::SetupZones()
{
unsigned int max_led_value = 0;
const corsair_v2_device* corsair = controller->GetDeviceData();
/*---------------------------------------------------------*\
| Fill in zones from the device data |
\*---------------------------------------------------------*/
for(size_t i = 0; i < CORSAIR_ZONES_MAX; i++)
{
if(corsair->zones[i] == NULL)
{
break;
}
else
{
zone new_zone;
new_zone.name = corsair->zones[i]->name;
new_zone.type = corsair->zones[i]->type;
if(new_zone.type == ZONE_TYPE_MATRIX)
{
new_zone.leds_count = corsair->layout_size;
matrix_map_type * new_map = new matrix_map_type;
new_zone.matrix_map = new_map;
new_map->height = corsair->zones[i]->rows;
new_map->width = corsair->zones[i]->cols;
new_map->map = new unsigned int[new_map->height * new_map->width];
/*---------------------------------------------------------*\
| Create an empty matrix |
\*---------------------------------------------------------*/
for(unsigned int y = 0; y < new_map->height; y++)
{
for(unsigned int x = 0; x < new_map->width; x++)
{
new_map->map[(y * new_map->width) + x] = NA;
}
}
/*---------------------------------------------------------*\
| Create LEDs for the Matrix zone |
| Place keys in the layout to populate the matrix |
\*---------------------------------------------------------*/
for(size_t led_idx = 0; led_idx < new_zone.leds_count; led_idx++)
{
led new_led;
new_led.name = corsair->layout[led_idx].name;
new_led.value = corsair->layout[led_idx].index;
max_led_value = std::max(max_led_value, new_led.value);
leds.push_back(new_led);
uint8_t layout_index = (corsair->layout[led_idx].row * new_map->width)
+ corsair->layout[led_idx].col;
new_map->map[layout_index] = led_idx;
}
/*---------------------------------------------------------*\
| Add 1 the max_led_value to account for the 0th index |
\*---------------------------------------------------------*/
max_led_value++;
}
else
{
new_zone.leds_count = corsair->zones[i]->rows * corsair->zones[i]->cols;
new_zone.matrix_map = NULL;
/*---------------------------------------------------------*\
| Create LEDs for the Linear / Single zone |
\*---------------------------------------------------------*/
for(size_t led_idx = 0; led_idx < new_zone.leds_count; led_idx++)
{
led new_led;
new_led.name = new_zone.name + " ";
new_led.name.append(std::to_string( led_idx ));
new_led.value = leds.size();
leds.push_back(new_led);
}
max_led_value = std::max(max_led_value, (unsigned int)leds.size());
}
LOG_DEBUG("[%s] Creating a %s zone: %s with %d LEDs", name.c_str(),
((new_zone.type == ZONE_TYPE_MATRIX) ? "matrix": "linear"),
new_zone.name.c_str(), new_zone.leds_count);
new_zone.leds_min = new_zone.leds_count;
new_zone.leds_max = new_zone.leds_count;
zones.push_back(new_zone);
}
}
SetupColors();
/*---------------------------------------------------------*\
| Create a buffer map of pointers which contains the |
| layout order of colors the device expects. |
\*---------------------------------------------------------*/
for(size_t led_idx = 0; led_idx < max_led_value; led_idx++)
{
buffer_map.push_back(&null_color);
}
for(size_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
buffer_map[leds[led_idx].value] = &colors[led_idx];
}
}
void RGBController_CorsairV2HW::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_CorsairV2HW::DeviceUpdateLEDs()
{
last_update_time = std::chrono::steady_clock::now();
controller->SetLedsDirect(buffer_map);
}
void RGBController_CorsairV2HW::UpdateZoneLEDs(int /*zone*/)
{
controller->SetLedsDirect(buffer_map);
}
void RGBController_CorsairV2HW::UpdateSingleLED(int /*led*/)
{
controller->SetLedsDirect(buffer_map);
}
void RGBController_CorsairV2HW::DeviceUpdateMode()
{
}
void RGBController_CorsairV2HW::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(30000ms);
}
}

View file

@ -0,0 +1,42 @@
/*---------------------------------------------------------------------*\
| RGBController_CorsairV2HardwareController.h |
| |
| Driver for the newer Corsair peripherals that use the '08' |
| based USB protocol and support hardware lighting modes. |
| |
| Chris M (Dr_No) 10 Dec 2022 |
\*---------------------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CorsairPeripheralV2Controller.h"
#include "CorsairPeripheralV2HardwareController.h"
class RGBController_CorsairV2HW : public RGBController
{
public:
RGBController_CorsairV2HW(CorsairPeripheralV2Controller* controller_ptr);
~RGBController_CorsairV2HW();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
void KeepaliveThread();
private:
CorsairPeripheralV2Controller* controller;
RGBColor null_color = 0;
std::vector<RGBColor *> buffer_map;
std::thread* keepalive_thread;
std::atomic<bool> keepalive_thread_run;
std::chrono::time_point
<std::chrono::steady_clock> last_update_time;
};

View file

@ -13,7 +13,7 @@
using namespace std::chrono_literals;
/**------------------------------------------------------------------*\
@name Corsair K55 RGB Pro
@name Corsair Peripherals V2 Software
@category Keyboard
@type USB
@save :x:
@ -35,7 +35,7 @@ RGBController_CorsairV2SW::RGBController_CorsairV2SW(CorsairPeripheralV2Controll
location = controller->GetDeviceLocation();
serial = controller->GetSerialString();
if(corsair->supports & CORSAIR_V2_MODE_SW)
if(corsair->protocol & CORSAIR_V2_TYPE_SW_COLOUR_BLOCK)
{
mode Direct;
Direct.name = "Direct";
@ -43,10 +43,7 @@ RGBController_CorsairV2SW::RGBController_CorsairV2SW(CorsairPeripheralV2Controll
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
}
if(corsair->supports & CORSAIR_V2_MODE_HW)
{
mode Static;
Static.name = "Static";
Static.value = CORSAIR_V2_MODE_STATIC;
@ -249,6 +246,6 @@ void RGBController_CorsairV2SW::KeepaliveThread()
DeviceUpdateLEDs();
}
}
std::this_thread::sleep_for(3000ms);
std::this_thread::sleep_for(30000ms);
}
}

View file

@ -10,6 +10,7 @@
#include "RGBController.h"
#include "CorsairPeripheralV2Controller.h"
#include "CorsairPeripheralV2HardwareController.h"
#include "CorsairPeripheralV2SoftwareController.h"
class RGBController_CorsairV2SW : public RGBController

View file

@ -355,7 +355,9 @@ HEADERS +=
Controllers/CorsairPeripheralController/RGBController_CorsairK95PlatinumXT.h \
Controllers/CorsairPeripheralV2Controller/CorsairPeripheralV2Controller.h \
Controllers/CorsairPeripheralV2Controller/CorsairPeripheralV2Devices.h \
Controllers/CorsairPeripheralV2Controller/CorsairPeripheralV2HardwareController.h \
Controllers/CorsairPeripheralV2Controller/CorsairPeripheralV2SoftwareController.h \
Controllers/CorsairPeripheralV2Controller/RGBController_CorsairV2Hardware.h \
Controllers/CorsairPeripheralV2Controller/RGBController_CorsairV2Software.h \
Controllers/CorsairVengeanceController/CorsairVengeanceController.h \
Controllers/CorsairVengeanceController/RGBController_CorsairVengeance.h \
@ -908,7 +910,9 @@ SOURCES +=
Controllers/CorsairPeripheralV2Controller/CorsairPeripheralV2Devices.cpp \
Controllers/CorsairPeripheralV2Controller/CorsairPeripheralV2Controller.cpp \
Controllers/CorsairPeripheralV2Controller/CorsairPeripheralV2ControllerDetect.cpp \
Controllers/CorsairPeripheralV2Controller/CorsairPeripheralV2HardwareController.cpp \
Controllers/CorsairPeripheralV2Controller/CorsairPeripheralV2SoftwareController.cpp \
Controllers/CorsairPeripheralV2Controller/RGBController_CorsairV2Hardware.cpp \
Controllers/CorsairPeripheralV2Controller/RGBController_CorsairV2Software.cpp \
Controllers/CorsairVengeanceController/CorsairVengeanceController.cpp \
Controllers/CorsairVengeanceController/CorsairVengeanceControllerDetect.cpp \