Logitech G915 TKL mode support

This commit is contained in:
Lanzaa
2022-05-05 22:56:30 +00:00
committed by Adam Honse
parent 817d5d55df
commit 04ba474030
3 changed files with 218 additions and 43 deletions

View File

@@ -16,6 +16,7 @@ LogitechG915Controller::LogitechG915Controller(hid_device* dev_handle, bool wire
if(wired)
{
device_index = 0xFF;
feature_4522_idx = 0x0E;
feature_8040_idx = 0x13;
feature_8071_idx = 0x09;
@@ -23,6 +24,7 @@ LogitechG915Controller::LogitechG915Controller(hid_device* dev_handle, bool wire
}
else
{
device_index = 0x01;
feature_4522_idx = 0x0F;
feature_8040_idx = 0x14;
feature_8071_idx = 0x0A;
@@ -69,14 +71,42 @@ void LogitechG915Controller::SetMode
(
unsigned char mode,
unsigned short speed,
unsigned short brightness,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
SendMode(LOGITECH_G915_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
SendMode(LOGITECH_G915_ZONE_MODE_LOGO, mode, speed, red, green, blue);
SendCommit();
BeginModeSet();
uint8_t logo_mode = mode;
switch(mode)
{
case LOGITECH_G915_MODE_OFF:
case LOGITECH_G915_MODE_STATIC:
{
logo_mode = mode; // static and off match
break;
}
case LOGITECH_G915_MODE_BREATHING:
{
logo_mode = LOGITECH_G915_LOGO_MODE_BREATHING; //0x03
break;
}
case LOGITECH_G915_MODE_CYCLE:
case LOGITECH_G915_MODE_WAVE:
{
logo_mode = LOGITECH_G915_LOGO_MODE_CYCLE; //0x02
break;
}
case LOGITECH_G915_MODE_RIPPLE:
{
logo_mode = LOGITECH_G915_LOGO_MODE_STATIC;
break;
}
}
SendMode(LOGITECH_G915_ZONE_MODE_KEYBOARD, mode, speed, brightness, red, green, blue);
SendMode(LOGITECH_G915_ZONE_MODE_LOGO, logo_mode, speed, brightness, red, green, blue);
}
/*-------------------------------------------------------------------------------------------------*\
@@ -96,7 +126,7 @@ void LogitechG915Controller::SendCommit()
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x01] = device_index;
usb_buf[0x02] = feature_8081_idx;
usb_buf[0x03] = LOGITECH_G915_COMMIT_BYTE;
@@ -107,7 +137,7 @@ void LogitechG915Controller::SendCommit()
hid_read_timeout(dev_handle, (unsigned char *)usb_buf, 20, LOGITECH_READ_TIMEOUT);
}
void LogitechG915Controller::InitializeDirect()
void LogitechG915Controller::BeginModeSet()
{
char usb_buf[20];
@@ -120,7 +150,7 @@ void LogitechG915Controller::InitializeDirect()
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x01] = device_index;
usb_buf[0x02] = feature_4522_idx;
usb_buf[0x03] = 0x3E;
@@ -139,7 +169,77 @@ void LogitechG915Controller::InitializeDirect()
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x01] = device_index;
usb_buf[0x02] = feature_4522_idx;
usb_buf[0x03] = 0x1E;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_handle, (unsigned char *)usb_buf, 20);
hid_read(dev_handle, (unsigned char *)usb_buf, 20);
}
void LogitechG915Controller::InitializeModeSet()
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = device_index;
usb_buf[0x02] = feature_8071_idx;
usb_buf[0x03] = 0x5E;
usb_buf[0x04] = 0x01;
usb_buf[0x05] = 0x03;
usb_buf[0x06] = 0x07;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_handle, (unsigned char *)usb_buf, 20);
hid_read(dev_handle, (unsigned char *)usb_buf, 20);
}
void LogitechG915Controller::InitializeDirect()
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = device_index;
usb_buf[0x02] = feature_4522_idx;
usb_buf[0x03] = 0x3E;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_handle, (unsigned char *)usb_buf, 20);
hid_read(dev_handle, (unsigned char *)usb_buf, 20);
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = device_index;
usb_buf[0x02] = feature_4522_idx;
usb_buf[0x03] = 0x1E;
@@ -158,7 +258,7 @@ void LogitechG915Controller::InitializeDirect()
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x01] = device_index;
usb_buf[0x02] = feature_8071_idx;
usb_buf[0x03] = 0x1E;
usb_buf[0x10] = 0x01;
@@ -178,7 +278,7 @@ void LogitechG915Controller::InitializeDirect()
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x01] = device_index;
usb_buf[0x02] = feature_8071_idx;
usb_buf[0x03] = 0x1E;
usb_buf[0x04] = 0x01;
@@ -210,7 +310,7 @@ void LogitechG915Controller::SendSingleLed
| Set up a 6F packet with a single color |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x01] = device_index;
usb_buf[0x02] = feature_8081_idx;
usb_buf[0x03] = LOGITECH_G915_ZONE_FRAME_TYPE_LITTLE;
@@ -244,7 +344,7 @@ void LogitechG915Controller::SendDirectFrame
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x01] = device_index;
usb_buf[0x02] = feature_8081_idx;
usb_buf[0x03] = frame_type;
@@ -265,6 +365,7 @@ void LogitechG915Controller::SendMode
unsigned char zone,
unsigned char mode,
unsigned short speed,
unsigned short brightness,
unsigned char red,
unsigned char green,
unsigned char blue
@@ -282,35 +383,53 @@ void LogitechG915Controller::SendMode
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x02] = feature_8040_idx;
usb_buf[0x03] = 0x3D; //TODO: Check if it is the correct value for G915
usb_buf[0x04] = zone;
usb_buf[0x01] = device_index;
usb_buf[0x02] = feature_8071_idx;
usb_buf[0x03] = 0x1E;
usb_buf[0x04] = zone;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 100 * speed;
if(mode != LOGITECH_G915_MODE_RIPPLE)
{
speed = 100 * speed;
}
if(mode == LOGITECH_G915_MODE_CYCLE)
// mode == LOGITECH_G915_MODE_OFF; No data to set
if(mode == LOGITECH_G915_MODE_STATIC)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = 0x64;
usb_buf[0x09] = 0x02;
}
else if(mode == LOGITECH_G915_MODE_BREATHING)
else if((mode == LOGITECH_G915_MODE_BREATHING && zone == LOGITECH_G915_ZONE_MODE_KEYBOARD) \
|| (mode == LOGITECH_G915_LOGO_MODE_BREATHING && zone == LOGITECH_G915_ZONE_MODE_LOGO))
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
usb_buf[0x0C] = 0x64;
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
usb_buf[0x0C] = brightness & 0xFF;
}
else
else if((mode == LOGITECH_G915_MODE_CYCLE && zone == LOGITECH_G915_ZONE_MODE_KEYBOARD) \
|| (mode == LOGITECH_G915_LOGO_MODE_CYCLE && zone == LOGITECH_G915_ZONE_MODE_LOGO))
{
return;
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = brightness & 0xFF;
}
else if(mode == LOGITECH_G915_MODE_WAVE)
{
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = 0x01; // Direction control 0x01 is horizontal
usb_buf[0x0E] = brightness & 0xFF;
usb_buf[0x0F] = speed >> 8;
}
else if(mode == LOGITECH_G915_MODE_RIPPLE)
{
usb_buf[0x0B] = speed & 0xFF;
}
usb_buf[0x10] = 0x01;
/*-----------------------------------------------------*\
| Send packet |

View File

@@ -19,9 +19,9 @@
enum
{
LOGITECH_G915_ZONE_MODE_KEYBOARD = 0x00,
LOGITECH_G915_ZONE_MODE_LOGO = 0x01,
LOGITECH_G915_ZONE_MODE_MULTIMEDIA = 0X02,
LOGITECH_G915_ZONE_MODE_KEYBOARD = 0x01,
LOGITECH_G915_ZONE_MODE_LOGO = 0x00,
LOGITECH_G915_ZONE_MODE_MULTIMEDIA = 0x02,
LOGITECH_G915_ZONE_MODE_GKEYS = 0x03,
LOGITECH_G915_ZONE_MODE_MODIFIERS = 0x04
};
@@ -47,7 +47,16 @@ enum
LOGITECH_G915_MODE_BREATHING = 0x02,
LOGITECH_G915_MODE_CYCLE = 0x03,
LOGITECH_G915_MODE_WAVE = 0x04,
LOGITECH_G915_MODE_DIRECT = 0x05,
LOGITECH_G915_MODE_RIPPLE = 0x05,
LOGITECH_G915_MODE_DIRECT = 0xFF,
};
enum
{
LOGITECH_G915_LOGO_MODE_OFF = 0x00,
LOGITECH_G915_LOGO_MODE_STATIC = 0x01,
LOGITECH_G915_LOGO_MODE_CYCLE = 0x02,
LOGITECH_G915_LOGO_MODE_BREATHING = 0x03,
};
/*---------------------------------------------------------------------------------------------*\
@@ -61,6 +70,14 @@ enum
LOGITECH_G915_SPEED_FASTEST = 0x0A, /* Fastest speed */
};
/* Ripple speeds are in ms directly. */
enum
{
LOGITECH_G915_SPEED_RIPPLE_SLOW = 200,
LOGITECH_G915_SPEED_RIPPLE_NORMAL = 20,
LOGITECH_G915_SPEED_RIPPLE_FAST = 2,
};
class LogitechG915Controller
{
public:
@@ -70,6 +87,8 @@ public:
std::string GetSerialString();
void Commit();
void InitializeDirect();
void InitializeModeSet();
void BeginModeSet();
void SetDirect
(
unsigned char frame_type,
@@ -86,6 +105,7 @@ public:
(
unsigned char mode,
unsigned short speed,
unsigned short brightness,
unsigned char red,
unsigned char green,
unsigned char blue
@@ -94,6 +114,7 @@ public:
private:
hid_device* dev_handle;
char feature_4522_idx;
char device_index;
char feature_8040_idx;
char feature_8071_idx;
char feature_8081_idx;
@@ -109,6 +130,7 @@ private:
unsigned char zone,
unsigned char mode,
unsigned short speed,
unsigned short brightness,
unsigned char red,
unsigned char green,
unsigned char blue

View File

@@ -235,29 +235,63 @@ RGBController_LogitechG915::RGBController_LogitechG915(LogitechG915Controller* c
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Cycle;
Cycle.name = "Cycle";
Cycle.value = LOGITECH_G915_MODE_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED;
Cycle.color_mode = MODE_COLORS_NONE;
Cycle.speed_min = LOGITECH_G915_SPEED_SLOWEST;
Cycle.speed_max = LOGITECH_G915_SPEED_FASTEST;
Cycle.speed = LOGITECH_G915_SPEED_NORMAL;
modes.push_back(Cycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = LOGITECH_G915_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors.resize(1);
Breathing.brightness_min = 1;
Breathing.brightness_max = 100;
Breathing.brightness = 100;
Breathing.speed_min = LOGITECH_G915_SPEED_SLOWEST;
Breathing.speed_max = LOGITECH_G915_SPEED_FASTEST;
Breathing.speed = LOGITECH_G915_SPEED_NORMAL;
modes.push_back(Breathing);
mode Cycle;
Cycle.name = "Spectrum Cycle";
Cycle.value = LOGITECH_G915_MODE_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Cycle.color_mode = MODE_COLORS_NONE;
Cycle.speed_min = LOGITECH_G915_SPEED_SLOWEST;
Cycle.speed_max = LOGITECH_G915_SPEED_FASTEST;
Cycle.speed = LOGITECH_G915_SPEED_NORMAL;
Cycle.brightness_min = 1;
Cycle.brightness_max = 100;
Cycle.brightness = 100;
modes.push_back(Cycle);
mode Wave;
Wave.name = "Rainbow Wave";
Wave.value = LOGITECH_G915_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
//Wave.flags |= MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_DIRECTION_HV;
Wave.brightness_min = 1;
Wave.brightness_max = 100;
Wave.brightness = 100;
Wave.color_mode = MODE_COLORS_NONE;
Wave.direction = MODE_DIRECTION_HORIZONTAL | MODE_DIRECTION_RIGHT;
Wave.speed_min = LOGITECH_G915_SPEED_SLOWEST;
Wave.speed_max = LOGITECH_G915_SPEED_FASTEST;
Wave.speed = LOGITECH_G915_SPEED_NORMAL;
modes.push_back(Wave);
mode Ripple;
Ripple.name = "Reactive (Ripple)";
Ripple.value = LOGITECH_G915_MODE_RIPPLE;
Ripple.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Ripple.colors_min = 1;
Ripple.colors_max = 1;
Ripple.color_mode = MODE_COLORS_MODE_SPECIFIC;
Ripple.colors.resize(1);
Ripple.speed_min = LOGITECH_G915_SPEED_RIPPLE_SLOW;
Ripple.speed_max = LOGITECH_G915_SPEED_RIPPLE_FAST;
Ripple.speed = LOGITECH_G915_SPEED_RIPPLE_NORMAL;
modes.push_back(Ripple);
SetupZones();
std::copy(colors.begin(), colors.end(),std::back_inserter(current_colors));
}
@@ -554,6 +588,7 @@ void RGBController_LogitechG915::DeviceUpdateMode()
controller->Commit();
return;
}
controller->InitializeModeSet();
unsigned char red = 0;
unsigned char grn = 0;
@@ -565,6 +600,5 @@ void RGBController_LogitechG915::DeviceUpdateMode()
grn = RGBGetGValue(modes[active_mode].colors[0]);
blu = RGBGetBValue(modes[active_mode].colors[0]);
}
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, red, grn, blu);
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, red, grn, blu);
}