From 0755959741d997a4e8da94e8abfcd9aa5481f2cd Mon Sep 17 00:00:00 2001 From: Thomas greenwood Date: Sun, 6 Jun 2021 02:41:56 +0100 Subject: [PATCH] Implement modes for Logitech G213 Keyboard --- .../LogitechG213Controller.cpp | 75 +++++++++++++++++ .../LogitechG213Controller.h | 53 ++++++++++++ .../RGBController_LogitechG213.cpp | 80 +++++++++++++++++++ 3 files changed, 208 insertions(+) diff --git a/Controllers/LogitechController/LogitechG213Controller.cpp b/Controllers/LogitechController/LogitechG213Controller.cpp index aa4d71ff..a4cd41ab 100644 --- a/Controllers/LogitechController/LogitechG213Controller.cpp +++ b/Controllers/LogitechController/LogitechG213Controller.cpp @@ -75,3 +75,78 @@ void LogitechG213Controller::SetDirect \*-----------------------------------------------------*/ hid_write(dev, (unsigned char *)usb_buf, 20); } + +void LogitechG213Controller::SetMode + ( + unsigned char mode, + unsigned short speed, + unsigned char direction, + unsigned char red, + unsigned char green, + unsigned char blue + ) +{ + SendMode(LOGITECH_G213_ZONE_MODE_KEYBOARD, mode, speed, direction, red, green, blue); +} + +void LogitechG213Controller::SendMode + ( + unsigned char zone, + unsigned char mode, + unsigned short speed, + unsigned char direction, + unsigned char red, + unsigned char green, + unsigned char blue + ) +{ + char usb_buf[20]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up Lighting Control packet | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0x11; + usb_buf[0x01] = 0xFF; + usb_buf[0x02] = 0x0C; + usb_buf[0x03] = 0x3C; + 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_G213_MODE_BREATHING) + { + usb_buf[0x09] = speed >> 8; + usb_buf[0x0A] = speed & 0xFF; + usb_buf[0x0C] = 0x64; + } + else if(mode == LOGITECH_G213_MODE_CYCLE) + { + usb_buf[0x0B] = speed >> 8; + usb_buf[0x0C] = speed & 0xFF; + usb_buf[0x0D] = 0x64; + } + else if(mode == LOGITECH_G213_MODE_WAVE) + { + usb_buf[0x0B] = speed >> 8; + usb_buf[0x0C] = speed & 0xFF; + usb_buf[0x0D] = direction & 0xFF; + usb_buf[0x0F] = speed >> 8; + } + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_write(dev, (unsigned char *)usb_buf, 20); + hid_read(dev, (unsigned char *)usb_buf, 20); +} diff --git a/Controllers/LogitechController/LogitechG213Controller.h b/Controllers/LogitechController/LogitechG213Controller.h index 024f4bff..14ab0f99 100644 --- a/Controllers/LogitechController/LogitechG213Controller.h +++ b/Controllers/LogitechController/LogitechG213Controller.h @@ -13,6 +13,39 @@ #pragma once +enum +{ + LOGITECH_G213_ZONE_MODE_KEYBOARD = 0x00 +}; + +enum +{ + LOGITECH_G213_MODE_OFF = 0x00, + LOGITECH_G213_MODE_STATIC = 0x01, + LOGITECH_G213_MODE_BREATHING = 0x02, + LOGITECH_G213_MODE_CYCLE = 0x03, + LOGITECH_G213_MODE_WAVE = 0x04, +}; + +enum +{ + LOGITECH_G213_WAVE_MODE_LEFT = 0x06, + LOGITECH_G213_WAVE_MODE_RIGHT = 0x01, + LOGITECH_G213_WAVE_MODE_CENTER_EDGE = 0x03, + LOGITECH_G213_WAVE_MODE_EDGE_CENTER = 0x08, +}; + +/*---------------------------------------------------------------------------------------------*\ +| Speed is 1000 for fast and 20000 for slow. | +| Values are multiplied by 100 later to give lots of GUI steps. | +\*---------------------------------------------------------------------------------------------*/ +enum +{ + LOGITECH_G213_SPEED_SLOWEST = 0xC8, /* Slowest speed */ + LOGITECH_G213_SPEED_NORMAL = 0x32, /* Normal speed */ + LOGITECH_G213_SPEED_FASTEST = 0x0A, /* Fastest speed */ +}; + class LogitechG213Controller { public: @@ -30,8 +63,28 @@ public: unsigned char b ); + void SetMode + ( + unsigned char mode, + unsigned short speed, + unsigned char direction, + unsigned char red, + unsigned char green, + unsigned char blue + ); + private: hid_device* dev; std::string location; + void SendMode + ( + unsigned char zone, + unsigned char mode, + unsigned short speed, + unsigned char direction, + unsigned char red, + unsigned char green, + unsigned char blue + ); }; diff --git a/Controllers/LogitechController/RGBController_LogitechG213.cpp b/Controllers/LogitechController/RGBController_LogitechG213.cpp index 8cfd28da..5eb7352d 100644 --- a/Controllers/LogitechController/RGBController_LogitechG213.cpp +++ b/Controllers/LogitechController/RGBController_LogitechG213.cpp @@ -46,6 +46,47 @@ RGBController_LogitechG213::RGBController_LogitechG213(LogitechG213Controller* l Direct.color_mode = MODE_COLORS_PER_LED; modes.push_back(Direct); + mode Off; + Off.name = "Off"; + Off.value = LOGITECH_G213_MODE_OFF; + Off.flags = 0; + Off.color_mode = MODE_COLORS_NONE; + modes.push_back(Off); + + mode Cycle; + Cycle.name = "Cycle"; + Cycle.value = LOGITECH_G213_MODE_CYCLE; + Cycle.flags = MODE_FLAG_HAS_SPEED; + Cycle.color_mode = MODE_COLORS_NONE; + Cycle.speed_min = LOGITECH_G213_SPEED_SLOWEST; + Cycle.speed_max = LOGITECH_G213_SPEED_FASTEST; + Cycle.speed = LOGITECH_G213_SPEED_NORMAL; + modes.push_back(Cycle); + + mode Wave; + Wave.name = "Wave"; + Wave.value = LOGITECH_G213_MODE_WAVE; + Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD; + Wave.color_mode = MODE_COLORS_NONE; + Wave.speed_min = LOGITECH_G213_SPEED_SLOWEST; + Wave.speed_max = LOGITECH_G213_SPEED_FASTEST; + Wave.speed = LOGITECH_G213_SPEED_NORMAL; + Wave.direction = MODE_DIRECTION_LEFT; + modes.push_back(Wave); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = LOGITECH_G213_MODE_BREATHING; + Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED; + Breathing.colors_min = 1; + Breathing.colors_max = 1; + Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC; + Breathing.colors.resize(1); + Breathing.speed_min = LOGITECH_G213_SPEED_SLOWEST; + Breathing.speed_max = LOGITECH_G213_SPEED_FASTEST; + Breathing.speed = LOGITECH_G213_SPEED_NORMAL; + modes.push_back(Breathing); + SetupZones(); } @@ -117,4 +158,43 @@ void RGBController_LogitechG213::DeviceUpdateMode() | Direct mode does not send a mode packet | | Call UpdateLEDs to send direct packet | \*---------------------------------------------------------*/ + if(active_mode == 0xFFFF) + { + UpdateLEDs(); + return; + } + + unsigned char red = 0; + unsigned char grn = 0; + unsigned char blu = 0; + unsigned char direction = 0; + + if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) + { + red = RGBGetRValue(modes[active_mode].colors[0]); + grn = RGBGetGValue(modes[active_mode].colors[0]); + blu = RGBGetBValue(modes[active_mode].colors[0]); + } + + switch (modes[active_mode].direction) + { + case MODE_DIRECTION_LEFT: + // Right to left + direction = LOGITECH_G213_WAVE_MODE_LEFT; + break; + case MODE_DIRECTION_RIGHT: + // Left to right + direction = LOGITECH_G213_WAVE_MODE_RIGHT; + break; + case MODE_DIRECTION_UP: + // Edge to center + direction = LOGITECH_G213_WAVE_MODE_EDGE_CENTER; + break; + case MODE_DIRECTION_DOWN: + // Center to edge + direction = LOGITECH_G213_WAVE_MODE_CENTER_EDGE; + break; + } + + logitechG213->SetMode(modes[active_mode].value, modes[active_mode].speed, direction, red, grn, blu); }