From 45755c79ae2076406527786da95f25170b8bec9f Mon Sep 17 00:00:00 2001 From: Diego Vargas Date: Mon, 2 May 2022 20:51:25 +0000 Subject: [PATCH] Add support for Patriot Viper Steel Direct mode --- .../PatriotViperSteelController.cpp | 88 +++++++++++++ .../PatriotViperSteelController.h | 52 ++++++++ .../PatriotViperSteelControllerDetect.cpp | 54 ++++++++ .../RGBController_PatriotViperSteel.cpp | 118 ++++++++++++++++++ .../RGBController_PatriotViperSteel.h | 32 +++++ OpenRGB.pro | 6 + 6 files changed, 350 insertions(+) create mode 100644 Controllers/PatriotViperSteelController/PatriotViperSteelController.cpp create mode 100644 Controllers/PatriotViperSteelController/PatriotViperSteelController.h create mode 100644 Controllers/PatriotViperSteelController/PatriotViperSteelControllerDetect.cpp create mode 100644 Controllers/PatriotViperSteelController/RGBController_PatriotViperSteel.cpp create mode 100644 Controllers/PatriotViperSteelController/RGBController_PatriotViperSteel.h diff --git a/Controllers/PatriotViperSteelController/PatriotViperSteelController.cpp b/Controllers/PatriotViperSteelController/PatriotViperSteelController.cpp new file mode 100644 index 00000000..17a13bdc --- /dev/null +++ b/Controllers/PatriotViperSteelController/PatriotViperSteelController.cpp @@ -0,0 +1,88 @@ +/*-----------------------------------------*\ +| PatriotViperSteelController.cpp | +| | +| Definitions and types for Patriot Viper | +| Steel RGB RAM lighting controller | +\*-----------------------------------------*/ + +#include "PatriotViperSteelController.h" +#include + +PatriotViperSteelController::PatriotViperSteelController(i2c_smbus_interface *bus, viper_dev_id dev) +{ + this->bus = bus; + this->dev = dev; + + strcpy(device_name, "Patriot Viper Steel RGB"); + + led_count = 5; +} + +PatriotViperSteelController::~PatriotViperSteelController() +{ +} + +std::string PatriotViperSteelController::GetDeviceName() +{ + return(device_name); +} + +std::string PatriotViperSteelController::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 int PatriotViperSteelController::GetLEDCount() +{ + return(led_count); +} + +unsigned int PatriotViperSteelController::GetSlotCount() +{ + unsigned int slot_count = 0; + + for(int slot = 0; slot < 4; slot++) + { + if((slots_valid & (1 << slot)) != 0) + { + slot_count++; + } + } + + return(slot_count); +} + +unsigned int PatriotViperSteelController::GetMode() +{ + return(mode); +} + +void PatriotViperSteelController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue) +{ + ViperRegisterWrite(VIPER_STEEL_REG_LED0_DIRECT_COLOR, red, blue, green); + ViperRegisterWrite(VIPER_STEEL_REG_LED1_DIRECT_COLOR, red, blue, green); + ViperRegisterWrite(VIPER_STEEL_REG_LED2_DIRECT_COLOR, red, blue, green); + ViperRegisterWrite(VIPER_STEEL_REG_LED3_DIRECT_COLOR, red, blue, green); + ViperRegisterWrite(VIPER_STEEL_REG_LED4_DIRECT_COLOR, red, blue, green); +} + +void PatriotViperSteelController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue) +{ + ViperRegisterWrite(VIPER_STEEL_REG_LED0_DIRECT_COLOR + led, red, blue, green); +} + +void PatriotViperSteelController::SetLEDColor(unsigned int /*slot*/, unsigned int led, unsigned char red, unsigned char green, unsigned char blue) +{ + ViperRegisterWrite(VIPER_STEEL_REG_LED0_DIRECT_COLOR + led, red, blue, green); +} + +void PatriotViperSteelController::ViperRegisterWrite(viper_register reg, unsigned char val0, unsigned char val1, unsigned char val2) +{ + bus->i2c_smbus_write_byte_data(dev, reg, val0); + bus->i2c_smbus_write_byte_data(dev, val2, val1); +} diff --git a/Controllers/PatriotViperSteelController/PatriotViperSteelController.h b/Controllers/PatriotViperSteelController/PatriotViperSteelController.h new file mode 100644 index 00000000..a1a77500 --- /dev/null +++ b/Controllers/PatriotViperSteelController/PatriotViperSteelController.h @@ -0,0 +1,52 @@ +/*-----------------------------------------*\ +| PatriotViperController.h | +| | +| Definitions and types for Patriot Viper | +| RGB RAM lighting controller | +\*-----------------------------------------*/ + +#include +#include "i2c_smbus.h" + +#pragma once + +typedef unsigned char viper_dev_id; +typedef unsigned short viper_register; + +enum +{ + VIPER_STEEL_REG_LED0_DIRECT_COLOR = 0x17, /* LED 0 Color (R, B, G) */ + VIPER_STEEL_REG_LED1_DIRECT_COLOR = 0x18, /* LED 1 Color (R, B, G) */ + VIPER_STEEL_REG_LED2_DIRECT_COLOR = 0x19, /* LED 2 Color (R, B, G) */ + VIPER_STEEL_REG_LED3_DIRECT_COLOR = 0x1a, /* LED 3 Color (R, B, G) */ + VIPER_STEEL_REG_LED4_DIRECT_COLOR = 0x1b, /* LED 4 Color (R, B, G) */ +}; + +class PatriotViperSteelController +{ +public: + PatriotViperSteelController(i2c_smbus_interface *bus, viper_dev_id dev); + ~PatriotViperSteelController(); + + std::string GetDeviceName(); + std::string GetDeviceLocation(); + unsigned int GetLEDCount(); + unsigned int GetSlotCount(); + unsigned int GetMode(); + + void SetAllColors(unsigned char red, unsigned char green, unsigned char blue); + void SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue); + void SetLEDColor(unsigned int slot, unsigned int led, unsigned char red, unsigned char green, unsigned char blue); + + void ViperRegisterWrite(viper_register reg, unsigned char val0, unsigned char val1, unsigned char val2); + bool direct; + +private: + char device_name[32]; + unsigned int led_count; + unsigned char slots_valid; + i2c_smbus_interface *bus; + viper_dev_id dev; + unsigned char mode; + unsigned char speed; +}; diff --git a/Controllers/PatriotViperSteelController/PatriotViperSteelControllerDetect.cpp b/Controllers/PatriotViperSteelController/PatriotViperSteelControllerDetect.cpp new file mode 100644 index 00000000..457d6dc1 --- /dev/null +++ b/Controllers/PatriotViperSteelController/PatriotViperSteelControllerDetect.cpp @@ -0,0 +1,54 @@ +#include "Detector.h" +#include "PatriotViperSteelController.h" +#include "LogManager.h" +#include "RGBController.h" +#include "RGBController_PatriotViperSteel.h" +#include "i2c_smbus.h" +#include "pci_ids.h" +#include +#include +#include + +using namespace std::chrono_literals; +#define PATRIOT_CONTROLLER_NAME "Patriot Viper Steel" + +/******************************************************************************************\ +* * +* DetectPatriotViperSteelControllers * +* * +* Detect Patriot Viper Steel RGB controllers on the enumerated I2C busses. * +* * +* bus - pointer to i2c_smbus_interface where Aura device is connected * +* dev - I2C address of Aura device * +* * +\******************************************************************************************/ + +void DetectPatriotViperSteelControllers(std::vector &busses) +{ + PatriotViperSteelController *new_viper; + RGBController_PatriotViperSteel *new_controller; + + for(unsigned int bus = 0; bus < busses.size(); bus++) + { + + IF_DRAM_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device) + { + int res = busses[bus]->i2c_smbus_read_byte_data(0x20, 0x1D); + + std::this_thread::sleep_for(1ms); + + if((busses[bus]->i2c_smbus_read_byte_data(0x20, 0x1D) == 0x0F) + &&(busses[bus]->i2c_smbus_read_byte_data(0x20, 0x1E) == 0x0C) + &&(busses[bus]->i2c_smbus_read_byte_data(0x20, 0x39) == 0x0F) + &&(busses[bus]->i2c_smbus_read_byte_data(0x20, 0x3A) == 0x0C)) + { + new_viper = new PatriotViperSteelController(busses[bus], 0x77); + new_controller = new RGBController_PatriotViperSteel(new_viper); + ResourceManager::get()->RegisterRGBController(new_controller); + } + } + } + +} /* DetectPatriotViperSteelControllers() */ + +REGISTER_I2C_DETECTOR(PATRIOT_CONTROLLER_NAME, DetectPatriotViperSteelControllers); diff --git a/Controllers/PatriotViperSteelController/RGBController_PatriotViperSteel.cpp b/Controllers/PatriotViperSteelController/RGBController_PatriotViperSteel.cpp new file mode 100644 index 00000000..66b32bc1 --- /dev/null +++ b/Controllers/PatriotViperSteelController/RGBController_PatriotViperSteel.cpp @@ -0,0 +1,118 @@ +/*-----------------------------------------*\ +| RGBController_PatriotViperSteel.cpp | +| | +| Generic RGB Interface for OpenRGB | +| Patriot Viper Steel RGB interface | +\*-----------------------------------------*/ + +#include "RGBController_PatriotViperSteel.h" + +/**------------------------------------------------------------------*\ + @name Patriot Viper Steel + @type I2C + @save :x: + @direct :white_check_mark: + @effects :white_check_mark: + @detectors DetectPatriotViperSteelControllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_PatriotViperSteel::RGBController_PatriotViperSteel(PatriotViperSteelController *viper_ptr) +{ + controller = viper_ptr; + + name = controller->GetDeviceName(); + vendor = "Patriot"; + type = DEVICE_TYPE_DRAM; + description = "Patriot Viper Steel Device"; + location = controller->GetDeviceLocation(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = 0xFFFF; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.speed_min = 0; + Direct.speed_max = 0; + Direct.color_mode = MODE_COLORS_PER_LED; + Direct.speed = 0; + modes.push_back(Direct); + + SetupZones(); +} + +RGBController_PatriotViperSteel::~RGBController_PatriotViperSteel() +{ + delete controller; +} + +void RGBController_PatriotViperSteel::SetupZones() +{ + /*---------------------------------------------------------*\ + | Set up zones | + \*---------------------------------------------------------*/ + zone *new_zone = new zone; + new_zone->name = "Patriot Viper Steel RGB"; + new_zone->type = ZONE_TYPE_LINEAR; + new_zone->leds_min = 5; + new_zone->leds_max = 5; + new_zone->leds_count = 5; + new_zone->matrix_map = NULL; + zones.push_back(*new_zone); + + /*---------------------------------------------------------*\ + | Set up LEDs | + \*---------------------------------------------------------*/ + for(std::size_t led_idx = 0; led_idx < zones[0].leds_count; led_idx++) + { + led *new_led = new led(); + + new_led->name = "Patriot Viper RGB LED "; + new_led->name.append(std::to_string(led_idx + 1)); + leds.push_back(*new_led); + } + + SetupColors(); +} + +void RGBController_PatriotViperSteel::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_PatriotViperSteel::DeviceUpdateLEDs() +{ + for(int led = 0; led < 5; led++) + { + RGBColor color = colors[led]; + unsigned char red = RGBGetRValue(color); + unsigned char grn = RGBGetGValue(color); + unsigned char blu = RGBGetBValue(color); + + controller->SetLEDColor(led, red, grn, blu); + } +} + +void RGBController_PatriotViperSteel::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_PatriotViperSteel::UpdateSingleLED(int led) +{ + RGBColor color = colors[led]; + unsigned char red = RGBGetRValue(color); + unsigned char grn = RGBGetGValue(color); + unsigned char blu = RGBGetBValue(color); + + controller->SetLEDColor(led, red, grn, blu); +} + +void RGBController_PatriotViperSteel::SetCustomMode() +{ +} + +void RGBController_PatriotViperSteel::DeviceUpdateMode() +{ +} diff --git a/Controllers/PatriotViperSteelController/RGBController_PatriotViperSteel.h b/Controllers/PatriotViperSteelController/RGBController_PatriotViperSteel.h new file mode 100644 index 00000000..bc254685 --- /dev/null +++ b/Controllers/PatriotViperSteelController/RGBController_PatriotViperSteel.h @@ -0,0 +1,32 @@ +/*---------------------------------------------*\ +| RGBController_PatriotViperSteel.h | +| | +| Generic RGB Interface for OpenRGB | +| Patriot Viper Steel RGB interface | +\*---------------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "PatriotViperSteelController.h" + +class RGBController_PatriotViperSteel : public RGBController +{ +public: + RGBController_PatriotViperSteel(PatriotViperSteelController *controller_ptr); + ~RGBController_PatriotViperSteel(); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void SetCustomMode(); + void DeviceUpdateMode(); + +private: + PatriotViperSteelController *controller; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index aecfbc04..ef386779 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -135,6 +135,7 @@ INCLUDEPATH += Controllers/NZXTKrakenController/ \ Controllers/OpenRazerController/ \ Controllers/PatriotViperController/ \ + Controllers/PatriotViperSteelController/ \ Controllers/PhilipsHueController/ \ Controllers/PhilipsWizController/ \ Controllers/PNYGPUController/ \ @@ -445,6 +446,8 @@ HEADERS += Controllers/OpenRazerController/OpenRazerDevices.h \ Controllers/PatriotViperController/PatriotViperController.h \ Controllers/PatriotViperController/RGBController_PatriotViper.h \ + Controllers/PatriotViperSteelController/PatriotViperSteelController.h \ + Controllers/PatriotViperSteelController/RGBController_PatriotViperSteel.h \ Controllers/PhilipsHueController/PhilipsHueController.h \ Controllers/PhilipsHueController/RGBController_PhilipsHue.h \ Controllers/PhilipsWizController/PhilipsWizController.h \ @@ -919,6 +922,9 @@ SOURCES += Controllers/PatriotViperController/PatriotViperController.cpp \ Controllers/PatriotViperController/PatriotViperControllerDetect.cpp \ Controllers/PatriotViperController/RGBController_PatriotViper.cpp \ + Controllers/PatriotViperSteelController/PatriotViperSteelController.cpp \ + Controllers/PatriotViperSteelController/PatriotViperSteelControllerDetect.cpp \ + Controllers/PatriotViperSteelController/RGBController_PatriotViperSteel.cpp \ Controllers/PhilipsHueController/PhilipsHueController.cpp \ Controllers/PhilipsHueController/PhilipsHueControllerDetect.cpp \ Controllers/PhilipsHueController/PhilipsHueEntertainmentController.cpp \