diff --git a/Controllers/IonicoController/IonicoController.cpp b/Controllers/IonicoController/IonicoController.cpp new file mode 100644 index 00000000..52ab3778 --- /dev/null +++ b/Controllers/IonicoController/IonicoController.cpp @@ -0,0 +1,112 @@ +/*-----------------------------------------*\ +| IonicoController.cpp | +| | +| Driver for the Ionico-II-17 lighting | +| controller | +| | +| Lucas Strafe 31/12/2022 | +\*-----------------------------------------*/ +#include "IonicoController.h" +#include + +IonicoController::IonicoController(hid_device* dev_handle, const hid_device_info& info, const unsigned short pid) +{ + dev = dev_handle; + location = info.path; + usb_pid = pid; +} + +IonicoController::~IonicoController() +{ + hid_close(dev); +} + +std::string IonicoController::GetDeviceLocation() +{ + return("HID: " + location); +} + +uint16_t IonicoController::GetUSBPID() +{ + return(usb_pid); +} + +void IonicoController::TurnOff() +{ + uint8_t usb_buf[IONICO_REPORT_SIZE]; + memset(usb_buf, 0x00, IONICO_REPORT_SIZE); + usb_buf[1] = 0x09; + usb_buf[2] = 0x02; + hid_send_feature_report(dev, usb_buf, IONICO_REPORT_SIZE); +} + +void IonicoController::SaveBios() +{ + uint8_t usb_buf[IONICO_REPORT_SIZE]; + memset(usb_buf, 0x00, IONICO_REPORT_SIZE); + usb_buf[1] = 0x1A; + usb_buf[3] = 0x01; + usb_buf[4] = 0x04; + usb_buf[8] = 0x01; + hid_send_feature_report(dev, usb_buf, IONICO_REPORT_SIZE); +} + +void IonicoController::SetMode(uint8_t mode_value, uint8_t brightness, uint8_t speed) +{ + uint8_t usb_buf[IONICO_REPORT_SIZE]; + memset(usb_buf, 0x00, IONICO_REPORT_SIZE); + usb_buf[1] = 0x08; + usb_buf[2] = 0x02; + usb_buf[3] = mode_value; + usb_buf[4] = speed; + usb_buf[5] = brightness; + usb_buf[6] = 0x08; + hid_send_feature_report(dev, usb_buf, IONICO_REPORT_SIZE); +} + +void IonicoController::SetColors(int device, std::vector array_colors, bool is_mode) +{ + /*---------------------------------------------------------*\ + | Direct mode and effects | + \*---------------------------------------------------------*/ + if(device == DEVICE_TYPE_KEYBOARD || (device == DEVICE_TYPE_LEDSTRIP && is_mode)) + { + uint8_t usb_buf[IONICO_REPORT_SIZE]; + memset(usb_buf, 0x00, IONICO_REPORT_SIZE); + for(int i = 0; i < array_colors.size(); i++) + { + usb_buf[1] = IONICO_DIRECT_CMD; + usb_buf[3] = i+1; + usb_buf[4] = RGBGetRValue(array_colors[i]); + usb_buf[5] = RGBGetGValue(array_colors[i]); + usb_buf[6] = RGBGetBValue(array_colors[i]); + hid_send_feature_report(dev, usb_buf, IONICO_REPORT_SIZE); + } + } + /*---------------------------------------------------------*\ + | LIGHT BAR LED PER LED | + \*---------------------------------------------------------*/ + else if(device == DEVICE_TYPE_LEDSTRIP && !is_mode) + { + uint8_t usb_buf[IONICO_REPORT_SIZE]; + memset(usb_buf, 0x00, IONICO_REPORT_SIZE); + usb_buf[1] = 0x12; + hid_send_feature_report(dev, usb_buf, IONICO_REPORT_SIZE); + + uint8_t usb_buf_led[IONICO_DIRECT_REPORT_SIZE]; + memset(usb_buf_led, 0x00, IONICO_DIRECT_REPORT_SIZE); + + for(int i = 0; i < array_colors.size(); i++) + { + usb_buf_led[1 + 3 * i] = RGBGetRValue(array_colors[i]); + usb_buf_led[2 + 3 * i] = RGBGetBValue(array_colors[i]); + usb_buf_led[3 + 3 * i] = RGBGetGValue(array_colors[i]); + } + hid_write(dev, usb_buf_led, IONICO_DIRECT_REPORT_SIZE); + + memset(usb_buf, 0x00, IONICO_REPORT_SIZE); + usb_buf[1] = 0x12; + usb_buf[3] = 0x01; + hid_send_feature_report(dev, usb_buf, IONICO_REPORT_SIZE); + } +} diff --git a/Controllers/IonicoController/IonicoController.h b/Controllers/IonicoController/IonicoController.h new file mode 100644 index 00000000..4286ab1b --- /dev/null +++ b/Controllers/IonicoController/IonicoController.h @@ -0,0 +1,50 @@ +#pragma once + +#include "RGBController.h" +#include +#include + +#define IONICO_REPORT_SIZE 9 +#define IONICO_DIRECT_REPORT_SIZE 65 +#define IONICO_DIRECT_CMD 0x14 +#define IONICO_KEYBOARD_LED_COUNT 4 +#define IONICO_BAR_LED_COUNT 22 +#define IONICO_DIRECT_BRIGHTNESS_MIN 0 +#define IONICO_DIRECT_BRIGHTNESS_MAX 50 +#define IONICO_DIRECT_SPEED_MIN 0 +#define IONICO_DIRECT_SPEED_MAX 10 +#define IONICO_DIRECT_SPEED_DEFAULT 5 + +enum +{ + IONICO_MODE_OFF = 0, + IONICO_MODE_DIRECT = 1, + IONICO_MODE_BREATHING = 2, + IONICO_MODE_WAVE = 3, + IONICO_MODE_RAIN = 10, + IONICO_MODE_FLASH = 18, + IONICO_FB_MODE_WAVE = 32 +}; + + +class IonicoController +{ + public: + IonicoController(hid_device* dev_handle, const hid_device_info& info, const unsigned short pid); + ~IonicoController(); + + std::string GetDeviceLocation(); + + void SetMode(uint8_t mode_value, uint8_t brightness, uint8_t speed); + void SetColors(int device, std::vector array_colors, bool is_mode); + void SaveBios(); + void TurnOff(); + uint16_t GetUSBPID(); + + private: + hid_device* dev; + std::string location; + std::string serial_number; + std::string version; + uint16_t usb_pid; +}; diff --git a/Controllers/IonicoController/IonicoControllerDetect.cpp b/Controllers/IonicoController/IonicoControllerDetect.cpp new file mode 100644 index 00000000..54525a82 --- /dev/null +++ b/Controllers/IonicoController/IonicoControllerDetect.cpp @@ -0,0 +1,52 @@ +/*-----------------------------------------*\ +| IonicoControllerDetect.cpp | +| | +| Driver for the Ionico-II-17 lighting | +| controller | +| | +| Lucas Strafe 31/12/2022 | +\*-----------------------------------------*/ + +#include "Detector.h" +#include "RGBController.h" +#include "hidapi/hidapi.h" +#include "IonicoController.h" +#include "RGBController_Ionico.h" + +/*-----------------------------------------------------*\ +| FRONT BAR | +\*-----------------------------------------------------*/ +#define IONICO_FB_VID 0x048D +#define IONICO_FB_PID 0x6005 + +/*-----------------------------------------------------*\ +| KEYBOARD | +\*-----------------------------------------------------*/ +#define IONICO_KB_VID 0x048D +#define IONICO_KB_PID 0xCE00 + + +void DetectIonicoControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + IonicoController* controller = new IonicoController(dev, *info, info->product_id); + RGBController_Ionico* rgb_controller = new RGBController_Ionico(controller); + rgb_controller->name = name; + + if(info->product_id == IONICO_KB_PID) + { + rgb_controller->type = DEVICE_TYPE_KEYBOARD; + } + else if(info->product_id == IONICO_FB_PID) + { + rgb_controller->type = DEVICE_TYPE_LEDSTRIP; + } + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_HID_DETECTOR_PU("Ionico Light Bar", DetectIonicoControllers, IONICO_FB_VID, IONICO_FB_PID, 0xFF03, 0x01); +REGISTER_HID_DETECTOR_PU("Ionico Keyboard", DetectIonicoControllers, IONICO_KB_VID, IONICO_KB_PID, 0xFF12, 0x01); diff --git a/Controllers/IonicoController/RGBController_Ionico.cpp b/Controllers/IonicoController/RGBController_Ionico.cpp new file mode 100644 index 00000000..7828881c --- /dev/null +++ b/Controllers/IonicoController/RGBController_Ionico.cpp @@ -0,0 +1,222 @@ +/*-----------------------------------------*\ +| RGBController_Ionico.cpp | +| | +| Driver for the Ionico-II-17 lighting | +| controller | +| | +| Lucas Strafe 31/12/2022 | +\*-----------------------------------------*/ + +#include "RGBController_Ionico.h" + +/**------------------------------------------------------------------*\ + @name Ionico-II 17 + @category Keyboard,LEDStrip + @type USB + @save :white_check_mark: + @direct :white_check_mark: + @effects :white_check_mark: + @detectors DetectIonicoControllers + @comment +\*-------------------------------------------------------------------*/ + + +RGBController_Ionico::RGBController_Ionico(IonicoController* controller_ptr) +{ + controller = controller_ptr; + name = "Ionico"; + vendor = "Pcspecialist"; + description = name; + location = controller->GetDeviceLocation(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = IONICO_MODE_DIRECT; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE; + Direct.color_mode = MODE_COLORS_PER_LED; + Direct.brightness_min = IONICO_DIRECT_BRIGHTNESS_MIN; + Direct.brightness_max = IONICO_DIRECT_BRIGHTNESS_MAX; + Direct.brightness = IONICO_DIRECT_BRIGHTNESS_MAX; + Direct.colors.resize(4); + modes.push_back(Direct); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = IONICO_MODE_BREATHING; + Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE; + Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC; + Breathing.speed_min = IONICO_DIRECT_SPEED_MIN; + Breathing.speed_max = IONICO_DIRECT_SPEED_MAX; + Breathing.speed = IONICO_DIRECT_SPEED_DEFAULT; + Breathing.brightness_min = IONICO_DIRECT_BRIGHTNESS_MIN; + Breathing.brightness_max = IONICO_DIRECT_BRIGHTNESS_MAX; + Breathing.brightness = IONICO_DIRECT_BRIGHTNESS_MAX; + Breathing.colors.resize(7); + modes.push_back(Breathing); + + mode Wave; + Wave.name = "Wave"; + if(controller->GetUSBPID() == IONICO_KB_PID) + { + Wave.value = IONICO_MODE_WAVE; + } + else if(controller->GetUSBPID() == IONICO_FB_PID) + { + Wave.value = IONICO_FB_MODE_WAVE; + } + Wave.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE; + Wave.color_mode = MODE_COLORS_MODE_SPECIFIC; + Wave.speed_min = IONICO_DIRECT_SPEED_MIN; + Wave.speed_max = IONICO_DIRECT_SPEED_MAX; + Wave.speed = IONICO_DIRECT_SPEED_DEFAULT; + Wave.brightness_min = IONICO_DIRECT_BRIGHTNESS_MIN; + Wave.brightness_max = IONICO_DIRECT_BRIGHTNESS_MAX; + Wave.brightness = IONICO_DIRECT_BRIGHTNESS_MAX; + Wave.colors.resize(7); + modes.push_back(Wave); + + if(controller->GetUSBPID() == IONICO_KB_PID) + { + mode Flash; + Flash.name = "Flashing"; + Flash.value = IONICO_MODE_FLASH; + Flash.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE; + Flash.color_mode = MODE_COLORS_MODE_SPECIFIC; + Flash.speed_min = IONICO_DIRECT_SPEED_MIN; + Flash.speed_max = IONICO_DIRECT_SPEED_MAX; + Flash.speed = IONICO_DIRECT_SPEED_DEFAULT; + Flash.brightness_min = IONICO_DIRECT_BRIGHTNESS_MIN; + Flash.brightness_max = IONICO_DIRECT_BRIGHTNESS_MAX; + Flash.brightness = IONICO_DIRECT_BRIGHTNESS_MAX; + Flash.colors.resize(7); + modes.push_back(Flash); + } + + if(controller->GetUSBPID() == IONICO_FB_PID) + { + mode Raindrops; + Raindrops.name = "Raindrops"; + Raindrops.value = IONICO_MODE_RAIN; + Raindrops.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE; + Raindrops.color_mode = MODE_COLORS_MODE_SPECIFIC; + Raindrops.speed_min = IONICO_DIRECT_SPEED_MIN; + Raindrops.speed_max = IONICO_DIRECT_SPEED_MAX; + Raindrops.speed = IONICO_DIRECT_SPEED_DEFAULT; + Raindrops.brightness_min = IONICO_DIRECT_BRIGHTNESS_MIN; + Raindrops.brightness_max = IONICO_DIRECT_BRIGHTNESS_MAX; + Raindrops.brightness = IONICO_DIRECT_BRIGHTNESS_MAX; + Raindrops.colors.resize(7); + modes.push_back(Raindrops); + } + + mode Off; + Off.name = "Off"; + modes.push_back(Off); + + SetupZones(); +} + +RGBController_Ionico::~RGBController_Ionico() +{ + delete controller; +} + +void RGBController_Ionico::SetupZones() +{ + /*-------------------------------------------------*\ + | Clear any existing color/LED configuration | + \*-------------------------------------------------*/ + leds.clear(); + colors.clear(); + + /*---------------------------------------------------------*\ + | Set up zones | + \*---------------------------------------------------------*/ + if(controller->GetUSBPID() == IONICO_KB_PID) + { + leds.resize(IONICO_KEYBOARD_LED_COUNT); + zone zone_keyboard; + zone_keyboard.name = "Keyboard"; + zone_keyboard.type = ZONE_TYPE_LINEAR; + zone_keyboard.leds_min = leds.size(); + zone_keyboard.leds_max = leds.size(); + zone_keyboard.leds_count = leds.size(); + zone_keyboard.matrix_map = nullptr; + zones.emplace_back(zone_keyboard); + for(int i = 0; i < leds.size(); ++i) + { + leds[i].name = "Keyboard Zone " + std::to_string(i+1); + } + } + else if(controller->GetUSBPID() == IONICO_FB_PID) + { + leds.resize(IONICO_BAR_LED_COUNT); + zone zone_bar; + zone_bar.name = "Front Bar"; + zone_bar.type = ZONE_TYPE_LINEAR; + zone_bar.leds_min = leds.size(); + zone_bar.leds_max = leds.size(); + zone_bar.leds_count = leds.size(); + zone_bar.matrix_map = nullptr; + zones.emplace_back(zone_bar); + for(int i = 0; i < leds.size(); ++i) + { + leds[i].name = "Bar Led " + std::to_string(i+1); + } + } + SetupColors(); +} + +void RGBController_Ionico::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_Ionico::DeviceUpdateLEDs() +{ + /*---------------------------------------------------------*\ + | MODE_COLORS_PER_LED | + \*---------------------------------------------------------*/ + controller->SetColors(type, colors, false); +} + +void RGBController_Ionico::DeviceSaveMode() +{ + controller->SaveBios(); +} + +void RGBController_Ionico::UpdateZoneLEDs(int zone) +{ + DeviceUpdateLEDs(); +} + +void RGBController_Ionico::UpdateSingleLED(int led) +{ + // +} + +void RGBController_Ionico::DeviceUpdateMode() +{ + switch (modes[active_mode].value) + { + case IONICO_MODE_OFF: + controller->TurnOff(); + break; + case IONICO_MODE_DIRECT: + if(type == DEVICE_TYPE_LEDSTRIP) + { + controller->SetMode(0x33, modes[active_mode].brightness, 0); + } + else + { + controller->SetMode(modes[active_mode].value, modes[active_mode].brightness, 0); + } + break; + default: + controller->SetMode(modes[active_mode].value, modes[active_mode].brightness, modes[active_mode].speed); + controller->SetColors(type, modes[active_mode].colors, true); + break; + } +} diff --git a/Controllers/IonicoController/RGBController_Ionico.h b/Controllers/IonicoController/RGBController_Ionico.h new file mode 100644 index 00000000..11628af4 --- /dev/null +++ b/Controllers/IonicoController/RGBController_Ionico.h @@ -0,0 +1,37 @@ +/*-----------------------------------------*\ +| RGBController_Ionico.h | +| | +| Driver for the Ionico-II-17 lighting | +| controller | +| | +| Lucas Strafe 31/12/2022 | +\*-----------------------------------------*/ +#pragma once + +#include "RGBController.h" +#include "IonicoController.h" + +#define IONICO_KB_PID 0xCE00 +#define IONICO_FB_PID 0x6005 + +class RGBController_Ionico : public RGBController +{ +public: + RGBController_Ionico(IonicoController* controller_ptr); + ~RGBController_Ionico(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void SetSingleLED(); + void UpdateSingleLED(int led); + void DeviceSaveMode(); + + void DeviceUpdateMode(); + + +private: + IonicoController* controller; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index e90100a7..20538759 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -131,6 +131,7 @@ INCLUDEPATH += Controllers/HyperXMouseController/ \ Controllers/HyperXMousematController/ \ Controllers/IntelArcA770LEController/ \ + Controllers/IonicoController/ \ Controllers/LEDStripController/ \ Controllers/LenovoControllers/ \ Controllers/LenovoMotherboardController/ \ @@ -455,6 +456,8 @@ HEADERS += Controllers/HyperXMousematController/RGBController_HyperXMousemat.h \ Controllers/IntelArcA770LEController/IntelArcA770LEController.h \ Controllers/IntelArcA770LEController/RGBController_IntelArcA770LE.h \ + Controllers/IonicoController/IonicoController.h \ + Controllers/IonicoController/RGBController_Ionico.h \ Controllers/KeychronKeyboardController/KeychronKeyboardController.h \ Controllers/KeychronKeyboardController/RGBController_KeychronKeyboard.h \ Controllers/LEDStripController/LEDStripController.h \ @@ -1034,6 +1037,9 @@ SOURCES += Controllers/HyperXMousematController/RGBController_HyperXMousemat.cpp \ Controllers/IntelArcA770LEController/IntelArcA770LEController.cpp \ Controllers/IntelArcA770LEController/IntelArcA770LEControllerDetect.cpp \ + Controllers/IonicoController/IonicoController.cpp \ + Controllers/IonicoController/IonicoControllerDetect.cpp \ + Controllers/IonicoController/RGBController_Ionico.cpp \ Controllers/IntelArcA770LEController/RGBController_IntelArcA770LE.cpp \ Controllers/KeychronKeyboardController/KeychronKeyboardController.cpp \ Controllers/KeychronKeyboardController/KeychronKeyboardControllerDetect.cpp \