diff --git a/Controllers/RGBFusion2SMBusController/RGBFusion2SMBusController.cpp b/Controllers/RGBFusion2SMBusController/RGBFusion2SMBusController.cpp index 1bb035ea..697077c5 100644 --- a/Controllers/RGBFusion2SMBusController/RGBFusion2SMBusController.cpp +++ b/Controllers/RGBFusion2SMBusController/RGBFusion2SMBusController.cpp @@ -12,6 +12,7 @@ #include #include #include + #ifdef DEBUG #include #include @@ -42,6 +43,37 @@ std::string RGBFusion2SMBusController::GetDeviceLocation() return(return_string); } +void RGBFusion2SMBusController::Apply() +{ + /* + * Given that reading the existing state from the device is not yet possible, + * unfortunately we may overwrite existing device states if the state transition did + * not occur within in the same OpenRGB instance. + * Current behavior is non-ideal but the best we have. + */ + for (int i = 0; i < 5; i++) { + #ifdef DEBUG + std::cout << "0x" << std::hex << (int)RGB_FUSION_2_LED_START_ADDR + 2*i << "\t"; + for (int j = 0; j < 2; j++) { + for (int k = 0; k < 16; k++) { + std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)led_data[2*i+j][k] << " "; + } + } + std::cout << std::endl; + #endif + + bus->i2c_smbus_write_block_data(RGB_FUSION_2_SMBUS_ADDR, + RGB_FUSION_2_LED_START_ADDR + 2*i, + 32, // Writes occur in 32 byte blocks + led_data[i*2]); + } + + // Protocol expects terminating sequence 0x01ff written to register 0x17 + bus->i2c_smbus_write_word_data(RGB_FUSION_2_SMBUS_ADDR, + RGB_FUSION_2_APPLY_ADDR, + RGB_FUSION_2_ACTION_APPLY); +} + void RGBFusion2SMBusController::SetLEDEffect ( unsigned int led, @@ -58,7 +90,7 @@ void RGBFusion2SMBusController::SetLEDEffect led_data[led][RGB_FUSION_2_IDX_BLUE] = blue; led_data[led][RGB_FUSION_2_IDX_BRIGHTNESS] = 0x64; // TODO - is this *really* the max value? - // TODO - These timing calculations are weird - need to improve + // TODO - more thorough understanding could lead to better implementation led_data[led][RGB_FUSION_2_TIMER_1_LSB] = 0x20 * speed; led_data[led][RGB_FUSION_2_TIMER_1_MSB] = 0x03 * speed; led_data[led][RGB_FUSION_2_TIMER_2_LSB] = 0x20 * speed; @@ -87,40 +119,5 @@ void RGBFusion2SMBusController::SetLEDEffect led_data[led][0xe] = 0x07; // ??? } // End dragons. Well, probably. - - #ifdef DEBUG - // Print out hex for debug purposes - for (int i = 0; i < 16; i++) { - std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)led_data[led][i] << " "; - } - std::cout << std::endl; - #endif - - /* - * Writes occur in 32 byte blocks - * Therefore, writing the second 16 bytes necessitates writing the *first* 16 bytes as well. - * Given that reading the existing state from the device is not yet possible, - * unfortunately this implies that we may overwrite existing device states if the state - * transition did not occur within in the same OpenRGB instance. That is to say, this current - * behavior is non-ideal but the best we have. - */ - unsigned char oca = 0x20; // On chip address - unsigned short chip_offset; - if (led % 2) { - chip_offset = led-1; - } else { - chip_offset = led; - } - unsigned char write_addr = oca + chip_offset; - - #ifdef DEBUG - std::cout << "LED: " << led << "\tWrite address: " << std::hex << (int)write_addr << std::endl; - #endif - bus->i2c_smbus_write_block_data(0x68, write_addr, 32, led_data[led]); // Write 32 byte blocks at a time. Matches RGBF2 dump from Windows app. - - // Protocol expects terminating sequence 0x01ff written to register 0x17 - unsigned short terminator = 0x01ff; - unsigned char termination_addr = 0x17; - bus->i2c_smbus_write_word_data(0x68, termination_addr, terminator); } diff --git a/Controllers/RGBFusion2SMBusController/RGBFusion2SMBusController.h b/Controllers/RGBFusion2SMBusController/RGBFusion2SMBusController.h index 42221578..14d6faa0 100644 --- a/Controllers/RGBFusion2SMBusController/RGBFusion2SMBusController.h +++ b/Controllers/RGBFusion2SMBusController/RGBFusion2SMBusController.h @@ -27,6 +27,18 @@ enum RGB_FUSION_2_TIMER_2_MSB = 0x0B, /* Timer 2 MSB */ }; +enum +{ + RGB_FUSION_2_APPLY_ADDR = 0x17, + RGB_FUSION_2_LED_START_ADDR = 0x20, + RGB_FUSION_2_SMBUS_ADDR = 0x68, +}; + +enum +{ + RGB_FUSION_2_ACTION_APPLY = 0x01ff +}; + enum { RGB_FUSION_2_MODE_PULSE = 0x01, /* Pulse mode */ @@ -50,6 +62,7 @@ public: std::string GetDeviceLocation(); unsigned int GetLEDCount(); + void Apply(); void SetLEDEffect ( diff --git a/RGBController/RGBController_RGBFusion2SMBus.cpp b/RGBController/RGBController_RGBFusion2SMBus.cpp index 14c1496c..518939b1 100644 --- a/RGBController/RGBController_RGBFusion2SMBus.cpp +++ b/RGBController/RGBController_RGBFusion2SMBus.cpp @@ -48,10 +48,6 @@ RGBController_RGBFusion2SMBus::RGBController_RGBFusion2SMBus(RGBFusion2SMBusCont type = DEVICE_TYPE_MOTHERBOARD; - // TODO - Something awry with modes and their default speeds. - // Setting individual LEDs work fine, but changing via Mode dropdown causes LEDs - // to exceed specified ranges - mode Static; Static.name = "Static"; Static.value = RGB_FUSION_2_MODE_STATIC; @@ -148,8 +144,11 @@ void RGBController_RGBFusion2SMBus::UpdateLEDs() int mode = modes[active_mode].value; unsigned int speed = modes[active_mode].speed; + rgb_fusion->SetLEDEffect(led, mode, speed, red, grn, blu); } + + rgb_fusion->Apply(); } void RGBController_RGBFusion2SMBus::UpdateZoneLEDs(int zone) @@ -161,12 +160,17 @@ void RGBController_RGBFusion2SMBus::UpdateZoneLEDs(int zone) int mode = modes[active_mode].value; unsigned int speed = modes[active_mode].speed; + rgb_fusion->SetLEDEffect(zone, mode, speed, red, grn, blu); + rgb_fusion->Apply(); } void RGBController_RGBFusion2SMBus::UpdateSingleLED(int led) { - UpdateZoneLEDs(led); + // Issuing updates of individual LEDs seems to cause odd speed behavior + // Mitigating by writing all LEDs every time + // TODO - Further investigation into individual updates may be warranted + UpdateLEDs(); } // TODO - Research if possible to read device state @@ -184,3 +188,4 @@ void RGBController_RGBFusion2SMBus::UpdateMode() { } + diff --git a/RGBController/RGBController_RGBFusion2SMBus.h b/RGBController/RGBController_RGBFusion2SMBus.h index 89170b44..a09832c8 100644 --- a/RGBController/RGBController_RGBFusion2SMBus.h +++ b/RGBController/RGBController_RGBFusion2SMBus.h @@ -27,7 +27,6 @@ public: void UpdateSingleLED(int led); void SetCustomMode(); - void SetMode(); void UpdateMode(); private: