Initial add for Coolermaster ARGB controller

* Not yet functional

Commit amended for code style and cherry-pick cleanup by Adam Honse <calcprogrammer1@gmail.com>
This commit is contained in:
Chris 2020-10-12 23:41:30 +11:00 committed by Adam Honse
parent 06c09da4ea
commit b709e5ddcc
4 changed files with 292 additions and 8 deletions

View file

@ -0,0 +1,152 @@
/*-------------------------------------------------------------------*\
| CMARGBController.cpp |
| |
| Driver for Coolermaster ARGB USB Controller |
| |
| Chris M (Dr_No) 10th Oct 2020 |
| |
\*-------------------------------------------------------------------*/
#include "CMARGBcontroller.h"
static unsigned char argb_colour_index_data[2][2][2] =
{ //R0 R1
{ { 0x00, 0x01 }, //G0 B0
{ 0x02, 0x04 }, }, //G1 B0
{ { 0x03, 0x05 }, //G0 B1
{ 0x06, 0x07 }, } //G1 B1
};
static unsigned char argb_mode_data[2][9] =
{
{ 0x05, 0x01, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x01 }, //12v RGB Mode values
{ 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)
{
std::size_t tmp_size = wcslen(_vendor);
dev = dev_handle;
location = _path;
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];
}
}
CMARGBController::~CMARGBController()
{
hid_close(dev);
}
char* CMARGBController::GetDeviceName()
{
return device_name;
}
char* CMARGBController::GetSerial()
{
return serial;
}
std::string CMARGBController::GetLocation()
{
return location;
}
unsigned char CMARGBController::GetMode()
{
return current_mode;
}
unsigned char CMARGBController::GetLedRed()
{
return current_red;
}
unsigned char CMARGBController::GetLedGreen()
{
return current_green;
}
unsigned char CMARGBController::GetLedBlue()
{
return current_blue;
}
unsigned char CMARGBController::GetLedSpeed()
{
return current_speed;
}
unsigned char CMARGBController::GetLargestColour(unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char largest;
if ( red > green )
{
( red > blue ) ? largest = red : largest = blue;
}
else
{
( green > blue ) ? largest = green : largest = blue;
}
return largest;
}
unsigned char CMARGBController::GetColourIndex(unsigned char red, unsigned char green, unsigned char blue)
{
//The Coolermaster ARGB controller 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 char 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;
return argb_colour_index_data[r][g][b];
}
void CMARGBController::SetMode(unsigned char mode, unsigned char speed)
{
current_mode = mode;
current_speed = speed;
SendUpdate();
}
void CMARGBController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
{
current_red = red;
current_green = green;
current_blue = blue;
SendUpdate();
}
void CMARGBController::SendUpdate(unsigned char zone)
{
unsigned char buffer[0x40] = { 0x00 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
bool boolARGB_header = true;
buffer[CM_ARGB_REPORT_BYTE] = 0x80;
buffer[CM_ARGB_COMMAND_BYTE] = 0x01;
buffer[CM_ARGB_MODE_BYTE] = 0x01;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT );
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_COLOUR_INDEX_BYTE] = GetColourIndex( current_red, current_green, current_blue );
buffer[CM_ARGB_SPEED_BYTE] = current_speed;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT );
}

View file

@ -0,0 +1,119 @@
/*-------------------------------------------------------------------*\
| CMARGBController.h |
| |
| Driver for Coolermaster ARGB USB Controller |
| |
| Chris M (Dr_No) 10th Oct 2020 |
| |
| Simple RGB device with 5 modes |
| 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 |
| BYTE4 = Colour Modes: BLUE else ignored |
| BYTE5 = Colour Modes: SPEED else ignored |
\*-------------------------------------------------------------------*/
#include <string>
#include <array>
#include <cmath> //Needed by round()
#include <hidapi/hidapi.h>
#pragma once
#define CM_ARGB_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
#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 HID_MAX_STR 255
enum
{
CM_ARGB_REPORT_BYTE = 0,
CM_ARGB_COMMAND_BYTE = 1,
CM_ARGB_MODE_BYTE = 2,
CM_ARGB_ZONE_BYTE = 3,
CM_ARGB_COLOUR_INDEX_BYTE = 5,
CM_ARGB_SPEED_BYTE = 6
};
// ARGB Modes
/*
* 01 Spectrum (random)
* 02 Reload
* 03 Recoil
* 04 Breathing
* 05 Refill
* 06 Demo Mode (random)
* 08 Fill Flow (random)
* 09 Rainbow (random)
* 0a Turn Off
*/
// RGB Modes
/*
* 01 Colour Cycle
* 02 Flash
* 03 Breathing
* 04 Motherboard (Pass Thru)
* 05 Turn Off
*/
enum
{
CM_ARGB_MODE_OFF = 1, //Turn off
CM_ARGB_MODE_SPECTRUM = 2, //Spectrum Mode
CM_ARGB_MODE_RELOAD = 3, //Reload Mode
CM_ARGB_MODE_RECOIL = 4, //Recoil Mode
CM_ARGB_MODE_BREATHING = 5, //Breathing Mode
CM_ARGB_MODE_REFILL = 6, //Refill Mode
CM_ARGB_MODE_DEMO = 7, //Demo Mode
CM_ARGB_MODE_FILLFLOW = 8, //Fill Flow Mode
CM_ARGB_MODE_RAINBOW = 9 //Rainbow Mode
};
enum
{
CM_ARGB_SPEED_SLOWEST = 0x00, // Slowest speed
CM_ARGB_SPEED_SLOW = 0x01, // Slower speed
CM_ARGB_SPEED_NORMAL = 0x02, // Normal speed
CM_ARGB_SPEED_FAST = 0x03, // Fast speed
CM_ARGB_SPEED_FASTEST = 0x04, // Fastest speed
};
class CMARGBController
{
public:
CMARGBController(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path);
~CMARGBController();
char* GetDeviceName();
char* GetSerial();
std::string GetLocation();
unsigned char GetMode();
unsigned char GetLedRed();
unsigned char GetLedGreen();
unsigned char GetLedBlue();
unsigned char GetLedSpeed();
void SetMode(unsigned char mode, unsigned char speed);
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
private:
char device_name[32];
char serial[32];
std::string location;
hid_device* dev;
unsigned char current_mode;
unsigned char current_speed;
unsigned char current_red;
unsigned char current_green;
unsigned char current_blue;
unsigned char GetLargestColour(unsigned char red, unsigned char green, unsigned char blue);
unsigned char GetColourIndex(unsigned char red, unsigned char green, unsigned char blue);
void GetStatus();
void SendUpdate(unsigned char zone);
};

