From deeb8a84b782aedb67f35030bdfaa0db64f6a466 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Sat, 22 Jul 2023 20:10:14 +0000 Subject: [PATCH] Initial HYTE CNVS controller implementation --- .../HYTEMousematController.cpp | 97 +++++++++++++++++ .../HYTEMousematController.h | 40 +++++++ .../HYTEMousematControllerDetect.cpp | 85 +++++++++++++++ .../RGBController_HYTEMousemat.cpp | 103 ++++++++++++++++++ .../RGBController_HYTEMousemat.h | 38 +++++++ OpenRGB.pro | 6 + 6 files changed, 369 insertions(+) create mode 100644 Controllers/HYTEMousematController/HYTEMousematController.cpp create mode 100644 Controllers/HYTEMousematController/HYTEMousematController.h create mode 100644 Controllers/HYTEMousematController/HYTEMousematControllerDetect.cpp create mode 100644 Controllers/HYTEMousematController/RGBController_HYTEMousemat.cpp create mode 100644 Controllers/HYTEMousematController/RGBController_HYTEMousemat.h diff --git a/Controllers/HYTEMousematController/HYTEMousematController.cpp b/Controllers/HYTEMousematController/HYTEMousematController.cpp new file mode 100644 index 00000000..96406a5d --- /dev/null +++ b/Controllers/HYTEMousematController/HYTEMousematController.cpp @@ -0,0 +1,97 @@ +/*---------------------------------------------------------*\ +| HYTEMousematController.cpp | +| | +| Driver for HYTE CNVS RGB mousemat controller | +| | +| Adam Honse (calcprogrammer1@gmail.com), 7/18/2023 | +\*---------------------------------------------------------*/ + +#include "HYTEMousematController.h" + +#include +#include +#include + +HYTEMousematController::HYTEMousematController(libusb_device_handle* dev_handle) +{ + dev = dev_handle; + + /*-----------------------------------------------------*\ + | Fill in location string with USB ID | + \*-----------------------------------------------------*/ + libusb_device_descriptor descriptor; + libusb_get_device_descriptor(libusb_get_device(dev_handle), &descriptor); + + std::stringstream location_stream; + location_stream << std::hex << std::setfill('0') << std::setw(4) << descriptor.idVendor << ":" << std::hex << std::setfill('0') << std::setw(4) << descriptor.idProduct; + location = location_stream.str(); +} + +HYTEMousematController::~HYTEMousematController() +{ + +} + +std::string HYTEMousematController::GetLocation() +{ + return(location); +} + +void HYTEMousematController::FirmwareAnimationControl(bool enabled) +{ + unsigned char serial_buf[4]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(serial_buf, 0, sizeof(serial_buf)); + + /*-----------------------------------------------------*\ + | Set up Firmware Animation Control packet | + \*-----------------------------------------------------*/ + serial_buf[0] = 0xFF; + serial_buf[1] = 0xDC; + serial_buf[2] = 0x05; + serial_buf[3] = enabled; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + libusb_bulk_transfer(dev, HYTE_CNVS_EP_OUT, serial_buf, sizeof(serial_buf), NULL, 1000); +} + +void HYTEMousematController::StreamingCommand(RGBColor* colors) +{ + unsigned char serial_buf[157]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(serial_buf, 0, sizeof(serial_buf)); + + /*-----------------------------------------------------*\ + | Set up Streaming packet | + \*-----------------------------------------------------*/ + serial_buf[0] = 0xFF; + serial_buf[1] = 0xEE; + serial_buf[2] = 0x02; + serial_buf[3] = 0x01; + serial_buf[4] = 0x00; + serial_buf[5] = 0x32; + serial_buf[6] = 0x00; + + /*-----------------------------------------------------*\ + | Copy in colors | + \*-----------------------------------------------------*/ + for(unsigned int color_idx = 0; color_idx < 50; color_idx++) + { + serial_buf[7 + (color_idx * 3)] = RGBGetGValue(colors[color_idx]); + serial_buf[8 + (color_idx * 3)] = RGBGetRValue(colors[color_idx]); + serial_buf[9 + (color_idx * 3)] = RGBGetBValue(colors[color_idx]); + } + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + libusb_bulk_transfer(dev, HYTE_CNVS_EP_OUT, serial_buf, sizeof(serial_buf), NULL, 1000); +} diff --git a/Controllers/HYTEMousematController/HYTEMousematController.h b/Controllers/HYTEMousematController/HYTEMousematController.h new file mode 100644 index 00000000..4ae19a05 --- /dev/null +++ b/Controllers/HYTEMousematController/HYTEMousematController.h @@ -0,0 +1,40 @@ +/*---------------------------------------------------------*\ +| HYTEMousematController.h | +| | +| Definitions for HYTE CNVS RGB mousemat controller | +| | +| Adam Honse (calcprogrammer1@gmail.com), 7/18/2023 | +\*---------------------------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include + +#ifdef __FreeBSD__ +#include +#else +#include +#endif + +/*---------------------------------------------------------*\ +| HYTE CNVS endpoint values | +\*---------------------------------------------------------*/ +#define HYTE_CNVS_EP_IN 0x81 +#define HYTE_CNVS_EP_OUT 0x01 + +class HYTEMousematController +{ +public: + HYTEMousematController(libusb_device_handle* dev_handle); + ~HYTEMousematController(); + + std::string GetLocation(); + + void FirmwareAnimationControl(bool enabled); + void StreamingCommand(RGBColor* colors); + +private: + libusb_device_handle* dev; + std::string location; +}; diff --git a/Controllers/HYTEMousematController/HYTEMousematControllerDetect.cpp b/Controllers/HYTEMousematController/HYTEMousematControllerDetect.cpp new file mode 100644 index 00000000..f01a00ac --- /dev/null +++ b/Controllers/HYTEMousematController/HYTEMousematControllerDetect.cpp @@ -0,0 +1,85 @@ +#include "Detector.h" +#include "HYTEMousematController.h" +#include "RGBController.h" +#include "RGBController_HYTEMousemat.h" +#include + +#ifdef __FreeBSD__ +#include +#else +#include +#endif + +/*-----------------------------------------------------*\ +| HYTE vendor ID | +\*-----------------------------------------------------*/ +#define HYTE_VID 0x3402 + +/*-----------------------------------------------------*\ +| HYTE CNVS product IDs | +\*-----------------------------------------------------*/ +#define HYTE_CNVS_HW_VER_1_PID 0x0B00 +#define HYTE_CNVS_HW_VER_2_PID 0x0B01 + +typedef struct +{ + unsigned short usb_vid; + unsigned short usb_pid; + unsigned char usb_interface; + const char * name; +} hyte_mousemat_device; + +#define HYTE_MOUSEMAT_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ])) + +static const hyte_mousemat_device device_list[] = +{ + /*-----------------------------------------------------------------------------------------------------*\ + | Mousemats | + \*-----------------------------------------------------------------------------------------------------*/ + { HYTE_VID, HYTE_CNVS_HW_VER_1_PID, 0, "HYTE CNVS" }, + { HYTE_VID, HYTE_CNVS_HW_VER_2_PID, 0, "HYTE CNVS" }, +}; + +/******************************************************************************************\ +* * +* DetectHYTEMousematControllers * +* * +* Detect devices supported by the HyteMousemat driver * +* * +\******************************************************************************************/ + +void DetectHYTEMousematControllers() +{ + libusb_init(NULL); + + #ifdef _WIN32 + libusb_set_option(NULL, LIBUSB_OPTION_USE_USBDK); + #endif + + for(std::size_t device_idx = 0; device_idx < HYTE_MOUSEMAT_NUM_DEVICES; device_idx++) + { + libusb_device_handle * dev = libusb_open_device_with_vid_pid(NULL, device_list[device_idx].usb_vid, device_list[device_idx].usb_pid); + + //Look for HYTE CNVS + if(dev) + { + libusb_detach_kernel_driver(dev, 0); + libusb_claim_interface(dev, 0); + + HYTEMousematController * controller = new HYTEMousematController(dev); + RGBController_HYTEMousemat * rgb_controller = new RGBController_HYTEMousemat(controller); + rgb_controller->name = device_list[device_idx].name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } + } + +} /* DetectHYTEMousematControllers() */ + +REGISTER_DETECTOR("HYTE Mousemat", DetectHYTEMousematControllers); +/*---------------------------------------------------------------------------------------------------------*\ +| Entries for dynamic UDEV rules | +| | +| DUMMY_DEVICE_DETECTOR("HYTE Mousemat", DetectHYTEMousematControllers, 0x3402, 0x0B00 ) | +| DUMMY_DEVICE_DETECTOR("HYTE Mousemat", DetectHYTEMousematControllers, 0x3402, 0x0B01 ) | +\*---------------------------------------------------------------------------------------------------------*/ diff --git a/Controllers/HYTEMousematController/RGBController_HYTEMousemat.cpp b/Controllers/HYTEMousematController/RGBController_HYTEMousemat.cpp new file mode 100644 index 00000000..b3571341 --- /dev/null +++ b/Controllers/HYTEMousematController/RGBController_HYTEMousemat.cpp @@ -0,0 +1,103 @@ +/*-----------------------------------------*\ +| RGBController_HYTEMousemat.cpp | +| | +| Generic RGB Interface for HYTE CNVS RGB | +| mousemat | +| | +| Adam Honse (CalcProgrammer1) 7/18/2023 | +\*-----------------------------------------*/ + +#include "RGBController_HYTEMousemat.h" + +RGBController_HYTEMousemat::RGBController_HYTEMousemat(HYTEMousematController* controller_ptr) +{ + controller = controller_ptr; + + name = "HYTE Mousemat"; + description = "HYTE Mousemat Device"; + type = DEVICE_TYPE_MOUSEMAT; + location = controller->GetLocation(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = HYTE_CNVS_MODE_DIRECT; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + // HYTE CNVS does not seem to be able to transfer back into firmware animation + // after streaming command has been used + //mode Rainbow; + //Rainbow.name = "Rainbow Wave"; + //Rainbow.value = HYTE_CNVS_MODE_RAINBOW; + //Rainbow.flags = MODE_FLAG_HAS_RANDOM_COLOR; + //Rainbow.color_mode = MODE_COLORS_RANDOM; + //modes.push_back(Rainbow); + + SetupZones(); +} + +RGBController_HYTEMousemat::~RGBController_HYTEMousemat() +{ + +} + +void RGBController_HYTEMousemat::SetupZones() +{ + zone mousemat_zone; + + mousemat_zone.name = "Mousemat"; + mousemat_zone.type = ZONE_TYPE_LINEAR; + mousemat_zone.leds_min = 50; + mousemat_zone.leds_max = 50; + mousemat_zone.leds_count = 50; + mousemat_zone.matrix_map = NULL; + + zones.push_back(mousemat_zone); + + for(unsigned int led_idx = 0; led_idx < zones[0].leds_count; led_idx++) + { + led mousemat_led; + + mousemat_led.name = "Mousemat LED "; + mousemat_led.name.append(std::to_string(led_idx)); + + leds.push_back(mousemat_led); + } + + SetupColors(); +} + +void RGBController_HYTEMousemat::ResizeZone(int /*zone*/, int /*new_size*/) +{ + +} + +void RGBController_HYTEMousemat::DeviceUpdateLEDs() +{ + controller->StreamingCommand(&colors[0]); +} + +void RGBController_HYTEMousemat::UpdateZoneLEDs(int /*zone*/) +{ + +} + +void RGBController_HYTEMousemat::UpdateSingleLED(int /*led*/) +{ + +} + +void RGBController_HYTEMousemat::DeviceUpdateMode() +{ + switch(modes[active_mode].value) + { + case HYTE_CNVS_MODE_DIRECT: + controller->FirmwareAnimationControl(false); + break; + + case HYTE_CNVS_MODE_RAINBOW: + controller->FirmwareAnimationControl(true); + break; + } +} diff --git a/Controllers/HYTEMousematController/RGBController_HYTEMousemat.h b/Controllers/HYTEMousematController/RGBController_HYTEMousemat.h new file mode 100644 index 00000000..67dc3952 --- /dev/null +++ b/Controllers/HYTEMousematController/RGBController_HYTEMousemat.h @@ -0,0 +1,38 @@ +/*-----------------------------------------*\ +| RGBController_HYTEMousemat.h | +| | +| Generic RGB Interface for HYTE CNVS RGB | +| mousemat | +| | +| Adam Honse (CalcProgrammer1) 7/18/2023 | +\*-----------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "HYTEMousematController.h" + +enum +{ + HYTE_CNVS_MODE_DIRECT = 0, /* Direct (streaming) mode */ + HYTE_CNVS_MODE_RAINBOW = 1, /* Rainbow wave (firmware animation) mode */ +}; + +class RGBController_HYTEMousemat : public RGBController +{ +public: + RGBController_HYTEMousemat(HYTEMousematController* controller_ptr); + ~RGBController_HYTEMousemat(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: + HYTEMousematController* controller; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index 4d3d6954..03c27156 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -172,6 +172,7 @@ INCLUDEPATH += Controllers/HyperXMicrophoneController/ \ Controllers/HyperXMouseController/ \ Controllers/HyperXMousematController/ \ + Controllers/HYTEMousematController/ \ Controllers/IntelArcA770LEController/ \ Controllers/IonicoController/ \ Controllers/LEDStripController/ \ @@ -533,6 +534,8 @@ HEADERS += Controllers/HyperXMouseController/RGBController_HyperXPulsefireRaid.h \ Controllers/HyperXMousematController/HyperXMousematController.h \ Controllers/HyperXMousematController/RGBController_HyperXMousemat.h \ + Controllers/HYTEMousematController/HYTEMousematController.h \ + Controllers/HYTEMousematController/RGBController_HYTEMousemat.h \ Controllers/IntelArcA770LEController/IntelArcA770LEController.h \ Controllers/IntelArcA770LEController/RGBController_IntelArcA770LE.h \ Controllers/IonicoController/IonicoController.h \ @@ -1181,6 +1184,9 @@ SOURCES += Controllers/HyperXMousematController/HyperXMousematController.cpp \ Controllers/HyperXMousematController/HyperXMousematControllerDetect.cpp \ Controllers/HyperXMousematController/RGBController_HyperXMousemat.cpp \ + Controllers/HYTEMousematController/HYTEMousematController.cpp \ + Controllers/HYTEMousematController/HYTEMousematControllerDetect.cpp \ + Controllers/HYTEMousematController/RGBController_HYTEMousemat.cpp \ Controllers/IntelArcA770LEController/IntelArcA770LEController.cpp \ Controllers/IntelArcA770LEController/IntelArcA770LEControllerDetect.cpp \ Controllers/IonicoController/IonicoController.cpp \