diff --git a/Controllers/SRGBmodsController/RGBController_SRGBmodsLEDControllerV1.cpp b/Controllers/SRGBmodsController/RGBController_SRGBmodsLEDControllerV1.cpp new file mode 100644 index 00000000..3b0daedf --- /dev/null +++ b/Controllers/SRGBmodsController/RGBController_SRGBmodsLEDControllerV1.cpp @@ -0,0 +1,221 @@ +/*-----------------------------------------*\ +| RGBController_SRGBmodsLEDControllerV1.cpp| +| | +| Generic RGB Interface for SRGBmods | +| LED Controller V1 | +| | +| Adam Honse (CalcProgrammer1) 6/30/2023 | +\*-----------------------------------------*/ + +#include "RGBController_SRGBmodsLEDControllerV1.h" + +/**------------------------------------------------------------------*\ + @name SRGBmods LED Controller V1 + @category LEDStrip + @type USB + @save :x: + @direct :white_check_mark: + @effects :white_check_mark: + @detectors DetectSRGBmodsControllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_SRGBmodsLEDControllerV1::RGBController_SRGBmodsLEDControllerV1(SRGBmodsLEDControllerV1* controller_ptr) +{ + controller = controller_ptr; + + name = "SRGBmods Device"; + vendor = "SRGBmods.net"; + description = "SRGBmods LED Controller V1 Device"; + type = DEVICE_TYPE_LEDSTRIP; + location = controller->GetLocationString(); + serial = controller->GetSerialString(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = SRGBMODS_LED_CONTROLLER_V1_MODE_DIRECT; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + mode Rainbow; + Rainbow.name = "Rainbow Wave"; + Rainbow.value = SRGBMODS_LED_CONTROLLER_V1_MODE_RAINBOW; + Rainbow.flags = MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; + Rainbow.color_mode = MODE_COLORS_RANDOM; + Rainbow.brightness_min = 0x00; + Rainbow.brightness_max = 0xFF; + Rainbow.brightness = 0xFF; + Rainbow.speed_min = 0x0A; + Rainbow.speed_max = 0xFF; + Rainbow.speed = 0x7F; + modes.push_back(Rainbow); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = SRGBMODS_LED_CONTROLLER_V1_MODE_BREATHING_MODE_SPECIFIC; + Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; + Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC; + Breathing.brightness_min = 0x00; + Breathing.brightness_max = 0xFF; + Breathing.brightness = 0xFF; + Breathing.speed_min = 0x0A; + Breathing.speed_max = 0xFF; + Breathing.speed = 0x7F; + Breathing.colors_min = 1; + Breathing.colors_max = 1; + Breathing.colors.resize(1); + modes.push_back(Breathing); + + mode Static; + Static.name = "Static"; + Static.value = SRGBMODS_LED_CONTROLLER_V1_MODE_STATIC; + Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; + Static.color_mode = MODE_COLORS_MODE_SPECIFIC; + Static.brightness_min = 0x00; + Static.brightness_max = 0xFF; + Static.brightness = 0xFF; + Static.colors_min = 1; + Static.colors_max = 1; + Static.colors.resize(1); + modes.push_back(Static); + + SetupZones(); +} + +RGBController_SRGBmodsLEDControllerV1::~RGBController_SRGBmodsLEDControllerV1() +{ + delete controller; +} + +void RGBController_SRGBmodsLEDControllerV1::SetupZones() +{ + /*-------------------------------------------------*\ + | Only set LED count on the first run | + \*-------------------------------------------------*/ + bool first_run = false; + + if(zones.size() == 0) + { + first_run = true; + } + + /*-------------------------------------------------*\ + | Clear any existing color/LED configuration | + \*-------------------------------------------------*/ + leds.clear(); + colors.clear(); + zones.resize(SRGBMODS_LED_CONTROLLER_V1_NUM_CHANNELS); + + /*-------------------------------------------------*\ + | Set zones and leds | + \*-------------------------------------------------*/ + for(unsigned int channel_idx = 0; channel_idx < SRGBMODS_LED_CONTROLLER_V1_NUM_CHANNELS; channel_idx++) + { + char ch_idx_string[2]; + snprintf(ch_idx_string, 2, "%d", channel_idx + 1); + + zones[channel_idx].name = "Channel "; + zones[channel_idx].name.append(ch_idx_string); + zones[channel_idx].type = ZONE_TYPE_LINEAR; + + /*-------------------------------------------------*\ + | The maximum number of LEDs per channel is 800 | + | according to https://srgbmods.net/lcv1/ | + \*-------------------------------------------------*/ + zones[channel_idx].leds_min = 0; + zones[channel_idx].leds_max = 800; + + if(first_run) + { + zones[channel_idx].leds_count = 0; + } + + zones[channel_idx].matrix_map = NULL; + + for(unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++) + { + char led_idx_string[4]; + snprintf(led_idx_string, 4, "%d", led_ch_idx + 1); + + led new_led; + new_led.name = "LED "; + new_led.name.append(led_idx_string); + + leds.push_back(new_led); + leds_channel.push_back(channel_idx); + } + } + + SetupColors(); +} + +void RGBController_SRGBmodsLEDControllerV1::ResizeZone(int zone, int new_size) +{ + if((size_t) zone >= zones.size()) + { + return; + } + + if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max)) + { + zones[zone].leds_count = new_size; + + SetupZones(); + } +} + +void RGBController_SRGBmodsLEDControllerV1::DeviceUpdateLEDs() +{ + if(modes[active_mode].value == SRGBMODS_LED_CONTROLLER_V1_MODE_DIRECT) + { + for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + if(zones[zone_idx].leds_count > 0) + { + controller->SetChannelLEDs(zone_idx, zones[zone_idx].colors, zones[zone_idx].leds_count); + } + } + } + else + { + DeviceUpdateMode(); + } +} + +void RGBController_SRGBmodsLEDControllerV1::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_SRGBmodsLEDControllerV1::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_SRGBmodsLEDControllerV1::DeviceUpdateMode() +{ + if(modes[active_mode].value == SRGBMODS_LED_CONTROLLER_V1_MODE_DIRECT) + { + controller->SetDirect(); + + DeviceUpdateLEDs(); + } + else + { + unsigned int value = modes[active_mode].value; + RGBColor color = 0; + + if(modes[active_mode].value == SRGBMODS_LED_CONTROLLER_V1_MODE_BREATHING_MODE_SPECIFIC && modes[active_mode].color_mode == MODE_COLORS_RANDOM) + { + value = SRGBMODS_LED_CONTROLLER_V1_MODE_BREATHING_RANDOM; + } + + if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) + { + color = modes[active_mode].colors[0]; + } + + controller->SetConfiguration(value, modes[active_mode].speed, modes[active_mode].brightness, color); + } +} diff --git a/Controllers/SRGBmodsController/RGBController_SRGBmodsLEDControllerV1.h b/Controllers/SRGBmodsController/RGBController_SRGBmodsLEDControllerV1.h new file mode 100644 index 00000000..91c3f343 --- /dev/null +++ b/Controllers/SRGBmodsController/RGBController_SRGBmodsLEDControllerV1.h @@ -0,0 +1,36 @@ +/*-----------------------------------------*\ +| RGBController_SRGBmodsLEDControllerV1.h | +| | +| Generic RGB Interface for SRGBmods | +| LED Controller V1 | +| | +| Adam Honse (CalcProgrammer1) 6/30/2023 | +\*-----------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "SRGBmodsLEDControllerV1.h" + +#define SRGBMODS_LED_CONTROLLER_V1_NUM_CHANNELS 1 + +class RGBController_SRGBmodsLEDControllerV1 : public RGBController +{ +public: + RGBController_SRGBmodsLEDControllerV1(SRGBmodsLEDControllerV1* controller_ptr); + ~RGBController_SRGBmodsLEDControllerV1(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: + SRGBmodsLEDControllerV1* controller; + std::vector leds_channel; + std::vector zones_channel; +}; diff --git a/Controllers/SRGBmodsController/SRGBmodsControllerDetect.cpp b/Controllers/SRGBmodsController/SRGBmodsControllerDetect.cpp index 69dc467b..8b79ed21 100644 --- a/Controllers/SRGBmodsController/SRGBmodsControllerDetect.cpp +++ b/Controllers/SRGBmodsController/SRGBmodsControllerDetect.cpp @@ -1,12 +1,16 @@ #include "Detector.h" +#include "SRGBmodsLEDControllerV1.h" #include "SRGBmodsPicoController.h" #include "RGBController.h" +#include "RGBController_SRGBmodsLEDControllerV1.h" #include "RGBController_SRGBmodsPico.h" #include #include -#define SRGBMODS_PICO_VID 0x16D0 -#define SRGBMODS_PICO_PID 0x1123 +#define SRGBMODS_VID 0x16D0 + +#define SRGBMODS_PICO_PID 0x1123 +#define SRGBMODS_LED_CONTROLLER_V1_PID 0x1205 /******************************************************************************************\ * * @@ -37,9 +41,18 @@ void DetectSRGBmodsControllers(hid_device_info* info, const std::string& name) RGBController_SRGBmodsPico* rgb_controller = new RGBController_SRGBmodsPico(controller); rgb_controller->name = name; + ResourceManager::get()->RegisterRGBController(rgb_controller); + } + else if(product_str == L"LED Controller v1") + { + SRGBmodsLEDControllerV1* controller = new SRGBmodsLEDControllerV1(dev, info->path); + RGBController_SRGBmodsLEDControllerV1* rgb_controller = new RGBController_SRGBmodsLEDControllerV1(controller); + rgb_controller->name = name; + ResourceManager::get()->RegisterRGBController(rgb_controller); } } } /* DetectSRGBmodsControllers() */ -REGISTER_HID_DETECTOR("SRGBmods Pico LED Controller", DetectSRGBmodsControllers, SRGBMODS_PICO_VID, SRGBMODS_PICO_PID); +REGISTER_HID_DETECTOR("SRGBmods Pico LED Controller", DetectSRGBmodsControllers, SRGBMODS_VID, SRGBMODS_PICO_PID ); +REGISTER_HID_DETECTOR("SRGBMods LED Controller v1", DetectSRGBmodsControllers, SRGBMODS_VID, SRGBMODS_LED_CONTROLLER_V1_PID); diff --git a/Controllers/SRGBmodsController/SRGBmodsLEDControllerV1.cpp b/Controllers/SRGBmodsController/SRGBmodsLEDControllerV1.cpp new file mode 100644 index 00000000..9e88fdcf --- /dev/null +++ b/Controllers/SRGBmodsController/SRGBmodsLEDControllerV1.cpp @@ -0,0 +1,170 @@ +/*-----------------------------------------*\ +| SRGBmodsLEDControllerV1.cpp | +| | +| Driver for SRGBmods LED Controller V1 | +| | +| Adam Honse (CalcProgrammer1) 6/30/2023 | +\*-----------------------------------------*/ + +#include "SRGBmodsLEDControllerV1.h" +#include + +using namespace std::chrono_literals; + +SRGBmodsLEDControllerV1::SRGBmodsLEDControllerV1(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; +} + +SRGBmodsLEDControllerV1::~SRGBmodsLEDControllerV1() +{ + hid_close(dev); +} + +std::string SRGBmodsLEDControllerV1::GetLocationString() +{ + return("HID: " + location); +} + +std::string SRGBmodsLEDControllerV1::GetSerialString() +{ + wchar_t serial_string[128]; + int ret = hid_get_serial_number_string(dev, serial_string, 128); + + if(ret != 0) + { + return(""); + } + + std::wstring return_wstring = serial_string; + std::string return_string(return_wstring.begin(), return_wstring.end()); + + return(return_string); +} + +void SRGBmodsLEDControllerV1::SetChannelLEDs(unsigned char channel, RGBColor* colors, unsigned int num_colors) +{ + /*-----------------------------------------------------*\ + | Determine number of packets to send | + \*-----------------------------------------------------*/ + unsigned int num_packets = (num_colors / 20) + ((num_colors % 20) > 0); + unsigned int color_idx = 0; + + /*-----------------------------------------------------*\ + | Send direct mode packets until all colors sent | + \*-----------------------------------------------------*/ + for(unsigned int packet_idx = 0; packet_idx < num_packets; packet_idx++) + { + unsigned int colors_in_packet = 20; + + if(num_colors - color_idx < colors_in_packet) + { + colors_in_packet = num_colors - color_idx; + } + + SendPacket(packet_idx + 1, num_packets, false, &colors[color_idx], colors_in_packet); + + color_idx += colors_in_packet; + } +} + +void SRGBmodsLEDControllerV1::SetConfiguration(unsigned char mode, unsigned char speed, unsigned char brightness, RGBColor color) +{ + SendConfiguration(0, 1, mode, speed, brightness, color, 0, 0); +} + +void SRGBmodsLEDControllerV1::SetDirect() +{ + /*-----------------------------------------------------*\ + | Disable hardware lighting and color compression | + \*-----------------------------------------------------*/ + SendConfiguration(0, 0, 0, 0, 0, 0, 0, 0); +} + +void SRGBmodsLEDControllerV1::SendPacket + ( + unsigned char this_packet_id, + unsigned char last_packet_id, + bool reset, + RGBColor* colors, + unsigned int num_colors + ) +{ + unsigned char usb_buf[65]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up Direct Lighting packet | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0x00; /* hidapi Report ID*/ + usb_buf[0x01] = this_packet_id; /* This Packet ID */ + usb_buf[0x02] = last_packet_id; /* Last Packet ID */ + usb_buf[0x03] = reset; /* Reset Flag */ + usb_buf[0x04] = 0xAA; /* Color update */ + + for(unsigned int color_idx = 0; color_idx < num_colors; color_idx++) + { + usb_buf[0x05 + (color_idx * 3)] = RGBGetRValue(colors[color_idx]); + usb_buf[0x06 + (color_idx * 3)] = RGBGetGValue(colors[color_idx]); + usb_buf[0x07 + (color_idx * 3)] = RGBGetBValue(colors[color_idx]); + } + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_write(dev, usb_buf, 65); +} + +void SRGBmodsLEDControllerV1::SendConfiguration + ( + bool reset, + unsigned char hw_effect_enable, + unsigned char hw_effect_mode, + unsigned char hw_effect_speed, + unsigned char hw_effect_brightness, + RGBColor hw_effect_color, + unsigned char status_led_enable, + unsigned char color_compression_enable + ) +{ + unsigned char usb_buf[65]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up Hardware Configuration packet | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0x00; /* hidapi Report ID*/ + usb_buf[0x01] = 0x00; /* This Packet ID */ + usb_buf[0x02] = 0x00; /* Last Packet ID */ + usb_buf[0x03] = reset; /* Reset Flag */ + usb_buf[0x04] = 0xBB; /* Config update */ + + usb_buf[0x05] = hw_effect_enable; /* HWL_enable */ + usb_buf[0x08] = hw_effect_mode; /* HWL_effectMode */ + usb_buf[0x09] = hw_effect_speed; /* HWL_effectSpeed */ + usb_buf[0x0A] = hw_effect_brightness; + usb_buf[0x0B] = RGBGetRValue(hw_effect_color); + usb_buf[0x0C] = RGBGetGValue(hw_effect_color); + usb_buf[0x0D] = RGBGetBValue(hw_effect_color); + usb_buf[0x0E] = status_led_enable; + usb_buf[0x0F] = color_compression_enable; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_write(dev, usb_buf, 65); + + /*-----------------------------------------------------*\ + | Delay 200ms | + \*-----------------------------------------------------*/ + std::this_thread::sleep_for(200ms); +} diff --git a/Controllers/SRGBmodsController/SRGBmodsLEDControllerV1.h b/Controllers/SRGBmodsController/SRGBmodsLEDControllerV1.h new file mode 100644 index 00000000..73276a63 --- /dev/null +++ b/Controllers/SRGBmodsController/SRGBmodsLEDControllerV1.h @@ -0,0 +1,63 @@ +/*-----------------------------------------*\ +| SRGBmodsLEDControllerV1.h | +| | +| Definitions and types for SRGBmods | +| LED Controller V1 | +| | +| Adam Honse (CalcProgrammer1) 6/30/2023 | +\*-----------------------------------------*/ + +#include "RGBController.h" +#include +#include +#include + +#pragma once + +enum +{ + SRGBMODS_LED_CONTROLLER_V1_MODE_RAINBOW = 0x01, /* Rainbow wave mode */ + SRGBMODS_LED_CONTROLLER_V1_MODE_BREATHING_RANDOM = 0x02, /* Breathing random mode */ + SRGBMODS_LED_CONTROLLER_V1_MODE_STATIC = 0x03, /* Static mode */ + SRGBMODS_LED_CONTROLLER_V1_MODE_BREATHING_MODE_SPECIFIC = 0x04, /* Breathing mode specific mode */ + SRGBMODS_LED_CONTROLLER_V1_MODE_DIRECT = 0xFF, /* Direct (SW) mode */ +}; + +class SRGBmodsLEDControllerV1 +{ +public: + SRGBmodsLEDControllerV1(hid_device* dev_handle, const char* path); + ~SRGBmodsLEDControllerV1(); + + std::string GetLocationString(); + std::string GetSerialString(); + + void SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors); + void SetConfiguration(unsigned char mode, unsigned char speed, unsigned char brightness, RGBColor color); + void SetDirect(); + +private: + hid_device* dev; + std::string location; + + void SendPacket + ( + unsigned char this_packet_id, + unsigned char last_packet_id, + bool reset, + RGBColor* colors, + unsigned int num_colors + ); + + void SendConfiguration + ( + bool reset, + unsigned char hw_effect_enable, + unsigned char hw_effect_mode, + unsigned char hw_effect_speed, + unsigned char hw_effect_brightness, + RGBColor hw_effect_color, + unsigned char status_led_enable, + unsigned char color_compression_enable + ); +}; diff --git a/Controllers/SRGBmodsController/SRGBmodsPicoController.cpp b/Controllers/SRGBmodsController/SRGBmodsPicoController.cpp index ec013ec5..d95f1715 100644 --- a/Controllers/SRGBmodsController/SRGBmodsPicoController.cpp +++ b/Controllers/SRGBmodsController/SRGBmodsPicoController.cpp @@ -1,5 +1,5 @@ /*-----------------------------------------*\ -| ZalmanZSyncController.cpp | +| SRGBmodsPicoController.cpp | | | | Driver for SRGBmods Raspberry Pi Pico | | LED Controller | diff --git a/Controllers/SRGBmodsController/SRGBmodsPicoController.h b/Controllers/SRGBmodsController/SRGBmodsPicoController.h index 62134292..381031aa 100644 --- a/Controllers/SRGBmodsController/SRGBmodsPicoController.h +++ b/Controllers/SRGBmodsController/SRGBmodsPicoController.h @@ -1,5 +1,5 @@ /*-----------------------------------------*\ -| ZalmanZSyncController.h | +| SRGBmodsPicoController.h | | | | Definitions and types for SRGBmods | | Raspberry Pi Pico LED Controller | @@ -32,7 +32,7 @@ private: std::thread* keepalive_thread; std::atomic keepalive_thread_run; std::chrono::time_point last_commit_time; - + void SendPacket ( unsigned char channel, @@ -42,4 +42,4 @@ private: RGBColor* colors, unsigned int num_colors ); -}; \ No newline at end of file +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index 5f0b17f7..06f9d38b 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -670,6 +670,8 @@ HEADERS += Controllers/SonyGamepadController/RGBController_SonyDualSense.h \ Controllers/SonyGamepadController/SonyDS4Controller.h \ Controllers/SonyGamepadController/RGBController_SonyDS4.h \ + Controllers/SRGBmodsController/SRGBmodsLEDControllerV1.h \ + Controllers/SRGBmodsController/RGBController_SRGBmodsLEDControllerV1.h \ Controllers/SRGBmodsController/SRGBmodsPicoController.h \ Controllers/SRGBmodsController/RGBController_SRGBmodsPico.h \ Controllers/SteelSeriesController/color32.h \ @@ -1354,8 +1356,10 @@ SOURCES += Controllers/SonyGamepadController/SonyDS4Controller.cpp \ Controllers/SonyGamepadController/RGBController_SonyDS4.cpp \ Controllers/SonyGamepadController/SonyGamepadControllerDetect.cpp \ + Controllers/SRGBmodsController/SRGBmodsLEDControllerV1.cpp \ Controllers/SRGBmodsController/SRGBmodsPicoController.cpp \ Controllers/SRGBmodsController/SRGBmodsControllerDetect.cpp \ + Controllers/SRGBmodsController/RGBController_SRGBmodsLEDControllerV1.cpp \ Controllers/SRGBmodsController/RGBController_SRGBmodsPico.cpp \ Controllers/SteelSeriesController/SteelSeriesAerox3Controller.cpp \ Controllers/SteelSeriesController/SteelSeriesAerox9Controller.cpp \