/*-----------------------------------------*\ | RGBController_RGBFusion2USB.cpp | | | | Generic RGB Interface for OpenRGB | | Gigabyte RGB Fusion 2.0 USB Driver | | | | jackun 1/8/2020 | \*-----------------------------------------*/ #include "RGBController_RGBFusion2USB.h" #include #include enum { ZONE_MB, ZONE_STRIP1, ZONE_STRIP2, }; static const std::array led_zones { "Motherboard", "LED Strip 1", // WS2812(B) strips "LED Strip 2", }; static const KnownChannels known_channels { { "Generic", { { { "Led 1", 0x20 }, { "Led 2", 0x21 }, { "Led 3", 0x22 }, { "Led 4", 0x23 }, { "Led 5", 0x24 }, { "Led 6", 0x25 }, { "Led 7", 0x26 }, { "Led 8", 0x27 }, }, // Zone 1 { { "LED Strip 1, LED 0", HDR_D_LED1 }, }, // Zone 2 { { "LED Strip 2, LED 0", HDR_D_LED2 }, } } }, { "IT8297BX-GBX570", { // Zone 0 { { "Back I/O", HDR_BACK_IO }, { "CPU", HDR_CPU }, { "PCIe", HDR_PCIE }, { "LED C1/C2", HDR_LED_C1C2 }, // 12VGRB headers seem to be connected }, // Zone 1 { { "LED Strip 1, LED 0", HDR_D_LED1 }, }, // Zone 2 { { "LED Strip 2, LED 0", HDR_D_LED2 }, } } }, }; RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController* controller_ptr) { controller = controller_ptr; name = "RGB Fusion 2 Controller"; type = DEVICE_TYPE_MOTHERBOARD; description = controller->GetDeviceName(); version = controller->GetFWVersion(); location = controller->GetDeviceLocation(); serial = controller->GetSerial(); 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 Static; Static.name = "Static"; Static.value = EFFECT_STATIC; Static.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_PER_LED_COLOR; Static.color_mode = MODE_COLORS_PER_LED; modes.push_back(Static); mode Breathing; Breathing.name = "Breathing"; Breathing.value = EFFECT_PULSE; Breathing.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_RANDOM_COLOR; Breathing.speed_min = 0; Breathing.speed_max = 4; Breathing.color_mode = MODE_COLORS_PER_LED; Breathing.speed = 2; modes.push_back(Breathing); mode Blinking; Blinking.name = "Blinking"; Blinking.value = EFFECT_BLINKING; Blinking.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_RANDOM_COLOR; Blinking.speed_min = 0; Blinking.speed_max = 4; Blinking.color_mode = MODE_COLORS_PER_LED; Blinking.speed = 2; modes.push_back(Blinking); mode ColorCycle; ColorCycle.name = "Color Cycle"; ColorCycle.value = EFFECT_COLORCYCLE; ColorCycle.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED; ColorCycle.speed_min = 0; ColorCycle.speed_max = 4; ColorCycle.color_mode = MODE_COLORS_NONE; ColorCycle.speed = 2; modes.push_back(ColorCycle); mode Flashing; Flashing.name = "Flashing"; Flashing.value = 10; Flashing.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_RANDOM_COLOR; Flashing.speed_min = 0; Flashing.speed_max = 4; Flashing.color_mode = MODE_COLORS_PER_LED; Flashing.speed = 2; modes.push_back(Flashing); SetupZones(); } void RGBController_RGBFusion2USB::SetupZones() { /*---------------------------------------------------------*\ | Look up channel map based on device name | \*---------------------------------------------------------*/ KnownChannels::const_iterator it = known_channels.find(controller->GetDeviceName()); if (it == known_channels.end()) { it = known_channels.find("Generic"); } /*---------------------------------------------------------*\ | Get the default number of addressable LEDs for each strip | \*---------------------------------------------------------*/ per_strip_led_cnt = 64; // TODO needs GUI option /*---------------------------------------------------------*\ | Get number of motherboard LEDs and set addressable LED | | count | \*---------------------------------------------------------*/ size_t mb_led_cnt = it->second[0].size(); controller->SetLedCount(per_strip_led_cnt); controller->DisableBuiltinEffect(0, 0x3); /*---------------------------------------------------------*\ | Set up zones | \*---------------------------------------------------------*/ for(std::size_t zone_idx = 0; zone_idx < led_zones.size(); zone_idx++) { zone new_zone; new_zone.name = led_zones[zone_idx]; new_zone.type = ZONE_TYPE_LINEAR; /*---------------------------------------------------------*\ | Zone index 0 is motherboard LEDs and has fixed size | \*---------------------------------------------------------*/ if(zone_idx == ZONE_MB) { new_zone.leds_min = mb_led_cnt; new_zone.leds_max = mb_led_cnt; new_zone.leds_count = mb_led_cnt; } else { new_zone.leds_min = 0; new_zone.leds_max = per_strip_led_cnt; //TODO - per-channel LED counts new_zone.leds_count = per_strip_led_cnt; } zones.push_back(new_zone); } /*---------------------------------------------------------*\ | Set up LEDs | \*---------------------------------------------------------*/ for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) { for(std::size_t led_idx = 0; led_idx < zones[zone_idx].leds_count; led_idx++) { led new_led; if( it != known_channels.end() && zone_idx < it->second.size() && led_idx < it->second[zone_idx].size()) { new_led.name = it->second[zone_idx][led_idx].name; } else { new_led.name = zones[zone_idx].name + " LED "; new_led.name.append(std::to_string(led_idx)); } new_led.value = zone_idx; leds.push_back(new_led); } } SetupColors(); } void RGBController_RGBFusion2USB::ResizeZone(int /*zone*/, int /*new_size*/) { } void RGBController_RGBFusion2USB::SetCustomMode() { active_mode = 0; } void RGBController_RGBFusion2USB::UpdateLEDs() { for(size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) { UpdateZoneLEDs(zone_idx); } } void RGBController_RGBFusion2USB::UpdateZoneLEDs(int zone) { /*---------------------------------------------------------*\ | Get mode parameters | \*---------------------------------------------------------*/ bool random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM); int mode_value = (modes[active_mode].value); KnownChannels::const_iterator it = known_channels.find(controller->GetDeviceName()); if (it == known_channels.end()) { it = known_channels.find("Generic"); } if (it == known_channels.end() || zone >= (int)it->second.size()) { return; } /*---------------------------------------------------------*\ | Set motherboard LEDs | \*---------------------------------------------------------*/ if(zone == ZONE_MB) { /*---------------------------------------------------------*\ | Motherboard LEDs always use effect mode, so use static for| | direct mode | \*---------------------------------------------------------*/ if(mode_value == 0xFFFF) { mode_value = EFFECT_STATIC; } for(size_t led_idx = 0; led_idx < zones[zone].leds_count; led_idx++) { unsigned char red = RGBGetRValue(zones[zone].colors[led_idx]); unsigned char grn = RGBGetGValue(zones[zone].colors[led_idx]); unsigned char blu = RGBGetBValue(zones[zone].colors[led_idx]); controller->SetLEDEffect(it->second[zone][led_idx].header, modes[active_mode].value, modes[active_mode].speed, random, red, grn, blu); } controller->ApplyEffect(); } /*---------------------------------------------------------*\ | Set strip LEDs | \*---------------------------------------------------------*/ else { /*---------------------------------------------------------*\ | Direct mode | \*---------------------------------------------------------*/ if(mode_value == 0xFFFF) { if(zones[zone].leds_count > 0) { unsigned char hdr = 0; if(zone == ZONE_STRIP1) { hdr = HDR_D_LED1_RGB; } else if(zone == ZONE_STRIP2) { hdr = HDR_D_LED2_RGB; } controller->DisableBuiltinEffect(1, zone == 1 ? 0x01 : 0x02); controller->SetStripColors(hdr, zones[zone].colors, zones[zone].leds_count); } } /*---------------------------------------------------------*\ | Effect mode | \*---------------------------------------------------------*/ else { if(it->second[zone].size()) { unsigned char red = RGBGetRValue(zones[zone].colors[0]); unsigned char grn = RGBGetGValue(zones[zone].colors[0]); unsigned char blu = RGBGetBValue(zones[zone].colors[0]); int hdr = it->second[zone].front().header; // apply built-in effects to LED strips controller->DisableBuiltinEffect(0, zone == 1 ? 0x01 : 0x02); controller->SetLEDEffect(hdr, modes[active_mode].value, modes[active_mode].speed, random, red, grn, blu); controller->ApplyEffect(); } } } } void RGBController_RGBFusion2USB::UpdateSingleLED(int led) { /*---------------------------------------------------------*\ | Get mode parameters | \*---------------------------------------------------------*/ bool random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM); int mode_value = (modes[active_mode].value); unsigned int zone_idx = leds[led].value; /*---------------------------------------------------------*\ | Set motherboard LEDs | \*---------------------------------------------------------*/ if(zone_idx == ZONE_MB) { int header = led; auto it = known_channels.find(controller->GetDeviceName()); if (it == known_channels.end() || it->second.size() == 0) header = it->second[ZONE_MB][led].header; /*---------------------------------------------------------*\ | Motherboard LEDs always use effect mode, so use static for| | direct mode | \*---------------------------------------------------------*/ if(mode_value == 0xFFFF) { mode_value = EFFECT_STATIC; } unsigned char red = RGBGetRValue(colors[led]); unsigned char grn = RGBGetGValue(colors[led]); unsigned char blu = RGBGetBValue(colors[led]); controller->SetLEDEffect(header, modes[active_mode].value, modes[active_mode].speed, random, red, grn, blu); controller->ApplyEffect(); } /*---------------------------------------------------------*\ | Set strip LEDs | \*---------------------------------------------------------*/ else { UpdateZoneLEDs(zone_idx); } } void RGBController_RGBFusion2USB::UpdateMode() { // XXX Comment out to allow each zone or motherboard LED have different modes UpdateLEDs(); }