From 6b184f2b8ce02d46a15442099be81c79342cc767 Mon Sep 17 00:00:00 2001 From: edbgon Date: Mon, 21 Jun 2021 10:08:44 +0200 Subject: [PATCH] Initial G933 support --- 60-openrgb.rules | 5 + .../LogitechControllerDetect.cpp | 27 ++++ .../LogitechG933Controller.cpp | 146 ++++++++++++++++++ .../LogitechG933Controller.h | 56 +++++++ .../RGBController_LogitechG933.cpp | 125 +++++++++++++++ .../RGBController_LogitechG933.h | 34 ++++ OpenRGB.pro | 4 + 7 files changed, 397 insertions(+) create mode 100644 Controllers/LogitechController/LogitechG933Controller.cpp create mode 100644 Controllers/LogitechController/LogitechG933Controller.h create mode 100644 Controllers/LogitechController/RGBController_LogitechG933.cpp create mode 100644 Controllers/LogitechController/RGBController_LogitechG933.h diff --git a/60-openrgb.rules b/60-openrgb.rules index 8fc2a57d5..7412e1062 100644 --- a/60-openrgb.rules +++ b/60-openrgb.rules @@ -339,6 +339,9 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="0cf2", ATTR{idProduct}=="7750", TAG+="uacces # Speakers: # # Logitech G560 # # # +# Headsets: # +# Logitech G933 # +# # # Joysticks: # # Logitech Rhino X56 Hotas (Throttle and Stick) # # # @@ -379,6 +382,8 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c53a", TAG+="uacces SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="0a78", TAG+="uaccess" +SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="0a5b", TAG+="uaccess" + SUBSYSTEMS=="usb", ATTR{idVendor}=="0738", ATTR{idProduct}=="2221", TAG+="uaccess" SUBSYSTEMS=="usb", ATTR{idVendor}=="0738", ATTR{idProduct}=="A221", TAG+="uaccess" diff --git a/Controllers/LogitechController/LogitechControllerDetect.cpp b/Controllers/LogitechController/LogitechControllerDetect.cpp index 4151ef6bf..cff25d0c1 100644 --- a/Controllers/LogitechController/LogitechControllerDetect.cpp +++ b/Controllers/LogitechController/LogitechControllerDetect.cpp @@ -4,6 +4,7 @@ #include "LogitechG203LController.h" #include "LogitechG213Controller.h" #include "LogitechG560Controller.h" +#include "LogitechG933Controller.h" #include "LogitechG810Controller.h" #include "LogitechG910Controller.h" #include "LogitechG815Controller.h" @@ -14,6 +15,7 @@ #include "RGBController_LogitechG203L.h" #include "RGBController_LogitechG213.h" #include "RGBController_LogitechG560.h" +#include "RGBController_LogitechG933.h" #include "RGBController_LogitechG810.h" #include "RGBController_LogitechG910.h" #include "RGBController_LogitechG815.h" @@ -74,6 +76,11 @@ \*-----------------------------------------------------*/ #define LOGITECH_G560_PID 0x0A78 +/*-----------------------------------------------------*\ +| Headset product IDs | +\*-----------------------------------------------------*/ +#define LOGITECH_G933_PID 0x0A5B + /*-----------------------------------------------------*\ | Unifying Device IDs (Including Lightspeed receivers) | | NB: Not used but preserved for debugging | @@ -479,6 +486,22 @@ void DetectLogitechG560(hid_device_info* info, const std::string& name) } } +void DetectLogitechG933(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + /*---------------------------------------------*\ + | Add G933 Headset | + \*---------------------------------------------*/ + LogitechG933Controller* controller = new LogitechG933Controller(dev, info->path); + RGBController_LogitechG933* rgb_controller = new RGBController_LogitechG933(controller); + rgb_controller->name = name; + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + void DetectLogitechX56(hid_device_info* info, const std::string& name) { hid_device* dev = hid_open_path(info->path); @@ -525,6 +548,10 @@ REGISTER_HID_DETECTOR_IP ("Logitech G Pro (HERO) Gaming Mouse", Dete \*-------------------------------------------------------------------------------------------------------------------------------------------------*/ REGISTER_HID_DETECTOR_IPU("Logitech G560 Lightsync Speaker", DetectLogitechG560, LOGITECH_VID, LOGITECH_G560_PID, 2, 0xFF43, 514); /*-------------------------------------------------------------------------------------------------------------------------------------------------*\ +| Headsets | +\*-------------------------------------------------------------------------------------------------------------------------------------------------*/ +REGISTER_HID_DETECTOR_IPU("Logitech G933 Lightsync Headset", DetectLogitechG933, LOGITECH_VID, LOGITECH_G933_PID, 3, 0xFF43, 514); +/*-------------------------------------------------------------------------------------------------------------------------------------------------*\ | Joysticks | \*-------------------------------------------------------------------------------------------------------------------------------------------------*/ REGISTER_HID_DETECTOR_IP("Logitech X56 Rhino Hotas Joystick", DetectLogitechX56, LOGITECH_X56_VID, LOGITECH_X56_JOYSTICK_PID, 2, 0xFF00); diff --git a/Controllers/LogitechController/LogitechG933Controller.cpp b/Controllers/LogitechController/LogitechG933Controller.cpp new file mode 100644 index 000000000..3b9a5ddd3 --- /dev/null +++ b/Controllers/LogitechController/LogitechG933Controller.cpp @@ -0,0 +1,146 @@ +/*-----------------------------------------*\ +| LogitechG933Controller.cpp | +| | +| Driver for Logitech G933 RGB Headset | +| | +| Edbgon 06/21/2021 | +| Based on | +| TheRogueZeta 8/31/2020 | +\*-----------------------------------------*/ + +#include "LogitechG933Controller.h" +#include +#include +#include + +using namespace std::chrono_literals; + +LogitechG933Controller::LogitechG933Controller(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; +} + +LogitechG933Controller::~LogitechG933Controller() +{ + hid_close(dev); +} + +std::string LogitechG933Controller::GetDeviceLocation() +{ + return("HID: " + location); +} + +void LogitechG933Controller::SetDirectMode(uint8_t zone) +{ + unsigned char usb_buf[LOGI_G933_LED_PACKET_SIZE]; + + usb_buf[0x00] = 0x11; + usb_buf[0x01] = 0xFF; + usb_buf[0x02] = 0x04; + usb_buf[0x03] = 0xCA; + usb_buf[0x04] = zone; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + fail_retry_write(dev, usb_buf, LOGI_G933_LED_PACKET_SIZE); +} + +void LogitechG933Controller::SetOffMode(uint8_t zone) +{ + unsigned char usb_buf[LOGI_G933_LED_PACKET_SIZE]; + + usb_buf[0x00] = 0x11; + usb_buf[0x01] = 0xFF; + usb_buf[0x02] = 0x04; + usb_buf[0x03] = 0x3F; + usb_buf[0x04] = zone; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + fail_retry_write(dev, usb_buf, LOGI_G933_LED_PACKET_SIZE); +} + +void LogitechG933Controller::SendHeadsetMode + ( + unsigned char zone, + unsigned char mode, + unsigned char red, + unsigned char green, + unsigned char blue + ) +{ + unsigned char usb_buf[LOGI_G933_LED_PACKET_SIZE]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up Lighting Control | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0x11; + usb_buf[0x01] = 0xFF; + usb_buf[0x02] = 0x04; + + /*-----------------------------------------------------*\ + | This packet sets speaker into direct mode. This mode | + | is used by Lightsync Ambilight and Music Visualizer | + | realtime effect. | + \*-----------------------------------------------------*/ + usb_buf[0x03] = 0x3A; + + /*-----------------------------------------------------*\ + | Set up mode and speed | + \*-----------------------------------------------------*/ + usb_buf[0x04] = zone; + usb_buf[0x05] = mode; + + /*-----------------------------------------------------*\ + | And set up the colors | + \*-----------------------------------------------------*/ + usb_buf[0x06] = red; + usb_buf[0x07] = green; + usb_buf[0x08] = blue; + + if(mode == LOGITECH_G933_MODE_DIRECT) //G933 only has Direct Mode. + { + usb_buf[0x09] = 0x02; + } + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + fail_retry_write(dev, usb_buf, LOGI_G933_LED_PACKET_SIZE); +} + +void LogitechG933Controller::fail_retry_write(hid_device *device, const unsigned char *data, size_t length) +{ + unsigned char usb_buf_out[LOGI_G933_LED_PACKET_SIZE]; + unsigned int write_max_retry = LOGI_G933_LED_COMMAND_SEND_RETRIES; + do + { + std::this_thread::sleep_for(1ms); + int ret = hid_write(device, data, length); + + /*-------------------------------------------------------------------------------------*\ + | HID write fails if a change led color and set volume command are sent at | + | the same time because RGB controller and volume control shares the same interface. | + \*-------------------------------------------------------------------------------------*/ + if(ret == 20) + { + std::this_thread::sleep_for(1ms); + hid_read_timeout(dev, usb_buf_out, LOGI_G933_LED_PACKET_SIZE, 20); + break; + } + else + { + write_max_retry--; + std::this_thread::sleep_for(10ms); + } + + }while (write_max_retry > 0); +} diff --git a/Controllers/LogitechController/LogitechG933Controller.h b/Controllers/LogitechController/LogitechG933Controller.h new file mode 100644 index 000000000..9981ca4dc --- /dev/null +++ b/Controllers/LogitechController/LogitechG933Controller.h @@ -0,0 +1,56 @@ +/*-----------------------------------------*\ +| LogitechG933Controller.h | +| | +| Definitions and types for | +| Logitech G933 RGB Headset | +| | +| Edbgon 06/21/2021 | +| Based on | +| TheRogueZeta 8/31/2020 | +\*-----------------------------------------*/ +#include "RGBController.h" + +#include +#include + +#pragma once + +#define LOGI_G933_LED_PACKET_SIZE 20 +#define LOGI_G933_LED_COMMAND_SEND_RETRIES 3 + +enum +{ + LOGITECH_G933_MODE_OFF = 0x00, + LOGITECH_G933_MODE_DIRECT = 0x01, + LOGITECH_G933_MODE_CYCLE = 0x02, + LOGITECH_G933_MODE_BREATHING = 0x03, +}; + +class LogitechG933Controller +{ +public: + LogitechG933Controller(hid_device* dev_handle, const char* path); + ~LogitechG933Controller(); + + std::string GetDeviceLocation(); + + void SetDirectMode(uint8_t zone); + void SetOffMode(uint8_t zone); + + void SendHeadsetMode + ( + unsigned char zone, + unsigned char mode, + unsigned char red, + unsigned char green, + unsigned char blue + ); + +private: + hid_device* dev; + std::string location; + + void fail_retry_write(hid_device *device, const unsigned char *data, size_t length); +}; + + diff --git a/Controllers/LogitechController/RGBController_LogitechG933.cpp b/Controllers/LogitechController/RGBController_LogitechG933.cpp new file mode 100644 index 000000000..c937287b2 --- /dev/null +++ b/Controllers/LogitechController/RGBController_LogitechG933.cpp @@ -0,0 +1,125 @@ +/*-----------------------------------------*\ +| RGBController_LogitechG933.cpp | +| | +| Generic RGB Interface for | +| Logitech G933 RGB Headset | +| | +| Edbgon 06/21/2021 | +| Based on | +| TheRogueZeta 8/31/2020 | +\*-----------------------------------------*/ + +#include "RGBController_LogitechG933.h" + +RGBController_LogitechG933::RGBController_LogitechG933(LogitechG933Controller* logitech_ptr) +{ + logitech = logitech_ptr; + + name = "Logitech G933 Lightsync Headset"; + vendor = "Logitech"; + type = DEVICE_TYPE_HEADSET; + description = "Logitech G933 Lightsync Headset"; + location = logitech->GetDeviceLocation(); + + mode Off; + Off.name = "Off"; + Off.value = LOGITECH_G933_MODE_OFF; + Off.flags = 0; + Off.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Off); + + mode Direct; + Direct.name = "Direct"; + Direct.value = LOGITECH_G933_MODE_DIRECT; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + SetupZones(); +} + +void RGBController_LogitechG933::SetupZones() +{ + zone G933_logo; + G933_logo.name = "Logo"; + G933_logo.type = ZONE_TYPE_SINGLE; + G933_logo.leds_min = 1; + G933_logo.leds_max = 1; + G933_logo.leds_count = 1; + G933_logo.matrix_map = NULL; + zones.push_back(G933_logo); + + led G933_logo_led; + G933_logo_led.name = "Logo"; + G933_logo_led.value = 0x00; + leds.push_back(G933_logo_led); + + zone G933_strip; + G933_strip.name = "LED Strip"; + G933_strip.type = ZONE_TYPE_SINGLE; + G933_strip.leds_min = 1; + G933_strip.leds_max = 1; + G933_strip.leds_count = 1; + G933_strip.matrix_map = NULL; + zones.push_back(G933_strip); + + led G933_strip_led; + G933_strip_led.name = "Led Strip"; + G933_strip_led.value = 0x01; + leds.push_back(G933_strip_led); + + SetupColors(); +} + +void RGBController_LogitechG933::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_LogitechG933::DeviceUpdateLEDs() +{ + for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++) + { + unsigned char red = RGBGetRValue(colors[led_idx]); + unsigned char grn = RGBGetGValue(colors[led_idx]); + unsigned char blu = RGBGetBValue(colors[led_idx]); + logitech->SendHeadsetMode((unsigned char)leds[led_idx].value, modes[active_mode].value, red, grn, blu); + } +} + +void RGBController_LogitechG933::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_LogitechG933::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_LogitechG933::SetCustomMode() +{ + active_mode = 1; +} + +void RGBController_LogitechG933::DeviceUpdateMode() +{ + for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++) + { + if(modes[active_mode].value == LOGITECH_G933_MODE_OFF) + { + logitech->SetOffMode(leds[led_idx].value); + } + else + { + /*---------------------------------------------------------*\ + | Required to "reset" RGB controller and start receiving | + | color in direct mode | + \*---------------------------------------------------------*/ + logitech->SetDirectMode(leds[led_idx].value); + } + + } + DeviceUpdateLEDs(); +} diff --git a/Controllers/LogitechController/RGBController_LogitechG933.h b/Controllers/LogitechController/RGBController_LogitechG933.h new file mode 100644 index 000000000..b9a0f17de --- /dev/null +++ b/Controllers/LogitechController/RGBController_LogitechG933.h @@ -0,0 +1,34 @@ +/*-----------------------------------------*\ +| RGBController_LogitechG933.h | +| | +| Generic RGB Interface for | +| G933 RGB Headset | +| | +| Edbgon 06/21/2021 | +| Based on | +| TheRogueZeta 8/31/2020 | +\*-----------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "LogitechG933Controller.h" + +class RGBController_LogitechG933 : public RGBController +{ +public: + RGBController_LogitechG933(LogitechG933Controller* logitech_ptr); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void SetCustomMode(); + void DeviceUpdateMode(); + +private: + LogitechG933Controller* logitech; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index 857c03ca7..a59815dd0 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -295,6 +295,7 @@ HEADERS += Controllers/LogitechController/LogitechG203LController.h \ Controllers/LogitechController/LogitechG213Controller.h \ Controllers/LogitechController/LogitechG560Controller.h \ + Controllers/LogitechController/LogitechG933Controller.h \ Controllers/LogitechController/LogitechG810Controller.h \ Controllers/LogitechController/LogitechG910Controller.h \ Controllers/LogitechController/LogitechG815Controller.h \ @@ -304,6 +305,7 @@ HEADERS += Controllers/LogitechController/RGBController_LogitechG203L.h \ Controllers/LogitechController/RGBController_LogitechG213.h \ Controllers/LogitechController/RGBController_LogitechG560.h \ + Controllers/LogitechController/RGBController_LogitechG933.h \ Controllers/LogitechController/RGBController_LogitechG810.h \ Controllers/LogitechController/RGBController_LogitechG910.h \ Controllers/LogitechController/RGBController_LogitechG815.h \ @@ -624,6 +626,7 @@ SOURCES += Controllers/LogitechController/LogitechG203LController.cpp \ Controllers/LogitechController/LogitechG213Controller.cpp \ Controllers/LogitechController/LogitechG560Controller.cpp \ + Controllers/LogitechController/LogitechG933Controller.cpp \ Controllers/LogitechController/LogitechG810Controller.cpp \ Controllers/LogitechController/LogitechG910Controller.cpp \ Controllers/LogitechController/LogitechG815Controller.cpp \ @@ -633,6 +636,7 @@ SOURCES += Controllers/LogitechController/RGBController_LogitechG203L.cpp \ Controllers/LogitechController/RGBController_LogitechG213.cpp \ Controllers/LogitechController/RGBController_LogitechG560.cpp \ + Controllers/LogitechController/RGBController_LogitechG933.cpp \ Controllers/LogitechController/RGBController_LogitechG810.cpp \ Controllers/LogitechController/RGBController_LogitechG910.cpp \ Controllers/LogitechController/RGBController_LogitechG815.cpp \