From 6fd6c7f17628ee3b478841114efb772d1f4e6116 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Tue, 18 Feb 2020 18:50:09 -0600 Subject: [PATCH] Initial support for addressable headers on Asus Aura motherboards. --- .../AuraAddressableController.cpp | 202 +++++++++++++++++ .../AuraAddressableController.h | 84 +++++++ .../AuraAddressableControllerDetect.cpp | 45 ++++ OpenRGB.cpp | 2 + OpenRGB.pro | 6 + .../RGBController_AuraAddressable.cpp | 214 ++++++++++++++++++ RGBController/RGBController_AuraAddressable.h | 38 ++++ 7 files changed, 591 insertions(+) create mode 100644 Controllers/AuraAddressableController/AuraAddressableController.cpp create mode 100644 Controllers/AuraAddressableController/AuraAddressableController.h create mode 100644 Controllers/AuraAddressableController/AuraAddressableControllerDetect.cpp create mode 100644 RGBController/RGBController_AuraAddressable.cpp create mode 100644 RGBController/RGBController_AuraAddressable.h diff --git a/Controllers/AuraAddressableController/AuraAddressableController.cpp b/Controllers/AuraAddressableController/AuraAddressableController.cpp new file mode 100644 index 00000000..317e39f9 --- /dev/null +++ b/Controllers/AuraAddressableController/AuraAddressableController.cpp @@ -0,0 +1,202 @@ +/*-----------------------------------------*\ +| AuraAddressableController.cpp | +| | +| Driver for ASUS Aura RGB Addressable | +| lighting controller | +| | +| Adam Honse (CalcProgrammer1) 1/18/2020 | +\*-----------------------------------------*/ + +#include "AuraAddressableController.h" +#include + +#ifdef WIN32 +#include +#else +#include + +static void Sleep(unsigned int milliseconds) +{ + usleep(1000 * milliseconds); +} +#endif + +AuraAddressableController::AuraAddressableController(hid_device* dev_handle) +{ + dev = dev_handle; + + channel_leds[0] = 40; +} + +AuraAddressableController::~AuraAddressableController() +{ + +} + +void AuraAddressableController::SetLEDsDirect(std::vector colors) +{ + unsigned char led_data[60]; + unsigned int leds_sent = 0; + + SendDirectBegin(); + + while(leds_sent < colors.size()) + { + unsigned int leds_to_send = 20; + + if((colors.size() - leds_sent) < leds_to_send) + { + leds_to_send = colors.size() - leds_sent; + } + + for(int led_idx = 0; leds_to_send < 20; led_idx++) + { + led_data[(led_idx * 3) + 0] = RGBGetRValue(colors[led_idx]); + led_data[(led_idx * 3) + 1] = RGBGetGValue(colors[led_idx]); + led_data[(led_idx * 3) + 2] = RGBGetBValue(colors[led_idx]); + } + + SendDirect + ( + 0, + leds_sent, + leds_to_send, + led_data + ); + } + + SendDirectApply(); +} + +void AuraAddressableController::SetMode + ( + unsigned char mode, + unsigned char red, + unsigned char grn, + unsigned char blu + ) +{ + SendEffect + ( + mode, + red, + grn, + blu + ); +} + +void AuraAddressableController::SendEffect + ( + unsigned char mode, + unsigned char red, + unsigned char grn, + unsigned char blu + ) +{ + unsigned char usb_buf[65]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up message packet | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0xEC; + usb_buf[0x01] = AURA_CONTROL_MODE_EFFECT; + usb_buf[0x02] = 0x00; + usb_buf[0x03] = 0x00; + usb_buf[0x04] = mode; + + /*-----------------------------------------------------*\ + | Copy in color data bytes | + \*-----------------------------------------------------*/ + usb_buf[0x05] = red; + usb_buf[0x06] = grn; + usb_buf[0x07] = blu; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, usb_buf, 64); +} + +void AuraAddressableController::SendDirect + ( + unsigned char device, + unsigned char start_led, + unsigned char led_count, + unsigned char* led_data + ) +{ + unsigned char usb_buf[65]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up message packet | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0xEC; + usb_buf[0x01] = AURA_CONTROL_MODE_DIRECT; + usb_buf[0x02] = device; + usb_buf[0x03] = start_led; + usb_buf[0x04] = led_count; + + /*-----------------------------------------------------*\ + | Copy in color data bytes | + \*-----------------------------------------------------*/ + memcpy(&usb_buf[0x05], led_data, led_count * 3); + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, usb_buf, 64); +} + +void AuraAddressableController::SendDirectBegin() +{ + unsigned char usb_buf[65]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up message packet | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0xEC; + usb_buf[0x01] = AURA_CONTROL_MODE_EFFECT; + usb_buf[0x04] = 0xFF; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, usb_buf, 64); +} + +void AuraAddressableController::SendDirectApply() +{ + unsigned char usb_buf[65]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up message packet | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0xEC; + usb_buf[0x01] = AURA_CONTROL_MODE_DIRECT; + usb_buf[0x02] = 0x80; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, usb_buf, 64); +} diff --git a/Controllers/AuraAddressableController/AuraAddressableController.h b/Controllers/AuraAddressableController/AuraAddressableController.h new file mode 100644 index 00000000..86c9ec42 --- /dev/null +++ b/Controllers/AuraAddressableController/AuraAddressableController.h @@ -0,0 +1,84 @@ +/*-----------------------------------------*\ +| AuraAddressableController.h | +| | +| Definitions and types for ASUS Aura | +| Addressable RGB lighting controller | +| | +| Adam Honse (CalcProgrammer1) 1/18/2020 | +\*-----------------------------------------*/ + +#include "RGBController.h" + +#include +#include + +#pragma once + +enum +{ + AURA_MODE_OFF = 0, /* OFF mode */ + AURA_MODE_STATIC = 1, /* Static color mode */ + AURA_MODE_BREATHING = 2, /* Breathing effect mode */ + AURA_MODE_FLASHING = 3, /* Flashing effect mode */ + AURA_MODE_SPECTRUM_CYCLE = 4, /* Spectrum Cycle mode */ + AURA_MODE_RAINBOW = 5, /* Rainbow effect mode */ + AURA_MODE_SPECTRUM_CYCLE_BREATHING = 6, /* Rainbow Breathing effect mode */ + AURA_MODE_CHASE_FADE = 7, /* Chase with Fade effect mode */ + AURA_MODE_SPECTRUM_CYCLE_CHASE_FADE = 8, /* Chase with Fade, Rainbow effect mode */ + AURA_MODE_CHASE = 9, /* Chase effect mode */ + AURA_MODE_SPECTRUM_CYCLE_CHASE = 10, /* Chase with Rainbow effect mode */ + AURA_MODE_SPECTRUM_CYCLE_WAVE = 11, /* Wave effect mode */ + AURA_MODE_CHASE_RAINBOW_PULSE = 12, /* Chase with Rainbow Pulse effect mode*/ + AURA_MODE_RANDOM_FLICKER = 13, /* Random flicker effect mode */ + AURA_MODE_MUSIC = 14, /* Music effect mode */ +}; + +enum +{ + AURA_CONTROL_MODE_EFFECT = 0x3B, /* Effect control mode */ + AURA_CONTROL_MODE_DIRECT = 0x40, /* Direct control mode */ +}; + +class AuraAddressableController +{ +public: + AuraAddressableController(hid_device* dev_handle); + ~AuraAddressableController(); + + void SetLEDsDirect(std::vector colors); + + void SetMode + ( + unsigned char mode, + unsigned char red, + unsigned char grn, + unsigned char blu + ); + + unsigned int channel_leds[1]; + +private: + char device_name[32]; + hid_device* dev; + unsigned int led_count; + + void SendEffect + ( + unsigned char mode, + unsigned char red, + unsigned char grn, + unsigned char blu + ); + + void SendDirect + ( + unsigned char device, + unsigned char start_led, + unsigned char led_count, + unsigned char* led_data + ); + + void SendDirectBegin(); + + void SendDirectApply(); +}; diff --git a/Controllers/AuraAddressableController/AuraAddressableControllerDetect.cpp b/Controllers/AuraAddressableController/AuraAddressableControllerDetect.cpp new file mode 100644 index 00000000..b224a794 --- /dev/null +++ b/Controllers/AuraAddressableController/AuraAddressableControllerDetect.cpp @@ -0,0 +1,45 @@ +#include "AuraAddressableController.h" +#include "RGBController.h" +#include "RGBController_AuraAddressable.h" +#include +#include + +#define AURA_ADDRESSABLE_VID 0x0B05 + +#define NUM_PIDS 2 +static const unsigned short pid_table[] = + { + 0x1867, + 0x1872 + }; + +/******************************************************************************************\ +* * +* DetectAuraAddressableControllers * +* * +* Tests the USB address to see if an Asus Aura addressable RGB header controller * +* exists there. * +* * +\******************************************************************************************/ + +void DetectAuraAddressableControllers(std::vector& rgb_controllers) +{ + hid_device* dev; + + //Look for Asus Aura addressable RGB header controller + hid_init(); + + for(int pid_idx = 0; pid_idx < NUM_PIDS; pid_idx++) + { + dev = hid_open(AURA_ADDRESSABLE_VID, pid_table[pid_idx], 0); + + if( dev ) + { + AuraAddressableController* controller = new AuraAddressableController(dev); + + RGBController_AuraAddressable* rgb_controller = new RGBController_AuraAddressable(controller); + + rgb_controllers.push_back(rgb_controller); + } + } +} diff --git a/OpenRGB.cpp b/OpenRGB.cpp index 1e9aa251..1231d588 100644 --- a/OpenRGB.cpp +++ b/OpenRGB.cpp @@ -294,6 +294,7 @@ void DetectPolychromeControllers(std::vector& busses, std: void DetectRGBFusionControllers(std::vector& busses, std::vector& rgb_controllers); void DetectRGBFusionGPUControllers(std::vector& busses, std::vector& rgb_controllers); void DetectMSIRGBControllers(std::vector &rgb_controllers); +void DetectAuraAddressableControllers(std::vector &rgb_controllers); void DetectLEDStripControllers(std::vector &rgb_controllers); void DetectHue2Controllers(std::vector &rgb_controllers); void DetectHuePlusControllers(std::vector &rgb_controllers); @@ -335,6 +336,7 @@ void DetectRGBControllers(void) DetectRGBFusionControllers(busses, rgb_controllers); DetectMSIRGBControllers(rgb_controllers); + DetectAuraAddressableControllers(rgb_controllers); DetectLEDStripControllers(rgb_controllers); DetectHue2Controllers(rgb_controllers); DetectHuePlusControllers(rgb_controllers); diff --git a/OpenRGB.pro b/OpenRGB.pro index d0331ae4..bbc7aec2 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -31,6 +31,7 @@ INCLUDEPATH += \ serial_port/ \ super_io/ \ Controllers/AMDWraithPrismController/ \ + Controllers/AuraAddressableController/ \ Controllers/AuraGPUController/ \ Controllers/AuraSMBusController/ \ Controllers/CorsairPeripheralController/ \ @@ -80,6 +81,8 @@ SOURCES += \ super_io/super_io.cpp \ Controllers/AMDWraithPrismController/AMDWraithPrismController.cpp \ Controllers/AMDWraithPrismController/AMDWraithPrismControllerDetect.cpp \ + Controllers/AuraAddressableController/AuraAddressableController.cpp \ + Controllers/AuraAddressableController/AuraAddressableControllerDetect.cpp \ Controllers/AuraGPUController/AuraGPUController.cpp \ Controllers/AuraGPUController/AuraGPUControllerDetect.cpp \ Controllers/AuraSMBusController/AuraSMBusController.cpp \ @@ -128,6 +131,7 @@ SOURCES += \ RGBController/RGBController.cpp \ RGBController/E131ControllerDetect.cpp \ RGBController/RGBController_AMDWraithPrism.cpp \ + RGBController/RGBController_AuraAddressable.cpp \ RGBController/RGBController_AuraGPU.cpp \ RGBController/RGBController_AuraSMBus.cpp \ RGBController/RGBController_CorsairLightingNode.cpp \ @@ -172,6 +176,7 @@ HEADERS += \ serial_port/serial_port.h \ super_io/super_io.h \ Controllers/AMDWraithPrismController/AMDWraithPrismController.h \ + Controllers/AuraAddressableController/AuraAddressableController.h \ Controllers/AuraGPUController/AuraGPUController.h \ Controllers/AuraSMBusController/AuraSMBusController.h \ Controllers/CorsairLightingNodeController/CorsairLightingNodeController.h \ @@ -197,6 +202,7 @@ HEADERS += \ Controllers/ThermaltakeRiingController/ThermaltakeRiingController.h \ RGBController/RGBController.h \ RGBController/RGBController_AMDWraithPrism.h \ + RGBController/RGBController_AuraAddressable.h \ RGBController/RGBController_AuraGPU.h \ RGBController/RGBController_AuraSMBus.h \ RGBController/RGBController_CorsairLightingNode.h \ diff --git a/RGBController/RGBController_AuraAddressable.cpp b/RGBController/RGBController_AuraAddressable.cpp new file mode 100644 index 00000000..1b124a50 --- /dev/null +++ b/RGBController/RGBController_AuraAddressable.cpp @@ -0,0 +1,214 @@ +/*-----------------------------------------*\ +| RGBController_AuraAddressable.cpp | +| | +| Generic RGB Interface for Asus Aura | +| addressable controller driver | +| | +| Adam Honse (CalcProgrammer1) 1/18/2020 | +\*-----------------------------------------*/ + +#include "RGBController_AuraAddressable.h" + +RGBController_AuraAddressable::RGBController_AuraAddressable(AuraAddressableController* aura_ptr) +{ + aura = aura_ptr; + + name = "ASUS Aura Addressable"; + type = DEVICE_TYPE_MOTHERBOARD; + description = "ASUS Aura Addressable Device"; + + 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); + + mode Off; + Off.name = "Off"; + Off.value = AURA_MODE_OFF; + Off.flags = 0; + Off.color_mode = MODE_COLORS_NONE; + modes.push_back(Off); + + mode Static; + Static.name = "Static"; + Static.value = AURA_MODE_STATIC; + 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 Breathing; + Breathing.name = "Breathing"; + Breathing.value = AURA_MODE_BREATHING; + Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + Breathing.colors_min = 1; + Breathing.colors_max = 1; + Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC; + Breathing.colors.resize(1); + modes.push_back(Breathing); + + mode Flashing; + Flashing.name = "Flashing"; + Flashing.value = AURA_MODE_FLASHING; + Flashing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + Flashing.colors_min = 1; + Flashing.colors_max = 1; + Flashing.color_mode = MODE_COLORS_MODE_SPECIFIC; + Flashing.colors.resize(1); + modes.push_back(Flashing); + + mode SpectrumCycle; + SpectrumCycle.name = "Spectrum Cycle"; + SpectrumCycle.value = AURA_MODE_SPECTRUM_CYCLE; + SpectrumCycle.flags = 0; + SpectrumCycle.color_mode = MODE_COLORS_NONE; + modes.push_back(SpectrumCycle); + + mode Rainbow; + Rainbow.name = "Rainbow"; + Rainbow.value = AURA_MODE_RAINBOW; + Rainbow.flags = 0; + Rainbow.color_mode = MODE_COLORS_NONE; + modes.push_back(Rainbow); + + mode ChaseFade; + ChaseFade.name = "Chase Fade"; + ChaseFade.value = AURA_MODE_CHASE_FADE; + ChaseFade.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + ChaseFade.colors_min = 1; + ChaseFade.colors_max = 1; + ChaseFade.color_mode = MODE_COLORS_MODE_SPECIFIC; + ChaseFade.colors.resize(1); + modes.push_back(ChaseFade); + + mode Chase; + Chase.name = "Chase"; + Chase.value = AURA_MODE_CHASE; + Chase.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + Chase.colors_min = 1; + Chase.colors_max = 1; + Chase.color_mode = MODE_COLORS_MODE_SPECIFIC; + Chase.colors.resize(1); + modes.push_back(Chase); + + SetupZones(); +} + +RGBController_AuraAddressable::~RGBController_AuraAddressable() +{ + +} + +void RGBController_AuraAddressable::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(AURA_ADDRESSABLE_NUM_CHANNELS); + + /*-------------------------------------------------*\ + | Set zones and leds | + \*-------------------------------------------------*/ + for (unsigned int channel_idx = 0; channel_idx < AURA_ADDRESSABLE_NUM_CHANNELS; channel_idx++) + { + char ch_idx_string[2]; + sprintf(ch_idx_string, "%d", channel_idx + 1); + + zones[channel_idx].name = "Aura 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 = AURA_ADDRESSABLE_MAX_LEDS; + + if(first_run) + { + zones[channel_idx].leds_count = 0; + } + + for (unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++) + { + char led_idx_string[4]; + sprintf(led_idx_string, "%d", led_ch_idx + 1); + + led new_led; + new_led.name = "Aura Channel "; + new_led.name.append(ch_idx_string); + new_led.name.append(", LED "); + new_led.name.append(led_idx_string); + + leds.push_back(new_led); + leds_channel.push_back(channel_idx); + } + } + + SetupColors(); +} + +void RGBController_AuraAddressable::ResizeZone(int zone, int new_size) +{ + 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_AuraAddressable::UpdateLEDs() +{ + if(modes[active_mode].value == 0xFFFF) + { + aura->SetLEDsDirect(colors); + } +} + +void RGBController_AuraAddressable::UpdateZoneLEDs(int zone) +{ + UpdateLEDs(); +} + +void RGBController_AuraAddressable::UpdateSingleLED(int led) +{ + UpdateLEDs(); +} + +void RGBController_AuraAddressable::SetCustomMode() +{ + +} + +void RGBController_AuraAddressable::UpdateMode() +{ + 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]); + } + + if(modes[active_mode].value != 0xFFFF) + { + aura->SetMode(modes[active_mode].value, red, grn, blu); + } +} \ No newline at end of file diff --git a/RGBController/RGBController_AuraAddressable.h b/RGBController/RGBController_AuraAddressable.h new file mode 100644 index 00000000..fa428701 --- /dev/null +++ b/RGBController/RGBController_AuraAddressable.h @@ -0,0 +1,38 @@ +/*-----------------------------------------*\ +| RGBController_AuraAddressable.h | +| | +| Generic RGB Interface for Asus Aura | +| addressable controller driver | +| | +| Adam Honse (CalcProgrammer1) 1/18/2020 | +\*-----------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "AuraAddressableController.h" + +#define AURA_ADDRESSABLE_MAX_LEDS 120 +#define AURA_ADDRESSABLE_NUM_CHANNELS 1 + +class RGBController_AuraAddressable : public RGBController +{ +public: + RGBController_AuraAddressable(AuraAddressableController* aura_ptr); + ~RGBController_AuraAddressable(); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void UpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void SetCustomMode(); + void UpdateMode(); + +private: + AuraAddressableController* aura; + std::vector leds_channel; + std::vector zones_channel; +}; \ No newline at end of file