Updating CM ARGB controller to allow 'Direct' mode for FW0028
+ Adding brightness to all modes + Adjusted setLedsDirect() for new protocol (M+ `System Lighting`) + Adjusted setMode() to include brightness + Adding mutex to guard against collisions * Correcting a segfault when any zone is set to `off` - Removing the "All ARGB Headers" tab - Removing deprecated code
This commit is contained in:
parent
d88aaecb80
commit
ecbc3c4e50
4 changed files with 265 additions and 236 deletions
|
|
@ -8,17 +8,8 @@
|
|||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#include "CMARGBcontroller.h"
|
||||
#include <cstring>
|
||||
|
||||
static unsigned char argb_colour_index_data[2][2][2] =
|
||||
{ //B0 B1
|
||||
{ { 0x00, 0x03 }, //G0 R0
|
||||
{ 0x02, 0x06 }, }, //G1 R0
|
||||
{ { 0x01, 0x05 }, //G0 R1
|
||||
{ 0x04, 0x07 }, } //G1 R1
|
||||
};
|
||||
|
||||
CMARGBController::CMARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx)
|
||||
CMARGBController::CMARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx, std::shared_ptr<std::mutex> cm_mutex)
|
||||
{
|
||||
const int szTemp = 256;
|
||||
wchar_t tmpName[szTemp];
|
||||
|
|
@ -26,6 +17,7 @@ CMARGBController::CMARGBController(hid_device* dev_handle, char *_path, unsigned
|
|||
dev = dev_handle;
|
||||
location = _path;
|
||||
zone_index = _zone_idx;
|
||||
mutex_ptr = cm_mutex;
|
||||
|
||||
hid_get_manufacturer_string(dev, tmpName, szTemp);
|
||||
std::wstring wName = std::wstring(tmpName);
|
||||
|
|
@ -66,6 +58,12 @@ void CMARGBController::GetStatus()
|
|||
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 |
|
||||
\*---------------------------------------------------------*/
|
||||
|
|
@ -132,38 +130,6 @@ bool CMARGBController::GetRandomColours()
|
|||
return bool_random;
|
||||
}
|
||||
|
||||
unsigned int CMARGBController::GetLargestColour(unsigned int red, unsigned int green, unsigned int blue)
|
||||
{
|
||||
unsigned int largest;
|
||||
if ( red > green )
|
||||
{
|
||||
( red > blue ) ? largest = red : largest = blue;
|
||||
}
|
||||
else
|
||||
{
|
||||
( green > blue ) ? largest = green : largest = blue;
|
||||
}
|
||||
|
||||
return (largest == 0) ? 1 : largest;
|
||||
}
|
||||
|
||||
unsigned char CMARGBController::GetColourIndex(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| The Cooler Master ARGB controller V0008 uses a limited colour pallette referenced by an index |
|
||||
| Starting at 0x00 Random, 0x01 Red, 0x02 Green, 0x03 Blue, 0x04 Yellow, 0x05 Purple, 0x06 Cyan, 0x07 White |
|
||||
| The index can be calculated by normalising the input colour, rounding those values |
|
||||
| and using them as the indicies of a 3d array containing the correct index |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
unsigned int divisor = GetLargestColour( red, green, blue);
|
||||
unsigned int r = round( red / divisor );
|
||||
unsigned int g = round( green / divisor );
|
||||
unsigned int b = round( blue / divisor );
|
||||
unsigned char idx = argb_colour_index_data[r][g][b];
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
void CMARGBController::SetLedCount(int zone, int led_count)
|
||||
{
|
||||
unsigned char buffer[CM_ARGB_PACKET_SIZE] = { 0x00, 0x80, 0x0D, 0x02 };
|
||||
|
|
@ -173,18 +139,24 @@ void CMARGBController::SetLedCount(int zone, int led_count)
|
|||
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);
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
}
|
||||
|
||||
void CMARGBController::SetMode(unsigned char mode, unsigned char speed, RGBColor colour, bool random_colours)
|
||||
void CMARGBController::SetMode(uint8_t mode, uint8_t speed, uint8_t brightness, RGBColor colour, bool random_colours)
|
||||
{
|
||||
bool needs_update = !( (current_mode == mode) && (current_speed == speed) && (current_brightness == 0xFF) && (ToRGBColor(current_red, current_green, current_blue) == colour));
|
||||
bool needs_update = !( (current_mode == mode) && (current_speed == speed) && (current_brightness == brightness) && (ToRGBColor(current_red, current_green, current_blue) == colour));
|
||||
|
||||
if (needs_update)
|
||||
{
|
||||
current_mode = mode;
|
||||
current_speed = speed;
|
||||
current_brightness = 0xFF;
|
||||
current_brightness = brightness;
|
||||
current_red = RGBGetRValue(colour);
|
||||
current_green = RGBGetGValue(colour);
|
||||
current_blue = RGBGetBValue(colour);
|
||||
|
|
@ -197,9 +169,9 @@ void CMARGBController::SetMode(unsigned char mode, unsigned char speed, RGBColor
|
|||
void CMARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_count)
|
||||
{
|
||||
const unsigned char buffer_size = CM_ARGB_PACKET_SIZE;
|
||||
unsigned char buffer[buffer_size] = { 0x00, 0x10, 0x02 };
|
||||
unsigned char buffer[buffer_size] = { 0x00, 0x00, 0x07, 0x02 };
|
||||
unsigned char packet_count = 0;
|
||||
std::vector<unsigned char> colours;
|
||||
std::vector<uint8_t> colours;
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Set up the RGB triplets to send |
|
||||
|
|
@ -213,11 +185,17 @@ void CMARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_cou
|
|||
colours.push_back( RGBGetBValue(colour) );
|
||||
}
|
||||
|
||||
buffer[CM_ARGB_ZONE_BYTE] = argb_header_data[zone_index].header;
|
||||
buffer[CM_ARGB_MODE_BYTE] = led_count;
|
||||
unsigned char buffer_idx = CM_ARGB_MODE_BYTE + 1;
|
||||
buffer[CM_ARGB_FUNCTION_BYTE] = zone_index - 1;
|
||||
buffer[CM_ARGB_ZONE_BYTE] = led_count;
|
||||
unsigned char buffer_idx = CM_ARGB_MODE_BYTE;
|
||||
|
||||
for(std::vector<unsigned char>::iterator it = colours.begin(); it != colours.end(); buffer_idx = 0)
|
||||
/*---------------------------------------------*\
|
||||
| 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 |
|
||||
|
|
@ -230,8 +208,12 @@ void CMARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_cou
|
|||
it++;
|
||||
}
|
||||
|
||||
if(it == colours.end())
|
||||
{
|
||||
buffer[CM_ARGB_REPORT_BYTE] += 0x80;
|
||||
}
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Reset the write buffer |
|
||||
|
|
@ -239,21 +221,15 @@ void CMARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_cou
|
|||
memset(buffer, 0x00, buffer_size );
|
||||
packet_count++;
|
||||
}
|
||||
|
||||
buffer[CM_ARGB_REPORT_BYTE] = 0x82;
|
||||
/*buffer[CM_ARGB_COMMAND_BYTE] = 0x62;
|
||||
buffer[CM_ARGB_FUNCTION_BYTE] = 0x00;
|
||||
buffer[CM_ARGB_ZONE_BYTE] = 0x73;
|
||||
buffer[CM_ARGB_MODE_BYTE] = 0x00;
|
||||
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = 0x33;
|
||||
buffer[CM_ARGB_SPEED_BYTE] = 0x1B;*/
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
@ -262,22 +238,29 @@ void CMARGBController::SendUpdate()
|
|||
unsigned char function = boolPassthru ? (boolARGB_header ? 0x02 : 0x04) : (boolARGB_header ? 0x01 : 0x03);
|
||||
buffer[CM_ARGB_REPORT_BYTE] = 0x80;
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = 0x01;
|
||||
buffer[CM_ARGB_FUNCTION_BYTE] = boolDirect ? 0x01 : function;
|
||||
|
||||
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);
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Direct mode is now set up and no other mode packet is required |
|
||||
\*-----------------------------------------------------------------*/
|
||||
if(boolDirect)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(boolARGB_header)
|
||||
{
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = 0x0b; //ARGB sends 0x0b (1011) RGB sends 0x04 (0100)
|
||||
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;
|
||||
|
|
@ -287,9 +270,6 @@ void CMARGBController::SendUpdate()
|
|||
buffer[CM_ARGB_RED_BYTE] = current_red;
|
||||
buffer[CM_ARGB_GREEN_BYTE] = current_green;
|
||||
buffer[CM_ARGB_BLUE_BYTE] = current_blue;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -301,8 +281,8 @@ void CMARGBController::SendUpdate()
|
|||
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);
|
||||
}
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue