Publish LumaOps source

This commit is contained in:
LumaOps release export
2026-09-03 01:18:36 +02:00
commit 7f1c0e5f71
2363 changed files with 501543 additions and 0 deletions
@@ -0,0 +1,588 @@
/*---------------------------------------------------------*\
| ASRockPolychromeUSBController.cpp |
| |
| Driver for ASRock Polychrome USB motherboards |
| |
| Ed Kambulow (dredvard) 20 Dec 2020 |
| Shady Nawara (ShadyNawara) 16 Jan 2023 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <cstring>
#include "RGBController.h"
#include "ResourceManager.h"
#include "SettingsManager.h"
#include "StringUtils.h"
#include "ASRockPolychromeUSBController.h"
#include "dmiinfo.h"
#define POLYCHROME_USB_READ_ZONE_CONFIG 0x11
#define POLYCHROME_USB_READ_HEADER 0x14
#define POLYCHROME_USB_WRITE_HEADER 0x15
#define POLYCHROME_USB_SET_ZONE 0x10
#define POLYCHROME_USB_INITIAL_CHUNK 0xE3
#define POLYCHROME_USB_SEND_CHUNK 0xE4
#define POLYCHROME_USB_INIT 0xA4
#define POLYCHROME_USB_COMMIT 0x12
const char* polychrome_USB_zone_names[] =
{
"RGB LED 1 Header",
"RGB LED 2 Header",
"Addressable Header 1",
"Addressable Header 2",
"PCH",
"IO Cover",
"PCB",
"Addressable Header 3/Audio",
};
PolychromeUSBController::PolychromeUSBController(hid_device* dev_handle, const char* path)
{
DMIInfo dmi;
dev = dev_handle;
device_name = "ASRock " + dmi.getMainboard();
location = path;
SetDeviceInfo();
}
PolychromeUSBController::~PolychromeUSBController()
{
}
unsigned int PolychromeUSBController::GetChannelCount()
{
return((unsigned int)device_info.size());
}
std::string PolychromeUSBController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string PolychromeUSBController::GetDeviceName()
{
return(device_name);
}
std::string PolychromeUSBController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
return(StringUtils::wstring_to_string(serial_string));
}
void PolychromeUSBController::SetDeviceInfo()
{
PolychromeDeviceInfo newdev_info;
ReadConfigTables();
/*--------------------------------------------------*\
| Read settings to check for configured RGSwap |
\*--------------------------------------------------*/
const std::string detector_name = "ASRock Polychrome USB";
const std::string json_rgswap = "RGSwap";
SettingsManager* settings_manager = ResourceManager::get()->GetSettingsManager();
json device_settings = settings_manager->GetSettings(detector_name);
/*---------------------------------------------------------*\
| Get RGSwap settings from the settings manager |
| If RGSwap settings are not found then write them out |
| Onboard leds are set to their existing values, |
| Addressable RGB and RGB headers are set to false |
\*---------------------------------------------------------*/
if(!device_settings.contains(json_rgswap))
{
device_settings[json_rgswap][polychrome_USB_zone_names[0]] = false;
device_settings[json_rgswap][polychrome_USB_zone_names[1]] = false;
device_settings[json_rgswap][polychrome_USB_zone_names[2]] = false;
device_settings[json_rgswap][polychrome_USB_zone_names[3]] = false;
device_settings[json_rgswap][polychrome_USB_zone_names[4]] = ((configtable[8] >> 4) & 1) ? true : false;
device_settings[json_rgswap][polychrome_USB_zone_names[5]] = ((configtable[8] >> 5) & 1) ? true : false;
device_settings[json_rgswap][polychrome_USB_zone_names[6]] = ((configtable[8] >> 6) & 1) ? true : false;
device_settings[json_rgswap][polychrome_USB_zone_names[7]] = false;
settings_manager->SetSettings(detector_name, device_settings);
settings_manager->SaveSettings();
}
else
{
for(std::size_t idx = 0; idx < 8; idx++)
{
if(device_settings[json_rgswap].contains(polychrome_USB_zone_names[idx]))
{
rgswapconfig[idx] = device_settings[json_rgswap][polychrome_USB_zone_names[idx]];
}
}
}
bool rgswap_final[8] = {0};
for (unsigned int zonecnt = 0; zonecnt < POLYCHROME_USB_ZONE_MAX_NUM; zonecnt++)
{
if(configtable[zonecnt] == 0x1E || !((configtable[9] >> zonecnt) & 1))
{
/*-----------------------------------------------------------------------*\
| If we don't have this device type (0x1E) we will skip it and continue. |
| Or if the device is not available we skip it and continue |
\*-----------------------------------------------------------------------*/
continue;
}
newdev_info.num_leds = configtable[zonecnt];
newdev_info.rgswap = ((configtable[8] >> zonecnt) & 1) || rgswapconfig[zonecnt];
rgswap_final[zonecnt] = newdev_info.rgswap;
/*--------------------------------------------------------------------------------------------------*\
| We will need to know what zone type this is, so that we can look up the name and make calls later. |
\*--------------------------------------------------------------------------------------------------*/
newdev_info.zone_type = zonecnt;
switch (zonecnt)
{
/*-----------------------------------------*\
| Type: Addressable, configurable |
\*-----------------------------------------*/
case POLYCHROME_USB_ZONE_ARGB1:
case POLYCHROME_USB_ZONE_ARGB2:
/*---------------------------------------------*\
| The last led channel is allocated to a |
| third ARGB header on some newer motherboards |
\*---------------------------------------------*/
case POLYCHROME_USB_ZONE_AUDIO:
newdev_info.device_type = PolychromeDeviceType::ADDRESSABLE;
break;
/*-----------------------------------------*\
| Type: Addressable, not configurable |
\*-----------------------------------------*/
case POLYCHROME_USB_ZONE_PCH:
case POLYCHROME_USB_ZONE_IOCOVER:
case POLYCHROME_USB_ZONE_PCB:
newdev_info.device_type = PolychromeDeviceType::FIXED;
break;
/*-----------------------------------------*\
| Type: Fixed |
\*-----------------------------------------*/
case POLYCHROME_USB_ZONE_RGB1:
case POLYCHROME_USB_ZONE_RGB2:
default:
newdev_info.device_type = PolychromeDeviceType::FIXED;
break;
}
device_info.push_back(newdev_info);
}
// set rgswap to match our settings
WriteRGSwap(rgswap_final[0], rgswap_final[1], rgswap_final[2], rgswap_final[3], rgswap_final[4], rgswap_final[5], rgswap_final[6], rgswap_final[7]);
}
void PolychromeUSBController::ResizeZone(int zone, int new_size)
{
unsigned char zonecfg[POLYCHROME_USB_ZONE_MAX_NUM];
memset(zonecfg, POLYCHROME_USB_ZONE_UNAVAILABLE, POLYCHROME_USB_ZONE_MAX_NUM);
configtable[zone] = new_size;
for(unsigned int i = 0; i < POLYCHROME_USB_ZONE_MAX_NUM; i++)
{
zonecfg[i] = configtable[i];
}
unsigned char zonecmd = POLYCHROME_USB_LEDCOUNT_CFG;
WriteHeader(zonecmd, zonecfg, sizeof(zonecfg));
}
void PolychromeUSBController::WriteZone
(
unsigned char zone,
unsigned char mode,
unsigned char speed,
RGBColor rgb,
bool allzone = false
)
{
/*----------------------------------------------------*\
| Get the device info so we can look up the zone type. |
\*----------------------------------------------------*/
PolychromeDeviceInfo device_info = GetPolychromeDevices()[zone];
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet with leading 00 |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_SET_ZONE;
usb_buf[0x03] = device_info.zone_type;
usb_buf[0x04] = mode;
if(device_info.rgswap)
{
usb_buf[0x05] = RGBGetRValue(rgb);
usb_buf[0x06] = RGBGetGValue(rgb);
}
else
{
usb_buf[0x05] = RGBGetGValue(rgb);
usb_buf[0x06] = RGBGetRValue(rgb);
}
usb_buf[0x07] = RGBGetBValue(rgb);
usb_buf[0x08] = speed;
usb_buf[0x09] = 0xFF;
usb_buf[0x10] = allzone;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
};
void PolychromeUSBController::WriteAllZones
(
const std::vector<PolychromeZoneInfo>& /*zones_info*/,
const std::vector<zone>& zones
)
{
std::vector<unsigned char> combined_leds_rgb;
std::size_t max_led_count = 0;
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++){
PolychromeDeviceInfo device_info = GetPolychromeDevices()[zone_idx];
for(std::size_t led_idx = 0; led_idx < zones[zone_idx].leds_count; led_idx++)
{
if(device_info.rgswap)
{
combined_leds_rgb.push_back(RGBGetRValue(zones[zone_idx].colors[led_idx]));
combined_leds_rgb.push_back(RGBGetGValue(zones[zone_idx].colors[led_idx]));
}
else
{
combined_leds_rgb.push_back(RGBGetGValue(zones[zone_idx].colors[led_idx]));
combined_leds_rgb.push_back(RGBGetRValue(zones[zone_idx].colors[led_idx]));
}
combined_leds_rgb.push_back(RGBGetBValue(zones[zone_idx].colors[led_idx]));
}
max_led_count += zones[zone_idx].leds_max;
}
combined_leds_rgb.resize((max_led_count + 8) * 3, 0);
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up initial message packet with leading 00 |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_SET_ZONE;
usb_buf[0x03] = 0xFF;
usb_buf[0x04] = POLYCHROME_USB_INITIAL_CHUNK;
usb_buf[0x07] = 0xFF;
usb_buf[0x40] = 0x65;
std::size_t initial_led_offset = 9;
std::size_t message_byte_capacity = 54; // 18 leds * 3 bytes
std::size_t led_byte_idx = 0;
while(led_byte_idx < combined_leds_rgb.size())
{
for(std::size_t byte_idx = 0; byte_idx < message_byte_capacity; byte_idx++)
{
usb_buf[initial_led_offset + byte_idx] = combined_leds_rgb[led_byte_idx++];
if(led_byte_idx >= combined_leds_rgb.size())
{
break;
}
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet with leading 00 |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_SET_ZONE;
usb_buf[0x03] = 0xFF;
usb_buf[0x04] = POLYCHROME_USB_SEND_CHUNK;
usb_buf[0x40] = 0x65;
initial_led_offset = 5;
message_byte_capacity = 57; // 19 leds * 3 bytes
}
}
/*-----------------------------------------------------*\
| If reset is true, rgswap is set to the values |
| specified in the settings file, otherwise set to off |
\*-----------------------------------------------------*/
void PolychromeUSBController::SetRGSwap(bool reset)
{
if(reset)
{
bool rg[8] = {0};
std::vector<PolychromeDeviceInfo> devices_info = GetPolychromeDevices();
for (PolychromeDeviceInfo device : devices_info)
{
rg[device.zone_type] = device.rgswap;
}
WriteRGSwap(rg[0], rg[1], rg[2], rg[3], rg[4], rg[5], rg[6], rg[7]);
}
else
{
/*-----------------------------------------------------------------*\
| Disable RGSwap as it causes flashing on each update in direct mode|
\*-----------------------------------------------------------------*/
WriteRGSwap(0, 0, 0, 0, 0, 0, 0, 0);
}
}
void PolychromeUSBController::WriteRGSwap
(
bool hdr0,
bool hdr1,
bool ahdr0,
bool ahdr1,
bool pch,
bool io,
bool pcb,
bool chnl8
)
{
unsigned char rgconfig[1] = {static_cast<unsigned char>((((unsigned char)chnl8 << 7) | ((unsigned char)pcb << 6) | ((unsigned char)io << 5) | ((unsigned char)pch << 4) | ((unsigned char)ahdr1 << 3) | ((unsigned char)ahdr0 << 2) | ((unsigned char)hdr1 << 1) | (unsigned char)hdr0))};
WriteHeader(POLYCHROME_USB_RGSWAP_CFG, rgconfig, 1);
}
void PolychromeUSBController::WriteHeader
(
unsigned char cfg,
unsigned char* configstring,
unsigned int configsize
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet with leading 00 |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_WRITE_HEADER;
usb_buf[0x03] = cfg;
memcpy(&usb_buf[4], configstring, configsize);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
}
PolychromeZoneInfo PolychromeUSBController::GetZoneConfig(unsigned char zone)
{
/*-----------------------------------------------------*\
| Get the device info so we can look up the zone type |
\*-----------------------------------------------------*/
PolychromeDeviceInfo device_info = GetPolychromeDevices()[zone];
unsigned char usb_buf[65];
PolychromeZoneInfo zoneinfo;
unsigned char r;
unsigned char g;
unsigned char b;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_READ_ZONE_CONFIG;
usb_buf[0x03] = device_info.zone_type;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
/*-----------------------------------------------------*\
| Read response |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
hid_read(dev, usb_buf, 64);
r = usb_buf[0x05];
g = usb_buf[0x06];
b = usb_buf[0x07];
/*------------------------------------------------------*\
| Set Chroma mode (0xE2) & Per-Led mode (0xE3) as Direct |
\*------------------------------------------------------*/
zoneinfo.mode = usb_buf[0x04] != 0xE2 && usb_buf[0x04] != 0xE3 && usb_buf[0x04] < 0x0F ? usb_buf[0x04] : 0x0F;
/*------------------------------------------------------*\
| G & R are swapped since RGSwap is disabled on init, |
| Unless overwritten in settings |
\*------------------------------------------------------*/
if(device_info.rgswap)
{
zoneinfo.color = ToRGBColor(r,g,b);
}
else
{
zoneinfo.color = ToRGBColor(g,r,b);
}
zoneinfo.speed = usb_buf[0x08];
zoneinfo.zone = usb_buf[0x03];
return(zoneinfo);
}
void PolychromeUSBController::ReadConfigTables()
{
unsigned char usb_buf[65];
unsigned char maxzoneleds[8];
unsigned char rgswap;
unsigned char header1;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up max led config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_READ_HEADER;
usb_buf[0x03] = POLYCHROME_USB_LEDCOUNT_CFG;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
/*-----------------------------------------------------*\
| Read response |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
hid_read(dev, usb_buf, 64);
/*-----------------------------------------------------*\
| Reads in format: RGB1, RGB2, ARGB1, ARGB2, PCH, IO, |
| PCB, AUDIO/ARGB3 |
\*-----------------------------------------------------*/
memcpy(&maxzoneleds,&usb_buf[0x04],8);
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up RGB Swap table request packet |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_READ_HEADER;
usb_buf[0x03] = POLYCHROME_USB_RGSWAP_CFG;
hid_write(dev, usb_buf, 65);
memset(usb_buf, 0x00, sizeof(usb_buf));
hid_read(dev, usb_buf, 64);
/*-----------------------------------------------------*\
| Reads bitwise in format: AUDIO/ARGB3, PCB, IO, PCH, |
| ARGB2,ARGB1, RGB2, RGB1 if available |
\*-----------------------------------------------------*/
rgswap=usb_buf[4];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Header1 config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_READ_HEADER;
usb_buf[0x03] = 0x01;
hid_write(dev, usb_buf, 64);
memset(usb_buf, 0x00, sizeof(usb_buf));
hid_read(dev, usb_buf, 64);
/*-----------------------------------------------------*\
| Reads bitwise in format: AUDIO/ARGB3, PCB, IO, PCH, |
| ARGB2,ARGB1, RGB2, RGB1 if available |
\*-----------------------------------------------------*/
header1=usb_buf[4];
memcpy(configtable,&maxzoneleds,8);
configtable[8]=rgswap;
configtable[9]=header1;
return;
}
void PolychromeUSBController::Commit()
{
/*-----------------------------------------------------*\
| Saves all Writes in Device - Will keep after powerup |
\*-----------------------------------------------------*/
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet with leading 00 |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_COMMIT;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
};
const std::vector<PolychromeDeviceInfo>& PolychromeUSBController::GetPolychromeDevices() const
{
return(device_info);
};
@@ -0,0 +1,166 @@
/*---------------------------------------------------------*\
| ASRockPolychromeUSBController.h |
| |
| Driver for ASRock Polychrome USB motherboards |
| |
| Ed Kambulow (dredvard) 20 Dec 2020 |
| Shady Nawara (ShadyNawara) 16 Jan 2023 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <string>
#include <hidapi.h>
#include "RGBController.h"
/*----------------------------------------------------------------------------------------------*\
| Definitions for Polychrome USB |
\*----------------------------------------------------------------------------------------------*/
#define POLYCHROME_USB_NUM_MODES 16 /* Number of Polychrome USB modes */
enum
{
POLYCHROME_USB_MODE_OFF = 0x00, /* OFF mode */
POLYCHROME_USB_MODE_STATIC = 0x01, /* Static color mode */
POLYCHROME_USB_MODE_BREATHING = 0x02, /* Breathing effect mode */
POLYCHROME_USB_MODE_STROBE = 0x03, /* Strobe effect mode */
POLYCHROME_USB_MODE_SPECTRUM_CYCLE = 0x04, /* Spectrum Cycle effect mode */
POLYCHROME_USB_MODE_RANDOM = 0x05, /* Random effect mode */
POLYCHROME_USB_MODE_MUSIC = 0x06, /* Random effect mode */
POLYCHROME_USB_MODE_WAVE = 0x07, /* Wave effect mode */
POLYCHROME_USB_MODE_SPRING = 0x08, /* Spring effect mode */
POLYCHROME_USB_MODE_STACK = 0x09, /* Stack effect mode */
POLYCHROME_USB_MODE_CRAM = 0x0A, /* Cram effect mode */
POLYCHROME_USB_MODE_SCAN = 0x0B, /* Scan effect mode */
POLYCHROME_USB_MODE_NEON = 0x0C, /* Neon effect mode */
POLYCHROME_USB_MODE_WATER = 0x0D, /* Water effect mode */
POLYCHROME_USB_MODE_RAINBOW = 0x0E, /* Rainbow effect mode */
POLYCHROME_USB_MODE_DIRECT = 0x0F, /* CHROMA CONNECT effect mode */
};
enum
{
POLYCHROME_USB_SPEED_MIN = 0xFF, /* Slowest speed */
POLYCHROME_USB_SPEED_DEFAULT = 0xE0, /* Default speed */
POLYCHROME_USB_SPEED_MAX = 0x00, /* Fastest speed */
};
enum
{
POLYCHROME_USB_ZONE_MAX_NUM = 0x08, /* Total Max number of zones */
POLYCHROME_USB_ZONE_ADDRESSABLE_MAX = 0x64, /* Maxinum number of ARGB LEDs */
};
enum
{
POLYCHROME_USB_LEDCOUNT_CFG = 0x02, // Config for LED Count
POLYCHROME_USB_RGSWAP_CFG = 0x03, // Config for RGSWAP
POLYCHROME_USB_ZONE_UNAVAILABLE = 0x1E, // Value from LEDCOUNT CFG if zone not present
};
extern const char* polychrome_USB_zone_names[];
enum
{
POLYCHROME_USB_ZONE_RGB1 = 0x00, // RGB Header 1
POLYCHROME_USB_ZONE_RGB2 = 0X01, // RGB Header 2
POLYCHROME_USB_ZONE_ARGB1 = 0X02, // ARGB Header 1
POLYCHROME_USB_ZONE_ARGB2 = 0X03, // ARGB Header 2
POLYCHROME_USB_ZONE_PCH = 0X04, // PCH
POLYCHROME_USB_ZONE_IOCOVER = 0X05, // IOCOVER
POLYCHROME_USB_ZONE_PCB = 0X06, // PCB - Could be mixed swapped with 0x07
POLYCHROME_USB_ZONE_AUDIO = 0X07 // AUDIO/ARGB Header 3
};
enum class PolychromeDeviceType
{
FIXED,
ADDRESSABLE,
};
struct PolychromeZoneInfo
{
unsigned char mode;
unsigned char zone;
unsigned char speed;
RGBColor color;
};
struct PolychromeDeviceInfo
{
unsigned char effect_channel;
unsigned char num_leds;
unsigned char zone_type;
bool rgswap;
PolychromeDeviceType device_type;
};
class PolychromeUSBController
{
public:
unsigned char zone_led_count[8];
PolychromeUSBController(hid_device* dev_handle, const char* path);
~PolychromeUSBController();
unsigned int GetChannelCount();
std::string GetDeviceLocation();
std::string GetDeviceName();
const std::vector<PolychromeDeviceInfo>& GetPolychromeDevices() const;
std::string GetSerialString();
PolychromeZoneInfo GetZoneConfig (unsigned char zone);
void WriteZone
(
unsigned char zone,
unsigned char mode,
unsigned char speed,
RGBColor rgb,
bool allzone
);
void WriteAllZones
(
const std::vector<PolychromeZoneInfo> &zones_info,
const std::vector<zone> &zones
);
void WriteHeader
(
unsigned char cfg,
unsigned char* configstring,
unsigned int configsize
);
void ResizeZone(int zone, int new_size);
void SetRGSwap(bool reset);
protected:
hid_device* dev;
std::vector<PolychromeDeviceInfo> device_info;
std::string location;
void WriteRGSwap
(
bool hdr0,
bool hdr1,
bool ahdr0,
bool ahdr1,
bool pch,
bool io,
bool pcb,
bool chnl8
);
private:
std::string device_name;
unsigned char configtable[12];
bool rgswapconfig[8] = { 0 };
void SetDeviceInfo();
void ReadConfigTables();
void Commit();
};
@@ -0,0 +1,42 @@
/*---------------------------------------------------------*\
| ASRockPolychromeUSBControllerDetect.cpp |
| |
| Detector for ASRock Polychrome USB motherboards |
| |
| Ed Kambulow (dredvard) 20 Dec 2020 |
| Shady Nawara (ShadyNawara) 16 Jan 2023 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <hidapi.h>
#include "Detector.h"
#include "ASRockPolychromeUSBController.h"
#include "RGBController_ASRockPolychromeUSB.h"
/*---------------------------------------------------------*\
| ASRock vendor ID |
\*---------------------------------------------------------*/
#define ASROCK_VID 0x26CE
/*---------------------------------------------------------*\
| ASRock product ID |
\*---------------------------------------------------------*/
#define ASROCK_MOTHERBOARD_1_PID 0x01A2
#define ASROCK_DESKMINI_ADDRESSABLE_LED_STRIP_PID 0x01A6
void DetectPolychromeUSBControllers(hid_device_info* info, const std::string& /*name*/)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
PolychromeUSBController* controller = new PolychromeUSBController(dev, info->path);
RGBController_PolychromeUSB* rgb_controller = new RGBController_PolychromeUSB(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR("ASRock Polychrome USB", DetectPolychromeUSBControllers, ASROCK_VID, ASROCK_MOTHERBOARD_1_PID);
REGISTER_HID_DETECTOR("ASRock Deskmini Addressable LED Strip", DetectPolychromeUSBControllers, ASROCK_VID, ASROCK_DESKMINI_ADDRESSABLE_LED_STRIP_PID);
@@ -0,0 +1,361 @@
/*---------------------------------------------------------*\
| RGBController_ASRockPolychromeUSB.cpp |
| |
| RGBController for ASRock Polychrome USB motherboards |
| |
| Ed Kambulow (dredvard) 20 Dec 2020 |
| Shady Nawara (ShadyNawara) 16 Jan 2023 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <string.h>
#include "RGBController_ASRockPolychromeUSB.h"
#define ASROCK_USB_MAX_ZONES 8
#define ASROCK_ADDRESSABLE_MAX_LEDS 100
/**------------------------------------------------------------------*\
@name ASrock Polychrome USB
@category Motherboard
@type USB
@save :robot:
@direct :x:
@effects :white_check_mark:
@detectors DetectPolychromeUSBControllers
@comment ASRock Polychrome controllers will save with each update.
\*-------------------------------------------------------------------*/
RGBController_PolychromeUSB::RGBController_PolychromeUSB(PolychromeUSBController* controller_ptr)
{
controller = controller_ptr;
name = controller->GetDeviceName();
description = "ASRock Polychrome USB Device";
vendor = "ASRock";
type = DEVICE_TYPE_MOTHERBOARD;
location = controller->GetDeviceLocation();
mode Off;
Off.name = "Off";
Off.value = POLYCHROME_USB_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = POLYCHROME_USB_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = POLYCHROME_USB_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.speed_min = POLYCHROME_USB_SPEED_MIN;
Breathing.speed_max = POLYCHROME_USB_SPEED_MAX;
Breathing.speed = POLYCHROME_USB_SPEED_DEFAULT;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
mode Strobe;
Strobe.name = "Strobe";
Strobe.value = POLYCHROME_USB_MODE_STROBE;
Strobe.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Strobe.speed_min = POLYCHROME_USB_SPEED_MIN;
Strobe.speed_max = POLYCHROME_USB_SPEED_MAX;
Strobe.speed = POLYCHROME_USB_SPEED_DEFAULT;
Strobe.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Strobe);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = POLYCHROME_USB_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED;
SpectrumCycle.speed_min = POLYCHROME_USB_SPEED_MIN;
SpectrumCycle.speed_max = POLYCHROME_USB_SPEED_MAX;
SpectrumCycle.speed = POLYCHROME_USB_SPEED_DEFAULT;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
mode Random;
Random.name = "Random";
Random.value = POLYCHROME_USB_MODE_RANDOM;
Random.flags = MODE_FLAG_HAS_SPEED;
Random.speed_min = POLYCHROME_USB_SPEED_MIN;
Random.speed_max = POLYCHROME_USB_SPEED_MAX;
Random.speed = POLYCHROME_USB_SPEED_DEFAULT;
Random.color_mode = MODE_COLORS_NONE;
modes.push_back(Random);
mode Music;
Random.name = "Music";
Random.value = POLYCHROME_USB_MODE_RANDOM;
Random.flags = MODE_FLAG_HAS_BRIGHTNESS;
Random.color_mode = MODE_COLORS_NONE;
modes.push_back(Random);
mode Wave;
Wave.name = "Wave";
Wave.value = POLYCHROME_USB_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_SPEED;
Wave.speed_min = POLYCHROME_USB_SPEED_MIN;
Wave.speed_max = POLYCHROME_USB_SPEED_MAX;
Wave.speed = POLYCHROME_USB_SPEED_DEFAULT;
Wave.color_mode = MODE_COLORS_NONE;
modes.push_back(Wave);
mode Spring;
Spring.name = "Spring";
Spring.value = POLYCHROME_USB_MODE_SPRING;
Spring.flags = MODE_FLAG_HAS_SPEED;
Spring.speed_min = POLYCHROME_USB_SPEED_MIN;
Spring.speed_max = POLYCHROME_USB_SPEED_MAX;
Spring.speed = POLYCHROME_USB_SPEED_DEFAULT;
Spring.color_mode = MODE_COLORS_NONE;
modes.push_back(Spring);
mode Stack;
Stack.name = "Stack";
Stack.value = POLYCHROME_USB_MODE_STACK;
Stack.flags = MODE_FLAG_HAS_SPEED;
Stack.speed_min = POLYCHROME_USB_SPEED_MIN;
Stack.speed_max = POLYCHROME_USB_SPEED_MAX;
Stack.speed = POLYCHROME_USB_SPEED_DEFAULT;
Stack.color_mode = MODE_COLORS_NONE;
modes.push_back(Stack);
mode Cram;
Cram.name = "Cram";
Cram.value = POLYCHROME_USB_MODE_CRAM;
Cram.flags = MODE_FLAG_HAS_SPEED;
Cram.speed_min = POLYCHROME_USB_SPEED_MIN;
Cram.speed_max = POLYCHROME_USB_SPEED_MAX;
Cram.speed = POLYCHROME_USB_SPEED_DEFAULT;
Cram.color_mode = MODE_COLORS_NONE;
modes.push_back(Cram);
mode Scan;
Scan.name = "Scan";
Scan.value = POLYCHROME_USB_MODE_SCAN;
Scan.flags = MODE_FLAG_HAS_SPEED;
Scan.speed_min = POLYCHROME_USB_SPEED_MIN;
Scan.speed_max = POLYCHROME_USB_SPEED_MAX;
Scan.speed = POLYCHROME_USB_SPEED_DEFAULT;
Scan.color_mode = MODE_COLORS_NONE;
modes.push_back(Scan);
mode Neon;
Neon.name = "Neon";
Neon.value = POLYCHROME_USB_MODE_NEON;
Neon.flags = 0;
Neon.color_mode = MODE_COLORS_NONE;
modes.push_back(Neon);
mode Water;
Water.name = "Water";
Water.value = POLYCHROME_USB_MODE_WATER;
Water.flags = MODE_FLAG_HAS_SPEED;
Water.speed_min = POLYCHROME_USB_SPEED_MIN;
Water.speed_max = POLYCHROME_USB_SPEED_MAX;
Water.speed = POLYCHROME_USB_SPEED_DEFAULT;
Water.color_mode = MODE_COLORS_NONE;
modes.push_back(Water);
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = POLYCHROME_USB_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED;
Rainbow.speed_min = POLYCHROME_USB_SPEED_MIN;
Rainbow.speed_max = POLYCHROME_USB_SPEED_MAX;
Rainbow.speed = POLYCHROME_USB_SPEED_DEFAULT;
Rainbow.color_mode = MODE_COLORS_NONE;
modes.push_back(Rainbow);
mode Direct;
Direct.name = "Direct";
Direct.value = POLYCHROME_USB_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
SetupZones();
}
void RGBController_PolychromeUSB::SetupZones()
{
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
leds.clear();
colors.clear();
zones.resize(controller->GetChannelCount());
/*-------------------------------------------------*\
| Set zones and leds |
\*-------------------------------------------------*/
for(unsigned int channel_idx = 0; channel_idx < zones.size(); channel_idx++)
{
PolychromeDeviceInfo device_info = controller->GetPolychromeDevices()[channel_idx];
zones[channel_idx].type = ZONE_TYPE_LINEAR;
if(device_info.device_type== PolychromeDeviceType::ADDRESSABLE)
{
zones[channel_idx].name = polychrome_USB_zone_names[device_info.zone_type];
zones[channel_idx].leds_min = 0;
zones[channel_idx].leds_max = ASROCK_ADDRESSABLE_MAX_LEDS;
zones[channel_idx].leds_count = device_info.num_leds;
}
else if(device_info.device_type==PolychromeDeviceType::FIXED)
{
zones[channel_idx].name = polychrome_USB_zone_names[device_info.zone_type];
zones[channel_idx].leds_min = device_info.num_leds;
zones[channel_idx].leds_max = device_info.num_leds;
zones[channel_idx].leds_count = device_info.num_leds;
}
for(unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++)
{
led new_led;
new_led.name = zones[channel_idx].name;
new_led.name.append(", LED ");
new_led.name.append(std::to_string(led_ch_idx + 1));
new_led.value = channel_idx;
leds.push_back(new_led);
}
zones[channel_idx].matrix_map = NULL;
}
SetupColors();
/*---------------------------------------------------------*\
| Initialize zone info to track zone, speed, mode |
| B550 Boards have modes, speed for each zone |
\*---------------------------------------------------------*/
for (unsigned int channel_idx = 0; channel_idx < zones.size(); channel_idx++)
{
PolychromeZoneInfo zoneinfo;
zoneinfo = controller->GetZoneConfig(channel_idx);
zones_info.push_back(zoneinfo);
}
/*---------------------------------------------------------*\
| Initialize colors for each LED |
| We cannot currently get the individual led color so |
| we use the zone color in each zone to set all leds |
| !!TODO: in Per-Led mode, zone color is always black |
\*---------------------------------------------------------*/
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
unsigned char led = (unsigned char)leds[led_idx].value;
colors[led_idx] = zones_info[led].color;
}
/*-------------------------------------------------*\
| Initialize active mode |
\*-------------------------------------------------*/
active_mode = zones_info.size() > 1 ? zones_info[0].mode : 0x0;
/*-----------------------------------------------------*\
| If in Direct mode, reset all Leds to match interface |
\*-----------------------------------------------------*/
if(active_mode == 0x0F)
{
controller->WriteAllZones(zones_info, zones);
}
}
void RGBController_PolychromeUSB::ResizeZone(int zone, int new_size)
{
zones[zone].leds_count = (unsigned char) new_size;
controller->ResizeZone(zones_info[zone].zone, new_size);
}
void RGBController_PolychromeUSB::DeviceUpdateLEDs()
{
if(POLYCHROME_USB_MODE_DIRECT == zones_info[0].mode )
{
controller->WriteAllZones(zones_info,zones);
return;
}
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
unsigned char set_mode = zones_info[zone_idx].mode;
if (set_mode>modes.size())
{
set_mode = active_mode;
}
controller->WriteZone((unsigned char)zone_idx, set_mode, zones_info[zone_idx].speed, zones[zone_idx].colors[0], false);
}
}
void RGBController_PolychromeUSB::UpdateZoneLEDs(int zone)
{
unsigned char set_mode=zones_info[zone].mode;
if(set_mode > modes.size())
{
set_mode = active_mode;
}
controller->WriteZone(zone, set_mode, zones_info[zone].speed, zones[zone].colors[0], false);
}
void RGBController_PolychromeUSB::UpdateSingleLED(int led)
{
unsigned int channel = leds[led].value;
unsigned char set_mode = zones_info[channel].mode;
if(set_mode > modes.size())
{
set_mode = active_mode;
}
controller->WriteZone(channel, set_mode, zones_info[channel].speed, zones[channel].colors[0], false);
}
unsigned char RGBController_PolychromeUSB::GetDeviceMode(unsigned char zone)
{
int dev_mode;
dev_mode = controller->GetZoneConfig(zone).mode;
active_mode = dev_mode;
return(active_mode);
}
void RGBController_PolychromeUSB::DeviceUpdateMode()
{
/*-----------------------------------------------------------------*\
| Disable RGSwap as it causes flashing on each update in direct mode|
| Otherwise, reset to values specified in settings.json |
\*-----------------------------------------------------------------*/
controller->SetRGSwap(modes[active_mode].name != "Direct");
for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
if(zones[zone_idx].leds_count > 0)
{
unsigned char set_mode =(unsigned char) modes[active_mode].value;
zones_info[zone_idx].mode =(unsigned char) modes[active_mode].value;
zones_info[zone_idx].speed =(unsigned char) modes[active_mode].speed;
if(set_mode > modes.size())
{
set_mode = active_mode;
}
controller->WriteZone(zone_idx, set_mode, zones_info[zone_idx].speed, zones[zone_idx].colors[0], false);
}
}
}
@@ -0,0 +1,38 @@
/*---------------------------------------------------------*\
| RGBController_ASRockPolychromeUSB.h |
| |
| RGBController for ASRock Polychrome USB motherboards |
| |
| Ed Kambulow (dredvard) 20 Dec 2020 |
| Shady Nawara (ShadyNawara) 16 Jan 2023 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "ASRockPolychromeUSBController.h"
class RGBController_PolychromeUSB : public RGBController
{
public:
RGBController_PolychromeUSB(PolychromeUSBController* controller_ptr);
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
private:
PolychromeUSBController* controller;
std::vector<PolychromeZoneInfo> zones_info;
unsigned char GetDeviceMode(unsigned char zone);
};