/*-----------------------------------------*\ | EVGAGPUv2Controller.cpp | | | | Driver for EVGA GPU RGB V2 (Turing) | | lighting controller | | | | TheRogueZeta 4/15/2021 | \*-----------------------------------------*/ #include "EVGAGPUv2Controller.h" EVGAGPUv2Controller::EVGAGPUv2Controller(i2c_smbus_interface* bus, evga_dev_id dev) { this->bus = bus; this->dev = dev; } EVGAGPUv2Controller::~EVGAGPUv2Controller() { } std::string EVGAGPUv2Controller::GetDeviceLocation() { std::string return_string(bus->device_name); char addr[5]; snprintf(addr, 5, "0x%02X", dev); return_string.append(", address "); return_string.append(addr); return("I2C: " + return_string); } unsigned char EVGAGPUv2Controller::GetBrightnessA() { return(bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_BRIGHTNESS)); } RGBColor EVGAGPUv2Controller::GetColorA() { int red = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_RED); int green = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_GREEN); int blue = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_BLUE); return(ToRGBColor(red, green, blue)); } RGBColor EVGAGPUv2Controller::GetColorB() { int red = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_COLOR_B_RED); int green = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_COLOR_B_GREEN); int blue = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_COLOR_B_BLUE); return(ToRGBColor(red, green, blue)); } unsigned char EVGAGPUv2Controller::GetMode() { unsigned char return_mode = 0; unsigned char mode = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_MODE); if(mode == 0xFF) { //Registers may not ready after saving config. Read again if 0xFF. mode = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_MODE); } switch (mode) { case EVGA_GPU_V2_MODE_OFF: { return_mode = EVGA_GPU_V2_RGB_MODE_OFF; } break; case EVGA_GPU_V2_MODE_DIRECT: { //No way to detect static so just return direct. return_mode = EVGA_GPU_V2_RGB_MODE_DIRECT; } break; case EVGA_GPU_V2_MODE_RAINBOW: { return_mode = EVGA_GPU_V2_RGB_MODE_RAINBOW; } break; case EVGA_GPU_V2_MODE_BREATHING: { u16_to_u8 speed_16 = { (uint16_t) 0 }; speed_16.LSB = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_B_TO_A_SPEED_LSB); speed_16.MSB = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_B_TO_A_SPEED_MSB); if (speed_16.u16 == 0) { return_mode = EVGA_GPU_V2_RGB_MODE_PULSE; } else { return_mode = EVGA_GPU_V2_RGB_MODE_BREATHING; } } break; default: break; } return(return_mode); } unsigned char EVGAGPUv2Controller::GetSpeed() { u16_to_u8 speed_16 = { (uint16_t) 0 }; speed_16.LSB = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_ONTIME_LSB); speed_16.MSB = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_ONTIME_MSB); speed_16.u16 /= SPEED_MULTIPLIER; return (unsigned char) speed_16.u16; } void EVGAGPUv2Controller::SetMode(unsigned char mode, RGBColor color1, RGBColor color2, unsigned int speed) { bool boolSave = false; EnableWrite(true); switch (mode) { case EVGA_GPU_V2_RGB_MODE_OFF: { SendMode(EVGA_GPU_V2_MODE_OFF); boolSave = true; } break; case EVGA_GPU_V2_RGB_MODE_DIRECT: case EVGA_GPU_V2_RGB_MODE_STATIC: { SendMode(EVGA_GPU_V2_MODE_DIRECT); //Static is mode 0x01 but with SaveSettings() boolSave = (mode == EVGA_GPU_V2_RGB_MODE_STATIC); SendColor(EVGA_GPU_V2_REG_COLOR_A_RED, RGBGetRValue(color1), RGBGetGValue(color1), RGBGetBValue(color1)); } break; case EVGA_GPU_V2_RGB_MODE_RAINBOW: { SendMode(EVGA_GPU_V2_MODE_RAINBOW); //OpenRGB does not do brightness yet SendBrightness(0x64); //Default = 0x64 // Set Rainbow speed? No control in the GUI but this register is only set in Ranbow mode. bus->i2c_smbus_write_byte_data(dev, 0x19, 0x11); boolSave = true; } break; case EVGA_GPU_V2_RGB_MODE_BREATHING: case EVGA_GPU_V2_RGB_MODE_PULSE: { SendMode(EVGA_GPU_V2_MODE_BREATHING); /*---------------------------------------------------------*\ | It is expected that color2 will be 0x000000 (black) for | | 1 color mode otherwise set correctly therfore no further | | inspection is required. | \*---------------------------------------------------------*/ SendColor(EVGA_GPU_V2_REG_COLOR_A_RED, RGBGetRValue(color1), RGBGetGValue(color1), RGBGetBValue(color1)); SendColor(EVGA_GPU_V2_REG_COLOR_B_RED, RGBGetRValue(color2), RGBGetGValue(color2), RGBGetBValue(color2)); /*-----------------------------------------------------------------*\ | Breathing mode speeds are consistent for B_TO_A and A_TO_B | | Pulse (Blink) mode is on/off ergo B_TO_A and A_TO_B = 0 (instant) | \*-----------------------------------------------------------------*/ u16_to_u8 speed_16 = { (uint16_t) (speed * SPEED_MULTIPLIER) }; u16_to_u8 rise_fall_un_16 = { (mode == EVGA_GPU_V2_RGB_MODE_PULSE) ? (uint16_t) 0 : speed_16.u16 }; SendSpeed(speed_16, speed_16, rise_fall_un_16, rise_fall_un_16, rise_fall_un_16); // 0x61 = 0x01 bus->i2c_smbus_write_byte_data(dev, 0x61, 0x01); // 0x6A and 0x6B = 0x00 bus->i2c_smbus_write_byte_data(dev, 0x6A, 0x00); bus->i2c_smbus_write_byte_data(dev, 0x6B, 0x00); boolSave = true; } break; default: break; } //Disable writes and Save (if applicable) EnableWrite(false); if(boolSave) { SaveSettings(); } } void EVGAGPUv2Controller::EnableWrite(bool boolEnable) { if(boolEnable) { bus->i2c_smbus_write_byte_data(dev, 0x0E, 0xE5); bus->i2c_smbus_write_byte_data(dev, 0x0E, 0xE9); bus->i2c_smbus_write_byte_data(dev, 0x0E, 0xF5); bus->i2c_smbus_write_byte_data(dev, 0x0E, 0xF9); } else { bus->i2c_smbus_write_byte_data(dev, 0x08, 0x01); //Dissable commands bus->i2c_smbus_write_byte_data(dev, 0x0E, 0xF0); bus->i2c_smbus_write_byte_data(dev, 0x0E, 0xE0); } } void EVGAGPUv2Controller::SaveSettings() { bus->i2c_smbus_write_byte_data(dev, 0x0E, 0xE5); bus->i2c_smbus_write_byte_data(dev, 0x0E, 0xE9); bus->i2c_smbus_write_byte_data(dev, 0x0E, 0xF0); bus->i2c_smbus_write_byte_data(dev, 0x1F, 0xE5); bus->i2c_smbus_write_byte_data(dev, 0x23, 0xE5); bus->i2c_smbus_write_byte_data(dev, 0x0E, 0xE0); bus->i2c_smbus_write_byte_data(dev, 0x0E, 0xE0); } void EVGAGPUv2Controller::SendBrightness(unsigned char brightness) { bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_BRIGHTNESS, brightness); } void EVGAGPUv2Controller::SendColor(unsigned char start_register, unsigned char red, unsigned char green, unsigned char blue, unsigned char brightness) { bus->i2c_smbus_write_byte_data(dev, start_register, red); bus->i2c_smbus_write_byte_data(dev, (start_register + 1), green); bus->i2c_smbus_write_byte_data(dev, (start_register + 2), blue); bus->i2c_smbus_write_byte_data(dev, (start_register + 3), brightness); } void EVGAGPUv2Controller::SendMode(unsigned char mode) { bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_MODE, mode); } void EVGAGPUv2Controller::SendSpeed(u16_to_u8 aOnTime, u16_to_u8 bOnTime, u16_to_u8 b2a, u16_to_u8 a2b, u16_to_u8 speed_un) { bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_B_UN_LSB, (unsigned char) speed_un.LSB ); bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_B_UN_MSB, (unsigned char) speed_un.MSB ); bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_B_TO_A_SPEED_LSB, (unsigned char) b2a.LSB ); bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_B_TO_A_SPEED_MSB, (unsigned char) b2a.MSB ); bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_B_ONTIME_LSB, (unsigned char) bOnTime.LSB ); bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_B_ONTIME_MSB, (unsigned char) bOnTime.MSB ); bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_A_TO_B_SPEED_LSB, (unsigned char) a2b.LSB ); bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_A_TO_B_SPEED_MSB, (unsigned char) a2b.MSB ); bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_ONTIME_LSB, (unsigned char) aOnTime.LSB ); bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_ONTIME_MSB, (unsigned char) aOnTime.MSB ); } void EVGAGPUv2Controller::SetColor(RGBColor colorA, RGBColor colorB, bool boolSave) { EnableWrite(true); SendColor(EVGA_GPU_V2_REG_COLOR_A_RED, RGBGetRValue(colorA), RGBGetGValue(colorA), RGBGetBValue(colorA), 0x64); SendColor(EVGA_GPU_V2_REG_COLOR_B_RED, RGBGetRValue(colorB), RGBGetGValue(colorB), RGBGetBValue(colorB), 0x64); EnableWrite(false); if(boolSave) { SaveSettings(); } }