Coolermastrer ARGB Controller detecting but not yet applying colour

* Compiling correctly
* Adding 5 controllers to GUI
* Changing Colour will cause segfault
This commit is contained in:
Chris 2020-10-17 00:52:09 +11:00 committed by Adam Honse
parent b709e5ddcc
commit 743a27d0a2
6 changed files with 292 additions and 28 deletions

View file

@ -23,20 +23,26 @@ static unsigned char argb_mode_data[2][9] =
{ 0x0A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, 0x09 } //5v ARGB Mode values
};
CMARGBController::CMARGBController(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path)
CMARGBController::CMARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx)
{
std::size_t tmp_size = wcslen(_vendor);
const int szTemp = 256;
wchar_t tmpName[szTemp];
dev = dev_handle;
location = _path;
zone_index = _zone_idx;
for(std::size_t i = 0; (i < tmp_size) && (i < CM_ARGB_DEVICE_NAME_SIZE); i++)
{
device_name[i] = (char)_vendor[i];
}
for(std::size_t j = 0; (j < wcslen(_vendor)) && (tmp_size + j < CM_ARGB_DEVICE_NAME_SIZE); j++)
{
device_name[tmp_size + j] = (char)_device_name[j];
}
hid_get_manufacturer_string(dev, tmpName, szTemp);
std::wstring wName = std::wstring(tmpName);
device_name = std::string(wName.begin(), wName.end());
hid_get_product_string(dev, tmpName, szTemp);
wName = std::wstring(tmpName);
device_name.append(" ").append(std::string(wName.begin(), wName.end()));
hid_get_serial_number_string(dev, tmpName, szTemp);
wName = std::wstring(tmpName);
serial = std::string(wName.begin(), wName.end());
}
CMARGBController::~CMARGBController()
@ -44,12 +50,12 @@ CMARGBController::~CMARGBController()
hid_close(dev);
}
char* CMARGBController::GetDeviceName()
std::string CMARGBController::GetDeviceName()
{
return device_name;
}
char* CMARGBController::GetSerial()
std::string CMARGBController::GetSerial()
{
return serial;
}
@ -59,6 +65,11 @@ std::string CMARGBController::GetLocation()
return location;
}
unsigned char CMARGBController::GetZoneIndex()
{
return zone_index;
}
unsigned char CMARGBController::GetMode()
{
return current_mode;
@ -84,9 +95,9 @@ unsigned char CMARGBController::GetLedSpeed()
return current_speed;
}
unsigned char CMARGBController::GetLargestColour(unsigned char red, unsigned char green, unsigned char blue)
unsigned int CMARGBController::GetLargestColour(unsigned int red, unsigned int green, unsigned int blue)
{
unsigned char largest;
unsigned int largest;
if ( red > green )
{
( red > blue ) ? largest = red : largest = blue;
@ -96,7 +107,7 @@ unsigned char CMARGBController::GetLargestColour(unsigned char red, unsigned cha
( green > blue ) ? largest = green : largest = blue;
}
return largest;
return (largest == 0) ? 1 : largest;
}
unsigned char CMARGBController::GetColourIndex(unsigned char red, unsigned char green, unsigned char blue)
@ -105,7 +116,7 @@ unsigned char CMARGBController::GetColourIndex(unsigned char red, unsigned char
//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 char divisor = GetLargestColour( red, green, blue);
unsigned int divisor = GetLargestColour( red, green, blue);
unsigned int r = round( red / divisor )+1;
unsigned int g = round( green / divisor )+1;
unsigned int b = round( blue / divisor )+1;
@ -129,7 +140,7 @@ void CMARGBController::SetColor(unsigned char red, unsigned char green, unsigned
SendUpdate();
}
void CMARGBController::SendUpdate(unsigned char zone)
void CMARGBController::SendUpdate()
{
unsigned char buffer[0x40] = { 0x00 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
@ -143,7 +154,7 @@ void CMARGBController::SendUpdate(unsigned char zone)
buffer[CM_ARGB_COMMAND_BYTE] = (boolARGB_header) ? 0x0b : 0x04; //ARGB sends 0x0b (1011) RGB sends 0x04 (0100)
buffer[CM_ARGB_MODE_BYTE] = current_mode;
buffer[CM_ARGB_ZONE_BYTE] = zone;
buffer[CM_ARGB_ZONE_BYTE] = argb_header_data[zone_index].header;
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = GetColourIndex( current_red, current_green, current_blue );
buffer[CM_ARGB_SPEED_BYTE] = current_speed;

View file

@ -6,7 +6,7 @@
| Chris M (Dr_No) 10th Oct 2020 |
| |
| Simple RGB device with 5 modes |
| BYTE0 = Mode (0x01 thru 0x05 |
| BYTE0 = Mode 0x01 thru 0x05 |
| BYTE1 = ?? Must be set to 0x04 for colour modes otherwise ignored |
| BYTE2 = Colour Modes: RED else Cycle SPEED |
| BYTE3 = Colour Modes: GREEN else ignored |
@ -22,9 +22,10 @@
#pragma once
#define CM_ARGB_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
#define CM_ARGB_HEADER_DATA_SIZE (sizeof(argb_header_data) / sizeof(argb_headers) )
#define CM_ARGB_INTERRUPT_TIMEOUT 250
#define CM_ARGB_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
#define CM_ARGB_SERIAL_SIZE (sizeof(serial) / sizeof(serial[ 0 ]))
//#define CM_ARGB_SERIAL_SIZE (sizeof(serial) / sizeof(serial[ 0 ]))
#define HID_MAX_STR 255
enum
@ -37,6 +38,22 @@ enum
CM_ARGB_SPEED_BYTE = 6
};
struct argb_headers
{
const char* name;
unsigned char header;
unsigned int count;
};
static argb_headers argb_header_data[5] =
{
{ "RGB Header", 0xFF, 1 },
{ "Digital ARGB1", 0x01, 0 },
{ "Digital ARGB2", 0x02, 0 },
{ "Digital ARGB3", 0x04, 0 },
{ "Digital ARGB4", 0x08, 0 }
};
// ARGB Modes
/*
* 01 Spectrum (random)
@ -84,13 +101,14 @@ enum
class CMARGBController
{
public:
CMARGBController(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path);
CMARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx);
~CMARGBController();
char* GetDeviceName();
char* GetSerial();
std::string GetDeviceName();
std::string GetSerial();
std::string GetLocation();
unsigned char GetZoneIndex();
unsigned char GetMode();
unsigned char GetLedRed();
unsigned char GetLedGreen();
@ -100,11 +118,12 @@ public:
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
private:
char device_name[32];
char serial[32];
std::string device_name;
std::string serial;
std::string location;
hid_device* dev;
unsigned char zone_index;
unsigned char current_mode;
unsigned char current_speed;
@ -112,8 +131,8 @@ private:
unsigned char current_green;
unsigned char current_blue;
unsigned char GetLargestColour(unsigned char red, unsigned char green, unsigned char blue);
unsigned int GetLargestColour(unsigned int red, unsigned int green, unsigned int blue);
unsigned char GetColourIndex(unsigned char red, unsigned char green, unsigned char blue);
void GetStatus();
void SendUpdate(unsigned char zone);
void SendUpdate();
};

View file

@ -3,6 +3,7 @@
#include "CMARGBcontroller.h"
#include "RGBController.h"
#include "RGBController_CMMP750Controller.h"
#include "RGBController_CMARGBController.h"
#include <hidapi/hidapi.h>
#define COOLERMASTER_VID 0x2516
@ -68,7 +69,12 @@ void DetectCoolerMasterControllers(std::vector<RGBController*>& rgb_controllers)
}
else if(dev_type == DEVICE_TYPE_LEDSTRIP)
{
//Add controllers here
for(std::size_t i = 0; i < CM_ARGB_HEADER_DATA_SIZE; i++)
{
CMARGBController* controller = new CMARGBController(dev, info->path, i);
RGBController_CMARGBController* rgb_controller = new RGBController_CMARGBController(controller);
rgb_controllers.push_back(rgb_controller);
}
}
}
info = info->next;

View file

@ -0,0 +1,191 @@
/*-------------------------------------------------------------------*\
| RGBController_CMARGBController.cpp |
| |
| Driver for Coolermaster ARGB Controller |
| |
| Chris M (Dr_No) 14th Oct 2020 |
| |
\*-------------------------------------------------------------------*/
#include "RGBController_CMARGBController.h"
RGBController_CMARGBController::RGBController_CMARGBController(CMARGBController *cmargb_ptr)
{
cmargb = cmargb_ptr;
unsigned char speed = cmargb->GetLedSpeed();
name = argb_header_data[cmargb->GetZoneIndex()].name;
type = DEVICE_TYPE_LEDSTRIP;
description = cmargb->GetDeviceName();
version = "1.0";
serial = cmargb->GetSerial();
location = cmargb->GetLocation();
mode Off;
Off.name = "Turn Off";
Off.value = CM_ARGB_MODE_OFF;
Off.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Spectrum;
Spectrum.name = "Spectrum";
Spectrum.value = CM_ARGB_MODE_SPECTRUM;
Spectrum.flags = MODE_FLAG_HAS_SPEED;
Spectrum.speed_min = CM_ARGB_SPEED_SLOWEST;
Spectrum.speed_max = CM_ARGB_SPEED_FASTEST;
Spectrum.color_mode = MODE_COLORS_NONE;
Spectrum.speed = speed;
modes.push_back(Spectrum);
mode Reload;
Reload.name = "Reload";
Reload.value = CM_ARGB_MODE_RELOAD;
Reload.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Reload.speed_min = CM_ARGB_SPEED_SLOWEST;
Reload.speed_max = CM_ARGB_SPEED_FASTEST;
Reload.color_mode = MODE_COLORS_PER_LED;
Reload.speed = speed;
modes.push_back(Reload);
mode Recoil;
Recoil.name = "Recoil";
Recoil.value = CM_ARGB_MODE_RECOIL;
Recoil.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Recoil.speed_min = CM_ARGB_SPEED_SLOWEST;
Recoil.speed_max = CM_ARGB_SPEED_FASTEST;
Recoil.color_mode = MODE_COLORS_PER_LED;
Recoil.speed = speed;
modes.push_back(Recoil);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = CM_ARGB_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.speed_min = CM_ARGB_SPEED_SLOWEST;
Breathing.speed_max = CM_ARGB_SPEED_FASTEST;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed = speed;
modes.push_back(Breathing);
mode Refill;
Refill.name = "Refill";
Refill.value = CM_ARGB_MODE_REFILL;
Refill.flags = MODE_FLAG_HAS_SPEED;
Refill.speed_min = CM_ARGB_SPEED_SLOWEST;
Refill.speed_max = CM_ARGB_SPEED_FASTEST;
Refill.color_mode = MODE_COLORS_NONE;
Refill.speed = speed;
modes.push_back(Refill);
Init_Controller(); //Only processed on first run
SetupZones();
//active_mode = cmargb->GetMode();
}
RGBController_CMARGBController::~RGBController_CMARGBController()
{
}
void RGBController_CMARGBController::Init_Controller()
{
int zone_idx = cmargb->GetZoneIndex();
int zone_led_count = argb_header_data[zone_idx].count;
bool boolSingleLED = ( zone_led_count == 1 ); //If argb_header_data[zone_idx].count == 1 then the zone is ZONE_TYPE_SINGLE
zone ARGB_zone;
ARGB_zone.name = std::to_string(zone_idx);
ARGB_zone.type = (boolSingleLED) ? ZONE_TYPE_SINGLE : ZONE_TYPE_LINEAR;
ARGB_zone.leds_min = 0;
ARGB_zone.leds_max = 64;
ARGB_zone.leds_count = zone_led_count;
ARGB_zone.matrix_map = NULL;
zones.push_back(ARGB_zone);
}
void RGBController_CMARGBController::SetupZones()
{
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
leds.clear();
colors.clear();
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
bool boolSingleLED = (zones[zone_idx].type == ZONE_TYPE_SINGLE); //Calculated for later use
for(unsigned int lp_idx = 0; lp_idx < zones[zone_idx].leds_count; lp_idx++)
{
led new_led;
unsigned int i = std::stoi(zones[zone_idx].name);
if(boolSingleLED)
{
new_led.name = i;
new_led.value = argb_header_data[i].header;
}
else
{
new_led.name = i;
new_led.name.append(" LED " + std::to_string(lp_idx));
new_led.value = argb_header_data[i].header;
}
leds.push_back(new_led);
}
}
SetupColors();
}
void RGBController_CMARGBController::ResizeZone(int zone, int new_size)
{
if((size_t) zone >= zones.size())
{
return;
}
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
{
zones[zone].leds_count = new_size;
SetupZones();
}
}
void RGBController_CMARGBController::DeviceUpdateLEDs()
{
unsigned char red = RGBGetRValue(colors[0]);
unsigned char grn = RGBGetGValue(colors[0]);
unsigned char blu = RGBGetBValue(colors[0]);
cmargb->SetColor(red, grn, blu);
}
void RGBController_CMARGBController::UpdateZoneLEDs(int zone)
{
RGBColor color = colors[zone];
unsigned char red = RGBGetRValue(color);
unsigned char grn = RGBGetGValue(color);
unsigned char blu = RGBGetBValue(color);
cmargb->SetColor(red, grn, blu);
}
void RGBController_CMARGBController::UpdateSingleLED(int led)
{
UpdateZoneLEDs(led);
}
void RGBController_CMARGBController::SetCustomMode()
{
active_mode = 0;
}
void RGBController_CMARGBController::DeviceUpdateMode()
{
cmargb->SetMode( modes[active_mode].value, modes[active_mode].speed );
}

View file

@ -0,0 +1,35 @@
/*-------------------------------------------------------------------*\
| RGBController_CMARGBController.h |
| |
| Driver for Coolermaster ARGB Controller |
| |
| Chris M (Dr_No) 14th Oct 2020 |
| |
\*-------------------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CMARGBcontroller.h"
#include <vector>
class RGBController_CMARGBController : public RGBController
{
public:
RGBController_CMARGBController(CMARGBController* cmargb_ptr);
~RGBController_CMARGBController();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
void Init_Controller();
int GetDeviceMode();
CMARGBController* cmargb;
};

View file

@ -151,6 +151,7 @@ HEADERS +=
Controllers/AuraSMBusController/RGBController_AuraSMBus.h \
Controllers/CoolerMasterController/CMARGBcontroller.h \
Controllers/CoolerMasterController/CMMP750Controller.h \
Controllers/CoolerMasterController/RGBController_CMARGBController.h \
Controllers/CoolerMasterController/RGBController_CMMP750Controller.h \
Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumController.h \
Controllers/CorsairDominatorPlatinumController/RGBController_CorsairDominatorPlatinum.h \
@ -321,6 +322,7 @@ SOURCES +=
Controllers/CoolerMasterController/CMARGBcontroller.cpp \
Controllers/CoolerMasterController/CMMP750Controller.cpp \
Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp \
Controllers/CoolerMasterController/RGBController_CMARGBController.cpp \
Controllers/CoolerMasterController/RGBController_CMMP750Controller.cpp \
Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumController.cpp \
Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumControllerDetect.cpp \