Skip to content

Commit 86ba185

Browse files
moooorgCalcProgrammer1
authored andcommitted
Add support for CoolerMaster GM27. Closes #3627
1 parent 3c7a24c commit 86ba185

File tree

6 files changed

+597
-1
lines changed

6 files changed

+597
-1
lines changed
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
/*-------------------------------------------------------------------*\
2+
| CMMonitorController.cpp |
3+
| |
4+
| Driver for Coolermaster Gaming Monitor |
5+
| |
6+
| morg (Morgan Guimard) 9/18/2023 |
7+
| |
8+
\*-------------------------------------------------------------------*/
9+
10+
#include "CMMonitorController.h"
11+
#include <cstring>
12+
13+
using namespace std::chrono_literals;
14+
15+
CMMonitorController::CMMonitorController(hid_device* dev_handle, const hid_device_info& info)
16+
{
17+
dev = dev_handle;
18+
location = info.path;
19+
20+
wchar_t serial_string[128];
21+
int ret = hid_get_serial_number_string(dev, serial_string, 128);
22+
23+
if(ret != 0)
24+
{
25+
serial_number = "";
26+
}
27+
else
28+
{
29+
std::wstring return_wstring = serial_string;
30+
serial_number = std::string(return_wstring.begin(), return_wstring.end());
31+
}
32+
}
33+
34+
CMMonitorController::~CMMonitorController()
35+
{
36+
hid_close(dev);
37+
}
38+
39+
std::string CMMonitorController::GetDeviceLocation()
40+
{
41+
return("HID: " + location);
42+
}
43+
44+
std::string CMMonitorController::GetSerialString()
45+
{
46+
return(serial_number);
47+
}
48+
49+
void CMMonitorController::SetMode(uint8_t mode_value, const RGBColor& color, uint8_t speed, uint8_t brightness)
50+
{
51+
if(software_mode_enabled)
52+
{
53+
DisableSoftwareMode();
54+
}
55+
56+
uint8_t usb_buf[CM_MONITOR_PACKET_LENGTH];
57+
memset(usb_buf, 0x00, CM_MONITOR_PACKET_LENGTH);
58+
59+
usb_buf[1] = 0x80;
60+
usb_buf[2] = (mode_value == CM_MONITOR_OFF_MODE) ? 0x0F : 0x0B;
61+
usb_buf[3] = 0x02;
62+
usb_buf[4] = 0x02;
63+
usb_buf[5] = mode_value;
64+
usb_buf[6] = (mode_value == CM_MONITOR_OFF_MODE) ? 0x00 : 0x08;;
65+
usb_buf[7] = speed;
66+
usb_buf[8] = brightness;
67+
usb_buf[9] = RGBGetRValue(color);
68+
usb_buf[10] = RGBGetGValue(color);
69+
usb_buf[11] = RGBGetBValue(color);
70+
71+
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
72+
}
73+
74+
void CMMonitorController::SetCustomMode(const std::vector<RGBColor>& colors, uint8_t brightnesss)
75+
{
76+
if(software_mode_enabled)
77+
{
78+
DisableSoftwareMode();
79+
}
80+
81+
/*---------------------------------------------------------*\
82+
| Creates the color buffer |
83+
\*---------------------------------------------------------*/
84+
uint8_t color_data[CM_MONITOR_COLOR_DATA_LENGTH];
85+
memset(color_data, 0x00, CM_MONITOR_COLOR_DATA_LENGTH);
86+
87+
uint8_t offset = 0;
88+
89+
for(const RGBColor& color: colors)
90+
{
91+
color_data[offset++] = RGBGetRValue(color);
92+
color_data[offset++] = RGBGetGValue(color);
93+
color_data[offset++] = RGBGetBValue(color);
94+
}
95+
96+
/*---------------------------------------------------------*\
97+
| Sends the 8 sequence packets |
98+
\*---------------------------------------------------------*/
99+
uint8_t usb_buf[CM_MONITOR_PACKET_LENGTH];
100+
101+
offset = 0;
102+
103+
for(unsigned int i = 0; i < 7; i++)
104+
{
105+
memset(usb_buf, 0x00, CM_MONITOR_PACKET_LENGTH);
106+
107+
usb_buf[1] = i < 6 ? i : 0x86;
108+
109+
/*---------------------------------------------------------*\
110+
| First packet contains static data |
111+
\*---------------------------------------------------------*/
112+
if(i == 0)
113+
{
114+
usb_buf[2] = 0x10;
115+
usb_buf[3] = 0x02;
116+
usb_buf[4] = 0x02;
117+
usb_buf[5] = 0x80;
118+
usb_buf[6] = brightnesss;
119+
120+
memcpy(&usb_buf[7], &color_data[offset], CM_MONITOR_PACKET_LENGTH - 7);
121+
offset += 58;
122+
}
123+
else
124+
{
125+
memcpy(&usb_buf[2], &color_data[offset], CM_MONITOR_PACKET_LENGTH - 2);
126+
offset += (CM_MONITOR_PACKET_LENGTH -2);
127+
}
128+
129+
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
130+
}
131+
}
132+
133+
void CMMonitorController::SendDirect(const std::vector<RGBColor>& colors)
134+
{
135+
if(!software_mode_enabled)
136+
{
137+
EnableSoftwareMode();
138+
}
139+
140+
/*---------------------------------------------------------*\
141+
| Creates the color buffer |
142+
\*---------------------------------------------------------*/
143+
uint8_t color_data[CM_MONITOR_COLOR_DATA_LENGTH];
144+
memset(color_data, 0x00, CM_MONITOR_COLOR_DATA_LENGTH);
145+
146+
unsigned int offset = 0;
147+
148+
for(const RGBColor& color: colors)
149+
{
150+
color_data[offset++] = RGBGetRValue(color);
151+
color_data[offset++] = RGBGetGValue(color);
152+
color_data[offset++] = RGBGetBValue(color);
153+
}
154+
155+
/*---------------------------------------------------------*\
156+
| Sends the 14 sequence packets |
157+
\*---------------------------------------------------------*/
158+
uint8_t usb_buf[CM_MONITOR_PACKET_LENGTH];
159+
160+
for(unsigned int p = 0; p < 2; p++)
161+
{
162+
offset = 0;
163+
164+
for(unsigned int i = 0; i < 7; i++)
165+
{
166+
memset(usb_buf, 0x00, CM_MONITOR_PACKET_LENGTH);
167+
168+
usb_buf[1] = i < 6 ? i : 0x86;
169+
170+
if(i == 0)
171+
{
172+
usb_buf[2] = 0x07;
173+
usb_buf[3] = 0x02;
174+
usb_buf[4] = p + 1;
175+
usb_buf[5] = 0x01;
176+
usb_buf[6] = 0x80;
177+
178+
memcpy(&usb_buf[7], &color_data[offset], CM_MONITOR_PACKET_LENGTH - 7);
179+
offset += CM_MONITOR_PACKET_LENGTH - 7;
180+
}
181+
else
182+
{
183+
memcpy(&usb_buf[2], &color_data[offset], CM_MONITOR_PACKET_LENGTH - 2);
184+
offset += (CM_MONITOR_PACKET_LENGTH -2);
185+
}
186+
187+
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
188+
}
189+
}
190+
}
191+
192+
void CMMonitorController::EnableSoftwareMode()
193+
{
194+
uint8_t usb_buf[CM_MONITOR_PACKET_LENGTH];
195+
memset(usb_buf, 0x00, CM_MONITOR_PACKET_LENGTH);
196+
197+
usb_buf[1] = 0x80;
198+
usb_buf[2] = 0x07;
199+
usb_buf[3] = 0x02;
200+
usb_buf[4] = 0x01;
201+
usb_buf[6] = 0x01;
202+
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
203+
204+
usb_buf[4] = 0x02;
205+
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
206+
207+
uint8_t read_buf[CM_MONITOR_PACKET_LENGTH];
208+
209+
/*---------------------------------------------------------*\
210+
| We have to send a few black packets, with some read ones |
211+
\*---------------------------------------------------------*/
212+
for(unsigned int p = 0; p < 4; p++)
213+
{
214+
for(unsigned int i = 0; i < 7; i++)
215+
{
216+
memset(usb_buf, 0x00, CM_MONITOR_PACKET_LENGTH);
217+
218+
usb_buf[1] = i < 6 ? i : 0x86;
219+
220+
if(i == 0)
221+
{
222+
usb_buf[2] = 0x07;
223+
usb_buf[3] = 0x02;
224+
usb_buf[4] = (p == 0 || p == 0 ) ? 0x01 : 0x02;
225+
usb_buf[5] = 0x01;
226+
usb_buf[6] = 0x80;
227+
}
228+
229+
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
230+
231+
if(p ==0 && (i == 2 || i == 4))
232+
{
233+
memset(read_buf, 0x00, CM_MONITOR_PACKET_LENGTH);
234+
hid_read(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
235+
}
236+
}
237+
}
238+
239+
software_mode_enabled = true;
240+
}
241+
242+
void CMMonitorController::DisableSoftwareMode()
243+
{
244+
uint8_t usb_buf[CM_MONITOR_PACKET_LENGTH];
245+
memset(usb_buf, 0x00, CM_MONITOR_PACKET_LENGTH);
246+
247+
usb_buf[1] = 0x80;
248+
usb_buf[2] = 0x07;
249+
usb_buf[3] = 0x02;
250+
usb_buf[4] = 0x01;
251+
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
252+
253+
usb_buf[4] = 0x02;
254+
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
255+
256+
software_mode_enabled = false;
257+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*-------------------------------------------------------------------*\
2+
| CMMonitorController.cpp |
3+
| |
4+
| Driver for Coolermaster Gaming Monitor |
5+
| |
6+
| morg (Morgan Guimard) 9/18/2023 |
7+
| |
8+
\*-------------------------------------------------------------------*/
9+
10+
#include "RGBController.h"
11+
#include <string>
12+
#include <hidapi/hidapi.h>
13+
14+
#pragma once
15+
16+
#define CM_MONITOR_PACKET_LENGTH 65
17+
#define CM_MONITOR_COLOR_DATA_LENGTH 436
18+
19+
enum
20+
{
21+
CM_MONITOR_DIRECT_MODE = 0xFF,
22+
CM_MONITOR_CUSTOM_MODE = 0xFE,
23+
CM_MONITOR_SPECTRUM_MODE = 0x00,
24+
CM_MONITOR_RELOAD_MODE = 0x01,
25+
CM_MONITOR_RECOIL_MODE = 0x02,
26+
CM_MONITOR_BREATHING_MODE = 0x03,
27+
CM_MONITOR_REFILL_MODE = 0x04,
28+
CM_MONITOR_OFF_MODE = 0x06
29+
};
30+
31+
enum
32+
{
33+
CM_MONITOR_BRIGHTNESS_MAX = 0xFF,
34+
CM_MONITOR_BRIGHTNESS_MIN = 0x00,
35+
CM_MONITOR_SPEED_MAX = 0x04,
36+
CM_MONITOR_SPEED_MIN = 0x00,
37+
};
38+
39+
class CMMonitorController
40+
{
41+
public:
42+
CMMonitorController(hid_device* dev_handle, const hid_device_info& info);
43+
~CMMonitorController();
44+
45+
std::string GetSerialString();
46+
std::string GetDeviceLocation();
47+
void SendDirect(const std::vector<RGBColor>& colors);
48+
void SetMode(uint8_t mode_value, const RGBColor& color, uint8_t speed, uint8_t brightness);
49+
void SetCustomMode(const std::vector<RGBColor>& colors, uint8_t brightnesss);
50+
private:
51+
std::string serial_number;
52+
std::string location;
53+
hid_device* dev;
54+
bool software_mode_enabled = false;
55+
void EnableSoftwareMode();
56+
void DisableSoftwareMode();
57+
};

Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#include "RGBController_CMRGBController.h"
1919
#include "RGBController_CMR6000Controller.h"
2020
#include "RGBController_CMMKController.h"
21-
21+
#include "RGBController_CMMonitorController.h"
2222
/*-----------------------------------------------------*\
2323
| Coolermaster USB vendor ID |
2424
\*-----------------------------------------------------*/
@@ -64,6 +64,11 @@
6464
#define COOLERMASTER_MP750_L_PID 0x0107
6565
#define COOLERMASTER_MP750_MEDIUM_PID 0x0105
6666

67+
/*-----------------------------------------------------*\
68+
| Coolermaster Monitors |
69+
\*-----------------------------------------------------*/
70+
#define COOLERMASTER_GM27_FQS_PID 0x01BB
71+
6772
/******************************************************************************************\
6873
* *
6974
* DetectCoolerMasterControllers *
@@ -207,6 +212,19 @@ void DetectCoolerMasterSmallARGB(hid_device_info* info, const std::string&)
207212
}
208213
}
209214

215+
void DetectCoolerMasterMonitor(hid_device_info* info, const std::string& name)
216+
{
217+
hid_device* dev = hid_open_path(info->path);
218+
219+
if(dev)
220+
{
221+
CMMonitorController* controller = new CMMonitorController(dev, *info);
222+
RGBController_CMMonitorController* rgb_controller = new RGBController_CMMonitorController(controller);
223+
rgb_controller->name = name;
224+
ResourceManager::get()->RegisterRGBController(rgb_controller);
225+
}
226+
}
227+
210228
/*-----------------------------------------------------*\
211229
| Coolermaster Keyboards |
212230
\*-----------------------------------------------------*/
@@ -248,3 +266,8 @@ REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 Medium", DetectCooler
248266
\*-----------------------------------------------------*/
249267
REGISTER_HID_DETECTOR_I ("Cooler Master Radeon 6000 GPU", DetectCoolerMasterGPU, COOLERMASTER_VID, COOLERMASTER_RADEON_6000_PID, 1 );
250268
REGISTER_HID_DETECTOR_I ("Cooler Master Radeon 6900 GPU", DetectCoolerMasterGPU, COOLERMASTER_VID, COOLERMASTER_RADEON_6900_PID, 1 );
269+
270+
/*-----------------------------------------------------*\
271+
| Coolermaster Monitors |
272+
\*-----------------------------------------------------*/
273+
REGISTER_HID_DETECTOR_IPU("Cooler Master GM27-FQS ARGB Monitor", DetectCoolerMasterMonitor, COOLERMASTER_VID, COOLERMASTER_GM27_FQS_PID, 0, 0xFF00, 1);

0 commit comments

Comments
 (0)