From 59aafb262aae8be23231e195aeeafb5dfc9f7f94 Mon Sep 17 00:00:00 2001 From: Kevin Pearson Date: Fri, 20 Sep 2019 09:37:49 -0400 Subject: [PATCH 1/5] Set two protocol bytes for effects The g815 doesn't use 0x3c as the 5th byte, so have it specified per device. Signed-off-by: Kevin Pearson --- src/classes/Keyboard.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/classes/Keyboard.cpp b/src/classes/Keyboard.cpp index f8a3972..ee92306 100644 --- a/src/classes/Keyboard.cpp +++ b/src/classes/Keyboard.cpp @@ -717,7 +717,7 @@ bool LedKeyboard::setStartupMode(StartupMode startupMode) { bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, std::chrono::duration period, Color color, NativeEffectStorage storage) { - uint8_t protocolByte = 0; + uint8_t protocolBytes[2] = {0x00, 0x00}; NativeEffectGroup effectGroup = static_cast(static_cast(effect) >> 8); // NativeEffectPart::all is not in the device protocol, but an alias for both keys and logo, plus indicators @@ -748,7 +748,8 @@ bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, switch (currentDevice.model) { case KeyboardModel::g213: case KeyboardModel::g413: - protocolByte = 0x0c; + protocolBytes[0] = 0x0c; + protocolBytes[1] = 0x3c; if (part == NativeEffectPart::logo) return true; //Does not have logo component break; case KeyboardModel::g410: @@ -756,10 +757,12 @@ bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, case KeyboardModel::g610: // Unconfirmed case KeyboardModel::g810: case KeyboardModel::gpro: - protocolByte = 0x0d; + protocolBytes[0] = 0x0d; + protocolBytes[1] = 0x3c; break; case KeyboardModel::g910: - protocolByte = 0x10; + protocolBytes[0] = 0x10; + protocolBytes[1] = 0x3c; break; default: return false; @@ -770,7 +773,7 @@ bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, } byte_buffer_t data = { - 0x11, 0xff, protocolByte, 0x3c, + 0x11, 0xff, protocolBytes[0], protocolBytes[1], (uint8_t)part, static_cast(effectGroup), // color of static-color and breathing effects color.red, color.green, color.blue, From 1a26bf7e640113b5158a6a49280bd9a84604b9dc Mon Sep 17 00:00:00 2001 From: Kevin Pearson Date: Wed, 25 Sep 2019 08:14:02 -0400 Subject: [PATCH 2/5] Initial g815 support: native effects TODO: There is a new ripple effect that needs to be added. This commit only provides support for the current effects. Signed-off-by: Kevin Pearson --- src/classes/Keyboard.cpp | 69 +++++++++++++++++++++++++++++++++++----- src/classes/Keyboard.h | 4 ++- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/src/classes/Keyboard.cpp b/src/classes/Keyboard.cpp index ee92306..1268fcb 100644 --- a/src/classes/Keyboard.cpp +++ b/src/classes/Keyboard.cpp @@ -374,9 +374,10 @@ bool LedKeyboard::commit() { case KeyboardModel::g413: return true; // Keyboard is non-transactional case KeyboardModel::g410: - case KeyboardModel::g513: + case KeyboardModel::g513: case KeyboardModel::g610: case KeyboardModel::g810: + case KeyboardModel::g815: case KeyboardModel::gpro: data = { 0x11, 0xff, 0x0c, 0x5a }; break; @@ -541,7 +542,12 @@ bool LedKeyboard::setGroupKeys(KeyGroup keyGroup, LedKeyboard::Color color) { keyArray = keyGroupLogo; break; case KeyGroup::indicators: - keyArray = keyGroupIndicators; + switch (currentDevice.model) { + case KeyboardModel::g815: + return true; + default: + keyArray = keyGroupIndicators; + } break; case KeyGroup::gkeys: keyArray = keyGroupGKeys; @@ -753,13 +759,17 @@ bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, if (part == NativeEffectPart::logo) return true; //Does not have logo component break; case KeyboardModel::g410: - case KeyboardModel::g513: + case KeyboardModel::g513: case KeyboardModel::g610: // Unconfirmed case KeyboardModel::g810: case KeyboardModel::gpro: protocolBytes[0] = 0x0d; protocolBytes[1] = 0x3c; break; + case KeyboardModel::g815: + protocolBytes[0] = 0x0f; + protocolBytes[1] = 0x1c; + break; case KeyboardModel::g910: protocolBytes[0] = 0x10; protocolBytes[1] = 0x3c; @@ -768,10 +778,6 @@ bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, return false; } - if ((effectGroup == NativeEffectGroup::waves) && (part == NativeEffectPart::logo)) { - return setNativeEffect(NativeEffect::color, part, std::chrono::seconds(0), Color({0x00, 0xff, 0xff}), storage); - } - byte_buffer_t data = { 0x11, 0xff, protocolBytes[0], protocolBytes[1], (uint8_t)part, static_cast(effectGroup), @@ -790,7 +796,54 @@ bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, 0, // unused? 0, // unused? }; - return sendDataInternal(data); + + byte_buffer_t setupData; + bool retval; + switch (currentDevice.model) { + case KeyboardModel::g815: + setupData = { 0x11, 0xff, 0x0f, 0x5c, 0x01, 0x03, 0x03 }; + setupData.resize(20, 0x00); + retval = sendDataInternal(setupData); + + data[16] = 0x01; + + switch (part) { + case NativeEffectPart::keys: + data[4] = 0x01; + break; + case NativeEffectPart::logo: + data[4] = 0x00; + switch (effect) { + case NativeEffect::breathing: + data[5]=0x03; + break; + case NativeEffect::cwave: + case NativeEffect::vwave: + case NativeEffect::hwave: + data[5]=0x02; + data[13]=0x64; + break; + case NativeEffect::waves: + case NativeEffect::cycle: + data[5]=0x02; + break; + default: + data[5]=0x01; + break; + } + break; + default: + break; + } + break; + default: //Many devices may not support logo coloring for wave? + if ((effectGroup == NativeEffectGroup::waves) && (part == NativeEffectPart::logo)) { + return setNativeEffect(NativeEffect::color, part, std::chrono::seconds(0), Color({0x00, 0xff, 0xff}), storage); + } + break; + } + retval = sendDataInternal(data); + return retval; } diff --git a/src/classes/Keyboard.h b/src/classes/Keyboard.h index 5119b9d..6579835 100644 --- a/src/classes/Keyboard.h +++ b/src/classes/Keyboard.h @@ -53,6 +53,7 @@ class LedKeyboard { { 0x46d, 0xc338, (uint16_t)KeyboardModel::g610 }, { 0x46d, 0xc331, (uint16_t)KeyboardModel::g810 }, { 0x46d, 0xc337, (uint16_t)KeyboardModel::g810 }, + { 0x46d, 0xc33f, (uint16_t)KeyboardModel::g815 }, { 0x46d, 0xc32b, (uint16_t)KeyboardModel::g910 }, { 0x46d, 0xc335, (uint16_t)KeyboardModel::g910 }, { 0x46d, 0xc339, (uint16_t)KeyboardModel::gpro } @@ -63,9 +64,10 @@ class LedKeyboard { g213, g410, g413, - g513, + g513, g610, g810, + g815, g910, gpro }; From b938bf6c1d9724943f2ec2d555d8860b9f68a41a Mon Sep 17 00:00:00 2001 From: Kevin Pearson Date: Thu, 26 Sep 2019 08:50:46 -0400 Subject: [PATCH 3/5] Add ripple and off effects NOTE: Ripple effect (0x05) seems to have a conflict with an unadvertised "stars"-like effect for the G410 and G810. Did not explore setting timing for the G410/G810 effect, but is likely contrasted greatly with the timing of the new Ripple effect. GHub limits ripple timing between 20ms and 200ms, but actual values are arbitrary and were tested up to 5000ms. Ideally should be kept within the 20-200ms range for best feel of the effect. Logo does not honor the effect, and GHub simply sets to the default "Logitech Blue". Signed-off-by: Kevin Pearson --- src/classes/Keyboard.cpp | 20 ++++++++++++++++++++ src/classes/Keyboard.h | 10 +++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/classes/Keyboard.cpp b/src/classes/Keyboard.cpp index 1268fcb..8e9fa05 100644 --- a/src/classes/Keyboard.cpp +++ b/src/classes/Keyboard.cpp @@ -739,12 +739,15 @@ bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, break; case NativeEffectGroup::cycle: case NativeEffectGroup::waves: + case NativeEffectGroup::ripple: if (! setGroupKeys( LedKeyboard::KeyGroup::indicators, LedKeyboard::Color({0xff, 0xff, 0xff})) ) return false; if (! commit()) return false; break; + default: + break; } return ( setNativeEffect(effect, LedKeyboard::NativeEffectPart::keys, period, color, storage) && @@ -810,6 +813,19 @@ bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, switch (part) { case NativeEffectPart::keys: data[4] = 0x01; + + //Seems to conflict with a star-like effect on G410 and G810 + switch (effect) { + case NativeEffect::ripple: + //Adjust periodicity + data[9]=0x00; + data[10]=period.count() >> 8 & 0xff;; + data[11]=period.count() & 0xff; + data[12]=0x00; + break; + default: + break; + } break; case NativeEffectPart::logo: data[4] = 0x00; @@ -827,6 +843,10 @@ bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, case NativeEffect::cycle: data[5]=0x02; break; + case NativeEffect::ripple: + case NativeEffect::off: + data[5]=0x00; + break; default: data[5]=0x01; break; diff --git a/src/classes/Keyboard.h b/src/classes/Keyboard.h index 6579835..74505e2 100644 --- a/src/classes/Keyboard.h +++ b/src/classes/Keyboard.h @@ -79,19 +79,23 @@ class LedKeyboard { color }; enum class NativeEffectGroup : uint8_t { - color = 0x01, + off, + color, breathing, cycle, - waves + waves, + ripple }; enum class NativeEffect : uint16_t { + off, color = static_cast(NativeEffectGroup::color) << 8, breathing = static_cast(NativeEffectGroup::breathing) << 8, cycle = static_cast(NativeEffectGroup::cycle) << 8, waves = static_cast(NativeEffectGroup::waves) << 8, hwave, vwave, - cwave + cwave, + ripple = static_cast(NativeEffectGroup::ripple) << 8 }; enum class NativeEffectPart : uint8_t { all = 0xff, From d438ec2e3a8d2533d5dbd4cc4bf467762f8821d0 Mon Sep 17 00:00:00 2001 From: Dan Eble Date: Mon, 30 Sep 2019 11:16:37 -0400 Subject: [PATCH 4/5] Stop prepending a zero byte to the input of hid_write() hid_write() expects a report ID in the first byte. The 0x11 and 0x12 values sent as the first byte of commands are consistent with report IDs published in the keyboard's USB descriptors. This change was motivated by commands not working reliably using hidapi on macOS with a G Pro keyboard. --- src/classes/Keyboard.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/classes/Keyboard.cpp b/src/classes/Keyboard.cpp index ee92306..5cb3b05 100644 --- a/src/classes/Keyboard.cpp +++ b/src/classes/Keyboard.cpp @@ -798,7 +798,6 @@ bool LedKeyboard::sendDataInternal(byte_buffer_t &data) { if (data.size() > 0) { #if defined(hidapi) if (! open(currentDevice.vendorID, currentDevice.productID, currentDevice.serialNumber)) return false; - data.insert(data.begin(), 0x00); if (hid_write(m_hidHandle, const_cast(data.data()), data.size()) < 0) { std::cout<<"Error: Can not write to hidraw, try with the libusb version"< Date: Tue, 29 Oct 2019 17:46:51 +0100 Subject: [PATCH 5/5] Adding seperate Profile Sections in README --- INSTALL.md | 9 +-------- PROFILES.md | 16 ++++++++++++++++ README.md | 4 ++++ 3 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 PROFILES.md diff --git a/INSTALL.md b/INSTALL.md index d3432fb..4589e43 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -65,11 +65,4 @@ Gentoo :
Same as install, but your profile and reboot files are preserved.
## Uninstall :
-`sudo make uninstall`
- -## Boot profiles :
-On boot, the keyboard is set with the udev file /etc/udev/rules.d/g810-led.rules
-This file launches the profile stored in /etc/g810-led/profile
-To prevent your keyboard flashing 3 times when you reboot use the systemd unit (g810-led-reboot).
- -Samples can be found in /etc/g810-led/samples.
+`sudo make uninstall`
\ No newline at end of file diff --git a/PROFILES.md b/PROFILES.md new file mode 100644 index 0000000..eaac74d --- /dev/null +++ b/PROFILES.md @@ -0,0 +1,16 @@ +# Profiles for your keyboard + +## Boot profiles :
+On boot, the keyboard is set with the udev file `/etc/udev/rules.d/g810-led.rules`
+This file launches the profile stored in `/etc/g810-led/profile`
+To prevent your keyboard flashing 3 times when you reboot use the systemd unit (g810-led-reboot).
+ +A profile looks like this: +``` +# G810-LED Profile (turn all keys on) + +a ffffff # Set all keys on + +c # Commit changes +``` +More samples can be found in [/etc/g810-led/samples.](https://github.com/MatMoul/g810-led/tree/master/sample_profiles)
diff --git a/README.md b/README.md index f178a92..960fe64 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,10 @@ Linux led controller for Logitech G213, G410, G413, G512, G513, G610, G810, G910 ## Install :
* [INSTALL.md](https://github.com/MatMoul/g810-led/blob/master/INSTALL.md) +## Profiles :
+You can load predefined configurations on startup! +* [PROFILES.md](https://github.com/MatMoul/g810-led/blob/master/PROFILES.md) + ## Help :
`g213-led --help`
`g410-led --help`