Add support for Cooler Master Addressable Gen 2 RGB LED Controller A1. Closes #2256

This commit is contained in:
morg 2022-07-18 23:58:44 +00:00 committed by Adam Honse
parent bba7fa9fd2
commit c0851f3b1e
6 changed files with 819 additions and 0 deletions

View 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));
}

View 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);
};

View file

@ -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 );

View file

@ -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();
}

View file

@ -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;
};

View file

@ -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 \