From e55b9a18979fdccc905486512773190c1502b359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AF=BA=E8=AF=BA?= <2777618756@qq.com> Date: Tue, 27 Jun 2023 16:19:42 +0000 Subject: [PATCH] Add Nollie32 Lamp strip controller --- .../NollieController/NollieController.cpp | 84 +++++++++ .../NollieController/NollieController.h | 28 +++ .../NollieControllerDetect.cpp | 37 ++++ .../NollieController/RGBController_Nollie.cpp | 178 ++++++++++++++++++ .../NollieController/RGBController_Nollie.h | 38 ++++ OpenRGB.pro | 6 + 6 files changed, 371 insertions(+) create mode 100644 Controllers/NollieController/NollieController.cpp create mode 100644 Controllers/NollieController/NollieController.h create mode 100644 Controllers/NollieController/NollieControllerDetect.cpp create mode 100644 Controllers/NollieController/RGBController_Nollie.cpp create mode 100644 Controllers/NollieController/RGBController_Nollie.h diff --git a/Controllers/NollieController/NollieController.cpp b/Controllers/NollieController/NollieController.cpp new file mode 100644 index 00000000..be911af0 --- /dev/null +++ b/Controllers/NollieController/NollieController.cpp @@ -0,0 +1,84 @@ +/*-----------------------------------------*\ +| NollieController.cpp | +| | +| Driver for Nollie32 LED strip controller | +| | +| Name (cnn1236661) 25th Jun 2023 | +\*-----------------------------------------*/ + +#include "NollieController.h" +#include + +using namespace std::chrono_literals; + +NollieController::NollieController(hid_device* dev_handle, const char* path, unsigned short pid) +{ + dev = dev_handle; + location = path; + /*-----------------------------------------------------*\ + | PID may be used in the future, here is to pass | + | arguments not to do storage | + \*-----------------------------------------------------*/ +} + +std::string NollieController::GetLocationString() +{ + return("HID: " + location); +} + +std::string NollieController::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 NollieController::SetMos(bool mos) +{ + unsigned char usb_buf[65]; + memset(usb_buf, 0x00, sizeof(usb_buf)); + usb_buf[0x01] = 0x80; + usb_buf[0x02] = mos; + hid_write(dev, usb_buf, 65); +} + +void NollieController::SetChannelLEDs(unsigned char channel, RGBColor* colors, unsigned int num_colors) +{ + SendPacket(channel,&colors[0], num_colors); +} + +void NollieController::SendPacket(unsigned char channel,RGBColor* colors,unsigned int num_colors) +{ + + unsigned char usb_buf[1025]; + memset(usb_buf, 0x00, sizeof(usb_buf)); + usb_buf[1] = channel; + usb_buf[2] = 0; + usb_buf[3] = num_colors / 256; + usb_buf[4] = num_colors % 256; + if(!num_colors) + { + hid_write(dev, usb_buf, 1025); + return; + } + for(unsigned int color_idx = 0; color_idx < num_colors; color_idx++) + { + usb_buf[0x05 + (color_idx * 3)] = RGBGetGValue(colors[color_idx]); + usb_buf[0x06 + (color_idx * 3)] = RGBGetRValue(colors[color_idx]); + usb_buf[0x07 + (color_idx * 3)] = RGBGetBValue(colors[color_idx]); + } + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_write(dev, usb_buf, 1025); +} + diff --git a/Controllers/NollieController/NollieController.h b/Controllers/NollieController/NollieController.h new file mode 100644 index 00000000..e46c159b --- /dev/null +++ b/Controllers/NollieController/NollieController.h @@ -0,0 +1,28 @@ +/*-----------------------------------------*\ +| RGBController.h | +| | +| Driver for Nollie32 LED strip controller | +| | +| Name (cnn1236661) 25th Jun 2023 | +\*-----------------------------------------*/ + +#include "RGBController.h" +#include +#include +#include + +#pragma once + +class NollieController +{ +public: + NollieController(hid_device* dev_handle, const char* path, unsigned short pid); + std::string GetLocationString(); + std::string GetSerialString(); + void SetMos(bool mos); + void SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors); +private: + hid_device* dev; + std::string location; + void SendPacket(unsigned char channel,RGBColor * colors,unsigned int num_colors); +}; diff --git a/Controllers/NollieController/NollieControllerDetect.cpp b/Controllers/NollieController/NollieControllerDetect.cpp new file mode 100644 index 00000000..bc563759 --- /dev/null +++ b/Controllers/NollieController/NollieControllerDetect.cpp @@ -0,0 +1,37 @@ +/*-----------------------------------------*\ +| NollieControllerDetect.cpp | +| | +| Driver for Nollie32 LED strip controller | +| | +| Name (cnn1236661) 25th Jun 2023 | +\*-----------------------------------------*/ + +#include "Detector.h" +#include "NollieController.h" +#include "RGBController.h" +#include "RGBController_Nollie.h" +#include +#include + + +void DetectNollieControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + wchar_t product[128]; + hid_get_product_string(dev, product, 128); + + std::wstring product_str(product); + + NollieController* controller = new NollieController(dev, info->path,info->product_id); + RGBController_Nollie* rgb_controller = new RGBController_Nollie(controller); + rgb_controller->name = name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + + } +} + +REGISTER_HID_DETECTOR("Nollie 32CH", DetectNollieControllers, NOLLIE_32_VID, NOLLIE_32_PID); diff --git a/Controllers/NollieController/RGBController_Nollie.cpp b/Controllers/NollieController/RGBController_Nollie.cpp new file mode 100644 index 00000000..7d0f1ea6 --- /dev/null +++ b/Controllers/NollieController/RGBController_Nollie.cpp @@ -0,0 +1,178 @@ +/**------------------------------------------------------------------*\ + @name Nollie Controller + @category LEDStrip + @type USB + @save :x: + @direct :white_check_mark: + @effects :x: + @detectors DetectNollieControllers + @comment +\*-------------------------------------------------------------------*/ + +#include "RGBController_Nollie.h" +#include +#include + +int channel_index[32] = {5, 4, 3, 2, 1, 0, 15, 14, 26, 27, 28, 29, 30, 31, 8, 9, 19, 18, 17, 16, 7, 6, 25, 24, 23, 22, 21, 20, 13, 12, 11, 10}; + +RGBController_Nollie::RGBController_Nollie(NollieController* controller_ptr) +{ + controller = controller_ptr; + + name = "Nollie Device"; + vendor = "Nollie"; + description = "Nollie Controller Device"; + type = DEVICE_TYPE_LEDSTRIP; + location = controller->GetLocationString(); + serial = controller->GetSerialString(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = 0xFFFF; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + SetupZones(); +} + +RGBController_Nollie::~RGBController_Nollie() +{ + delete controller; +} + +void RGBController_Nollie::SetupZones() +{ + bool first_run = false; + if(zones.size() == 0) + { + first_run = true; + } + leds.clear(); + colors.clear(); + zones.resize(NOLLIE_CHANNELS_NUM); + for(unsigned int channel_idx = 0; channel_idx < NOLLIE_CHANNELS_NUM; channel_idx++) + { + if(channel_idx > 27 ) + { + char ch_idx_string[4]; + snprintf(ch_idx_string, 4, "%d", channel_idx + 1 - 28); + zones[channel_idx].name = "Channel EXT "; + zones[channel_idx].name.append(ch_idx_string); + } + else if(channel_idx > 21 ) + { + char ch_idx_string[4]; + snprintf(ch_idx_string, 4, "%d", channel_idx + 1 - 22); + zones[channel_idx].name = "Channel GPU "; + zones[channel_idx].name.append(ch_idx_string); + } + else if(channel_idx > 15 ) + { + char ch_idx_string[4]; + snprintf(ch_idx_string, 4, "%d", channel_idx + 1 - 16); + zones[channel_idx].name = "Channel ATX "; + zones[channel_idx].name.append(ch_idx_string); + } + else + { + char ch_idx_string[4]; + snprintf(ch_idx_string, 4, "%d", channel_idx + 1); + zones[channel_idx].name = "Channel "; + zones[channel_idx].name.append(ch_idx_string); + } + zones[channel_idx].type = ZONE_TYPE_LINEAR; + zones[channel_idx].leds_min = 0; + zones[channel_idx].leds_max = NOLLIE_CHANNELS_LED_NUM; + + 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_Nollie::ResizeZone(int zone, int new_size) +{ + /*-----------------------------------------------------*\ + | Set whether MOS is enabled or not | + \*-----------------------------------------------------*/ + if(zone == 26 && new_size >20) + { + controller->SetMos(false); + } + else if(zone == 26) + { + controller->SetMos(true); + } + + 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_Nollie::DeviceUpdateLEDs() +{ + std::vector ChSort; + for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + unsigned int channel = channel_index[zone_idx]; + if(zones[zone_idx].leds_count > 0) + { + ChSort.push_back(channel); + } + else if(channel == 15 || channel == 31) + { + ChSort.push_back(channel); + } + } + std::sort(ChSort.begin(), ChSort.end()); + for (int i = 0; i < ChSort.size(); i++) + { + int* ptr = std::find(channel_index, channel_index + 32, ChSort[i]); + int zone_idx = ptr - channel_index; + controller->SetChannelLEDs(ChSort[i], zones[zone_idx].colors, zones[zone_idx].leds_count); + } +} + +void RGBController_Nollie::UpdateZoneLEDs(int zone) +{ + controller->SetChannelLEDs(channel_index[zone], zones[zone].colors, zones[zone].leds_count); +} + +void RGBController_Nollie::UpdateSingleLED(int led) +{ + unsigned int channel = leds_channel[led]; + + controller->SetChannelLEDs(channel_index[channel], zones[channel].colors, zones[channel].leds_count); +} + +void RGBController_Nollie::DeviceUpdateMode() +{ + DeviceUpdateLEDs(); +} diff --git a/Controllers/NollieController/RGBController_Nollie.h b/Controllers/NollieController/RGBController_Nollie.h new file mode 100644 index 00000000..d2f30387 --- /dev/null +++ b/Controllers/NollieController/RGBController_Nollie.h @@ -0,0 +1,38 @@ +/*-----------------------------------------*\ +| RGBController_Nollie.h | +| | +| Driver for Nollie32 LED strip controller | +| | +| Name (cnn1236661) 25th Jun 2023 | +\*-----------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "NollieController.h" + +#define NOLLIE_CHANNELS_LED_NUM 256 +#define NOLLIE_CHANNELS_NUM 32 +#define NOLLIE_32_PID 0x4714 +#define NOLLIE_32_VID 0x3061 + +class RGBController_Nollie : public RGBController +{ +public: + RGBController_Nollie(NollieController* controller_ptr); + ~RGBController_Nollie(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: + NollieController* controller; + std::vector leds_channel; + std::vector zones_channel; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index b291e2d6..1e68931f 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -159,6 +159,7 @@ INCLUDEPATH += Controllers/MSIRGBController/ \ Controllers/MSIVigorController/ \ Controllers/NanoleafController/ \ + Controllers/NollieController/ \ Controllers/NZXTHue1Controller/ \ Controllers/NZXTHue2Controller/ \ Controllers/NZXTHuePlusController/ \ @@ -590,6 +591,8 @@ HEADERS += Controllers/N5312AController/RGBController_N5312A.h \ Controllers/NvidiaESAController/NvidiaESAController.h \ Controllers/NanoleafController/RGBController_Nanoleaf.h \ + Controllers/NollieController/NollieController.h \ + Controllers/NollieController/RGBController_Nollie.h \ Controllers/NvidiaESAController/RGBController_NvidiaESA.h \ Controllers/NZXTHue1Controller/NZXTHue1Controller.h \ Controllers/NZXTHue1Controller/RGBController_NZXTHue1.h \ @@ -1249,6 +1252,9 @@ SOURCES += Controllers/N5312AController/N5312AController.cpp \ Controllers/N5312AController/N5312AControllerDetect.cpp \ Controllers/N5312AController/RGBController_N5312A.cpp \ + Controllers/NollieController/NollieController.cpp \ + Controllers/NollieController/NollieControllerDetect.cpp \ + Controllers/NollieController/RGBController_Nollie.cpp \ Controllers/NvidiaESAController/NvidiaESAController.cpp \ Controllers/NvidiaESAController/NvidiaESAControllerDetect.cpp \ Controllers/NvidiaESAController/RGBController_NvidiaESA.cpp \