280 lines
9.7 KiB
C++
280 lines
9.7 KiB
C++
/*---------------------------------------------------------*\
|
|
| CorsairCommanderCoreController.cpp |
|
|
| |
|
|
| Processing Code for Corsair Commander Core |
|
|
| |
|
|
| Jeff P. |
|
|
\*---------------------------------------------------------*/
|
|
|
|
#include "CorsairCommanderCoreController.h"
|
|
|
|
#include <cstring>
|
|
#include <iomanip>
|
|
#include <iostream>
|
|
|
|
using namespace std::chrono_literals;
|
|
|
|
CorsairCommanderCoreController::CorsairCommanderCoreController(hid_device* dev_handle, const char* path)
|
|
{
|
|
dev = dev_handle;
|
|
location = path;
|
|
keepalive_thread_run = 1;
|
|
controller_ready = 0;
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Initialize controller |
|
|
\*-----------------------------------------------------*/
|
|
InitController();
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Start keepalive thread |
|
|
\*-----------------------------------------------------*/
|
|
keepalive_thread = new std::thread(&CorsairCommanderCoreController::KeepaliveThread, this);
|
|
}
|
|
|
|
CorsairCommanderCoreController::~CorsairCommanderCoreController()
|
|
{
|
|
/*-----------------------------------------------------*\
|
|
| Close keepalive thread |
|
|
\*-----------------------------------------------------*/
|
|
keepalive_thread_run = 0;
|
|
keepalive_thread->join();
|
|
delete keepalive_thread;
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Close HID device |
|
|
\*-----------------------------------------------------*/
|
|
hid_close(dev);
|
|
}
|
|
|
|
void CorsairCommanderCoreController::InitController()
|
|
{
|
|
/*-----------------------------------------------------*\
|
|
| Packet sequence to put controller into direct mode |
|
|
\*-----------------------------------------------------*/
|
|
unsigned char buffarray[][5] =
|
|
{
|
|
{0x08, 0x01, 0x03, 0x00, 0x02},
|
|
{0x08, 0x0D, 0x00, 0x22, 0x00},
|
|
};
|
|
|
|
SendMultiPkt(buffarray, sizeof(buffarray) / sizeof(buffarray[0]), sizeof(buffarray)[0] / sizeof(buffarray[0][0]));
|
|
SetFanMode();
|
|
}
|
|
|
|
std::string CorsairCommanderCoreController::GetLocationString()
|
|
{
|
|
return("HID: " + location);
|
|
}
|
|
|
|
void CorsairCommanderCoreController::KeepaliveThread()
|
|
{
|
|
while(keepalive_thread_run.load())
|
|
{
|
|
if (controller_ready)
|
|
{
|
|
if((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::seconds(10))
|
|
{
|
|
SendCommit();
|
|
}
|
|
}
|
|
std::this_thread::sleep_for(1s);
|
|
}
|
|
}
|
|
|
|
void CorsairCommanderCoreController::SendCommit()
|
|
{
|
|
if(!lastcolors.empty())
|
|
{
|
|
/*-----------------------------------------------------*\
|
|
| If colors remain to be sent, send them |
|
|
\*-----------------------------------------------------*/
|
|
SetDirectColor(lastcolors, lastzones);
|
|
}
|
|
else
|
|
{
|
|
unsigned char usb_buf[1025];
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Zero out buffer |
|
|
\*-----------------------------------------------------*/
|
|
memset(usb_buf, 0x00, sizeof(usb_buf));
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Update last commit time |
|
|
\*-----------------------------------------------------*/
|
|
last_commit_time = std::chrono::steady_clock::now();
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Set up Commit packet |
|
|
\*-----------------------------------------------------*/
|
|
memset(usb_buf, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
|
|
|
usb_buf[0] = 0x00;
|
|
usb_buf[1] = 0x08;
|
|
usb_buf[2] = 0x06;
|
|
usb_buf[4] = 0xBD;
|
|
usb_buf[5] = 0x02;
|
|
usb_buf[8] = 0x12;
|
|
|
|
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
|
}
|
|
}
|
|
|
|
|
|
void CorsairCommanderCoreController::SendMultiPkt(unsigned char buffarray[][5], int r, int c)
|
|
{
|
|
/*---------------------------------------------------------*\
|
|
| Private function to send multiple packets |
|
|
\*---------------------------------------------------------*/
|
|
unsigned char* hidtemp = new unsigned char[CORSAIR_COMMANDER_CORE_PACKET_SIZE];
|
|
|
|
for(unsigned int i = 0; i < r; i++)
|
|
{
|
|
memset(hidtemp, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
|
|
|
for(unsigned int j = 0; j < c; j++)
|
|
{
|
|
hidtemp[j+1] = buffarray[i][j];
|
|
}
|
|
|
|
hid_write(dev, hidtemp, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
|
hid_read(dev, hidtemp, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
|
}
|
|
|
|
delete[] hidtemp;
|
|
}
|
|
|
|
void CorsairCommanderCoreController::SetDirectColor
|
|
(
|
|
std::vector<RGBColor> colors,
|
|
std::vector<zone> zones
|
|
)
|
|
{
|
|
if(controller_ready == 1 && ((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::milliseconds(33)))
|
|
{
|
|
lastcolors = colors;
|
|
lastzones = zones;
|
|
int packet_offset = CORSAIR_COMMANDER_CORE_PREAMBLE_OFFSET;
|
|
int led_idx = 0;
|
|
int channel_idx = 0;
|
|
unsigned char* usb_buf = new unsigned char[CORSAIR_COMMANDER_CORE_PACKET_SIZE];
|
|
|
|
memset(usb_buf, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Prepare color information packet |
|
|
\*-----------------------------------------------------*/
|
|
usb_buf[0] = 0x00;
|
|
usb_buf[1] = 0x08;
|
|
usb_buf[2] = 0x06;
|
|
usb_buf[4] = 0xBD;
|
|
usb_buf[5] = 0x02;
|
|
usb_buf[8] = 0x12;
|
|
|
|
for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
|
{
|
|
/*-------------------------------------------------*\
|
|
| Add led colors |
|
|
\*-------------------------------------------------*/
|
|
for(unsigned int i = led_idx; i < led_idx + zones[zone_idx].leds_count; i++)
|
|
{
|
|
usb_buf[packet_offset] = RGBGetRValue(colors[i]);
|
|
usb_buf[packet_offset+1] = RGBGetGValue(colors[i]);
|
|
usb_buf[packet_offset+2] = RGBGetBValue(colors[i]);
|
|
|
|
packet_offset = packet_offset + 3;
|
|
}
|
|
|
|
led_idx = led_idx + zones[zone_idx].leds_count;
|
|
|
|
/*-------------------------------------------------*\
|
|
| Move offset for pump zone with less than 33 LEDs |
|
|
\*-------------------------------------------------*/
|
|
if(zone_idx == 0)
|
|
{
|
|
packet_offset = packet_offset + 3 * (33 - zones[zone_idx].leds_count);
|
|
}
|
|
|
|
/*-------------------------------------------------*\
|
|
| Move offset for fans with less than 34 LEDs |
|
|
\*-------------------------------------------------*/
|
|
if(zone_idx != 0)
|
|
{
|
|
packet_offset = packet_offset + 3 * (34 - zones[zone_idx].leds_count);
|
|
}
|
|
|
|
channel_idx++;
|
|
}
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Sending a direct mode color packet resets the timeout |
|
|
\*-----------------------------------------------------*/
|
|
last_commit_time = std::chrono::steady_clock::now();
|
|
|
|
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
|
|
|
delete[] usb_buf;
|
|
}
|
|
}
|
|
|
|
void CorsairCommanderCoreController::SetFanMode()
|
|
{
|
|
/*--------------------------------------------------------------------------------------------------*\
|
|
| Force controller to 6 QL fan mode to expose maximum number of LEDs per rgb port (34 LEDs per port) |
|
|
\*--------------------------------------------------------------------------------------------------*/
|
|
|
|
unsigned char usb_buf[1025];
|
|
|
|
unsigned char buffarray4[][5] =
|
|
{
|
|
{0x08, 0x05, 0x01, 0x01, 0x00},
|
|
{0x08, 0x0D, 0x01, 0x1E, 0x00},
|
|
{0x08, 0x09, 0x01, 0x00, 0x00}
|
|
};
|
|
|
|
SendMultiPkt(buffarray4, sizeof(buffarray4) / sizeof(buffarray4[0]), sizeof(buffarray4)[0] / sizeof(buffarray4[0][0]));
|
|
|
|
memset(usb_buf, 0, sizeof(usb_buf));
|
|
|
|
usb_buf[0] = 0x00;
|
|
usb_buf[1] = 0x08;
|
|
usb_buf[2] = 0x06;
|
|
usb_buf[3] = 0x01;
|
|
usb_buf[4] = 0x11;
|
|
usb_buf[8] = 0x0D;
|
|
usb_buf[10] = 0x07;
|
|
usb_buf[11] = 0x01;
|
|
usb_buf[12] = 0x08;
|
|
|
|
for(unsigned int i = 13; i < 25; i = i + 2)
|
|
{
|
|
usb_buf[i] = 0x01;
|
|
usb_buf[i + 1] = 0x06;
|
|
}
|
|
|
|
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
|
hid_read(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
|
|
|
unsigned char buffarray2[][5] =
|
|
{
|
|
{0x08, 0x05, 0x01, 0x01, 0x00},
|
|
{0x08, 0x15, 0x01, 0x00, 0x00}
|
|
};
|
|
|
|
SendMultiPkt(buffarray2, sizeof(buffarray2) / sizeof(buffarray2[0]), sizeof(buffarray2)[0] / sizeof(buffarray2[0][0]));
|
|
|
|
memset(usb_buf, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
|
|
|
usb_buf[0] = 0x00;
|
|
usb_buf[1] = 0x08;
|
|
usb_buf[2] = 0x06;
|
|
usb_buf[4] = 0xBD;
|
|
usb_buf[5] = 0x02;
|
|
usb_buf[8] = 0x12;
|
|
|
|
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
|
hid_read(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
|
|
|
controller_ready = 1;
|
|
}
|