diff --git a/Controllers/N5312AController/N5312AController.cpp b/Controllers/N5312AController/N5312AController.cpp new file mode 100644 index 00000000..405a4418 --- /dev/null +++ b/Controllers/N5312AController/N5312AController.cpp @@ -0,0 +1,105 @@ +/*-----------------------------------------*\ +| N5312AController.cpp | +| | +| Driver for N5312A lighting | +| controller | +| | +| Guimard Morgan (morg) 4/02/2022 | +\*-----------------------------------------*/ +#include "N5312AController.h" +#include +#include "LogManager.h" + +N5312AController::N5312AController(hid_device* dev_handle, const hid_device_info& info) +{ + dev = dev_handle; + location = info.path; + version = ""; + + wchar_t serial_string[128]; + int ret = hid_get_serial_number_string(dev, serial_string, 128); + + if(ret != 0) + { + serial_number = ""; + } + else + { + std::wstring return_wstring = serial_string; + serial_number = std::string(return_wstring.begin(), return_wstring.end()); + } + + SendInit(); +} + +N5312AController::~N5312AController() +{ + hid_close(dev); +} + +std::string N5312AController::GetDeviceLocation() +{ + return("HID: " + location); +} + +std::string N5312AController::GetSerialString() +{ + return(serial_number); +} + +std::string N5312AController::GetFirmwareVersion() +{ + return(version); +} + +void N5312AController::SendInit() +{ + unsigned char usb_buf[N5312A_PACKET_DATA_LENGTH]; + + memset(usb_buf, 0x00, N5312A_PACKET_DATA_LENGTH); + + usb_buf[0x00] = N5312A_REPORT_ID; + usb_buf[0x01] = N5312A_INIT_BYTE; + + hid_send_feature_report(dev, usb_buf, N5312A_PACKET_DATA_LENGTH); +} + +void N5312AController::SetColor(RGBColor color) +{ + unsigned char usb_buf[N5312A_PACKET_DATA_LENGTH]; + + memset(usb_buf, 0x00, N5312A_PACKET_DATA_LENGTH); + + usb_buf[0x00] = N5312A_REPORT_ID; + usb_buf[0x01] = N5312A_SET_COLOR_BYTE; + usb_buf[0x02] = 1; + usb_buf[0x03] = RGBGetRValue(color); + usb_buf[0x04] = RGBGetGValue(color); + usb_buf[0x05] = RGBGetBValue(color); + + hid_send_feature_report(dev, usb_buf, N5312A_PACKET_DATA_LENGTH); + +} + +void N5312AController::SetMode(RGBColor color, unsigned char mode_value, unsigned char brightness, unsigned char speed) +{ + SetColor(color); + + unsigned char usb_buf[N5312A_PACKET_DATA_LENGTH]; + + memset(usb_buf, 0x00, N5312A_PACKET_DATA_LENGTH); + + usb_buf[0x00] = N5312A_REPORT_ID; + usb_buf[0x01] = N5312A_SET_MODE_BYTE; + + usb_buf[0x02] = mode_value; + + usb_buf[0x03] = 0x01; + usb_buf[0x04] = 0x01; + usb_buf[0x05] = 0x01; + + usb_buf[0x06] = speed; + usb_buf[0x07] = brightness; + + hid_send_feature_report(dev, usb_buf, N5312A_PACKET_DATA_LENGTH); +} diff --git a/Controllers/N5312AController/N5312AController.h b/Controllers/N5312AController/N5312AController.h new file mode 100644 index 00000000..89efe23e --- /dev/null +++ b/Controllers/N5312AController/N5312AController.h @@ -0,0 +1,59 @@ +/*-----------------------------------------*\ +| N5312AController.h | +| | +| Driver for N5312A lighting | +| controller - header file | +| | +| Guimard Morgan (morg) 4/02/2022 | +\*-----------------------------------------*/ +#pragma once + +#include "RGBController.h" +#include +#include + +#define N5312A_REPORT_ID 0x07 +#define N5312A_PACKET_DATA_LENGTH 8 +#define N5312A_NUMBER_OF_LEDS 1 +#define N5312A_INIT_BYTE 0xA0 +#define N5312A_SET_MODE_BYTE 0x0A +#define N5312A_SET_COLOR_BYTE 0x0B + +enum +{ + N5312A_BREATHING_MODE_VALUE = 0x00, + N5312A_SINGLE_BREATH_MODE_VALUE = 0x01, + N5312A_DIRECT_MODE_VALUE = 0x02, + N5312A_OFF_MODE_VALUE = 0x03 +}; + +enum +{ + N5312A_BRIGHTNESS_MIN = 0x0A, + N5312A_BRIGHTNESS_MAX = 0x64, + N5312A_SPEED_MIN = 0x01, + N5312A_SPEED_MAX = 0x0A +}; + +class N5312AController +{ +public: + N5312AController(hid_device* dev_handle, const hid_device_info& info); + ~N5312AController(); + + std::string GetSerialString(); + std::string GetDeviceLocation(); + std::string GetFirmwareVersion(); + + void SetColor(RGBColor color); + void SetMode(RGBColor color, unsigned char mode_value, unsigned char brightness, unsigned char speed); + +private: + hid_device* dev; + + std::string location; + std::string serial_number; + std::string version; + + void SendInit(); +}; diff --git a/Controllers/N5312AController/N5312AControllerDetect.cpp b/Controllers/N5312AController/N5312AControllerDetect.cpp new file mode 100644 index 00000000..e64f80ff --- /dev/null +++ b/Controllers/N5312AController/N5312AControllerDetect.cpp @@ -0,0 +1,30 @@ +#include "Detector.h" +#include "N5312AController.h" +#include "RGBController.h" +#include "RGBController_N5312A.h" + +/*---------------------------------------------------------*\ +| N5312A vendor ID | +\*---------------------------------------------------------*/ +#define N5312A_VID 0x4E53 + +/*---------------------------------------------------------*\ +| Product ID | +\*---------------------------------------------------------*/ +#define N5312A_PID 0x5406 + +void DetectN5312AControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + N5312AController* controller = new N5312AController(dev, *info); + RGBController_N5312A* rgb_controller = new RGBController_N5312A(controller); + rgb_controller->name = rgb_controller->name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_HID_DETECTOR_IPU("N5312A USB Optical Mouse", DetectN5312AControllers, N5312A_VID, N5312A_PID, 1, 0xFF01, 0x01); diff --git a/Controllers/N5312AController/RGBController_N5312A.cpp b/Controllers/N5312AController/RGBController_N5312A.cpp new file mode 100644 index 00000000..b06aec77 --- /dev/null +++ b/Controllers/N5312AController/RGBController_N5312A.cpp @@ -0,0 +1,143 @@ +/*-----------------------------------------*\ +| RGBController_N5312A.cpp | +| | +| Generic RGB Interface for OpenRGB | +| N5312A RGB USB Driver | +| | +| Guimard Morgan (morg) 4/02/2022 | +\*-----------------------------------------*/ + +#include "RGBController_N5312A.h" + +#include +#include + +/**------------------------------------------------------------------*\ + @name N5312A mouse + @category Mouse + @type USB + @save :x: + @direct :white_check_mark: + @effects :white_check_mark: + @detectors DetectN5312AControllers + @comment This controller should work with all mouse with this chip. + Identified devices that work with this controller: ANT Esports KM540 Mouse, + Marvo M115 +\*-------------------------------------------------------------------*/ +RGBController_N5312A::RGBController_N5312A(N5312AController* controller_ptr) +{ + controller = controller_ptr; + name = "N5312A Device"; + vendor = "Unknown"; + type = DEVICE_TYPE_MOUSE; + description = name; + location = controller->GetDeviceLocation(); + serial = controller->GetSerialString(); + version = controller->GetFirmwareVersion(); + + mode Static; + Static.name = "Direct"; + Static.value = N5312A_DIRECT_MODE_VALUE; + Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Static.color_mode = MODE_COLORS_PER_LED; + Static.brightness_min = N5312A_BRIGHTNESS_MIN; + Static.brightness_max = N5312A_BRIGHTNESS_MAX; + Static.brightness = N5312A_BRIGHTNESS_MAX; + modes.push_back(Static); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = N5312A_BREATHING_MODE_VALUE; + Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED; + Breathing.color_mode = MODE_COLORS_PER_LED; + Breathing.brightness_min = N5312A_BRIGHTNESS_MIN; + Breathing.brightness_max = N5312A_BRIGHTNESS_MAX; + Breathing.brightness = N5312A_BRIGHTNESS_MAX; + Breathing.speed = N5312A_SPEED_MIN; + Breathing.speed_min = N5312A_SPEED_MIN; + Breathing.speed_max = N5312A_SPEED_MAX; + modes.push_back(Breathing); + + mode SingleBreath; + SingleBreath.name = "Single Breath"; + SingleBreath.value = N5312A_SINGLE_BREATH_MODE_VALUE; + SingleBreath.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED; + SingleBreath.color_mode = MODE_COLORS_PER_LED; + SingleBreath.brightness_min = N5312A_BRIGHTNESS_MIN; + SingleBreath.brightness_max = N5312A_BRIGHTNESS_MAX; + SingleBreath.brightness = N5312A_BRIGHTNESS_MAX; + SingleBreath.speed = N5312A_SPEED_MIN; + SingleBreath.speed_min = N5312A_SPEED_MIN; + SingleBreath.speed_max = N5312A_SPEED_MAX; + modes.push_back(SingleBreath); + + mode Off; + Off.name = "Off"; + Off.value = N5312A_OFF_MODE_VALUE; + Off.flags = 0x00; + Off.color_mode = MODE_COLORS_NONE; + modes.push_back(Off); + + SetupZones(); +} + +RGBController_N5312A::~RGBController_N5312A() +{ + delete controller; +} + +void RGBController_N5312A::SetupZones() +{ + zone new_zone; + + new_zone.name = "Mouse"; + new_zone.type = ZONE_TYPE_LINEAR; + new_zone.leds_min = N5312A_NUMBER_OF_LEDS; + new_zone.leds_max = N5312A_NUMBER_OF_LEDS; + new_zone.leds_count = N5312A_NUMBER_OF_LEDS; + new_zone.matrix_map = nullptr; + + zones.emplace_back(new_zone); + + leds.resize(new_zone.leds_count); + + for(unsigned int i = 0; i < N5312A_NUMBER_OF_LEDS; i++) + { + leds[i].name = "LED " + std::to_string(i + 1); + } + + SetupColors(); +} + +void RGBController_N5312A::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_N5312A::DeviceUpdateLEDs() +{ + UpdateZoneLEDs(0); +} + +void RGBController_N5312A::UpdateZoneLEDs(int /*zone*/) +{ + controller->SetColor(colors[0]); +} + +void RGBController_N5312A::UpdateSingleLED(int led) +{ + UpdateZoneLEDs(led); +} + +void RGBController_N5312A::SetCustomMode() +{ + active_mode = 0; +} + +void RGBController_N5312A::DeviceUpdateMode() +{ + const RGBColor& color = modes[active_mode].value == N5312A_OFF_MODE_VALUE ? 0 : colors[0]; + controller->SetMode(color, modes[active_mode].value, modes[active_mode].brightness, modes[active_mode].speed); +} diff --git a/Controllers/N5312AController/RGBController_N5312A.h b/Controllers/N5312AController/RGBController_N5312A.h new file mode 100644 index 00000000..e49ff35b --- /dev/null +++ b/Controllers/N5312AController/RGBController_N5312A.h @@ -0,0 +1,31 @@ +/*-----------------------------------------*\ +| RGBController_N5312A.h | +| | +| Generic RGB Interface for OpenRGB | +| N5312A RGB USB Driver | +| | +| Guimard Morgan (morg) 4/02/2022 | +\*-----------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "N5312AController.h" + +class RGBController_N5312A : public RGBController +{ +public: + RGBController_N5312A(N5312AController* controller_ptr); + ~RGBController_N5312A(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + void DeviceUpdateMode(); + void SetCustomMode(); + +private: + N5312AController* controller; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index 17d07be2..4f62ace2 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -463,6 +463,8 @@ HEADERS += Controllers/MSIVigorController/MSIVigorGK30Controller.h \ Controllers/NanoleafController/NanoleafController.h \ Controllers/MSIRGBController/RGBController_MSIRGB.h \ + Controllers/N5312AController/N5312AController.h \ + Controllers/N5312AController/RGBController_N5312A.h \ Controllers/NvidiaESAController/NvidiaESAController.h \ Controllers/NanoleafController/RGBController_Nanoleaf.h \ Controllers/NvidiaESAController/RGBController_NvidiaESA.h \ @@ -968,6 +970,9 @@ SOURCES += Controllers/NanoleafController/NanoleafController.cpp \ Controllers/NanoleafController/NanoleafControllerDetect.cpp \ Controllers/NanoleafController/RGBController_Nanoleaf.cpp \ + Controllers/N5312AController/N5312AController.cpp \ + Controllers/N5312AController/N5312AControllerDetect.cpp \ + Controllers/N5312AController/RGBController_N5312A.cpp \ Controllers/NvidiaESAController/NvidiaESAController.cpp \ Controllers/NvidiaESAController/NvidiaESAControllerDetect.cpp \ Controllers/NvidiaESAController/RGBController_NvidiaESA.cpp \