mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2025-12-28 09:47:50 -05:00
+ Adding K60 and K60 Low Profile PID to CorsairPeripheralV2Devices.h + Adding device layout + Registering detector + Adding pointer layout map and changing calls to accomodate.
291 lines
9.3 KiB
C++
291 lines
9.3 KiB
C++
/*---------------------------------------------------------------------*\
|
|
| CorsairPeripheralV2Controller.cpp |
|
|
| |
|
|
| Base class for the 08 based Corsair protocol |
|
|
| |
|
|
| Chris M (Dr_No) 07 Aug 2022 |
|
|
| |
|
|
\*---------------------------------------------------------------------*/
|
|
|
|
#include "CorsairPeripheralV2Controller.h"
|
|
|
|
CorsairPeripheralV2Controller::CorsairPeripheralV2Controller(hid_device* dev_handle, const char* path, std::string /*name*/, uint16_t pid)
|
|
{
|
|
const uint8_t sz = HID_MAX_STR;
|
|
wchar_t tmp[sz];
|
|
|
|
dev = dev_handle;
|
|
location = path;
|
|
|
|
hid_get_manufacturer_string(dev, tmp, sz);
|
|
std::wstring wName = std::wstring(tmp);
|
|
device_name = std::string(wName.begin(), wName.end());
|
|
|
|
hid_get_product_string(dev, tmp, sz);
|
|
wName = std::wstring(tmp);
|
|
device_name.append(" ").append(std::string(wName.begin(), wName.end()));
|
|
|
|
for(size_t i = 0; i < CORSAIR_V2_DEVICE_COUNT; i++)
|
|
{
|
|
if(corsair_v2_device_list[i]->pid == pid)
|
|
{
|
|
/*---------------------------------------------------------*\
|
|
| Set device ID |
|
|
\*---------------------------------------------------------*/
|
|
device_index = i;
|
|
write_cmd = CORSAIR_V2_WRITE_ID + corsair_v2_device_list[device_index]->wireless;
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Possibly is Wireless connected? |
|
|
\*---------------------------------------------------------*/
|
|
GetAddress(0x11);
|
|
}
|
|
|
|
CorsairPeripheralV2Controller::~CorsairPeripheralV2Controller()
|
|
{
|
|
hid_close(dev);
|
|
}
|
|
|
|
const corsair_v2_device* CorsairPeripheralV2Controller::GetDeviceData()
|
|
{
|
|
return corsair_v2_device_list[device_index];
|
|
}
|
|
|
|
std::string CorsairPeripheralV2Controller::GetDeviceLocation()
|
|
{
|
|
return("HID: " + location);
|
|
}
|
|
|
|
std::string CorsairPeripheralV2Controller::GetFirmwareString()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
std::string CorsairPeripheralV2Controller::GetName()
|
|
{
|
|
return device_name;
|
|
}
|
|
|
|
std::string CorsairPeripheralV2Controller::GetSerialString()
|
|
{
|
|
const uint8_t sz = HID_MAX_STR;
|
|
wchar_t tmp[sz];
|
|
|
|
int ret = hid_get_serial_number_string(dev, tmp, sz);
|
|
|
|
if(ret != 0)
|
|
{
|
|
LOG_DEBUG("[%s] Get HID Serial string failed", device_name.c_str());
|
|
return("");
|
|
}
|
|
|
|
std::wstring w_tmp = std::wstring(tmp);
|
|
std::string serial = std::string(w_tmp.begin(), w_tmp.end());
|
|
|
|
return serial;
|
|
}
|
|
|
|
void CorsairPeripheralV2Controller::SetRenderMode(corsair_v2_device_mode mode)
|
|
{
|
|
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
|
|
|
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Set Mode |
|
|
\*---------------------------------------------------------*/
|
|
buffer[1] = write_cmd;
|
|
buffer[2] = CORSAIR_V2_CMD_SET;
|
|
buffer[3] = CORSAIR_V2_VALUE_MODE;
|
|
buffer[5] = mode;
|
|
|
|
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
|
}
|
|
|
|
void CorsairPeripheralV2Controller::LightingControl(uint8_t opt1, uint8_t opt2)
|
|
{
|
|
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
|
|
|
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
|
|
|
/*---------------------------------------------------------*\
|
|
| The Corsair command is the same for each initialisation |
|
|
| packet and the registers and options differ for |
|
|
| each peripheral supported by the protocol |
|
|
\*---------------------------------------------------------*/
|
|
buffer[1] = write_cmd;
|
|
buffer[2] = CORSAIR_V2_CMD_GET;
|
|
buffer[3] = opt1;
|
|
buffer[5] = 0x00;
|
|
|
|
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Open a RGB lighting handle |
|
|
\*---------------------------------------------------------*/
|
|
buffer[2] = 0x0D;
|
|
buffer[3] = 0x00;
|
|
buffer[4] = 0x01;
|
|
buffer[5] = opt2;
|
|
|
|
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
|
}
|
|
|
|
void CorsairPeripheralV2Controller::GetAddress(uint8_t address)
|
|
{
|
|
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
|
uint8_t read[CORSAIR_V2_WRITE_SIZE];
|
|
|
|
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
|
memset(read, 0, CORSAIR_V2_WRITE_SIZE);
|
|
|
|
buffer[1] = write_cmd;
|
|
buffer[2] = CORSAIR_V2_CMD_GET;
|
|
buffer[3] = address;
|
|
|
|
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
|
hid_read(dev, read, CORSAIR_V2_WRITE_SIZE);
|
|
|
|
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]);
|
|
}
|
|
|
|
void CorsairPeripheralV2Controller::StartTransaction(uint8_t opt1)
|
|
{
|
|
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
|
|
|
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
|
|
|
buffer[1] = write_cmd;
|
|
buffer[2] = CORSAIR_V2_CMD_START_TX;
|
|
buffer[3] = opt1;
|
|
buffer[4] = 0x01;
|
|
|
|
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
|
}
|
|
|
|
void CorsairPeripheralV2Controller::StopTransaction(uint8_t opt1)
|
|
{
|
|
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
|
|
|
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
|
|
|
buffer[1] = write_cmd;
|
|
buffer[2] = CORSAIR_V2_CMD_STOP_TX;
|
|
buffer[3] = 0x01;
|
|
buffer[4] = opt1;
|
|
|
|
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
|
}
|
|
|
|
void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
|
|
{
|
|
const uint8_t offset1 = 8;
|
|
const uint8_t offset2 = 4;
|
|
uint16_t remaining = data_size;
|
|
|
|
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
|
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
|
|
|
StartTransaction(0);
|
|
/*---------------------------------------------------------*\
|
|
| Set the data header in packet 1 with the data length |
|
|
| signaling how many packets to expect to the device |
|
|
\*---------------------------------------------------------*/
|
|
buffer[1] = write_cmd;
|
|
buffer[2] = CORSAIR_V2_CMD_BLK_W1;
|
|
buffer[4] = data_size & 0xFF;
|
|
buffer[5] = data_size >> 8;
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Check if the data needs more than 1 packet |
|
|
\*---------------------------------------------------------*/
|
|
uint16_t copy_bytes = CORSAIR_V2_WRITE_SIZE - offset1;
|
|
if(remaining < copy_bytes)
|
|
{
|
|
copy_bytes = remaining;
|
|
}
|
|
|
|
memcpy(&buffer[offset1], &data[0], copy_bytes);
|
|
|
|
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
|
|
|
remaining -= copy_bytes;
|
|
buffer[2] = CORSAIR_V2_CMD_BLK_WN;
|
|
copy_bytes = CORSAIR_V2_WRITE_SIZE - offset2;
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Send the remaining packets |
|
|
\*---------------------------------------------------------*/
|
|
while(remaining)
|
|
{
|
|
uint16_t index = data_size - remaining;
|
|
if(remaining < copy_bytes)
|
|
{
|
|
memset(&buffer[offset2], 0, copy_bytes);
|
|
copy_bytes = remaining;
|
|
}
|
|
|
|
memcpy(&buffer[offset2], &data[index], copy_bytes);
|
|
|
|
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
|
|
|
remaining -= copy_bytes;
|
|
}
|
|
|
|
StopTransaction(0);
|
|
}
|
|
|
|
void CorsairPeripheralV2Controller::UpdateHWMode(uint16_t mode, corsair_v2_color /*color_mode*/, uint8_t /*speed*/,
|
|
uint8_t /*direction*/, uint8_t /*brightness*/, std::vector<RGBColor> /*colors*/)
|
|
{
|
|
/*---------------------------------------------------------*\
|
|
| If we are switching to `Direct` mode |
|
|
| set device in software mode |
|
|
\*---------------------------------------------------------*/
|
|
if(mode == CORSAIR_V2_MODE_DIRECT)
|
|
{
|
|
SetRenderMode(CORSAIR_V2_MODE_SW);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
SetRenderMode(CORSAIR_V2_MODE_HW);
|
|
|
|
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
|
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
|
*/
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Set the data header in packet 1 with the data length |
|
|
| signaling how many packets to expect to the device |
|
|
\*---------------------------------------------------------*/
|
|
|
|
/*
|
|
buffer[1] = write_cmd;
|
|
buffer[2] = CORSAIR_V2_CMD_BLK_W1;
|
|
buffer[3] = CORSAIR_V2_MODE_HW;
|
|
buffer[4] = 0x30;
|
|
buffer[8] = mode & 0xFF;
|
|
buffer[9] = mode >> 8;
|
|
|
|
buffer[10] = CORSAIR_V2_COLOR_SPECIFIC;
|
|
buffer[11] = speed;
|
|
|
|
buffer[14] = colors.size();
|
|
|
|
for(size_t i = 0; i < colors.size(); ++i)
|
|
{
|
|
uint8_t offset = 15 + (i * 4);
|
|
|
|
buffer[offset] = brightness;
|
|
buffer[offset + 1] = RGBGetBValue(colors[i]);
|
|
buffer[offset + 2] = RGBGetGValue(colors[i]);
|
|
buffer[offset + 3] = RGBGetRValue(colors[i]);
|
|
}
|
|
*/
|
|
|
|
}
|