diff --git a/Controllers/IntelArcA770LEController/IntelArcA770LEController.cpp b/Controllers/IntelArcA770LEController/IntelArcA770LEController.cpp new file mode 100644 index 00000000..bd7ef66d --- /dev/null +++ b/Controllers/IntelArcA770LEController/IntelArcA770LEController.cpp @@ -0,0 +1,204 @@ +/*-----------------------------------------*\ +| IntelArcA770LEController.cpp | +| | +| Driver for Intel Arc A770 LE RGB lighting| +| controller | +| | +| Adam Honse (CalcProgrammer1) 11/1/2022 | +\*-----------------------------------------*/ + +#include "IntelArcA770LEController.h" +#include +#include +#include + +IntelArcA770LEController::IntelArcA770LEController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; +} + +IntelArcA770LEController::~IntelArcA770LEController() +{ + hid_close(dev); +} + +std::string IntelArcA770LEController::GetLocationString() +{ + return("HID: " + location); +} + +std::string IntelArcA770LEController::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); +} + +std::string IntelArcA770LEController::GetFirmwareVersionString() +{ + std::string ret_string = ""; + + unsigned char usb_buf[] = + { + 0x00, + 0x12, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }; + + unsigned char fw_buf[16] = {0x00}; + + hid_write(dev, usb_buf, 65); + hid_read(dev, usb_buf, 64); + + for(int char_idx = 0; char_idx < 16; char_idx+=2) + { + if(usb_buf[char_idx + 0x08] != 0) + { + fw_buf[char_idx / 2] = usb_buf[char_idx + 0x08]; + } + else + { + break; + } + } + + ret_string.append((char *)fw_buf); + + return(ret_string); +} + +void IntelArcA770LEController::SendEnableCommand() +{ + unsigned char usb_buf[] = + { + 0x00, + 0x41, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }; + + hid_write(dev, usb_buf, 65); + hid_read(dev, usb_buf, 64); +} + +void IntelArcA770LEController::SendApplyCommand() +{ + unsigned char usb_buf[] = + { + 0x00, + 0x51, 0x28, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }; + + hid_write(dev, usb_buf, 65); + hid_read(dev, usb_buf, 64); +} + +void IntelArcA770LEController::SendDirectPacket + ( + unsigned char size, + unsigned char * led_ids, + RGBColor * colors + ) +{ + unsigned char usb_buf[] = + { + 0x00, + 0xC0, 0x01, size, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }; + + for(unsigned int led_idx = 0; led_idx < size; led_idx++) + { + unsigned int index = led_idx * 4; + + /*-----------------------------------------*\ + | Special handling for Logo LED (0x96) | + | Use the maximum channel value as this is | + | a white LED using the red channel | + \*-----------------------------------------*/ + if(led_ids[led_idx] == 0x96) + { + usb_buf[index + 5] = led_ids[led_idx]; + + usb_buf[index + 6] = std::max(RGBGetRValue(colors[led_idx]), std::max(RGBGetGValue(colors[led_idx]), RGBGetBValue(colors[led_idx]))); + usb_buf[index + 7] = 0; + usb_buf[index + 8] = 0; + } + else + { + usb_buf[index + 5] = led_ids[led_idx]; + usb_buf[index + 6] = RGBGetRValue(colors[led_idx]); + usb_buf[index + 7] = RGBGetGValue(colors[led_idx]); + usb_buf[index + 8] = RGBGetBValue(colors[led_idx]); + } + } + + hid_write(dev, usb_buf, 65); + hid_read(dev, usb_buf, 64); +} diff --git a/Controllers/IntelArcA770LEController/IntelArcA770LEController.h b/Controllers/IntelArcA770LEController/IntelArcA770LEController.h new file mode 100644 index 00000000..93dbfcc1 --- /dev/null +++ b/Controllers/IntelArcA770LEController/IntelArcA770LEController.h @@ -0,0 +1,42 @@ +/*-----------------------------------------*\ +| IntelArcA770LEController.h | +| | +| Definitions and types for Intel Arc A770 | +| LE lighting controller | +| | +| Adam Honse (CalcProgrammer1) 11/1/2022 | +\*-----------------------------------------*/ + +#include +#include + +#include "RGBController.h" + +#pragma once + +class IntelArcA770LEController +{ +public: + IntelArcA770LEController(hid_device* dev_handle, const char* path); + ~IntelArcA770LEController(); + + std::string GetEffectChannelString(unsigned char channel); + std::string GetFirmwareVersionString(); + std::string GetLocationString(); + std::string GetSerialString(); + + void SendDirectPacket + ( + unsigned char size, + unsigned char * led_ids, + RGBColor * colors + ); + + void SendEnableCommand(); + + void SendApplyCommand(); + +private: + hid_device* dev; + std::string location; +}; diff --git a/Controllers/IntelArcA770LEController/IntelArcA770LEControllerDetect.cpp b/Controllers/IntelArcA770LEController/IntelArcA770LEControllerDetect.cpp new file mode 100644 index 00000000..53f3c3ea --- /dev/null +++ b/Controllers/IntelArcA770LEController/IntelArcA770LEControllerDetect.cpp @@ -0,0 +1,30 @@ +#include "Detector.h" +#include "IntelArcA770LEController.h" +#include "RGBController.h" +#include "RGBController_IntelArcA770LE.h" +#include + +#define INTEL_ARC_A770_LIMITED_EDITION_VID 0x2516 +#define INTEL_ARC_A770_LIMITED_EDITION_PID 0x01B5 + +/******************************************************************************************\ +* * +* DetectIntelArcA770LEControllers * +* * +* Tests the USB address to see if an Intel Arc A770 LE controller exists there. * +* * +\******************************************************************************************/ + +void DetectIntelArcA770LEControllers(hid_device_info* info, const std::string&) +{ + hid_device* dev = hid_open_path(info->path); + if( dev ) + { + IntelArcA770LEController* controller = new IntelArcA770LEController(dev, info->path); + RGBController_IntelArcA770LE* rgb_controller = new RGBController_IntelArcA770LE(controller); + // Constructor sets the name + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_HID_DETECTOR_IP("Intel Arc A770 Limited Edition", DetectIntelArcA770LEControllers, INTEL_ARC_A770_LIMITED_EDITION_VID, INTEL_ARC_A770_LIMITED_EDITION_PID, 1, 0xFF00); diff --git a/Controllers/IntelArcA770LEController/RGBController_IntelArcA770LE.cpp b/Controllers/IntelArcA770LEController/RGBController_IntelArcA770LE.cpp new file mode 100644 index 00000000..56922ec5 --- /dev/null +++ b/Controllers/IntelArcA770LEController/RGBController_IntelArcA770LE.cpp @@ -0,0 +1,202 @@ +/*-----------------------------------------*\ +| RGBController_IntelArcA770LE.cpp | +| | +| Generic RGB Interface for Intel Arc A770 | +| LE | +| | +| Adam Honse (CalcProgrammer1) 11/2/2022 | +\*-----------------------------------------*/ + +#include "RGBController_IntelArcA770LE.h" + +/**------------------------------------------------------------------*\ + @name Intel Arc A770 Limited Edition + @category GPU + @type USB + @save :o: + @direct :white_check_mark: + @effects :tools: + @detectors DetectIntelArcA770LEControllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_IntelArcA770LE::RGBController_IntelArcA770LE(IntelArcA770LEController* controller_ptr) +{ + controller = controller_ptr; + + name = "Intel Arc A770 Limited Edition"; + vendor = "Cooler Master"; + type = DEVICE_TYPE_GPU; + description = "Intel Arc A770 Limited Edition"; + version = controller->GetFirmwareVersionString(); + location = controller->GetLocationString(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = 0; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Direct.brightness_min = 0; + Direct.brightness_max = 0; + Direct.brightness = 0; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + controller->SendEnableCommand(); + controller->SendApplyCommand(); + + SetupZones(); +} + +RGBController_IntelArcA770LE::~RGBController_IntelArcA770LE() +{ + delete controller; +} + +void RGBController_IntelArcA770LE::SetupZones() +{ + const unsigned int fan_1_leds[16] = { 0x01, 0x04, 0x07, 0x0A, 0x0D, 0x10, 0x13, 0x16, + 0x19, 0x1C, 0x1F, 0x22, 0x25, 0x28, 0x2B, 0x2E }; + const unsigned int fan_2_leds[16] = { 0x31, 0x34, 0x37, 0x3A, 0x3D, 0x40, 0x43, 0x46, + 0x49, 0x4C, 0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E }; + const unsigned int back_leds[8] = { 0x02, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x17 }; + const unsigned int ring_leds[50] = { 0x00, 0x03, 0x06, 0x09, 0x0C, 0x0F, 0x12, 0x15, + 0x18, 0x1B, 0x1E, 0x21, 0x24, 0x27, 0x2A, 0x2D, + 0x30, 0x33, 0x36, 0x39, 0x3C, 0x3F, 0x42, 0x45, + 0x48, 0x4B, 0x4E, 0x51, 0x54, 0x57, 0x5A, 0x5D, + 0x60, 0x63, 0x66, 0x69, 0x6C, 0x6F, 0x72, 0x75, + 0x78, 0x7B, 0x7E, 0x81, 0x84, 0x87, 0x8A, 0x8D, + 0x90, 0x93 }; + const unsigned int logo_leds[1] = { 0x96 }; + + zone fan_1_zone; + fan_1_zone.name = "Fan 1"; + fan_1_zone.type = ZONE_TYPE_LINEAR; + fan_1_zone.leds_min = 16; + fan_1_zone.leds_max = 16; + fan_1_zone.leds_count = 16; + fan_1_zone.matrix_map = NULL; + zones.push_back(fan_1_zone); + + zone fan_2_zone; + fan_2_zone.name = "Fan 2"; + fan_2_zone.type = ZONE_TYPE_LINEAR; + fan_2_zone.leds_min = 16; + fan_2_zone.leds_max = 16; + fan_2_zone.leds_count = 16; + fan_2_zone.matrix_map = NULL; + zones.push_back(fan_2_zone); + + zone back; + back.name = "Back"; + back.type = ZONE_TYPE_LINEAR; + back.leds_min = 8; + back.leds_max = 8; + back.leds_count = 8; + back.matrix_map = NULL; + zones.push_back(back); + + zone ring; + ring.name = "Ring"; + ring.type = ZONE_TYPE_LINEAR; + ring.leds_min = 50; + ring.leds_max = 50; + ring.leds_count = 50; + ring.matrix_map = NULL; + zones.push_back(ring); + + zone logo; + logo.name = "Logo"; + logo.type = ZONE_TYPE_SINGLE; + logo.leds_min = 1; + logo.leds_max = 1; + logo.leds_count = 1; + zones.push_back(logo); + + for(unsigned int led_idx = 0; led_idx < 16; led_idx++) + { + led fan_1_led; + fan_1_led.name = "Fan 1 LED"; + fan_1_led.value = fan_1_leds[led_idx]; + leds.push_back(fan_1_led); + } + + for(unsigned int led_idx = 0; led_idx < 16; led_idx++) + { + led fan_2_led; + fan_2_led.name = "Fan 2 LED"; + fan_2_led.value = fan_2_leds[led_idx]; + leds.push_back(fan_2_led); + } + + for(unsigned int led_idx = 0; led_idx < 8; led_idx++) + { + led back_led; + back_led.name = "Back LED"; + back_led.value = back_leds[led_idx]; + leds.push_back(back_led); + } + + for(unsigned int led_idx = 0; led_idx < 50; led_idx++) + { + led ring_led; + ring_led.name = "Ring LED"; + ring_led.value = ring_leds[led_idx]; + leds.push_back(ring_led); + } + + for(unsigned int led_idx = 0; led_idx < 1; led_idx++) + { + led logo_led; + logo_led.name = "Logo LED"; + logo_led.value = logo_leds[led_idx]; + leds.push_back(logo_led); + } + + SetupColors(); +} + +void RGBController_IntelArcA770LE::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_IntelArcA770LE::DeviceUpdateLEDs() +{ + unsigned char led_ids[15]; + RGBColor color_buf[15]; + unsigned int leds_count = 0; + + for(unsigned int led_idx = 0; led_idx < colors.size(); led_idx++) + { + led_ids[leds_count] = (unsigned char)leds[led_idx].value; + color_buf[leds_count] = colors[led_idx]; + + leds_count++; + + if(leds_count >= 15) + { + controller->SendDirectPacket(15, led_ids, color_buf); + leds_count = 0; + } + } + + if(leds_count > 0) + { + controller->SendDirectPacket(leds_count, led_ids, color_buf); + } +} + +void RGBController_IntelArcA770LE::UpdateZoneLEDs(int zone) +{ + +} + +void RGBController_IntelArcA770LE::UpdateSingleLED(int led) +{ +} + +void RGBController_IntelArcA770LE::DeviceUpdateMode() +{ +} diff --git a/Controllers/IntelArcA770LEController/RGBController_IntelArcA770LE.h b/Controllers/IntelArcA770LEController/RGBController_IntelArcA770LE.h new file mode 100644 index 00000000..3feb6972 --- /dev/null +++ b/Controllers/IntelArcA770LEController/RGBController_IntelArcA770LE.h @@ -0,0 +1,32 @@ +/*-----------------------------------------*\ +| RGBController_IntelArcA770LE.h | +| | +| Generic RGB Interface for Intel Arc A770 | +| LE | +| | +| Adam Honse (CalcProgrammer1) 11/2/2022 | +\*-----------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "IntelArcA770LEController.h" + +class RGBController_IntelArcA770LE : public RGBController +{ +public: + RGBController_IntelArcA770LE(IntelArcA770LEController* controller_ptr); + ~RGBController_IntelArcA770LE(); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: + IntelArcA770LEController* controller; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index a96ce2a4..d2dd721f 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -129,6 +129,7 @@ INCLUDEPATH += Controllers/HyperXKeyboardController/ \ Controllers/HyperXMouseController/ \ Controllers/HyperXMousematController/ \ + Controllers/IntelArcA770LEController/ \ Controllers/LEDStripController/ \ Controllers/LenovoControllers/ \ Controllers/LianLiController/ \ @@ -441,6 +442,8 @@ HEADERS += Controllers/HyperXMouseController/RGBController_HyperXPulsefireRaid.h \ Controllers/HyperXMousematController/HyperXMousematController.h \ Controllers/HyperXMousematController/RGBController_HyperXMousemat.h \ + Controllers/IntelArcA770LEController/IntelArcA770LEController.h \ + Controllers/IntelArcA770LEController/RGBController_IntelArcA770LE.h \ Controllers/KeychronKeyboardController/KeychronKeyboardController.h \ Controllers/KeychronKeyboardController/RGBController_KeychronKeyboard.h \ Controllers/LEDStripController/LEDStripController.h \ @@ -989,6 +992,9 @@ SOURCES += Controllers/HyperXMousematController/HyperXMousematController.cpp \ Controllers/HyperXMousematController/HyperXMousematControllerDetect.cpp \ Controllers/HyperXMousematController/RGBController_HyperXMousemat.cpp \ + Controllers/IntelArcA770LEController/IntelArcA770LEController.cpp \ + Controllers/IntelArcA770LEController/IntelArcA770LEControllerDetect.cpp \ + Controllers/IntelArcA770LEController/RGBController_IntelArcA770LE.cpp \ Controllers/KeychronKeyboardController/KeychronKeyboardController.cpp \ Controllers/KeychronKeyboardController/KeychronKeyboardControllerDetect.cpp \ Controllers/KeychronKeyboardController/RGBController_KeychronKeyboard.cpp \