Add support for Cooler Master Addressable Gen 2 RGB LED Controller A1. Closes #2256
This commit is contained in:
parent
bba7fa9fd2
commit
c0851f3b1e
6 changed files with 819 additions and 0 deletions
373
Controllers/CoolerMasterController/CMARGBGen2A1controller.cpp
Normal file
373
Controllers/CoolerMasterController/CMARGBGen2A1controller.cpp
Normal file
|
|
@ -0,0 +1,373 @@
|
|||
/*-------------------------------------------------------------------*\
|
||||
| CMARGBGen2A1controller.cpp |
|
||||
| |
|
||||
| Driver for Coolermaster ARGB Gen 2 A1 USB Controller |
|
||||
| |
|
||||
| morg (Morgan Guimard) 6/26/2022 |
|
||||
| |
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#include "CMARGBGen2A1controller.h"
|
||||
#include <cstring>
|
||||
|
||||
CMARGBGen2A1controller::CMARGBGen2A1controller(hid_device* dev_handle, const hid_device_info& info)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = info.path;
|
||||
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
serial_number = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring return_wstring = serial_string;
|
||||
serial_number = std::string(return_wstring.begin(), return_wstring.end());
|
||||
}
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Setup direct mode on start |
|
||||
\*---------------------------------------------*/
|
||||
SetupDirectMode();
|
||||
}
|
||||
|
||||
CMARGBGen2A1controller::~CMARGBGen2A1controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string CMARGBGen2A1controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string CMARGBGen2A1controller::GetSerialString()
|
||||
{
|
||||
return(serial_number);
|
||||
}
|
||||
|
||||
void CMARGBGen2A1controller::SaveToFlash()
|
||||
{
|
||||
unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH];
|
||||
|
||||
memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND;
|
||||
usb_buf[2] = CM_ARGB_GEN2_A1_FLASH;
|
||||
usb_buf[3] = CM_ARGB_GEN2_A1_WRITE;
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
|
||||
void CMARGBGen2A1controller::SetupDirectMode()
|
||||
{
|
||||
unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH];
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Swith to direct mode |
|
||||
\*---------------------------------------------*/
|
||||
memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND;
|
||||
usb_buf[2] = CM_ARGB_GEN2_A1_LIGHTNING_CONTROL;
|
||||
usb_buf[3] = CM_ARGB_GEN2_A1_WRITE;
|
||||
usb_buf[4] = 0x01; // channel???
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
|
||||
software_mode_activated = true;
|
||||
}
|
||||
|
||||
void CMARGBGen2A1controller::SetupZoneSize(unsigned int zone_id, unsigned int size)
|
||||
{
|
||||
/*---------------------------------------------*\
|
||||
| Set the mode sequence to full static |
|
||||
| (01 for static) |
|
||||
| |
|
||||
| This device stores 2 distinct values |
|
||||
| - effect speed |
|
||||
| - approximated zone size |
|
||||
| |
|
||||
| It's probably based on standard ARGB sizes |
|
||||
| Still, the 06 value has some mystery. |
|
||||
| |
|
||||
| ES= effect speed |
|
||||
| LC= LEDs count |
|
||||
| |
|
||||
| ES LC |
|
||||
| ----- |
|
||||
| 0a 06 |
|
||||
| 09 06 |
|
||||
| 08 07 |
|
||||
| 07 08 |
|
||||
| 06 0a |
|
||||
| 05 0c |
|
||||
| 04 0f |
|
||||
| 03 14 |
|
||||
| 02 1e |
|
||||
| 01 3c |
|
||||
\*---------------------------------------------*/
|
||||
|
||||
const unsigned char gaps[10] =
|
||||
{
|
||||
0x05, 0x06, 0x07, 0x08, 0x0A, 0x0C, 0x0F, 0x14, 0x1E, 0x3C
|
||||
};
|
||||
|
||||
unsigned char speed = 0x0A;
|
||||
|
||||
for(unsigned int g = 0; g < 10; g++)
|
||||
{
|
||||
if(size <= gaps[g])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
speed--;
|
||||
}
|
||||
|
||||
unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH];
|
||||
|
||||
memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND;
|
||||
usb_buf[2] = CM_ARGB_GEN2_A1_SIZES;
|
||||
usb_buf[3] = CM_ARGB_GEN2_A1_WRITE;
|
||||
usb_buf[4] = 1 << zone_id;
|
||||
|
||||
usb_buf[5] = speed;
|
||||
usb_buf[6] = size;
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
|
||||
void CMARGBGen2A1controller::SendDirectChannel(unsigned int zone_id, std::vector<RGBColor> colors)
|
||||
{
|
||||
/*---------------------------------------------*\
|
||||
| Create the color data array |
|
||||
\*---------------------------------------------*/
|
||||
std::vector<unsigned char> color_data = CreateColorData(colors);
|
||||
|
||||
std::vector<unsigned char>::iterator it = color_data.begin();
|
||||
|
||||
unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH];
|
||||
|
||||
unsigned int offset;
|
||||
|
||||
unsigned char packet_start[CM_ARGB_GEN2_A1_PACKETS_PER_CHANNEL] =
|
||||
{
|
||||
0x00, 0x01, 0x82
|
||||
};
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Send 3 packets for the zone |
|
||||
\*---------------------------------------------*/
|
||||
for(unsigned int p = 0; p < CM_ARGB_GEN2_A1_PACKETS_PER_CHANNEL; p++)
|
||||
{
|
||||
memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = packet_start[p];
|
||||
usb_buf[2] = 0x09;
|
||||
|
||||
if(p == 0)
|
||||
{
|
||||
usb_buf[3] = 1 << zone_id;
|
||||
usb_buf[5] = 0x3C;
|
||||
|
||||
offset = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = 3;
|
||||
}
|
||||
|
||||
while(offset < CM_ARGB_GEN2_A1_PACKET_LENGTH && it != color_data.end())
|
||||
{
|
||||
usb_buf[offset] = *it;
|
||||
offset++;
|
||||
it++;
|
||||
}
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| This device needs some delay before we send |
|
||||
| any other packet |
|
||||
\*---------------------------------------------*/
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Next channel needs some delay as well |
|
||||
\*---------------------------------------------*/
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
||||
}
|
||||
|
||||
void CMARGBGen2A1controller::SetMode(unsigned int mode_value, unsigned char speed, unsigned char brightness, RGBColor color, bool random)
|
||||
{
|
||||
unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH];
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Switch to hardware mode if needed |
|
||||
\*---------------------------------------------*/
|
||||
if(software_mode_activated)
|
||||
{
|
||||
memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND;
|
||||
usb_buf[2] = CM_ARGB_GEN2_A1_LIGHTNING_CONTROL;
|
||||
usb_buf[3] = CM_ARGB_GEN2_A1_WRITE;
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
software_mode_activated = false;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Set the mode values and write to the device |
|
||||
\*---------------------------------------------*/
|
||||
memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND;
|
||||
usb_buf[2] = CM_ARGB_GEN2_A1_HW_MODE_SETUP;
|
||||
usb_buf[3] = CM_ARGB_GEN2_A1_WRITE;
|
||||
|
||||
usb_buf[4] = 0xFF;
|
||||
usb_buf[5] = 0xFF;
|
||||
|
||||
usb_buf[6] = mode_value;
|
||||
|
||||
bool is_custom_mode = mode_value == CM_ARGB_GEN2_A1_CUSTOM_MODE;
|
||||
|
||||
if(is_custom_mode)
|
||||
{
|
||||
usb_buf[8] = 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
usb_buf[7] = speed;
|
||||
usb_buf[8] = brightness;
|
||||
usb_buf[9] = RGBGetRValue(color);
|
||||
usb_buf[10] = RGBGetGValue(color);
|
||||
usb_buf[11] = RGBGetBValue(color);
|
||||
usb_buf[12] = random;
|
||||
}
|
||||
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
|
||||
if(is_custom_mode)
|
||||
{
|
||||
for(unsigned int channel = 0; channel < CM_ARGB_GEN2_A1_CHANNEL_COUNT; channel++)
|
||||
{
|
||||
SetCustomSequence(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<unsigned char> CMARGBGen2A1controller::CreateColorData(std::vector<RGBColor> colors)
|
||||
{
|
||||
std::vector<unsigned char> color_data;
|
||||
|
||||
for(unsigned int c = 0; c < colors.size(); c++)
|
||||
{
|
||||
color_data.push_back(RGBGetRValue(colors[c]));
|
||||
color_data.push_back(RGBGetGValue(colors[c]));
|
||||
color_data.push_back(RGBGetBValue(colors[c]));
|
||||
}
|
||||
|
||||
return color_data;
|
||||
}
|
||||
|
||||
|
||||
void CMARGBGen2A1controller::SetCustomColors(unsigned int zone_id, std::vector<RGBColor> colors)
|
||||
{
|
||||
unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH];
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Create the color data array |
|
||||
\*---------------------------------------------*/
|
||||
std::vector<unsigned char> color_data = CreateColorData(colors);
|
||||
|
||||
std::vector<unsigned char>::iterator it = color_data.begin();
|
||||
|
||||
unsigned char packet_start[5] =
|
||||
{
|
||||
CM_ARGB_GEN2_A1_COMMAND, 0x00, 0x01, 0x02, 0x83
|
||||
};
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Send the 5 packets of colors |
|
||||
\*---------------------------------------------*/
|
||||
for(unsigned int p = 0; p < 5; p++)
|
||||
{
|
||||
memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = packet_start[p];
|
||||
|
||||
/*----------------------------------------------*\
|
||||
| This part isnt well understood |
|
||||
| 1st packet starts with CM_ARGB_GEN2_A1_COMMAND |
|
||||
| Looks like it is a read command |
|
||||
\*----------------------------------------------*/
|
||||
usb_buf[2] = p == 0 ? 0x06 : 0x08; // 0x08 custom data, 0x06 sizes?
|
||||
usb_buf[3] = p == 0 ? 0x01 : 0x02; // read/write has no meaning here
|
||||
|
||||
usb_buf[4] = 1 << zone_id;
|
||||
|
||||
unsigned int offset = 6;
|
||||
|
||||
while(p > 0 && offset < CM_ARGB_GEN2_A1_PACKET_LENGTH && it != color_data.end())
|
||||
{
|
||||
usb_buf[offset] = *it;
|
||||
offset++;
|
||||
it++;
|
||||
}
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CMARGBGen2A1controller::SetCustomSequence(unsigned int zone_id)
|
||||
{
|
||||
unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH];
|
||||
|
||||
const unsigned char static_seq = 0x01;
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Set the mode sequence to full static |
|
||||
| (01 for static) |
|
||||
\*---------------------------------------------*/
|
||||
memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND;
|
||||
usb_buf[2] = CM_ARGB_GEN2_A1_CUSTOM_SEQUENCES;
|
||||
usb_buf[3] = CM_ARGB_GEN2_A1_WRITE;
|
||||
usb_buf[4] = 1 << zone_id;
|
||||
|
||||
usb_buf[5] = static_seq;
|
||||
usb_buf[6] = static_seq;
|
||||
usb_buf[7] = static_seq;
|
||||
usb_buf[8] = static_seq;
|
||||
usb_buf[9] = static_seq;
|
||||
usb_buf[10] = static_seq;
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
89
Controllers/CoolerMasterController/CMARGBGen2A1controller.h
Normal file
89
Controllers/CoolerMasterController/CMARGBGen2A1controller.h
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/*-------------------------------------------------------------------*\
|
||||
| CMARGBGen2A1controller.h |
|
||||
| |
|
||||
| Driver for Coolermaster ARGB Gen 2 A1 USB Controller |
|
||||
| |
|
||||
| morg (Morgan Guimard) 6/26/2022 |
|
||||
| |
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
#define CM_ARGB_GEN2_A1_PACKET_LENGTH 65
|
||||
#define CM_ARGB_GEN2_A1_CHANNEL_MAX_SIZE 48
|
||||
#define CM_ARGB_GEN2_A1_CHANNEL_COUNT 3
|
||||
#define CM_ARGB_GEN2_A1_PACKETS_PER_CHANNEL 3
|
||||
|
||||
enum
|
||||
{
|
||||
CM_ARGB_GEN2_A1_DIRECT_MODE = 0xFF,
|
||||
CM_ARGB_GEN2_A1_SPECTRUM_MODE = 0x00,
|
||||
CM_ARGB_GEN2_A1_STATIC_MODE = 0x01,
|
||||
CM_ARGB_GEN2_A1_RELOAD_MODE = 0x02,
|
||||
CM_ARGB_GEN2_A1_RECOIL_MODE = 0x03,
|
||||
CM_ARGB_GEN2_A1_BREATHING_MODE = 0x04,
|
||||
CM_ARGB_GEN2_A1_REFILL_MODE = 0x05,
|
||||
CM_ARGB_GEN2_A1_DEMO_MODE = 0x06,
|
||||
CM_ARGB_GEN2_A1_FILL_FLOW_MODE = 0x07,
|
||||
CM_ARGB_GEN2_A1_RAINBOW_MODE = 0x08,
|
||||
CM_ARGB_GEN2_A1_CUSTOM_MODE = 0xC0,
|
||||
CM_ARGB_GEN2_A1_OFF_MODE = 0x09
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_ARGB_GEN2_A1_BRIGHTNESS_MAX = 0xFF,
|
||||
CM_ARGB_GEN2_A1_BRIGHTNESS_MIN = 0x00,
|
||||
CM_ARGB_GEN2_A1_SPEED_MAX = 0x04,
|
||||
CM_ARGB_GEN2_A1_SPEED_MIN = 0x00,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_ARGB_GEN2_A1_COMMAND = 0x80,
|
||||
CM_ARGB_GEN2_A1_READ = 0x01,
|
||||
CM_ARGB_GEN2_A1_WRITE = 0x02,
|
||||
CM_ARGB_GEN2_A1_RESPONSE = 0x03
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_ARGB_GEN2_A1_SIZES = 0x06,
|
||||
CM_ARGB_GEN2_A1_FLASH = 0x0B,
|
||||
CM_ARGB_GEN2_A1_IDENTIFY = 0x0A,
|
||||
CM_ARGB_GEN2_A1_LIGHTNING_CONTROL = 0x01,
|
||||
CM_ARGB_GEN2_A1_HW_MODE_SETUP = 0x03,
|
||||
CM_ARGB_GEN2_A1_CUSTOM_SEQUENCES = 0x10,
|
||||
CM_ARGB_GEN2_A1_CUSTOM_SPEED = 0x11
|
||||
|
||||
};
|
||||
|
||||
class CMARGBGen2A1controller
|
||||
{
|
||||
public:
|
||||
CMARGBGen2A1controller(hid_device* dev_handle, const hid_device_info& info);
|
||||
~CMARGBGen2A1controller();
|
||||
|
||||
std::string GetSerialString();
|
||||
std::string GetDeviceLocation();
|
||||
|
||||
void SendDirectChannel(unsigned int zone_id, std::vector<RGBColor> colors);
|
||||
void SetupZoneSize(unsigned int zone_id, unsigned int size);
|
||||
void SetupDirectMode();
|
||||
void SetMode(unsigned int mode_value, unsigned char speed, unsigned char brightness, RGBColor color, bool random);
|
||||
void SetCustomColors(unsigned int zone_id, std::vector<RGBColor> colors);
|
||||
void SaveToFlash();
|
||||
|
||||
private:
|
||||
std::string serial_number;
|
||||
std::string location;
|
||||
bool software_mode_activated = false;
|
||||
hid_device* dev;
|
||||
|
||||
void SetCustomSequence(unsigned int zone_id);
|
||||
std::vector<unsigned char> CreateColorData(std::vector<RGBColor> colors);
|
||||
};
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
#include "RGBController_CMMP750Controller.h"
|
||||
#include "RGBController_CMARGBController.h"
|
||||
#include "RGBController_CMSmallARGBController.h"
|
||||
#include "RGBController_CMARGBGen2A1Controller.h"
|
||||
#include "RGBController_CMRGBController.h"
|
||||
#include "RGBController_CMR6000Controller.h"
|
||||
#include "RGBController_CMMKController.h"
|
||||
|
|
@ -27,6 +28,7 @@
|
|||
#define COOLERMASTER_MP750_L_PID 0x0107
|
||||
#define COOLERMASTER_MP750_MEDIUM_PID 0x0105
|
||||
#define COOLERMASTER_ARGB_PID 0x1011
|
||||
#define COOLERMASTER_ARGB_GEN2_A1_PID 0x0173
|
||||
#define COOLERMASTER_SMALL_ARGB_PID 0x1000
|
||||
#define COOLERMASTER_RGB_PID 0x004F
|
||||
#define COOLERMASTER_RADEON_6000_PID 0x014D
|
||||
|
|
@ -67,6 +69,19 @@ void DetectCoolerMasterARGB(hid_device_info* info, const std::string&)
|
|||
}
|
||||
}
|
||||
|
||||
void DetectCoolerMasterARGBGen2A1(hid_device_info* info, const std::string&)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CMARGBGen2A1controller* controller = new CMARGBGen2A1controller(dev, *info);
|
||||
RGBController_CMARGBGen2A1Controller* rgb_controller = new RGBController_CMARGBGen2A1Controller(controller);
|
||||
// Constructor sets the name
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectCoolerMasterGPU(hid_device_info* info, const std::string&)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
|
@ -170,6 +185,7 @@ REGISTER_HID_DETECTOR_IPU("Cooler Master MK570", DetectCooler
|
|||
REGISTER_HID_DETECTOR_IPU("Cooler Master SK630", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_SK630_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master SK650", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_SK650_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB", DetectCoolerMasterARGB, COOLERMASTER_VID, COOLERMASTER_ARGB_PID, 0, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB Gen 2 A1", DetectCoolerMasterARGBGen2A1, COOLERMASTER_VID, COOLERMASTER_ARGB_GEN2_A1_PID, 1, 0xFF01, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master Small ARGB", DetectCoolerMasterSmallARGB, COOLERMASTER_VID, COOLERMASTER_SMALL_ARGB_PID, 0, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master RGB", DetectCoolerMasterRGB, COOLERMASTER_VID, COOLERMASTER_RGB_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_I ("Cooler Master Radeon 6000 GPU", DetectCoolerMasterGPU, COOLERMASTER_VID, COOLERMASTER_RADEON_6000_PID, 1 );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,305 @@
|
|||
/*-------------------------------------------------------------------*\
|
||||
| RGBController_CMARGBGen2A1Controller.cpp |
|
||||
| |
|
||||
| Driver for Coolermaster ARGB Gen 2 A1 USB Controller |
|
||||
| |
|
||||
| morg (Morgan Guimard) 6/26/2022 |
|
||||
| |
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_CMARGBGen2A1Controller.h"
|
||||
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Coolermaster ARGB A1
|
||||
@category LEDStrip
|
||||
@type USB
|
||||
@save :white_check_mark:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectCoolerMasterARGBGen2A1
|
||||
@comment This device does not have Gen 2 support in OpenRGB yet.
|
||||
|
||||
Gen2 has auto-resize feature and parallel to serial magical stuff.<
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CMARGBGen2A1Controller::RGBController_CMARGBGen2A1Controller(CMARGBGen2A1controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
name = "CoolerMaster LED Controller A1";
|
||||
vendor = "CoolerMaster";
|
||||
type = DEVICE_TYPE_LEDSTRIP;
|
||||
description = name;
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
version = "";
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = CM_ARGB_GEN2_A1_DIRECT_MODE;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Spectrum;
|
||||
Spectrum.name = "Spectrum";
|
||||
Spectrum.value = CM_ARGB_GEN2_A1_SPECTRUM_MODE;
|
||||
Spectrum.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE;
|
||||
Spectrum.color_mode = MODE_COLORS_NONE;
|
||||
Spectrum.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Spectrum.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Spectrum.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Spectrum.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2;
|
||||
Spectrum.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN;
|
||||
Spectrum.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX;
|
||||
modes.push_back(Spectrum);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = CM_ARGB_GEN2_A1_STATIC_MODE;
|
||||
Static.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_MANUAL_SAVE;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Static.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Static.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Reload;
|
||||
Reload.name = "Reload";
|
||||
Reload.value = CM_ARGB_GEN2_A1_RELOAD_MODE;
|
||||
Reload.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_MANUAL_SAVE;
|
||||
Reload.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Reload.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Reload.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Reload.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Reload.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2;
|
||||
Reload.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN;
|
||||
Reload.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX;
|
||||
Reload.colors.resize(1);
|
||||
modes.push_back(Reload);
|
||||
|
||||
mode Recoil;
|
||||
Recoil.name = "Recoil";
|
||||
Recoil.value = CM_ARGB_GEN2_A1_RECOIL_MODE;
|
||||
Recoil.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_MANUAL_SAVE;
|
||||
Recoil.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Recoil.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Recoil.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Recoil.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Recoil.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2;
|
||||
Recoil.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN;
|
||||
Recoil.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX;
|
||||
Recoil.colors.resize(1);
|
||||
modes.push_back(Recoil);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CM_ARGB_GEN2_A1_BREATHING_MODE;
|
||||
Breathing.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_MANUAL_SAVE;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Breathing.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Breathing.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2;
|
||||
Breathing.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN;
|
||||
Breathing.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX;
|
||||
Breathing.colors.resize(1);
|
||||
modes.push_back(Breathing);
|
||||
|
||||
|
||||
mode Refill;
|
||||
Refill.name = "Refill";
|
||||
Refill.value = CM_ARGB_GEN2_A1_REFILL_MODE;
|
||||
Refill.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_MANUAL_SAVE;
|
||||
Refill.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Refill.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Refill.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Refill.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Refill.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2;
|
||||
Refill.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN;
|
||||
Refill.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX;
|
||||
Refill.colors.resize(1);
|
||||
modes.push_back(Refill);
|
||||
|
||||
mode Demo;
|
||||
Demo.name = "Demo";
|
||||
Demo.value = CM_ARGB_GEN2_A1_DEMO_MODE;
|
||||
Demo.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Demo.color_mode = MODE_COLORS_NONE;
|
||||
Demo.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Demo.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Demo.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
modes.push_back(Demo);
|
||||
|
||||
mode FillFlow;
|
||||
FillFlow.name = "Fill Flow";
|
||||
FillFlow.value = CM_ARGB_GEN2_A1_FILL_FLOW_MODE;
|
||||
FillFlow.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE;;
|
||||
FillFlow.color_mode = MODE_COLORS_NONE;
|
||||
FillFlow.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
FillFlow.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
FillFlow.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
FillFlow.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2;
|
||||
FillFlow.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN;
|
||||
FillFlow.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX;
|
||||
modes.push_back(FillFlow);
|
||||
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.value = CM_ARGB_GEN2_A1_RAINBOW_MODE;
|
||||
Rainbow.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE;;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
Rainbow.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Rainbow.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Rainbow.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Rainbow.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2;
|
||||
Rainbow.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN;
|
||||
Rainbow.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
mode Custom;
|
||||
Custom.name = "Custom";
|
||||
Custom.value = CM_ARGB_GEN2_A1_CUSTOM_MODE;
|
||||
Custom.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE;
|
||||
Custom.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Custom);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = CM_ARGB_GEN2_A1_OFF_MODE;
|
||||
Off.flags = MODE_FLAG_MANUAL_SAVE;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_CMARGBGen2A1Controller::~RGBController_CMARGBGen2A1Controller()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::SetupZones()
|
||||
{
|
||||
unsigned int total_leds = 0;
|
||||
|
||||
for(unsigned int channel = 0; channel < CM_ARGB_GEN2_A1_CHANNEL_COUNT; channel++)
|
||||
{
|
||||
zone new_zone;
|
||||
|
||||
new_zone.name = "Channel " + std::to_string(channel + 1);
|
||||
new_zone.type = ZONE_TYPE_LINEAR;
|
||||
new_zone.leds_min = 0;
|
||||
new_zone.leds_max = CM_ARGB_GEN2_A1_CHANNEL_MAX_SIZE;
|
||||
new_zone.leds_count = 0;
|
||||
new_zone.matrix_map = nullptr;
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
total_leds += new_zone.leds_count;
|
||||
}
|
||||
|
||||
leds.resize(total_leds);
|
||||
|
||||
for(unsigned int i = 0; i < total_leds; i++)
|
||||
{
|
||||
leds[i].name = "LED " + std::to_string(i + 1);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::ResizeZone(int zone, int new_size)
|
||||
{
|
||||
zones[zone].leds_count = new_size;
|
||||
|
||||
// todo: refactor with above code
|
||||
unsigned int total_leds = 0;
|
||||
|
||||
for(unsigned int channel = 0; channel < CM_ARGB_GEN2_A1_CHANNEL_COUNT; channel++)
|
||||
{
|
||||
total_leds += zones[channel].leds_count;
|
||||
}
|
||||
|
||||
leds.resize(total_leds);
|
||||
|
||||
for(unsigned int i = 0; i < total_leds; i++)
|
||||
{
|
||||
leds[i].name = "LED " + std::to_string(i + 1);
|
||||
}
|
||||
|
||||
controller->SetupZoneSize(zone, new_size);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::DeviceUpdateLEDs()
|
||||
{
|
||||
for(unsigned int channel = 0; channel < CM_ARGB_GEN2_A1_CHANNEL_COUNT; channel ++)
|
||||
{
|
||||
UpdateZoneLEDs(channel);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
if(zones[zone].leds_count > 0)
|
||||
{
|
||||
unsigned int start = zones[zone].start_idx;
|
||||
unsigned int end = start + zones[zone].leds_count;
|
||||
|
||||
std::vector<RGBColor> zone_colors(colors.begin() + start , colors.begin() + end);
|
||||
|
||||
if(modes[active_mode].value == CM_ARGB_GEN2_A1_DIRECT_MODE)
|
||||
{
|
||||
controller->SendDirectChannel(zone, zone_colors);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetCustomColors(zone, zone_colors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::SetCustomMode()
|
||||
{
|
||||
active_mode = 0;
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::DeviceUpdateMode()
|
||||
{
|
||||
const mode& active = modes[active_mode];
|
||||
|
||||
if(active.value == CM_ARGB_GEN2_A1_DIRECT_MODE)
|
||||
{
|
||||
controller->SetupDirectMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
RGBColor color = active.color_mode == MODE_COLORS_MODE_SPECIFIC ?
|
||||
active.colors[0] : 0;
|
||||
|
||||
controller->SetMode
|
||||
(
|
||||
active.value,
|
||||
active.speed,
|
||||
active.brightness,
|
||||
color,
|
||||
active.color_mode == MODE_COLORS_RANDOM
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::DeviceSaveMode()
|
||||
{
|
||||
controller->SaveToFlash();
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*-------------------------------------------------------------------*\
|
||||
| RGBController_CMARGBGen2A1Controller.h |
|
||||
| |
|
||||
| Driver for Coolermaster ARGB Controller |
|
||||
| |
|
||||
| morg (Morgan Guimard) 6/26/2022 |
|
||||
| |
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
#include "RGBController.h"
|
||||
#include "CMARGBGen2A1controller.h"
|
||||
#include <vector>
|
||||
|
||||
class RGBController_CMARGBGen2A1Controller : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CMARGBGen2A1Controller(CMARGBGen2A1controller* controller_ptr);
|
||||
~RGBController_CMARGBGen2A1Controller();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
void SetCustomMode();
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
CMARGBGen2A1controller* controller;
|
||||
};
|
||||
|
|
@ -284,6 +284,7 @@ HEADERS +=
|
|||
Controllers/BlinkyTapeController/BlinkyTapeController.h \
|
||||
Controllers/BlinkyTapeController/RGBController_BlinkyTape.h \
|
||||
Controllers/CoolerMasterController/CMARGBcontroller.h \
|
||||
Controllers/CoolerMasterController/CMARGBGen2A1controller.h \
|
||||
Controllers/CoolerMasterController/CMMKController.h \
|
||||
Controllers/CoolerMasterController/CMMMController.h \
|
||||
Controllers/CoolerMasterController/CMMM711Controller.h \
|
||||
|
|
@ -292,6 +293,7 @@ HEADERS +=
|
|||
Controllers/CoolerMasterController/CMRGBController.h \
|
||||
Controllers/CoolerMasterController/CMSmallARGBController.h \
|
||||
Controllers/CoolerMasterController/RGBController_CMARGBController.h \
|
||||
Controllers/CoolerMasterController/RGBController_CMARGBGen2A1Controller.h \
|
||||
Controllers/CoolerMasterController/RGBController_CMMKController.h \
|
||||
Controllers/CoolerMasterController/RGBController_CMMMController.h \
|
||||
Controllers/CoolerMasterController/RGBController_CMMM711Controller.h \
|
||||
|
|
@ -749,6 +751,7 @@ SOURCES +=
|
|||
Controllers/BlinkyTapeController/BlinkyTapeControllerDetect.cpp \
|
||||
Controllers/BlinkyTapeController/RGBController_BlinkyTape.cpp \
|
||||
Controllers/CoolerMasterController/CMARGBcontroller.cpp \
|
||||
Controllers/CoolerMasterController/CMARGBGen2A1controller.cpp \
|
||||
Controllers/CoolerMasterController/CMMKController.cpp \
|
||||
Controllers/CoolerMasterController/CMMMController.cpp \
|
||||
Controllers/CoolerMasterController/CMMM711Controller.cpp \
|
||||
|
|
@ -758,6 +761,7 @@ SOURCES +=
|
|||
Controllers/CoolerMasterController/CMSmallARGBController.cpp \
|
||||
Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp \
|
||||
Controllers/CoolerMasterController/RGBController_CMARGBController.cpp \
|
||||
Controllers/CoolerMasterController/RGBController_CMARGBGen2A1Controller.cpp \
|
||||
Controllers/CoolerMasterController/RGBController_CMMKController.cpp \
|
||||
Controllers/CoolerMasterController/RGBController_CMMMController.cpp \
|
||||
Controllers/CoolerMasterController/RGBController_CMMM711Controller.cpp \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue