Skip to content

Commit 4509b9d

Browse files
Initial support for Logitech G910 Orion Spectrum - G Keys and G910 bottom logo not working yet
1 parent 4287128 commit 4509b9d

6 files changed

Lines changed: 773 additions & 0 deletions

File tree

Controllers/LogitechController/LogitechControllerDetect.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
#include "LogitechG213Controller.h"
44
#include "LogitechG560Controller.h"
55
#include "LogitechG810Controller.h"
6+
#include "LogitechG910Controller.h"
67
#include "LogitechG815Controller.h"
78
#include "LogitechGLightsyncController.h"
89
#include "RGBController.h"
910
#include "RGBController_LogitechG203L.h"
1011
#include "RGBController_LogitechG213.h"
1112
#include "RGBController_LogitechG560.h"
1213
#include "RGBController_LogitechG810.h"
14+
#include "RGBController_LogitechG910.h"
1315
#include "RGBController_LogitechG815.h"
1416
#include "RGBController_LogitechGLightsync.h"
1517
#include "RGBController_LogitechGLightsync1zone.h"
@@ -35,6 +37,7 @@
3537
#define LOGITECH_G810_2_PID 0xC337
3638
#define LOGITECH_G813_PID 0xC232
3739
#define LOGITECH_G815_PID 0xC33F
40+
#define LOGITECH_G910_PID 0xC335
3841

3942
/*-----------------------------------------------------*\
4043
| Mouse product IDs |
@@ -147,6 +150,65 @@ void DetectLogitechKeyboardG810(hid_device_info* info, const std::string& name)
147150
#endif
148151
}
149152

153+
void DetectLogitechKeyboardG910(hid_device_info* info, const std::string& name)
154+
{
155+
/*-------------------------------------------------------------------------------------------------*\
156+
| Logitech keyboards use two different usages, one for 20-byte packets and one for 64-byte packets |
157+
| Usage 0x0602 for 20 byte, usage 0x0604 for 64 byte, both are on usage page 0xFF43 |
158+
\*-------------------------------------------------------------------------------------------------*/
159+
#ifdef USE_HID_USAGE
160+
hid_device* dev_usage_0x0602 = nullptr;
161+
hid_device* dev_usage_0x0604 = nullptr;
162+
hid_device_info* info_temp = info;
163+
164+
while(info_temp)
165+
{
166+
if(info_temp->vendor_id == info->vendor_id // constant LOGITECH_VID
167+
&& info_temp->product_id == info->product_id // NON-constant
168+
&& info_temp->interface_number == info->interface_number // constant 1
169+
&& info_temp->usage_page == info->usage_page) // constant 0xFF43
170+
{
171+
if(info_temp->usage == 0x0602)
172+
{
173+
dev_usage_0x0602 = hid_open_path(info_temp->path);
174+
}
175+
else if(info_temp->usage == 0x0604)
176+
{
177+
dev_usage_0x0604 = hid_open_path(info_temp->path);
178+
}
179+
}
180+
if(dev_usage_0x0602 && dev_usage_0x0604)
181+
{
182+
break;
183+
}
184+
info_temp = info_temp->next;
185+
}
186+
if(dev_usage_0x0602 && dev_usage_0x0604)
187+
{
188+
LogitechG910Controller* controller = new LogitechG910Controller(dev_usage_0x0602, dev_usage_0x0604);
189+
RGBController_LogitechG910* rgb_controller = new RGBController_LogitechG910(controller);
190+
rgb_controller->name = name;
191+
ResourceManager::get()->RegisterRGBController(rgb_controller);
192+
}
193+
else
194+
{
195+
// Not all of them could be opened, do some cleanup
196+
hid_close(dev_usage_0x0602);
197+
hid_close(dev_usage_0x0604);
198+
}
199+
#else
200+
hid_device* dev = hid_open_path(info->path);
201+
202+
if(dev)
203+
{
204+
LogitechG910Controller* controller = new LogitechG910Controller(dev, dev);
205+
RGBController_LogitechG910* rgb_controller = new RGBController_LogitechG910(controller);
206+
rgb_controller->name = name;
207+
ResourceManager::get()->RegisterRGBController(rgb_controller);
208+
}
209+
#endif
210+
}
211+
150212
void DetectLogitechKeyboardG815(hid_device_info* info, const std::string& name)
151213
{
152214
/*-------------------------------------------------------------------------------------------------*\
@@ -461,6 +523,7 @@ REGISTER_HID_DETECTOR_IP ("Logitech G810 Orion Spectrum", Dete
461523
REGISTER_HID_DETECTOR_IP ("Logitech G810 Orion Spectrum", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G810_2_PID, 1, 0xFF43);
462524
REGISTER_HID_DETECTOR_IP ("Logitech G813 RGB Mechanical Gaming Keyboard", DetectLogitechKeyboardG815, LOGITECH_VID, LOGITECH_G813_PID, 1, 0xFF43);
463525
REGISTER_HID_DETECTOR_IP ("Logitech G815 RGB Mechanical Gaming Keyboard", DetectLogitechKeyboardG815, LOGITECH_VID, LOGITECH_G815_PID, 1, 0xFF43);
526+
REGISTER_HID_DETECTOR_IP ("Logitech G910 Orion Spectrum", DetectLogitechKeyboardG910, LOGITECH_VID, LOGITECH_G910_PID, 1, 0xFF43);
464527
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
465528
| Mice |
466529
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/*-----------------------------------------*\
2+
| LogitechG910Controller.cpp |
3+
| |
4+
| Driver for Logitech G910 Orion Spectrum |
5+
| keyboard light controller |
6+
| |
7+
| Adam Honse (CalcProgrammer1) 6/11/2020 |
8+
\*-----------------------------------------*/
9+
10+
#include "LogitechG910Controller.h"
11+
#include <cstring>
12+
13+
LogitechG910Controller::LogitechG910Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12)
14+
{
15+
dev_pkt_0x11 = dev_handle_0x11;
16+
dev_pkt_0x12 = dev_handle_0x12;
17+
}
18+
19+
LogitechG910Controller::~LogitechG910Controller()
20+
{
21+
hid_close(dev_pkt_0x11);
22+
hid_close(dev_pkt_0x12);
23+
}
24+
25+
std::string LogitechG910Controller::GetSerialString()
26+
{
27+
wchar_t serial_string[128];
28+
hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
29+
30+
std::wstring return_wstring = serial_string;
31+
std::string return_string(return_wstring.begin(), return_wstring.end());
32+
33+
return(return_string);
34+
}
35+
36+
void LogitechG910Controller::Commit()
37+
{
38+
SendCommit();
39+
}
40+
41+
void LogitechG910Controller::SetDirect
42+
(
43+
unsigned char zone,
44+
unsigned char frame_count,
45+
unsigned char * frame_data
46+
)
47+
{
48+
SendDirectFrame(zone, frame_count, frame_data);
49+
}
50+
51+
void LogitechG910Controller::SetMode
52+
(
53+
unsigned char mode,
54+
unsigned short speed,
55+
unsigned char red,
56+
unsigned char green,
57+
unsigned char blue
58+
)
59+
{
60+
SendMode(LOGITECH_G910_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
61+
SendMode(LOGITECH_G910_ZONE_MODE_LOGO, mode, speed, red, green, blue);
62+
63+
SendCommit();
64+
}
65+
66+
/*-------------------------------------------------------------------------------------------------*\
67+
| Private packet sending functions. |
68+
\*-------------------------------------------------------------------------------------------------*/
69+
70+
void LogitechG910Controller::SendCommit()
71+
{
72+
char usb_buf[20];
73+
74+
/*-----------------------------------------------------*\
75+
| Zero out buffer |
76+
\*-----------------------------------------------------*/
77+
memset(usb_buf, 0x00, sizeof(usb_buf));
78+
79+
/*-----------------------------------------------------*\
80+
| Set up Commit packet |
81+
\*-----------------------------------------------------*/
82+
usb_buf[0x00] = 0x11;
83+
usb_buf[0x01] = 0xFF;
84+
usb_buf[0x02] = 0x0F;
85+
usb_buf[0x03] = 0x5F;
86+
87+
/*-----------------------------------------------------*\
88+
| Send packet |
89+
\*-----------------------------------------------------*/
90+
hid_write(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
91+
hid_read(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
92+
}
93+
94+
void LogitechG910Controller::SendDirectFrame
95+
(
96+
unsigned char zone,
97+
unsigned char frame_count,
98+
unsigned char * frame_data
99+
)
100+
{
101+
char usb_buf[64];
102+
103+
/*-----------------------------------------------------*\
104+
| Zero out buffer |
105+
\*-----------------------------------------------------*/
106+
memset(usb_buf, 0x00, sizeof(usb_buf));
107+
108+
/*-----------------------------------------------------*\
109+
| Set up Lighting Control packet |
110+
\*-----------------------------------------------------*/
111+
usb_buf[0x00] = 0x12;
112+
usb_buf[0x01] = 0xFF;
113+
usb_buf[0x02] = 0x0F;
114+
usb_buf[0x03] = 0x3F;
115+
usb_buf[0x05] = zone;
116+
usb_buf[0x07] = frame_count;
117+
118+
/*-----------------------------------------------------*\
119+
| Copy in frame data |
120+
\*-----------------------------------------------------*/
121+
memcpy(&usb_buf[0x08], frame_data, frame_count * 4);
122+
123+
/*-----------------------------------------------------*\
124+
| Send packet |
125+
\*-----------------------------------------------------*/
126+
hid_write(dev_pkt_0x12, (unsigned char *)usb_buf, 64);
127+
hid_read(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
128+
}
129+
130+
void LogitechG910Controller::SendMode
131+
(
132+
unsigned char zone,
133+
unsigned char mode,
134+
unsigned short speed,
135+
unsigned char red,
136+
unsigned char green,
137+
unsigned char blue
138+
)
139+
{
140+
char usb_buf[20];
141+
142+
/*-----------------------------------------------------*\
143+
| Zero out buffer |
144+
\*-----------------------------------------------------*/
145+
memset(usb_buf, 0x00, sizeof(usb_buf));
146+
147+
/*-----------------------------------------------------*\
148+
| Set up Lighting Control packet |
149+
\*-----------------------------------------------------*/
150+
usb_buf[0x00] = 0x11;
151+
usb_buf[0x01] = 0xFF;
152+
usb_buf[0x02] = 0x10;
153+
usb_buf[0x03] = 0x3B;
154+
usb_buf[0x04] = zone;
155+
156+
usb_buf[0x05] = mode;
157+
158+
usb_buf[0x06] = red;
159+
usb_buf[0x07] = green;
160+
usb_buf[0x08] = blue;
161+
162+
speed = 100 * speed;
163+
if(mode == LOGITECH_G910_MODE_CYCLE)
164+
{
165+
usb_buf[0x0B] = speed >> 8;
166+
usb_buf[0x0C] = speed & 0xFF;
167+
usb_buf[0x0D] = 0x64;
168+
}
169+
else if(mode == LOGITECH_G910_MODE_BREATHING)
170+
{
171+
usb_buf[0x09] = speed >> 8;
172+
usb_buf[0x0A] = speed & 0xFF;
173+
usb_buf[0x0C] = 0x64;
174+
}
175+
176+
/*-----------------------------------------------------*\
177+
| Send packet |
178+
\*-----------------------------------------------------*/
179+
hid_write(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
180+
hid_read(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
181+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*-----------------------------------------*\
2+
| LogitechG910Controller.h |
3+
| |
4+
| Definitions and types for Logitech G910 |
5+
| Orion Spectrum keyboard light controller |
6+
| |
7+
| Adam Honse (CalcProgrammer1) 6/11/2020 |
8+
\*-----------------------------------------*/
9+
10+
#include "RGBController.h"
11+
12+
#include <string>
13+
#include <hidapi/hidapi.h>
14+
15+
#pragma once
16+
17+
enum
18+
{
19+
LOGITECH_G910_ZONE_MODE_KEYBOARD = 0x00,
20+
LOGITECH_G910_ZONE_MODE_LOGO = 0x01,
21+
};
22+
23+
enum
24+
{
25+
LOGITECH_G910_ZONE_DIRECT_KEYBOARD = 0x01,
26+
LOGITECH_G910_ZONE_DIRECT_MEDIA = 0x02,
27+
LOGITECH_G910_ZONE_DIRECT_LOGO = 0x10,
28+
LOGITECH_G910_ZONE_DIRECT_INDICATORS = 0x40,
29+
};
30+
31+
enum
32+
{
33+
LOGITECH_G910_MODE_OFF = 0x00,
34+
LOGITECH_G910_MODE_STATIC = 0x01,
35+
LOGITECH_G910_MODE_BREATHING = 0x02,
36+
LOGITECH_G910_MODE_CYCLE = 0x03,
37+
LOGITECH_G910_MODE_WAVE = 0x04,
38+
};
39+
40+
/*---------------------------------------------------------------------------------------------*\
41+
| Speed is 1000 for fast and 20000 for slow. |
42+
| Values are multiplied by 100 later to give lots of GUI steps. |
43+
\*---------------------------------------------------------------------------------------------*/
44+
enum
45+
{
46+
LOGITECH_G910_SPEED_SLOWEST = 0xC8, /* Slowest speed */
47+
LOGITECH_G910_SPEED_NORMAL = 0x32, /* Normal speed */
48+
LOGITECH_G910_SPEED_FASTEST = 0x0A, /* Fastest speed */
49+
};
50+
51+
class LogitechG910Controller
52+
{
53+
public:
54+
LogitechG910Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12);
55+
~LogitechG910Controller();
56+
57+
std::string GetSerialString();
58+
59+
void Commit();
60+
61+
void SetDirect
62+
(
63+
unsigned char zone,
64+
unsigned char frame_count,
65+
unsigned char * frame_data
66+
);
67+
68+
void SetMode
69+
(
70+
unsigned char mode,
71+
unsigned short speed,
72+
unsigned char red,
73+
unsigned char green,
74+
unsigned char blue
75+
);
76+
77+
private:
78+
hid_device* dev_pkt_0x11;
79+
hid_device* dev_pkt_0x12;
80+
81+
void SendDirectFrame
82+
(
83+
unsigned char zone,
84+
unsigned char frame_count,
85+
unsigned char * frame_data
86+
);
87+
88+
void SendMode
89+
(
90+
unsigned char zone,
91+
unsigned char mode,
92+
unsigned short speed,
93+
unsigned char red,
94+
unsigned char green,
95+
unsigned char blue
96+
);
97+
98+
void SendCommit();
99+
};

0 commit comments

Comments
 (0)