From 694ad92bebf5df16e5a451400ec3e3e389e6f8f6 Mon Sep 17 00:00:00 2001 From: Zachary Guinn Date: Mon, 7 Feb 2022 09:07:54 -0600 Subject: [PATCH] Initial commit for Airgoo Lustrous Commander controller (!1080) Cleaned up, squashed, and rebased by Adam Honse --- .../AirgooLustrousCommanderController.cpp | 143 ++++++++++++ .../AirgooLustrousCommanderController.h | 49 +++++ ...irgooLustrousCommanderControllerDetect.cpp | 41 ++++ .../RGBController_AirgooLustrousCommander.cpp | 208 ++++++++++++++++++ .../RGBController_AirgooLustrousCommander.h | 35 +++ 5 files changed, 476 insertions(+) create mode 100644 Controllers/AirgooLustrousCommanderController/AirgooLustrousCommanderController.cpp create mode 100644 Controllers/AirgooLustrousCommanderController/AirgooLustrousCommanderController.h create mode 100644 Controllers/AirgooLustrousCommanderController/AirgooLustrousCommanderControllerDetect.cpp create mode 100644 Controllers/AirgooLustrousCommanderController/RGBController_AirgooLustrousCommander.cpp create mode 100644 Controllers/AirgooLustrousCommanderController/RGBController_AirgooLustrousCommander.h diff --git a/Controllers/AirgooLustrousCommanderController/AirgooLustrousCommanderController.cpp b/Controllers/AirgooLustrousCommanderController/AirgooLustrousCommanderController.cpp new file mode 100644 index 000000000..2367e6e66 --- /dev/null +++ b/Controllers/AirgooLustrousCommanderController/AirgooLustrousCommanderController.cpp @@ -0,0 +1,143 @@ +/*---------------------------------------------------------*\ +| AirgooLustrousCommanderController.cpp | +| | +| Processing Code for Airgoo Lustrous Commander | +| Based on code by: | +| Jeff P (@jeffp1), 2020/02/07 | +| | +| Zacahry G. | +\*---------------------------------------------------------*/ + +#include "AirgooLustrousCommanderController.h" + +#include +#include +#include + +using namespace std::chrono_literals; + +AirgooLustrousCommanderController::AirgooLustrousCommanderController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; + controller_ready = 0; + + /*-----------------------------------------------------*\ + | Initialize controller | + \*-----------------------------------------------------*/ + InitController(); + + +} + +AirgooLustrousCommanderController::~AirgooLustrousCommanderController() +{ + /*-----------------------------------------------------*\ + | Close HID device | + \*-----------------------------------------------------*/ + hid_close(dev); +} + +void AirgooLustrousCommanderController::InitController() +{ + unsigned char usb_buf[AIRGOO_LUSTROUS_COMMANDER_PACKET_SIZE]; + + /*-----------------------------------------------------*\ + | Initialize Controller | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + usb_buf[0x00] = 0x00; + usb_buf[0x01] = 0x03; + usb_buf[0x02] = 0x55; + usb_buf[0x03] = 0xAA; + + hid_write(dev, usb_buf, AIRGOO_LUSTROUS_COMMANDER_PACKET_SIZE); + + //expecting the device to return AA 55 01 + hid_read(dev, usb_buf, AIRGOO_LUSTROUS_COMMANDER_PACKET_SIZE); + + usb_buf[0x00] = 0x00; + usb_buf[0x01] = 0x03; + usb_buf[0x02] = 0x55; + usb_buf[0x03] = 0xAA; + usb_buf[0x04] = 0x01; + + //looks like the client software awknolleges? it returns a 0x01 in pos 4 of the buffer array + hid_write(dev, usb_buf, AIRGOO_LUSTROUS_COMMANDER_PACKET_SIZE); + + //device will send aa 55 00 back and it seems that we should be ready to send commands at this point + + controller_ready = 1; + +} + +std::string AirgooLustrousCommanderController::GetLocationString() +{ + return("HID: " + location); +} + +void AirgooLustrousCommanderController::SetMode(unsigned char mode) +{ + active_mode = mode; +} + + +void AirgooLustrousCommanderController::UpdateDevice( + unsigned char mode, + unsigned char red, + unsigned char grn, + unsigned char blu, + unsigned char speed) +{ + unsigned char usb_buf[65]; + + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up message packet with leading 00 | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0x00; + + switch(mode) + { + case 0: //off + usb_buf[0x01] = 0x09; //number of bytes in package + usb_buf[0x02] = 0xFF; + usb_buf[0x03] = 0x00; + usb_buf[0x04] = 0xF0; + usb_buf[0x05] = 0x00; //Red + usb_buf[0x06] = 0x00; //Green + usb_buf[0x07] = 0x00; //Blue + usb_buf[0x08] = 0x05; + usb_buf[0x09] = 0x05; + usb_buf[0x0A] = 0xFE; + break; + case 1: //static + usb_buf[0x01] = 0x09; //number of bytes in package + usb_buf[0x02] = 0xFF; + usb_buf[0x03] = 0x00; + usb_buf[0x04] = 0xF0; + usb_buf[0x05] = red; //Red + usb_buf[0x06] = grn; //Green + usb_buf[0x07] = blu; //Blue + usb_buf[0x08] = 0x05; + usb_buf[0x09] = 0x05; + usb_buf[0x0A] = 0xFE; + break; + case 2://rainbow + usb_buf[0x01] = 0x05; //number of bytes in package + usb_buf[0x02] = 0xFF; + usb_buf[0x03] = 0x06; + usb_buf[0x04] = 0x01; //type like wheel or rolling + usb_buf[0x05] = speed; //speed + usb_buf[0x06] = 0xFE; + } + + hid_write(dev, usb_buf, AIRGOO_LUSTROUS_COMMANDER_PACKET_SIZE); +} + +void AirgooLustrousCommanderController::SetFanMode() +{ + +} diff --git a/Controllers/AirgooLustrousCommanderController/AirgooLustrousCommanderController.h b/Controllers/AirgooLustrousCommanderController/AirgooLustrousCommanderController.h new file mode 100644 index 000000000..3e3c7acb2 --- /dev/null +++ b/Controllers/AirgooLustrousCommanderController/AirgooLustrousCommanderController.h @@ -0,0 +1,49 @@ +/*---------------------------------------------------------*\ +| AirgooLustrousCommanderController.h | +| | +| Definitions for Airgoo Lustrous Commander | +| Based on code by: | +| Jeff P (@jeffp1), 2020/02/07 | +| | +| Zachary G | +\*---------------------------------------------------------*/ + +#include "RGBController.h" +#include +#include +#include + +#pragma once + +#define AIRGOO_LUSTROUS_COMMANDER_PACKET_SIZE 65 +#define AIRGOO_LUSTROUS_COMMANDER_NUM_RGB_CHANNELS 2 +#define AIRGOO_LUSTROUS_COMMANDER_NUM_FAN_CHANNELS 4 + +class AirgooLustrousCommanderController +{ +public: + AirgooLustrousCommanderController(hid_device* dev_handle, const char* path); + ~AirgooLustrousCommanderController(); + + std::string GetLocationString(); + + void SetFanMode(); + void SetMode(unsigned char mode); + void UpdateDevice + ( + unsigned char mode, + unsigned char red, + unsigned char grn, + unsigned char blu, + unsigned char speed + ); + + +private: + hid_device* dev; + unsigned char active_mode; + std::atomic controller_ready; + std::string location; + + void InitController(); +}; diff --git a/Controllers/AirgooLustrousCommanderController/AirgooLustrousCommanderControllerDetect.cpp b/Controllers/AirgooLustrousCommanderController/AirgooLustrousCommanderControllerDetect.cpp new file mode 100644 index 000000000..6127e4f53 --- /dev/null +++ b/Controllers/AirgooLustrousCommanderController/AirgooLustrousCommanderControllerDetect.cpp @@ -0,0 +1,41 @@ +#include "Detector.h" +#include "AirgooLustrousCommanderController.h" +#include "RGBController.h" +#include "RGBController_AirgooLustrousCommander.h" +#include +#include + +/*-----------------------------------------------------*\ +| Airgoo vendor ID | +\*-----------------------------------------------------*/ +#define AIRGOO_VID 0x1A86 + +/*-----------------------------------------------------*\ +| Lustrous Commander product IDs | +\*-----------------------------------------------------*/ +#define AIRGOO_LUSTROUS_COMMANDER_PID 0xE6E0 + +/******************************************************************************************\ +* * +* DetectAirgooCommanderControllers * +* * +* Tests the USB address to see if a Airgoo RGB controller exists there. * +* * +\******************************************************************************************/ + +void DetectAirgooLustrousCommanderHIDControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + AirgooLustrousCommanderController* controller = new AirgooLustrousCommanderController(dev, info->path); + RGBController_AirgooLustrousCommander* rgb_controller = new RGBController_AirgooLustrousCommander(controller); + + rgb_controller->name = name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_HID_DETECTOR("Airgoo Lustrous Commander", DetectAirgooLustrousCommanderHIDControllers, AIRGOO_VID, AIRGOO_LUSTROUS_COMMANDER_PID); diff --git a/Controllers/AirgooLustrousCommanderController/RGBController_AirgooLustrousCommander.cpp b/Controllers/AirgooLustrousCommanderController/RGBController_AirgooLustrousCommander.cpp new file mode 100644 index 000000000..a9d4f67b4 --- /dev/null +++ b/Controllers/AirgooLustrousCommanderController/RGBController_AirgooLustrousCommander.cpp @@ -0,0 +1,208 @@ +/*-----------------------------------------*\ +| RGBController_AirgooLustrousCommander.cpp| +| | +| Generic RGB Interface for Airgoo | +| Based on code by: | +| Jeff P (@jeffp1), 2020/02/07 | +| | +| Zachary G | +\*-----------------------------------------*/ + +#include "RGBController_AirgooLustrousCommander.h" + +RGBController_AirgooLustrousCommander::RGBController_AirgooLustrousCommander(AirgooLustrousCommanderController* controller_ptr) +{ + controller = controller_ptr; + + vendor = "Aurgoo"; + description = "Lustrous Commander"; + type = DEVICE_TYPE_LEDSTRIP; + location = controller->GetLocationString(); + + SetupZones(); + SetupModes(); +} + +RGBController_AirgooLustrousCommander::~RGBController_AirgooLustrousCommander() +{ + delete controller; +} + +void RGBController_AirgooLustrousCommander::SetupZones() +{ + std::atomic first_run; + first_run = 0; + + if(zones.size() == 0) + { + first_run = 1; + } + + zones.resize(3); + + for(unsigned int i = 1; i < (AIRGOO_LUSTROUS_COMMANDER_NUM_RGB_CHANNELS + 1); i++) + { + zones[i].name = "RGB Port " + std::to_string(i); + zones[i].type = ZONE_TYPE_LINEAR; + zones[i].leds_min = 1; + zones[i].leds_max = 34; + + if(first_run) + { + zones[i].leds_count = 1; + } + } + + leds.clear(); + colors.clear(); + + for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + for (unsigned int led_idx = 0; led_idx < zones[zone_idx].leds_count; led_idx++) + { + led new_led; + new_led.name = zones[zone_idx].name + " LED " + std::to_string(led_idx+1); + + leds.push_back(new_led); + } + } + + SetupColors(); +} + +void RGBController_AirgooLustrousCommander::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_AirgooLustrousCommander::SetupModes() +{ + mode Off; + Off.name = "Off"; + Off.value = 0; + Off.flags = 0; + Off.color_mode = MODE_COLORS_NONE; + modes.push_back(Off); + + mode Static; + Static.name = "Static"; + Static.value = 1; + Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + Static.colors_min = 1; + Static.colors_max = 1; + Static.color_mode = MODE_COLORS_MODE_SPECIFIC; + Static.colors.resize(1); + modes.push_back(Static); + + // mode Shift; + // Shift.name = "Shift"; + // Shift.value = 1; + // Shift.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED; + // Shift.color_mode = MODE_COLORS_MODE_SPECIFIC; + // Shift.colors_min = 1; + // Shift.colors_max = 16; + // Shift.colors.resize(Shift.colors_max); + // Shift.speed_min = 0; + // Shift.speed_max = 255; + // Shift.speed = 05; + // Shift.brightness_min = 100; + // Shift.brightness_max = 0; + // Shift.brightness = 0; + // modes.push_back(Shift); + + // mode Pulse; + // Pulse.name = "Pulse"; + // Pulse.value = 2; + // Pulse.flags = MODE_FLAG_HAS_PER_LED_COLOR; + // Pulse.color_mode = MODE_COLORS_MODE_SPECIFIC; + // modes.push_back(Pulse); + + // mode Gradual; + // Gradual.name = "Gradual"; + // Gradual.value = 3; + // Gradual.flags = MODE_FLAstd::cout << "@@@@@@@Init Contoller@@@@@@@" << std::endl;ORS_MODE_SPECIFIC; + // modes.push_back(Gradual); + + // mode StarLight; + // StarLight.name = "StarLight"; + // StarLight.value = 4; + // StarLight.flags = MODE_FLAG_HAS_PER_LED_COLOR; + // StarLight.color_mode = MODE_COLORS_MODE_SPECIFIC; + // modes.push_back(StarLight); + + mode Rainbow; + Rainbow.name = "Rainbow"; + Rainbow.value = 2; + Rainbow.flags = MODE_FLAG_HAS_SPEED; + Rainbow.speed_min = 1; + Rainbow.speed_max = 255; + Rainbow.speed = 50; + Rainbow.color_mode = MODE_COLORS_NONE; + modes.push_back(Rainbow); + + // mode ColorWave; + // ColorWave.name = "Color Wave"; + // ColorWave.value = 6; + // ColorWave.flags = MODE_FLAG_HAS_PER_LED_COLOR; + // ColorWave.color_mode = MODE_COLORS_MODE_SPECIFIC; + // modes.push_back(ColorWave); + + // mode ColorPulse; + // ColorPulse.name = "Color Pulse"; + // ColorPulse.value = 7; + // ColorPulse.flags = MODE_FLAG_HAS_PER_LED_COLOR; + // ColorPulse.color_mode = MODE_COLORS_MODE_SPECIFIC; + // modes.push_back(ColorPulse); + + // mode ColorMeteor; + // ColorMeteor.name = "Color Meteor"; + // ColorMeteor.value = 8; + // ColorMeteor.flags = MODE_FLAG_HAS_PER_LED_COLOR; + // ColorMeteor.color_mode = MODE_COLORS_MODE_SPECIFIC; + // modes.push_back(ColorMeteor); + +} + +void RGBController_AirgooLustrousCommander::DeviceUpdateLEDs() +{ + DeviceUpdateMode(); +} + +void RGBController_AirgooLustrousCommander::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_AirgooLustrousCommander::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_AirgooLustrousCommander::SetCustomMode() +{ + active_mode = 0; +} + +void RGBController_AirgooLustrousCommander::DeviceUpdateMode() +{ + unsigned char red = 0; + unsigned char grn = 0; + unsigned char blu = 0; + if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) + { + red = RGBGetRValue(modes[active_mode].colors[0]); + grn = RGBGetGValue(modes[active_mode].colors[0]); + blu = RGBGetBValue(modes[active_mode].colors[0]); + } + controller->UpdateDevice(modes[active_mode].value, red, grn, blu, modes[active_mode].speed); +} \ No newline at end of file diff --git a/Controllers/AirgooLustrousCommanderController/RGBController_AirgooLustrousCommander.h b/Controllers/AirgooLustrousCommanderController/RGBController_AirgooLustrousCommander.h new file mode 100644 index 000000000..c3e2e2bcf --- /dev/null +++ b/Controllers/AirgooLustrousCommanderController/RGBController_AirgooLustrousCommander.h @@ -0,0 +1,35 @@ +/*-----------------------------------------*\ +| RGBController_AirgooLustrousCommander.h | +| | +| Generic RGB Interface for Airgoo | +| Lustrous Commander | +| Based on code by: | +| Jeff P (@jeffp1), 2020/02/07 | +| | +| Zachary G | +\*-----------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "AirgooLustrousCommanderController.h" + +class RGBController_AirgooLustrousCommander : public RGBController +{ +public: + RGBController_AirgooLustrousCommander(AirgooLustrousCommanderController* controller_ptr); + ~RGBController_AirgooLustrousCommander(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + void DeviceUpdateLEDs(); + void SetupModes(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void SetCustomMode(); + void DeviceUpdateMode(); + +private: + AirgooLustrousCommanderController* controller; + std::vector fanleds{0}; +};