/*---------------------------------------------------------*\ | GigabyteRGBFusion2USBController.h | | | | Driver for Gigabyte Aorus RGB Fusion 2 USB motherboard | | | | jackun 08 Jan 2020 | | megadjc 31 Jul 2025 | | | | This file is part of the OpenRGB project | | SPDX-License-Identifier: GPL-2.0-or-later | \*---------------------------------------------------------*/ #pragma once #include #include #include #include #include "RGBController.h" #include "GigabyteFusion2USB_Devices.h" #define FUSION2_USB_BUFFER_SIZE 64 /*--------------------------------------------------------*\ | Gen2 scan/info opcode base | \*--------------------------------------------------------*/ #define GEN2_LED_BASE_SCAN 0x38 /*---------------------------------------------------------*\ | Effects mode list | \*---------------------------------------------------------*/ enum EffectType { EFFECT_NONE = 0, EFFECT_STATIC = 1, EFFECT_PULSE = 2, EFFECT_BLINKING = 3, EFFECT_COLORCYCLE = 4, EFFECT_WAVE = 6, EFFECT_RANDOM = 8, EFFECT_WAVE1 = 9, EFFECT_WAVE2 = 10, EFFECT_WAVE3 = 11, EFFECT_WAVE4 = 12, EFFECT_DFLASH = 15, // to be continued... }; /*---------------------------------------------------------*\ | Low level strip length divisions | \*---------------------------------------------------------*/ enum LEDCount { LEDS_32 = 0, LEDS_64, LEDS_256, LEDS_512, LEDS_1024, }; /*---------------------------------------------------------*\ | Defines the RGB led data structure. | \*---------------------------------------------------------*/ struct LEDs { uint8_t r; uint8_t g; uint8_t b; }; /*---------------------------------------------------------*\ | Defines structure for low level calibration data. | \*---------------------------------------------------------*/ struct CalibrationData { uint32_t dled[4] = {0, 0, 0, 0}; uint32_t spare[4] = {0, 0, 0, 0}; uint32_t mainboard = 0; }; /*---------------------------------------------------------*\ | Defines structure for high level calibration data. | \*---------------------------------------------------------*/ struct EncodedCalibration { std::string dled[4]; std::string spare[4]; std::string mainboard; }; /*---------------------------------------------------------*\ | High level struct to contain Gen2 Header Data | \*---------------------------------------------------------*/ struct Gen2StripInfo { uint8_t numStrip = 0; std::vector LedsOfStrip; uint32_t totalLeds = 0; }; #pragma pack(push, 1) /*---------------------------------------------------------*\ | Packet structure for applying effects | \*---------------------------------------------------------*/ union PktEffectApply { unsigned char buffer[FUSION2_USB_BUFFER_SIZE]; struct apply_data { uint8_t report_id = 0xCC; uint8_t command_id = 0x28; uint32_t zone_sel0 = 0; uint32_t zone_sel1 = 0; uint8_t padding[54]; } a; PktEffectApply() : a {} { std::memset(a.padding, 0, sizeof(a.padding)); } }; /*---------------------------------------------------------*\ | Single LED Calibration struct | \*---------------------------------------------------------*/ struct RGBA { union { uint8_t raw[4]; struct { uint8_t blue; uint8_t green; uint8_t red; uint8_t alpha; }; }; }; typedef std::map< std::string, RGBA > RGBCalibration; typedef std::map< std::string, std::string> calibration; /*---------------------------------------------------------*\ | Packet structure for ARGB headers (addressable) | \*---------------------------------------------------------*/ union PktRGB { unsigned char buffer[FUSION2_USB_BUFFER_SIZE]; struct RGBData { uint8_t report_id; uint8_t header; uint16_t boffset; uint8_t bcount; LEDs leds[19]; uint16_t padding0; } s; PktRGB() : s {} { } void Init(uint8_t header, uint8_t report_id) { switch(header) { case LED4: case HDR_D_LED2: header = HDR_D_LED2_ARGB; break; case HDR_D_LED3: header = HDR_D_LED3_ARGB; break; case HDR_D_LED4: header = HDR_D_LED4_ARGB; break; default: header = HDR_D_LED1_ARGB; break; } s.report_id = report_id; s.header = header; s.boffset = 0; s.bcount = 0; memset(s.leds, 0, sizeof(s.leds)); } }; /*---------------------------------------------------------*\ | Packet structure for hardware effects | | Default values for Hardware Effects mode. | | Old init values. | | (All values 0 unless otherwise noted below) | | e.color0 = 0x00FF2100; //orange | | e.period1 = 1200; | | e.period2 = 200; | | e.period3 = 200; | | e.effect_param2 = 1; | \*---------------------------------------------------------*/ union PktEffect { unsigned char buffer[FUSION2_USB_BUFFER_SIZE]; struct Effect { uint8_t report_id = 0; uint8_t header = 0; uint32_t zone0 = 0; // RGB Fusion sets it to pow(2, led) uint32_t zone1 = 0; uint8_t reserved0 = 0; uint8_t effect_type = EFFECT_STATIC; uint8_t max_brightness = 255; uint8_t min_brightness = 0; uint32_t color0 = 0; uint32_t color1 = 0; uint16_t period0 = 0; // Fade in - Rising Timer - Needs to be 0 for "Direct" uint16_t period1 = 0; // Fade out uint16_t period2 = 0; // Hold uint16_t period3 = 0; uint8_t effect_param0 = 0; // ex color count to cycle through (max seems to be 7) uint8_t effect_param1 = 0; uint8_t effect_param2 = 0; // ex flash repeat count uint8_t effect_param3 = 0; uint8_t padding0[30]; } e; PktEffect() : e {} { } void Init(int led, uint8_t report_id, uint16_t pid) { memset(buffer, 0, sizeof(buffer)); e.report_id = report_id; if(led == -1) { e.zone0 = (pid == 0x5711) ? 0x07FF : 0xFF; e.header = 0x20; } else if(led < 8) { e.zone0 = 1U << led; e.header = 0x20 + led; } else if(led < 11) { e.zone0 = 1U << led; e.header = 0x90 + (led - 8); } else { e.zone0 = 0; e.header = 0; } } }; /*---------------------------------------------------------*\ | Basic Controller Init Struct | \*---------------------------------------------------------*/ struct IT8297Report { uint8_t report_id; uint8_t product; uint8_t device_num; uint8_t strip_detect; uint32_t fw_ver; uint8_t curr_led_count_high; uint8_t curr_led_count_low; uint8_t strip_ctrl_length1; uint8_t support_cmd_flag; char str_product[28]; uint32_t cal_spare0; uint32_t cal_strip0; uint32_t cal_strip1; uint32_t rgb_cali; uint32_t chip_id; uint32_t cal_spare1; }; /*---------------------------------------------------------*\ | CC61 Calibration Struct (For IT5711) | \*---------------------------------------------------------*/ struct IT5711Calibration { uint8_t report_id; uint8_t reserved[3]; uint32_t cal_strip2; uint32_t cal_strip3; uint32_t cal_spare2; uint32_t cal_spare3; uint8_t padding[44]; }; /*---------------------------------------------------------*\ | CC33 Set Calibration Struct | \*---------------------------------------------------------*/ union CMD_0x33 { unsigned char buffer[FUSION2_USB_BUFFER_SIZE]; struct Calibration { uint8_t report_id = 0xCC; uint8_t command_id = 0x33; uint32_t d_strip_c0 = 0; uint32_t d_strip_c1 = 0; uint32_t rgb_cali = 0; uint32_t c_spare0 = 0; uint32_t c_spare1 = 0; uint32_t d_strip_c2 = 0; uint32_t d_strip_c3 = 0; uint32_t c_spare2 = 0; uint32_t c_spare3 = 0; uint8_t reserved[25]; } c; CMD_0x33() : c{} { memset(c.reserved, 0, sizeof(c.reserved)); } }; #pragma pack(pop) class RGBFusion2USBController { public: RGBFusion2USBController(hid_device* handle, const char *path, std::string mb_name, uint16_t pid); ~RGBFusion2USBController(); bool ApplyEffect(bool batch_commit = false); bool SetCalibration(const EncodedCalibration& cal, bool refresh_from_hw); void SetLedCount(unsigned int c0, unsigned int c1, unsigned int c2, unsigned int c3); void SetLEDEffect(int led, int mode, unsigned int speed, unsigned char brightness, bool random, uint32_t* color); bool SetStripBuiltinEffectState(int hdr, bool enable); void SetStripColors(unsigned int hdr, RGBColor * colors, unsigned int num_colors, int single_led = -1); bool SupportsGen2() const; bool ScanGen2Strips(); EncodedCalibration GetCalibration(bool refresh_from_hw = false); std::string GetDeviceName(); uint8_t GetDeviceNum(); std::string GetDeviceDescription(); std::string GetDeviceLocation(); std::string GetFWVersion(); uint16_t GetProductID(); std::string GetSerial(); std::vector ExportGen2Strips() const; Gen2StripInfo g2_strip_info[4]; private: std::string DecodeCalibrationBuffer(uint32_t value) const; bool EnableLampArray(bool enable); bool EnableBeat(bool enable); uint32_t EncodeCalibrationBuffer(const std::string& rgb_order); bool RefreshHardwareInfo(); void ResetController(); bool SaveLEDState(bool enable); bool SaveCalState(); bool SendCCReport(uint8_t a, uint8_t b, uint8_t c = 0); bool SendReport(uint8_t id, uint8_t a, uint8_t b, uint8_t c = 0); int SendPacket(unsigned char* packet); hid_device* dev; uint8_t device_num; uint16_t product_id; uint32_t effect_zone_mask = 0; int mode; IT8297Report report; CalibrationData cal_data; std::string name; std::string description; std::string location; std::string version; std::string chip_id; int effect_disabled = -1; int report_id = 0xCC; bool report_loaded = false; bool cali_loaded = false; LEDCount D_LED1_count; LEDCount D_LED2_count; LEDCount D_LED3_count; LEDCount D_LED4_count; };