Const cleanup, fix behavioral bugs by writing all LEDs every time

This commit is contained in:
Matt Harper 2020-05-08 11:10:37 -05:00 committed by Adam Honse
parent 1b65bb9cc3
commit 216b492f24
4 changed files with 56 additions and 42 deletions

View file

@ -12,6 +12,7 @@
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#ifdef DEBUG
#include <iostream>
#include <iomanip>
@ -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);
}

View file

@ -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
(

View file

@ -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()
{
}

View file

@ -27,7 +27,6 @@ public:
void UpdateSingleLED(int led);
void SetCustomMode();
void SetMode();
void UpdateMode();
private: