Compare commits

..
Author SHA1 Message Date
Adam Honse 42df4c5026 Make i2c thread safe 2020-01-07 23:59:52 -06:00
337 changed files with 7221 additions and 44613 deletions
-8
View File
@@ -1,8 +0,0 @@
*.pro.user*
*.o
ui_*
moc_*
qrc_*
OpenRGB
Makefile
OpenRGB-x86_64.AppImage
-99
View File
@@ -1,99 +0,0 @@
# swy: some useful references; the MSVC part of the CI script is based on the one from bind9, by Michał Kępień:
# https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/gcp/windows-containers/blob/master/cookbooks/preinstalled-software/README.md
# https://gitlab.isc.org/isc-projects/bind9/commit/facc6a051fcac70fbbc61cb92a37be8c3e4db5ec#587d266bb27a4dc3022bbed44dfa19849df3044c_718_731
# https://www.kittell.net/code/powershell-unix-sed-equivalent-change-text-file/
# https://powershell.org/forums/topic/how-to-use-ansi-vt100-formatting-in-powershell-ooh-pretty-colors/
.shared_windows_runners:
tags:
- shared-windows
- windows
- windows-1809
stages:
- build
before_script:
- echo "started by ${GITLAB_USER_NAME}"
build_linux:
image: ubuntu:bionic
stage: build
script:
- apt update
- apt install -y build-essential qtcreator qt5-default libusb-1.0-0-dev libhidapi-dev pkgconf wget git
- ./scripts/build-appimage.sh
artifacts:
paths:
- OpenRGB-x86_64.AppImage
expire_in: 1337 years
build_windows:
extends:
- .shared_windows_runners
stage: build
script:
- $esc = "$([char]27)"
- $count = 0
- function _unix_tmsec_ { [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalSeconds }
- function _fold_start_ { param( [string]$TEXT_TAG ) $t=_unix_tmsec_; $global:count += 1; Write-Host -NoNewLine "`r`n`r`nsection_start:${t}:sect_${count}`r${esc}[0K${esc}[33m${TEXT_TAG}${esc}[39m`r`n"; }
- function _fold_final_ { $t=_unix_tmsec_; Write-Host -NoNewLine "`r`n`r`nsection_end:${t}:sect_${count}`r${esc}[0K`r`n" ; }
- _fold_start_ 'configuring the msvc environment variables'
- Push-Location "C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Auxiliary/Build"
- '& cmd.exe /C "vcvarsall.bat x64 & set" | Foreach-Object { if ($_ -match "(.*?)=(.*)") { Set-Item -force -path "Env:\$($matches[1])" -value "$($matches[2])" } }'
- Pop-Location
- _fold_final_
- _fold_start_ 'downloading precompiled versions of qtbase, qttools (for windeployqt) and jom (for a more parallel nmake)'
- mkdir _qt
- mkdir _qt_download
- Push-Location _qt_download
- curl.exe -LJ -o qt-base.7z 'https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win64_msvc2017_64/5.15.0-0-202002260536qtbase-Windows-Windows_10-MSVC2017-Windows-Windows_10-X86_64.7z'
- curl.exe -LJ -o qt-tools.7z 'https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win64_msvc2017_64/5.15.0-0-202002260536qttools-Windows-Windows_10-MSVC2017-Windows-Windows_10-X86_64.7z'
- curl.exe -LJ -o qt-jom.zip 'https://download.qt.io/official_releases/jom/jom.zip'
- _fold_final_
- _fold_start_ 'extracting the downloaded qt binaries'
- 7z x qt-base.7z '-o../_qt' -y
- 7z x qt-tools.7z '-o../_qt' -y
- 7z x qt-jom.zip '-o../_qt' -y
- _fold_final_
- _fold_start_ 'turn the qt install from enterprise to foss; remove the licensing checks'
- ${qconfig-pri-folder} = '..\_qt\5.15.0\msvc2017_64\mkspecs\qconfig.pri'
- (Get-Content ${qconfig-pri-folder}).replace('QT_EDITION = Enterprise', 'QT_EDITION = OpenSource') | Set-Content ${qconfig-pri-folder}
- (Get-Content ${qconfig-pri-folder}).replace('QT_LICHECK = licheck.exe', '') | Set-Content ${qconfig-pri-folder}
- Pop-Location
- _fold_final_
- _fold_start_ 'run qmake and generate the msvc nmake makefile'
- mkdir _build; cd _build
- ..\_qt\5.15.0\msvc2017_64\bin\qmake ..\OpenRGB.pro
- _fold_final_
- _fold_start_ 'start the actual build with jom instead of nmake; for speed'
- ..\_qt\jom
- _fold_final_
- _fold_start_ 'run windeployqt to automatically copy the needed dll files'
- ..\_qt\5.15.0\msvc2017_64\bin\windeployqt --no-angle --no-translations --no-opengl-sw --no-system-d3d-compiler --no-compiler-runtime --no-webkit2 .\release\
- _fold_final_
- _fold_start_ 'compressing the release folder so that we can upload it as artifact'
- mv release 'OpenRGB Windows 64-bit'
- ${datetime} = Get-Date ([datetime]::UtcNow) -Format "yyyy-MM-ddTHH-mm-ss"
- ${revision} = ((git rev-parse --short HEAD) | Out-String).Trim()
- ${rversion} = (((Get-Content '..\OpenRGB.pro' | Select-String -Pattern "VERSION =") | Out-String).Trim().Split("="))[1].Trim()
- 7z a -mx9 -r -y "OpenRGB_${rversion}_64_${revision}_nightly_${datetime}.7z" 'OpenRGB Windows 64-bit'
- _fold_final_
# cache:
# key: same-key
# paths:
# - C:\vcpkg\installed\
artifacts:
paths:
- _build/*.7z
expire_in: 1337 years
+3 -3
View File
@@ -1,3 +1,3 @@
[submodule "razer-drivers-win32"]
path = razer-drivers-win32
url = https://github.com/rsandoz/razer-drivers-win32
[submodule "dependencies/libe131"]
path = dependencies/libe131
url = https://github.com/CalcProgrammer1/libe131
-216
View File
@@ -1,216 +0,0 @@
#---------------------------------------------------------------#
# OpenRGB udev rules #
# #
# Adam Honse (CalcProgrammer1) 5/29/2020 #
#---------------------------------------------------------------#
#---------------------------------------------------------------#
# User I2C/SMBus Access #
#---------------------------------------------------------------#
KERNEL=="i2c-[0-99]*", TAG+="uaccess"
#---------------------------------------------------------------#
# User hidraw Access #
#---------------------------------------------------------------#
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", TAG+="uaccess"
#---------------------------------------------------------------#
# AMD Wraith Prism #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0051", TAG+="uaccess"
#---------------------------------------------------------------#
# ASUS Aura Core Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1854", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1869", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1866", TAG+="uaccess"
#---------------------------------------------------------------#
# ASUS Aura USB Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1867", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1872", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1889", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18a3", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18f3", TAG+="uaccess"
#---------------------------------------------------------------#
# Cooler Master Peripheral Devices #
# #
# Mousemats: #
# Cooler Master MP750 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0109", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Lighting Node Devices #
# #
# Corsair Lighting Node Core #
# Corsair Lighting Node Pro #
# Corsair Commander Pro #
# Corsair LS100 #
# Corsair 1000D Obsidian #
# Corsair Spec Omega RGB #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c1a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c0b", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c10", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c1e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1d00", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1d04", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Peripheral Devices #
# #
# Keyboards: #
# Corsair K55 RGB #
# Corsair K65 RGB #
# Corsair K65 RGB Lux #
# Corsair K65 RGB Rapidfire #
# Corsair K68 RGB #
# Corsair K70 RGB #
# Corsair K70 RGB Lux #
# Corsair K70 RGB Rapidfire #
# Corsair K70 RGB MK2 #
# Corsair K70 RGB MK2 SE #
# Corsair K70 RGB MK2 LP #
# Corsair K95 RGB #
# Corsair K95 Platinum #
# Corsair Strafe #
# Corsair Strafe MK2 #
# #
# Mice: #
# Corsair M65 Pro #
# Corsair M65 RGB Elite #
# #
# Mousemats: #
# Corsair MM800 RGB Polaris #
# #
# Headset Stands: #
# Corsair ST100 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3d", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b17", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b37", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b39", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b4f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b13", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b33", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b38", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b49", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b6b", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b55", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b11", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2d", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b20", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b48", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b5a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3b", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0a34", TAG+="uaccess"
#---------------------------------------------------------------#
# HyperX Peripheral Devices #
# #
# Keyboards: #
# HyperX Alloy Elite #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16be", TAG+="uaccess"
#---------------------------------------------------------------#
# Logitech Peripheral Devices #
# #
# Mice: #
# Logitech G203 Prodigy #
# Logitech G403 Prodigy #
# Logitech G403 Hero #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c084", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c083", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08f", TAG+="uaccess"
#---------------------------------------------------------------#
# MSI/SteelSeries 3-Zone Laptop Keyboard #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1770", ATTR{idProduct}=="FF00", TAG+="uaccess"
#---------------------------------------------------------------#
# NZXT Hue 2 Devices #
# #
# NZXT Hue 2 #
# NZXT Smart Device V2 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2001", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2006", TAG+="uaccess"
#---------------------------------------------------------------#
# NZXT Kraken #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="170e", TAG+="uaccess"
#---------------------------------------------------------------#
# Redragon Peripheral Devices #
# #
# Keyboards: #
# Redragon K550 Yama #
# Redragon K552 Kumara #
# Redragon K556 Devarajas #
# Tecware Phantom Elite #
# #
# Mice: #
# Redragon M711 Cobra #
# Redragon M715 Dagger #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="5204", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="5104", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="5004", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="652f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc30", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc39", TAG+="uaccess"
#---------------------------------------------------------------#
# Gigabyte/Aorus RGB Fusion 2 USB #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="048d", ATTR{idProduct}=="8297", TAG+="uaccess"
#---------------------------------------------------------------#
# SteelSeries Peripheral Devices #
# #
# Mice: #
# SteelSeries Rival 100 #
# SteelSeries Rival 100 DotA 2 Edition #
# SteelSeries Rival 105 #
# SteelSeries Rival 110 #
# SteelSeries Rival 300 #
# Acer Predator Gaming Mouse (Rival 300) #
# SteelSeries Rival 300 CS:GO Fade Edition #
# SteelSeries Rival 300 CS:GO Fade Edition (stm32) #
# SteelSeries Rival 300 CS:GO Hyperbeast Edition #
# SteelSeries Rival 300 Dota 2 Edition #
# SteelSeries Rival 300 HP Omen Edition #
# Headsets: #
# SteelSeries Siberia 350 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1702", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="170c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1814", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1729", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1384", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1714", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1394", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1716", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="171a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1392", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1718", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1229", TAG+="uaccess"
#---------------------------------------------------------------#
# Thermaltake Poseidon Z RGB Keyboard #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="3006", TAG+="uaccess"
@@ -12,25 +12,15 @@
#include <stdio.h>
#include <stdlib.h>
AMDWraithPrismController::AMDWraithPrismController(hid_device* dev_handle)
AMDWraithPrismController::AMDWraithPrismController(libusb_device_handle* dev_handle)
{
dev = dev_handle;
strcpy(device_name, "AMD Wraith Prism");
current_fan_mode = AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC;
current_fan_speed = 0xFF;
current_fan_random_color = false;
current_logo_mode = AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC;
current_logo_speed = 0xFF;
current_logo_random_color = false;
current_ring_mode = AMD_WRAITH_PRISM_EFFECT_CHANNEL_STATIC;
current_ring_speed = 0xFF;
current_ring_direction = false;
SendEnableCommand();
SetRingEffectChannel(0x00);
SendApplyCommand();
}
AMDWraithPrismController::~AMDWraithPrismController()
@@ -67,10 +57,12 @@ std::string AMDWraithPrismController::GetEffectChannelString(unsigned char chann
0x00, 0x00, 0x00, 0x00,
};
int actual;
usb_buf[0x02] = channel;
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
ret_string.append((char *)&usb_buf[0x08]);
@@ -101,10 +93,11 @@ std::string AMDWraithPrismController::GetFirmwareVersionString()
0x00, 0x00, 0x00, 0x00,
};
int actual;
unsigned char fw_buf[16] = {0x00};
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
for(int char_idx = 0; char_idx < 16; char_idx+=2)
{
@@ -123,83 +116,133 @@ std::string AMDWraithPrismController::GetFirmwareVersionString()
return(ret_string);
}
void AMDWraithPrismController::SetFanMode(unsigned char mode, unsigned char speed, bool random_color)
{
current_fan_mode = mode;
current_fan_speed = speed_values_fan_logo[mode][speed];
current_fan_random_color = random_color;
}
void AMDWraithPrismController::SetFanColor(unsigned char red, unsigned char green, unsigned char blue)
{
SendEffectChannelUpdate
(
AMD_WRAITH_PRISM_EFFECT_CHANNEL_FAN_LED,
current_fan_speed,
false,
current_fan_random_color,
current_fan_mode,
max_brightness_fan_logo[current_fan_mode],
red,
green,
blue
);
}
unsigned char usb_buf[] =
{
0x51, 0x2C, 0x01, 0x00,
0x06, 0xFF, 0x00, 0x01,
0xFF, 0xFF, 0x00, 0xFF,
0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF
};
void AMDWraithPrismController::SetLogoMode(unsigned char mode, unsigned char speed, bool random_color)
{
current_logo_mode = mode;
current_logo_speed = speed_values_fan_logo[mode][speed];
current_logo_random_color = random_color;
int actual;
usb_buf[0x0A] = red;
usb_buf[0x0B] = green;
usb_buf[0x0C] = blue;
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
}
void AMDWraithPrismController::SetLogoColor(unsigned char red, unsigned char green, unsigned char blue)
{
SendEffectChannelUpdate
(
AMD_WRAITH_PRISM_EFFECT_CHANNEL_LOGO_LED,
current_logo_speed,
false,
current_logo_random_color,
current_logo_mode,
max_brightness_fan_logo[current_logo_mode],
red,
green,
blue
);
}
unsigned char usb_buf[] =
{
0x51, 0x2C, 0x01, 0x00,
0x05, 0xFF, 0x00, 0x01,
0xFF, 0xFF, 0x00, 0xFF,
0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF
};
void AMDWraithPrismController::SetRingMode(unsigned char mode, unsigned char speed, bool direction, bool random_color)
{
current_ring_mode = mode;
current_ring_speed = speed_values_ring[mode][speed];
current_ring_direction = direction;
current_ring_random_color = random_color;
int actual;
usb_buf[0x0A] = red;
usb_buf[0x0B] = green;
usb_buf[0x0C] = blue;
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
}
void AMDWraithPrismController::SetRingColor(unsigned char red, unsigned char green, unsigned char blue)
{
SetRingEffectChannel(current_ring_mode);
unsigned char usb_buf[] =
{
0x51, 0x2C, 0x01, 0x00,
0x00, 0xFF, 0x00, 0xFF,
0xFF, 0xFF, 0x00, 0xFF,
0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF
};
SendEffectChannelUpdate
(
current_ring_mode,
current_ring_speed,
current_ring_direction,
current_ring_random_color,
mode_value_ring[current_ring_mode],
max_brightness_ring[current_ring_mode],
red,
green,
blue
);
int actual;
SendApplyCommand();
usb_buf[0x0A] = red;
usb_buf[0x0B] = green;
usb_buf[0x0C] = blue;
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
}
void AMDWraithPrismController::SetRingEffectChannel(unsigned char channel)
{
SendChannelRemap(channel, AMD_WRAITH_PRISM_EFFECT_CHANNEL_LOGO_LED, AMD_WRAITH_PRISM_EFFECT_CHANNEL_FAN_LED);
unsigned char usb_buf[] =
{
0x51, 0xA0, 0x01, 0x00,
0x00, 0x03, 0x00, 0x00,
0x05, 0x06, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07,
0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
int actual;
for(int led = 0x0A; led <= 0x18; led++)
{
usb_buf[led] = channel;
}
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
}
void AMDWraithPrismController::SendEnableCommand()
@@ -224,8 +267,10 @@ void AMDWraithPrismController::SendEnableCommand()
0x00, 0x00, 0x00, 0x00,
};
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
int actual;
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
}
void AMDWraithPrismController::SendApplyCommand()
@@ -250,22 +295,13 @@ void AMDWraithPrismController::SendApplyCommand()
0x00, 0x00, 0x00, 0x00,
};
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
int actual;
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
}
void AMDWraithPrismController::SendEffectChannelUpdate
(
unsigned char effect_channel,
unsigned char speed,
bool direction,
bool random_color,
unsigned char mode,
unsigned char brightness,
unsigned char red,
unsigned char green,
unsigned char blue
)
void AMDWraithPrismController::SendEffectCommand()
{
unsigned char usb_buf[] =
{
@@ -287,51 +323,8 @@ void AMDWraithPrismController::SendEffectChannelUpdate
0xFF, 0xFF, 0xFF, 0xFF
};
usb_buf[0x04] = effect_channel;
usb_buf[0x05] = speed;
usb_buf[0x06] = (direction ? 0x01 : 0x00) | (random_color ? 0x80 : 0x00);
usb_buf[0x07] = mode;
int actual;
usb_buf[0x09] = brightness;
usb_buf[0x0A] = red;
usb_buf[0x0B] = green;
usb_buf[0x0C] = blue;
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
}
void AMDWraithPrismController::SendChannelRemap(unsigned char ring_channel, unsigned char logo_channel, unsigned char fan_channel)
{
unsigned char usb_buf[] =
{
0x51, 0xA0, 0x01, 0x00,
0x00, 0x03, 0x00, 0x00,
0x05, 0x06, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07,
0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
usb_buf[0x08] = logo_channel;
usb_buf[0x09] = fan_channel;
for(int led = 0x0A; led <= 0x18; led++)
{
usb_buf[led] = ring_channel;
}
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
}
@@ -8,108 +8,14 @@
\*-----------------------------------------*/
#include <string>
#include <hidapi/hidapi.h>
#include <libusb-1.0/libusb.h>
#pragma once
static const unsigned char max_brightness_fan_logo[] =
{
0x00,
0xFF,
0x7F,
0xFF
};
static const unsigned char speed_values_fan_logo[][5] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, /* Static */
{ 0x96, 0x8C, 0x80, 0x6E, 0x68 }, /* Color Cycle */
{ 0x3C, 0x37, 0x31, 0x2C, 0x26 }, /* Breathing */
};
static const unsigned char max_brightness_ring[] =
{
0xFF,
0xFF,
0x7F,
0x00,
0x00,
0x00,
0x00,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF
};
static const unsigned char mode_value_ring[] =
{
0xFF,
0x03,
0xFF,
0x00,
0x00,
0x00,
0x00,
0x05,
0xFF,
0xC3,
0x4A,
0x05
};
static const unsigned char speed_values_ring[][5] =
{
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, /* Static */
{ 0x3C, 0x37, 0x31, 0x2C, 0x26 }, /* Breathing */
{ 0x96, 0x8C, 0x80, 0x6E, 0x68 }, /* Color Cycle */
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
{ 0x72, 0x68, 0x64, 0x62, 0x61 }, /* Rainbow */
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Bounce */
{ 0x77, 0x74, 0x6E, 0x6B, 0x67 }, /* Chase */
{ 0x77, 0x74, 0x6E, 0x6B, 0x67 }, /* Swirl */
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Morse Code */
};
enum
{
AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC = 0x01, /* Fan/Logo Static Mode */
AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE = 0x02, /* Fan/Logo Color Cycle Mode */
AMD_WRAITH_PRISM_FAN_LOGO_MODE_BREATHING = 0x03, /* Fan/Logo Breathing Mode */
};
enum
{
AMD_WRAITH_PRISM_EFFECT_CHANNEL_STATIC = 0x00, /* Static effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_BREATHING = 0x01, /* Breathing effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_COLOR_CYCLE = 0x02, /* Color cycle effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_LOGO_LED = 0x05, /* Logo LED effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_FAN_LED = 0x06, /* Fan LED effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_RAINBOW = 0x07, /* Rainbow effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_BOUNCE = 0x08, /* Bounce effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_CHASE = 0x09, /* Chase effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_SWIRL = 0x0A, /* Swirl effect channel */
AMD_WRAITH_PRISM_EFFECT_CHANNEL_MORSE = 0x0B, /* Morse code effect channel */
};
enum
{
AMD_WRAITH_PRISM_SPEED_SLOWEST = 0x00, /* Slowest speed */
AMD_WRAITH_PRISM_SPEED_SLOW = 0x01, /* Slow speed */
AMD_WRAITH_PRISM_SPEED_NORMAL = 0x02, /* Normal speed */
AMD_WRAITH_PRISM_SPEED_FAST = 0x03, /* Fast speed */
AMD_WRAITH_PRISM_SPEED_FASTEST = 0x04, /* Fastest speed */
};
class AMDWraithPrismController
{
public:
AMDWraithPrismController(hid_device* dev_handle);
AMDWraithPrismController(libusb_device_handle* dev_handle);
~AMDWraithPrismController();
char* GetDeviceName();
@@ -119,48 +25,15 @@ public:
void SetRingEffectChannel(unsigned char channel);
void SetFanMode(unsigned char mode, unsigned char speed, bool random_color);
void SetFanColor(unsigned char red, unsigned char green, unsigned char blue);
void SetLogoMode(unsigned char mode, unsigned char speed, bool random_color);
void SetLogoColor(unsigned char red, unsigned char green, unsigned char blue);
void SetRingMode(unsigned char mode, unsigned char speed, bool direction, bool random_color);
void SetRingColor(unsigned char red, unsigned char green, unsigned char blue);
void SendEnableCommand();
void SendApplyCommand();
void SendEffectCommand();
private:
char device_name[32];
hid_device* dev;
unsigned char current_fan_mode;
unsigned char current_fan_speed;
bool current_fan_random_color;
unsigned char current_logo_mode;
unsigned char current_logo_speed;
bool current_logo_random_color;
unsigned char current_ring_mode;
unsigned char current_ring_speed;
bool current_ring_direction;
bool current_ring_random_color;
void SendEnableCommand();
void SendApplyCommand();
void SendEffectChannelUpdate
(
unsigned char effect_channel,
unsigned char speed,
bool direction,
bool random_color,
unsigned char mode,
unsigned char brightness,
unsigned char red,
unsigned char green,
unsigned char blue
);
void SendChannelRemap(unsigned char ring_channel, unsigned char logo_channel, unsigned char fan_channel);
libusb_device_handle* dev;
};
@@ -2,7 +2,8 @@
#include "RGBController.h"
#include "RGBController_AMDWraithPrism.h"
#include <vector>
#include <hidapi/hidapi.h>
#include <libusb-1.0/libusb.h>
#define AMD_WRAITH_PRISM_VID 0x2516
#define AMD_WRAITH_PRISM_PID 0x0051
@@ -16,31 +17,17 @@
void DetectAMDWraithPrismControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device_info* info;
hid_device* dev = NULL;
hid_init();
info = hid_enumerate(AMD_WRAITH_PRISM_VID, AMD_WRAITH_PRISM_PID);
libusb_context * ctx;
libusb_init(&ctx);
//Look for AMD Wraith Prism
while(info)
{
if((info->vendor_id == AMD_WRAITH_PRISM_VID)
&&(info->product_id == AMD_WRAITH_PRISM_PID)
&&(info->interface_number == 1))
{
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
libusb_device_handle * dev = libusb_open_device_with_vid_pid(ctx, AMD_WRAITH_PRISM_VID, AMD_WRAITH_PRISM_PID);
if( dev )
{
libusb_detach_kernel_driver(dev, 1);
libusb_claim_interface(dev, 1);
AMDWraithPrismController* controller = new AMDWraithPrismController(dev);
RGBController_AMDWraithPrism* rgb_controller = new RGBController_AMDWraithPrism(controller);
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| AuraSMBusController.cpp |
| AuraController.cpp |
| |
| Driver for ASUS Aura RGB lighting |
| controller |
@@ -7,10 +7,10 @@
| Adam Honse (CalcProgrammer1) 8/19/2018 |
\*-----------------------------------------*/
#include "AuraSMBusController.h"
#include "AuraController.h"
#include <cstring>
AuraSMBusController::AuraSMBusController(i2c_smbus_interface* bus, aura_dev_id dev)
AuraController::AuraController(i2c_smbus_interface* bus, aura_dev_id dev)
{
this->bus = bus;
this->dev = dev;
@@ -77,17 +77,17 @@ AuraSMBusController::AuraSMBusController(i2c_smbus_interface* bus, aura_dev_id d
}
}
AuraSMBusController::~AuraSMBusController()
AuraController::~AuraController()
{
}
std::string AuraSMBusController::GetDeviceName()
std::string AuraController::GetDeviceName()
{
return(device_name);
}
std::string AuraSMBusController::GetDeviceLocation()
std::string AuraController::GetDeviceLocation()
{
std::string return_string(bus->device_name);
char addr[5];
@@ -97,12 +97,12 @@ std::string AuraSMBusController::GetDeviceLocation()
return(return_string);
}
unsigned char AuraSMBusController::GetChannel(unsigned int led)
unsigned char AuraController::GetChannel(unsigned int led)
{
return(config_table[channel_cfg + led]);
}
const char * AuraSMBusController::GetChannelName(unsigned int led)
const char * AuraController::GetChannelName(unsigned int led)
{
switch (config_table[channel_cfg + led])
{
@@ -152,27 +152,27 @@ const char * AuraSMBusController::GetChannelName(unsigned int led)
}
}
unsigned int AuraSMBusController::GetLEDCount()
unsigned int AuraController::GetLEDCount()
{
return(led_count);
}
unsigned char AuraSMBusController::GetLEDRed(unsigned int led)
unsigned char AuraController::GetLEDRed(unsigned int led)
{
return(AuraRegisterRead(direct_reg + ( 3 * led )));
}
unsigned char AuraSMBusController::GetLEDGreen(unsigned int led)
unsigned char AuraController::GetLEDGreen(unsigned int led)
{
return(AuraRegisterRead(direct_reg + ( 3 * led ) + 2));
}
unsigned char AuraSMBusController::GetLEDBlue(unsigned int led)
unsigned char AuraController::GetLEDBlue(unsigned int led)
{
return(AuraRegisterRead(direct_reg + ( 3 * led ) + 1));
}
void AuraSMBusController::SetAllColorsDirect(unsigned char red, unsigned char green, unsigned char blue)
void AuraController::SetAllColorsDirect(unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char* colors = new unsigned char[led_count * 3];
@@ -188,7 +188,7 @@ void AuraSMBusController::SetAllColorsDirect(unsigned char red, unsigned char gr
delete colors;
}
void AuraSMBusController::SetAllColorsEffect(unsigned char red, unsigned char green, unsigned char blue)
void AuraController::SetAllColorsEffect(unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char* colors = new unsigned char[led_count * 3];
@@ -206,20 +206,20 @@ void AuraSMBusController::SetAllColorsEffect(unsigned char red, unsigned char gr
delete[] colors;
}
void AuraSMBusController::SetDirect(unsigned char direct)
void AuraController::SetDirect(unsigned char direct)
{
AuraRegisterWrite(AURA_REG_DIRECT, direct);
AuraRegisterWrite(AURA_REG_APPLY, AURA_APPLY_VAL);
}
void AuraSMBusController::SetLEDColorDirect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
void AuraController::SetLEDColorDirect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char colors[3] = { red, blue, green };
AuraRegisterWriteBlock(direct_reg + ( 3 * led ), colors, 3);
}
void AuraSMBusController::SetLEDColorEffect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
void AuraController::SetLEDColorEffect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char colors[3] = { red, blue, green };
@@ -228,13 +228,13 @@ void AuraSMBusController::SetLEDColorEffect(unsigned int led, unsigned char red,
AuraRegisterWrite(AURA_REG_APPLY, AURA_APPLY_VAL);
}
void AuraSMBusController::SetMode(unsigned char mode)
void AuraController::SetMode(unsigned char mode)
{
AuraRegisterWrite(AURA_REG_MODE, mode);
AuraRegisterWrite(AURA_REG_APPLY, AURA_APPLY_VAL);
}
void AuraSMBusController::AuraUpdateDeviceName()
void AuraController::AuraUpdateDeviceName()
{
for (int i = 0; i < 16; i++)
{
@@ -242,32 +242,47 @@ void AuraSMBusController::AuraUpdateDeviceName()
}
}
unsigned char AuraSMBusController::AuraRegisterRead(aura_register reg)
unsigned char AuraController::AuraRegisterRead(aura_register reg)
{
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
//Write Aura register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
//Read Aura value
return(bus->i2c_smbus_read_byte_data(dev, 0x81));
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void AuraSMBusController::AuraRegisterWrite(aura_register reg, unsigned char val)
void AuraController::AuraRegisterWrite(aura_register reg, unsigned char val)
{
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
//Write Aura register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
//Write Aura value
bus->i2c_smbus_write_byte_data(dev, 0x01, val);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void AuraSMBusController::AuraRegisterWriteBlock(aura_register reg, unsigned char * data, unsigned char sz)
void AuraController::AuraRegisterWriteBlock(aura_register reg, unsigned char * data, unsigned char sz)
{
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
//Write Aura register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
//Write Aura block data
bus->i2c_smbus_write_block_data(dev, 0x03, sz, data);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| AuraSMBusController.h |
| AuraController.h |
| |
| Definitions and types for ASUS Aura RGB |
| lighting controller |
@@ -88,11 +88,11 @@ enum
AURA_CONFIG_CHANNEL_V2 = 0x1B, /* LED Channel V2 configuration offset */
};
class AuraSMBusController
class AuraController
{
public:
AuraSMBusController(i2c_smbus_interface* bus, aura_dev_id dev);
~AuraSMBusController();
AuraController(i2c_smbus_interface* bus, aura_dev_id dev);
~AuraController();
std::string GetDeviceName();
std::string GetDeviceLocation();
@@ -1,23 +1,31 @@
#include "AuraSMBusController.h"
#include "AuraController.h"
#include "RGBController.h"
#include "RGBController_AuraSMBus.h"
#include "RGBController_Aura.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std::chrono_literals;
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
/*----------------------------------------------------------------------*\
| This list contains the available SMBus addresses for mapping Aura RAM |
\*----------------------------------------------------------------------*/
#define AURA_RAM_ADDRESS_COUNT 22
#define AURA_RAM_ADDRESS_COUNT 17
static const unsigned char aura_ram_addresses[] =
{
0x70,
0x71,
0x72,
0x73,
0x74,
0x75,
@@ -32,32 +40,29 @@ static const unsigned char aura_ram_addresses[] =
0x7F,
0x4F,
0x66,
0x67,
0x39,
0x3B,
0x3C,
0x3D
0x67
};
/*---------------------------------------------------------------------------------*\
| This list contains the available SMBus addresses for mapping Aura motherboards |
\*---------------------------------------------------------------------------------*/
#define AURA_MOBO_ADDRESS_COUNT 3
#define AURA_MOBO_ADDRESS_COUNT 4
static const unsigned char aura_mobo_addresses[] =
{
0x40,
0x4E,
0x4F
0x4F,
0x66
};
/******************************************************************************************\
* *
* AuraRegisterWrite *
* *
* A standalone version of the AuraSMBusController::AuraRegisterWrite function for *
* access to Aura devices without instancing the AuraSMBusController class or reading *
* the config table from the device. *
* A standalone version of the AuraController::AuraRegisterWrite function for access *
* to Aura devices without instancing the AuraController class or reading the config *
* table from the device. *
* *
\******************************************************************************************/
@@ -72,7 +77,7 @@ void AuraRegisterWrite(i2c_smbus_interface* bus, aura_dev_id dev, aura_register
/******************************************************************************************\
* *
* TestForAuraSMBusController *
* TestForAuraController *
* *
* Tests the given address to see if an Aura controller exists there. First does a *
* quick write to test for a response, and if so does a simple read at 0xA0 to test *
@@ -80,7 +85,7 @@ void AuraRegisterWrite(i2c_smbus_interface* bus, aura_dev_id dev, aura_register
* *
\******************************************************************************************/
bool TestForAuraSMBusController(i2c_smbus_interface* bus, unsigned char address)
bool TestForAuraController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
@@ -103,11 +108,11 @@ bool TestForAuraSMBusController(i2c_smbus_interface* bus, unsigned char address)
return(pass);
} /* TestForAuraSMBusController() */
} /* TestForAuraController() */
/******************************************************************************************\
* *
* DetectAuraSMBusControllers *
* DetectAuraControllers *
* *
* Detect Aura controllers on the enumerated I2C busses. Searches for Aura-enabled *
* RAM at 0x77 and tries to initialize their slot addresses, then searches for them *
@@ -119,14 +124,14 @@ bool TestForAuraSMBusController(i2c_smbus_interface* bus, unsigned char address)
* *
\******************************************************************************************/
void DetectAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
void DetectAuraControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
AuraSMBusController* new_aura;
RGBController_AuraSMBus* new_controller;
AuraController* new_aura;
RGBController_Aura* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
int address_list_idx = -1;
int address_list_idx = 0;
// Remap Aura-enabled RAM modules on 0x77
for (unsigned int slot = 0; slot < 8; slot++)
@@ -140,11 +145,10 @@ void DetectAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses, std::
do
{
address_list_idx++;
if(address_list_idx < AURA_RAM_ADDRESS_COUNT)
{
res = busses[bus]->i2c_smbus_write_quick(aura_ram_addresses[address_list_idx], I2C_SMBUS_WRITE);
address_list_idx++;
}
else
{
@@ -152,38 +156,35 @@ void DetectAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses, std::
}
} while (res >= 0);
if(address_list_idx < AURA_RAM_ADDRESS_COUNT)
{
AuraRegisterWrite(busses[bus], 0x77, AURA_REG_SLOT_INDEX, slot);
AuraRegisterWrite(busses[bus], 0x77, AURA_REG_I2C_ADDRESS, (aura_ram_addresses[address_list_idx] << 1));
}
AuraRegisterWrite(busses[bus], 0x77, AURA_REG_SLOT_INDEX, slot);
AuraRegisterWrite(busses[bus], 0x77, AURA_REG_I2C_ADDRESS, (aura_ram_addresses[address_list_idx] << 1));
}
// Add Aura-enabled controllers at their remapped addresses
for (unsigned int address_list_idx = 0; address_list_idx < AURA_RAM_ADDRESS_COUNT; address_list_idx++)
{
if (TestForAuraSMBusController(busses[bus], aura_ram_addresses[address_list_idx]))
if (TestForAuraController(busses[bus], aura_ram_addresses[address_list_idx]))
{
new_aura = new AuraSMBusController(busses[bus], aura_ram_addresses[address_list_idx]);
new_controller = new RGBController_AuraSMBus(new_aura);
new_aura = new AuraController(busses[bus], aura_ram_addresses[address_list_idx]);
new_controller = new RGBController_Aura(new_aura);
rgb_controllers.push_back(new_controller);
}
std::this_thread::sleep_for(1ms);
Sleep(1);
}
// Add Aura-enabled motherboard controllers
for (unsigned int address_list_idx = 0; address_list_idx < AURA_MOBO_ADDRESS_COUNT; address_list_idx++)
{
if (TestForAuraSMBusController(busses[bus], aura_mobo_addresses[address_list_idx]))
if (TestForAuraController(busses[bus], aura_mobo_addresses[address_list_idx]))
{
new_aura = new AuraSMBusController(busses[bus], aura_mobo_addresses[address_list_idx]);
new_controller = new RGBController_AuraSMBus(new_aura);
new_aura = new AuraController(busses[bus], aura_mobo_addresses[address_list_idx]);
new_controller = new RGBController_Aura(new_aura);
rgb_controllers.push_back(new_controller);
}
std::this_thread::sleep_for(1ms);
Sleep(1);
}
}
} /* DetectAuraSMBusControllers() */
} /* DetectAuraControllers() */
@@ -1,125 +0,0 @@
/*-----------------------------------------*\
| AuraCoreController.cpp |
| |
| Driver for ASUS ROG Aura Core RGB |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 4/13/2020 |
\*-----------------------------------------*/
#include "AuraCoreController.h"
#include <cstring>
AuraCoreController::AuraCoreController(hid_device* dev_handle)
{
dev = dev_handle;
}
AuraCoreController::~AuraCoreController()
{
}
void AuraCoreController::SendBrightness
(
unsigned char brightness
)
{
unsigned char usb_buf[17];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x5A;
usb_buf[0x01] = AURA_CORE_COMMAND_BRIGHTNESS;
usb_buf[0x02] = 0xC5;
usb_buf[0x03] = 0xC4;
usb_buf[0x04] = brightness;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, 17);
}
void AuraCoreController::SendUpdate
(
unsigned char zone,
unsigned char mode,
unsigned char speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
unsigned char usb_buf[17];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x5D;
usb_buf[0x01] = AURA_CORE_COMMAND_UPDATE;
usb_buf[0x02] = zone;
usb_buf[0x03] = mode;
usb_buf[0x04] = red;
usb_buf[0x05] = green;
usb_buf[0x06] = blue;
usb_buf[0x07] = speed;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, 17);
}
void AuraCoreController::SendSet()
{
unsigned char usb_buf[17];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x5D;
usb_buf[0x01] = AURA_CORE_COMMAND_SET;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, 17);
}
void AuraCoreController::SendApply()
{
unsigned char usb_buf[17];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x5D;
usb_buf[0x01] = AURA_CORE_COMMAND_APPLY;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, 17);
}
@@ -1,76 +0,0 @@
/*-----------------------------------------*\
| AuraCoreController.h |
| |
| Definitions and types for ASUS ROG Aura |
| Core RGB lighting controller |
| |
| Adam Honse (CalcProgrammer1) 4/13/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
AURA_CORE_MODE_STATIC = 0, /* Static color mode */
AURA_CORE_MODE_BREATHING = 1, /* Breathing effect mode */
AURA_CORE_MODE_SPECTRUM_CYCLE = 2, /* Spectrum Cycle mode */
};
enum
{
AURA_CORE_COMMAND_UPDATE = 0xB3, /* Update mode and color */
AURA_CORE_COMMAND_SET = 0xB5, /* Set command */
AURA_CORE_COMMAND_APPLY = 0xB4, /* Apply command */
AURA_CORE_COMMAND_BRIGHTNESS = 0xBA, /* Brightness command */
};
enum
{
AURA_CORE_ZONE_IDX_ALL = 0x00, /* Update all zones */
AURA_CORE_ZONE_IDX_1 = 0x01, /* Update zone 1 */
AURA_CORE_ZONE_IDX_2 = 0x02, /* Update zone 2 */
AURA_CORE_ZONE_IDX_3 = 0x03, /* Update zone 3 */
AURA_CORE_ZONE_IDX_4 = 0x04, /* Update zone 4 */
};
enum
{
AURA_CORE_SPEED_SLOW = 0xE1, /* Slowest speed */
AURA_CORE_SPEED_NORMAL = 0xEB, /* Normal speed */
AURA_CORE_SPEED_FAST = 0xF5, /* Fastest speed */
};
class AuraCoreController
{
public:
AuraCoreController(hid_device* dev_handle);
~AuraCoreController();
void SendBrightness
(
unsigned char brightness
);
void SendUpdate
(
unsigned char zone,
unsigned char mode,
unsigned char speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
void SendSet();
void SendApply();
private:
hid_device* dev;
};
@@ -1,45 +0,0 @@
#include "AuraCoreController.h"
#include "RGBController.h"
#include "RGBController_AuraCore.h"
#include <vector>
#include <hidapi/hidapi.h>
#define AURA_CORE_VID 0x0B05
#define NUM_PIDS 3
static const unsigned short pid_table[] =
{
0x1854,
0x1869,
0x1866
};
/******************************************************************************************\
* *
* DetectAuraCoreControllers *
* *
* Tests the USB address to see if an Asus ROG Aura Core controller exists there *
* *
\******************************************************************************************/
void DetectAuraCoreControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device* dev;
//Look for Asus ROG Aura Core RGB controller
hid_init();
for(int pid_idx = 0; pid_idx < NUM_PIDS; pid_idx++)
{
dev = hid_open(AURA_CORE_VID, pid_table[pid_idx], 0);
if( dev )
{
AuraCoreController* controller = new AuraCoreController(dev);
RGBController_AuraCore* rgb_controller = new RGBController_AuraCore(controller);
rgb_controllers.push_back(rgb_controller);
}
}
}
@@ -1,84 +0,0 @@
/*-----------------------------------------*\
| AuraGPUController.cpp |
| |
| Driver for ASUS Aura RGB on GPUs |
| |
| Jan Rettig (Klapstuhl) 14.02.2020 |
\*-----------------------------------------*/
#include "AuraGPUController.h"
#include <cstring>
AuraGPUController::AuraGPUController(i2c_smbus_interface* bus, aura_gpu_dev_id dev)
{
this->bus = bus;
this->dev = dev;
strcpy(device_name, "ASUS Aura GPU"); // Would be nice to get the actual GPU name. Using this as a placeholder.
}
AuraGPUController::~AuraGPUController()
{
}
std::string AuraGPUController::GetDeviceName()
{
return(device_name);
}
std::string AuraGPUController::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(return_string);
}
unsigned char AuraGPUController::GetLEDRed()
{
return(AuraGPURegisterRead(AURA_GPU_REG_RED));
}
unsigned char AuraGPUController::GetLEDGreen()
{
return(AuraGPURegisterRead(AURA_GPU_REG_GREEN));
}
unsigned char AuraGPUController::GetLEDBlue()
{
return(AuraGPURegisterRead(AURA_GPU_REG_BLUE));
}
void AuraGPUController::SetLEDColorsDirect(unsigned char red, unsigned char green, unsigned char blue) // Direct Mode is just Static Mode without applying color changes
{
AuraGPURegisterWrite(AURA_GPU_REG_RED, red);
AuraGPURegisterWrite(AURA_GPU_REG_GREEN, green);
AuraGPURegisterWrite(AURA_GPU_REG_BLUE, blue);
}
void AuraGPUController::SetLEDColorsEffect(unsigned char red, unsigned char green, unsigned char blue)
{
AuraGPURegisterWrite(AURA_GPU_REG_RED, red);
AuraGPURegisterWrite(AURA_GPU_REG_GREEN, green);
AuraGPURegisterWrite(AURA_GPU_REG_BLUE, blue);
AuraGPURegisterWrite(AURA_GPU_REG_APPLY, AURA_GPU_APPLY_VAL);
}
void AuraGPUController::SetMode(unsigned char mode)
{
AuraGPURegisterWrite(AURA_GPU_REG_MODE, mode);
AuraGPURegisterWrite(AURA_GPU_REG_APPLY, AURA_GPU_APPLY_VAL);
}
unsigned char AuraGPUController::AuraGPURegisterRead(unsigned char reg)
{
return(bus->i2c_smbus_read_byte_data(dev, reg));
}
void AuraGPUController::AuraGPURegisterWrite(unsigned char reg, unsigned char val)
{
bus->i2c_smbus_write_byte_data(dev, reg, val);
}
@@ -1,64 +0,0 @@
/*-----------------------------------------*\
| AuraGPUController.h |
| |
| Definitions for ASUS Aura RGB on GPUs |
| |
| Jan Rettig (Klapstuhl) 14.02.2020 |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char aura_gpu_dev_id;
#define AURA_GPU_MAGIC_VAL 0x1589 /* This magic value is present in all Aura GPU controllers */
#define AURA_GPU_APPLY_VAL 0x01 /* Value for Apply Changes Register */
enum
{
AURA_GPU_REG_RED = 0x04, /* AURA GPU RED Register */
AURA_GPU_REG_GREEN = 0x05, /* AURA GPU GREEN Register */
AURA_GPU_REG_BLUE = 0x06, /* AURA GPU BLUE Register */
AURA_GPU_REG_MODE = 0x07, /* AURA GPU Mode Selection Register */
AURA_GPU_REG_SYNC = 0x0C, /* AURA GPU "Sync" Register */
AURA_GPU_REG_APPLY = 0x0E, /* AURA GPU Apply Chnages Register */
};
enum
{
AURA_GPU_MODE_OFF = 0, /* OFF mode (not a real Mode! Doesn't do anything!) */
AURA_GPU_MODE_STATIC = 1, /* Static color mode */
AURA_GPU_MODE_BREATHING = 2, /* Breathing effect mode */
AURA_GPU_MODE_FLASHING = 3, /* Flashing effect mode */
AURA_GPU_MODE_SPECTRUM_CYCLE = 4, /* Spectrum Cycle mode */
AURA_GPU_MODE_DIRECT = 5, /* Direct mode (not a real Mode! Doesn't do anything!) */
AURA_GPU_NUMBER_MODES
};
class AuraGPUController
{
public:
AuraGPUController(i2c_smbus_interface* bus, aura_gpu_dev_id);
~AuraGPUController();
std::string GetDeviceName();
std::string GetDeviceLocation();
unsigned char GetLEDRed();
unsigned char GetLEDGreen();
unsigned char GetLEDBlue();
void SetLEDColorsDirect(unsigned char red, unsigned char green, unsigned char blue);
void SetLEDColorsEffect(unsigned char red, unsigned char green, unsigned char blue);
void SetMode(unsigned char mode);
unsigned char AuraGPURegisterRead(unsigned char reg);
void AuraGPURegisterWrite(unsigned char reg, unsigned char val);
bool direct = false; // Temporary solution to check if we are in "Direct" mode
private:
char device_name[16];
i2c_smbus_interface * bus;
aura_gpu_dev_id dev;
};
@@ -1,85 +0,0 @@
/*-----------------------------------------*\
| AuraGPUControllerDetect.cpp |
| |
| Driver for ASUS Aura RGB on GPUs |
| |
| Jan Rettig (Klapstuhl) 14.02.2020 |
\*-----------------------------------------*/
#include "AuraGPUController.h"
#include "RGBController.h"
#include "RGBController_AuraGPU.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std::chrono_literals;
/*-------------------------------------------------------------*\
| This list contains the available I2C addresses for Aura GPUs |
\*-------------------------------------------------------------*/
#define AURA_GPU_ADDRESS_COUNT 3
static const unsigned char aura_gpu_addresses[] =
{
0x29,
0x2A,
0x60
};
/******************************************************************************************\
* *
* TestForAuraGPUController *
* *
* Tests the given address to see if an Aura GPU controller exists there. *
* *
\******************************************************************************************/
bool TestForAuraGPUController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
unsigned char aura_gpu_magic_high = bus->i2c_smbus_read_byte_data(address, 0x20); // High Byte of magic (0x15)
unsigned char aura_gpu_magic_low = bus->i2c_smbus_read_byte_data(address, 0x21); // Low Byte of magic (0x89)
if((aura_gpu_magic_high << 8) + aura_gpu_magic_low == AURA_GPU_MAGIC_VAL)
{
pass = true;
}
return(pass);
} /* TestForAuraGPUController() */
/******************************************************************************************\
* *
* DetectAuraGPUControllers *
* *
* Detect Aura GPU controllers on the enumerated I2C busses. *
* *
\******************************************************************************************/
void DetectAuraGPUControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
AuraGPUController* new_aura_gpu;
RGBController_AuraGPU* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Add Aura-enabled GPU controllers
for (unsigned int address_list_idx = 0; address_list_idx < AURA_GPU_ADDRESS_COUNT; address_list_idx++)
{
if (TestForAuraGPUController(busses[bus], aura_gpu_addresses[address_list_idx]))
{
new_aura_gpu = new AuraGPUController(busses[bus], aura_gpu_addresses[address_list_idx]);
new_controller = new RGBController_AuraGPU(new_aura_gpu);
rgb_controllers.push_back(new_controller);
}
std::this_thread::sleep_for(1ms);
}
}
} /* DetectAuraGPUControllers() */
@@ -1,144 +0,0 @@
/*-----------------------------------------*\
| AuraAddressableController.cpp |
| |
| Driver for ASUS Aura RGB Addressable |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 1/18/2020 |
\*-----------------------------------------*/
#include "AuraAddressableController.h"
#include <cstring>
AuraAddressableController::AuraAddressableController(hid_device* dev_handle) : AuraUSBController(dev_handle)
{
/*-----------------------------------------------------*\
| Add addressable devices |
\*-----------------------------------------------------*/
for(int i = 0; i < config_table[0x02]; ++i)
{
device_info.push_back({0x01, (unsigned char)i, 0x01, AuraDeviceType::ADDRESSABLE});
}
}
AuraAddressableController::~AuraAddressableController()
{
}
void AuraAddressableController::SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors)
{
unsigned char led_data[60];
unsigned int leds_sent = 0;
while(leds_sent < num_colors)
{
unsigned int leds_to_send = 20;
if((num_colors - leds_sent) < leds_to_send)
{
leds_to_send = num_colors - leds_sent;
}
for(int led_idx = 0; led_idx < leds_to_send; led_idx++)
{
led_data[(led_idx * 3) + 0] = RGBGetRValue(colors[led_idx + leds_sent]);
led_data[(led_idx * 3) + 1] = RGBGetGValue(colors[led_idx + leds_sent]);
led_data[(led_idx * 3) + 2] = RGBGetBValue(colors[led_idx + leds_sent]);
}
SendDirect
(
channel,
leds_sent,
leds_to_send,
led_data
);
leds_sent += leds_to_send;
}
SendDirectApply(channel);
}
void AuraAddressableController::SetMode
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
)
{
SendEffect
(
channel,
mode,
red,
grn,
blu
);
}
void AuraAddressableController::SendEffect
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_ADDRESSABLE_CONTROL_MODE_EFFECT;
usb_buf[0x02] = channel;
usb_buf[0x03] = 0x00;
usb_buf[0x04] = mode;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
usb_buf[0x05] = red;
usb_buf[0x06] = grn;
usb_buf[0x07] = blu;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
void AuraAddressableController::SendDirectApply
(
unsigned char channel
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_CONTROL_MODE_DIRECT;
usb_buf[0x02] = 0x80 | channel;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
@@ -1,60 +0,0 @@
/*-----------------------------------------*\
| AuraAddressableController.h |
| |
| Definitions and types for ASUS Aura |
| Addressable RGB lighting controller |
| |
| Adam Honse (CalcProgrammer1) 1/18/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include "AuraUSBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
AURA_ADDRESSABLE_CONTROL_MODE_EFFECT = 0x3B, /* Effect control mode */
};
class AuraAddressableController : public AuraUSBController
{
public:
AuraAddressableController(hid_device* dev_handle);
~AuraAddressableController();
void SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
unsigned int num_colors
);
void SetMode
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
);
private:
void SendEffect
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
);
void SendDirectApply
(
unsigned char channel
);
};
@@ -1,199 +0,0 @@
/*-----------------------------------------*\
| AuraMainboardController.cpp |
| |
| Driver for ASUS Aura RGB USB mainboard |
| lighting controller |
| |
| Martin Hartl (inlart) 4/25/2020 |
\*-----------------------------------------*/
#include "AuraMainboardController.h"
#include <cstring>
AuraMainboardController::AuraMainboardController(hid_device* dev_handle) : AuraUSBController(dev_handle), mode(AURA_MODE_DIRECT)
{
/*-----------------------------------------------------*\
| Add mainboard device |
\*-----------------------------------------------------*/
device_info.push_back({0x00, 0x04, config_table[0x1B], AuraDeviceType::FIXED});
/*-----------------------------------------------------*\
| Add addressable devices |
\*-----------------------------------------------------*/
for(int i = 0; i < config_table[0x02]; ++i)
{
device_info.push_back({0x01, (unsigned char)i, 0x01, AuraDeviceType::ADDRESSABLE});
}
}
AuraMainboardController::~AuraMainboardController()
{
}
void AuraMainboardController::SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors)
{
unsigned char led_data[60];
unsigned int leds_sent = 0;
while(leds_sent < num_colors)
{
unsigned int leds_to_send = 20;
if((num_colors - leds_sent) < leds_to_send)
{
leds_to_send = num_colors - leds_sent;
}
for(int led_idx = 0; led_idx < leds_to_send; led_idx++)
{
led_data[(led_idx * 3) + 0] = RGBGetRValue(colors[led_idx + leds_sent]);
led_data[(led_idx * 3) + 1] = RGBGetGValue(colors[led_idx + leds_sent]);
led_data[(led_idx * 3) + 2] = RGBGetBValue(colors[led_idx + leds_sent]);
}
SendDirect
(
device_info[channel].direct_channel,
leds_sent,
leds_to_send,
led_data,
leds_sent + leds_to_send >= num_colors
);
leds_sent += leds_to_send;
}
SendCommit();
}
void AuraMainboardController::SetMode
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
)
{
this->mode = mode;
RGBColor color = ToRGBColor(red, grn, blu);
SendEffect(device_info[channel].effect_channel, mode);
if(mode == AURA_MODE_DIRECT)
{
return;
}
unsigned char led_data[60];
unsigned char start_led = 0;
for(std::size_t i = 0; i < channel; ++i)
{
start_led += device_info[i].num_leds;
}
for(std::size_t led_idx = 0; led_idx < device_info[channel].num_leds; led_idx++)
{
led_data[(led_idx * 3) + 0] = RGBGetRValue(color);
led_data[(led_idx * 3) + 1] = RGBGetGValue(color);
led_data[(led_idx * 3) + 2] = RGBGetBValue(color);
}
SendColor
(
channel,
start_led,
device_info[channel].num_leds,
led_data,
device_info[channel].device_type == AuraDeviceType::FIXED
);
SendCommit();
}
void AuraMainboardController::SendEffect
(
unsigned char channel,
unsigned char mode
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_MAINBOARD_CONTROL_MODE_EFFECT;
usb_buf[0x02] = channel;
usb_buf[0x03] = 0x00;
usb_buf[0x04] = 0x00;
usb_buf[0x05] = mode;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
void AuraMainboardController::SendColor
(
unsigned char channel,
unsigned char start_led,
unsigned char led_count,
unsigned char* led_data,
bool fixed
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_MAINBOARD_CONTROL_MODE_EFFECT_COLOR;
usb_buf[0x02] = channel;
usb_buf[0x03] = fixed ? 0xFF : 0x00;
usb_buf[0x04] = 0x00;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x05 + 3 * start_led], led_data, led_count * 3);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
void AuraMainboardController::SendCommit()
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_MAINBOARD_CONTROL_MODE_COMMIT;
usb_buf[0x02] = 0x55;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
@@ -1,66 +0,0 @@
/*-----------------------------------------*\
| AuraMainboardController.h |
| |
| Definitions and types for ASUS Aura |
| USB Mainboard RGB lighting controller |
| |
| Martin Hartl (inlart) 4/25/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include "AuraUSBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
AURA_MAINBOARD_CONTROL_MODE_EFFECT = 0x35, /* Effect control mode */
AURA_MAINBOARD_CONTROL_MODE_EFFECT_COLOR = 0x36, /* Effect color control mode */
AURA_MAINBOARD_CONTROL_MODE_COMMIT = 0x3F, /* Commit mode */
};
class AuraMainboardController : public AuraUSBController
{
public:
AuraMainboardController(hid_device* dev_handle);
~AuraMainboardController();
void SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
unsigned int num_colors
);
void SetMode
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
);
private:
unsigned int mode;
void SendEffect
(
unsigned char channel,
unsigned char mode
);
void SendColor
(
unsigned char channel,
unsigned char start_led,
unsigned char led_count,
unsigned char* led_data,
bool fixed
);
void SendCommit();
};
@@ -1,155 +0,0 @@
/*-----------------------------------------*\
| AuraUSBController.cpp |
| |
| Driver for ASUS Aura RGB USB |
| lighting controller |
| |
| Martin Hartl (inlart) 4/25/2020 |
\*-----------------------------------------*/
#include "AuraUSBController.h"
#include <cstring>
#include <stdexcept>
AuraUSBController::AuraUSBController(hid_device* dev_handle)
{
dev = dev_handle;
GetFirmwareVersion();
GetConfigTable();
}
AuraUSBController::~AuraUSBController()
{
}
unsigned int AuraUSBController::GetChannelCount()
{
return(device_info.size());
}
std::string AuraUSBController::GetDeviceName()
{
return(device_name);
}
const std::vector<AuraDeviceInfo>& AuraUSBController::GetAuraDevices() const
{
return(device_info);
}
void AuraUSBController::GetConfigTable()
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_REQUEST_CONFIG_TABLE;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 65);
/*-----------------------------------------------------*\
| Copy the firmware string if the reply ID is correct |
\*-----------------------------------------------------*/
if(usb_buf[1] == 0x30)
{
memcpy(config_table, &usb_buf[4], 60);
for(int i = 0; i < 60; i+=6)
{
printf("%02X %02X %02X %02X %02X %02X\r\n", config_table[i + 0],
config_table[i + 1],
config_table[i + 2],
config_table[i + 3],
config_table[i + 4],
config_table[i + 5]);
}
}
else
{
if(dev)
{
hid_close(dev);
}
throw std::runtime_error("Could not read config table");
}
}
void AuraUSBController::GetFirmwareVersion()
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up firmware version request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_REQUEST_FIRMWARE_VERSION;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 65);
/*-----------------------------------------------------*\
| Copy the firmware string if the reply ID is correct |
\*-----------------------------------------------------*/
if(usb_buf[1] == 0x02)
{
memcpy(device_name, &usb_buf[2], 16);
}
}
void AuraUSBController::SendDirect
(
unsigned char device,
unsigned char start_led,
unsigned char led_count,
unsigned char* led_data,
bool apply /* = false */
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_CONTROL_MODE_DIRECT;
usb_buf[0x02] = apply ? 0x80 : 0x00;
usb_buf[0x02] |= device;
usb_buf[0x03] = start_led;
usb_buf[0x04] = led_count;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x05], led_data, led_count * 3);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
@@ -1,107 +0,0 @@
/*-----------------------------------------*\
| AuraUSBController.h |
| |
| Definitions and types for ASUS Aura |
| USB RGB lighting controller |
| |
| Martin Hartl (inlart) 4/25/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
enum
{
AURA_MODE_OFF = 0, /* OFF mode */
AURA_MODE_STATIC = 1, /* Static color mode */
AURA_MODE_BREATHING = 2, /* Breathing effect mode */
AURA_MODE_FLASHING = 3, /* Flashing effect mode */
AURA_MODE_SPECTRUM_CYCLE = 4, /* Spectrum Cycle mode */
AURA_MODE_RAINBOW = 5, /* Rainbow effect mode */
AURA_MODE_SPECTRUM_CYCLE_BREATHING = 6, /* Rainbow Breathing effect mode */
AURA_MODE_CHASE_FADE = 7, /* Chase with Fade effect mode */
AURA_MODE_SPECTRUM_CYCLE_CHASE_FADE = 8, /* Chase with Fade, Rainbow effect mode */
AURA_MODE_CHASE = 9, /* Chase effect mode */
AURA_MODE_SPECTRUM_CYCLE_CHASE = 10, /* Chase with Rainbow effect mode */
AURA_MODE_SPECTRUM_CYCLE_WAVE = 11, /* Wave effect mode */
AURA_MODE_CHASE_RAINBOW_PULSE = 12, /* Chase with Rainbow Pulse effect mode*/
AURA_MODE_RANDOM_FLICKER = 13, /* Random flicker effect mode */
AURA_MODE_MUSIC = 14, /* Music effect mode */
AURA_MODE_DIRECT = 0xFF, /* Direct control mode */
};
enum
{
AURA_REQUEST_FIRMWARE_VERSION = 0x82, /* Request firmware string */
AURA_REQUEST_CONFIG_TABLE = 0xB0, /* Request configuration table */
AURA_CONTROL_MODE_DIRECT = 0x40, /* Direct control mode */
};
enum class AuraDeviceType
{
FIXED,
ADDRESSABLE,
};
struct AuraDeviceInfo
{
unsigned char effect_channel;
unsigned char direct_channel;
unsigned char num_leds;
AuraDeviceType device_type;
};
class AuraUSBController
{
public:
AuraUSBController(hid_device* dev_handle);
virtual ~AuraUSBController();
unsigned int GetChannelCount();
std::string GetDeviceName();
const std::vector<AuraDeviceInfo>& GetAuraDevices() const;
virtual void SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
unsigned int num_colors
) = 0;
virtual void SetMode
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
) = 0;
protected:
hid_device* dev;
unsigned char config_table[60];
std::vector<AuraDeviceInfo> device_info;
void SendDirect
(
unsigned char device,
unsigned char start_led,
unsigned char led_count,
unsigned char* led_data,
bool apply = false
);
private:
char device_name[16];
unsigned int led_count;
void GetConfigTable();
void GetFirmwareVersion();
};
@@ -1,77 +0,0 @@
#include "AuraAddressableController.h"
#include "AuraMainboardController.h"
#include "RGBController.h"
#include "RGBController_AuraUSB.h"
#include <vector>
#include <stdexcept>
#include <hidapi/hidapi.h>
#define AURA_USB_VID 0x0B05
#define NUM_ADDRESSABLE_PIDS 4
static const unsigned short addressable_pid_table[] =
{
0x1867,
0x1872,
0x1889,
0x18A3
};
#define NUM_MAINBOARD_PIDS 2
static const unsigned short mainboard_pid_table[] =
{
0x18f3,
0x1939
};
/******************************************************************************************\
* *
* DetectAuraUSBControllers *
* *
* Tests the USB address to see if an Asus Aura USB RGB header controller *
* exists there. *
* *
\******************************************************************************************/
void DetectAuraUSBControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device* dev;
//Look for Asus Aura addressable RGB header controller
hid_init();
for(int pid_idx = 0; pid_idx < NUM_ADDRESSABLE_PIDS; pid_idx++)
{
dev = hid_open(AURA_USB_VID, addressable_pid_table[pid_idx], 0);
if( dev )
{
AuraAddressableController* controller = new AuraAddressableController(dev);
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
rgb_controllers.push_back(rgb_controller);
}
}
for(int pid_idx = 0; pid_idx < NUM_MAINBOARD_PIDS; pid_idx++)
{
dev = hid_open(AURA_USB_VID, mainboard_pid_table[pid_idx], 0);
if( dev )
{
try
{
AuraMainboardController* controller = new AuraMainboardController(dev);
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
rgb_controllers.push_back(rgb_controller);
}
catch(std::runtime_error&)
{
// reading the config table failed
}
}
}
}
@@ -1,93 +0,0 @@
/*-------------------------------------------------------------------*\
| CMMP750Controller.cpp |
| |
| Driver for Coolermaster MP750 mousepad |
| |
| Chris M (Dr_No) 16th Apr 2020 |
| |
\*-------------------------------------------------------------------*/
#include "CMMP750Controller.h"
CMMP750Controller::CMMP750Controller(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path)
{
int tmp_size = wcslen(_vendor);
dev = dev_handle;
for (int i=0; ( i<tmp_size && i<CM_DEVICE_NAME_SIZE); i++)
{
device_name[i] = (char)_vendor[i];
}
for (int j=0; ( j<wcslen(_vendor) && tmp_size+j<CM_DEVICE_NAME_SIZE); j++)
device_name[tmp_size+j] = (char)_device_name[j];
location = _path;
current_mode = MP750_MODE_STATIC;
current_speed = MP750_SPEED_NORMAL;
}
CMMP750Controller::~CMMP750Controller()
{
hid_close(dev);
}
char* CMMP750Controller::GetDeviceName()
{
return device_name;
}
char* CMMP750Controller::GetSerial()
{
return serial;
}
std::string CMMP750Controller::GetLocation()
{
return location;
}
void CMMP750Controller::SetMode(unsigned char mode, unsigned char speed)
{
current_mode = mode;
current_speed = speed;
SendUpdate();
}
void CMMP750Controller::SetColor(unsigned char red, unsigned char green, unsigned char blue)
{
current_red = red;
current_green = green;
current_blue = blue;
SendUpdate();
}
void CMMP750Controller::SendUpdate()
{
unsigned char buffer[0x40] = { 0x00 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
for(int i = 0; i < CM_COLOUR_MODE_DATA_SIZE; i++)
{
buffer[i] = colour_mode_data[current_mode][i];
}
if(current_mode > MP750_MODE_BREATHING)
{
//If the mode is random colours set SPEED at BYTE2
buffer[CM_RED_BYTE] = speed_mode_data[current_mode][current_speed];
}
else
{
//Otherwise SPEED is BYTE5
buffer[CM_RED_BYTE] = current_red;
buffer[CM_GREEN_BYTE] = current_green;
buffer[CM_BLUE_BYTE] = current_blue;
buffer[CM_SPEED_BYTE] = speed_mode_data[current_mode][current_speed];
}
hid_write(dev, buffer, buffer_size);
}
@@ -1,105 +0,0 @@
/*-------------------------------------------------------------------*\
| CMMP750Controller.h |
| |
| Driver for Coolermaster MP750 mousepad |
| |
| Chris M (Dr_No) 16th Apr 2020 |
| |
| Simple RGB device with 5 modes |
| BYTE0 = Mode (0x01 thru 0x05 |
| BYTE1 = ?? Must be set to 0x04 for colour modes otherwise ignored |
| BYTE2 = Colour Modes: RED else Cycle SPEED |
| BYTE3 = Colour Modes: GREEN else ignored |
| BYTE4 = Colour Modes: BLUE else ignored |
| BYTE5 = Colour Modes: SPEED else ignored |
\*-------------------------------------------------------------------*/
#include <string>
#include <array>
#include <hidapi/hidapi.h>
#pragma once
#define CM_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data) / sizeof(colour_mode_data[0]))
#define CM_INTERRUPT_TIMEOUT 250
#define CM_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
#define CM_SERIAL_SIZE (sizeof(serial) / sizeof(serial[ 0 ]))
#define HID_MAX_STR 255
enum
{
CM_MODE_BYTE = 0,
CM_RED_BYTE = 2,
CM_GREEN_BYTE = 3,
CM_BLUE_BYTE = 4,
CM_SPEED_BYTE = 5
};
enum
{
MP750_MODE_STATIC = 0x00, //Static Mode
MP750_MODE_BLINK = 0x01, //Blinking Mode
MP750_MODE_BREATHING = 0x02, //Breathing Mode
MP750_MODE_COLOR_CYCLE = 0x03, //Color Cycle Mode
MP750_MODE_BREATH_CYCLE = 0x04 //Breathing Cycle Mode
};
static unsigned char colour_mode_data[][6] =
{
{ 0x01, 0x04, 0xFF, 0x00, 0xFF, 0x00 }, /* Static */
{ 0x02, 0x04, 0xFF, 0x00, 0xFF, 0x80 }, /* Blinking */
{ 0x03, 0x04, 0xFF, 0x00, 0xFF, 0x80 }, /* Breathing */
{ 0x04, 0x04, 0x80, 0x00, 0x00, 0x00 }, /* Colour Cycle */
{ 0x05, 0x04, 0x80, 0x00, 0x00, 0x00 } /* Colour Breath */
};
static unsigned char speed_mode_data[][9] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },/* Static */
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 },/* Blinking */
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 },/* Breathing */
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 },/* Colour Cycle */
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 } /* Colour Breath */
};
enum
{
MP750_SPEED_SLOWEST = 0x00, /* Slowest speed */
MP750_SPEED_SLOWER = 0x01, /* Slower speed */
MP750_SPEED_SLOW = 0x02, /* Slow speed */
MP750_SPEED_SLOWISH = 0x03, /* Slowish speed */
MP750_SPEED_NORMAL = 0x04, /* Normal speed */
MP750_SPEED_FASTISH = 0x05, /* Fastish speed */
MP750_SPEED_FAST = 0x06, /* Fast speed */
MP750_SPEED_FASTER = 0x07, /* Faster speed */
MP750_SPEED_FASTEST = 0x08, /* Fastest speed */
};
class CMMP750Controller
{
public:
CMMP750Controller(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path);
~CMMP750Controller();
char* GetDeviceName();
char* GetSerial();
std::string GetLocation();
void SetMode(unsigned char mode, unsigned char speed);
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
private:
char device_name[32];
char serial[32];
std::string location;
hid_device* dev;
unsigned char current_mode;
unsigned char current_speed;
unsigned char current_red;
unsigned char current_green;
unsigned char current_blue;
void SendUpdate();
};
@@ -1,66 +0,0 @@
#include "CMMP750Controller.h"
#include "RGBController.h"
#include "RGBController_CMMP750Controller.h"
#include <hidapi/hidapi.h>
#define COOLERMASTER_VID 0x2516
#define COOLERMASTER_MP750_XL_PID 0x0109
#define COOLERMASTER_MP750_MEDIUM_PID 0x0105
#define COOLERMASTER_NUM_DEVICES (sizeof(cm_pids) / sizeof(cm_pids[ 0 ]))
enum
{
CM_PID = 0,
CM_INTERFACE = 1
};
static const unsigned int cm_pids[][4] =
{ // PID, Interface
{ COOLERMASTER_MP750_XL_PID, 0x00 }, //Coolermaster MP750 (Extra Large)
{ COOLERMASTER_MP750_MEDIUM_PID, 0x00 } //Coolermaster MP750 (Medium)
};
/******************************************************************************************\
* *
* DetectCoolerMasterControllers *
* *
* Tests the USB address to see if any CoolerMaster controllers exists there. *
* *
\******************************************************************************************/
void DetectCoolerMasterControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device_info* info;
//Look for the passed in cm_pids
hid_init();
info = hid_enumerate(0x0, 0x0);
while(info)
{
hid_device* dev = NULL;
if(info->vendor_id == COOLERMASTER_VID)
{
for(int cm_pid_idx = 0; cm_pid_idx < COOLERMASTER_NUM_DEVICES; cm_pid_idx++)
{
if((info->product_id == cm_pids[cm_pid_idx][CM_PID])
&&(info->interface_number == cm_pids[cm_pid_idx][CM_INTERFACE]))
{
dev = hid_open_path(info->path);
break;
}
}
}
if(dev)
{
CMMP750Controller* controller = new CMMP750Controller(dev, info->manufacturer_string, info->product_string, info->path);
RGBController_CMMP750Controller* rgb_controller = new RGBController_CMMP750Controller(controller);
rgb_controllers.push_back(rgb_controller);
}
info = info->next;
}
hid_free_enumeration(info);
}
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| CorsairVengeanceController.h |
| CorsairController.h |
| |
| Driver for Corsair Vengeance RGB RAM |
| lighting controller |
@@ -7,10 +7,10 @@
| Adam Honse (CalcProgrammer1) 3/8/2019 |
\*-----------------------------------------*/
#include "CorsairVengeanceController.h"
#include "CorsairController.h"
#include <cstring>
CorsairVengeanceController::CorsairVengeanceController(i2c_smbus_interface* bus, corsair_dev_id dev)
CorsairController::CorsairController(i2c_smbus_interface* bus, corsair_dev_id dev)
{
this->bus = bus;
this->dev = dev;
@@ -19,17 +19,17 @@ CorsairVengeanceController::CorsairVengeanceController(i2c_smbus_interface* bus,
led_count = 1;
}
CorsairVengeanceController::~CorsairVengeanceController()
CorsairController::~CorsairController()
{
}
std::string CorsairVengeanceController::GetDeviceName()
std::string CorsairController::GetDeviceName()
{
return(device_name);
}
std::string CorsairVengeanceController::GetDeviceLocation()
std::string CorsairController::GetDeviceLocation()
{
std::string return_string(bus->device_name);
char addr[5];
@@ -39,21 +39,33 @@ std::string CorsairVengeanceController::GetDeviceLocation()
return(return_string);
}
unsigned int CorsairVengeanceController::GetLEDCount()
unsigned int CorsairController::GetLEDCount()
{
return(led_count);
}
void CorsairVengeanceController::SetLEDColor(unsigned char red, unsigned char green, unsigned char blue)
void CorsairController::SetLEDColor(unsigned char red, unsigned char green, unsigned char blue)
{
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_FADE_TIME, 0x00);
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_RED_VAL, red);
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_GREEN_VAL, green);
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_BLUE_VAL, blue);
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_MODE, CORSAIR_VENGEANCE_RGB_MODE_SINGLE);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void CorsairVengeanceController::SetMode(unsigned char /*mode*/)
void CorsairController::SetMode(unsigned char /*mode*/)
{
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_MODE, CORSAIR_VENGEANCE_RGB_MODE_SINGLE);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| CorsairVengeanceController.h |
| CorsairController.h |
| |
| Definitions and types for Corsair |
| Vengeance RGB RAM lighting controller |
@@ -33,11 +33,11 @@ enum
CORSAIR_NUMBER_MODES /* Number of Corsair modes */
};
class CorsairVengeanceController
class CorsairController
{
public:
CorsairVengeanceController(i2c_smbus_interface* bus, corsair_dev_id dev);
~CorsairVengeanceController();
CorsairController(i2c_smbus_interface* bus, corsair_dev_id dev);
~CorsairController();
std::string GetDeviceName();
std::string GetDeviceLocation();
@@ -1,6 +1,6 @@
#include "CorsairVengeanceController.h"
#include "CorsairController.h"
#include "RGBController.h"
#include "RGBController_CorsairVengeance.h"
#include "RGBController_Corsair.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
@@ -8,13 +8,13 @@
/******************************************************************************************\
* *
* TestForCorsairVengeanceController *
* TestForCorsairController *
* *
* Tests the given address to see if a Corsair controller exists there. *
* *
\******************************************************************************************/
bool TestForCorsairVengeanceController(i2c_smbus_interface* bus, unsigned char address)
bool TestForCorsairController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
@@ -37,11 +37,11 @@ bool TestForCorsairVengeanceController(i2c_smbus_interface* bus, unsigned char a
return(pass);
} /* TestForCorsairVengeanceController() */
} /* TestForCorsairController() */
/******************************************************************************************\
* *
* DetectCorsairVengeanceControllers *
* DetectCorsairControllers *
* *
* Detect Corsair controllers on the enumerated I2C busses. *
* *
@@ -50,76 +50,60 @@ bool TestForCorsairVengeanceController(i2c_smbus_interface* bus, unsigned char a
* *
\******************************************************************************************/
void DetectCorsairVengeanceControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
void DetectCorsairControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
CorsairVengeanceController* new_corsair;
RGBController_CorsairVengeance* new_controller;
CorsairController* new_corsair;
RGBController_Corsair* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Check for Corsair controller at 0x58
if (TestForCorsairVengeanceController(busses[bus], 0x58))
if (TestForCorsairController(busses[bus], 0x58))
{
new_corsair = new CorsairVengeanceController(busses[bus], 0x58);
new_controller = new RGBController_CorsairVengeance(new_corsair);
new_corsair = new CorsairController(busses[bus], 0x58);
new_controller = new RGBController_Corsair(new_corsair);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x59
if (TestForCorsairVengeanceController(busses[bus], 0x59))
if (TestForCorsairController(busses[bus], 0x59))
{
new_corsair = new CorsairVengeanceController(busses[bus], 0x59);
new_controller = new RGBController_CorsairVengeance(new_corsair);
new_corsair = new CorsairController(busses[bus], 0x59);
new_controller = new RGBController_Corsair(new_corsair);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5A
if (TestForCorsairVengeanceController(busses[bus], 0x5A))
if (TestForCorsairController(busses[bus], 0x5A))
{
new_corsair = new CorsairVengeanceController(busses[bus], 0x5A);
new_controller = new RGBController_CorsairVengeance(new_corsair);
new_corsair = new CorsairController(busses[bus], 0x5A);
new_controller = new RGBController_Corsair(new_corsair);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5B
if (TestForCorsairVengeanceController(busses[bus], 0x5B))
if (TestForCorsairController(busses[bus], 0x5B))
{
new_corsair = new CorsairVengeanceController(busses[bus], 0x5B);
new_controller = new RGBController_CorsairVengeance(new_corsair);
new_corsair = new CorsairController(busses[bus], 0x5B);
new_controller = new RGBController_Corsair(new_corsair);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5C
if (TestForCorsairVengeanceController(busses[bus], 0x5C))
if (TestForCorsairController(busses[bus], 0x5C))
{
new_corsair = new CorsairVengeanceController(busses[bus], 0x5C);
new_controller = new RGBController_CorsairVengeance(new_corsair);
new_corsair = new CorsairController(busses[bus], 0x5C);
new_controller = new RGBController_Corsair(new_corsair);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5D
if (TestForCorsairVengeanceController(busses[bus], 0x5D))
if (TestForCorsairController(busses[bus], 0x5D))
{
new_corsair = new CorsairVengeanceController(busses[bus], 0x5D);
new_controller = new RGBController_CorsairVengeance(new_corsair);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5E
if (TestForCorsairVengeanceController(busses[bus], 0x5E))
{
new_corsair = new CorsairVengeanceController(busses[bus], 0x5E);
new_controller = new RGBController_CorsairVengeance(new_corsair);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5F
if (TestForCorsairVengeanceController(busses[bus], 0x5F))
{
new_corsair = new CorsairVengeanceController(busses[bus], 0x5F);
new_controller = new RGBController_CorsairVengeance(new_corsair);
new_corsair = new CorsairController(busses[bus], 0x5D);
new_controller = new RGBController_Corsair(new_corsair);
rgb_controllers.push_back(new_controller);
}
}
} /* DetectCorsairVengeanceControllers() */
} /* DetectCorsairControllers() */
@@ -1,461 +0,0 @@
/*---------------------------------------------------------*\
| Processing Code for Corsair Lighting Node Pro |
| |
| Adam Honse ([email protected]), 1/12/2020 |
\*---------------------------------------------------------*/
#include "CorsairLightingNodeController.h"
#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
//Include thread libraries for Windows or Linux
#ifdef WIN32
#include <process.h>
#else
#include "pthread.h"
#include "unistd.h"
#endif
//Thread functions have different types in Windows and Linux
#ifdef WIN32
#define THREAD static void
#define THREADRETURN
#else
#define THREAD static void*
#define THREADRETURN return(NULL);
#endif
using namespace std::chrono_literals;
THREAD keepalive_thread(void *param)
{
CorsairLightingNodeController* corsair = static_cast<CorsairLightingNodeController*>(param);
corsair->KeepaliveThread();
THREADRETURN
}
CorsairLightingNodeController::CorsairLightingNodeController(hid_device* dev_handle)
{
dev = dev_handle;
SendFirmwareRequest();
/*-----------------------------------------------------*\
| The Corsair Lighting Node Pro requires a packet within|
| 20 seconds of sending the lighting change in order |
| to not revert back into rainbow mode. Start a thread |
| to continuously send a keepalive packet every 5s |
\*-----------------------------------------------------*/
#ifdef WIN32
_beginthread(keepalive_thread, 0, this);
#else
pthread_t thread;
pthread_create(&thread, NULL, &keepalive_thread, this);
#endif
}
CorsairLightingNodeController::~CorsairLightingNodeController()
{
}
void CorsairLightingNodeController::KeepaliveThread()
{
while(1)
{
if((clock() - last_commit_time) > 5000)
{
SendCommit();
}
std::this_thread::sleep_for(1s);
}
}
std::string CorsairLightingNodeController::GetFirmwareString()
{
return(firmware_version);
}
void CorsairLightingNodeController::SetChannelEffect(unsigned char channel,
unsigned char num_leds,
unsigned char mode,
unsigned char speed,
unsigned char direction,
bool random,
unsigned char red1,
unsigned char grn1,
unsigned char blu1,
unsigned char red2,
unsigned char grn2,
unsigned char blu2,
unsigned char red3,
unsigned char grn3,
unsigned char blu3
)
{
/*-----------------------------------------------------*\
| Send Reset packet |
\*-----------------------------------------------------*/
SendReset(channel);
/*-----------------------------------------------------*\
| Send Begin packet |
\*-----------------------------------------------------*/
SendBegin(channel);
/*-----------------------------------------------------*\
| Set Port State packet |
\*-----------------------------------------------------*/
SendPortState(channel, CORSAIR_LIGHTING_NODE_PORT_STATE_HARDWARE);
/*-----------------------------------------------------*\
| Set Effect Configuration packet |
\*-----------------------------------------------------*/
SendEffectConfig
(
channel,
0,
num_leds,
mode,
speed,
direction,
random,
red1,
grn1,
blu1,
red2,
grn2,
blu2,
red3,
grn3,
blu3,
0,
0,
0
);
/*-----------------------------------------------------*\
| Send Commit packet |
\*-----------------------------------------------------*/
SendCommit();
}
void CorsairLightingNodeController::SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors)
{
unsigned char red_color_data[50];
unsigned char grn_color_data[50];
unsigned char blu_color_data[50];
unsigned char pkt_offset = 0;
unsigned char pkt_size = 0;
unsigned int colors_remaining = num_colors;
/*-----------------------------------------------------*\
| Send Port State packet |
\*-----------------------------------------------------*/
SendPortState(channel, CORSAIR_LIGHTING_NODE_PORT_STATE_SOFTWARE);
/*-----------------------------------------------------*\
| Loop through colors and send 50 at a time |
\*-----------------------------------------------------*/
while(colors_remaining > 0)
{
if(colors_remaining < 50)
{
pkt_size = colors_remaining;
}
else
{
pkt_size = 50;
}
for(int color_idx = 0; color_idx < pkt_size; color_idx++)
{
red_color_data[color_idx] = RGBGetRValue(colors[pkt_offset + color_idx]);
grn_color_data[color_idx] = RGBGetGValue(colors[pkt_offset + color_idx]);
blu_color_data[color_idx] = RGBGetBValue(colors[pkt_offset + color_idx]);
}
SendDirect(channel, pkt_offset, pkt_size, CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_RED, red_color_data);
SendDirect(channel, pkt_offset, pkt_size, CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_GREEN, grn_color_data);
SendDirect(channel, pkt_offset, pkt_size, CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_BLUE, blu_color_data);
colors_remaining -= pkt_size;
pkt_offset += pkt_size;
}
/*-----------------------------------------------------*\
| Send Commit packet |
\*-----------------------------------------------------*/
SendCommit();
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void CorsairLightingNodeController::SendFirmwareRequest()
{
int actual;
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Firmware Version Request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_FIRMWARE;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
actual = hid_read(dev, usb_buf, 16);
if(actual > 0)
{
firmware_version = std::to_string(usb_buf[0x01]) + "." + std::to_string(usb_buf[0x02]) + "." + std::to_string(usb_buf[0x03]);
}
}
void CorsairLightingNodeController::SendDirect
(
unsigned char channel,
unsigned char start,
unsigned char count,
unsigned char color_channel,
unsigned char* color_data
)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Direct packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_DIRECT;
usb_buf[0x01] = channel;
usb_buf[0x02] = start;
usb_buf[0x03] = count;
usb_buf[0x04] = color_channel;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x05], color_data, count);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 16);
}
void CorsairLightingNodeController::SendCommit()
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Update last commit time |
\*-----------------------------------------------------*/
last_commit_time = clock();
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_COMMIT;
usb_buf[0x01] = 0xFF;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 16);
}
void CorsairLightingNodeController::SendBegin
(
unsigned char channel
)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Begin packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_BEGIN;
usb_buf[0x01] = channel;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 16);
}
void CorsairLightingNodeController::SendEffectConfig
(
unsigned char channel,
unsigned char count,
unsigned char led_type,
unsigned char mode,
unsigned char speed,
unsigned char direction,
unsigned char change_style,
unsigned char color_0_red,
unsigned char color_0_green,
unsigned char color_0_blue,
unsigned char color_1_red,
unsigned char color_1_green,
unsigned char color_1_blue,
unsigned char color_2_red,
unsigned char color_2_green,
unsigned char color_2_blue,
unsigned short temperature_0,
unsigned short temperature_1,
unsigned short temperature_2
)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Effect Config packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_EFFECT_CONFIG;
usb_buf[0x01] = channel;
usb_buf[0x02] = count;
usb_buf[0x03] = led_type;
/*-----------------------------------------------------*\
| Set up mode parameters |
\*-----------------------------------------------------*/
usb_buf[0x04] = mode;
usb_buf[0x05] = speed;
usb_buf[0x06] = direction;
usb_buf[0x07] = change_style;
usb_buf[0x08] = 0;
/*-----------------------------------------------------*\
| Set up mode colors |
\*-----------------------------------------------------*/
usb_buf[0x09] = color_0_red;
usb_buf[0x0A] = color_0_green;
usb_buf[0x0B] = color_0_blue;
usb_buf[0x0C] = color_1_red;
usb_buf[0x0D] = color_1_green;
usb_buf[0x0E] = color_1_blue;
usb_buf[0x0F] = color_2_red;
usb_buf[0x10] = color_2_green;
usb_buf[0x11] = color_2_blue;
/*-----------------------------------------------------*\
| Set up temperatures |
\*-----------------------------------------------------*/
usb_buf[0x12] = (temperature_0 >> 8);
usb_buf[0x13] = (temperature_0 & 0xFF);
usb_buf[0x14] = (temperature_1 >> 8);
usb_buf[0x15] = (temperature_1 & 0xFF);
usb_buf[0x16] = (temperature_2 >> 8);
usb_buf[0x17] = (temperature_2 & 0xFF);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 16);
}
void CorsairLightingNodeController::SendTemperature()
{
}
void CorsairLightingNodeController::SendReset
(
unsigned char channel
)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Reset packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_RESET;
usb_buf[0x01] = channel;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 16);
}
void CorsairLightingNodeController::SendPortState
(
unsigned char channel,
unsigned char state
)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Port State packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_PORT_STATE;
usb_buf[0x01] = channel;
usb_buf[0x02] = state;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 16);
}
void CorsairLightingNodeController::SendBrightness()
{
}
void CorsairLightingNodeController::SendLEDCount()
{
}
void CorsairLightingNodeController::SendProtocol()
{
}
@@ -1,173 +0,0 @@
/*---------------------------------------------------------*\
| Definitions for Corsair Lighting Node Pro |
| |
| Adam Honse ([email protected]), 1/12/2020 |
\*---------------------------------------------------------*/
#include "RGBController.h"
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
enum
{
CORSAIR_LIGHTING_NODE_PACKET_ID_FIRMWARE = 0x02, /* Get firmware version */
CORSAIR_LIGHTING_NODE_PACKET_ID_DIRECT = 0x32, /* Direct mode LED update packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_COMMIT = 0x33, /* Commit changes packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_BEGIN = 0x34, /* Begin effect packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_EFFECT_CONFIG = 0x35, /* Effect mode configuration packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_TEMPERATURE = 0x36, /* Update temperature value packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_RESET = 0x37, /* Reset channel packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_PORT_STATE = 0x38, /* Set port state packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_BRIGHTNESS = 0x39, /* Set brightness packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_LED_COUNT = 0x3A, /* Set LED count packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_PROTOCOL = 0x3B, /* Set protocol packet */
};
enum
{
CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_RED = 0x00, /* Red channel for direct update */
CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_GREEN = 0x01, /* Green channel for direct update */
CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_BLUE = 0x02, /* Blue channel for direct update */
};
enum
{
CORSAIR_LIGHTING_NODE_PORT_STATE_HARDWARE = 0x01, /* Effect hardware control of channel */
CORSAIR_LIGHTING_NODE_PORT_STATE_SOFTWARE = 0x02, /* Direct software control of channel */
};
enum
{
CORSAIR_LIGHTING_NODE_LED_TYPE_LED_STRIP = 0x0A, /* Corsair LED Strip Type */
CORSAIR_LIGHTING_NODE_LED_TYPE_HD_FAN = 0x0C, /* Corsair HD-series Fan Type */
CORSAIR_LIGHTING_NODE_LED_TYPE_SP_FAN = 0x01, /* Corsair SP-series Fan Type */
CORSAIR_LIGHTING_NODE_LED_TYPE_ML_FAN = 0x02, /* Corsair ML-series Fan Type */
};
enum
{
CORSAIR_LIGHTING_NODE_CHANNEL_1 = 0x00, /* Channel 1 */
CORSAIR_LIGHTING_NODE_CHANNEL_2 = 0x01, /* Channel 2 */
CORSAIR_LIGHTING_NODE_NUM_CHANNELS = 0x02, /* Number of channels */
};
enum
{
CORSAIR_LIGHTING_NODE_SPEED_FAST = 0x00, /* Fast speed */
CORSAIR_LIGHTING_NODE_SPEED_MEDIUM = 0x01, /* Medium speed */
CORSAIR_LIGHTING_NODE_SPEED_SLOW = 0x02, /* Slow speed */
};
enum
{
CORSAIR_LIGHTING_NODE_MODE_RAINBOW_WAVE = 0x00, /* Rainbow Wave mode */
CORSAIR_LIGHTING_NODE_MODE_COLOR_SHIFT = 0x01, /* Color Shift mode */
CORSAIR_LIGHTING_NODE_MODE_COLOR_PULSE = 0x02, /* Color Pulse mode */
CORSAIR_LIGHTING_NODE_MODE_COLOR_WAVE = 0x03, /* Color Wave mode */
CORSAIR_LIGHTING_NODE_MODE_STATIC = 0x04, /* Static mode */
CORSAIR_LIGHTING_NODE_MODE_TEMPERATURE = 0x05, /* Temperature mode */
CORSAIR_LIGHTING_NODE_MODE_VISOR = 0x06, /* Visor mode */
CORSAIR_LIGHTING_NODE_MODE_MARQUEE = 0x07, /* Marquee mode */
CORSAIR_LIGHTING_NODE_MODE_BLINK = 0x08, /* Blink mode */
CORSAIR_LIGHTING_NODE_MODE_SEQUENTIAL = 0x09, /* Sequential mode */
CORSAIR_LIGHTING_NODE_MODE_RAINBOW = 0x0A, /* Rainbow mode */
};
class CorsairLightingNodeController
{
public:
CorsairLightingNodeController(hid_device* dev_handle);
~CorsairLightingNodeController();
std::string GetFirmwareString();
unsigned int GetStripsOnChannel(unsigned int channel);
void SetChannelEffect(unsigned char channel,
unsigned char num_leds,
unsigned char mode,
unsigned char speed,
unsigned char direction,
bool random,
unsigned char red1,
unsigned char grn1,
unsigned char blu1,
unsigned char red2,
unsigned char grn2,
unsigned char blu2,
unsigned char red3,
unsigned char grn3,
unsigned char blu3
);
void SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors);
void KeepaliveThread();
private:
hid_device* dev;
std::string firmware_version;
clock_t last_commit_time;
void SendFirmwareRequest();
void SendDirect
(
unsigned char channel,
unsigned char start,
unsigned char count,
unsigned char color_channel,
unsigned char* color_data
);
void SendCommit();
void SendBegin
(
unsigned char channel
);
void SendEffectConfig
(
unsigned char channel,
unsigned char count,
unsigned char led_type,
unsigned char mode,
unsigned char speed,
unsigned char direction,
unsigned char change_style,
unsigned char color_0_red,
unsigned char color_0_green,
unsigned char color_0_blue,
unsigned char color_1_red,
unsigned char color_1_green,
unsigned char color_1_blue,
unsigned char color_2_red,
unsigned char color_2_green,
unsigned char color_2_blue,
unsigned short temperature_0,
unsigned short temperature_1,
unsigned short temperature_2
);
void SendTemperature();
void SendReset
(
unsigned char channel
);
void SendPortState
(
unsigned char channel,
unsigned char state
);
void SendBrightness();
void SendLEDCount();
void SendProtocol();
};
@@ -1,79 +0,0 @@
#include "CorsairLightingNodeController.h"
#include "RGBController.h"
#include "RGBController_CorsairLightingNode.h"
#include <vector>
#include <hidapi/hidapi.h>
#define CORSAIR_VID 0x1B1C
#define CORSAIR_LIGHTING_NODE_CORE_PID 0x0C1A
#define CORSAIR_LIGHTING_NODE_PRO_PID 0x0C0B
#define CORSAIR_COMMANDER_PRO_PID 0x0C10
#define CORSAIR_LS100_PID 0x0C1E
#define CORSAIR_1000D_OBSIDIAN_PID 0x1D00
#define CORSAIR_SPEC_OMEGA_RGB_PID 0x1D04
typedef struct
{
unsigned short usb_vid;
unsigned short usb_pid;
unsigned char channel_count;
const char * name;
} corsair_node_device;
#define CORSAIR_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
static const corsair_node_device device_list[] =
{
{ CORSAIR_VID, CORSAIR_LIGHTING_NODE_CORE_PID, 1, "Corsair Lighting Node Core" },
{ CORSAIR_VID, CORSAIR_LIGHTING_NODE_PRO_PID, 2, "Corsair Lighting Node Pro" },
{ CORSAIR_VID, CORSAIR_COMMANDER_PRO_PID, 2, "Corsair Commander Pro" },
{ CORSAIR_VID, CORSAIR_LS100_PID, 1, "Corsair LS100 Lighting Kit" },
{ CORSAIR_VID, CORSAIR_1000D_OBSIDIAN_PID, 2, "Corsair 1000D Obsidian" },
{ CORSAIR_VID, CORSAIR_SPEC_OMEGA_RGB_PID, 2, "Corsair SPEC OMEGA RGB" }
};
/******************************************************************************************\
* *
* DetectCorsairLightingNodeControllers *
* *
* Detect devices supported by the Corsair Lighting Node Pro driver *
* *
\******************************************************************************************/
void DetectCorsairLightingNodeControllers(std::vector<RGBController*> &rgb_controllers)
{
hid_device_info* info;
hid_device* dev;
hid_init();
for(std::size_t device_idx = 0; device_idx < CORSAIR_NUM_DEVICES; device_idx++)
{
dev = NULL;
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for Corsair Lighting Node Devices
while(info)
{
if((info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid))
{
dev = hid_open_path(info->path);
if( dev )
{
CorsairLightingNodeController* controller = new CorsairLightingNodeController(dev);
RGBController_CorsairLightingNode* rgb_controller = new RGBController_CorsairLightingNode(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
info = info->next;
}
}
} /* DetectCorsairLightingNodeControllers() */
@@ -1,550 +0,0 @@
/*-----------------------------------------*\
| CorsairPeripheralController.cpp |
| |
| Driver for Corsair RGB keyboard, mouse, |
| and mousemat lighting controller |
| |
| Adam Honse (CalcProgrammer1) 1/9/2020 |
\*-----------------------------------------*/
#include "CorsairPeripheralController.h"
#include <cstring>
using namespace std::chrono_literals;
static unsigned int keys[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12,
0x14, 0x15, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x24, 0x25, 0x26,
0x27, 0x28, 0x2A, 0x2B, 0x2C, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x42, 0x43, 0x44, 0x45, 0x48, 73, 74, 75, 76, 78,
79, 80, 81, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 96, 97,
98, 99, 100, 101, 102, 103, 104, 105, 108, 109, 110, 111, 112, 113, 115,
116, 117, 120, 121, 122, 123, 124, 126, 127, 128, 129, 132, 133, 134, 135,
136, 137, 139, 140, 141};
static unsigned int st100[] = { 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x04 };
static void send_usb_msg(hid_device* dev, char * data_pkt)
{
char usb_pkt[65];
usb_pkt[0] = 0x00;
for(int i = 1; i < 65; i++)
{
usb_pkt[i] = data_pkt[i-1];
}
int bytes = hid_send_feature_report(dev, (unsigned char *)usb_pkt, 65);
bytes++;
std::this_thread::sleep_for(1ms);
}
CorsairPeripheralController::CorsairPeripheralController(hid_device* dev_handle)
{
dev = dev_handle;
ReadFirmwareInfo();
SpecialFunctionControl();
LightingControl();
}
CorsairPeripheralController::~CorsairPeripheralController()
{
}
device_type CorsairPeripheralController::GetDeviceType()
{
return type;
}
std::string CorsairPeripheralController::GetFirmwareString()
{
return firmware_version;
}
void CorsairPeripheralController::SetLEDs(std::vector<RGBColor>colors)
{
switch(type)
{
case DEVICE_TYPE_KEYBOARD:
SetLEDsKeyboardFull(colors);
break;
case DEVICE_TYPE_MOUSE:
SetLEDsMouse(colors);
break;
case DEVICE_TYPE_MOUSEMAT:
SetLEDsMousemat(colors);
break;
case DEVICE_TYPE_HEADSET_STAND:
/*-----------------------------------------------------*\
| The logo zone of the ST100 is in the middle of the |
| base LED strip, so remap the colors so that the logo |
| is the last LED in the sequence. |
\*-----------------------------------------------------*/
std::vector<RGBColor> remap_colors;
remap_colors.resize(colors.size());
for(int i = 0; i < 9; i++)
{
remap_colors[st100[i]] = colors[i];
}
/*-----------------------------------------------------*\
| The ST100 uses the mousemat protocol |
\*-----------------------------------------------------*/
SetLEDsMousemat(remap_colors);
break;
}
}
void CorsairPeripheralController::SetLEDsKeyboardFull(std::vector<RGBColor> colors)
{
unsigned char red_val[144];
unsigned char grn_val[144];
unsigned char blu_val[144];
/*-----------------------------------------------------*\
| Zero out buffers |
\*-----------------------------------------------------*/
memset(red_val, 0x00, sizeof( red_val ));
memset(grn_val, 0x00, sizeof( grn_val ));
memset(blu_val, 0x00, sizeof( blu_val ));
/*-----------------------------------------------------*\
| Copy red, green, and blue components into buffers |
\*-----------------------------------------------------*/
for(std::size_t color_idx = 0; color_idx < colors.size(); color_idx++)
{
RGBColor color = colors[color_idx];
red_val[keys[color_idx]] = RGBGetRValue(color);
grn_val[keys[color_idx]] = RGBGetGValue(color);
blu_val[keys[color_idx]] = RGBGetBValue(color);
}
/*-----------------------------------------------------*\
| Send red bytes |
\*-----------------------------------------------------*/
StreamPacket(1, 60, &red_val[0]);
StreamPacket(2, 60, &red_val[60]);
StreamPacket(3, 24, &red_val[120]);
SubmitKeyboardFullColors(1, 3, 1);
/*-----------------------------------------------------*\
| Send green bytes |
\*-----------------------------------------------------*/
StreamPacket(1, 60, &grn_val[0]);
StreamPacket(2, 60, &grn_val[60]);
StreamPacket(3, 24, &grn_val[120]);
SubmitKeyboardFullColors(2, 3, 1);
/*-----------------------------------------------------*\
| Send blue bytes |
\*-----------------------------------------------------*/
StreamPacket(1, 60, &blu_val[0]);
StreamPacket(2, 60, &blu_val[60]);
StreamPacket(3, 24, &blu_val[120]);
SubmitKeyboardFullColors(3, 3, 2);
}
void CorsairPeripheralController::SetLEDsMouse(std::vector<RGBColor> colors)
{
SubmitMouseColors(colors.size(), &colors[0]);
}
void CorsairPeripheralController::SetLEDsMousemat(std::vector<RGBColor> colors)
{
SubmitMousematColors(colors.size(), &colors[0]);
}
void CorsairPeripheralController::SetLEDsKeyboardLimited(std::vector<RGBColor> colors)
{
unsigned char data_pkt[216];
unsigned char red_val[144];
unsigned char grn_val[144];
unsigned char blu_val[144];
/*-----------------------------------------------------*\
| Zero out buffers |
\*-----------------------------------------------------*/
memset(data_pkt, 0x00, sizeof( data_pkt ));
memset(red_val, 0x00, sizeof( red_val ));
memset(grn_val, 0x00, sizeof( grn_val ));
memset(blu_val, 0x00, sizeof( blu_val ));
/*-----------------------------------------------------*\
| Scale color values to 9-bit |
\*-----------------------------------------------------*/
for(std::size_t color_idx = 0; color_idx < colors.size(); color_idx++)
{
RGBColor color = colors[color_idx];
unsigned char red = RGBGetRValue(color);
unsigned char grn = RGBGetGValue(color);
unsigned char blu = RGBGetBValue(color);
if( red > 7 ) red = 7;
if( grn > 7 ) grn = 7;
if( blu > 7 ) blu = 7;
red = 7 - red;
grn = 7 - grn;
blu = 7 - blu;
red_val[keys[color_idx]] = red;
grn_val[keys[color_idx]] = grn;
blu_val[keys[color_idx]] = blu;
}
/*-----------------------------------------------------*\
| Pack the color values, 2 values per byte |
\*-----------------------------------------------------*/
for(int red_idx = 0; red_idx < 72; red_idx++)
{
data_pkt[red_idx] = red_val[(red_idx * 2) + 1] << 4 | red_val[red_idx * 2];
}
for(int grn_idx = 0; grn_idx < 72; grn_idx++)
{
data_pkt[grn_idx + 72] = grn_val[(grn_idx * 2) + 1] << 4 | grn_val[grn_idx * 2];
}
for(int blu_idx = 0; blu_idx < 72; blu_idx++)
{
data_pkt[blu_idx + 144] = blu_val[(blu_idx * 2) + 1] << 4 | blu_val[blu_idx * 2];
}
/*-----------------------------------------------------*\
| Send the packets |
\*-----------------------------------------------------*/
StreamPacket(1, 60, &data_pkt[0]);
StreamPacket(2, 60, &data_pkt[60]);
StreamPacket(3, 60, &data_pkt[120]);
StreamPacket(4, 36, &data_pkt[180]);
SubmitKeyboardLimitedColors(216);
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void CorsairPeripheralController::LightingControl()
{
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_LIGHTING_CONTROL;
usb_buf[0x02] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
/*-----------------------------------------------------*\
| Lighting control byte needs to be 3 for keyboards and |
| headset stand, 1 for mice and mousepads |
\*-----------------------------------------------------*/
switch(type)
{
default:
case DEVICE_TYPE_KEYBOARD:
usb_buf[0x04] = 0x03;
break;
case DEVICE_TYPE_MOUSE:
usb_buf[0x04] = 0x01;
break;
case DEVICE_TYPE_MOUSEMAT:
usb_buf[0x04] = 0x04;
break;
case DEVICE_TYPE_HEADSET_STAND:
usb_buf[0x04] = 0x03;
break;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf);
}
void CorsairPeripheralController::SpecialFunctionControl()
{
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_SPECIAL_FUNCTION;
usb_buf[0x02] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf);
}
void CorsairPeripheralController::ReadFirmwareInfo()
{
int actual;
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Read Firmware Info packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_READ;
usb_buf[0x01] = CORSAIR_PROPERTY_FIRMWARE_INFO;
/*-----------------------------------------------------*\
| Send packet and try reading it using an HID read |
| If that fails, repeat the send and read the reply as |
| a feature report. |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char*)usb_buf, 64);
actual = hid_read_timeout(dev, (unsigned char*)usb_buf, 64, 1000);
if(actual == 0)
{
/*-------------------------------------------------*\
| Zero out buffer |
\*-------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-------------------------------------------------*\
| Set up Read Firmware Info packet |
\*-------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_READ;
usb_buf[0x01] = CORSAIR_PROPERTY_FIRMWARE_INFO;
hid_write(dev, (unsigned char*)usb_buf, 64);
actual = hid_get_feature_report(dev, (unsigned char*)usb_buf, 64);
}
/*-----------------------------------------------------*\
| Get device type |
| 0xC0 Device is a keyboard |
| 0xC1 Device is a mouse |
| 0xC2 Device is a mousepad or headset stand |
\*-----------------------------------------------------*/
switch((unsigned char)usb_buf[0x14])
{
case 0xC0:
type = DEVICE_TYPE_KEYBOARD;
break;
case 0xC1:
type = DEVICE_TYPE_MOUSE;
break;
case 0xC2:
{
unsigned short pid = (unsigned short)(usb_buf[0x0F] << 8) + (unsigned char)(usb_buf[0x0E]);
switch(pid)
{
case 0x0A34:
type = DEVICE_TYPE_HEADSET_STAND;
break;
default:
type = DEVICE_TYPE_MOUSEMAT;
break;
}
}
break;
default:
type = DEVICE_TYPE_UNKNOWN;
break;
}
/*-----------------------------------------------------*\
| Format firmware version string if device type is valid|
\*-----------------------------------------------------*/
if(type != DEVICE_TYPE_UNKNOWN)
{
firmware_version = std::to_string(usb_buf[0x09]) + "." + std::to_string(usb_buf[0x08]);
}
}
void CorsairPeripheralController::StreamPacket
(
unsigned char packet_id,
unsigned char data_sz,
unsigned char* data_ptr
)
{
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Stream packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_STREAM;
usb_buf[0x01] = packet_id;
usb_buf[0x02] = data_sz;
/*-----------------------------------------------------*\
| Copy in data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x04], data_ptr, data_sz);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 64);
}
void CorsairPeripheralController::SubmitKeyboardFullColors
(
unsigned char color_channel,
unsigned char packet_count,
unsigned char finish_val
)
{
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Keyboard 24-Bit Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_24;
usb_buf[0x02] = color_channel;
usb_buf[0x03] = packet_count;
usb_buf[0x04] = finish_val;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 64);
}
void CorsairPeripheralController::SubmitKeyboardLimitedColors
(
unsigned char byte_count
)
{
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Keyboard 9-Bit Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_9;
usb_buf[0x04] = byte_count;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 64);
}
void CorsairPeripheralController::SubmitMouseColors
(
unsigned char num_zones,
RGBColor * color_data
)
{
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Mouse Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
usb_buf[0x02] = num_zones;
usb_buf[0x03] = 0x00;
/*-----------------------------------------------------*\
| Copy in colors in <ZONE> <RED> <GREEN> <BLUE> order |
\*-----------------------------------------------------*/
for(unsigned int zone_idx = 0; zone_idx < num_zones; zone_idx++)
{
usb_buf[(zone_idx * 4) + 4] = zone_idx;
usb_buf[(zone_idx * 4) + 5] = RGBGetRValue(color_data[zone_idx]);
usb_buf[(zone_idx * 4) + 6] = RGBGetGValue(color_data[zone_idx]);
usb_buf[(zone_idx * 4) + 7] = RGBGetBValue(color_data[zone_idx]);
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 64);
}
void CorsairPeripheralController::SubmitMousematColors
(
unsigned char num_zones,
RGBColor * color_data
)
{
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Mouse Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
usb_buf[0x02] = num_zones;
usb_buf[0x03] = 0x00;
/*-----------------------------------------------------*\
| Copy in colors in <RED> <GREEN> <BLUE> order |
\*-----------------------------------------------------*/
for(unsigned int zone_idx = 0; zone_idx < num_zones; zone_idx++)
{
usb_buf[(zone_idx * 3) + 4] = RGBGetRValue(color_data[zone_idx]);
usb_buf[(zone_idx * 3) + 5] = RGBGetGValue(color_data[zone_idx]);
usb_buf[(zone_idx * 3) + 6] = RGBGetBValue(color_data[zone_idx]);
}
/*-----------------------------------------------------*\
| Send packet using feature reports, as headset stand |
| seems to not update completely using HID writes |
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf);
}
@@ -1,106 +0,0 @@
/*-----------------------------------------*\
| CorsairPeripheralController.h |
| |
| Definitions and types for Corsair RGB |
| keyboard, mouse, and mousemat lighting |
| controller |
| |
| Adam Honse (CalcProgrammer1) 1/9/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
CORSAIR_COMMAND_WRITE = 0x07,
CORSAIR_COMMAND_READ = 0x0E,
CORSAIR_COMMAND_STREAM = 0x7F
};
enum
{
CORSAIR_PROPERTY_FIRMWARE_INFO = 0x01,
CORSAIR_PROPERTY_RESET = 0x02,
CORSAIR_PROPERTY_SPECIAL_FUNCTION = 0x04,
CORSAIR_PROPERTY_LIGHTING_CONTROL = 0x05,
CORSAIR_PROPERTY_HARDWARE_PROFILE = 0x13,
CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR = 0x22,
CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_9 = 0x27,
CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_24 = 0x28,
};
enum
{
CORSAIR_LIGHTING_CONTROL_HARDWARE = 0x01,
CORSAIR_LIGHTING_CONTROL_SOFTWARE = 0x02
};
enum
{
CORSAIR_COLOR_CHANNEL_RED = 0x01,
CORSAIR_COLOR_CHANNEL_GREEN = 0x02,
CORSAIR_COLOR_CHANNEL_BLUE = 0x03
};
class CorsairPeripheralController
{
public:
CorsairPeripheralController(hid_device* dev_handle);
~CorsairPeripheralController();
device_type GetDeviceType();
std::string GetFirmwareString();
void SetLEDs(std::vector<RGBColor> colors);
void SetLEDsKeyboardFull(std::vector<RGBColor> colors);
void SetLEDsKeyboardLimited(std::vector<RGBColor> colors);
void SetLEDsMouse(std::vector<RGBColor> colors);
void SetLEDsMousemat(std::vector<RGBColor> colors);
private:
hid_device* dev;
std::string firmware_version;
device_type type;
void LightingControl();
void SpecialFunctionControl();
void ReadFirmwareInfo();
void StreamPacket
(
unsigned char packet_id,
unsigned char data_sz,
unsigned char* data_ptr
);
void SubmitKeyboardFullColors
(
unsigned char color_channel,
unsigned char packet_count,
unsigned char finish_val
);
void SubmitKeyboardLimitedColors
(
unsigned char byte_count
);
void SubmitMouseColors
(
unsigned char num_zones,
RGBColor * color_data
);
void SubmitMousematColors
(
unsigned char num_zones,
RGBColor * color_data
);
};
@@ -1,153 +0,0 @@
#include "CorsairPeripheralController.h"
#include "RGBController.h"
#include "RGBController_CorsairPeripheral.h"
#include <vector>
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| Corsair vendor ID |
\*-----------------------------------------------------*/
#define CORSAIR_VID 0x1B1C
/*-----------------------------------------------------*\
| Keyboard product IDs |
| List taken from ckb-next |
| Non-RGB keyboards were omitted from this list |
\*-----------------------------------------------------*/
#define CORSAIR_K55_RGB_PID 0x1B3D
#define CORSAIR_K65_RGB_PID 0x1B17
#define CORSAIR_K65_LUX_RGB_PID 0x1B37
#define CORSAIR_K65_RGB_RAPIDFIRE_PID 0x1B39
#define CORSAIR_K68_RGB 0x1B4F
#define CORSAIR_K70_RGB_PID 0x1B13
#define CORSAIR_K70_LUX_RGB_PID 0x1B33
#define CORSAIR_K70_RGB_RAPIDFIRE_PID 0x1B38
#define CORSAIR_K70_RGB_MK2_PID 0x1B49
#define CORSAIR_K70_RGB_MK2_SE_PID 0x1B6B
#define CORSAIR_K70_RGB_MK2_LP_PID 0x1B55
#define CORSAIR_K95_RGB_PID 0x1B11
#define CORSAIR_K95_PLATINUM_PID 0x1B2D
#define CORSAIR_STRAFE_PID 0x1B20
#define CORSAIR_STRAFE_MK2_PID 0x1B48
/*-----------------------------------------------------*\
| Mouse product IDs |
| List taken from ckb-next |
\*-----------------------------------------------------*/
#define CORSAIR_M65_PRO_PID 0x1B2E
#define CORSAIR_M65_RGB_ELITE_PID 0x1B5A
/*-----------------------------------------------------*\
| Mousepad product IDs |
| List taken from ckb-next |
\*-----------------------------------------------------*/
#define CORSAIR_MM800_RGB_POLARIS_PID 0x1B3B
/*-----------------------------------------------------*\
| Headset Stand product IDs |
| List taken from ckb-next |
\*-----------------------------------------------------*/
#define CORSAIR_ST100_PID 0x0A34
typedef struct
{
unsigned short usb_vid;
unsigned short usb_pid;
unsigned char usb_interface;
const char * name;
} corsair_node_device;
#define CORSAIR_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
static const corsair_node_device device_list[] =
{
/*-----------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-----------------------------------------------------------------------------------------------------*/
// { CORSAIR_VID, CORSAIR_K55_RGB_PID, 1, "Corsair K55 RGB" }, //Not per-key, disabled for now
{ CORSAIR_VID, CORSAIR_K65_RGB_PID, 1, "Corsair K65 RGB" },
{ CORSAIR_VID, CORSAIR_K65_LUX_RGB_PID, 1, "Corsair K65 LUX RGB" },
{ CORSAIR_VID, CORSAIR_K65_RGB_RAPIDFIRE_PID, 1, "Corsair K65 RGB RAPIDFIRE" },
{ CORSAIR_VID, CORSAIR_K68_RGB, 1, "Corsair K68 RGB" },
{ CORSAIR_VID, CORSAIR_K70_RGB_PID, 1, "Corsair K70 RGB" },
{ CORSAIR_VID, CORSAIR_K70_LUX_RGB_PID, 1, "Corsair K70 LUX RGB" },
{ CORSAIR_VID, CORSAIR_K70_RGB_RAPIDFIRE_PID, 1, "Corsair K70 RGB RAPIDFIRE" },
{ CORSAIR_VID, CORSAIR_K70_RGB_MK2_PID, 1, "Corsair K70 RGB MK.2" },
{ CORSAIR_VID, CORSAIR_K70_RGB_MK2_SE_PID, 1, "Corsair K70 RGB MK.2 SE" },
{ CORSAIR_VID, CORSAIR_K70_RGB_MK2_LP_PID, 1, "Corsair K70 RGB MK.2 Low Profile" },
{ CORSAIR_VID, CORSAIR_K95_RGB_PID, 1, "Corsair K95 RGB" },
{ CORSAIR_VID, CORSAIR_K95_PLATINUM_PID, 1, "Corsair K95 RGB PLATINUM" },
{ CORSAIR_VID, CORSAIR_STRAFE_PID, 1, "Corsair Strafe" },
{ CORSAIR_VID, CORSAIR_STRAFE_MK2_PID, 1, "Corsair Strafe MK.2" },
/*-----------------------------------------------------------------------------------------------------*\
| Mice |
\*-----------------------------------------------------------------------------------------------------*/
{ CORSAIR_VID, CORSAIR_M65_PRO_PID, 1, "Corsair M65 PRO" },
{ CORSAIR_VID, CORSAIR_M65_RGB_ELITE_PID, 1, "Corsair M65 RGB Elite" },
/*-----------------------------------------------------------------------------------------------------*\
| Mousemats |
\*-----------------------------------------------------------------------------------------------------*/
{ CORSAIR_VID, CORSAIR_MM800_RGB_POLARIS_PID, 0, "Corsair MM800 RGB Polaris" },
/*-----------------------------------------------------------------------------------------------------*\
| Headset Stands |
\*-----------------------------------------------------------------------------------------------------*/
{ CORSAIR_VID, CORSAIR_ST100_PID, 0, "Corsair ST100 RGB" }
};
/******************************************************************************************\
* *
* DetectCorsairPeripheralControllers *
* *
* Tests the USB address to see if a Corsair RGB Keyboard controller exists there. *
* *
\******************************************************************************************/
void DetectCorsairPeripheralControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device_info* info;
hid_device* dev;
hid_init();
for(std::size_t device_idx = 0; device_idx < CORSAIR_NUM_DEVICES; device_idx++)
{
dev = NULL;
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for Corsair RGB Peripheral
while(info)
{
if((info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid)
&&(info->interface_number == device_list[device_idx].usb_interface))
{
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
if( dev )
{
CorsairPeripheralController* controller = new CorsairPeripheralController(dev);
if(controller->GetDeviceType() != DEVICE_TYPE_UNKNOWN)
{
RGBController_CorsairPeripheral* rgb_controller = new RGBController_CorsairPeripheral(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
}
}
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| CorsairVengeanceProController.cpp |
| CorsairProController.cpp |
| |
| Definitions and types for Corsair |
| Vengeance Pro RGB RAM lighting controller|
@@ -7,12 +7,21 @@
| Adam Honse (CalcProgrammer1) 6/30/2019 |
\*-----------------------------------------*/
#include "CorsairVengeanceProController.h"
#include "CorsairProController.h"
#include <cstring>
using namespace std::chrono_literals;
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
CorsairVengeanceProController::CorsairVengeanceProController(i2c_smbus_interface* bus, corsair_dev_id dev)
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
CorsairProController::CorsairProController(i2c_smbus_interface* bus, corsair_dev_id dev)
{
this->bus = bus;
this->dev = dev;
@@ -20,8 +29,6 @@ CorsairVengeanceProController::CorsairVengeanceProController(i2c_smbus_interface
strcpy(device_name, "Corsair Vengeance Pro RGB");
led_count = CORSAIR_PRO_LED_COUNT;
effect_mode = CORSAIR_PRO_MODE_STATIC;
for (unsigned int i = 0; i < led_count; i++)
{
led_red[i] = 0;
@@ -30,17 +37,17 @@ CorsairVengeanceProController::CorsairVengeanceProController(i2c_smbus_interface
}
}
CorsairVengeanceProController::~CorsairVengeanceProController()
CorsairProController::~CorsairProController()
{
}
std::string CorsairVengeanceProController::GetDeviceName()
std::string CorsairProController::GetDeviceName()
{
return(device_name);
}
std::string CorsairVengeanceProController::GetDeviceLocation()
std::string CorsairProController::GetDeviceLocation()
{
std::string return_string(bus->device_name);
char addr[5];
@@ -50,17 +57,12 @@ std::string CorsairVengeanceProController::GetDeviceLocation()
return(return_string);
}
unsigned int CorsairVengeanceProController::GetLEDCount()
unsigned int CorsairProController::GetLEDCount()
{
return(led_count);
}
unsigned char CorsairVengeanceProController::GetEffect()
{
return(effect_mode);
}
void CorsairVengeanceProController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
void CorsairProController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
{
for (unsigned int i = 0; i < led_count; i++)
{
@@ -70,19 +72,22 @@ void CorsairVengeanceProController::SetAllColors(unsigned char red, unsigned cha
}
}
void CorsairVengeanceProController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
void CorsairProController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
led_red[led] = red;
led_green[led] = green;
led_blue[led] = blue;
}
void CorsairVengeanceProController::ApplyColors()
void CorsairProController::ApplyColors()
{
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
bus->i2c_smbus_write_byte_data(dev, 0x26, 0x02);
std::this_thread::sleep_for(1ms);
Sleep(1);
bus->i2c_smbus_write_byte_data(dev, 0x21, 0x00);
std::this_thread::sleep_for(1ms);
Sleep(1);
for (int i = 0; i < 10; i++)
{
@@ -93,49 +98,32 @@ void CorsairVengeanceProController::ApplyColors()
}
bus->i2c_smbus_write_byte_data(dev, 0x82, 0x02);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void CorsairVengeanceProController::SetEffect(unsigned char mode,
unsigned char speed,
unsigned char direction,
bool random,
unsigned char red1,
unsigned char grn1,
unsigned char blu1,
unsigned char red2,
unsigned char grn2,
unsigned char blu2
)
void CorsairProController::SetEffect(unsigned char mode)
{
effect_mode = mode;
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
bus->i2c_smbus_write_byte_data(dev, 0x26, 0x01);
std::this_thread::sleep_for(1ms);
Sleep(1);
bus->i2c_smbus_write_byte_data(dev, 0x21, 0x00);
std::this_thread::sleep_for(1ms);
Sleep(1);
unsigned char random_byte;
if(random)
{
random_byte = CORSAIR_PRO_EFFECT_RANDOM_COLORS;
}
else
{
random_byte = CORSAIR_PRO_EFFECT_CUSTOM_COLORS;
}
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, effect_mode); //Mode
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, speed); //Speed
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, random_byte); //Custom color
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, direction); //Direction
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, red1); // Custom color 1 red
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, grn1); // Custom color 1 green
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, blu1); // Custom color 1 blue
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, mode); //Mode
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, CORSAIR_PRO_SPEED_MEDIUM); //Speed
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, CORSAIR_PRO_EFFECT_RANDOM_COLORS); //Custom color
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, CORSAIR_PRO_DIRECTION_UP); //Direction
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 1 red
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 1 green
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 1 blue
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0xFF);
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, red2); // Custom color 2 red
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, grn2); // Custom color 2 green
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, blu2); // Custom color 2 blue
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 2 red
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 2 green
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 2 blue
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0xFF);
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00);
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00);
@@ -148,15 +136,23 @@ void CorsairVengeanceProController::SetEffect(unsigned char mode,
bus->i2c_smbus_write_byte_data(dev, 0x82, 0x01);
WaitReady();
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
bool CorsairVengeanceProController::WaitReady()
void CorsairProController::SetCustom()
{
SetEffect(CORSAIR_PRO_MODE_STATIC);
}
bool CorsairProController::WaitReady()
{
int i = 0;
while (bus->i2c_smbus_read_byte_data(dev, 0x41) != 0x00)
{
i++;
std::this_thread::sleep_for(1ms);
Sleep(1);
}
return false;
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| CorsairVengeanceProController.h |
| CorsairProController.h |
| |
| Definitions and types for Corsair |
| Vengeance Pro RGB RAM lighting controller|
@@ -60,27 +60,17 @@ enum
CORSAIR_PRO_DIRECTION_HORIZONTAL = 0x03, /* Horizontal direction */
};
class CorsairVengeanceProController
class CorsairProController
{
public:
CorsairVengeanceProController(i2c_smbus_interface* bus, corsair_dev_id dev);
~CorsairVengeanceProController();
CorsairProController(i2c_smbus_interface* bus, corsair_dev_id dev);
~CorsairProController();
std::string GetDeviceName();
std::string GetDeviceLocation();
unsigned int GetLEDCount();
unsigned char GetEffect();
void SetEffect(unsigned char mode,
unsigned char speed,
unsigned char direction,
bool random,
unsigned char red1,
unsigned char grn1,
unsigned char blu1,
unsigned char red2,
unsigned char grn2,
unsigned char blu2
);
void SetEffect(unsigned char mode);
void SetCustom();
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);
@@ -90,7 +80,7 @@ public:
private:
char device_name[32];
unsigned int led_count;
unsigned char effect_mode;
unsigned char led_red[CORSAIR_PRO_LED_COUNT];
unsigned char led_green[CORSAIR_PRO_LED_COUNT];
unsigned char led_blue[CORSAIR_PRO_LED_COUNT];
@@ -0,0 +1,127 @@
#include "CorsairProController.h"
#include "RGBController.h"
#include "RGBController_CorsairPro.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
/******************************************************************************************\
* *
* TestForCorsairProController *
* *
* Tests the given address to see if a Corsair Pro controller exists there. *
* *
\******************************************************************************************/
bool TestForCorsairProController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
if (res >= 0)
{
pass = true;
res = bus->i2c_smbus_read_byte_data(address, 0x24);
if (res != 0x02)
{
pass = false;
}
res = bus->i2c_smbus_read_byte_data(address, 0x25);
if (res != 0x02)
{
pass = false;
}
res = bus->i2c_smbus_read_byte_data(address, 0x43);
if (res != 0x1C)
{
pass = false;
}
res = bus->i2c_smbus_read_byte_data(address, 0x44);
if (res != 0x03)
{
pass = false;
}
}
return(pass);
} /* TestForCorsairProController() */
/******************************************************************************************\
* *
* DetectCorsairProControllers *
* *
* Detect Corsair Pro controllers on the enumerated I2C busses. *
* *
* bus - pointer to i2c_smbus_interface where Aura device is connected *
* dev - I2C address of Aura device *
* *
\******************************************************************************************/
void DetectCorsairProControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
CorsairProController* new_corsair_pro;
RGBController_CorsairPro* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Check for Corsair controller at 0x58
if (TestForCorsairProController(busses[bus], 0x58))
{
new_corsair_pro = new CorsairProController(busses[bus], 0x58);
new_controller = new RGBController_CorsairPro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x59
if (TestForCorsairProController(busses[bus], 0x59))
{
new_corsair_pro = new CorsairProController(busses[bus], 0x59);
new_controller = new RGBController_CorsairPro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5A
if (TestForCorsairProController(busses[bus], 0x5A))
{
new_corsair_pro = new CorsairProController(busses[bus], 0x5A);
new_controller = new RGBController_CorsairPro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5B
if (TestForCorsairProController(busses[bus], 0x5B))
{
new_corsair_pro = new CorsairProController(busses[bus], 0x5B);
new_controller = new RGBController_CorsairPro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5C
if (TestForCorsairProController(busses[bus], 0x5C))
{
new_corsair_pro = new CorsairProController(busses[bus], 0x5C);
new_controller = new RGBController_CorsairPro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5D
if (TestForCorsairProController(busses[bus], 0x5D))
{
new_corsair_pro = new CorsairProController(busses[bus], 0x5D);
new_controller = new RGBController_CorsairPro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
}
} /* DetectCorsairProControllers() */
@@ -1,133 +0,0 @@
#include "CorsairVengeanceProController.h"
#include "RGBController.h"
#include "RGBController_CorsairVengeancePro.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std::chrono_literals;
/******************************************************************************************\
* *
* TestForCorsairVengeanceProController *
* *
* Tests the given address to see if a Corsair Pro controller exists there. *
* *
\******************************************************************************************/
bool TestForCorsairVengeanceProController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
if (res >= 0)
{
pass = true;
res = bus->i2c_smbus_read_byte_data(address, 0x43);
if (res != 0x1C)
{
pass = false;
}
res = bus->i2c_smbus_read_byte_data(address, 0x44);
if (!((res == 0x03) || (res == 0x04)))
{
pass = false;
}
}
std::this_thread::sleep_for(10ms);
return(pass);
} /* TestForCorsairVengeanceProController() */
/******************************************************************************************\
* *
* DetectCorsairVengeanceProControllers *
* *
* Detect Corsair Vengeance Pro controllers on the enumerated I2C busses. *
* *
* bus - pointer to i2c_smbus_interface where Aura device is connected *
* dev - I2C address of Aura device *
* *
\******************************************************************************************/
void DetectCorsairVengeanceProControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
CorsairVengeanceProController* new_corsair_pro;
RGBController_CorsairVengeancePro* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Check for Corsair controller at 0x58
if (TestForCorsairVengeanceProController(busses[bus], 0x58))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x58);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x59
if (TestForCorsairVengeanceProController(busses[bus], 0x59))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x59);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5A
if (TestForCorsairVengeanceProController(busses[bus], 0x5A))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5A);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5B
if (TestForCorsairVengeanceProController(busses[bus], 0x5B))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5B);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5C
if (TestForCorsairVengeanceProController(busses[bus], 0x5C))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5C);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5D
if (TestForCorsairVengeanceProController(busses[bus], 0x5D))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5D);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5E
if (TestForCorsairVengeanceProController(busses[bus], 0x5E))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5E);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
// Check for Corsair controller at 0x5F
if (TestForCorsairVengeanceProController(busses[bus], 0x5F))
{
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5F);
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
rgb_controllers.push_back(new_controller);
}
}
} /* DetectCorsairVengeanceProControllers() */
@@ -1,150 +0,0 @@
/*-----------------------------------------*\
| CrucialController.cpp |
| |
| Driver for Crucial Ballistix RGB lighting|
| controller |
| |
| Adam Honse (CalcProgrammer1) 1/19/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include "CrucialController.h"
#include <cstring>
CrucialController::CrucialController(i2c_smbus_interface* bus, crucial_dev_id dev)
{
this->bus = bus;
this->dev = dev;
}
CrucialController::~CrucialController()
{
}
std::string CrucialController::GetDeviceName()
{
return(device_name);
}
std::string CrucialController::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(return_string);
}
unsigned int CrucialController::GetLEDCount()
{
return(led_count);
}
void CrucialController::SetMode(unsigned char mode)
{
SendEffectMode(mode, 0x10);
}
void CrucialController::SetAllColorsDirect(RGBColor* colors)
{
SendDirectColors(colors);
}
void CrucialController::SetAllColorsEffect(RGBColor* colors)
{
for(int led_idx = 0; led_idx < 8; led_idx++)
{
unsigned char red = RGBGetRValue(colors[led_idx]);
unsigned char grn = RGBGetGValue(colors[led_idx]);
unsigned char blu = RGBGetBValue(colors[led_idx]);
SendEffectColor(led_idx, red, grn, blu);
}
}
void CrucialController::SendBrightness(unsigned char brightness)
{
CrucialRegisterWrite(0x82EE, 0xFF);
CrucialRegisterWrite(0x82EF, brightness);
CrucialRegisterWrite(0x82F0, 0x83);
}
void CrucialController::SendEffectMode(unsigned char mode, unsigned char speed)
{
CrucialRegisterWrite(0x820F, mode);
CrucialRegisterWrite(0x82EE, 0x00);
CrucialRegisterWrite(0x82EF, speed);
CrucialRegisterWrite(0x82F0, 0x84);
}
void CrucialController::SendDirectColors(RGBColor* color_buf)
{
//Red Channels
CrucialRegisterWrite(0x8300, RGBGetRValue(color_buf[0]));
CrucialRegisterWrite(0x8301, RGBGetRValue(color_buf[1]));
CrucialRegisterWrite(0x8302, RGBGetRValue(color_buf[2]));
CrucialRegisterWrite(0x8303, RGBGetRValue(color_buf[3]));
CrucialRegisterWrite(0x8304, RGBGetRValue(color_buf[4]));
CrucialRegisterWrite(0x8305, RGBGetRValue(color_buf[5]));
CrucialRegisterWrite(0x8306, RGBGetRValue(color_buf[6]));
CrucialRegisterWrite(0x8307, RGBGetRValue(color_buf[7]));
//Green Channels
CrucialRegisterWrite(0x8340, RGBGetGValue(color_buf[0]));
CrucialRegisterWrite(0x8341, RGBGetGValue(color_buf[1]));
CrucialRegisterWrite(0x8342, RGBGetGValue(color_buf[2]));
CrucialRegisterWrite(0x8343, RGBGetGValue(color_buf[3]));
CrucialRegisterWrite(0x8344, RGBGetGValue(color_buf[4]));
CrucialRegisterWrite(0x8345, RGBGetGValue(color_buf[5]));
CrucialRegisterWrite(0x8346, RGBGetGValue(color_buf[6]));
CrucialRegisterWrite(0x8347, RGBGetGValue(color_buf[7]));
//Blue Channels
CrucialRegisterWrite(0x8380, RGBGetBValue(color_buf[0]));
CrucialRegisterWrite(0x8381, RGBGetBValue(color_buf[1]));
CrucialRegisterWrite(0x8382, RGBGetBValue(color_buf[2]));
CrucialRegisterWrite(0x8383, RGBGetBValue(color_buf[3]));
CrucialRegisterWrite(0x8384, RGBGetBValue(color_buf[4]));
CrucialRegisterWrite(0x8385, RGBGetBValue(color_buf[5]));
CrucialRegisterWrite(0x8386, RGBGetBValue(color_buf[6]));
CrucialRegisterWrite(0x8387, RGBGetBValue(color_buf[7]));
}
unsigned char CrucialController::CrucialRegisterRead(crucial_register reg)
{
//Write Crucial register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
//Read Crucial value
return(bus->i2c_smbus_read_byte_data(dev, 0x81));
}
void CrucialController::CrucialRegisterWrite(crucial_register reg, unsigned char val)
{
//Write Crucial register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
//Write Crucial value
bus->i2c_smbus_write_byte_data(dev, 0x01, val);
}
void CrucialController::SendEffectColor
(
unsigned int led_idx,
unsigned int red,
unsigned int green,
unsigned int blue
)
{
CrucialRegisterWrite(0x82E9, (1 << led_idx));
CrucialRegisterWrite(0x82EA, 0x00);
CrucialRegisterWrite(0x82EB, 0x00);
CrucialRegisterWrite(0x82EC, 0x00);
CrucialRegisterWrite(0x82ED, red);
CrucialRegisterWrite(0x82EE, green);
CrucialRegisterWrite(0x82EF, blue);
CrucialRegisterWrite(0x82F0, 0x01);
}
@@ -1,70 +0,0 @@
/*-----------------------------------------*\
| CrucialController.h |
| |
| Definitions and types for Crucial |
| Ballistix RGB lighting controller |
| |
| Adam Honse (CalcProgrammer1) 1/19/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char crucial_dev_id;
typedef unsigned short crucial_register;
enum
{
CRUCIAL_MODE_SHIFT = 0x1F, /* Shift effect mode */
CRUCIAL_MODE_GRADIENT_SHIFT = 0x2F, /* Gradient shift mode */
CRUCIAL_MODE_FILL = 0x3F, /* Fill effect mode */
CRUCIAL_MODE_STACK = 0x4F, /* Stack effect mode */
CRUCIAL_MODE_DOUBLE_STACK = 0x5F, /* Double stack effect mode */
CRUCIAL_MODE_BREATHING = 0x6F, /* Breathing effect mode */
CRUCIAL_MODE_MOTION_POINT = 0x7F, /* Motion point effect mode */
CRUCIAL_MODE_INSIDE_OUT = 0x8F, /* Inside out effect mode */
CRUCIAL_MODE_COLOR_STEP = 0x9F, /* Color step effect mode */
CRUCIAL_MODE_WATER_WAVE = 0xAF, /* Water wave effect mode */
CRUCIAL_MODE_FLASHING = 0xBF, /* Flashing effect mode */
CRUCIAL_MODE_STATIC = 0xCF, /* Static effect mode */
};
class CrucialController
{
public:
CrucialController(i2c_smbus_interface* bus, crucial_dev_id dev);
~CrucialController();
std::string GetDeviceName();
std::string GetDeviceLocation();
unsigned int GetLEDCount();
void SetAllColorsDirect(RGBColor* colors);
void SetAllColorsEffect(RGBColor* colors);
void SetMode(unsigned char mode);
unsigned char CrucialRegisterRead(crucial_register reg);
void CrucialRegisterWrite(crucial_register reg, unsigned char val);
private:
char device_name[16];
unsigned char config_table[64];
unsigned int led_count;
unsigned char channel_cfg;
i2c_smbus_interface * bus;
crucial_dev_id dev;
void SendEffectColor
(
unsigned int led_idx,
unsigned int red,
unsigned int green,
unsigned int blue
);
void SendDirectColors(RGBColor* color_buf);
void SendBrightness(unsigned char brightness);
void SendEffectMode(unsigned char mode, unsigned char speed);
};
@@ -1,88 +0,0 @@
#include "CrucialController.h"
#include "RGBController.h"
#include "RGBController_Crucial.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
/*----------------------------------------------------------------------*\
| This list contains the available SMBus addresses for Crucial RAM |
\*----------------------------------------------------------------------*/
#define CRUCIAL_ADDRESS_COUNT 4
static const unsigned char crucial_addresses[] =
{
0x20,
0x21,
0x22,
0x23
};
/******************************************************************************************\
* *
* TestForCrucialController *
* *
* Tests the given address to see if an Crucial controller exists there. First does a*
* quick write to test for a response, and if so does a simple read at 0xA0 to test *
* for incrementing values 0...F which was observed at this location during data dump *
* *
\******************************************************************************************/
bool TestForCrucialController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
if (res >= 0)
{
pass = true;
for (int i = 0xA0; i < 0xB0; i++)
{
res = bus->i2c_smbus_read_byte_data(address, i);
if (res != (i - 0xA0))
{
pass = false;
}
}
}
return(pass);
} /* TestForCrucialController() */
/******************************************************************************************\
* *
* DetectCrucialControllers *
* *
* Detect Crucial controllers on the enumerated I2C busses. *
* *
* bus - pointer to i2c_smbus_interface where Aura device is connected *
* dev - I2C address of Aura device *
* *
\******************************************************************************************/
void DetectCrucialControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
CrucialController* new_crucial;
RGBController_Crucial* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Add Crucial controllers
for (unsigned int address_list_idx = 0; address_list_idx < CRUCIAL_ADDRESS_COUNT; address_list_idx++)
{
if (TestForCrucialController(busses[bus], crucial_addresses[address_list_idx]))
{
new_crucial = new CrucialController(busses[bus], crucial_addresses[address_list_idx]);
new_controller = new RGBController_Crucial(new_crucial);
rgb_controllers.push_back(new_controller);
}
}
}
} /* DetectCrucialControllers() */
@@ -1,278 +0,0 @@
/*-----------------------------------------*\
| RGBController_GloriousModelO.cpp |
| |
| Definitions and types for Glorious |
| and other Mice |
| |
| Niels Westphal (crashniels) 20/5/2020 |
\*-----------------------------------------*/
#include "GloriousModelOController.h"
#include <cstring>
using namespace std::chrono_literals;
GloriousModelOController::GloriousModelOController(hid_device* dev_handle)
{
dev = dev_handle;
strcpy(device_name, "Glorious Mouse");
led_count = 1;
current_mode = GLORIOUS_MODE_STATIC;
current_speed = GLORIOUS_SPEED_NORMAL;
current_direction = GLORIOUS_DIRECTION_UP;
}
GloriousModelOController::~GloriousModelOController()
{
}
std::string GloriousModelOController::GetDeviceName()
{
return(device_name);
}
unsigned int GloriousModelOController::GetLEDCount()
{
return(led_count);
}
void GloriousModelOController::SetLEDColor(RGBColor* color_buf)
{
unsigned char usb_buf[520] =
{
0x04, 0x11, 0x00, 0x7b,
0x00, 0x00, 0x00, 0x00, 0x64, 0x06, 0x04, 0x24,
0xf0, 0x03, 0x07, 0x0f, 0x1f, 0x31, 0x63, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x41, 0x01, 0x40, 0xff, 0xff, 0xff,
0x42, 0x07, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff,
0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x43,
0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x42, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x42, 0x02, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
usb_buf[0x0B] = 0x24;
usb_buf[0x35] = GLORIOUS_MODE_STATIC;
usb_buf[0x38] = 0x40; //max brightness
usb_buf[0x39] = RGBGetRValue(color_buf[0]);
usb_buf[0x3A] = RGBGetBValue(color_buf[0]);
usb_buf[0x3B] = RGBGetGValue(color_buf[0]);
//DPI Button
/*
usb_buf[0x0B] = 0x44; //third DPI
usb_buf[0x26] = red;
usb_buf[0x27] = blue;
usb_buf[0x28] = green;
*/
hid_send_feature_report(dev, usb_buf, sizeof(usb_buf));
std::this_thread::sleep_for(1ms);
}
void GloriousModelOController::SetMode(unsigned char mode,
unsigned char speed,
unsigned char direction,
RGBColor* color_buf)
{
unsigned char usb_buf[520] =
{
0x04, 0x11, 0x00, 0x7b,
0x00, 0x00, 0x00, 0x00, 0x64, 0x06, 0x04, 0x24,
0xf0, 0x03, 0x07, 0x0f, 0x1f, 0x31, 0x63, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x41, 0x01, 0x40, 0xff, 0xff, 0xff,
0x42, 0x07, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff,
0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x43,
0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x42, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x42, 0x02, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
usb_buf[0x35] = mode;
switch (mode)
{
case GLORIOUS_MODE_OFF:
usb_buf[0x81] = 0x00; //mode 0 either 0x00 or 0x03
break;
case GLORIOUS_MODE_RAINBOW:
usb_buf[0x36] = speed;
usb_buf[0x37] = direction;
break;
case GLORIOUS_MODE_SPECTRUM_BREATING:
//colours not yet researched
usb_buf[0x3C] = speed; //speed for mode 3
usb_buf[0x3D] = 0x07; //maybe some kind of bank change?+
//usb_buf[0x3D] = 0x06;
usb_buf[0x3E] = RGBGetRValue(color_buf[0]); //mode 3 red 1
usb_buf[0x3F] = RGBGetBValue(color_buf[0]); //mode 3 blue 1
usb_buf[0x40] = RGBGetGValue(color_buf[0]); //mode 3 green 1
usb_buf[0x41] = RGBGetRValue(color_buf[1]); //mode 3 red 2
usb_buf[0x42] = RGBGetBValue(color_buf[1]); //mode 3 blue 2
usb_buf[0x43] = RGBGetGValue(color_buf[1]); //mode 3 green 2
usb_buf[0x44] = RGBGetRValue(color_buf[2]); //mode 3 red 3
usb_buf[0x45] = RGBGetBValue(color_buf[2]); //mode 3 blue 3
usb_buf[0x46] = RGBGetGValue(color_buf[2]); //mode 3 green 3
usb_buf[0x47] = RGBGetRValue(color_buf[3]); //mode 3 red 4
usb_buf[0x48] = RGBGetBValue(color_buf[3]); //mode 3 blue 4
usb_buf[0x49] = RGBGetGValue(color_buf[3]); //mode 3 green 4
usb_buf[0x4A] = RGBGetRValue(color_buf[4]); //mode 3 red 5
usb_buf[0x4B] = RGBGetBValue(color_buf[4]); //mode 3 blue 5
usb_buf[0x4C] = RGBGetGValue(color_buf[4]); //mode 3 green 5
usb_buf[0x4D] = RGBGetRValue(color_buf[5]); //mode 3 red 6
usb_buf[0x4E] = RGBGetBValue(color_buf[5]); //mode 3 blue 6
usb_buf[0x4F] = RGBGetGValue(color_buf[5]); //mode 3 green 6
usb_buf[0x50] = RGBGetRValue(color_buf[6]); //mode 3 red 7
usb_buf[0x51] = RGBGetBValue(color_buf[6]); //mode 3 blue 7
usb_buf[0x52] = RGBGetGValue(color_buf[6]); //mode 3 green 7
break;
case GLORIOUS_MODE_TAIL:
usb_buf[0x53] = speed; //Speed for mode 4
break;
case GLORIOUS_MODE_SPECTRUM_CYCLE:
usb_buf[0x54] = speed; //Speed for mode 1,2,5
break;
case GLORIOUS_MODE_RAVE:
usb_buf[0x74] = speed; //Speed for mode 7
usb_buf[0x75] = RGBGetRValue(color_buf[0]); //mode 7 red 1
usb_buf[0x76] = RGBGetBValue(color_buf[0]); //mode 7 blue 1
usb_buf[0x77] = RGBGetGValue(color_buf[0]); //mode 7 green 1
usb_buf[0x78] = RGBGetRValue(color_buf[1]); //mode 7 red 2
usb_buf[0x79] = RGBGetBValue(color_buf[1]); //mode 7 blue 2
usb_buf[0x7A] = RGBGetGValue(color_buf[1]); //mode 7 green 2
break;
case GLORIOUS_MODE_WAVE:
usb_buf[0x7C] = speed; //Speed for mode 9
break;
case GLORIOUS_MODE_BREATHING:
usb_buf[0x7D] = speed;
usb_buf[0x7E] = RGBGetRValue(color_buf[0]); //mode 0a red
usb_buf[0x7F] = RGBGetBValue(color_buf[0]); //mode 0a blue
usb_buf[0x80] = RGBGetGValue(color_buf[0]); //mode 0a green
default:
break;
}
hid_send_feature_report(dev, usb_buf, sizeof(usb_buf));
std::this_thread::sleep_for(1ms);
}
@@ -1,71 +0,0 @@
/*-----------------------------------------*\
| GloriousModelOController.h |
| |
| Definitions and types for Glorious |
| and other Mice |
| |
| Niels Westphal (crashniels) 20/5/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
enum
{
GLORIOUS_MODE_OFF = 0x00, //does nothing
GLORIOUS_MODE_RAINBOW = 0x01,
GLORIOUS_MODE_STATIC = 0x02,
GLORIOUS_MODE_SPECTRUM_BREATING = 0x03,
GLORIOUS_MODE_TAIL = 0x04,
GLORIOUS_MODE_SPECTRUM_CYCLE = 0x05,
GLORIOUS_MODE_RAVE = 0x07,
GLORIOUS_MODE_EPILEPSY = 0x08, //not in the official software
GLORIOUS_MODE_WAVE = 0x09,
GLORIOUS_MODE_BREATHING = 0x0a,
};
enum
{
GLORIOUS_SPEED_SLOW = 0x41,
GLORIOUS_SPEED_NORMAL = 0x42,
GLORIOUS_SPEED_FAST = 0x43,
};
enum
{
GLORIOUS_DIRECTION_UP = 0x00,
GLORIOUS_DIRECTION_DOWN = 0x01,
};
enum
{
GLORIOUS_MODE_BREATING_SLOW = 0x01,
GLORIOUS_MODE_BREATING_NORMAL = 0x02,
GLORIOUS_MODE_BREATING_FAST = 0x03,
};
class GloriousModelOController
{
public:
GloriousModelOController(hid_device* dev_handle);
~GloriousModelOController();
std::string GetDeviceName();
unsigned int GetLEDCount();
void SetLEDColor(RGBColor* color_buf);
void SetMode(unsigned char mode, unsigned char speed, unsigned char direction, RGBColor* color_buf);
private:
hid_device* dev;
char device_name[32];
unsigned int led_count;
unsigned char current_mode;
unsigned char current_speed;
unsigned char current_direction;
};
@@ -1,55 +0,0 @@
#include "GloriousModelOController.h"
#include "RGBController.h"
#include "RGBController_GloriousModelO.h"
#include <vector>
#include <hidapi/hidapi.h>
#define Glorious_Model_O_VID 0x258A
#define Glorious_Model_O_PID 0x0036
/******************************************************************************************\
* *
* DetectGloriousModelController *
* *
* Tests the USB address to see if a Glorious Model O controller exists there. *
* *
\******************************************************************************************/
void DetectGloriousModelOControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device_info* info;
hid_device* dev = NULL;
hid_init();
dev = NULL;
info = hid_enumerate(Glorious_Model_O_VID, Glorious_Model_O_PID);
//Look for Glorious Model O
while(info)
{
if((info->vendor_id == Glorious_Model_O_VID)
&&(info->product_id == Glorious_Model_O_PID)
&&(info->interface_number == 1))
{
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
if( dev )
{
GloriousModelOController* controller = new GloriousModelOController(dev);
RGBController_GloriousModelO* rgb_controller = new RGBController_GloriousModelO(controller);
rgb_controller->name = "Glorious Mouse";
rgb_controllers.push_back(rgb_controller);
}
}
@@ -0,0 +1,239 @@
/*---------------------------------------------------------*\
| Processing Code for NZXT Hue 2 |
| |
| Adam Honse ([email protected]), 12/29/2016 |
\*---------------------------------------------------------*/
#include "Hue2Controller.h"
#include <fstream>
#include <iostream>
#include <string>
Hue2Controller::Hue2Controller(libusb_device_handle* dev_handle)
{
dev = dev_handle;
GetStripsOnChannel(HUE_2_CHANNEL_1);
}
Hue2Controller::~Hue2Controller()
{
}
unsigned int Hue2Controller::GetStripsOnChannel(unsigned int /*channel*/)
{
unsigned int ret_val = 0;
unsigned char usb_buf[] =
{
0x20, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
int actual = 0;
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x81, usb_buf, 64, &actual, 0);
for(int chan = 0; chan < 4; chan++)
{
unsigned int start = 0x0F + (6 * chan);
unsigned int num_leds_on_channel = 0;
for(int dev = 0; dev < 6; dev++)
{
switch(usb_buf[start + dev])
{
case 0x01: //Hue 1 strip
num_leds_on_channel += 10;
break;
case 0x04: //Hue 2 strip
num_leds_on_channel += 10;
break;
case 0x0B: //Aer 2 fan
num_leds_on_channel += 8;
break;
default:
break;
}
}
channel_leds[chan] = num_leds_on_channel;
}
return(ret_val);
}
void Hue2Controller::SetChannelEffect(unsigned int channel, unsigned int mode, std::vector<RGBColor> colors)
{
unsigned char usb_buf[] =
{
0x28, 0x03, 0x00, 0x28,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
int actual = 0;
/*-----------------------------------------------------*\
| Set channel in USB packet |
\*-----------------------------------------------------*/
usb_buf[0x02] = 1 << channel;
/*-----------------------------------------------------*\
| Set mode in USB packet |
\*-----------------------------------------------------*/
usb_buf[0x04] = mode;
/*-----------------------------------------------------*\
| Set color count in USB packet |
\*-----------------------------------------------------*/
usb_buf[0x08] = colors.size();
/*-----------------------------------------------------*\
| Fill in color data |
\*-----------------------------------------------------*/
for (std::size_t idx = 0; idx < colors.size(); idx++)
{
int pixel_idx = idx * 3;
RGBColor color = colors[idx];
usb_buf[pixel_idx + 0x0A] = RGBGetGValue(color);
usb_buf[pixel_idx + 0x0B] = RGBGetRValue(color);
usb_buf[pixel_idx + 0x0C] = RGBGetBValue(color);
}
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
libusb_interrupt_transfer(dev, 0x81, usb_buf, 64, &actual, 0);
}
void Hue2Controller::SetChannelLEDs(unsigned int channel, std::vector<RGBColor> colors)
{
unsigned char usb_buf[] =
{
0x22, 0x10, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
unsigned char usb_apply[] =
{
0x22, 0xA0, 0x01, 0x00,
0x01, 0x00, 0x00, 0x28,
0x00, 0x00, 0x80, 0x00,
0x32, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
int actual;
std::size_t pkt_max = 20;
/*-----------------------------------------------------*\
| Set channel in USB packets |
\*-----------------------------------------------------*/
usb_buf[0x02] = 1 << channel;
usb_apply[0x02] = 1 << channel;
/*-----------------------------------------------------*\
| Send first packet for first 20 LEDs |
\*-----------------------------------------------------*/
if(pkt_max > colors.size())
{
pkt_max = colors.size();
}
for (std::size_t idx = 0; idx < pkt_max; idx++)
{
int pixel_idx = idx * 3;
RGBColor color = colors[idx];
usb_buf[pixel_idx + 4] = RGBGetGValue(color);
usb_buf[pixel_idx + 5] = RGBGetRValue(color);
usb_buf[pixel_idx + 6] = RGBGetBValue(color);
}
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
/*-----------------------------------------------------*\
| Send second packet for second 20 LEDs if necessary |
\*-----------------------------------------------------*/
for(int idx = 4; idx < 64; idx++)
{
usb_buf[idx] = 0;
}
usb_buf[0x01] = 0x11;
pkt_max = 0;
if (colors.size() > 20)
{
pkt_max = colors.size() - 20;
}
if(pkt_max > 0)
{
for (std::size_t idx = 0; idx < pkt_max; idx++)
{
int pixel_idx = idx * 3;
RGBColor color = colors[idx + 20];
usb_buf[pixel_idx + 4] = RGBGetGValue(color);
usb_buf[pixel_idx + 5] = RGBGetRValue(color);
usb_buf[pixel_idx + 6] = RGBGetBValue(color);
}
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
}
/*-----------------------------------------------------*\
| Send apply packet |
\*-----------------------------------------------------*/
libusb_interrupt_transfer(dev, 0x01, usb_apply, 64, &actual, 0);
}
@@ -0,0 +1,59 @@
/*---------------------------------------------------------*\
| Definitions for NZXT Hue 2 |
| |
| Adam Honse ([email protected]), 12/29/2016 |
\*---------------------------------------------------------*/
#include "RGBController.h"
#include <vector>
#include <libusb-1.0/libusb.h>
#pragma once
enum
{
HUE_2_CHANNEL_ALL = 0x00, /* All channels */
HUE_2_CHANNEL_1 = 0x01, /* Channel 1 */
HUE_2_CHANNEL_2 = 0x02, /* Channel 2 */
HUE_2_CHANNEL_3 = 0x03, /* Channel 3 */
HUE_2_CHANNEL_4 = 0x04, /* Channel 4 */
HUE_2_NUM_CHANNELS = 0x04 /* Number of channels */
};
enum
{
HUE_2_CHANNEL_1_IDX = 0x00, /* Channel 1 array index */
HUE_2_CHANNEL_2_IDX = 0x01, /* Channel 2 array index */
HUE_2_CHANNEL_3_IDX = 0x01, /* Channel 3 array index */
HUE_2_CHANNEL_4_IDX = 0x01, /* Channel 4 array index */
};
enum
{
HUE_2_MODE_FIXED = 0x00, /* Fixed colors mode */
HUE_2_MODE_FADING = 0x01, /* Fading mode */
HUE_2_MODE_SPECTRUM = 0x02, /* Spectrum cycle mode */
HUE_2_MODE_MARQUEE = 0x03, /* Marquee mode */
HUE_2_MODE_COVER_MARQUEE = 0x04, /* Cover marquee mode */
HUE_2_MODE_ALTERNATING = 0x05, /* Alternating mode */
HUE_2_MODE_PULSING = 0x06, /* Pulsing mode */
HUE_2_MODE_BREATHING = 0x07, /* Breathing mode */
HUE_2_NUM_MODES /* Number of Hue 2 modes */
};
class Hue2Controller
{
public:
Hue2Controller(libusb_device_handle* dev_handle);
~Hue2Controller();
char* GetLEDString();
unsigned int GetStripsOnChannel(unsigned int channel);
void SetChannelEffect(unsigned int channel, unsigned int mode, std::vector<RGBColor> colors);
void SetChannelLEDs(unsigned int channel, std::vector<RGBColor> colors);
unsigned int channel_leds[HUE_2_NUM_CHANNELS];
private:
libusb_device_handle* dev;
};
@@ -0,0 +1,37 @@
#include "Hue2Controller.h"
#include "RGBController.h"
#include "RGBController_Hue2.h"
#include <vector>
#include <libusb-1.0/libusb.h>
#define NZXT_HUE_2_VID 0x1E71
#define NZXT_HUE_2_PID 0x2001
/******************************************************************************************\
* *
* DetectHue2Controllers *
* *
* Detect devices supported by the Hue2 driver *
* * *
\******************************************************************************************/
void DetectHue2Controllers(std::vector<RGBController*> &rgb_controllers)
{
libusb_context * ctx;
libusb_init(&ctx);
//Look for NZXT Hue 2
libusb_device_handle * dev = libusb_open_device_with_vid_pid(ctx, NZXT_HUE_2_VID, NZXT_HUE_2_PID);
if( dev )
{
libusb_detach_kernel_driver(dev, 0);
libusb_claim_interface(dev, 0);
Hue2Controller* controller = new Hue2Controller(dev);
RGBController_Hue2* rgb_controller = new RGBController_Hue2(controller);
rgb_controllers.push_back(rgb_controller);
}
} /* DetectHuePlusControllers() */
@@ -9,9 +9,18 @@
#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
using namespace std::chrono_literals;
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
HuePlusController::HuePlusController()
{
@@ -22,22 +31,22 @@ HuePlusController::~HuePlusController()
{
}
void HuePlusController::Initialize(char* port)
void HuePlusController::Initialize(char* port_name)
{
strcpy(port_name, port);
strcpy(led_string, port_name);
serialport = new serial_port(port_name, HUE_PLUS_BAUD);
channel_leds[HUE_PLUS_CHANNEL_1_IDX] = GetLEDsOnChannel(HUE_PLUS_CHANNEL_1);
channel_leds[HUE_PLUS_CHANNEL_2_IDX] = GetLEDsOnChannel(HUE_PLUS_CHANNEL_2);
channel_leds[HUE_PLUS_CHANNEL_1_IDX] = GetStripsOnChannel(HUE_PLUS_CHANNEL_1) * 10;
channel_leds[HUE_PLUS_CHANNEL_2_IDX] = GetStripsOnChannel(HUE_PLUS_CHANNEL_2) * 10;
}
char* HuePlusController::GetLocation()
char* HuePlusController::GetLEDString()
{
return(port_name);
return(led_string);
}
unsigned int HuePlusController::GetLEDsOnChannel(unsigned int channel)
unsigned int HuePlusController::GetStripsOnChannel(unsigned int channel)
{
unsigned char serial_buf[] =
{
@@ -55,155 +64,60 @@ unsigned int HuePlusController::GetLEDsOnChannel(unsigned int channel)
serialport->serial_write((char *)serial_buf, 2);
serialport->serial_flush_tx();
std::this_thread::sleep_for(50ms);
Sleep(50);
int bytes_read = serialport->serial_read((char *)serial_buf, 5);
if(bytes_read == 5)
{
if(serial_buf[3] == 0x01)
{
ret_val = serial_buf[4] * 8;
}
else
{
ret_val += serial_buf[4] * 10;
}
ret_val = serial_buf[4];
}
return(ret_val);
}
void HuePlusController::SetChannelEffect
(
unsigned char channel,
unsigned char mode,
unsigned char speed,
bool direction,
RGBColor * colors,
unsigned int num_colors
)
void HuePlusController::SetChannelEffect(unsigned int channel, unsigned int mode, std::vector<RGBColor> colors)
{
unsigned char color_data[120];
/*-----------------------------------------------------*\
| If mode requires no colors, send packet |
\*-----------------------------------------------------*/
if(num_colors == 0)
unsigned char serial_buf[] =
{
/*-----------------------------------------------------*\
| Send mode without color data |
\*-----------------------------------------------------*/
SendPacket(channel, mode, direction, 0, speed, 0, NULL);
}
/*-----------------------------------------------------*\
| If mode requires indexed colors, send color index |
| packets for each mode color |
\*-----------------------------------------------------*/
else if(num_colors <= 8)
{
for(std::size_t color_idx = 0; color_idx < num_colors; color_idx++)
{
/*-----------------------------------------------------*\
| Fill in color data (40 entries per color) |
\*-----------------------------------------------------*/
for (std::size_t idx = 0; idx < 40; idx++)
{
int pixel_idx = idx * 3;
RGBColor color = colors[color_idx];
color_data[pixel_idx + 0x00] = RGBGetGValue(color);
color_data[pixel_idx + 0x01] = RGBGetRValue(color);
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
}
/*-----------------------------------------------------*\
| Send mode and color data |
\*-----------------------------------------------------*/
SendPacket(channel, mode, direction, color_idx, speed, 40, &color_data[0]);
}
}
/*-----------------------------------------------------*\
| If mode requires per-LED colors, fill colors array |
\*-----------------------------------------------------*/
else
{
/*-----------------------------------------------------*\
| Fill in color data (up to 40 colors) |
\*-----------------------------------------------------*/
for (std::size_t idx = 0; idx < num_colors; idx++)
{
int pixel_idx = idx * 3;
RGBColor color = colors[idx];
color_data[pixel_idx + 0x00] = RGBGetGValue(color);
color_data[pixel_idx + 0x01] = RGBGetRValue(color);
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
}
/*-----------------------------------------------------*\
| Send mode and color data |
\*-----------------------------------------------------*/
SendPacket(channel, mode, direction, 0, speed, num_colors, &color_data[0]);
}
}
void HuePlusController::SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
unsigned int num_colors
)
{
unsigned char color_data[120];
/*-----------------------------------------------------*\
| Fill in color data (up to 40 colors) |
\*-----------------------------------------------------*/
for (std::size_t idx = 0; idx < num_colors; idx++)
{
int pixel_idx = idx * 3;
RGBColor color = colors[idx];
color_data[pixel_idx + 0x00] = RGBGetGValue(color);
color_data[pixel_idx + 0x01] = RGBGetRValue(color);
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
}
/*-----------------------------------------------------*\
| Send color data |
\*-----------------------------------------------------*/
SendPacket(channel, HUE_PLUS_MODE_FIXED, false, 0, 0, num_colors, &color_data[0]);
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void HuePlusController::SendPacket
(
unsigned char channel,
unsigned char mode,
bool direction,
unsigned char color_idx,
unsigned char speed,
unsigned char color_count,
unsigned char* color_data
)
{
unsigned char serial_buf[125];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(serial_buf, 0x00, sizeof(serial_buf));
/*-----------------------------------------------------*\
| Set up Direct packet |
\*-----------------------------------------------------*/
serial_buf[0x00] = 0x4B;
0x4B, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00
};
/*-----------------------------------------------------*\
| Set channel in serial packet |
\*-----------------------------------------------------*/
serial_buf[0x01] = channel + 1;
serial_buf[0x01] = channel;
/*-----------------------------------------------------*\
| Set mode in serial packet |
@@ -211,29 +125,85 @@ void HuePlusController::SendPacket
serial_buf[0x02] = mode;
/*-----------------------------------------------------*\
| Set options bitfield in serial packet |
| Fill in color data |
\*-----------------------------------------------------*/
serial_buf[0x03] = 0;
serial_buf[0x03] |= direction ? ( 1 << 4 ) : 0;
for (std::size_t idx = 0; idx < colors.size(); idx++)
{
int pixel_idx = idx * 3;
RGBColor color = colors[idx];
serial_buf[pixel_idx + 0x05] = RGBGetGValue(color);
serial_buf[pixel_idx + 0x06] = RGBGetRValue(color);
serial_buf[pixel_idx + 0x07] = RGBGetBValue(color);
}
/*-----------------------------------------------------*\
| Set color index and speed in serial packet |
\*-----------------------------------------------------*/
serial_buf[0x04] = ( color_idx << 5 ) | speed;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
memcpy(&serial_buf[0x05], color_data, color_count * 3);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
serialport->serial_write((char *)serial_buf, HUE_PLUS_PACKET_SIZE);
serialport->serial_flush_tx();
Sleep(10);
}
void HuePlusController::SetChannelLEDs(unsigned int channel, std::vector<RGBColor> colors)
{
unsigned char serial_buf[] =
{
0x4B, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00
};
/*-----------------------------------------------------*\
| Delay to allow Hue+ device to ready for next packet |
| Set channel in serial packet |
\*-----------------------------------------------------*/
std::this_thread::sleep_for(20ms);
serial_buf[0x01] = channel;
/*-----------------------------------------------------*\
| Set mode in serial packet |
\*-----------------------------------------------------*/
serial_buf[0x02] = HUE_PLUS_MODE_FIXED;
/*-----------------------------------------------------*\
| Fill in color data |
\*-----------------------------------------------------*/
for (unsigned int idx = 0; idx < (colors.size() * 3); idx += 3)
{
int pixel_idx = idx / 3;
RGBColor color = colors[pixel_idx];
serial_buf[idx + 5] = RGBGetGValue(color);
serial_buf[idx + 6] = RGBGetRValue(color);
serial_buf[idx + 7] = RGBGetBValue(color);
}
serialport->serial_write((char *)serial_buf, HUE_PLUS_PACKET_SIZE);
serialport->serial_flush_tx();
Sleep(10);
}
@@ -41,27 +41,10 @@ enum
enum
{
HUE_PLUS_SPEED_SLOWEST = 0x00, /* Slowest speed */
HUE_PLUS_SPEED_SLOW = 0x01, /* Slow speed */
HUE_PLUS_SPEED_NORMAL = 0x02, /* Normal speed */
HUE_PLUS_SPEED_FAST = 0x03, /* Fast speed */
HUE_PLUS_SPEED_FASTEST = 0x04, /* Fastest speed */
};
enum
{
HUE_PLUS_MODE_FIXED = 0x00, /* Fixed colors mode */
HUE_PLUS_MODE_FADING = 0x01, /* Fading mode */
HUE_PLUS_MODE_SPECTRUM = 0x02, /* Spectrum cycle mode */
HUE_PLUS_MODE_MARQUEE = 0x03, /* Marquee mode */
HUE_PLUS_MODE_COVER_MARQUEE = 0x04, /* Cover marquee mode */
HUE_PLUS_MODE_ALTERNATING = 0x05, /* Alternating mode */
HUE_PLUS_MODE_PULSING = 0x06, /* Pulsing mode */
HUE_PLUS_MODE_BREATHING = 0x07, /* Breathing mode */
HUE_PLUS_MODE_ALERT = 0x08, /* Alert mode */
HUE_PLUS_MODE_CANDLELIGHT = 0x09, /* Candlelight mode */
HUE_PLUS_MODE_WINGS = 0x0C, /* Wings mode */
HUE_PLUS_MODE_WAVE = 0x0D, /* Wave mode */
HUE_PLUS_MODE_FIXED = 0x00, /* Fixed colors mode */
HUE_PLUS_MODE_FADING = 0x01, /* Fading mode */
HUE_PLUS_MODE_SPECTRUM = 0x02, /* Spectrum cycle mode */
HUE_PLUS_NUM_MODES /* Number of Hue Plus modes */
};
class HuePlusController
@@ -70,43 +53,18 @@ public:
HuePlusController();
~HuePlusController();
void Initialize(char* port);
char* GetLocation();
unsigned int GetLEDsOnChannel(unsigned int channel);
void SetChannelEffect
(
unsigned char channel,
unsigned char mode,
unsigned char speed,
bool direction,
RGBColor * colors,
unsigned int num_colors
);
void SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
unsigned int num_colors
);
void Initialize(char* port_name);
char* GetLEDString();
unsigned int GetStripsOnChannel(unsigned int channel);
void SetChannelEffect(unsigned int channel, unsigned int mode, std::vector<RGBColor> colors);
void SetChannelLEDs(unsigned int channel, std::vector<RGBColor> colors);
unsigned int channel_leds[HUE_PLUS_NUM_CHANNELS];
private:
char port_name[128];
serial_port *serialport;
void SendPacket
(
unsigned char channel,
unsigned char mode,
bool direction,
unsigned char color_idx,
unsigned char speed,
unsigned char color_count,
unsigned char* color_data
);
char led_string[1024];
char port_name[128];
serial_port *serialport;
};
#endif
@@ -12,7 +12,7 @@
* DetectHuePlusControllers *
* *
* Detect devices supported by the HuePlus driver *
* *
* * *
\******************************************************************************************/
void DetectHuePlusControllers(std::vector<RGBController*> &rgb_controllers)
@@ -1,16 +1,16 @@
/*-----------------------------------------*\
| HyperXDRAMController.cpp |
| HyperXController.cpp |
| |
| Definitions and types for HyperX Predator|
| and Fury RGB RAM lighting controller |
| RGB RAM lighting controller |
| |
| Adam Honse (CalcProgrammer1) 6/29/2019 |
\*-----------------------------------------*/
#include "HyperXDRAMController.h"
#include "HyperXController.h"
#include <cstring>
HyperXDRAMController::HyperXDRAMController(i2c_smbus_interface* bus, hyperx_dev_id dev, unsigned char slots)
HyperXController::HyperXController(i2c_smbus_interface* bus, hyperx_dev_id dev, unsigned char slots)
{
this->bus = bus;
this->dev = dev;
@@ -31,17 +31,17 @@ HyperXDRAMController::HyperXDRAMController(i2c_smbus_interface* bus, hyperx_dev_
mode = HYPERX_MODE_DIRECT;
}
HyperXDRAMController::~HyperXDRAMController()
HyperXController::~HyperXController()
{
}
std::string HyperXDRAMController::GetDeviceName()
std::string HyperXController::GetDeviceName()
{
return(device_name);
}
std::string HyperXDRAMController::GetDeviceLocation()
std::string HyperXController::GetDeviceLocation()
{
std::string return_string(bus->device_name);
char addr[5];
@@ -51,12 +51,12 @@ std::string HyperXDRAMController::GetDeviceLocation()
return(return_string);
}
unsigned int HyperXDRAMController::GetLEDCount()
unsigned int HyperXController::GetLEDCount()
{
return(led_count);
}
unsigned int HyperXDRAMController::GetSlotCount()
unsigned int HyperXController::GetSlotCount()
{
unsigned int slot_count = 0;
@@ -71,13 +71,16 @@ unsigned int HyperXDRAMController::GetSlotCount()
return(slot_count);
}
unsigned int HyperXDRAMController::GetMode()
unsigned int HyperXController::GetMode()
{
return(mode);
}
void HyperXDRAMController::SetEffectColor(unsigned char red, unsigned char green, unsigned char blue)
void HyperXController::SetEffectColor(unsigned char red, unsigned char green, unsigned char blue)
{
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_EFFECT_RED, red );
@@ -87,10 +90,16 @@ void HyperXDRAMController::SetEffectColor(unsigned char red, unsigned char green
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void HyperXDRAMController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
void HyperXController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
{
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
/*-----------------------------------------------------*\
@@ -109,7 +118,7 @@ void HyperXDRAMController::SetAllColors(unsigned char red, unsigned char green,
if(mode == HYPERX_MODE_DIRECT)
{
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE_INDEPENDENT, HYPERX_MODE3_DIRECT);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE3, HYPERX_MODE3_DIRECT);
}
for(int led = 0; led < 5; led++)
@@ -124,9 +133,12 @@ void HyperXDRAMController::SetAllColors(unsigned char red, unsigned char green,
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void HyperXDRAMController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
void HyperXController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
/*-----------------------------------------------------*\
| led_slot - the unmapped slot ID for the given LED |
@@ -163,6 +175,9 @@ void HyperXDRAMController::SetLEDColor(unsigned int led, unsigned char red, unsi
unsigned char blue_base = base + 0x02;
unsigned char bright_base = base + 0x10;
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
bus->i2c_smbus_write_byte_data(dev, red_base + (3 * led), red );
@@ -172,10 +187,13 @@ void HyperXDRAMController::SetLEDColor(unsigned int led, unsigned char red, unsi
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void HyperXDRAMController::SetLEDColor(unsigned int slot, unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
void HyperXController::SetLEDColor(unsigned int slot, unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char base = slot_base[slot];
unsigned char red_base = base + 0x00;
@@ -183,6 +201,9 @@ void HyperXDRAMController::SetLEDColor(unsigned int slot, unsigned int led, unsi
unsigned char blue_base = base + 0x02;
unsigned char bright_base = base + 0x10;
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
bus->i2c_smbus_write_byte_data(dev, red_base + (3 * led), red );
@@ -192,96 +213,62 @@ void HyperXDRAMController::SetLEDColor(unsigned int slot, unsigned int led, unsi
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void HyperXDRAMController::SetMode(unsigned char new_mode, bool random, unsigned short new_speed)
void HyperXController::SetMode(unsigned char new_mode)
{
mode = new_mode;
speed = new_speed;
mode = new_mode;
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
/*-----------------------------------------------------*\
| Determine which mode register to use. |
| If set to random color mode, use Mode1. |
| If set to fixed color mode, use Mode2. |
\*-----------------------------------------------------*/
unsigned char mode_reg;
if(random)
{
mode_reg = HYPERX_REG_MODE_RANDOM;
}
else
{
mode_reg = HYPERX_REG_MODE_CUSTOM;
}
switch (mode)
{
case HYPERX_MODE_DIRECT:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE_INDEPENDENT, HYPERX_MODE3_DIRECT);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE3, HYPERX_MODE3_DIRECT);
break;
case HYPERX_MODE_STATIC:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE_CUSTOM, HYPERX_MODE2_STATIC);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_STATIC);
break;
case HYPERX_MODE_RAINBOW:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE_RANDOM, HYPERX_MODE1_RAINBOW);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE1, HYPERX_MODE1_RAINBOW);
break;
case HYPERX_MODE_COMET:
bus->i2c_smbus_write_byte_data(dev, mode_reg, HYPERX_MODE2_COMET);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_COMET);
break;
case HYPERX_MODE_HEARTBEAT:
bus->i2c_smbus_write_byte_data(dev, mode_reg, HYPERX_MODE2_HEARTBEAT);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_DELAY_TIME_MSB, 0x03);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_DELAY_TIME_LSB, 0xE8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_HEARTBEAT);
break;
case HYPERX_MODE_CYCLE:
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE_RANDOM, HYPERX_MODE1_CYCLE);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_CHANGE_TIME_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_CHANGE_TIME_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE1, HYPERX_MODE1_CYCLE);
break;
case HYPERX_MODE_BREATHING:
bus->i2c_smbus_write_byte_data(dev, mode_reg, HYPERX_MODE2_BREATHING);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_FADE_IN_TIME_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_FADE_IN_TIME_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_FADE_OUT_TIME_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_FADE_OUT_TIME_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_MSB, 0x00);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_LSB, 0x00);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_BREATHING);
break;
case HYPERX_MODE_BOUNCE:
bus->i2c_smbus_write_byte_data(dev, mode_reg, HYPERX_MODE2_BOUNCE);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_BOUNCE);
break;
case HYPERX_MODE_BLINK:
bus->i2c_smbus_write_byte_data(dev, mode_reg, HYPERX_MODE2_BLINK);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_MSB, speed >> 8);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_LSB, speed & 0xFF);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_MSB, 0x07);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_LSB, 0xD4);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_BLINK);
break;
}
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
@@ -1,8 +1,8 @@
/*-----------------------------------------*\
| HyperXDRAMController.h |
| HyperXController.h |
| |
| Definitions and types for HyperX Predator|
| and Fury RGB RAM lighting controller |
| RGB RAM lighting controller |
| |
| Adam Honse (CalcProgrammer1) 6/29/2019 |
\*-----------------------------------------*/
@@ -101,25 +101,11 @@ enum
HYPERX_REG_SLOT3_LED3_BRIGHTNESS = 0xBA, /* Brightness for LED 3, Slot 3 (0-100) */
HYPERX_REG_SLOT3_LED4_BRIGHTNESS = 0xBD, /* Brightness for LED 4, Slot 3 (0-100) */
HYPERX_REG_TIMER_MSB = 0xD1, /* Timer MSB */
HYPERX_REG_TIMER_LSB = 0xD2, /* Timer LSB */
HYPERX_REG_ON_TIME_MSB = 0xD3, /* Effect on time MSB */
HYPERX_REG_ON_TIME_LSB = 0xD4, /* Effect on time LSB */
HYPERX_REG_CHANGE_TIME_MSB = 0xD5, /* Change time MSB */
HYPERX_REG_CHANGE_TIME_LSB = 0xD6, /* Change time LSB */
HYPERX_REG_FADE_IN_TIME_MSB = 0xD7, /* Fade in time MSB */
HYPERX_REG_FADE_IN_TIME_LSB = 0xD8, /* Fade in time LSB */
HYPERX_REG_FADE_OUT_TIME_MSB = 0xD9, /* Fade out time MSB */
HYPERX_REG_FADE_OUT_TIME_LSB = 0xDA, /* Fade out time LSB */
HYPERX_REG_OFF_TIME_MSB = 0xDB, /* Effect off time MSB */
HYPERX_REG_OFF_TIME_LSB = 0xDC, /* Effect off time LSB */
HYPERX_REG_EFFECT_BRIGHTNESS = 0xDD, /* Brightness for effects (0-100) */
HYPERX_REG_APPLY = 0xE1, /* Apply changes register */
HYPERX_REG_MODE_RANDOM = 0xE3, /* Mode control register, random colors */
HYPERX_REG_MODE_CUSTOM = 0xE4, /* Mode control register, custom colors */
HYPERX_REG_MODE_INDEPENDENT = 0xE5, /* Mode control register, independent */
HYPERX_REG_DELAY_TIME_MSB = 0xEA, /* Delay time MSB */
HYPERX_REG_DELAY_TIME_LSB = 0xEB, /* Delay time LSB */
HYPERX_REG_MODE1 = 0xE3, /* Mode control register 1 */
HYPERX_REG_MODE2 = 0xE4, /* Mode control register 2 */
HYPERX_REG_MODE3 = 0xE5, /* Mode control register 3 */
HYPERX_REG_EFFECT_RED = 0xEC, /* Red color register for effects */
HYPERX_REG_EFFECT_GREEN = 0xED, /* Green color register for effects */
HYPERX_REG_EFFECT_BLUE = 0xEE, /* Blue color register for effects */
@@ -160,31 +146,6 @@ enum
HYPERX_NUMBER_MODES /* Number of HyperX modes */
};
enum
{
HYPERX_SPEED_BOUNCE_SLOW = 0x07D0, /* Slowest speed for bounce mode */
HYPERX_SPEED_BOUNCE_NORMAL = 0x07D0, /* Normal speed for bounce mode */
HYPERX_SPEED_BOUNCE_FAST = 0x0064, /* Fastest speed for bounce mode */
HYPERX_SPEED_BREATHING_SLOW = 0x07D0, /* Slowest speed for breathing mode */
HYPERX_SPEED_BREATHING_NORMAL = 0x07D0, /* Normal speed for breathing mode */
HYPERX_SPEED_BREATHING_FAST = 0x0064, /* Fastest speed for breathing mode */
HYPERX_SPEED_CYCLE_SLOW = 0x05DC, /* Slowest speed for cycle mode */
HYPERX_SPEED_CYCLE_NORMAL = 0x05DC, /* Normal speed for cycle mode */
HYPERX_SPEED_CYCLE_FAST = 0x00FA, /* Fastest speed for cycle mode */
HYPERX_SPEED_RAINBOW_SLOW = 0x07D0, /* Slowest speed for rainbow mode */
HYPERX_SPEED_RAINBOW_NORMAL = 0x07D0, /* Normal speed for rainbow mode */
HYPERX_SPEED_RAINBOW_FAST = 0x0064, /* Fastest speed for rainbow mode */
HYPERX_SPEED_BLINK_SLOW = 0x07D0, /* Slowest speed for blink mode */
HYPERX_SPEED_BLINK_NORMAL = 0x07D0, /* Normal speed for blink mode */
HYPERX_SPEED_BLINK_FAST = 0x01F4, /* Fastest speed for blink mode */
HYPERX_SPEED_HEARTBEAT_SLOW = 0x07D0, /* Slowest speed for heartbeat mode */
HYPERX_SPEED_HEARTBEAT_NORMAL = 0x07D0, /* Normal speed for heartbeat mode */
HYPERX_SPEED_HEARTBEAT_FAST = 0x01F4, /* Fastest speed for heartbeat mode */
HYPERX_SPEED_COMET_SLOW = 0x07D0, /* Slowest speed for comet mode */
HYPERX_SPEED_COMET_NORMAL = 0x07D0, /* Normal speed for comet mode */
HYPERX_SPEED_COMET_FAST = 0x0064, /* Fastest speed for comet mode */
};
static const unsigned char slot_base[4] =
{
HYPERX_REG_SLOT0_LED0_RED, /* SPD 0x50 maps to slot 0 */
@@ -193,18 +154,18 @@ static const unsigned char slot_base[4] =
HYPERX_REG_SLOT3_LED0_RED /* SPD 0x53 maps to slot 3 */
};
class HyperXDRAMController
class HyperXController
{
public:
HyperXDRAMController(i2c_smbus_interface* bus, hyperx_dev_id dev, unsigned char slots);
~HyperXDRAMController();
HyperXController(i2c_smbus_interface* bus, hyperx_dev_id dev, unsigned char slots);
~HyperXController();
std::string GetDeviceName();
std::string GetDeviceLocation();
unsigned int GetLEDCount();
unsigned int GetSlotCount();
unsigned int GetMode();
void SetMode(unsigned char new_mode, bool random, unsigned short new_speed);
void SetMode(unsigned char new_mode);
void SetAllColors(unsigned char red, unsigned char green, unsigned char blue);
void SetEffectColor(unsigned char red, unsigned char green, unsigned char blue);
@@ -218,5 +179,4 @@ private:
i2c_smbus_interface* bus;
hyperx_dev_id dev;
unsigned int mode;
unsigned short speed;
};
@@ -1,22 +1,31 @@
#include "HyperXDRAMController.h"
#include "HyperXController.h"
#include "RGBController.h"
#include "RGBController_HyperXDRAM.h"
#include "RGBController_HyperX.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std::chrono_literals;
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
/******************************************************************************************\
* *
* TestForHyperXDRAMController *
* TestForHyperXController *
* *
* Tests the given address to see if a HyperX controller exists there. *
* Tests the given address to see if a HyperX controller exists there. *
* *
\******************************************************************************************/
bool TestForHyperXDRAMController(i2c_smbus_interface* bus, unsigned char address)
bool TestForHyperXController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
@@ -39,35 +48,35 @@ bool TestForHyperXDRAMController(i2c_smbus_interface* bus, unsigned char address
return(pass);
} /* TestForHyperXDRAMController() */
} /* TestForHyperXController() */
/******************************************************************************************\
* *
* DetectHyperXDRAMControllers *
* DetectHyperXControllers *
* *
* Detect HyperX DRAM controllers on the enumerated I2C busses. *
* Detect HyperX controllers on the enumerated I2C busses. *
* *
* bus - pointer to i2c_smbus_interface where Aura device is connected *
* dev - I2C address of Aura device *
* *
\******************************************************************************************/
void DetectHyperXDRAMControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
void DetectHyperXControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
HyperXDRAMController* new_hyperx;
RGBController_HyperXDRAM* new_controller;
HyperXController* new_hyperx;
RGBController_HyperX* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
unsigned char slots_valid = 0x00;
// Check for HyperX controller at 0x27
if (TestForHyperXDRAMController(busses[bus], 0x27))
if (TestForHyperXController(busses[bus], 0x27))
{
busses[bus]->i2c_smbus_write_byte_data(0x37, 0x00, 0xFF);
std::this_thread::sleep_for(1ms);
Sleep(1);
for(int slot_addr = 0x50; slot_addr <= 0x57; slot_addr++)
{
@@ -80,16 +89,16 @@ void DetectHyperXDRAMControllers(std::vector<i2c_smbus_interface*> &busses, std:
slots_valid |= (1 << (slot_addr - 0x50));
}
std::this_thread::sleep_for(1ms);
Sleep(1);
}
if(slots_valid != 0)
{
new_hyperx = new HyperXDRAMController(busses[bus], 0x27, slots_valid);
new_controller = new RGBController_HyperXDRAM(new_hyperx);
new_hyperx = new HyperXController(busses[bus], 0x27, slots_valid);
new_controller = new RGBController_HyperX(new_hyperx);
rgb_controllers.push_back(new_controller);
}
}
}
} /* DetectHyperXDRAMControllers() */
} /* DetectHyperXControllers() */
@@ -1,480 +0,0 @@
/*-----------------------------------------*\
| HyperXKeyboardController.cpp |
| |
| Driver for HyperX RGB Keyboard lighting |
| controller |
| |
| Adam Honse (CalcProgrammer1) 1/30/2020 |
\*-----------------------------------------*/
#include "HyperXKeyboardController.h"
#include <cstring>
using namespace std::chrono_literals;
static unsigned int keys[] = {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x20, 0x21, 0x22,
0x23, 0x24, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
0x31, 0x32, 0x33, 0x34, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3E, 0x3F, 0x41,
0x44, 0x45, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x51, 0x54, 0x55,
0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5E, 0x5F, 0x61, 0x64, 0x65, 0x68, 0x69, 0x6A,
0x6B, 0x6C, 0x6E, 0x6F, 0x74, 0x75, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E,
0x7F, 0x81, 0x84, 0x85, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x91,
0x94, 0x95 };
static unsigned int extended_red[] = {0x08, 0x48, 0x88, 0x09, 0x89, 0x0A, 0x8A, 0x0B, 0x8B, 0x0C, 0x8C, 0x0D, 0x8D, 0x0E, 0x8F, 0x8E, 0x0F, 0x4F, 0x92, 0x13, 0x93, 0x12 };
static unsigned int extended_grn[] = {0x29, 0x28, 0x78, 0x19, 0x79, 0x1A, 0x7A, 0x1B, 0x7B, 0x1C, 0x7C, 0x1D, 0x7D, 0x1E, 0x6E, 0x7E, 0x1F, 0x6F, 0x82, 0x23, 0x83, 0x22 };
static unsigned int extended_blu[] = {0x39, 0x38, 0x68, 0x3A, 0x69, 0x2A, 0x6A, 0x2B, 0x6B, 0x2C, 0x6C, 0x2D, 0x6D, 0x2E, 0x5E, 0x5D, 0x2F, 0x5F, 0x72, 0x33, 0x73, 0x32 };
HyperXKeyboardController::HyperXKeyboardController(hid_device* dev_handle)
{
dev = dev_handle;
}
HyperXKeyboardController::~HyperXKeyboardController()
{
}
void HyperXKeyboardController::SetMode
(
unsigned char mode,
unsigned char direction,
unsigned char speed,
std::vector<RGBColor> colors
)
{
unsigned char color_mode;
unsigned char mode_colors[9];
active_mode = mode;
active_direction = direction;
active_speed = speed;
memset(mode_colors, 0x00, sizeof(mode_colors));
switch(colors.size())
{
default:
case 0:
color_mode = HYPERX_COLOR_MODE_SPECTRUM;
break;
case 1:
color_mode = HYPERX_COLOR_MODE_SINGLE;
mode_colors[0] = RGBGetRValue(colors[0]);
mode_colors[1] = RGBGetGValue(colors[0]);
mode_colors[2] = RGBGetBValue(colors[0]);
break;
case 2:
color_mode = HYPERX_COLOR_MODE_DUAL;
mode_colors[3] = RGBGetRValue(colors[0]);
mode_colors[4] = RGBGetGValue(colors[0]);
mode_colors[5] = RGBGetBValue(colors[0]);
mode_colors[6] = RGBGetRValue(colors[1]);
mode_colors[7] = RGBGetGValue(colors[1]);
mode_colors[8] = RGBGetBValue(colors[1]);
break;
}
SendEffect
(
0x01,
active_mode,
active_direction,
HYPERX_REACTIVE_MODE_NONE,
active_speed,
color_mode,
mode_colors[0],
mode_colors[1],
mode_colors[2],
mode_colors[3],
mode_colors[4],
mode_colors[5],
mode_colors[6],
mode_colors[7],
mode_colors[8]
);
std::this_thread::sleep_for(100ms);
}
void HyperXKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
{
unsigned char red_color_data[106];
unsigned char grn_color_data[106];
unsigned char blu_color_data[106];
unsigned char ext_color_data[150];
for(std::size_t i = 0; i < 106; i++)
{
red_color_data[i] = RGBGetRValue(colors[i]);
grn_color_data[i] = RGBGetGValue(colors[i]);
blu_color_data[i] = RGBGetBValue(colors[i]);
}
for(std::size_t i = 0; i < 22; i++)
{
ext_color_data[extended_red[i]] = RGBGetRValue(colors[i + 106]);
ext_color_data[extended_grn[i]] = RGBGetGValue(colors[i + 106]);
ext_color_data[extended_blu[i]] = RGBGetBValue(colors[i + 106]);
}
SendDirect
(
HYPERX_COLOR_CHANNEL_RED,
red_color_data
);
std::this_thread::sleep_for(5ms);
SendDirect
(
HYPERX_COLOR_CHANNEL_GREEN,
grn_color_data
);
std::this_thread::sleep_for(5ms);
SendDirect
(
HYPERX_COLOR_CHANNEL_BLUE,
blu_color_data
);
std::this_thread::sleep_for(5ms);
SendDirectExtended
(
ext_color_data
);
}
void HyperXKeyboardController::SetLEDs(std::vector<RGBColor> colors)
{
unsigned char red_color_data[106];
unsigned char grn_color_data[106];
unsigned char blu_color_data[106];
unsigned char ext_color_data[150];
for(std::size_t i = 0; i < 106; i++)
{
red_color_data[i] = RGBGetRValue(colors[i]);
grn_color_data[i] = RGBGetGValue(colors[i]);
blu_color_data[i] = RGBGetBValue(colors[i]);
}
for(std::size_t i = 0; i < 22; i++)
{
ext_color_data[extended_red[i]] = RGBGetRValue(colors[i + 106]);
ext_color_data[extended_grn[i]] = RGBGetGValue(colors[i + 106]);
ext_color_data[extended_blu[i]] = RGBGetBValue(colors[i + 106]);
}
SendColor
(
0x01,
HYPERX_COLOR_CHANNEL_RED,
red_color_data
);
std::this_thread::sleep_for(5ms);
SendColor
(
0x01,
HYPERX_COLOR_CHANNEL_GREEN,
grn_color_data
);
std::this_thread::sleep_for(5ms);
SendColor
(
0x01,
HYPERX_COLOR_CHANNEL_BLUE,
blu_color_data
);
std::this_thread::sleep_for(5ms);
SendExtendedColor
(
0x01,
ext_color_data
);
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void HyperXKeyboardController::SelectProfile
(
unsigned char profile
)
{
unsigned char buf[264];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Select Profile packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x07;
buf[0x01] = 0x01;
buf[0x02] = profile;
buf[0x06] = 0x03;
buf[0x07] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 264);
}
void HyperXKeyboardController::SendEffect
(
unsigned char profile,
unsigned char mode,
unsigned char direction,
unsigned char reactive_mode,
unsigned char speed,
unsigned char color_mode,
unsigned char red_single,
unsigned char grn_single,
unsigned char blu_single,
unsigned char red_dual_1,
unsigned char grn_dual_1,
unsigned char blu_dual_1,
unsigned char red_dual_2,
unsigned char grn_dual_2,
unsigned char blu_dual_2
)
{
unsigned char buf[264];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Effect packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x07;
buf[0x01] = HYPERX_PACKET_ID_SET_EFFECT;
buf[0x02] = profile;
/*-----------------------------------------------------*\
| Set mode |
\*-----------------------------------------------------*/
buf[0x09] = 0x01;
buf[0x0A] = mode;
/*-----------------------------------------------------*\
| Set direction |
\*-----------------------------------------------------*/
buf[0x0D] = direction;
buf[0x0E] = direction;
/*-----------------------------------------------------*\
| Set reactive mode |
\*-----------------------------------------------------*/
buf[0x1B] = reactive_mode;
buf[0x1C] = reactive_mode;
buf[0x1D] = reactive_mode;
buf[0x1E] = reactive_mode;
buf[0x1F] = reactive_mode;
buf[0x20] = reactive_mode;
buf[0x21] = reactive_mode;
buf[0x22] = reactive_mode;
/*-----------------------------------------------------*\
| Set mode-specific colors |
\*-----------------------------------------------------*/
buf[0x29] = red_single;
buf[0x41] = grn_single;
buf[0x59] = blu_single;
buf[0x2A] = red_dual_1;
buf[0x42] = grn_dual_1;
buf[0x5A] = blu_dual_1;
buf[0x2B] = red_dual_2;
buf[0x43] = grn_dual_2;
buf[0x5B] = blu_dual_2;
buf[0x6B] = 0x09;
buf[0x6C] = 0x09;
buf[0x6D] = 0x05;
buf[0x6E] = 0x05;
buf[0x6F] = 0x06;
buf[0x70] = 0x05;
/*-----------------------------------------------------*\
| Set speed |
\*-----------------------------------------------------*/
buf[0x71] = speed;
buf[0x72] = 0x09;
/*-----------------------------------------------------*\
| Set color mode |
\*-----------------------------------------------------*/
buf[0x73] = color_mode;
buf[0x74] = color_mode;
buf[0x75] = color_mode;
buf[0x76] = color_mode;
buf[0x77] = color_mode;
buf[0x78] = color_mode;
buf[0x79] = color_mode;
buf[0x7A] = color_mode;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 264);
}
void HyperXKeyboardController::SendColor
(
unsigned char profile,
unsigned char color_channel,
unsigned char* color_data
)
{
unsigned char buf[264];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Color packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x07;
buf[0x01] = HYPERX_PACKET_ID_SET_COLOR;
buf[0x02] = profile;
buf[0x03] = color_channel;
/*-----------------------------------------------------*\
| Fill in color data |
\*-----------------------------------------------------*/
for(int i = 0; i < 106; i++)
{
buf[keys[i]] = color_data[i];
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 264);
}
void HyperXKeyboardController::SendExtendedColor
(
unsigned char profile,
unsigned char* color_data
)
{
unsigned char buf[264];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Color packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x07;
buf[0x01] = HYPERX_PACKET_ID_SET_COLOR;
buf[0x02] = profile;
buf[0x03] = HYPERX_COLOR_CHANNEL_EXTENDED;
/*-----------------------------------------------------*\
| Fill in color data |
\*-----------------------------------------------------*/
for(int i = 0x08; i <= 0x93; i++)
{
buf[i] = color_data[i];
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 264);
}
void HyperXKeyboardController::SendDirect
(
unsigned char color_channel,
unsigned char* color_data
)
{
unsigned char buf[264];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Direct packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x07;
buf[0x01] = HYPERX_PACKET_ID_DIRECT;
buf[0x02] = color_channel;
/*-----------------------------------------------------*\
| Fill in color data |
\*-----------------------------------------------------*/
for(int i = 0; i < 106; i++)
{
buf[keys[i]] = color_data[i];
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 264);
}
void HyperXKeyboardController::SendDirectExtended
(
unsigned char* color_data
)
{
unsigned char buf[264];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Direct packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x07;
buf[0x01] = HYPERX_PACKET_ID_DIRECT;
buf[0x02] = HYPERX_COLOR_CHANNEL_EXTENDED;
/*-----------------------------------------------------*\
| Fill in color data |
\*-----------------------------------------------------*/
for(int i = 0x08; i <= 0x93; i++)
{
buf[i] = color_data[i];
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 264);
}
@@ -1,135 +0,0 @@
/*-----------------------------------------*\
| HyperXKeyboardController.h |
| |
| Definitions and types for HyperX RGB |
| Keyboard lighting controller |
| |
| Adam Honse (CalcProgrammer1) 1/30/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
HYPERX_PACKET_ID_SET_EFFECT = 0x02, /* Set profile effect packet */
HYPERX_PACKET_ID_SET_COLOR = 0x06, /* Set profile color packet */
HYPERX_PACKET_ID_DIRECT = 0x16, /* Direct control packet */
};
enum
{
HYPERX_DIRECTION_RIGHT = 0x00,
HYPERX_DIRECTION_LEFT = 0x01,
HYPERX_DIRECTION_UP = 0x02,
HYPERX_DIRECTION_DOWN = 0x03,
HYPERX_DIRECTION_IN = 0x04,
HYPERX_DIRECTION_OUT = 0x05
};
enum
{
HYPERX_MODE_WAVE = 0x00,
HYPERX_MODE_STATIC = 0x01,
HYPERX_MODE_BREATHING = 0x02,
};
enum
{
HYPERX_REACTIVE_MODE_TRIGGER = 0x03,
HYPERX_REACTIVE_MODE_EXPLOSION = 0x04,
HYPERX_REACTIVE_MODE_HYPERX_FLAME = 0x05,
HYPERX_REACTIVE_MODE_NONE = 0xFF
};
enum
{
HYPERX_COLOR_MODE_SINGLE = 0x00,
HYPERX_COLOR_MODE_DUAL = 0x01,
HYPERX_COLOR_MODE_SPECTRUM = 0x02
};
enum
{
HYPERX_COLOR_CHANNEL_RED = 0x01,
HYPERX_COLOR_CHANNEL_GREEN = 0x02,
HYPERX_COLOR_CHANNEL_BLUE = 0x03,
HYPERX_COLOR_CHANNEL_EXTENDED = 0x04
};
class HyperXKeyboardController
{
public:
HyperXKeyboardController(hid_device* dev_handle);
~HyperXKeyboardController();
void SetMode
(
unsigned char mode,
unsigned char direction,
unsigned char speed,
std::vector<RGBColor> colors
);
void SetLEDsDirect(std::vector<RGBColor> colors);
void SetLEDs(std::vector<RGBColor> colors);
private:
hid_device* dev;
unsigned char active_mode;
unsigned char active_direction;
unsigned char active_speed;
void SelectProfile
(
unsigned char profile
);
void SendEffect
(
unsigned char profile,
unsigned char mode,
unsigned char direction,
unsigned char reactive_mode,
unsigned char speed,
unsigned char color_mode,
unsigned char red_single,
unsigned char grn_single,
unsigned char blu_single,
unsigned char red_dual_1,
unsigned char grn_dual_1,
unsigned char blu_dual_1,
unsigned char red_dual_2,
unsigned char grn_dual_2,
unsigned char blu_dual_2
);
void SendColor
(
unsigned char profile,
unsigned char color_channel,
unsigned char* color_data
);
void SendExtendedColor
(
unsigned char profile,
unsigned char* color_data
);
void SendDirect
(
unsigned char color_channel,
unsigned char* color_data
);
void SendDirectExtended
(
unsigned char* color_data
);
};
@@ -1,79 +0,0 @@
#include "HyperXKeyboardController.h"
#include "RGBController.h"
#include "RGBController_HyperXKeyboard.h"
#include <vector>
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| HyperX keyboard vendor IDs |
\*-----------------------------------------------------*/
#define HYPERX_KEYBOARD_VID 0x0951
#define HYPERX_ALLOY_ELITE_PID 0x16BE
typedef struct
{
unsigned short usb_vid;
unsigned short usb_pid;
unsigned char usb_interface;
const char * name;
} hyperx_device;
#define HYPERX_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
static const hyperx_device device_list[] =
{
/*-----------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-----------------------------------------------------------------------------------------------------*/
{ HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ELITE_PID, 2, "HyperX Alloy Elite RGB" },
};
/******************************************************************************************\
* *
* DetectHyperXKeyboardControllers *
* *
* Tests the USB address to see if a HyperX Keyboard controller exists there. *
* *
\******************************************************************************************/
void DetectHyperXKeyboardControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device_info* info;
hid_device* dev = NULL;
hid_init();
for(std::size_t device_idx = 0; device_idx < HYPERX_NUM_DEVICES; device_idx++)
{
dev = NULL;
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for HyperX RGB Peripheral
while(info)
{
if((info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid)
&&(info->interface_number == device_list[device_idx].usb_interface))
{
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
if( dev )
{
HyperXKeyboardController* controller = new HyperXKeyboardController(dev);
RGBController_HyperXKeyboard* rgb_controller = new RGBController_HyperXKeyboard(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
}
@@ -1,142 +0,0 @@
#include "LogitechG203Controller.h"
#include "LogitechG403Controller.h"
#include "LogitechG810Controller.h"
#include "RGBController.h"
#include "RGBController_LogitechG203.h"
#include "RGBController_LogitechG403.h"
#include "RGBController_LogitechG810.h"
#include <vector>
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| Logitech vendor ID |
\*-----------------------------------------------------*/
#define LOGITECH_VID 0x046D
/*-----------------------------------------------------*\
| Keyboard product IDs |
\*-----------------------------------------------------*/
#define LOGITECH_G810_1_PID 0xC337
#define LOGITECH_G810_2_PID 0xC331
#define LOGITECH_G512_PID 0xC342
/*-----------------------------------------------------*\
| Mouse product IDs |
\*-----------------------------------------------------*/
#define LOGITECH_G203_PID 0xC084
#define LOGITECH_G403_PID 0xC083
#define LOGITECH_G403H_PID 0xC08F
typedef struct
{
unsigned short usb_vid;
unsigned short usb_pid;
unsigned char usb_interface;
device_type type;
const char * name;
} logitech_device;
#define LOGITECH_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
static const logitech_device device_list[] =
{
/*-------------------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-------------------------------------------------------------------------------------------------------------*/
{ LOGITECH_VID, LOGITECH_G810_1_PID, 1, DEVICE_TYPE_KEYBOARD, "Logitech G810 Orion Spectrum" },
{ LOGITECH_VID, LOGITECH_G810_2_PID, 1, DEVICE_TYPE_KEYBOARD, "Logitech G810 Orion Spectrum" },
{ LOGITECH_VID, LOGITECH_G512_PID, 1, DEVICE_TYPE_KEYBOARD, "Logitech G512" },
/*-------------------------------------------------------------------------------------------------------------*\
| Mice |
\*-------------------------------------------------------------------------------------------------------------*/
{ LOGITECH_VID, LOGITECH_G203_PID, 1, DEVICE_TYPE_MOUSE, "Logitech G203 Prodigy" },
{ LOGITECH_VID, LOGITECH_G403_PID, 1, DEVICE_TYPE_MOUSE, "Logitech G403 Prodigy" },
{ LOGITECH_VID, LOGITECH_G403H_PID, 1, DEVICE_TYPE_MOUSE, "Logitech G403 Hero" },
/*-------------------------------------------------------------------------------------------------------------*\
| Mousemats |
\*-------------------------------------------------------------------------------------------------------------*/
};
/******************************************************************************************\
* *
* DetectLogitechControllers *
* *
* Tests the USB address to see if a Logitech RGB Keyboard controller exists there. *
* *
\******************************************************************************************/
void DetectLogitechControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device_info* info;
hid_device* dev;
hid_init();
for(int device_idx = 0; device_idx < LOGITECH_NUM_DEVICES; device_idx++)
{
dev = NULL;
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for Logitech RGB Peripheral
while(info)
{
if((info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid)
&&(info->interface_number == device_list[device_idx].usb_interface))
{
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
if( dev )
{
switch(device_list[device_idx].type)
{
case DEVICE_TYPE_KEYBOARD:
{
LogitechG810Controller* controller = new LogitechG810Controller(dev);
RGBController_LogitechG810* rgb_controller = new RGBController_LogitechG810(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
break;
case DEVICE_TYPE_MOUSE:
{
switch(device_list[device_idx].usb_pid)
{
case LOGITECH_G203_PID:
{
LogitechG203Controller* controller = new LogitechG203Controller(dev);
RGBController_LogitechG203* rgb_controller = new RGBController_LogitechG203(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
break;
case LOGITECH_G403_PID:
case LOGITECH_G403H_PID:
{
LogitechG403Controller* controller = new LogitechG403Controller(dev);
RGBController_LogitechG403* rgb_controller = new RGBController_LogitechG403(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
}
break;
}
}
hid_free_enumeration(info);
}
}
@@ -1,73 +0,0 @@
/*-----------------------------------------*\
| LogitechG203Controller.cpp |
| |
| Driver for Logitech G203 Prodigy mouse |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 5/17/2020 |
\*-----------------------------------------*/
#include "LogitechG203Controller.h"
#include <cstring>
LogitechG203Controller::LogitechG203Controller(hid_device* dev_handle)
{
dev = dev_handle;
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void LogitechG203Controller::SendMouseMode
(
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x0E;
usb_buf[0x03] = 0x3C;
usb_buf[0x04] = 0x00;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 1000 + 4750 * (LOGITECH_G203_SPEED_FASTEST - speed);
if(mode == LOGITECH_G203_MODE_CYCLE)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = 0x64;
}
else if(mode == LOGITECH_G203_MODE_BREATHING)
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
usb_buf[0x0C] = 0x64;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 20);
hid_read(dev, (unsigned char *)usb_buf, 20);
}
@@ -1,51 +0,0 @@
/*-----------------------------------------*\
| LogitechG203Controller.h |
| |
| Definitions and types for Logitech G203 |
| Prodigy mouse lighting controller |
| |
| Adam Honse (CalcProgrammer1) 5/17/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
LOGITECH_G203_MODE_OFF = 0x00,
LOGITECH_G203_MODE_STATIC = 0x01,
LOGITECH_G203_MODE_CYCLE = 0x02,
LOGITECH_G203_MODE_BREATHING = 0x03,
};
enum
{
LOGITECH_G203_SPEED_SLOWEST = 0x00, /* Slowest speed */
LOGITECH_G203_SPEED_SLOW = 0x01, /* Slow speed */
LOGITECH_G203_SPEED_NORMAL = 0x02, /* Normal speed */
LOGITECH_G203_SPEED_FAST = 0x03, /* Fast speed */
LOGITECH_G203_SPEED_FASTEST = 0x04, /* Fastest speed */
};
class LogitechG203Controller
{
public:
LogitechG203Controller(hid_device* dev_handle);
~LogitechG203Controller();
void SendMouseMode
(
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
hid_device* dev;
};
@@ -1,75 +0,0 @@
/*-----------------------------------------*\
| LogitechG403Controller.cpp |
| |
| Driver for Logitech G403 Prodigy mouse |
| lighting controller |
| |
| Martin Hartl (inlart) 5/19/2020 |
\*-----------------------------------------*/
#include "LogitechG403Controller.h"
#include <cstring>
LogitechG403Controller::LogitechG403Controller(hid_device* dev_handle)
{
dev = dev_handle;
}
LogitechG403Controller::~LogitechG403Controller()
{
hid_close(dev);
}
void LogitechG403Controller::SendMouseMode
(
unsigned char mode,
std::uint16_t speed,
unsigned char channel,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
unsigned char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x0E;
usb_buf[0x03] = 0x3C;
usb_buf[0x04] = channel;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 1000 + 4750 * (LOGITECH_G403_SPEED_FASTEST - speed);
if(mode == LOGITECH_G403_MODE_CYCLE)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = 0x64;
}
else if(mode == LOGITECH_G403_MODE_BREATHING)
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
usb_buf[0x0C] = 0x64;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 20);
hid_read(dev, usb_buf, 20);
}
@@ -1,52 +0,0 @@
/*-----------------------------------------*\
| LogitechG403Controller.h |
| |
| Definitions and types for Logitech G403 |
| Prodigy mouse lighting controller |
| |
| Martin Hartl (inlart) 5/19/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
LOGITECH_G403_MODE_OFF = 0x00,
LOGITECH_G403_MODE_STATIC = 0x01,
LOGITECH_G403_MODE_CYCLE = 0x02,
LOGITECH_G403_MODE_BREATHING = 0x03,
};
enum
{
LOGITECH_G403_SPEED_SLOWEST = 0x00, /* Slowest speed */
LOGITECH_G403_SPEED_SLOW = 0x01, /* Slow speed */
LOGITECH_G403_SPEED_NORMAL = 0x02, /* Normal speed */
LOGITECH_G403_SPEED_FAST = 0x03, /* Fast speed */
LOGITECH_G403_SPEED_FASTEST = 0x04, /* Fastest speed */
};
class LogitechG403Controller
{
public:
LogitechG403Controller(hid_device* dev_handle);
~LogitechG403Controller();
void SendMouseMode
(
unsigned char mode,
unsigned short speed,
unsigned char channel,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
hid_device* dev;
};
@@ -1,168 +0,0 @@
/*-----------------------------------------*\
| LogitechG810Controller.cpp |
| |
| Driver for Logitech G810 Orion Spectrum |
| keyboard light controller |
| |
| Adam Honse (CalcProgrammer1) 6/11/2020 |
\*-----------------------------------------*/
#include "LogitechG810Controller.h"
#include <cstring>
LogitechG810Controller::LogitechG810Controller(hid_device* dev_handle)
{
dev = dev_handle;
}
LogitechG810Controller::~LogitechG810Controller()
{
}
void LogitechG810Controller::Commit()
{
SendCommit();
}
void LogitechG810Controller::SetDirect
(
unsigned char zone,
unsigned char frame_count,
unsigned char * frame_data
)
{
SendDirectFrame(zone, frame_count, frame_data);
}
void LogitechG810Controller::SetMode
(
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
SendMode(LOGITECH_G810_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
SendMode(LOGITECH_G810_ZONE_MODE_LOGO, mode, speed, red, green, blue);
SendCommit();
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void LogitechG810Controller::SendCommit()
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x0C;
usb_buf[0x03] = 0x5D;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 20);
hid_read(dev, (unsigned char *)usb_buf, 20);
}
void LogitechG810Controller::SendDirectFrame
(
unsigned char zone,
unsigned char frame_count,
unsigned char * frame_data
)
{
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x12;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x0C;
usb_buf[0x03] = 0x3D;
usb_buf[0x05] = zone;
usb_buf[0x07] = frame_count;
/*-----------------------------------------------------*\
| Copy in frame data |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x08], frame_data, frame_count * 4);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 64);
hid_read(dev, (unsigned char *)usb_buf, 20);
}
void LogitechG810Controller::SendMode
(
unsigned char zone,
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x0D;
usb_buf[0x03] = 0x3D;
usb_buf[0x04] = zone;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 1000 + 4750 * (LOGITECH_G810_SPEED_FASTEST - speed);
if(mode == LOGITECH_G810_MODE_CYCLE)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = 0x64;
}
else if(mode == LOGITECH_G810_MODE_BREATHING)
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
usb_buf[0x0C] = 0x64;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 20);
hid_read(dev, (unsigned char *)usb_buf, 20);
}
@@ -1,94 +0,0 @@
/*-----------------------------------------*\
| LogitechG810Controller.h |
| |
| Definitions and types for Logitech G810 |
| Orion Spectrum keyboard light controller |
| |
| Adam Honse (CalcProgrammer1) 6/11/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
LOGITECH_G810_ZONE_MODE_KEYBOARD = 0x00,
LOGITECH_G810_ZONE_MODE_LOGO = 0x01,
};
enum
{
LOGITECH_G810_ZONE_DIRECT_KEYBOARD = 0x01,
LOGITECH_G810_ZONE_DIRECT_MEDIA = 0x02,
LOGITECH_G810_ZONE_DIRECT_LOGO = 0x10,
LOGITECH_G810_ZONE_DIRECT_INDICATORS = 0x40,
};
enum
{
LOGITECH_G810_MODE_OFF = 0x00,
LOGITECH_G810_MODE_STATIC = 0x01,
LOGITECH_G810_MODE_BREATHING = 0x02,
LOGITECH_G810_MODE_CYCLE = 0x03,
LOGITECH_G810_MODE_WAVE = 0x04,
};
enum
{
LOGITECH_G810_SPEED_SLOWEST = 0x00, /* Slowest speed */
LOGITECH_G810_SPEED_SLOW = 0x01, /* Slow speed */
LOGITECH_G810_SPEED_NORMAL = 0x02, /* Normal speed */
LOGITECH_G810_SPEED_FAST = 0x03, /* Fast speed */
LOGITECH_G810_SPEED_FASTEST = 0x04, /* Fastest speed */
};
class LogitechG810Controller
{
public:
LogitechG810Controller(hid_device* dev_handle);
~LogitechG810Controller();
void Commit();
void SetDirect
(
unsigned char zone,
unsigned char frame_count,
unsigned char * frame_data
);
void SetMode
(
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
hid_device* dev;
void SendDirectFrame
(
unsigned char zone,
unsigned char frame_count,
unsigned char * frame_data
);
void SendMode
(
unsigned char zone,
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
void SendCommit();
};
@@ -1,78 +0,0 @@
/*-----------------------------------------*\
| MSI3ZoneController.cpp |
| |
| Driver for MSI/Steelseries 3-Zone |
| Keyboard lighting controller |
| |
| Adam Honse (CalcProgrammer1) 12/25/2019 |
\*-----------------------------------------*/
#include "MSI3ZoneController.h"
MSI3ZoneController::MSI3ZoneController(hid_device* dev_handle)
{
dev = dev_handle;
//strcpy(device_name, "MSI 3-Zone Keyboard");
}
MSI3ZoneController::~MSI3ZoneController()
{
}
char* MSI3ZoneController::GetDeviceName()
{
return device_name;
}
void MSI3ZoneController::SetLEDs(std::vector<RGBColor> colors)
{
//Shout out to bparker06 for reverse engineering the MSI keyboard USB protocol!
// https://github.com/bparker06/msi-keyboard/blob/master/keyboard.cpp for original implementation
unsigned char buf[8] = { 0 };
buf[0] = 1;
buf[1] = 2;
buf[2] = 64;
buf[3] = 1;
buf[4] = RGBGetRValue(colors[0]);
buf[5] = RGBGetGValue(colors[0]);
buf[6] = RGBGetBValue(colors[0]);
buf[7] = 236;
hid_send_feature_report(dev, buf, 8);
buf[3] = 2;
buf[4] = RGBGetRValue(colors[1]);
buf[5] = RGBGetGValue(colors[1]);
buf[6] = RGBGetBValue(colors[1]);
hid_send_feature_report(dev, buf, 8);
buf[3] = 3;
buf[4] = RGBGetRValue(colors[2]);
buf[5] = RGBGetGValue(colors[2]);
buf[6] = RGBGetBValue(colors[2]);
hid_send_feature_report(dev, buf, 8);
buf[3] = 4;
buf[4] = RGBGetRValue(colors[3]);
buf[5] = RGBGetGValue(colors[3]);
buf[6] = RGBGetBValue(colors[3]);
hid_send_feature_report(dev, buf, 8);
buf[3] = 5;
hid_send_feature_report(dev, buf, 8);
buf[3] = 6;
hid_send_feature_report(dev, buf, 8);
buf[3] = 7;
hid_send_feature_report(dev, buf, 8);
}
@@ -1,30 +0,0 @@
/*-----------------------------------------*\
| MSI3ZoneController.h |
| |
| Definitions and types for MSI/Steelseries|
| 3-Zone Keyboard lighting controller |
| |
| Adam Honse (CalcProgrammer1) 12/25/2019 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
class MSI3ZoneController
{
public:
MSI3ZoneController(hid_device* dev_handle);
~MSI3ZoneController();
char* GetDeviceName();
void SetLEDs(std::vector<RGBColor> colors);
private:
char device_name[32];
hid_device* dev;
};
@@ -1,36 +0,0 @@
#include "MSI3ZoneController.h"
#include "RGBController.h"
#include "RGBController_MSI3Zone.h"
#include <vector>
#include <hidapi/hidapi.h>
#define MSI_3_ZONE_KEYBOARD_VID 0x1770
#define MSI_3_ZONE_KEYBOARD_PID 0xFF00
/******************************************************************************************\
* *
* DetectMSI3ZoneControllers *
* *
* Tests the USB address to see if an MSI/SteelSeries 3-zone Keyboard controller *
* exists there. *
* *
\******************************************************************************************/
void DetectMSI3ZoneControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device* dev;
//Look for MSI/Steelseries 3-zone Keyboard
hid_init();
dev = hid_open(MSI_3_ZONE_KEYBOARD_VID, MSI_3_ZONE_KEYBOARD_PID, 0);
if( dev )
{
MSI3ZoneController* controller = new MSI3ZoneController(dev);
RGBController_MSI3Zone* rgb_controller = new RGBController_MSI3Zone(controller);
rgb_controllers.push_back(rgb_controller);
}
}
@@ -1,394 +0,0 @@
/*-----------------------------------------*\
| MSIMysticLightController.cpp |
| |
| Driver for MSI Mystic Light USB |
| lighting controller |
| |
| T-bond 3/4/2020 |
\*-----------------------------------------*/
#include "MSIMysticLightController.h"
#include <algorithm>
#include <array>
#include <bitset>
MSIMysticLightController::MSIMysticLightController(hid_device* handle, const char *path)
{
dev = handle;
if(dev)
{
loc = path;
ReadName();
ReadSerial();
ReadFwVersion();
ReadSettings();
}
}
MSIMysticLightController::~MSIMysticLightController()
{
if(dev)
{
hid_close(dev);
}
}
unsigned int MSIMysticLightController::GetZoneMinLedCount(ZONE /*zone*/)
{
return 1u;
}
unsigned int MSIMysticLightController::GetZoneMaxLedCount(ZONE zone)
{
switch (zone)
{
case J_RAINBOW_1:
case J_RAINBOW_2:
case J_CORSAIR:
return 4u; // TODO: It can be different by zone and by mobo
default:
return 1u;
}
}
unsigned int MSIMysticLightController::GetZoneLedCount(ZONE zone)
{
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
if (!requestedZone)
{
return GetZoneMaxLedCount(zone);
}
return requestedZone->cycle_or_led_num;
}
void MSIMysticLightController::SetZoneLedCount(ZONE zone, unsigned int led_count)
{
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
if (!requestedZone)
{
return;
}
led_count = std::min(GetZoneMaxLedCount(zone), std::max(GetZoneMinLedCount(zone), led_count));
requestedZone->cycle_or_led_num = led_count;
}
void MSIMysticLightController::SetMode(ZONE zone, EFFECT mode, SPEED speed, BRIGHTNESS brightness, bool rainbow_color)
{
ZoneData* zoneData = GetZoneData(zone);
if(!zoneData)
{
return;
}
zoneData->effect = mode;
zoneData->speedAndBrightnessFlags = (zoneData->speedAndBrightnessFlags & 128u) | brightness << 2u | speed;
zoneData->colorFlags = BitSet(zoneData->colorFlags, !rainbow_color, 7u);
}
std::string MSIMysticLightController::GetDeviceName()
{
return name;
}
std::string MSIMysticLightController::GetFWVersion()
{
return std::string("AP/LD ").append(version_APROM).append(" / ").append(version_LDROM);
}
std::string MSIMysticLightController::GetDeviceLocation()
{
return loc;
}
std::string MSIMysticLightController::GetSerial()
{
return chip_id;
}
bool MSIMysticLightController::ReadSettings()
{
return hid_get_feature_report(dev, reinterpret_cast<unsigned char *>(&data), sizeof data) == sizeof data;
}
bool MSIMysticLightController::Update()
{
return hid_send_feature_report(dev, reinterpret_cast<unsigned char *>(&data), sizeof data) == sizeof data;
}
void MSIMysticLightController::SaveOnUpdate(bool save)
{
data.save_data = save;
}
void MSIMysticLightController::SetZoneColor(ZONE zone, unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2)
{
ZoneData* zoneData = GetZoneData(zone);
if(!zoneData)
{
return;
}
zoneData->color.R = r1;
zoneData->color.G = g1;
zoneData->color.B = b1;
zoneData->color2.R = r2;
zoneData->color2.G = g2;
zoneData->color2.B = b2;
}
std::pair<Color, Color> MSIMysticLightController::GetZoneColor(ZONE zone)
{
ZoneData *zoneData = GetZoneData(zone);
if (!zoneData)
{
return std::make_pair(Color{}, Color{});
}
return std::make_pair(Color{
zoneData->color.R,
zoneData->color.G,
zoneData->color.B},
Color{zoneData->color2.R, zoneData->color2.G, zoneData->color2.B});
}
ZoneData *MSIMysticLightController::GetZoneData(ZONE zone)
{
switch (zone)
{
case J_RGB_1:
return &data.j_rgb_1;
case J_RGB_2:
return &data.j_rgb_2;
case J_RAINBOW_1:
return &data.j_rainbow_1;
case J_RAINBOW_2:
return &data.j_rainbow_2;
case J_PIPE_1:
return &data.j_pipe_1;
case J_PIPE_2:
return &data.j_pipe_2;
case ON_BOARD_LED:
return &data.on_board_led;
case ON_BOARD_LED_1:
return &data.on_board_led_1;
case ON_BOARD_LED_2:
return &data.on_board_led_2;
case ON_BOARD_LED_3:
return &data.on_board_led_3;
case ON_BOARD_LED_4:
return &data.on_board_led_4;
case ON_BOARD_LED_5:
return &data.on_board_led_5;
case ON_BOARD_LED_6:
return &data.on_board_led_6;
case ON_BOARD_LED_7:
return &data.on_board_led_7;
case ON_BOARD_LED_8:
return &data.on_board_led_8;
case ON_BOARD_LED_9:
return &data.on_board_led_9;
case J_CORSAIR_OUTERLL120:
return &data.j_corsair_outerll120;
default:
case J_CORSAIR:
break;
}
return nullptr;
}
RainbowZoneData *MSIMysticLightController::GetRainbowZoneData(ZONE zone)
{
switch (zone)
{
case J_RAINBOW_1:
return &data.j_rainbow_1;
case J_RAINBOW_2:
return &data.j_rainbow_2;
case J_CORSAIR:
default:
return nullptr;
}
}
bool MSIMysticLightController::ReadFwVersion()
{
// First read the APROM
// Checksum also available at report ID 180, with highCheksum stored at index 8, and low at 9
int num = 1;
unsigned char request[64] = {1, 176};
unsigned char response[64];
std::fill_n(request + 2, sizeof request - 2, 204);
num &= hid_write(dev, request, 64);
num &= hid_read(dev, response, 64);
unsigned char highValue = response[2] >> 4;
unsigned char lowValue = response[2] & 15;
version_APROM = std::to_string(static_cast<int>(highValue)).append(".").append(std::to_string(static_cast<int>(lowValue)));
// Now read the LDROM
// Checksum also available at report ID 184, with highCheksum stored at index 8, and low at 9
request[1] = 182u;
num &= hid_write(dev, request, 64);
num &= hid_read(dev, response, 64);
highValue = response[2] >> 4u;
lowValue = response[2] & 15u;
version_LDROM = std::to_string(static_cast<int>(highValue)).append(".").append(std::to_string(static_cast<int>(lowValue)));
return num == 1;
}
void MSIMysticLightController::ReadSerial()
{
wchar_t serial[256];
hid_get_serial_number_string(dev, serial, 256);
std::wstring wserial = std::wstring(serial);
chip_id = std::string(wserial.begin(), wserial.end());
}
void MSIMysticLightController::ReadName()
{
wchar_t tname[256];
hid_get_manufacturer_string(dev, tname, 256);
std::wstring wname = std::wstring(tname);
name = std::string(wname.begin(), wname.end());
hid_get_product_string(dev, tname, 256);
wname = std::wstring(tname);
name.append(" ").append(std::string(wname.begin(), wname.end()));
}
void MSIMysticLightController::SetDeviceSettings(bool is_fan, FAN_TYPE fan_type,
unsigned char corsair_device_quantity,
bool is_LL120Outer_individual)
{
// If is_fan false, it is a stripe
CorsairZoneData &settingsZone = data.j_corsair;
settingsZone.fan_flags = (settingsZone.fan_flags & 128u) | fan_type << 1u | is_fan;
settingsZone.corsair_quantity = corsair_device_quantity << 2u;
settingsZone.is_individual = BitSet(settingsZone.is_individual, is_LL120Outer_individual, 0u);
}
bool MSIMysticLightController::SetVolume(unsigned char main, unsigned char left, unsigned char right)
{
unsigned char packet[64];
std::fill_n(packet, sizeof packet, 204u);
if(main > 100u)
{
main = 100u;
}
if(left > 100u)
{
left = 100u;
}
if(right > 100u)
{
right = 100u;
}
packet[0] = 1u;
packet[1] = 192u;
packet[3] = main;
packet[4] = left;
packet[5] = right;
return hid_write(dev, packet, sizeof packet);
}
void MSIMysticLightController::SetBoardSyncSettings(bool onboard_sync, bool combine_JRGB, bool combine_JPIPE1,
bool combine_JPIPE2, bool combine_JRAINBOW1, bool combine_JRAINBOW2,
bool combine_crossair)
{
ZoneData &syncZone = data.on_board_led;
syncZone.colorFlags = BitSet(syncZone.colorFlags, onboard_sync, 0u);
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JRAINBOW1, 1u);
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JRAINBOW2, 2u);
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_crossair, 3u);
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JPIPE1, 4u);
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JPIPE2, 5u);
syncZone.speedAndBrightnessFlags = BitSet(syncZone.speedAndBrightnessFlags, combine_JRGB, 7u);
}
void MSIMysticLightController::GetMode(ZONE zone, EFFECT &mode, SPEED &speed, BRIGHTNESS &brightness, bool &rainbow_color)
{
ZoneData *zoneData = GetZoneData(zone);
if (!zoneData)
{
return;
}
mode = static_cast<EFFECT>(zoneData->effect);
speed = static_cast<SPEED>(zoneData->speedAndBrightnessFlags & 3u);
brightness = static_cast<BRIGHTNESS>((zoneData->speedAndBrightnessFlags >> 2u) & 31u);
rainbow_color = (zoneData->colorFlags & 128u) >> 7u;
}
unsigned char MSIMysticLightController::BitSet(unsigned char value, bool bit, unsigned int position)
{
return static_cast<unsigned char>(std::bitset<8>(value).set(position, bit).to_ulong());
}
void MSIMysticLightController::SetCycleCount(ZONE zone, unsigned char cycle_num)
{
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
if (!requestedZone)
{
return;
}
requestedZone->cycle_or_led_num = cycle_num;
}
unsigned char MSIMysticLightController::GetCycleCount(ZONE zone)
{
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
if (!requestedZone)
{
return 0;
}
return requestedZone->cycle_or_led_num;
}
void MSIMysticLightController::GetBoardSyncSettings(bool &onboard_sync, bool &combine_JRGB, bool &combine_JPIPE1,
bool &combine_JPIPE2, bool &combine_JRAINBOW1,
bool &combine_JRAINBOW2, bool &combine_crossair)
{
ZoneData &syncZone = data.on_board_led;
onboard_sync = syncZone.colorFlags & 1u;
combine_JRAINBOW1 = syncZone.colorFlags >> 1u & 1u;
combine_JRAINBOW2 = syncZone.colorFlags >> 1u & 1u;
combine_crossair = syncZone.colorFlags >> 3u & 1u;
combine_JPIPE1 = syncZone.colorFlags >> 4u & 1u;
combine_JPIPE2 = syncZone.colorFlags >> 5u & 1u;
combine_JRGB = (syncZone.speedAndBrightnessFlags & 128u) >> 7u;
}
void MSIMysticLightController::GetDeviceSettings(bool &stripe_or_fan, FAN_TYPE &fan_type,
unsigned char &corsair_device_quantity,
bool &is_LL120Outer_individual)
{
CorsairZoneData &settingsZone = data.j_corsair;
stripe_or_fan = settingsZone.fan_flags & 1u;
fan_type = static_cast<FAN_TYPE >((settingsZone.fan_flags & 14u) >> 1u);
corsair_device_quantity = (settingsZone.corsair_quantity & 252u) >> 2u;
is_LL120Outer_individual = settingsZone.is_individual & 1u;
}
@@ -1,228 +0,0 @@
/*-----------------------------------------*\
| MSIMysticLightController.h |
| |
| Definitions and types for MSI Mystic |
| Light USB lighting controllers |
| |
| T-bond 3/4/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <cstring>
#include <hidapi/hidapi.h>
#include <limits>
#pragma once
enum ZONE
{
J_RGB_1 = 1,
J_RGB_2 = 174,
J_PIPE_1 = 11,
J_PIPE_2 = 21,
J_RAINBOW_1 = 31,
J_RAINBOW_2 = 42,
J_CORSAIR = 53,
J_CORSAIR_OUTERLL120 = 64,
ON_BOARD_LED = 74,
ON_BOARD_LED_1 = 84,
ON_BOARD_LED_2 = 94,
ON_BOARD_LED_3 = 104,
ON_BOARD_LED_4 = 114,
ON_BOARD_LED_5 = 124,
ON_BOARD_LED_6 = 134,
ON_BOARD_LED_7 = 144,
ON_BOARD_LED_8 = 154,
ON_BOARD_LED_9 = 164
};
struct ZoneDescription
{
std::string name;
ZONE value;
};
enum EFFECT
{
DISABLE,
STATIC,
BREATHING,
FLASHING,
DOUBLE_FLASHING,
LIGHTNING,
MSI_MARQUEE,
METEOR,
WATER_DROP,
MSI_RAINBOW,
POP,
RAP,
JAZZ,
PLAY,
MOVIE,
COLOR_RING,
PLANETARY,
DOUBLE_METEOR,
ENERGY,
BLINK,
CLOCK,
COLOR_PULSE,
COLOR_SHIFT,
COLOR_WAVE,
MARQUEE,
RAINBOW,
RAINBOW_WAVE,
VISOR,
JRAINBOW,
RAINBOW_FLASHING,
RAINBOW_DOUBLE_FLASHING,
RANDOM,
FAN_CONTROL,
DISABLE_2,
COLOR_RING_FLASHING,
COLOR_RING_DOUBLE_FLASHING,
STACK,
CORSAIR_QUE,
FIRE,
LAVA
};
enum SPEED
{
LOW,
MEDIUM,
HIGH
};
enum FAN_TYPE
{
SP,
HD,
LL
};
enum BRIGHTNESS
{
OFF,
LEVEL_10,
LEVEL_20,
LEVEL_30,
LEVEL_40,
LEVEL_50,
LEVEL_60,
LEVEL_70,
LEVEL_80,
LEVEL_90,
LEVEL_100
};
struct Color
{
unsigned char R;
unsigned char G;
unsigned char B;
};
struct CorsairZoneData
{
unsigned char effect = EFFECT::STATIC;
Color color { std::numeric_limits<unsigned char>::max(), 0, 0 };
unsigned char fan_flags = 40;
unsigned char corsair_quantity;
unsigned char padding[3];
unsigned char is_individual = 0;
};
struct ZoneData
{
unsigned char effect = EFFECT::STATIC;
Color color { std::numeric_limits<unsigned char>::max(), 0u, 0u };
unsigned char speedAndBrightnessFlags = 40u;
Color color2 { 0, std::numeric_limits<unsigned char>::max(), 0u };
unsigned char colorFlags = 128u;
const unsigned char padding = 0u;
};
struct RainbowZoneData : ZoneData
{
unsigned char cycle_or_led_num = 20u;
};
struct FeaturePacket
{
const unsigned char report_id = 82u; // Report ID
ZoneData j_rgb_1; // 1
ZoneData j_pipe_1; // 11
ZoneData j_pipe_2; // 21
RainbowZoneData j_rainbow_1; // 31
RainbowZoneData j_rainbow_2; // 42
CorsairZoneData j_corsair; // 53
ZoneData j_corsair_outerll120; // 64
ZoneData on_board_led; // 74
ZoneData on_board_led_1; // 84
ZoneData on_board_led_2; // 94
ZoneData on_board_led_3; // 104
ZoneData on_board_led_4; // 114
ZoneData on_board_led_5; // 124
ZoneData on_board_led_6; // 134
ZoneData on_board_led_7; // 144
ZoneData on_board_led_8; // 154
ZoneData on_board_led_9; // 164
ZoneData j_rgb_2; // 174
unsigned char save_data = 0u; // 184
};
class MSIMysticLightController
{
public:
MSIMysticLightController(hid_device* handle, const char *path);
~MSIMysticLightController();
unsigned int GetZoneMinLedCount(ZONE zone);
unsigned int GetZoneMaxLedCount(ZONE zone);
unsigned int GetZoneLedCount(ZONE zone);
void SetZoneLedCount(ZONE zone, unsigned int led_count);
void SetMode(ZONE zone, EFFECT mode, SPEED speed, BRIGHTNESS brightness, bool rainbow_color);
void GetMode(ZONE zone, EFFECT &mode, SPEED &speed, BRIGHTNESS &brightness, bool &rainbow_color);
void SetZoneColor(ZONE zone, unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2);
void SetCycleCount(ZONE zone, unsigned char cycle_num);
unsigned char GetCycleCount(ZONE zone);
std::pair<Color, Color>
GetZoneColor(ZONE zone);
bool Update();
void SetDeviceSettings(bool stripe_or_fan, FAN_TYPE fan_type, unsigned char corsair_device_quantity, bool is_LL120Outer_individual);
void GetDeviceSettings(bool &stripe_or_fan, FAN_TYPE &fan_type, unsigned char &corsair_device_quantity, bool &is_LL120Outer_individual);
bool SetVolume(unsigned char main, unsigned char left, unsigned char right);
void SetBoardSyncSettings(bool onboard_sync, bool combine_JRGB, bool combine_JPIPE1, bool combine_JPIPE2, bool combine_JRAINBOW1, bool combine_JRAINBOW2, bool combine_crossair);
void GetBoardSyncSettings(bool &onboard_sync, bool &combine_JRGB, bool &combine_JPIPE1, bool &combine_JPIPE2, bool &combine_JRAINBOW1, bool &combine_JRAINBOW2, bool &combine_crossair);
std::string GetDeviceName();
std::string GetDeviceLocation();
std::string GetFWVersion();
std::string GetSerial();
private:
bool ReadSettings();
void SaveOnUpdate(bool send);
bool ReadFwVersion();
void ReadSerial();
void ReadName();
ZoneData* GetZoneData(ZONE zone);
RainbowZoneData*
GetRainbowZoneData(ZONE zone);
static unsigned char BitSet(unsigned char value, bool bit, unsigned int position);
hid_device* dev;
std::string name;
std::string loc;
std::string version_APROM;
std::string version_LDROM;
std::string chip_id;
FeaturePacket data;
};
@@ -1,98 +0,0 @@
#include "MSIMysticLightController.h"
#include "RGBController_MSIMysticLight.h"
#define MSI_USB_VID 0x1462
#define NUM_MSI_PIDS 41
static const unsigned short msi_pid_table[] =
{
0x7C67, // MS_7C67
0x7B10, // MS_7B10
0x7C87, // MS_7C87
0x7B93, // MS_7B93
0x7C34, // MS_7C34
0x7C35, // MS_7C35
0x7C36, // MS_7C36
0x7C37, // MS_7C37
0x7C42, // MS_7C42
0x7C84, // MS_7C84
0x7B94, // MS_7B94
0x7B96, // MS_7B96
0x7C59, // MS_7C59
0x7C60, // MS_7C60
0x7C70, // MS_7C70
0x7C71, // MS_7C71
0x7C73, // MS_7C73
0x7C75, // MS_7C75
0x7C76, // MS_7C76
0x7C77, // MS_7C77
0x7C79, // MS_7C79
0x7C80, // MS_7C80
0x7C98, // MS_7C98
0x7C99, // MS_7C99
0x7C81, // MS_7C81
0x7C82, // MS_7C82
0x7C83, // MS_7C83
0x7C85, // MS_7C85
0x7C86, // MS_7C86
0x7C88, // MS_7C88
0x7C89, // MS_7C89
0x4559, // MS_4459
0x3EA4, // MS_3EA4
0x905D, // MS_905D
0x7C90, // MS_7C90
0x7C91, // MS_7C91
0x7C92, // MS_7C92
0x7C94, // MS_7C94
0x7C95, // MS_7C95
0x7C96, // MS_7C96
0x7C56 // MS_7C56
};
/******************************************************************************************\
* *
* DetectMSIMysticLightControllers *
* *
* Detect MSI Mystic Light devices that use NCT6775 RGB controllers *
* *
\******************************************************************************************/
void DetectMSIMysticLightControllers(std::vector<RGBController*> &rgb_controllers)
{
hid_device_info* info;
hid_device* dev;
hid_init();
for(int device_idx = 0; device_idx < NUM_MSI_PIDS; device_idx++)
{
dev = NULL;
info = hid_enumerate(MSI_USB_VID, msi_pid_table[device_idx]);
//Look for MSI Mystic Light Controller
while(info)
{
if((info->vendor_id == MSI_USB_VID)
&&(info->product_id == msi_pid_table[device_idx]))
{
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
if( dev )
{
MSIMysticLightController * controller = new MSIMysticLightController(dev, info->path);
RGBController_MSIMysticLight * rgb_controller = new RGBController_MSIMysticLight(controller);
rgb_controllers.push_back(rgb_controller);
}
}
}
@@ -1,99 +0,0 @@
/*-----------------------------------------*\
| MSIRGBController.cpp |
| |
| Driver for MSI-RGB lighting controller |
| |
| Logic adapted from: |
| https://github.com/nagisa/msi-rgb |
| |
| Adam Honse (CalcProgrammer1) 2/11/2020 |
\*-----------------------------------------*/
#include "MSIRGBController.h"
#include "super_io.h"
MSIRGBController::MSIRGBController(int sioaddr)
{
msi_sioaddr = sioaddr;
/*-----------------------------------------------------*\
| This setup step isn't well documented |
| Without this, pulsing does not work |
\*-----------------------------------------------------*/
superio_outb(msi_sioaddr, SIO_REG_LOGDEV, 0x09);
int val_at_2c = superio_inb(msi_sioaddr, 0x2C);
val_at_2c &= 0b11110111;
val_at_2c |= 0b00010000;
superio_outb(msi_sioaddr, 0x2C, val_at_2c);
/*-----------------------------------------------------*\
| Set logical device register to RGB controller |
\*-----------------------------------------------------*/
superio_outb(msi_sioaddr, SIO_REG_LOGDEV, MSI_SIO_LOGDEV_RGB);
/*-----------------------------------------------------*\
| Test if RGB is enabled. If it is not, enable it. |
\*-----------------------------------------------------*/
int enable = superio_inb(msi_sioaddr, MSI_SIO_RGB_REG_ENABLE);
if((enable & MSI_SIO_RGB_ENABLE_MASK) != MSI_SIO_RGB_ENABLE_MASK)
{
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_ENABLE, MSI_SIO_RGB_ENABLE_MASK & (enable & !MSI_SIO_RGB_ENABLE_MASK));
}
/*-----------------------------------------------------*\
| Lighting enabled, no pulsing or blinking |
\*-----------------------------------------------------*/
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_CFG_1, 0x00);
/*-----------------------------------------------------*\
| Lighting enabled, RGB non-inverted, header on |
\*-----------------------------------------------------*/
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_CFG_3, 0xE2);
}
MSIRGBController::~MSIRGBController()
{
}
void MSIRGBController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
{
/*-----------------------------------------------------*\
| The MSI RGB controller uses 4 bits per color rather |
| than 8. Shift the values by 4 so that the 4 most |
| significant bits of each color are the new color value|
\*-----------------------------------------------------*/
red = red >> 4;
green = green >> 4;
blue = blue >> 4;
/*-----------------------------------------------------*\
| Set logical device register to RGB controller |
\*-----------------------------------------------------*/
superio_outb(msi_sioaddr, SIO_REG_LOGDEV, MSI_SIO_LOGDEV_RGB);
/*-----------------------------------------------------*\
| Write the colors to the color sequence registers |
| Only static mode is supported right now - all colors |
| are the same. |
\*-----------------------------------------------------*/
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_1_0, (red | (red << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_3_2, (red | (red << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_5_4, (red | (red << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_7_6, (red | (red << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_1_0, (green | (green << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_3_2, (green | (green << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_5_4, (green | (green << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_7_6, (green | (green << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_1_0, (blue | (blue << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_3_2, (blue | (blue << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_5_4, (blue | (blue << 4)));
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_7_6, (blue | (blue << 4)));
}
@@ -1,56 +0,0 @@
/*-----------------------------------------*\
| MSIRGBController.h |
| |
| Definitions and types for MSI-RGB |
| lighting controller |
| |
| Logic adapted from: |
| https://github.com/nagisa/msi-rgb |
| |
| Adam Honse (CalcProgrammer1) 2/11/2020 |
\*-----------------------------------------*/
#include <string>
#pragma once
#define MSI_SIO_LOGDEV_RGB 0x12
enum
{
MSI_SIO_RGB_REG_ENABLE = 0xE0,
MSI_SIO_RGB_REG_CFG_1 = 0xE4,
MSI_SIO_RGB_REG_RED_1_0 = 0xF0,
MSI_SIO_RGB_REG_RED_3_2 = 0xF1,
MSI_SIO_RGB_REG_RED_5_4 = 0xF2,
MSI_SIO_RGB_REG_RED_7_6 = 0xF3,
MSI_SIO_RGB_REG_GREEN_1_0 = 0xF4,
MSI_SIO_RGB_REG_GREEN_3_2 = 0xF5,
MSI_SIO_RGB_REG_GREEN_5_4 = 0xF6,
MSI_SIO_RGB_REG_GREEN_7_6 = 0xF7,
MSI_SIO_RGB_REG_BLUE_1_0 = 0xF8,
MSI_SIO_RGB_REG_BLUE_3_2 = 0xF9,
MSI_SIO_RGB_REG_BLUE_5_4 = 0xFA,
MSI_SIO_RGB_REG_BLUE_7_6 = 0xFB,
MSI_SIO_RGB_REG_CFG_2 = 0xFE,
MSI_SIO_RGB_REG_CFG_3 = 0xFF,
};
#define MSI_SIO_RGB_ENABLE_MASK 0xE0
class MSIRGBController
{
public:
MSIRGBController(int sioaddr);
~MSIRGBController();
std::string GetDeviceName();
std::string GetDeviceLocation();
unsigned int GetMode();
void SetMode(unsigned char new_mode, unsigned char new_speed);
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
private:
int msi_sioaddr;
};
@@ -1,40 +0,0 @@
#include "MSIRGBController.h"
#include "RGBController.h"
#include "RGBController_MSIRGB.h"
#include "super_io.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
/******************************************************************************************\
* *
* DetectMSIRGBControllers *
* *
* Detect MSI-RGB compatible Super-IO chips. *
* *
\******************************************************************************************/
void DetectMSIRGBControllers(std::vector<RGBController*> &rgb_controllers)
{
int sio_addrs[2] = {0x2E, 0x4E};
for(int sioaddr_idx = 0; sioaddr_idx < 2; sioaddr_idx++)
{
int sioaddr = sio_addrs[sioaddr_idx];
superio_enter(sioaddr);
int val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) | superio_inb(sioaddr, SIO_REG_DEVID + 1);
switch (val & SIO_ID_MASK)
{
case SIO_NCT6795_ID:
case SIO_NCT6797_ID:
MSIRGBController* new_msi = new MSIRGBController(sioaddr);
RGBController_MSIRGB* new_rgb = new RGBController_MSIRGB(new_msi);
rgb_controllers.push_back(new_rgb);
break;
}
}
} /* DetectMSIRGBControllers() */
@@ -1,303 +0,0 @@
/*---------------------------------------------------------*\
| Processing Code for NZXT Hue 2 |
| |
| Adam Honse ([email protected]), 12/29/2016 |
\*---------------------------------------------------------*/
#include "NZXTHue2Controller.h"
#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
NZXTHue2Controller::NZXTHue2Controller(hid_device* dev_handle)
{
dev = dev_handle;
SendFirmwareRequest();
GetStripsOnChannel(HUE_2_CHANNEL_1);
}
NZXTHue2Controller::~NZXTHue2Controller()
{
}
std::string NZXTHue2Controller::GetFirmwareVersion()
{
return(firmware_version);
}
unsigned int NZXTHue2Controller::GetStripsOnChannel(unsigned int /*channel*/)
{
unsigned int ret_val = 0;
unsigned char usb_buf[] =
{
0x20, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
for(int chan = 0; chan < 4; chan++)
{
unsigned int start = 0x0F + (6 * chan);
unsigned int num_leds_on_channel = 0;
for(int dev = 0; dev < 6; dev++)
{
switch(usb_buf[start + dev])
{
case 0x01: //Hue 1 strip
num_leds_on_channel += 10;
break;
case 0x02: //Aer 1 fan
num_leds_on_channel += 8;
break;
case 0x04: //Hue 2 strip
num_leds_on_channel += 10;
break;
case 0x0B: //Aer 2 fan (120mm)
num_leds_on_channel += 8;
break;
case 0x0C: //Aer 2 fan (140mm)
num_leds_on_channel += 8;
break;
default:
break;
}
}
channel_leds[chan] = num_leds_on_channel;
}
return(ret_val);
}
void NZXTHue2Controller::SetChannelEffect
(
unsigned char channel,
unsigned char mode,
unsigned char speed,
bool direction,
RGBColor * colors,
unsigned int num_colors
)
{
unsigned char color_data[24];
/*-----------------------------------------------------*\
| Fill in color data (up to 8 colors) |
\*-----------------------------------------------------*/
for (std::size_t idx = 0; idx < num_colors; idx++)
{
int pixel_idx = idx * 3;
RGBColor color = colors[idx];
color_data[pixel_idx + 0x00] = RGBGetGValue(color);
color_data[pixel_idx + 0x01] = RGBGetRValue(color);
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
}
/*-----------------------------------------------------*\
| Send effect packet |
\*-----------------------------------------------------*/
SendEffect(channel, mode, speed, direction, num_colors, &color_data[0]);
}
void NZXTHue2Controller::SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
unsigned int num_colors
)
{
unsigned char color_data[120];
/*-----------------------------------------------------*\
| Fill in color data (up to 40 colors) |
\*-----------------------------------------------------*/
for (std::size_t idx = 0; idx < num_colors; idx++)
{
int pixel_idx = idx * 3;
RGBColor color = colors[idx];
color_data[pixel_idx + 0x00] = RGBGetGValue(color);
color_data[pixel_idx + 0x01] = RGBGetRValue(color);
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
}
/*-----------------------------------------------------*\
| Send first group of color data |
\*-----------------------------------------------------*/
SendDirect(channel, 0, 20, &color_data[0]);
/*-----------------------------------------------------*\
| Send second group of color data if necessary |
\*-----------------------------------------------------*/
if(num_colors > 20)
{
SendDirect(channel, 1, 20, &color_data[60]);
}
/*-----------------------------------------------------*\
| Send apply packet |
\*-----------------------------------------------------*/
SendApply(channel);
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void NZXTHue2Controller::SendApply
(
unsigned char channel
)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Apply packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x22;
usb_buf[0x01] = 0xA0;
usb_buf[0x02] = (unsigned char)(1 << channel);
usb_buf[0x04] = 0x01;
usb_buf[0x07] = 0x28;
usb_buf[0x0A] = 0x80;
usb_buf[0x0C] = 0x32;
usb_buf[0x0F] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
}
void NZXTHue2Controller::SendDirect
(
unsigned char channel,
unsigned char group,
unsigned char color_count,
unsigned char* color_data
)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Direct packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x22;
usb_buf[0x01] = 0x10 | group;
usb_buf[0x02] = (unsigned char)(1 << channel);
usb_buf[0x03] = 0x00;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x04], color_data, color_count * 3);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
}
void NZXTHue2Controller::SendEffect
(
unsigned char channel,
unsigned char mode,
unsigned char speed,
bool direction,
unsigned char color_count,
unsigned char* color_data
)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Effect packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x28;
usb_buf[0x01] = 0x03;
usb_buf[0x02] = (unsigned char)(1 << channel);
usb_buf[0x03] = 0x28;
/*-----------------------------------------------------*\
| Set mode in USB packet |
\*-----------------------------------------------------*/
usb_buf[0x04] = mode;
/*-----------------------------------------------------*\
| Set speed in USB packet |
\*-----------------------------------------------------*/
usb_buf[0x05] = speed;
/*-----------------------------------------------------*\
| Set direction in USB packet |
\*-----------------------------------------------------*/
usb_buf[0x06] = direction ? 0x01 : 0x00;
/*-----------------------------------------------------*\
| Set color count in USB packet |
\*-----------------------------------------------------*/
usb_buf[0x08] = color_count;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x0A], color_data, color_count * 3);
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
}
void NZXTHue2Controller::SendFirmwareRequest()
{
unsigned char usb_buf[64];
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x00] = 0x10;
usb_buf[0x01] = 0x01;
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
snprintf(firmware_version, 16, "%u.%u.%u", usb_buf[0x11], usb_buf[0x12], usb_buf[0x13]);
}
@@ -1,114 +0,0 @@
/*---------------------------------------------------------*\
| Definitions for NZXT Hue 2 |
| |
| Adam Honse ([email protected]), 12/29/2016 |
\*---------------------------------------------------------*/
#include "RGBController.h"
#include <string>
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
enum
{
HUE_2_CHANNEL_ALL = 0x00, /* All channels */
HUE_2_CHANNEL_1 = 0x01, /* Channel 1 */
HUE_2_CHANNEL_2 = 0x02, /* Channel 2 */
HUE_2_CHANNEL_3 = 0x03, /* Channel 3 */
HUE_2_CHANNEL_4 = 0x04, /* Channel 4 */
HUE_2_NUM_CHANNELS = 0x04 /* Number of channels */
};
enum
{
HUE_2_CHANNEL_1_IDX = 0x00, /* Channel 1 array index */
HUE_2_CHANNEL_2_IDX = 0x01, /* Channel 2 array index */
HUE_2_CHANNEL_3_IDX = 0x01, /* Channel 3 array index */
HUE_2_CHANNEL_4_IDX = 0x01, /* Channel 4 array index */
};
enum
{
HUE_2_SPEED_SLOWEST = 0x00, /* Slowest speed */
HUE_2_SPEED_SLOW = 0x01, /* Slow speed */
HUE_2_SPEED_NORMAL = 0x02, /* Normal speed */
HUE_2_SPEED_FAST = 0x03, /* Fast speed */
HUE_2_SPEED_FASTEST = 0x04, /* Fastest speed */
};
enum
{
HUE_2_MODE_FIXED = 0x00, /* Fixed colors mode */
HUE_2_MODE_FADING = 0x01, /* Fading mode */
HUE_2_MODE_SPECTRUM = 0x02, /* Spectrum cycle mode */
HUE_2_MODE_MARQUEE = 0x03, /* Marquee mode */
HUE_2_MODE_COVER_MARQUEE = 0x04, /* Cover marquee mode */
HUE_2_MODE_ALTERNATING = 0x05, /* Alternating mode */
HUE_2_MODE_PULSING = 0x06, /* Pulsing mode */
HUE_2_MODE_BREATHING = 0x07, /* Breathing mode */
HUE_2_NUM_MODES /* Number of Hue 2 modes */
};
class NZXTHue2Controller
{
public:
NZXTHue2Controller(hid_device* dev_handle);
~NZXTHue2Controller();
std::string GetFirmwareVersion();
unsigned int GetStripsOnChannel
(
unsigned int channel
);
void SetChannelEffect
(
unsigned char channel,
unsigned char mode,
unsigned char speed,
bool direction,
RGBColor * colors,
unsigned int num_colors
);
void SetChannelLEDs
(
unsigned char channel,
RGBColor * colors,
unsigned int num_colors
);
unsigned int channel_leds[HUE_2_NUM_CHANNELS];
private:
hid_device* dev;
char firmware_version[16];
void SendApply
(
unsigned char channel
);
void SendDirect
(
unsigned char channel,
unsigned char group,
unsigned char color_count,
unsigned char* color_data
);
void SendEffect
(
unsigned char channel,
unsigned char mode,
unsigned char speed,
bool direction,
unsigned char color_count,
unsigned char* color_data
);
void SendFirmwareRequest();
};
@@ -1,80 +0,0 @@
#include "NZXTHue2Controller.h"
#include "RGBController.h"
#include "RGBController_NZXTHue2.h"
#include <vector>
#include <hidapi/hidapi.h>
#define NZXT_VID 0x1E71
#define NZXT_HUE_2_PID 0x2001
#define NZXT_HUE_2_AMBIENT_PID 0x2002
#define NZXT_SMART_DEVICE_V2_PID 0x2006
#define NZXT_RGB_FAN_CONTROLLER_PID 0x2009
typedef struct
{
unsigned short usb_vid;
unsigned short usb_pid;
const char * name;
} nzxt_hue_2_device;
#define NZXT_HUE_2_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
static const nzxt_hue_2_device device_list[] =
{
/*-----------------------------------------------------------------------------------------------------*\
| NZXT Hue 2 devices |
\*-----------------------------------------------------------------------------------------------------*/
{ NZXT_VID, NZXT_HUE_2_PID, "NZXT Hue 2" },
{ NZXT_VID, NZXT_HUE_2_AMBIENT_PID, "NZXT Hue 2 Ambient" },
{ NZXT_VID, NZXT_SMART_DEVICE_V2_PID, "NZXT Smart Device V2" },
{ NZXT_VID, NZXT_RGB_FAN_CONTROLLER_PID, "NZXT RGB & Fan Controller" },
};
/******************************************************************************************\
* *
* DetectNZXTHue2Controllers *
* *
* Detect devices supported by the NZXT Hue 2 driver *
* *
\******************************************************************************************/
void DetectNZXTHue2Controllers(std::vector<RGBController*> &rgb_controllers)
{
hid_device_info* info;
hid_device* dev;
hid_init();
for(std::size_t device_idx = 0; device_idx < NZXT_HUE_2_NUM_DEVICES; device_idx++)
{
dev = NULL;
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for NZXT Hue 2 devices
while(info)
{
if((info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid))
{
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
if( dev )
{
NZXTHue2Controller* controller = new NZXTHue2Controller(dev);
RGBController_NZXTHue2* rgb_controller = new RGBController_NZXTHue2(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
} /* DetectNZXTHue2Controllers() */
@@ -1,153 +0,0 @@
/*---------------------------------------------------------*\
| Driver for NZXT Kraken |
| |
| Martin Hartl (inlart), 04/04/2020 |
\*---------------------------------------------------------*/
#include "NZXTKrakenController.h"
#include <string>
#include <sstream>
#include <cstring>
static void SetColor(const std::vector<RGBColor>& colors, unsigned char* color_data)
{
for (std::size_t idx = 0; idx < colors.size(); idx++)
{
int pixel_idx = idx * 3;
RGBColor color = colors[idx];
color_data[pixel_idx + 0x00] = RGBGetRValue(color);
color_data[pixel_idx + 0x01] = RGBGetGValue(color);
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
}
}
static RGBColor ToLogoColor(RGBColor rgb)
{
return ToRGBColor(RGBGetGValue(rgb), RGBGetRValue(rgb), RGBGetBValue(rgb));
}
NZXTKrakenController::NZXTKrakenController(hid_device* dev_handle)
{
dev = dev_handle;
/*-----------------------------------------------------*\
| Get the firmware version |
\*-----------------------------------------------------*/
UpdateStatus();
}
NZXTKrakenController::~NZXTKrakenController()
{
hid_close(dev);
}
std::string NZXTKrakenController::GetFirmwareVersion()
{
return firmware_version;
}
void NZXTKrakenController::UpdateStatus()
{
unsigned char usb_buf[64];
memset(usb_buf, 0, sizeof(usb_buf));
hid_read(dev, usb_buf, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Extract cooler information |
\*-----------------------------------------------------*/
liquid_temperature = usb_buf[0x1] + (usb_buf[0x2] * 0.1);
fan_speed = usb_buf[0x3] << 8 | usb_buf[0x4];
pump_speed = usb_buf[0x5] << 8 | usb_buf[0x6];
/*-----------------------------------------------------*\
| Extract firmware version |
\*-----------------------------------------------------*/
int major = usb_buf[0xb];
int minor = usb_buf[0xc] << 8 | usb_buf[0xd];
int patch = usb_buf[0xe];
std::stringstream ss;
ss << major << '.' << minor << '.' << patch;
firmware_version = ss.str();
}
void NZXTKrakenController::UpdateEffect
(
NZXTKrakenChannel_t channel,
unsigned char mode,
bool direction,
unsigned char speed,
int seq,
std::vector<RGBColor> colors
)
{
unsigned char color_data[9 * 3];
memset(color_data, 0, sizeof(color_data));
if(!colors.empty() && channel != NZXT_KRAKEN_CHANNEL_RING)
{
colors[0] = ToLogoColor(colors[0]);
}
SetColor(colors, color_data);
SendEffect(channel, mode, direction, color_data, speed, false, seq);
}
void NZXTKrakenController::SendEffect
(
unsigned char channel,
unsigned char mode,
bool direction,
unsigned char* color_data,
unsigned char speed /* = 0x02 */,
bool movement /* = false */,
int cis /* = 0 */,
int size /* = 0 */
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set effect mode |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x02;
usb_buf[0x01] = 0x4c;
/*-----------------------------------------------------*\
| Set effect channel, movement and direction |
\*-----------------------------------------------------*/
usb_buf[0x02] = channel;
usb_buf[0x02] |= movement ? ( 1 << 3 ) : 0;
usb_buf[0x02] |= direction ? ( 1 << 4 ) : 0;
/*-----------------------------------------------------*\
| Set mode |
\*-----------------------------------------------------*/
usb_buf[0x03] = mode;
/*-----------------------------------------------------*\
| Set effect speed, size and color in set |
\*-----------------------------------------------------*/
usb_buf[0x04] = speed;
usb_buf[0x04] |= size << 3;
usb_buf[0x04] |= cis << 5;
/*-----------------------------------------------------*\
| Copy color data bytes |
\*-----------------------------------------------------*/
if(color_data)
{
memcpy(usb_buf + 0x05, color_data, 9 * 3);
}
/*-----------------------------------------------------*\
| Send effect |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, sizeof(usb_buf));
}
@@ -1,86 +0,0 @@
/*---------------------------------------------------------*\
| Definitions for NZXT Kraken |
| |
| Martin Hartl (inlart), 04/04/2020 |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include <vector>
#include <string>
#include <hidapi/hidapi.h>
enum NZXTKrakenChannel_t
{
NZXT_KRAKEN_CHANNEL_SYNC = 0x00, /* Sync Channel */
NZXT_KRAKEN_CHANNEL_LOGO = 0x01, /* Logo Channel */
NZXT_KRAKEN_CHANNEL_RING = 0x02, /* Ring Channel */
};
enum
{
NZXT_KRAKEN_MODE_FIXED = 0x00, /* Fixed colors mode */
NZXT_KRAKEN_MODE_FADING = 0x01, /* Fading mode */
NZXT_KRAKEN_MODE_SPECTRUM = 0x02, /* Spectrum cycle mode */
NZXT_KRAKEN_MODE_MARQUEE = 0x03, /* Marquee mode */
NZXT_KRAKEN_MODE_COVER_MARQUEE = 0x04, /* Cover marquee mode */
NZXT_KRAKEN_MODE_ALTERNATING = 0x05, /* Alternating mode */
NZXT_KRAKEN_MODE_BREATHING = 0x06, /* Breathing mode */
NZXT_KRAKEN_MODE_PULSE = 0x07, /* Pulse mode */
NZXT_KRAKEN_MODE_TAI_CHI = 0x08, /* Tai Chi mode */
NZXT_KRAKEN_MODE_WATER_COOLER = 0x09, /* Water color mode */
NZXT_KRAKEN_MODE_LOADING = 0x0a, /* Loading mode */
NZXT_KRAKEN_MODE_WINGS = 0x0c, /* Wings mode */
};
enum
{
NZXT_KRAKEN_SPEED_SLOWEST = 0x00, /* Slowest speed */
NZXT_KRAKEN_SPEED_SLOW = 0x01, /* Slow speed */
NZXT_KRAKEN_SPEED_NORMAL = 0x02, /* Normal speed */
NZXT_KRAKEN_SPEED_FAST = 0x03, /* Fast speed */
NZXT_KRAKEN_SPEED_FASTEST = 0x04, /* Fastest speed */
};
class NZXTKrakenController
{
public:
NZXTKrakenController(hid_device* dev_handle);
~NZXTKrakenController();
std::string GetFirmwareVersion();
void UpdateEffect
(
NZXTKrakenChannel_t channel,
unsigned char mode,
bool direction,
unsigned char speed,
int seq,
std::vector<RGBColor> colors
);
private:
void UpdateStatus();
void SendEffect
(
unsigned char channel,
unsigned char mode,
bool direction,
unsigned char* color_data,
unsigned char speed = 0x02,
bool movement = false,
int cis = 0 ,
int size = 0
);
hid_device* dev;
// -- status
std::string firmware_version;
double liquid_temperature;
unsigned int fan_speed;
unsigned int pump_speed;
};
@@ -1,33 +0,0 @@
#include "NZXTKrakenController.h"
#include "RGBController.h"
#include "RGBController_NZXTKraken.h"
#include <vector>
#include <hidapi/hidapi.h>
#define NZXT_KRAKEN_VID 0x1E71
#define NZXT_KRAKEN_PID 0x170E
/******************************************************************************************\
* *
* DetectNZXTKrakenControllers *
* *
* Detect devices supported by the NZXTKraken driver *
* * *
\******************************************************************************************/
void DetectNZXTKrakenControllers(std::vector<RGBController*> &rgb_controllers)
{
hid_init();
hid_device* dev = hid_open(NZXT_KRAKEN_VID, NZXT_KRAKEN_PID, nullptr);
if( dev )
{
NZXTKrakenController* controller = new NZXTKrakenController(dev);
RGBController_NZXTKraken* rgb_controller = new RGBController_NZXTKraken(controller);
rgb_controllers.push_back(rgb_controller);
}
}
@@ -76,6 +76,9 @@ unsigned int PatriotViperController::GetMode()
void PatriotViperController::SetEffectColor(unsigned char red, unsigned char green, unsigned char blue)
{
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
@@ -85,13 +88,19 @@ void PatriotViperController::SetEffectColor(unsigned char red, unsigned char gre
ViperRegisterWrite(VIPER_REG_LED3_EFFECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_REG_LED4_EFFECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_REG_MODE, mode, 0x00, speed);
ViperRegisterWrite(VIPER_REG_MODE, mode, 0x00, 0x0C);
ViperRegisterWrite(VIPER_REG_MODE, 0xAA, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_MODE, 0xFA, 0x00, 0x00);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void PatriotViperController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
{
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
@@ -102,71 +111,110 @@ void PatriotViperController::SetAllColors(unsigned char red, unsigned char green
ViperRegisterWrite(VIPER_REG_LED4_DIRECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_REG_APPLY, 0x01, 0x00, 0x00);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void PatriotViperController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_LED0_DIRECT_COLOR + led, red, blue, green);
ViperRegisterWrite(VIPER_REG_APPLY, 0x01, 0x00, 0x00);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void PatriotViperController::SetLEDEffectColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_LED0_EFFECT_COLOR + led, red, blue, green);
ViperRegisterWrite(VIPER_REG_MODE, mode, 0x00, speed);
ViperRegisterWrite(VIPER_REG_MODE, mode, 0x00, 0x0C);
ViperRegisterWrite(VIPER_REG_MODE, 0xAA, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_MODE, 0xFA, 0x00, 0x00);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void PatriotViperController::SetLEDColor(unsigned int /*slot*/, unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
void PatriotViperController::SetLEDColor(unsigned int slot, unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_LED0_DIRECT_COLOR + led, red, blue, green);
ViperRegisterWrite(VIPER_REG_APPLY, 0x01, 0x00, 0x00);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void PatriotViperController::SetLEDEffectColor(unsigned int /*slot*/, unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
void PatriotViperController::SetLEDEffectColor(unsigned int slot, unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_LED0_EFFECT_COLOR + led, red, blue, green);
ViperRegisterWrite(VIPER_REG_MODE, mode, 0x00, speed);
ViperRegisterWrite(VIPER_REG_MODE, mode, 0x00, 0x0C);
ViperRegisterWrite(VIPER_REG_MODE, 0xAA, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_MODE, 0xFA, 0x00, 0x00);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void PatriotViperController::SetMode(unsigned char new_mode, unsigned char new_speed)
void PatriotViperController::SetMode(unsigned char new_mode)
{
direct = false;
mode = new_mode;
speed = new_speed;
mode = new_mode;
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_MODE, mode, 0x00, speed);
ViperRegisterWrite(VIPER_REG_MODE, new_mode, 0x00, 0x0C);
ViperRegisterWrite(VIPER_REG_MODE, 0xAA, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_MODE, 0xFA, 0x00, 0x00);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void PatriotViperController::SetDirect()
{
direct = true;
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
ViperRegisterWrite(VIPER_REG_APPLY, 0x01, 0x00, 0x00);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void PatriotViperController::ViperRegisterWrite(viper_register reg, unsigned char val0, unsigned char val1, unsigned char val2)
@@ -45,16 +45,6 @@ enum
VIPER_MODE_NEON = 0x08, /* Neon mode */
};
enum
{
VIPER_SPEED_MIN = 0xC8, /* Slowest speed for non-breathing mode */
VIPER_SPEED_DEFAULT = 0x64, /* Default speed for non-breathing mode */
VIPER_SPEED_MAX = 0x14, /* Fastest speed for non-breathing mode */
VIPER_SPEED_BREATHING_MIN = 0xFF, /* Slowest speed for breathing mode */
VIPER_SPEED_BREATHING_DEFAULT = 0x0C, /* Default speed for breathing mode */
VIPER_SPEED_BREATHING_MAX = 0x00, /* Fastest speed for breathing mode */
};
class PatriotViperController
{
public:
@@ -66,7 +56,7 @@ public:
unsigned int GetLEDCount();
unsigned int GetSlotCount();
unsigned int GetMode();
void SetMode(unsigned char new_mode, unsigned char new_speed);
void SetMode(unsigned char new_mode);
void SetDirect();
void SetAllColors(unsigned char red, unsigned char green, unsigned char blue);
@@ -85,6 +75,5 @@ private:
unsigned char slots_valid;
i2c_smbus_interface* bus;
viper_dev_id dev;
unsigned char mode;
unsigned char speed;
unsigned int mode;
};
@@ -6,7 +6,16 @@
#include <stdio.h>
#include <stdlib.h>
using namespace std::chrono_literals;
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
/******************************************************************************************\
* *
@@ -35,13 +44,13 @@ void DetectPatriotViperControllers(std::vector<i2c_smbus_interface*> &busses, st
// Tests SPD addresses in order: 0x00, 0x40, 0x41, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68
busses[bus]->i2c_smbus_write_byte_data(0x36, 0x00, 0xFF);
std::this_thread::sleep_for(1ms);
Sleep(1);
if(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x00) == 0x23)
{
busses[bus]->i2c_smbus_write_byte_data(0x37, 0x00, 0xFF);
std::this_thread::sleep_for(1ms);
Sleep(1);
if((busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x40) == 0x85)
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x41) == 0x02)
@@ -58,7 +67,7 @@ void DetectPatriotViperControllers(std::vector<i2c_smbus_interface*> &busses, st
}
}
std::this_thread::sleep_for(1ms);
Sleep(1);
}
if(slots_valid != 0)
@@ -15,33 +15,31 @@ PolychromeController::PolychromeController(i2c_smbus_interface* bus, polychrome_
this->bus = bus;
this->dev = dev;
unsigned short fw_version = GetFirmwareVersion();
unsigned char major_version = fw_version >> 8;
unsigned char minor_version = fw_version & 0xFF;
switch (GetFirmwareVersion())
{
case FIRMWARE_VER_1_PT_10:
led_count = 1;
asr_led = true;
strcpy(device_name, "ASRock ASR LED FW 1.10");
break;
/*-----------------------------------------------------*\
| Determine whether the device uses ASR LED or |
| Polychrome protocol by checking firmware version. |
| Versions 1.xx and 2.xx use ASR LED, 3.xx uses |
| Polychrome |
\*-----------------------------------------------------*/
if((major_version < 0x03) && (major_version > 0x00))
{
snprintf(device_name, 32, "ASRock ASR LED FW %d.%02d", major_version, minor_version);
led_count = 1;
asr_led = true;
case FIRMWARE_VER_2_PT_00:
led_count = 1;
asr_led = false;
strcpy(device_name, "ASRock Polychrome FW 2.00");
break;
case FIRMWARE_VER_3_PT_00:
led_count = 1;
asr_led = false;
strcpy(device_name, "ASRock Polychrome FW 3.00");
break;
default:
led_count = 0;
strcpy(device_name, "");
break;
}
else if(major_version == 0x03)
{
snprintf(device_name, 32, "ASRock Polychrome FW %d.%02d", major_version, minor_version);
led_count = 1;
asr_led = false;
}
else
{
led_count = 0;
}
}
PolychromeController::~PolychromeController()
@@ -78,38 +76,45 @@ unsigned int PolychromeController::GetLEDCount()
unsigned int PolychromeController::GetMode()
{
return(active_mode);
return(0);
}
bool PolychromeController::IsAsrLed()
void PolychromeController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
{
return(asr_led);
}
void PolychromeController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char colors[3] = { red, green, blue };
if (asr_led)
{
bus->i2c_smbus_write_block_data(dev, active_mode, 3, colors);
}
else
{
unsigned char colors[3] = { red, green, blue };
bus->i2c_smbus_write_block_data(dev, POLYCHROME_REG_COLOR, 3, colors);
}
}
void PolychromeController::SetLEDColor(unsigned int /*led*/, unsigned char red, unsigned char green, unsigned char blue)
{
if (asr_led)
{
}
else
{
unsigned char colors[3] = { red, green, blue };
bus->i2c_smbus_write_block_data(dev, POLYCHROME_REG_COLOR, 3, colors);
}
}
void PolychromeController::SetMode(unsigned char mode)
{
active_mode = mode;
if (asr_led)
{
bus->i2c_smbus_write_block_data(dev, ASRLED_REG_MODE, 1, &active_mode);
}
else
{
bus->i2c_smbus_write_block_data(dev, POLYCHROME_REG_MODE, 1, &active_mode);
bus->i2c_smbus_write_byte_data(dev, POLYCHROME_REG_MODE, mode);
}
}
@@ -14,6 +14,13 @@
typedef unsigned char polychrome_dev_id;
enum
{
FIRMWARE_VER_1_PT_10 = 0x010A, /* Firmware nu51_1.10 */
FIRMWARE_VER_2_PT_00 = 0x0200, /* Firmware nu51_2.00 */
FIRMWARE_VER_3_PT_00 = 0x0300, /* Firmware nu51_3.00 */
};
enum
{
ASRLED_REG_FIRMWARE_VER = 0x00, /* Firmware version Major.Minor */
@@ -70,8 +77,8 @@ public:
char* GetDeviceName();
unsigned int GetLEDCount();
unsigned int GetMode();
bool IsAsrLed();
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
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 SetMode(unsigned char mode);
unsigned short GetFirmwareVersion();
@@ -79,8 +86,7 @@ private:
bool asr_led;
char device_name[32];
unsigned int led_count;
unsigned char active_mode;
i2c_smbus_interface* bus;
polychrome_dev_id dev;
};
};
@@ -1,232 +0,0 @@
/*-----------------------------------------*\
| PoseidonZRGBController.cpp |
| |
| Driver for Thermaltake Poseidon Z RGB |
| Keyboard lighting controller |
| |
| Adam Honse (CalcProgrammer1) 12/25/2019 |
\*-----------------------------------------*/
#include "PoseidonZRGBController.h"
#include <cstring>
using namespace std::chrono_literals;
static unsigned int keys[] = {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x15,
0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
0x24, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31,
0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3E, 0x3F, 0x40,
0x41, 0x42, 0x43, 0x44, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C,
0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x66, 0x67, 0x68, 0x69, 0x6A,
0x6C, 0x6D, 0x6F, 0x70, 0x72, 0x73, 0x75, 0x76, 0x77, 0x78, 0x7C, 0x80, 0x81 };
PoseidonZRGBController::PoseidonZRGBController(hid_device* dev_handle)
{
dev = dev_handle;
}
PoseidonZRGBController::~PoseidonZRGBController()
{
}
void PoseidonZRGBController::SetMode(unsigned char mode, unsigned char direction, unsigned char speed)
{
active_mode = mode;
active_direction = direction;
active_speed = speed;
SendControl
(
POSEIDONZ_PROFILE_P1,
POSEIDONZ_PROFILE_P1,
active_direction,
active_mode,
POSEIDONZ_BRIGHTNESS_MAX,
active_speed
);
std::this_thread::sleep_for(200ms);
}
void PoseidonZRGBController::SetLEDsDirect(std::vector<RGBColor> colors)
{
unsigned char red_grn_buf[264];
unsigned char blu_buf[264];
/*-----------------------------------------------------*\
| Zero out buffers |
\*-----------------------------------------------------*/
memset(red_grn_buf, 0x00, sizeof(red_grn_buf));
memset(blu_buf, 0x00, sizeof(blu_buf));
/*-----------------------------------------------------*\
| Set up Direct packets |
\*-----------------------------------------------------*/
red_grn_buf[0] = 0x07;
red_grn_buf[1] = POSEIDONZ_PACKET_ID_SET_DIRECT;
red_grn_buf[2] = POSEIDONZ_PROFILE_P1;
red_grn_buf[3] = POSEIDONZ_DIRECT_RED_GREEN;
red_grn_buf[4] = 0x00;
red_grn_buf[5] = 0x00;
red_grn_buf[6] = 0x00;
red_grn_buf[7] = 0x00;
blu_buf[0] = 0x07;
blu_buf[1] = POSEIDONZ_PACKET_ID_SET_DIRECT;
blu_buf[2] = POSEIDONZ_PROFILE_P1;
blu_buf[3] = POSEIDONZ_DIRECT_BLUE;
blu_buf[4] = 0x00;
blu_buf[5] = 0x00;
blu_buf[6] = 0x00;
blu_buf[7] = 0x00;
/*-----------------------------------------------------*\
| Fill in color data |
\*-----------------------------------------------------*/
for(std::size_t i = 0; i < 104; i++)
{
red_grn_buf[keys[i] ] = RGBGetRValue(colors[i]);
red_grn_buf[keys[i] + 128] = RGBGetGValue(colors[i]);
blu_buf[ keys[i] ] = RGBGetBValue(colors[i]);
}
/*-----------------------------------------------------*\
| Send packets |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, red_grn_buf, 264);
std::this_thread::sleep_for(5ms);
hid_send_feature_report(dev, blu_buf, 264);
}
void PoseidonZRGBController::SetLEDs(std::vector<RGBColor> colors)
{
unsigned char red_color_data[104];
unsigned char grn_color_data[104];
unsigned char blu_color_data[104];
for(std::size_t i = 0; i < 104; i++)
{
red_color_data[i] = RGBGetRValue(colors[i]);
grn_color_data[i] = RGBGetGValue(colors[i]);
blu_color_data[i] = RGBGetBValue(colors[i]);
}
SendColor
(
POSEIDONZ_PROFILE_P1,
POSEIDONZ_COLOR_RED,
red_color_data
);
std::this_thread::sleep_for(10ms);
SendColor
(
POSEIDONZ_PROFILE_P1,
POSEIDONZ_COLOR_GREEN,
grn_color_data
);
std::this_thread::sleep_for(10ms);
SendColor
(
POSEIDONZ_PROFILE_P1,
POSEIDONZ_COLOR_BLUE,
blu_color_data
);
std::this_thread::sleep_for(10ms);
SendControl
(
POSEIDONZ_PROFILE_P1,
POSEIDONZ_PROFILE_P1,
active_direction,
active_mode,
POSEIDONZ_BRIGHTNESS_MAX,
active_speed
);
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void PoseidonZRGBController::SendColor
(
unsigned char profile_to_edit,
unsigned char color_channel,
unsigned char* color_data
)
{
unsigned char buf[264];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Color packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x07;
buf[0x01] = POSEIDONZ_PACKET_ID_SET_COLOR;
buf[0x02] = profile_to_edit;
buf[0x03] = color_channel;
/*-----------------------------------------------------*\
| Fill in color data |
\*-----------------------------------------------------*/
for(int i = 0; i < 104; i++)
{
buf[keys[i]] = color_data[i];
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 264);
}
void PoseidonZRGBController::SendControl
(
unsigned char profile_to_activate,
unsigned char profile_to_edit,
unsigned char direction,
unsigned char mode,
unsigned char brightness,
unsigned char speed
)
{
unsigned char buf[264];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Effect packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x07;
buf[0x01] = POSEIDONZ_PACKET_ID_SET_EFFECT;
buf[0x02] = profile_to_activate;
buf[0x08] = profile_to_edit;
buf[0x0A] = direction;
buf[0x0C] = mode;
buf[0x0D] = brightness;
buf[0x10] = 0x08;
buf[0x12] = speed;
buf[0x13] = 0x50;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 264);
}
@@ -1,106 +0,0 @@
/*-----------------------------------------*\
| PoseidonZRGBController.h |
| |
| Definitions and types for Thermaltake |
| Poseidon Z RGB Keyboard lighting |
| controller |
| |
| Adam Honse (CalcProgrammer1) 12/25/2019 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
#define POSEIDONZ_START 0x07
#define POSEIDONZ_PROFILE 0x01
#define POSEIDONZ_LED_CMD 0x0E
#define POSEIDONZ_RED_GRN_CH 0x01
#define POSEIDONZ_BLU_CH 0x02
enum
{
POSEIDONZ_PACKET_ID_SET_EFFECT = 0x02, /* Set profile effect packet */
POSEIDONZ_PACKET_ID_SET_COLOR = 0x09, /* Set profile color packet */
POSEIDONZ_PACKET_ID_SET_DIRECT = 0x0E, /* Set direct color packet */
};
enum
{
POSEIDONZ_MODE_STATIC = 0x00,
POSEIDONZ_MODE_REACTIVE = 0x01,
POSEIDONZ_MODE_ARROW_FLOW = 0x02,
POSEIDONZ_MODE_WAVE = 0x03,
POSEIDONZ_MODE_RIPPLE = 0x04
};
enum
{
POSEIDONZ_PROFILE_P1 = 0x01,
POSEIDONZ_PROFILE_P2 = 0x02,
POSEIDONZ_PROFILE_P3 = 0x03,
POSEIDONZ_PROFILE_P4 = 0x04,
POSEIDONZ_PROFILE_P5 = 0x05
};
enum
{
POSEIDONZ_BRIGHTNESS_MIN = 0x00,
POSEIDONZ_BRIGHTNESS_MAX = 0x04
};
enum
{
POSEIDONZ_COLOR_RED = 0x01,
POSEIDONZ_COLOR_GREEN = 0x02,
POSEIDONZ_COLOR_BLUE = 0x03
};
enum
{
POSEIDONZ_DIRECT_RED_GREEN = 0x01,
POSEIDONZ_DIRECT_BLUE = 0x02
};
enum
{
POSEIDONZ_SPEED_SLOW = 0x10,
POSEIDONZ_SPEED_FAST = 0x05
};
class PoseidonZRGBController
{
public:
PoseidonZRGBController(hid_device* dev_handle);
~PoseidonZRGBController();
void SetMode(unsigned char mode, unsigned char direction, unsigned char speed);
void SetLEDsDirect(std::vector<RGBColor> colors);
void SetLEDs(std::vector<RGBColor> colors);
private:
hid_device* dev;
unsigned char active_mode;
unsigned char active_direction;
unsigned char active_speed;
void SendControl
(
unsigned char profile_to_activate,
unsigned char profile_to_edit,
unsigned char direction,
unsigned char mode,
unsigned char brightness,
unsigned char speed
);
void SendColor
(
unsigned char profile_to_edit,
unsigned char color_channel,
unsigned char* color_data
);
};
@@ -1,52 +0,0 @@
#include "PoseidonZRGBController.h"
#include "RGBController.h"
#include "RGBController_PoseidonZRGB.h"
#include <vector>
#include <hidapi/hidapi.h>
#define TT_POSEIDON_Z_RGB_VID 0x264A
#define TT_POSEIDON_Z_RGB_PID 0x3006
/******************************************************************************************\
* *
* DetectPoseidonZRGBControllers *
* *
* Tests the USB address to see if a Thermaltake Poseidon Z RGB Keyboard controller *
* exists there. *
* *
\******************************************************************************************/
void DetectPoseidonZRGBControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device_info* info;
hid_device* dev = NULL;
hid_init();
info = hid_enumerate(TT_POSEIDON_Z_RGB_VID, TT_POSEIDON_Z_RGB_PID);
//Look for Thermaltake Poseidon Z RGB, Interface 2
while(info)
{
if((info->vendor_id == TT_POSEIDON_Z_RGB_VID)
&&(info->product_id == TT_POSEIDON_Z_RGB_PID)
&&(info->interface_number == 2))
{
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
if( dev )
{
PoseidonZRGBController* controller = new PoseidonZRGBController(dev);
RGBController_PoseidonZRGB* rgb_controller = new RGBController_PoseidonZRGB(controller);
rgb_controllers.push_back(rgb_controller);
}
}
@@ -1,78 +0,0 @@
/*-----------------------------------------*\
| RGBFusion2DRAMController.cpp |
| |
| Driver for Gigabyte Aorus RGB Fusion 2 |
| DRAM lighting controller |
| |
| Adam Honse (CalcProgrammer1) 6/7/2020 |
\*-----------------------------------------*/
#include "RGBFusion2DRAMController.h"
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
RGBFusion2DRAMController::RGBFusion2DRAMController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev)
{
/*-----------------------------------------------------*\
| Initialize pointers |
\*-----------------------------------------------------*/
this->bus = bus;
this->dev = dev;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(led_data, 0, sizeof(led_data));
/*-----------------------------------------------------*\
| Initialize controller with 6 LEDs and mask 0x3B |
| This is hard coded for Aorus RGB RAM |
\*-----------------------------------------------------*/
led_data[RGB_FUSION_2_DRAM_LED_EN_MASK] = 0x3B;
led_count = 6;
/*-----------------------------------------------------*\
| Initialize brightness to 100% |
\*-----------------------------------------------------*/
led_data[RGB_FUSION_2_DRAM_IDX_BRIGHTNESS] = 0x64;
}
unsigned int RGBFusion2DRAMController::GetLEDCount()
{
return(led_count);
}
std::string RGBFusion2DRAMController::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(return_string);
}
void RGBFusion2DRAMController::Apply()
{
bus->i2c_smbus_write_byte_data(dev, RGB_FUSION_2_DRAM_APPLY_ADDR, RGB_FUSION_2_DRAM_ACTION_APPLY);
}
void RGBFusion2DRAMController::SetLEDEffect
(
unsigned int led,
int mode,
unsigned int speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
led_data[RGB_FUSION_2_DRAM_IDX_MODE] = mode;
led_data[RGB_FUSION_2_DRAM_IDX_RED] = red;
led_data[RGB_FUSION_2_DRAM_IDX_GREEN] = green;
led_data[RGB_FUSION_2_DRAM_IDX_BLUE] = blue;
bus->i2c_smbus_write_block_data(dev, RGB_FUSION_2_DRAM_LED_START_ADDR, 32, led_data);
}
@@ -1,72 +0,0 @@
/*-----------------------------------------*\
| RGBFusion2DRAMController.h |
| |
| Definitions and types for Gigabyte Aorus |
| RGB Fusion 2 DRAM lighting controller |
| |
| Adam Honse (CalcProgrammer1) 6/7/2020 |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char rgb_fusion_dev_id;
enum
{
RGB_FUSION_2_DRAM_LED_EN_MASK = 0x00, /* LED enable bitfield */
RGB_FUSION_2_DRAM_IDX_MODE = 0x09, /* Mode index */
RGB_FUSION_2_DRAM_IDX_BRIGHTNESS = 0x0A, /* Brightness index */
RGB_FUSION_2_DRAM_IDX_BLUE = 0x0C, /* Blue index */
RGB_FUSION_2_DRAM_IDX_GREEN = 0x0D, /* Green index */
RGB_FUSION_2_DRAM_IDX_RED = 0x0E, /* Red index */
// RGB_FUSION_2_DRAM_TIMER_1_LSB = 0x08, /* Timer 1 LSB. Valid timer values [0-65535] */
// RGB_FUSION_2_DRAM_TIMER_1_MSB = 0x09, /* Timer 1 MSB. Timer unis are milliseconds */
// RGB_FUSION_2_DRAM_TIMER_2_LSB = 0x0A, /* Timer 2 LSB */
// RGB_FUSION_2_DRAM_TIMER_2_MSB = 0x0B, /* Timer 2 MSB */
// RGB_FUSION_2_DRAM_TIMER_3_LSB = 0x0C, /* Timer 3 LSB */
// RGB_FUSION_2_DRAM_TIMER_3_MSB = 0x0D, /* Timer 3 MSB */
// RGB_FUSION_2_DRAM_IDX_OPT_1 = 0x0E, /* Option 1. Use case varies by mode */
// RGB_FUSION_2_DRAM_IDX_OPT_2 = 0x0F, /* Option 2. Use case varies by mode */
};
enum
{
RGB_FUSION_2_DRAM_LED_START_ADDR = 0x20,
RGB_FUSION_2_DRAM_APPLY_ADDR = 0x28,
};
enum
{
RGB_FUSION_2_DRAM_ACTION_APPLY = 0x0F,
};
class RGBFusion2DRAMController
{
public:
RGBFusion2DRAMController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev);
~RGBFusion2DRAMController();
std::string GetDeviceLocation();
unsigned int GetLEDCount();
void Apply();
void SetLEDEffect
(
unsigned int led,
int mode,
unsigned int speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
unsigned int led_count;
i2c_smbus_interface* bus;
rgb_fusion_dev_id dev;
unsigned char led_data[32];
};
@@ -1,67 +0,0 @@
#include "RGBFusion2DRAMController.h"
#include "RGBController.h"
#include "RGBController_RGBFusion2DRAM.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string>
/******************************************************************************************\
* *
* TestForRGBFusion2DRAMController *
* *
* Tests the given address to see if an RGB 2 Fusion DRAMcontroller exists there. *
* First does a quick write to test for a response *
* *
\******************************************************************************************/
bool TestForRGBFusion2DRAMController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
if (res >= 0)
{
pass = true;
// res = bus->i2c_smbus_read_byte_data(address, 0xF2);
// if (res != 0xC4)
// {
// pass = false;
// }
}
return(pass);
} /* TestForRGBFusion2DRAMController() */
/******************************************************************************************\
* *
* DetectRGBFusion2DRAMControllers *
* *
* Detect RGB Fusion 2 controllers on the enumerated I2C busses at address 0x67. *
* *
* bus - pointer to i2c_smbus_interface where RGB Fusion device is connected *
* dev - I2C address of RGB Fusion device *
* *
\******************************************************************************************/
void DetectRGBFusion2DRAMControllers(std::vector<i2c_smbus_interface*>& busses, std::vector<RGBController*>& rgb_controllers)
{
RGBFusion2DRAMController* new_rgb_fusion;
RGBController_RGBFusion2DRAM* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Check for RGB Fusion 2 DRAM controller at 0x67
if (TestForRGBFusion2DRAMController(busses[bus], 0x67))
{
new_rgb_fusion = new RGBFusion2DRAMController(busses[bus], 0x67);
new_controller = new RGBController_RGBFusion2DRAM(new_rgb_fusion);
rgb_controllers.push_back(new_controller);
}
}
} /* DetectRGBFusion2DRAMControllers() */
@@ -1,139 +0,0 @@
/*-----------------------------------------*\
| RGBFusion2SMBusController.cpp |
| |
| Driver for Gigabyte Aorus RGB Fusion 2 |
| SMBus lighting controller |
| |
| Adam Honse (CalcProgrammer1) 3/12/2020 |
| Matt Harper 5/5/2020 |
\*-----------------------------------------*/
#include "RGBFusion2SMBusController.h"
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#ifdef DEBUG
#include <iostream>
#include <iomanip>
#endif
RGBFusion2SMBusController::RGBFusion2SMBusController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev)
{
this->bus = bus;
this->dev = dev;
memset(led_data, 0, 10*16);
led_count = 10; // Protocol supports 10 'slots'
}
unsigned int RGBFusion2SMBusController::GetLEDCount()
{
return(led_count);
}
std::string RGBFusion2SMBusController::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(return_string);
}
/* Writes are performed in 32 byte chunks. If we need to write the second 16 bytes,
* we must necessarily write the first 16 as well. 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.
* That is to say, the current behavior is non-deal but the best we have
*/
void RGBFusion2SMBusController::WriteLED(int led)
{
unsigned short register_offset = led / 2; // Relying on integer division to truncate
unsigned short write_register = RGB_FUSION_2_LED_START_ADDR + 2*register_offset;
// Adjust if we are writing the second 16 bytes
if(led % 2)
{
led -= 1;
}
#ifdef DEBUG
std::cout << std::hex << write_register << "\t";
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 16; j++)
{
std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)led_data[led+i][j] << " ";
}
std::cout << " ";
}
std::cout << std::endl;
#endif
bus->i2c_smbus_write_block_data(RGB_FUSION_2_SMBUS_ADDR, write_register, 32, led_data[led]);
}
void RGBFusion2SMBusController::Apply()
{
// 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,
int mode,
unsigned int speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
led_data[led][RGB_FUSION_2_IDX_MODE] = mode;
led_data[led][RGB_FUSION_2_IDX_RED] = red;
led_data[led][RGB_FUSION_2_IDX_GREEN] = green;
led_data[led][RGB_FUSION_2_IDX_BLUE] = blue;
led_data[led][RGB_FUSION_2_IDX_BRIGHTNESS] = 0x64;
switch (mode)
{
case RGB_FUSION_2_MODE_PULSE:
// Timer 1: On time
// Timer 2: Off time
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;
led_data[led][RGB_FUSION_2_TIMER_2_MSB] = 0x03 * speed;
break;
case RGB_FUSION_2_MODE_COLOR_CYCLE:
// Timer 1: Cycle time
led_data[led][RGB_FUSION_2_TIMER_1_LSB] = 0x00;
led_data[led][RGB_FUSION_2_TIMER_1_MSB] = 0x03 * speed;
led_data[led][RGB_FUSION_2_IDX_OPT_1] = 0x07; // Number of colors to cycle through. Valid range [1-7]
led_data[led][RGB_FUSION_2_IDX_OPT_2] = 0x00; // Color cycle, or color cycle and pulse. [0,1]
break;
case RGB_FUSION_2_MODE_FLASHING:
/* Timer 1: On time
* Timer 2: Interval
* Timer 3: Cycle time */
led_data[led][RGB_FUSION_2_TIMER_1_LSB] = 0x64;
led_data[led][RGB_FUSION_2_TIMER_1_MSB] = 0;
led_data[led][RGB_FUSION_2_TIMER_2_LSB] = 0xc8;
led_data[led][RGB_FUSION_2_TIMER_2_MSB] = 0;
led_data[led][RGB_FUSION_2_TIMER_3_LSB] = 0xd0;
led_data[led][RGB_FUSION_2_TIMER_3_MSB] = 0x07;
led_data[led][RGB_FUSION_2_IDX_OPT_1] = speed; // Controls number of flashes
break;
}
WriteLED(led);
}
@@ -1,103 +0,0 @@
/*-----------------------------------------*\
| RGBFusion2SMBusController.h |
| |
| Definitions and types for Gigabyte Aorus |
| RGB Fusion 2 SMBus lighting controller |
| |
| Adam Honse (CalcProgrammer1) 3/12/2020 |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char rgb_fusion_dev_id;
enum
{
RGB_FUSION_2_IDX_MODE = 0x01, /* Mode index */
RGB_FUSION_2_IDX_BRIGHTNESS = 0x02, /* Brightness index */
RGB_FUSION_2_IDX_MAX_BRIGHTNESS = 0x02, /* Max brightness index */
RGB_FUSION_2_IDX_MIN_BRIGHTNESS = 0x03, /* Minimum brightness index */
RGB_FUSION_2_IDX_BLUE = 0x04, /* Blue index */
RGB_FUSION_2_IDX_GREEN = 0x05, /* Green index */
RGB_FUSION_2_IDX_RED = 0x06, /* Red index */
RGB_FUSION_2_IDX_WHITE = 0x07, /* White index */
RGB_FUSION_2_TIMER_1_LSB = 0x08, /* Timer 1 LSB. Valid timer values [0-65535] */
RGB_FUSION_2_TIMER_1_MSB = 0x09, /* Timer 1 MSB. Timer unis are milliseconds */
RGB_FUSION_2_TIMER_2_LSB = 0x0A, /* Timer 2 LSB */
RGB_FUSION_2_TIMER_2_MSB = 0x0B, /* Timer 2 MSB */
RGB_FUSION_2_TIMER_3_LSB = 0x0C, /* Timer 3 LSB */
RGB_FUSION_2_TIMER_3_MSB = 0x0D, /* Timer 3 MSB */
RGB_FUSION_2_IDX_OPT_1 = 0x0E, /* Option 1. Use case varies by mode */
RGB_FUSION_2_IDX_OPT_2 = 0x0F, /* Option 2. Use case varies by mode */
};
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 */
RGB_FUSION_2_MODE_MUSIC = 0x02, /* Music mode */
RGB_FUSION_2_MODE_COLOR_CYCLE = 0x03, /* Color cycle mode */
RGB_FUSION_2_MODE_STATIC = 0x04, /* Static color mode */
RGB_FUSION_2_MODE_FLASHING = 0x05, /* Flashing / Double Flashing mode */
RGB_FUSION_2_MODE_TRANSITION = 0x09, /* Gradual transition from current */
RGB_FUSION_2_MODE_DIGITAL_A = 0x0A, /* Wave mode */
RGB_FUSION_2_MODE_DIGITAL_B = 0x0B, /* */
RGB_FUSION_2_MODE_DIGITAL_C = 0x0C, /* */
RGB_FUSION_2_MODE_DIGITAL_D = 0x0D, /* */
RGB_FUSION_2_MODE_DIGITAL_E = 0x0E, /* */
RGB_FUSION_2_MODE_DIGITAL_F = 0x0F, /* */
RGB_FUSION_2_MODE_DIGITAL_G = 0x10, /* */
RGB_FUSION_2_MODE_DIGITAL_H = 0x11, /* */
RGB_FUSION_2_MODE_DIGITAL_I = 0x12, /* */
};
enum
{
RGB_FUSION_2_SPEED_FAST = 0x01,
RGB_FUSION_2_SPEED_NORMAL = 0x02,
RGB_FUSION_2_SPEED_SLOW = 0x04,
};
class RGBFusion2SMBusController
{
public:
RGBFusion2SMBusController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev);
~RGBFusion2SMBusController();
std::string GetDeviceLocation();
unsigned int GetLEDCount();
void Apply();
void SetLEDEffect
(
unsigned int led,
int mode,
unsigned int speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
unsigned int led_count;
i2c_smbus_interface* bus;
rgb_fusion_dev_id dev;
unsigned char led_data[10][16];
void WriteLED(int);
};
@@ -1,73 +0,0 @@
#include "RGBFusion2SMBusController.h"
#include "RGBController.h"
#include "RGBController_RGBFusion2SMBus.h"
#include "i2c_smbus.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string>
/******************************************************************************************\
* *
* TestForRGBFusion2SMBusController *
* *
* Tests the given address to see if an RGB 2 Fusion controller exists there. First *
* does a quick write to test for a response *
* *
\******************************************************************************************/
bool TestForRGBFusion2SMBusController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
if (res >= 0)
{
pass = true;
// res = bus->i2c_smbus_read_byte_data(address, 0xF2);
// if (res != 0xC4)
// {
// pass = false;
// }
}
return(pass);
} /* TestForRGBFusion2SMBusController() */
/******************************************************************************************\
* *
* DetectRGBFusion2SMBusControllers *
* *
* Detect RGB Fusion 2 controllers on the enumerated I2C busses at address 0x68. *
* *
* bus - pointer to i2c_smbus_interface where RGB Fusion device is connected *
* dev - I2C address of RGB Fusion device *
* *
\******************************************************************************************/
void DetectRGBFusion2SMBusControllers(std::vector<i2c_smbus_interface*>& busses, std::vector<RGBController*>& rgb_controllers)
{
RGBFusion2SMBusController* new_rgb_fusion;
RGBController_RGBFusion2SMBus* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// TODO - Is this necessary? Or an artifact of my own system?
// Skip dmcd devices
std::string device_name = std::string(busses[bus]->device_name);
if (device_name.find("dmdc") == std::string::npos)
{
// Check for RGB Fusion 2 controller at 0x68
if (TestForRGBFusion2SMBusController(busses[bus], 0x68))
{
new_rgb_fusion = new RGBFusion2SMBusController(busses[bus], 0x68);
new_controller = new RGBController_RGBFusion2SMBus(new_rgb_fusion);
rgb_controllers.push_back(new_controller);
}
}
}
} /* DetectRGBFusion2SMBusControllers() */
@@ -1,290 +0,0 @@
/*-----------------------------------------*\
| RGBFusion2USBController.cpp |
| |
| Driver for Gigabyte Aorus RGB Fusion 2.0 |
| USB lighting controller |
| |
| jackun 1/8/2020 |
\*-----------------------------------------*/
#include "RGBFusion2USBController.h"
#include <algorithm>
#include <array>
#include <thread>
#include <chrono>
static LEDCount LedCountToEnum(unsigned int c)
{
if (c <= 32)
return(LEDS_32);
if (c <= 64)
return(LEDS_64);
if (c <= 256)
return(LEDS_256);
if (c <= 512)
return(LEDS_512);
return(LEDS_1024);
}
RGBFusion2USBController::RGBFusion2USBController(hid_device* handle, const char *path) : dev(handle)
{
int res = 0;
char text[64] {};
unsigned char buffer[64] {};
if( dev ) {
SetCalibration();
// hid report read needs 0x60 packet or it gives IO error
SendPacket(0x60, 0x00);
buffer[0] = report_id;
res = hid_get_feature_report(dev, buffer, 64);
if( res > 0 )
{
report = *reinterpret_cast<IT8297Report*>(buffer);
name = std::string(report.str_product, 32);
name.erase(std::find(name.begin(), name.end(), '\0'), name.end());
snprintf(text, 11, "0x%08X", report.fw_ver);
version = text;
snprintf(text, 11, "0x%08X", report.chip_id);
chip_id = text;
}
loc = path;
EnableBeat(false);
}
}
RGBFusion2USBController::~RGBFusion2USBController()
{
if( dev ) {
hid_close(dev);
}
}
void RGBFusion2USBController::SetMode(int m)
{
mode = m;
}
// Sets RGB color mapping to LED pins.
// "Custom" RGB packets don't seem to get remapped so use report.byteorderN and do it manually.
// Of course it all depends how we send data to the controller, but bios/rgb fusion 2 itself
// set it up like this.
void RGBFusion2USBController::SetCalibration()
{
uint8_t buffer[64] {};
buffer[0] = report_id;
buffer[1] = 0x33;
// D_LED1 WS2812 GRB, 0x00RRGGBB to 0x00GGRRBB
buffer[2] = 0x02; // B
buffer[3] = 0x00; // G
buffer[4] = 0x01; // R
buffer[5] = 0x00;
// D_LED2 WS2812 GRB
buffer[6] = 0x02;
buffer[7] = 0x00;
buffer[8] = 0x01;
buffer[9] = 0x00;
// LED C1/C2 12vGRB, seems pins already connect to LEDs correctly
buffer[10] = 0x00;
buffer[11] = 0x01;
buffer[12] = 0x02;
buffer[13] = 0x00;
SendPacket(buffer);
}
void RGBFusion2USBController::SetLedCount(unsigned int count)
{
LEDCount s0 = LedCountToEnum(count);
SendPacket(0x34, s0 | (s0 << 4)); // D_LED1 | D_LED2
}
bool RGBFusion2USBController::DisableBuiltinEffect(int enable_bit, int mask)
{
if(effect_disabled & enable_bit)
return(true);
effect_disabled &= ~mask;
effect_disabled |= enable_bit;
int res = SendPacket(0x32, effect_disabled);
// Sometimes effect doesn't apply at first, delay a little and let MCU to react, if this packet is the cause
std::this_thread::sleep_for(std::chrono::milliseconds(50));
return res;
}
bool RGBFusion2USBController::EnableBeat(bool e)
{
return SendPacket(0x31, e ? 1 : 0);
}
std::string RGBFusion2USBController::GetDeviceName()
{
return(name);
}
std::string RGBFusion2USBController::GetFWVersion()
{
return(version);
}
std::string RGBFusion2USBController::GetDeviceLocation()
{
return(loc);
}
std::string RGBFusion2USBController::GetSerial()
{
return(chip_id);
}
void RGBFusion2USBController::SetStripColors
(
unsigned int hdr,
RGBColor * colors,
unsigned int num_colors,
int single_led
)
{
PktRGB pkt;
pkt.Init(hdr, report_id);
// FIXME assuming that LED strips ports are 0x58/0x59 for all boards
uint32_t byteorder = hdr == HDR_D_LED1_RGB ? report.byteorder0 : report.byteorder1;
unsigned char bo_r = byteorder >> 16;
unsigned char bo_g = byteorder >> 8;
unsigned char bo_b = byteorder & 0xFF;
int res;
int leds_left = num_colors;
int sent_data = 0;
int k = 0;
int leds_in_pkt = sizeof(pkt.s.leds) / sizeof(*pkt.s.leds); /* 19 */
// other leds stay at whatever the builtin effect was doing at that moment
// if breathing/pulse effect faded out then they stay dark
if(single_led > -1)
{
leds_left = 1;
k = single_led;
sent_data = k * 3;
leds_in_pkt = 1;
}
while(leds_left > 0)
{
leds_in_pkt = (std::min)(leds_in_pkt, leds_left);
leds_left -= leds_in_pkt;
pkt.s.bcount = leds_in_pkt * 3;
pkt.s.boffset = sent_data;
sent_data += pkt.s.bcount;
for(int i = 0; i < leds_in_pkt; i++)
{
RGBColor color = colors[k];
unsigned char red = RGBGetRValue(color);
unsigned char grn = RGBGetGValue(color);
unsigned char blu = RGBGetBValue(color);
pkt.buffer[5 + i * 3 + bo_r] = red;
pkt.buffer[5 + i * 3 + bo_g] = grn;
pkt.buffer[5 + i * 3 + bo_b] = blu;
k++;
}
res = SendPacket(pkt.buffer);
if(res < 0)
return;
}
if (hdr == HDR_D_LED1_RGB)
DisableBuiltinEffect(0x01, 0x01);
else
DisableBuiltinEffect(0x02, 0x02);
}
static const std::array< std::array<int, 3>, 5> speeds = {
{
{1600, 1600, 200},
{1200, 1200, 200},
{800, 800, 200},
{400, 400, 200},
{200, 200, 200},
},
};
void RGBFusion2USBController::SetLEDEffect(unsigned int led, int mode, unsigned int speed, bool random, unsigned char r, unsigned char g, unsigned char b)
{
PktEffect pkt;
pkt.Init(led, report_id);
pkt.e.effect_type = mode;
pkt.e.color0 = r << 16 | g << 8 | b;
if (speed < speeds.size()) {
const auto& s = speeds[speed];
pkt.e.period0 = s[0];
pkt.e.period1 = s[1];
pkt.e.period2 = s[2];
}
switch(mode)
{
case 0: break;
case 1: break; // static
case 2: // breathing
case 3: // blink
if (random)
pkt.e.effect_param0 = 7; // cycle through up to 7 (max?) colors
break;
case 4: // color cycle
pkt.e.effect_param0 = 7; // cycle through up to 7 (max?) colors
break;
// "fake" effects
case 10: // flashing, flashing color cycle
pkt.e.period0 = 200;
pkt.e.period1 = 200;
pkt.e.period2 = 5000 - 1000 * speed; // time between flashing, doesn't seem to be affected by period0/period1
pkt.e.effect_type = 3;
pkt.e.effect_param2 = 2; // flash twice
if (random)
pkt.e.effect_param0 = 7;
break;
}
SendPacket(pkt.buffer);
}
bool RGBFusion2USBController::ApplyEffect()
{
return SendPacket(0x28, 0xFF);
}
bool RGBFusion2USBController::SendPacket(uint8_t a, uint8_t b, uint8_t c)
{
unsigned char buffer[64] {};
buffer[0] = report_id;
buffer[1] = a;
buffer[2] = b;
buffer[3] = c;
return (SendPacket(buffer) == 64);
}
int RGBFusion2USBController::SendPacket(unsigned char* packet)
{
return hid_send_feature_report(dev, packet, 64);
}
@@ -1,196 +0,0 @@
/*-----------------------------------------*\
| RGBFusion2USBController.h |
| |
| Definitions and types for Gigabyte Aorus |
| RGB Fusion 2.0 USB lighting controller |
| |
| jackun 1/8/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <cstring>
#include <hidapi/hidapi.h>
#pragma once
// LED "headers" 0x20..0x27, As seen on Gigabyte X570 Elite board
const uint8_t HDR_BACK_IO = 0x20;
const uint8_t HDR_CPU = 0x21;
const uint8_t HDR_LED_2 = 0x22;
const uint8_t HDR_PCIE = 0x23;
const uint8_t HDR_LED_C1C2 = 0x24;
const uint8_t HDR_D_LED1 = 0x25;
const uint8_t HDR_D_LED2 = 0x26;
const uint8_t HDR_LED_7 = 0x27;
const uint8_t HDR_D_LED1_RGB = 0x58; // FIXME assuming that it is 0x58 for all boards
const uint8_t HDR_D_LED2_RGB = 0x59;
enum EffectType
{
EFFECT_NONE = 0,
EFFECT_STATIC = 1,
EFFECT_PULSE = 2,
EFFECT_BLINKING = 3,
EFFECT_COLORCYCLE = 4,
// to be continued...
};
enum LEDCount
{
LEDS_32 = 0,
LEDS_64,
LEDS_256,
LEDS_512,
LEDS_1024,
};
struct LEDs
{
uint8_t r;
uint8_t g;
uint8_t b;
};
#pragma pack(push, 1)
union PktRGB
{
unsigned char buffer[64];
struct RGBData
{
uint8_t report_id;
uint8_t header;
uint16_t boffset; // in bytes, absolute
uint8_t bcount;
LEDs leds[19];
uint16_t padding0;
} s;
PktRGB() : s {}
{
}
void Init(uint8_t header, uint8_t report_id)
{
s.report_id = report_id;
s.header = header;
s.boffset = 0;
s.bcount = 0;
memset(s.leds, 0, sizeof(s.leds));
}
};
union PktEffect
{
unsigned char buffer[64];
struct Effect
{
uint8_t report_id;
uint8_t header;
uint32_t zone0; // rgb fusion seems to set it to pow(2, header - 0x20)
uint32_t zone1;
uint8_t reserved0;
uint8_t effect_type;
uint8_t max_brightness;
uint8_t min_brightness;
uint32_t color0;
uint32_t color1;
uint16_t period0; // fade in
uint16_t period1; // fade out
uint16_t period2; // hold
uint16_t period3;
uint8_t effect_param0;
uint8_t effect_param1;
uint8_t effect_param2;
uint8_t effect_param3;
uint8_t padding0[30];
} e;
PktEffect() : e {}
{
}
void Init(int header, uint8_t report_id)
{
memset(buffer, 0, sizeof(buffer));
e.report_id = report_id;
if (header < 8)
e.header = 32 + header; // set as default
else
e.header = header;
e.zone0 = (uint32_t)(1 << (e.header - 32));
e.effect_type = EFFECT_STATIC;
e.max_brightness = 100;
e.min_brightness = 0;
e.color0 = 0x00FF2100; //orange
e.period0 = 1200;
e.period1 = 1200;
e.period2 = 200;
e.period3 = 200;
e.effect_param0 = 0; // ex color count to cycle through (max seems to be 7)
e.effect_param1 = 0;
e.effect_param2 = 1; // ex flash repeat count
e.effect_param3 = 0;
}
};
struct IT8297Report
{
uint8_t report_id;
uint8_t product;
uint8_t device_num;
uint8_t total_leds;
uint32_t fw_ver;
uint16_t curr_led_count;
uint16_t reserved0;
char str_product[32]; // might be 28 and an extra byteorder3
uint32_t byteorder0; // is little-endian 0x00RRGGBB ?
uint32_t byteorder1;
uint32_t byteorder2;
uint32_t chip_id;
uint32_t reserved1;
};
#pragma pack(pop)
class RGBFusion2USBController
{
public:
RGBFusion2USBController(hid_device* handle, const char *path);
~RGBFusion2USBController();
void SetStripColors
(
unsigned int hdr,
RGBColor * colors,
unsigned int num_colors,
int single_led = -1
);
void SetLEDEffect(unsigned int led, int mode, unsigned int speed, bool random, unsigned char red, unsigned char green, unsigned char blue);
void SetLedCount(unsigned int count);
void SetMode(int mode);
bool ApplyEffect();
bool DisableBuiltinEffect(int enable_bit, int mask);
void SetCalibration();
std::string GetDeviceName();
std::string GetDeviceLocation();
std::string GetFWVersion();
std::string GetSerial();
private:
bool EnableBeat(bool enable);
bool SendPacket(uint8_t a, uint8_t b, uint8_t c = 0);
int SendPacket(unsigned char* packet);
hid_device* dev;
int mode;
IT8297Report report;
std::string name;
std::string loc;
std::string version;
std::string chip_id;
int effect_disabled = 0;
int report_id = 0xCC;
};
@@ -1,37 +0,0 @@
#include "RGBFusion2USBController.h"
#include "RGBController_RGBFusion2USB.h"
#define IT8297_VID 0x048D
#define IT8297_PID 0x8297
/******************************************************************************************\
* *
* DetectRGBFusion2USBControllers *
* *
* Detect RGB Fusion 2 devices that use IT8297 RGB controller *
* *
\******************************************************************************************/
void DetectRGBFusion2USBControllers(std::vector<RGBController*> &rgb_controllers)
{
if (hid_init() < 0)
return;
hid_device_info * device_list = hid_enumerate(IT8297_VID, IT8297_PID);
if (!device_list)
return;
hid_device_info * device = device_list;
while (device)
{
hid_device * dev = hid_open_path(device->path);
if (dev) {
RGBFusion2USBController * controller = new RGBFusion2USBController(dev, device_list->path);
RGBController_RGBFusion2USB * rgb_controller = new RGBController_RGBFusion2USB(controller);
rgb_controllers.push_back(rgb_controller);
}
device = device->next;
}
hid_free_enumeration(device_list);
}
@@ -63,6 +63,9 @@ void RGBFusionController::SetAllColors(unsigned char red, unsigned char green, u
{
unsigned char mode_ch_0;
unsigned char mode_ch_1;
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
switch_bank(1);
set_color_ch_0(red, green, blue);
@@ -74,6 +77,8 @@ void RGBFusionController::SetAllColors(unsigned char red, unsigned char green, u
set_mode_ch_0(mode_ch_0);
set_mode_ch_1(mode_ch_1);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void RGBFusionController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
@@ -83,32 +88,48 @@ void RGBFusionController::SetLEDColor(unsigned int led, unsigned char red, unsig
switch (led)
{
case 0:
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
switch_bank(1);
set_color_ch_0(red, green, blue);
switch_bank(0);
mode = get_mode_ch_0();
set_mode_ch_0(mode);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
break;
case 1:
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
switch_bank(1);
set_color_ch_1(red, green, blue);
switch_bank(0);
mode = get_mode_ch_1();
set_mode_ch_1(mode);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
break;
}
}
void RGBFusionController::SetMode(unsigned char mode, unsigned char speed)
void RGBFusionController::SetMode(unsigned char mode)
{
//Lock SMBus interface
bus->i2c_smbus_wait_and_lock();
switch_bank(0);
set_mode_ch_0(mode);
set_timers_ch_0(speed_table[0][speed], speed_table[1][speed]);
set_mode_ch_1(mode);
set_timers_ch_1(speed_table[0][speed], speed_table[1][speed]);
//Unlock SMBus interface
bus->i2c_smbus_unlock();
}
void RGBFusionController::dump()
@@ -172,22 +193,6 @@ void RGBFusionController::set_mode_ch_1(unsigned char mode)
bus->i2c_smbus_write_byte_data(dev, RGB_FUSION_BANK_0_REG_CH_1_MODE, mode + RGB_FUSION_WRITE_MODE_OFST);
}
void RGBFusionController::set_timers_ch_0(unsigned short timer0, unsigned short timer1)
{
bus->i2c_smbus_write_byte_data(dev, RGB_FUSION_BANK_0_REG_CH_0_TIMER_0_MSB, timer0 >> 8);
bus->i2c_smbus_write_byte_data(dev, RGB_FUSION_BANK_0_REG_CH_0_TIMER_0_LSB, timer0 & 0xFF);
bus->i2c_smbus_write_byte_data(dev, RGB_FUSION_BANK_0_REG_CH_0_TIMER_1_MSB, timer1 >> 8);
bus->i2c_smbus_write_byte_data(dev, RGB_FUSION_BANK_0_REG_CH_0_TIMER_1_LSB, timer1 & 0xFF);
}
void RGBFusionController::set_timers_ch_1(unsigned short timer0, unsigned short timer1)
{
bus->i2c_smbus_write_byte_data(dev, RGB_FUSION_BANK_0_REG_CH_1_TIMER_0_MSB, timer0 >> 8);
bus->i2c_smbus_write_byte_data(dev, RGB_FUSION_BANK_0_REG_CH_1_TIMER_0_LSB, timer0 & 0xFF);
bus->i2c_smbus_write_byte_data(dev, RGB_FUSION_BANK_0_REG_CH_1_TIMER_1_MSB, timer1 >> 8);
bus->i2c_smbus_write_byte_data(dev, RGB_FUSION_BANK_0_REG_CH_1_TIMER_1_LSB, timer1 & 0xFF);
}
void RGBFusionController::switch_bank(unsigned char bank)
{
bus->i2c_smbus_write_byte_data(dev, RGB_FUSION_BANK_SWITCH_REG, bank);
@@ -17,23 +17,7 @@ typedef unsigned char rgb_fusion_dev_id;
enum
{
RGB_FUSION_BANK_0_REG_CH_0_MODE = 0x03, /* Channel 0 Mode Selection */
RGB_FUSION_BANK_0_REG_CH_0_TIMER_0_MSB
= 0x06, /* Channel 0 Timer 0 MSB */
RGB_FUSION_BANK_0_REG_CH_0_TIMER_0_LSB
= 0x07, /* Channel 0 Timer 0 LSB */
RGB_FUSION_BANK_0_REG_CH_0_TIMER_1_MSB
= 0x08, /* Channel 0 Timer 1 MSB */
RGB_FUSION_BANK_0_REG_CH_0_TIMER_1_LSB
= 0x09, /* Channel 0 Timer 1 LSB */
RGB_FUSION_BANK_0_REG_CH_1_MODE = 0x13, /* Channel 1 Mode Selection */
RGB_FUSION_BANK_0_REG_CH_1_TIMER_0_MSB
= 0x16, /* Channel 1 Timer 0 MSB */
RGB_FUSION_BANK_0_REG_CH_1_TIMER_0_LSB
= 0x17, /* Channel 1 Timer 0 LSB */
RGB_FUSION_BANK_0_REG_CH_1_TIMER_1_MSB
= 0x18, /* Channel 1 Timer 1 MSB */
RGB_FUSION_BANK_0_REG_CH_1_TIMER_1_LSB
= 0x19, /* Channel 1 Timer 1 LSB */
RGB_FUSION_BANK_1_REG_CH_0_R = 0x00, /* Channel 0 Red Value */
RGB_FUSION_BANK_1_REG_CH_0_G = 0x01, /* Channel 0 Green Value */
RGB_FUSION_BANK_1_REG_CH_0_B = 0x02, /* Channel 0 Blue Value */
@@ -43,19 +27,6 @@ enum
RGB_FUSION_BANK_SWITCH_REG = 0xF0, /* Bank Switch Register */
};
enum
{
RGB_FUSION_SPEED_SLOW = 0x00, /* Slowest speed */
RGB_FUSION_SPEED_NORMAL = 0x01, /* Normal speed */
RGB_FUSION_SPEED_FAST = 0x02, /* Fastest speed */
};
static const short speed_table[2][3] =
{
{ 0x01E0, 0x00F0, 0x0078 },
{ 0x4000, 0x2000, 0x1000 }
};
#define RGB_FUSION_NUMBER_MODES 3 /* Number of RGB Fusion modes */
#define RGB_FUSION_WRITE_MODE_OFST 0x10 /* offset to add when writing mode */
@@ -78,7 +49,7 @@ public:
unsigned char 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 SetMode(unsigned char mode, unsigned char speed);
void SetMode(unsigned char mode);
private:
void dump();
@@ -90,8 +61,6 @@ private:
void set_color_ch_1(unsigned char red, unsigned char green, unsigned char blue);
void set_mode_ch_0(unsigned char mode);
void set_mode_ch_1(unsigned char mode);
void set_timers_ch_0(unsigned short timer0, unsigned short timer1);
void set_timers_ch_1(unsigned short timer0, unsigned short timer1);
void switch_bank(unsigned char bank);
char device_name[32];
@@ -1,47 +0,0 @@
/*-----------------------------------------*\
| RGBFusionGPUController.cpp |
| |
| Driver for Gigabyte Aorus RGB Fusion GPU |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 2/20/2020 |
\*-----------------------------------------*/
#include "RGBFusionGPUController.h"
RGBFusionGPUController::RGBFusionGPUController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev)
{
this->bus = bus;
this->dev = dev;
}
RGBFusionGPUController::~RGBFusionGPUController()
{
}
std::string RGBFusionGPUController::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(return_string);
}
void RGBFusionGPUController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
{
bus->i2c_smbus_write_byte(dev, RGB_FUSION_GPU_REG_COLOR);
bus->i2c_smbus_write_byte(dev, red);
bus->i2c_smbus_write_byte(dev, green);
bus->i2c_smbus_write_byte(dev, blue);
}
void RGBFusionGPUController::SetMode(unsigned char mode, unsigned char speed)
{
bus->i2c_smbus_write_byte(dev, RGB_FUSION_GPU_REG_MODE);
bus->i2c_smbus_write_byte(dev, mode);
bus->i2c_smbus_write_byte(dev, speed);
bus->i2c_smbus_write_byte(dev, 0x63);
}
@@ -1,54 +0,0 @@
/*-----------------------------------------*\
| RGBFusionGPUController.h |
| |
| Definitions and types for Gigabyte Aorus |
| RGB Fusion GPU lighting controller |
| |
| Adam Honse (CalcProgrammer1) 2/20/2020 |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char rgb_fusion_dev_id;
enum
{
RGB_FUSION_GPU_REG_COLOR = 0x40,
RGB_FUSION_GPU_REG_MODE = 0x88
};
enum
{
RGB_FUSION_GPU_MODE_STATIC = 0x01,
RGB_FUSION_GPU_MODE_BREATHING = 0x02,
RGB_FUSION_GPU_MODE_FLASHING = 0x04,
RGB_FUSION_GPU_MODE_DUAL_FLASHING = 0x08,
RGB_FUSION_GPU_MODE_SPECTRUM_CYCLE = 0x11
};
enum
{
RGB_FUSION_GPU_SPEED_SLOWEST = 0x00,
RGB_FUSION_GPU_SPEED_NORMAL = 0x05,
RGB_FUSION_GPU_SPEED_FASTEST = 0x09
};
class RGBFusionGPUController
{
public:
RGBFusionGPUController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev);
~RGBFusionGPUController();
std::string GetDeviceLocation();
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
void SetMode(unsigned char mode, unsigned char speed);
private:
i2c_smbus_interface* bus;
rgb_fusion_dev_id dev;
};

Some files were not shown because too many files have changed in this diff Show More