View file

@ -1,5 +1,6 @@
#include "Detector.h"
#include "CMMP750Controller.h"
#include "CMARGBcontroller.h"
#include "RGBController.h"
#include "RGBController_CMMP750Controller.h"
#include <hidapi/hidapi.h>
@ -8,19 +9,21 @@
#define COOLERMASTER_MP750_XL_PID 0x0109
#define COOLERMASTER_MP750_MEDIUM_PID 0x0105
#define COOLERMASTER_ARGB_PID 0x1011
#define COOLERMASTER_NUM_DEVICES (sizeof(cm_pids) / sizeof(cm_pids[ 0 ]))
enum
{
CM_PID = 0,
CM_INTERFACE = 1
CM_PID = 0,
CM_INTERFACE = 1
};
static const unsigned int cm_pids[][4] =
{ // PID, Interface
{ COOLERMASTER_MP750_XL_PID, 0x00 }, //Coolermaster MP750 (Extra Large)
{ COOLERMASTER_MP750_MEDIUM_PID, 0x00 } //Coolermaster MP750 (Medium)
{ // PID, Interface Type
{ COOLERMASTER_MP750_XL_PID, 0x00, DEVICE_TYPE_MOUSEMAT }, //Coolermaster MP750 (Extra Large)
{ COOLERMASTER_MP750_MEDIUM_PID, 0x00, DEVICE_TYPE_MOUSEMAT }, //Coolermaster MP750 (Medium)
{ COOLERMASTER_ARGB_PID, 0x01, DEVICE_TYPE_LEDSTRIP } //Coolermaster ARGB Controller
};
/******************************************************************************************\
@ -57,13 +60,21 @@ void DetectCoolerMasterControllers(std::vector<RGBController*>& rgb_controllers)
if(dev)
{
CMMP750Controller* controller = new CMMP750Controller(dev, info->manufacturer_string, info->product_string, info->path);
RGBController_CMMP750Controller* rgb_controller = new RGBController_CMMP750Controller(controller);
rgb_controllers.push_back(rgb_controller);
if (dev_type == DEVICE_TYPE_MOUSEMAT)
{
CMMP750Controller* controller = new CMMP750Controller(dev, info->manufacturer_string, info->product_string, info->path);
RGBController_CMMP750Controller* rgb_controller = new RGBController_CMMP750Controller(controller);
rgb_controllers.push_back(rgb_controller);
}
else if(dev_type == DEVICE_TYPE_LEDSTRIP)
{
//Add controllers here
}
}
info = info->next;
}
hid_free_enumeration(info);
} /* DetectCoolerMasterControllers() */
REGISTER_DETECTOR("Cooler Master", DetectCoolerMasterControllers);

View file

@ -149,6 +149,7 @@ HEADERS +=
Controllers/AuraGPUController/RGBController_AuraGPU.h \
Controllers/AuraSMBusController/AuraSMBusController.h \
Controllers/AuraSMBusController/RGBController_AuraSMBus.h \
Controllers/CoolerMasterController/CMARGBcontroller.h \
Controllers/CoolerMasterController/CMMP750Controller.h \
Controllers/CoolerMasterController/RGBController_CMMP750Controller.h \
Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumController.h \
@ -317,6 +318,7 @@ SOURCES +=
Controllers/AuraSMBusController/AuraSMBusController.cpp \
Controllers/AuraSMBusController/AuraSMBusControllerDetect.cpp \
Controllers/AuraSMBusController/RGBController_AuraSMBus.cpp \
Controllers/CoolerMasterController/CMARGBcontroller.cpp \
Controllers/CoolerMasterController/CMMP750Controller.cpp \
Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp \
Controllers/CoolerMasterController/RGBController_CMMP750Controller.cpp \