Compare commits

..
Author SHA1 Message Date
Adam Honse 8e89d82c24 Check for local server before detecting devices from hardware 2020-06-27 17:32:01 -05:00
2040 changed files with 14249 additions and 482257 deletions
-12
View File
@@ -1,12 +0,0 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: CalcProgrammer1
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
-3
View File
@@ -4,8 +4,5 @@ ui_*
moc_*
qrc_*
OpenRGB
openrgb
Makefile
OpenRGB-x86_64.AppImage
.qmake.stash
.vscode
+20 -473
View File
@@ -4,10 +4,6 @@
# 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/
#-----------------------------------------------------------------------#
# OpenRGB GitLab CI Configuration #
#-----------------------------------------------------------------------#
.shared_windows_runners:
tags:
- shared-windows
@@ -16,429 +12,24 @@
stages:
- build
- test
before_script:
- echo "started by ${GITLAB_USER_NAME}"
#reusable templates
.ccache_init: &ccache_init
before_script:
- export QT_SELECT=qt5
- export APPIMAGE_EXTRACT_AND_RUN=1
#-----------------------------------------------------------------------#
# Linux (AppImage) 32-bit Build Target #
#-----------------------------------------------------------------------#
"Linux 32 AppImage":
<<: *ccache_init
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:buster-32
build_linux:
image: ubuntu:bionic
stage: build
script:
- export $(dpkg-architecture)
- 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:
name: "${CI_PROJECT_NAME}_Linux_32_${CI_COMMIT_SHORT_SHA}"
paths:
- OpenRGB-i386.AppImage
- 60-openrgb.rules
- README.md
expire_in: 30 days
#-----------------------------------------------------------------------#
# Linux (AppImage) 64-bit Build Target #
#-----------------------------------------------------------------------#
"Linux 64 AppImage":
<<: *ccache_init
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:buster-64
stage: build
script:
- export $(dpkg-architecture)
- ./scripts/build-appimage.sh
artifacts:
name: "${CI_PROJECT_NAME}_Linux_64_${CI_COMMIT_SHORT_SHA}"
paths:
- OpenRGB-x86_64.AppImage
- 60-openrgb.rules
- README.md
expire_in: 30 days
expire_in: 1337 years
#-----------------------------------------------------------------------#
# Linux (.deb) 32-bit Build Target #
#-----------------------------------------------------------------------#
"Linux 32 deb":
<<: *ccache_init
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:buster-32
stage: build
script:
- dpkg-architecture -l
- dpkg-buildpackage --target-arch i386 -us -B
- rm -v ../openrgb-dbgsym*.deb
- mv -v ../openrgb*.deb ./
artifacts:
name: "${CI_PROJECT_NAME}_Linux_32_deb_${CI_COMMIT_SHORT_SHA}"
paths:
- openrgb*.deb
exclude:
- openrgb-dbgsym*.deb
expire_in: 30 days
#-----------------------------------------------------------------------#
# Linux (.deb) 64-bit Build Target #
#-----------------------------------------------------------------------#
"Linux 64 deb":
<<: *ccache_init
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:buster-64
stage: build
script:
- dpkg-architecture -l
- dpkg-buildpackage -us -B
- rm -v ../openrgb-dbgsym*.deb
- mv -v ../openrgb*.deb ./
artifacts:
name: "${CI_PROJECT_NAME}_Linux_64_deb_${CI_COMMIT_SHORT_SHA}"
paths:
- openrgb*.deb
exclude:
- openrgb-dbgsym*.deb
expire_in: 30 days
#-----------------------------------------------------------------------#
# Linux (.rpm) 64-bit Build Target #
#-----------------------------------------------------------------------#
"Linux 64 rpm":
image: fedora:34
stage: build
script:
- dnf install rpmdevtools dnf-plugins-core -y
- rpmdev-setuptree
- ls /root/
- cp fedora/OpenRGB.spec /root/rpmbuild/SPECS
- cp ../OpenRGB /root/rpmbuild/SOURCES/ -r
- cd /root/rpmbuild/SOURCES
- tar -cf OpenRGB.tar.gz OpenRGB/
- cd ..
- dnf builddep SPECS/OpenRGB.spec -y
- rpmbuild -ba SPECS/OpenRGB.spec
- cd RPMS/x86_64/
- mv openrgb*.rpm ${CI_PROJECT_DIR}/
- cd ${CI_PROJECT_DIR}
artifacts:
name: "${CI_PROJECT_NAME}_Linux_64_rpm_${CI_COMMIT_SHORT_SHA}"
paths:
- openrgb*.rpm
expire_in: 30 days
#-----------------------------------------------------------------------#
# Linux (.deb) Debian Bullseye 32-bit Build Target #
#-----------------------------------------------------------------------#
"Linux 32 deb Bullseye":
<<: *ccache_init
image: i386/debian:bullseye
stage: build
script:
- apt update
- apt install -y build-essential qtcreator qtbase5-dev libusb-1.0-0-dev libhidapi-dev libmbedtls-dev pkgconf wget git file debhelper
- dpkg-architecture -l
- dpkg-buildpackage --target-arch i386 -us -B
- rm -v ../openrgb-dbgsym*.deb
- mv -v ../openrgb*.deb ./
artifacts:
name: "${CI_PROJECT_NAME}_Linux_32_deb_${CI_COMMIT_SHORT_SHA}"
paths:
- openrgb*.deb
exclude:
- openrgb-dbgsym*.deb
expire_in: 30 days
#-----------------------------------------------------------------------#
# Linux (.deb) Debian Bullseye 64-bit Build Target #
#-----------------------------------------------------------------------#
"Linux 64 deb Bullseye":
<<: *ccache_init
image: debian:bullseye
stage: build
script:
- apt update
- apt install -y build-essential qtcreator qtbase5-dev libusb-1.0-0-dev libhidapi-dev libmbedtls-dev pkgconf wget git file debhelper
- dpkg-architecture -l
- dpkg-buildpackage -us -B
- rm -v ../openrgb-dbgsym*.deb
- mv -v ../openrgb*.deb ./
artifacts:
name: "${CI_PROJECT_NAME}_Linux_64_deb_${CI_COMMIT_SHORT_SHA}"
paths:
- openrgb*.deb
exclude:
- openrgb-dbgsym*.deb
expire_in: 30 days
#-----------------------------------------------------------------------#
# Debian 32 Buster test #
#-----------------------------------------------------------------------#
"Debian 32 Buster":
image: i386/debian:buster
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 32 deb"
needs:
- "Linux 32 deb"
#-----------------------------------------------------------------------#
# Debian 32 Bullseye test #
#-----------------------------------------------------------------------#
"Debian 32 Bullseye":
image: i386/debian:bullseye
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 32 deb"
needs:
- "Linux 32 deb"
# #-----------------------------------------------------------------------#
# # Ubuntu 32 18.04LTS test #
# #-----------------------------------------------------------------------#
# "Ubuntu 32 18.04LTS":
# image: i386/ubuntu:bionic
# stage: test
# script:
# - apt update
# - DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
# - openrgb --version
# - openrgb -l
# - apt remove -y openrgb
# dependencies:
# - "Linux 32 deb"
# needs:
# - "Linux 32 deb"
# #-----------------------------------------------------------------------#
# # Mint 32 19.3 test #
# #-----------------------------------------------------------------------#
# "Mint 32 20.1":
# image: linuxmintd/mint19.3-i386
# stage: test
# script:
# - apt update
# - DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
# - openrgb --version
# - openrgb -l
# - apt remove -y openrgb
# dependencies:
# - "Linux 32 deb"
# needs:
# - "Linux 32 deb"
#-----------------------------------------------------------------------#
# Debian 64 Buster test #
#-----------------------------------------------------------------------#
"Debian 64 Buster":
image: debian:buster
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Debian 64 Bullseye test #
#-----------------------------------------------------------------------#
"Debian 64 Bullseye":
image: debian:bullseye
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Fedora 64 v34 test #
#-----------------------------------------------------------------------#
"Fedora 64 v34":
image: fedora:34
stage: test
script:
- yum -y localinstall ./openrgb*64.rpm
- openrgb --version
- openrgb -l
- yum -y remove openrgb
dependencies:
- "Linux 64 rpm"
needs:
- "Linux 64 rpm"
# #-----------------------------------------------------------------------#
# # Ubuntu 64 18.04LTS test #
# #-----------------------------------------------------------------------#
# "Ubuntu 64 18.04LTS":
# image: ubuntu:bionic
# stage: test
# script:
# - apt update
# - DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
# - openrgb --version
# - openrgb -l
# - apt remove -y openrgb
# dependencies:
# - "Linux 64 deb"
# needs:
# - "Linux 64 deb"
#-----------------------------------------------------------------------#
# Ubuntu 64 20.04LTS test #
#-----------------------------------------------------------------------#
"Ubuntu 64 20.04LTS":
image: ubuntu:focal
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Ubuntu 64 20.10 test #
#-----------------------------------------------------------------------#
"Ubuntu 64 20.10":
image: ubuntu:groovy
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Mint 64 20.1 test #
#-----------------------------------------------------------------------#
"Mint 64 20.1":
image: linuxmintd/mint20.1-amd64
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Windows (32-bit) Build Target #
#-----------------------------------------------------------------------#
"Windows 32":
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 x86 & 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://qt-mirror.dannhauer.de/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win32_msvc2019/5.15.0-0-202005150700qtbase-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86.7z'
- curl.exe -LJ -o qt-tools.7z 'https://qt-mirror.dannhauer.de/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win32_msvc2019/5.15.0-0-202005150700qttools-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86.7z'
- curl.exe -LJ -o qt-jom.zip 'https://qt-mirror.dannhauer.de/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\msvc2019\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\msvc2019\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\msvc2019\bin\windeployqt --no-angle --no-translations --no-opengl-sw --no-system-d3d-compiler --no-compiler-runtime --no-webkit2 .\release\
- _fold_final_
- _fold_start_ 'Moving results for upload'
- mv release ../'OpenRGB Windows 32-bit'
- _fold_final_
# cache:
# key: same-key
# paths:
# - C:\vcpkg\installed\
artifacts:
name: "${CI_PROJECT_NAME}_Windows_32_${CI_COMMIT_SHORT_SHA}"
paths:
- 'OpenRGB Windows 32-bit'
expire_in: 30 days
#-----------------------------------------------------------------------#
# Windows (64-bit) Build Target #
#-----------------------------------------------------------------------#
"Windows 64":
build_windows:
extends:
- .shared_windows_runners
stage: build
@@ -460,9 +51,9 @@ before_script:
- mkdir _qt
- mkdir _qt_download
- Push-Location _qt_download
- curl.exe -LJ -o qt-base.7z 'https://qt-mirror.dannhauer.de/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win64_msvc2019_64/5.15.0-0-202005150700qtbase-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86_64.7z'
- curl.exe -LJ -o qt-tools.7z 'https://qt-mirror.dannhauer.de/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win64_msvc2019_64/5.15.0-0-202005150700qttools-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86_64.7z'
- curl.exe -LJ -o qt-jom.zip 'https://qt-mirror.dannhauer.de/official_releases/jom/jom.zip'
- 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'
@@ -472,7 +63,7 @@ before_script:
- _fold_final_
- _fold_start_ 'turn the qt install from enterprise to foss; remove the licensing checks'
- ${qconfig-pri-folder} = '..\_qt\5.15.0\msvc2019_64\mkspecs\qconfig.pri'
- ${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
@@ -480,7 +71,7 @@ before_script:
- _fold_start_ 'run qmake and generate the msvc nmake makefile'
- mkdir _build; cd _build
- ..\_qt\5.15.0\msvc2019_64\bin\qmake ..\OpenRGB.pro
- ..\_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'
@@ -488,65 +79,21 @@ before_script:
- _fold_final_
- _fold_start_ 'run windeployqt to automatically copy the needed dll files'
- ..\_qt\5.15.0\msvc2019_64\bin\windeployqt --no-angle --no-translations --no-opengl-sw --no-system-d3d-compiler --no-compiler-runtime --no-webkit2 .\release\
- ..\_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_ 'Moving results for upload'
- mv release ../'OpenRGB Windows 64-bit'
- _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:
name: "${CI_PROJECT_NAME}_Windows_64_${CI_COMMIT_SHORT_SHA}"
paths:
- 'OpenRGB Windows 64-bit'
expire_in: 30 days
#-----------------------------------------------------------------------#
# MacOS Build Target #
#-----------------------------------------------------------------------#
"MacOS ARM64":
tags:
- macos
stage: build
script:
- eval $(/opt/homebrew/bin/brew shellenv)
- qmake OpenRGB.pro
- make -j16
- macdeployqt OpenRGB.app -codesign=OpenRGB
artifacts:
name: "${CI_PROJECT_NAME}_MacOS_ARM64_${CI_COMMIT_SHORT_SHA}"
paths:
- OpenRGB.app
expire_in: 30 days
rules:
- if: '$CI_PROJECT_PATH == "CalcProgrammer1/OpenRGB"'
when: on_success
- if: '$BUILD_MACOS =~ /.+/'
when: on_success
"MacOS Intel":
tags:
- macos
stage: build
script:
- eval $(/usr/local/bin/brew shellenv)
- arch -x86_64 /usr/local/bin/qmake OpenRGB.pro
- arch -x86_64 make -j16
- arch -x86_64 macdeployqt OpenRGB.app -codesign=OpenRGB
artifacts:
name: "${CI_PROJECT_NAME}_MacOS_Intel_${CI_COMMIT_SHORT_SHA}"
paths:
- OpenRGB.app
expire_in: 30 days
rules:
- if: '$CI_PROJECT_PATH == "CalcProgrammer1/OpenRGB"'
when: on_success
- if: '$BUILD_MACOS =~ /.+/'
when: on_success
- _build/*.7z
expire_in: 1337 years
-19
View File
@@ -1,19 +0,0 @@
<!--
Found a bug? Something isn't working as expected?
To help us keep track of the requests please start the title with [Bug Report]
-->
### Description of Bug
<!--
Please describe the bug.
Explain any steps taken to reproduce the bug
and what you expect the correct behavior to be.
-->
### Hardware Configuration
<!--
Please list the RGB hardware that you are using with OpenRGB.
If your bug does not relate to any one particular device or device type,
or if the bug is in a part of the code not directly interacting with hardware, this is optional.
-->
@@ -1,11 +0,0 @@
<!--
Have something you would like to see added to OpenRGB? Let us know here
To help us keep track of the requests please start the title with [Feature Request]
-->
### Feature Request
<!--
Please explain the new feature you would like to see added in detail.
Explain how you think it should work and provide any mock-ups,
code snippets, etc. that you think will help explain the feature.
-->
-86
View File
@@ -1,86 +0,0 @@
<!--
When naming the support request please title the request as
`[New Device] <Name of new device>`
Please open one issue per device you would like to add
-->
### Name of device:
<!--
Please put the name of the product, including manufacturer, beneath this line
-->
### Link to manufacturer's product page:
<!--
Please add a link to the manufacturer's product page beneath this line
-->
### Please select what type of device/interface the device uses:
<!-- Please select from one of the following
This determines how the device connects to the PC -->
~"DeviceType::IDK" <!-- I Don't know -->
~"DeviceType::USB" <!-- The device connects to an internal header or external usb port -->
~"DeviceType::GPU::AMD" <!-- The device is an AMD GPU -->
~"DeviceType::GPU::NVidia" <!-- The device is a NVidia GPU -->
~"DeviceType::SMBus" <!-- The device is connected to the SMBus eg. RAM -->
~"DeviceType::WMI" <!-- The device is controlled thru Windows Management Instrumentation -->
<!-- Please delete any lines that are not relevant -->
### ID information:
<!--
For PCI (GPU) devices we will need the Vendor ID, Device ID, Sub-Vendor ID and Sub-Device IDs
To get the Device ID formation for a GPU on Windows run the following command in Powershell:
wmic path Win32_VideoController get name,PNPDeviceID
Linux this can be found using the terminal:
lspci -d 1002: -nnvm | head -6 | tail -n 4 && lspci -d 10DE: -nnvm | head -6 | tail -n 4
-->
<!--
For USB devices we will need the USB VID and PID
Windows Powershell:
gwmi Win32_USBControllerDevice |%{[wmi]($_.Dependent)} | Sort Manufacturer,Description,DeviceID | Ft -GroupBy Manufacturer Description,Service,DeviceID
Linux Terminal:
lsusb
-->
### Please attach screenshots of the device's official control application here:
<!--
Screenshots of the official control software should show lists of supported modes, color selection, and zone/LED selection capabilities of the device's official software.
-->
### Please attach device captures here:
<!-- If you have code examples from other projects please link them here or alternatively
for information on how to capture device packets please refer to the wiki article
https://gitlab.com/Dr_No/OpenRGB/-/wikis/OpenRGB-doesn%27t-have-my-device
-->
<!-- For admin purposes: Please leave this section as is -->
/label ~"Issue Type - New Device"
/label ~"NewDevice::Step0 - Unconfirmed"
# Checklist for Step2
- [ ] Name of device
- [ ] A link to the vendors product page has been included
- [ ] The transport bus has been identified and the appropriate label added to the issue.
- [ ] The device ID's have been included for [USB](https://gitlab.com/Dr_No/OpenRGB/-/wikis/USB-Vendor-Identification-and-Product-Identification) or PCI
- [ ] Screenshots of the OEM Application are included
- [ ] There is either, appropriate code examples linked or suitable device captures attached
<!-- For admin purposes: Please leave this section as is -->
+1 -529
View File
@@ -9,11 +9,6 @@
#---------------------------------------------------------------#
KERNEL=="i2c-[0-99]*", TAG+="uaccess"
#---------------------------------------------------------------#
# Super I/O Access #
#---------------------------------------------------------------#
KERNEL=="port", TAG+="uaccess"
#---------------------------------------------------------------#
# User hidraw Access #
#---------------------------------------------------------------#
@@ -24,20 +19,6 @@ KERNEL=="hidraw*", SUBSYSTEM=="hidraw", TAG+="uaccess"
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0051", TAG+="uaccess"
#---------------------------------------------------------------#
# Aorus Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1044", ATTR{idProduct}=="7a42", TAG+="uaccess"
#---------------------------------------------------------------#
# ASRock Devices #
# #
# ASRock Polychrome USB #
# ASRock Deskmini Addressable LED Strip #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="26CE", ATTR{idProduct}=="01A2", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="26CE", ATTR{idProduct}=="01A6", TAG+="uaccess"
#---------------------------------------------------------------#
# ASUS Aura Core Devices #
#---------------------------------------------------------------#
@@ -53,86 +34,14 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1872", TAG+="uacces
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"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18a5", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1939", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18af", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18dd", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1845", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1875", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1877", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18cd", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18cf", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18e5", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18e3", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1958", TAG+="uaccess"
#---------------------------------------------------------------#
# ASUS TUF Laptops (faustus) #
#---------------------------------------------------------------#
ACTION=="add", SUBSYSTEM=="platform", KERNEL=="faustus", RUN+="/bin/chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_blue"
ACTION=="add", SUBSYSTEM=="platform", KERNEL=="faustus", RUN+="/bin/chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_flags"
ACTION=="add", SUBSYSTEM=="platform", KERNEL=="faustus", RUN+="/bin/chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_green"
ACTION=="add", SUBSYSTEM=="platform", KERNEL=="faustus", RUN+="/bin/chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_mode"
ACTION=="add", SUBSYSTEM=="platform", KERNEL=="faustus", RUN+="/bin/chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_red"
ACTION=="add", SUBSYSTEM=="platform", KERNEL=="faustus", RUN+="/bin/chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_set"
ACTION=="add", SUBSYSTEM=="platform", KERNEL=="faustus", RUN+="/bin/chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_speed"
#---------------------------------------------------------------#
# Cooler Master Peripheral Devices #
# #
# Mousemats: #
# Cooler Master MP750 #
# Controllers: #
# ARGB Device #
# Small ARGB Device #
# Graphics Cards: #
# Radeon RX6000 Series Reference Cards #
# Keyboards: #
# Masterkeys Pro L #
# Masterkeys Pro L White #
# Masterkeys Pro S #
# Masterkeys MK750 #
# Masterkeys SK630 #
# Masterkeys SK650 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0109", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0105", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="1011", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="1000", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="014d", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0047", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="003c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0067", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0089", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="008d", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Hydro Series Devices #
# #
# Corsair H100i Pro RGB #
# Corsair H115i Pro RGB #
# Corsair H150i Pro RGB #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c15", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c13", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c12", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Hydro Platinum Series Devices #
# #
# Corsair H100i Platinum RGB #
# Corsair H100i Platinum SE RGB #
# Corsair H115i Platinum RGB #
# Corsair H100i Pro XT RGB #
# Corsair H115i Pro XT RGB #
# Corsair H150i Pro XT RGB #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c18", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c19", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c17", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c20", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c21", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c22", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Lighting Node Devices #
@@ -143,7 +52,6 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c22", TAG+="uacces
# Corsair LS100 #
# Corsair 1000D Obsidian #
# Corsair Spec Omega RGB #
# Corsair LT100 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c1a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c0b", TAG+="uaccess"
@@ -151,7 +59,6 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c10", TAG+="uacces
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"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c23", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Peripheral Devices #
@@ -176,12 +83,6 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c23", TAG+="uacces
# Mice: #
# Corsair M65 Pro #
# Corsair M65 RGB Elite #
# Corsair Glaive RGB #
# Corsair Glaive RGB Pro #
# Corsair Harpoon RGB #
# Corsair Harpoon RGB Pro #
# Corsair Scimitar Pro RGB #
# Corsair Sabre RGB #
# #
# Mousemats: #
# Corsair MM800 RGB Polaris #
@@ -205,402 +106,51 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2d", TAG+="uacces
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}=="1b34", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b74", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b75", 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}=="1b3e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3b", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0a34", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Wireless Devices #
# #
# Keyboards: #
# Corsair K57 RGB Wired #
# Corsair K57 RGB Wireless #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b6e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b62", TAG+="uaccess"
#---------------------------------------------------------------#
# Creative Devices #
# #
# Devices: #
# Creative SoundblasterX G6 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="041e", ATTR{idProduct}=="3256", TAG+="uaccess"
#---------------------------------------------------------------#
# Ducky Keyboard Devices #
# #
# Keyboards: #
# Ducky Shine 7 One 2 RGB #
# Ducky One 2 RGB TKL #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="0348", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="0356", TAG+="uaccess"
#---------------------------------------------------------------#
# EK Controller Devices #
# #
# Controllers: #
# EK Loop Connect #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="5750", TAG+="uaccess"
#---------------------------------------------------------------#
# Holtek Devices #
# #
# Mice: #
# Holtek A070 #
# Mousemats: #
# Holtek A1FA #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="a070", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="a1fa", TAG+="uaccess"
#---------------------------------------------------------------#
# HyperX Peripheral Devices #
# #
# Keyboards: #
# HyperX Alloy Elite #
# HyperX Alloy Elite 2 #
# HyperX Alloy FPS RGB #
# HyperX Alloy Origins #
# HyperX Alloy Origins Core #
# #
# Mice: #
# HyperX Pulsefire Surge #
# HyperX Pulsefire FPS Pro #
# HyperX Pulsefire Dart Wireless #
# HyperX Pulsefire Dart Wired #
# #
# Mousemats: #
# HyperX Fury Ultra #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16be", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="1711", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16dc", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16e5", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16e6", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16d3", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16d7", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16e1", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16e2", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="1705", TAG+="uaccess"
#---------------------------------------------------------------#
# Lian Li Uni Hub #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0cf2", ATTR{idProduct}=="7750", TAG+="uaccess"
#---------------------------------------------------------------#
# Logitech Peripheral Devices #
# #
# Keyboards: #
# Logitech G213 #
# Logitech G512 #
# Logitech G512 RGB #
# Logitech G610 #1 #
# Logitech G610 #2 #
# Logitech G810 #1 #
# Logitech G810 #2 #
# Logitech G813 #
# Logitech G815 #
# #
# Mice: #
# Logitech G203 Prodigy #
# Logitech G203 Lightsync #
# Logitech G303 #
# Logitech G403 Prodigy #
# Logitech G403 Hero #
# Logitech G502 Proteus Spectrum #
# Logitech G502 Hero #
# Logitech G502 Wireless #
# Logitech G703 Wireless #
# Logitech G900 Wireless #
# Logitech G903 Wireless #
# Logitech G Lightspeed Wireless Gaming Mouse #
# Logitech G Pro Wireless Gaming Mouse (Wired) #
# Logitech G Pro Hero Gaming Mouse (Wired) #
# #
# Mousemats: #
# Logitech G Powerplay Mousepad with Lightspeed #
# #
# Speakers: #
# Logitech G560 #
# #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c336", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c342", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c33c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c333", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c338", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c331", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c337", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c232", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c33f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c084", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c092", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c083", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c082", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="405d", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c332", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08b", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08d", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="407f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c087", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="4070", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c081", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="4053", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c086", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="4067", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c539", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c085", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c088", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="4079", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c53a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="0a78", TAG+="uaccess"
#---------------------------------------------------------------#
# Metadot Das Keyboard 4Q + 5Q #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="24f0", ATTR{idProduct}=="2037", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="24f0", ATTR{idProduct}=="2020", TAG+="uaccess"
#---------------------------------------------------------------#
# MSI Mysticlight #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="3EA4", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="4459", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B10", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B12", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B17", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B85", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B93", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B94", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B96", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C34", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C35", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C36", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C37", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C42", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C56", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C59", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C60", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C67", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C70", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C71", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C73", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C75", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C76", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C77", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C79", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C80", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C81", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C82", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C83", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C84", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C85", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C86", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C87", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C88", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C89", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C90", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C91", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C92", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C94", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C95", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C96", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C98", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C99", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7D09", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="905D", TAG+="uaccess"
#---------------------------------------------------------------#
# MSI/SteelSeries 3-Zone Laptop Keyboard #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1770", ATTR{idProduct}=="FF00", TAG+="uaccess"
#---------------------------------------------------------------#
# NZXT Hue+ #
#---------------------------------------------------------------#
KERNEL=="ttyACM[0-9]*", ATTR{idVendor}=="04D8", ATTR{idProduct}=="00DF", TAG+="uaccess"
#---------------------------------------------------------------#
# NZXT Hue 2 Devices #
# #
# NZXT Hue 2 #
# NZXT Hue 2 Ambient #
# NZXT Motherboard #
# NZXT Smart Device V2 #
# NZXT Kraken X3 #
# NZXT RGB Fan Controller #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2001", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2002", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2005", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2006", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2007", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2009", TAG+="uaccess"
#---------------------------------------------------------------#
# NZXT Kraken #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="170e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="1715", TAG+="uaccess"
#---------------------------------------------------------------#
# Razer Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0241", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0203", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0209", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0221", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0228", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0237", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0235", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0211", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0216", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="021A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="020F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0224", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0233", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="023B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0240", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="023A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0246", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0245", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="024D", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0253", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0255", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="026F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0210", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0225", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="022F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0234", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="024C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0205", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0220", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="022D", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0232", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0239", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="024A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0252", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0259", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="022A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="023F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="025E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0204", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0226", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0227", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0243", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0207", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="021E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="025D", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0208", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="022B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0020", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="005E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="006A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="006B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0042", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="005B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0062", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0064", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0065", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0083", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0038", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="004F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0037", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0016", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0054", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0043", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="005C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="006E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0071", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="008C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0084", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="007C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="007D", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="004C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="002F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0060", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0059", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="005A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0070", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="006F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0024", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0025", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0044", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0045", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0073", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0072", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="006C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0046", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="002E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0040", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0053", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="003F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="003E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0041", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0036", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0050", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0067", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0013", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0039", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0048", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0032", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0034", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="008A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0078", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="007A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="007B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0506", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0501", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F19", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0504", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0527", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0510", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F03", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F08", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F20", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F26", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F1F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F09", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F07", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F0E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0215", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0068", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0C00", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0C04", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0C02", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0C01", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F1D", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0517", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0518", TAG+="uaccess"
#---------------------------------------------------------------#
# Roccat Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e7d", ATTR{idProduct}=="2e2c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e7d", ATTR{idProduct}=="2e27", TAG+="uaccess"
#---------------------------------------------------------------#
# Redragon Peripheral Devices #
@@ -622,30 +172,11 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="652f", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc30", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc39", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc4d", TAG+="uaccess"
#---------------------------------------------------------------#
# Gigabyte/Aorus RGB Fusion 2 USB #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="048d", ATTR{idProduct}=="8297", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="048d", ATTR{idProduct}=="5702", TAG+="uaccess"
#---------------------------------------------------------------#
# Sinowealth USB #
# Glorious Model O / O- #
# Glorious Model D / D- #
# Everest GT-100 RGB #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="258a", ATTR{idProduct}=="0036", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="258a", ATTR{idProduct}=="0033", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="258a", ATTR{idProduct}=="0029", TAG+="uaccess"
#---------------------------------------------------------------#
# Sony Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="054c", ATTR{idProduct}=="05c4", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="054c", ATTR{idProduct}=="09cc", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="054c", ATTR{idProduct}=="0ba0", TAG+="uaccess"
#---------------------------------------------------------------#
# SteelSeries Peripheral Devices #
@@ -662,83 +193,24 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="054c", ATTR{idProduct}=="0ba0", TAG+="uacces
# SteelSeries Rival 300 CS:GO Hyperbeast Edition #
# SteelSeries Rival 300 Dota 2 Edition #
# SteelSeries Rival 300 HP Omen Edition #
# SteelSeries Rival 300 Blackops Edition #
# SteelSeries Rival 310 #
# SteelSeries Rival 310 CS:GO Howl Edition #
# SteelSeries Rival 310 PubG Edition #
# SteelSeries Rival Sensei Ten #
# SteelSeries Rival Sensei Ten CS:GO Neon Rider #
# SteelSeries Rival Sensei 310 #
# Headsets: #
# SteelSeries Siberia 350 #
# Keyboards: #
# SteelSeries Apex 5 #
# SteelSeries Apex 7 #
# SteelSeries Apex 7 TKL #
# SteelSeries Apex Pro #
# SteelSeries Apex Pro TKL #
# SteelSeries Apex M750 #
# SteelSeries Apex OG #
# SteelSeries Apex 350 #
# Mousemats: #
# SteelSeries QCK Prism Cloth #
#---------------------------------------------------------------#
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}=="1710", 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}=="1720", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="171e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1736", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1832", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1834", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1722", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1229", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="161c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1612", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1618", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1610", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1614", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="0616", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1202", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1206", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="150d", TAG+="uaccess"
#---------------------------------------------------------------#
# Tecknet Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc05", TAG+="uaccess"
#---------------------------------------------------------------#
# Thermaltake Poseidon Z RGB Keyboard #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="3006", TAG+="uaccess"
#---------------------------------------------------------------#
# Thermaltake Riing Controllers #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="1FA[5-9]", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="1FA[A-F]", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="1FB[0-5]", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="226[0-3]", TAG+="uaccess"
#---------------------------------------------------------------#
# Wooting Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="03eb", ATTR{idProduct}=="ff01", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="03eb", ATTR{idProduct}=="ff02", TAG+="uaccess"
#---------------------------------------------------------------#
# Zalman ZSync Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1c57", ATTR{idProduct}=="7ed0", TAG+="uaccess"
@@ -12,10 +12,9 @@
#include <stdio.h>
#include <stdlib.h>
AMDWraithPrismController::AMDWraithPrismController(hid_device* dev_handle, const char* path)
AMDWraithPrismController::AMDWraithPrismController(hid_device* dev_handle)
{
dev = dev_handle;
location = path;
dev = dev_handle;
strcpy(device_name, "AMD Wraith Prism");
@@ -36,12 +35,7 @@ AMDWraithPrismController::AMDWraithPrismController(hid_device* dev_handle, const
AMDWraithPrismController::~AMDWraithPrismController()
{
hid_close(dev);
}
std::string AMDWraithPrismController::GetLocationString()
{
return("HID: " + location);
}
char* AMDWraithPrismController::GetDeviceName()
@@ -49,29 +43,12 @@ char* AMDWraithPrismController::GetDeviceName()
return device_name;
}
std::string AMDWraithPrismController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
std::string AMDWraithPrismController::GetEffectChannelString(unsigned char channel)
{
std::string ret_string = "";
unsigned char usb_buf[] =
{
0x00,
0x40, 0x21, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
@@ -90,9 +67,9 @@ std::string AMDWraithPrismController::GetEffectChannelString(unsigned char chann
0x00, 0x00, 0x00, 0x00,
};
usb_buf[0x03] = channel;
usb_buf[0x02] = channel;
hid_write(dev, usb_buf, 65);
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
ret_string.append((char *)&usb_buf[0x08]);
@@ -106,7 +83,6 @@ std::string AMDWraithPrismController::GetFirmwareVersionString()
unsigned char usb_buf[] =
{
0x00,
0x12, 0x20, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
@@ -127,7 +103,7 @@ std::string AMDWraithPrismController::GetFirmwareVersionString()
unsigned char fw_buf[16] = {0x00};
hid_write(dev, usb_buf, 65);
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
for(int char_idx = 0; char_idx < 16; char_idx+=2)
@@ -230,7 +206,6 @@ void AMDWraithPrismController::SendEnableCommand()
{
unsigned char usb_buf[] =
{
0x00,
0x41, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
@@ -249,7 +224,7 @@ void AMDWraithPrismController::SendEnableCommand()
0x00, 0x00, 0x00, 0x00,
};
hid_write(dev, usb_buf, 65);
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
}
@@ -257,7 +232,6 @@ void AMDWraithPrismController::SendApplyCommand()
{
unsigned char usb_buf[] =
{
0x00,
0x51, 0x28, 0x00, 0x00,
0xE0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
@@ -276,7 +250,7 @@ void AMDWraithPrismController::SendApplyCommand()
0x00, 0x00, 0x00, 0x00,
};
hid_write(dev, usb_buf, 65);
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
}
@@ -295,7 +269,6 @@ void AMDWraithPrismController::SendEffectChannelUpdate
{
unsigned char usb_buf[] =
{
0x00,
0x51, 0x2C, 0x01, 0x00,
0x05, 0xFF, 0x00, 0x01,
0xFF, 0xFF, 0x00, 0xFF,
@@ -314,18 +287,18 @@ void AMDWraithPrismController::SendEffectChannelUpdate
0xFF, 0xFF, 0xFF, 0xFF
};
usb_buf[0x05] = effect_channel;
usb_buf[0x06] = speed;
usb_buf[0x07] = (direction ? 0x01 : 0x00) | (random_color ? 0x80 : 0x00);
usb_buf[0x08] = mode;
usb_buf[0x04] = effect_channel;
usb_buf[0x05] = speed;
usb_buf[0x06] = (direction ? 0x01 : 0x00) | (random_color ? 0x80 : 0x00);
usb_buf[0x07] = mode;
usb_buf[0x0A] = brightness;
usb_buf[0x09] = brightness;
usb_buf[0x0B] = red;
usb_buf[0x0C] = green;
usb_buf[0x0D] = blue;
usb_buf[0x0A] = red;
usb_buf[0x0B] = green;
usb_buf[0x0C] = blue;
hid_write(dev, usb_buf, 65);
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
}
@@ -333,7 +306,6 @@ void AMDWraithPrismController::SendChannelRemap(unsigned char ring_channel, unsi
{
unsigned char usb_buf[] =
{
0x00,
0x51, 0xA0, 0x01, 0x00,
0x00, 0x03, 0x00, 0x00,
0x05, 0x06, 0x07, 0x07,
@@ -352,14 +324,14 @@ void AMDWraithPrismController::SendChannelRemap(unsigned char ring_channel, unsi
0x00, 0x00, 0x00, 0x00,
};
usb_buf[0x09] = logo_channel;
usb_buf[0x0A] = fan_channel;
usb_buf[0x08] = logo_channel;
usb_buf[0x09] = fan_channel;
for(int led = 0x0B; led <= 0x19; led++)
for(int led = 0x0A; led <= 0x18; led++)
{
usb_buf[led] = ring_channel;
}
hid_write(dev, usb_buf, 65);
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
}
@@ -109,15 +109,13 @@ enum
class AMDWraithPrismController
{
public:
AMDWraithPrismController(hid_device* dev_handle, const char* path);
AMDWraithPrismController(hid_device* dev_handle);
~AMDWraithPrismController();
char* GetDeviceName();
std::string GetEffectChannelString(unsigned char channel);
std::string GetFirmwareVersionString();
std::string GetLocationString();
std::string GetSerialString();
void SetRingEffectChannel(unsigned char channel);
@@ -133,7 +131,6 @@ public:
private:
char device_name[32];
hid_device* dev;
std::string location;
unsigned char current_fan_mode;
unsigned char current_fan_speed;
@@ -1,9 +1,8 @@
#include "Detector.h"
#include "AMDWraithPrismController.h"
#include "RGBController.h"
#include "RGBController_AMDWraithPrism.h"
#include <vector>
#include <hidapi/hidapi.h>
#define AMD_WRAITH_PRISM_VID 0x2516
#define AMD_WRAITH_PRISM_PID 0x0051
@@ -15,16 +14,37 @@
* *
\******************************************************************************************/
void DetectAMDWraithPrismControllers(hid_device_info* info, const std::string&)
void DetectAMDWraithPrismControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device* dev = hid_open_path(info->path);
hid_device_info* info;
hid_device* dev = NULL;
hid_init();
info = hid_enumerate(AMD_WRAITH_PRISM_VID, AMD_WRAITH_PRISM_PID);
//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;
}
}
if( dev )
{
AMDWraithPrismController* controller = new AMDWraithPrismController(dev, info->path);
AMDWraithPrismController* controller = new AMDWraithPrismController(dev);
RGBController_AMDWraithPrism* rgb_controller = new RGBController_AMDWraithPrism(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
rgb_controllers.push_back(rgb_controller);
}
}
REGISTER_HID_DETECTOR_IP("AMD Wraith Prism", DetectAMDWraithPrismControllers, AMD_WRAITH_PRISM_VID, AMD_WRAITH_PRISM_PID, 1, 0xFF00);
@@ -1,342 +0,0 @@
/*-----------------------------------------*\
| ASRockPolychromeSMBusController.cpp |
| |
| Driver for for ASRock ASR LED and |
| Polychrome RGB lighting controller |
| |
| Adam Honse (CalcProgrammer1) 12/14/2019 |
\*-----------------------------------------*/
#include "ASRockPolychromeSMBusController.h"
#include <cstring>
#include "dependencies/dmiinfo.h"
using namespace std::chrono_literals;
PolychromeController::PolychromeController(i2c_smbus_interface* bus, polychrome_dev_id dev)
{
this->bus = bus;
this->dev = dev;
DMIInfo dmi;
unsigned short fw_version = ReadFirmwareVersion();
unsigned char major_version = fw_version >> 8;
/*-----------------------------------------------------*\
| 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 |
\*-----------------------------------------------------*/
switch(major_version)
{
case ASROCK_TYPE_ASRLED:
device_name = "ASRock " + dmi.getMainboard();
asrock_type = ASROCK_TYPE_ASRLED;
memset(zone_led_count, 0, sizeof(zone_led_count));
break;
case ASROCK_TYPE_POLYCHROME_V1:
device_name = "ASRock " + dmi.getMainboard();
asrock_type = ASROCK_TYPE_POLYCHROME_V1;
ReadLEDConfiguration();
break;
case ASROCK_TYPE_POLYCHROME_V2:
device_name = "ASRock " + dmi.getMainboard();
asrock_type = ASROCK_TYPE_POLYCHROME_V2;
ReadLEDConfiguration();
break;
default:
asrock_type = ASROCK_TYPE_UNKNOWN;
break;
}
}
PolychromeController::~PolychromeController()
{
}
unsigned int PolychromeController::GetASRockType()
{
return(asrock_type);
}
std::string PolychromeController::GetDeviceLocation()
{
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
return_string.append(addr);
return("I2C: " + return_string);
}
std::string PolychromeController::GetDeviceName()
{
return(device_name);
}
std::string PolychromeController::GetFirmwareVersion()
{
unsigned short fw_version = ReadFirmwareVersion();
unsigned char major_version = fw_version >> 8;
unsigned char minor_version = fw_version & 0xFF;
return(std::to_string(major_version) + "." + std::to_string(minor_version));
}
unsigned short PolychromeController::ReadFirmwareVersion()
{
// The firmware register holds two bytes, so the first read should return 2
// If not, report invalid firmware revision FFFF
if (bus->i2c_smbus_read_byte_data(dev, ASROCK_REG_FIRMWARE_VER) == 0x02)
{
std::this_thread::sleep_for(1ms);
unsigned char major = bus->i2c_smbus_read_byte(dev);
std::this_thread::sleep_for(1ms);
unsigned char minor = bus->i2c_smbus_read_byte(dev);
return((major << 8) | minor);
}
else
{
return(0xFFFF);
}
}
void PolychromeController::ReadLEDConfiguration()
{
/*---------------------------------------------------------------------------------*\
| The LED configuration register holds 6 bytes, so the first read should return 6 |
| If not, set all zone sizes to zero |
\*---------------------------------------------------------------------------------*/
if (bus->i2c_smbus_read_byte_data(dev, POLYCHROME_REG_LED_CONFIG) == 0x06)
{
std::this_thread::sleep_for(1ms);
zone_led_count[POLYCHROME_ZONE_1] = bus->i2c_smbus_read_byte(dev);
std::this_thread::sleep_for(1ms);
zone_led_count[POLYCHROME_ZONE_2] = bus->i2c_smbus_read_byte(dev);
std::this_thread::sleep_for(1ms);
zone_led_count[POLYCHROME_ZONE_3] = bus->i2c_smbus_read_byte(dev);
std::this_thread::sleep_for(1ms);
zone_led_count[POLYCHROME_ZONE_4] = bus->i2c_smbus_read_byte(dev);
std::this_thread::sleep_for(1ms);
zone_led_count[POLYCHROME_ZONE_5] = bus->i2c_smbus_read_byte(dev);
std::this_thread::sleep_for(1ms);
zone_led_count[POLYCHROME_ZONE_ADDRESSABLE] = bus->i2c_smbus_read_byte(dev);
}
else
{
memset(zone_led_count, 0, sizeof(zone_led_count));
}
}
unsigned int PolychromeController::GetMode()
{
return(active_mode);
}
void PolychromeController::SetColorsAndSpeed(unsigned char led, unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char color_speed_pkt[4] = { red, green, blue, active_speed };
unsigned char select_led_pkt[1] = { led };
switch(asrock_type)
{
case ASROCK_TYPE_ASRLED:
/*-----------------------------------------------------*\
| Select LED |
\*-----------------------------------------------------*/
if(active_mode != ASRLED_MODE_OFF)
{
bus->i2c_smbus_write_block_data(dev, ASROCK_REG_LED_SELECT, 1, select_led_pkt);
std::this_thread::sleep_for(1ms);
}
switch(active_mode)
{
/*-----------------------------------------------------*\
| These modes take 4 bytes in R/G/B/S order |
\*-----------------------------------------------------*/
case ASRLED_MODE_BREATHING:
case ASRLED_MODE_STROBE:
case ASRLED_MODE_SPECTRUM_CYCLE:
bus->i2c_smbus_write_block_data(dev, active_mode, 4, color_speed_pkt);
break;
/*-----------------------------------------------------*\
| These modes take 3 bytes in R/G/B order |
\*-----------------------------------------------------*/
default:
case ASRLED_MODE_STATIC:
case ASRLED_MODE_MUSIC:
bus->i2c_smbus_write_block_data(dev, active_mode, 3, color_speed_pkt);
break;
/*-----------------------------------------------------*\
| These modes take 1 byte - speed |
\*-----------------------------------------------------*/
case ASRLED_MODE_RANDOM:
case ASRLED_MODE_WAVE:
bus->i2c_smbus_write_block_data(dev, active_mode, 1, &active_speed);
break;
/*-----------------------------------------------------*\
| These modes take no bytes |
\*-----------------------------------------------------*/
case ASRLED_MODE_OFF:
break;
}
std::this_thread::sleep_for(1ms);
break;
case ASROCK_TYPE_POLYCHROME_V1:
/*-----------------------------------------------------*\
| Select LED |
\*-----------------------------------------------------*/
if(active_mode != ASRLED_MODE_OFF)
{
bus->i2c_smbus_write_block_data(dev, ASROCK_REG_LED_SELECT, 1, select_led_pkt);
std::this_thread::sleep_for(1ms);
}
switch(active_mode)
{
/*-----------------------------------------------------*\
| These modes take 4 bytes in R/G/B/S order |
\*-----------------------------------------------------*/
case POLYCHROME_V1_MODE_BREATHING:
case POLYCHROME_V1_MODE_STROBE:
case POLYCHROME_V1_MODE_SPECTRUM_CYCLE:
case POLYCHROME_V1_MODE_SPRING:
case POLYCHROME_V1_MODE_METEOR:
case POLYCHROME_V1_MODE_STACK:
case POLYCHROME_V1_MODE_CRAM:
case POLYCHROME_V1_MODE_SCAN:
case POLYCHROME_V1_MODE_NEON:
case POLYCHROME_V1_MODE_WATER:
bus->i2c_smbus_write_block_data(dev, active_mode, 4, color_speed_pkt);
break;
/*-----------------------------------------------------*\
| These modes take 3 bytes in R/G/B order |
\*-----------------------------------------------------*/
default:
case POLYCHROME_V1_MODE_STATIC:
case POLYCHROME_V1_MODE_MUSIC:
bus->i2c_smbus_write_block_data(dev, active_mode, 3, color_speed_pkt);
break;
/*-----------------------------------------------------*\
| These modes take 1 byte - speed |
\*-----------------------------------------------------*/
case POLYCHROME_V1_MODE_RANDOM:
case POLYCHROME_V1_MODE_WAVE:
case POLYCHROME_V1_MODE_RAINBOW:
bus->i2c_smbus_write_block_data(dev, active_mode, 1, &active_speed);
break;
/*-----------------------------------------------------*\
| These modes take no bytes |
\*-----------------------------------------------------*/
case POLYCHROME_V1_MODE_OFF:
break;
}
std::this_thread::sleep_for(1ms);
break;
case ASROCK_TYPE_POLYCHROME_V2:
/*-----------------------------------------------------*\
| Select LED |
\*-----------------------------------------------------*/
switch(active_mode)
{
case POLYCHROME_V2_MODE_OFF:
case POLYCHROME_V2_MODE_RAINBOW:
case POLYCHROME_V2_MODE_SPECTRUM_CYCLE:
break;
default:
bus->i2c_smbus_write_block_data(dev, ASROCK_REG_LED_SELECT, 1, select_led_pkt);
std::this_thread::sleep_for(1ms);
/*-----------------------------------------------------*\
| Polychrome firmware always writes color to fixed reg |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, POLYCHROME_V2_REG_COLOR, 3, color_speed_pkt);
std::this_thread::sleep_for(1ms);
break;
}
break;
}
}
void PolychromeController::SetMode(unsigned char zone,unsigned char mode, unsigned char speed)
{
unsigned char led_count_pkt[1] = { 0x00 };
active_zone = zone;
active_mode = mode;
active_speed = speed;
switch(asrock_type)
{
case ASROCK_TYPE_ASRLED:
bus->i2c_smbus_write_block_data(dev, ASROCK_REG_MODE, 1, &active_mode);
std::this_thread::sleep_for(1ms);
break;
case ASROCK_TYPE_POLYCHROME_V1:
/*-----------------------------------------------------*\
| Make sure set all register is set to 0 |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, POLYCHROME_V1_REG_SET_ALL, 1, led_count_pkt);
std::this_thread::sleep_for(1ms);
/*-----------------------------------------------------*\
| Set the zone we are working on |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, ASROCK_REG_LED_SELECT, 1, &active_zone);
std::this_thread::sleep_for(1ms);
/*-----------------------------------------------------*\
| Write the mode |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, ASROCK_REG_MODE, 1, &active_mode);
std::this_thread::sleep_for(1ms);
break;
case ASROCK_TYPE_POLYCHROME_V2:
bus->i2c_smbus_write_block_data(dev, ASROCK_REG_MODE, 1, &active_mode);
std::this_thread::sleep_for(1ms);
/*-----------------------------------------------------*\
| Select a single LED |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, POLYCHROME_V2_REG_LED_COUNT, 0, led_count_pkt);
std::this_thread::sleep_for(1ms);
switch(active_mode)
{
/*-----------------------------------------------------*\
| These modes don't take a speed |
\*-----------------------------------------------------*/
case POLYCHROME_V2_MODE_OFF:
case POLYCHROME_V2_MODE_STATIC:
break;
/*-----------------------------------------------------*\
| All other modes, write speed to active mode register |
\*-----------------------------------------------------*/
default:
bus->i2c_smbus_write_block_data(dev, active_mode, 1, &speed);
std::this_thread::sleep_for(1ms);
break;
}
break;
}
}
@@ -1,221 +0,0 @@
/*-----------------------------------------*\
| ASRockPolychromeSMBusController.h |
| |
| Definitions and types for ASRock |
| ASR LED and Polychrome RGB lighting |
| controller |
| |
| Adam Honse (CalcProgrammer1) 12/13/2019 |
\*-----------------------------------------*/
#include "i2c_smbus.h"
#include <string>
#pragma once
typedef unsigned char polychrome_dev_id;
enum
{
ASROCK_TYPE_UNKNOWN = 0x00, /* Unknown Type or Not ASRock Device */
ASROCK_TYPE_ASRLED = 0x01, /* ASRock Firmware 1.x - ASR LED */
ASROCK_TYPE_POLYCHROME_V1 = 0x02, /* ASRock Firmware 2.x - Polychrome V1 */
ASROCK_TYPE_POLYCHROME_V2 = 0x03, /* ASRock Firmware 3.x - Polychrome V2 */
};
enum
{
/*------------------------------------------------------------------------------------------*\
| ASRock Common Registers |
\*------------------------------------------------------------------------------------------*/
ASROCK_REG_FIRMWARE_VER = 0x00, /* Firmware version Major.Minor */
ASROCK_REG_MODE = 0x30, /* Mode selection register */
ASROCK_REG_LED_SELECT = 0x31, /* LED selection register */
/*------------------------------------------------------------------------------------------*\
| ASRock Polychrome V1/V2 Common Registers |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_REG_LED_CONFIG = 0x33, /* LED configuration register */
/*------------------------------------------------------------------------------------------*\
| ASRock Polychrome V1 (Firmware 2.x) Registers |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_REG_SET_ALL = 0x32, /* Set All register 0x1 = set all */
POLYCHROME_V1_REG_ARGB_GRB = 0x35, /* ARGB bistream reversing register */
/*------------------------------------------------------------------------------------------*\
| ASRock Polychrome V2 (Firmware 3.x) Registers |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V2_REG_LED_COUNT = 0x32, /* Additional LED count register */
POLYCHROME_V2_REG_COLOR = 0x34, /* Color register: Red, Green, Blue */
POLYCHROME_V2_REG_ARGB_GRB = 0x35, /* ARGB bistream reversing register */
};
enum
{
POLYCHROME_ZONE_1 = 0x00, /* RGB LED 1 Header */
POLYCHROME_ZONE_2 = 0x01, /* RGB LED 2 Header */
POLYCHROME_ZONE_3 = 0x02, /* Audio/PCH Zone LEDs */
POLYCHROME_ZONE_4 = 0x03, /* Audio/PCH Zone LEDs */
POLYCHROME_ZONE_5 = 0x04, /* IO Cover Zone LEDs */
POLYCHROME_ZONE_ADDRESSABLE = 0x05, /* Addressable LED header */
POLYCHROME_ZONE_COUNT = 0x06, /* Total number of zones */
POLYCHROME_ZONE_ADDRESSABLE_MAX = 0x64, /* Maxinum number of ARGB LEDs */
};
/*----------------------------------------------------------------------------------------------*\
| Definitions for ASR LED |
\*----------------------------------------------------------------------------------------------*/
#define ASRLED_NUM_MODES 8 /* Number of ASR LED modes */
enum
{
ASRLED_MODE_OFF = 0x10, /* OFF mode */
ASRLED_MODE_STATIC = 0x11, /* Static color mode */
ASRLED_MODE_BREATHING = 0x12, /* Breathing effect mode */
ASRLED_MODE_STROBE = 0x13, /* Strobe effect mode */
ASRLED_MODE_SPECTRUM_CYCLE = 0x14, /* Spectrum Cycle effect mode */
ASRLED_MODE_RANDOM = 0x15, /* Random effect mode */
ASRLED_MODE_MUSIC = 0x17, /* Music effect mode */
ASRLED_MODE_WAVE = 0x18, /* Wave effect mode */
};
enum
{
ASRLED_SPEED_MIN = 0x05, /* Slowest speed */
ASRLED_SPEED_DEFAULT = 0x03, /* Default speed */
ASRLED_SPEED_MAX = 0x00, /* Fastest speed */
};
/*----------------------------------------------------------------------------------------------*\
| Definitions for Polychrome V1 |
\*----------------------------------------------------------------------------------------------*/
#define POLYCHROME_V1_NUM_MODES 16 /* Number of Polychrome V1 modes */
enum
{
POLYCHROME_V1_MODE_OFF = 0x10, /* OFF mode */
POLYCHROME_V1_MODE_STATIC = 0x11, /* Static color mode */
POLYCHROME_V1_MODE_BREATHING = 0x12, /* Breating effect mode */
POLYCHROME_V1_MODE_STROBE = 0x13, /* Strobe effect mode */
POLYCHROME_V1_MODE_SPECTRUM_CYCLE = 0x14, /* Spectrum Cycle effect mode */
POLYCHROME_V1_MODE_RANDOM = 0x15, /* Random effect mode */
POLYCHROME_V1_MODE_MUSIC = 0x17, /* Music effect mode */
POLYCHROME_V1_MODE_WAVE = 0x18, /* Wave effect mode */
/*------------------------------------------------------------------------------------------*\
| Modes only available on ARGB headers |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_MODE_SPRING = 0x19, /* Spring effect mode */
POLYCHROME_V1_MODE_METEOR = 0x1A, /* Meteor effect mode */
POLYCHROME_V1_MODE_STACK = 0x1B, /* Stack effect mode */
POLYCHROME_V1_MODE_CRAM = 0x1C, /* Cram effect mode */
POLYCHROME_V1_MODE_SCAN = 0x1D, /* Scan effect mode */
POLYCHROME_V1_MODE_NEON = 0x1E, /* Neon effect mode */
POLYCHROME_V1_MODE_WATER = 0x1F, /* Water effect mode */
POLYCHROME_V1_MODE_RAINBOW = 0x20, /* Rainbow chase effect mode */
};
enum
{
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_BREATHING |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_BREATHING = 0x0A, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_BREATHING = 0x02, /* Default speed */
POLYCHROME_V1_SPEED_MAX_BREATHING = 0x02, /* Fastest speed */
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_STROBE |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_STROBE = 0xA0, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_STROBE = 0x14, /* Default speed */
POLYCHROME_V1_SPEED_MAX_STROBE = 0x05, /* Fastest speed */
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_SPECTRUM_CYCLE |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_CYCLE = 0xA0, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_CYCLE = 0x14, /* Default speed */
POLYCHROME_V1_SPEED_MAX_CYCLE = 0x0A, /* Fastest speed */
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_RANDOM |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_RANDOM = 0xA0, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_RANDOM = 0x28, /* Default speed */
POLYCHROME_V1_SPEED_MAX_RANDOM = 0x05, /* Fastest speed */
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_WAVE |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_WAVE = 0x06, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_WAVE = 0x02, /* Default speed */
POLYCHROME_V1_SPEED_MAX_WAVE = 0x01, /* Fastest speed */
POLYCHROME_V1_SPEED_DEFAULT_SPRING = 0x04, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_METEOR = 0x0A, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_STACK = 0x04, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_CRAM = 0x04, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_SCAN = 0x0A, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_NEON = 0x20, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_WATER = 0x0A, /* Default speed */
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_RAINBOW |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_RAINBOW = 0x12, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_RAINBOW = 0x0A, /* Default speed */
POLYCHROME_V1_SPEED_MAX_RAINBOW = 0x01, /* Fastest speed */
POLYCHROME_V1_SPEED_MIN_ARGB = 0x20, /* Slowest speed */
POLYCHROME_V1_SPEED_MAX_ARGB = 0x02, /* Fastest speed */
};
/*----------------------------------------------------------------------------------------------*\
| Definitions for Polychrome V2 |
\*----------------------------------------------------------------------------------------------*/
#define POLYCHROME_V2_NUM_MODES 14 /* Number of Polychrome V2 modes */
enum
{
POLYCHROME_V2_MODE_OFF = 0x10, /* OFF mode */
POLYCHROME_V2_MODE_STATIC = 0x11, /* Static color mode */
POLYCHROME_V2_MODE_BREATHING = 0x12, /* Breating effect mode */
POLYCHROME_V2_MODE_STROBE = 0x13, /* Strobe effect mode */
POLYCHROME_V2_MODE_SPECTRUM_CYCLE = 0x14, /* Spectrum Cycle effect mode */
POLYCHROME_V2_MODE_RANDOM = 0x15, /* Random effect mode */
POLYCHROME_V2_MODE_WAVE = 0x17, /* Wave effect mode */
POLYCHROME_V2_MODE_SPRING = 0x18, /* Spring effect mode */
POLYCHROME_V2_MODE_STACK = 0x19, /* Stack effect mode */
POLYCHROME_V2_MODE_CRAM = 0x1A, /* Cram effect mode */
POLYCHROME_V2_MODE_SCAN = 0x1B, /* Scan effect mode */
POLYCHROME_V2_MODE_NEON = 0x1C, /* Neon effect mode */
POLYCHROME_V2_MODE_WATER = 0x1D, /* Water effect mode */
POLYCHROME_V2_MODE_RAINBOW = 0x1E, /* Rainbow effect mode */
};
enum
{
POLYCHROME_V2_SPEED_MIN = 0x05, /* Slowest speed */
POLYCHROME_V2_SPEED_DEFAULT = 0x03, /* Default speed */
POLYCHROME_V2_SPEED_MAX = 0x00, /* Fastest speed */
};
class PolychromeController
{
public:
PolychromeController(i2c_smbus_interface* bus, polychrome_dev_id dev);
~PolychromeController();
std::string GetDeviceLocation();
std::string GetDeviceName();
std::string GetFirmwareVersion();
unsigned int GetMode();
unsigned int GetASRockType();
void SetColorsAndSpeed(unsigned char led, unsigned char red, unsigned char green, unsigned char blue);
void SetMode(unsigned char zone, unsigned char mode, unsigned char speed);
unsigned char zone_led_count[6];
private:
unsigned int asrock_type;
std::string device_name;
unsigned char active_zone;
unsigned char active_mode;
unsigned char active_speed;
i2c_smbus_interface* bus;
polychrome_dev_id dev;
unsigned short ReadFirmwareVersion();
void ReadLEDConfiguration();
};
@@ -1,642 +0,0 @@
/*-----------------------------------------*\
| RGBController_ASRockPolychromeSMBus.cpp |
| |
| Generic RGB Interface for OpenRGB |
| ASRock ASR LED and Polychrome RGB Driver |
| |
| Adam Honse (CalcProgrammer1) 12/15/2019 |
\*-----------------------------------------*/
#include "RGBController_ASRockPolychromeSMBus.h"
#define ASROCK_MAX_ZONES 4
#define ASROCK_MAX_LEDS 22
static const char* polychrome_v1_zone_names[] =
{
"RGB LED 1 Header",
"RGB LED 2 Header",
"PCH",
"IO Cover",
"Audio",
"Addressable Header"
};
static const char* polychrome_v2_zone_names[] =
{
"RGB LED 1 Header",
"RGB LED 2 Header",
"Audio",
"PCH",
"IO Cover",
"Addressable Header"
};
RGBController_Polychrome::RGBController_Polychrome(PolychromeController* polychrome_ptr)
{
polychrome = polychrome_ptr;
name = polychrome->GetDeviceName();
vendor = "ASRock";
version = polychrome->GetFirmwareVersion();
type = DEVICE_TYPE_MOTHERBOARD;
location = polychrome->GetDeviceLocation();
switch(polychrome->GetASRockType())
{
case ASROCK_TYPE_ASRLED:
{
description = "ASRock ASR LED Device";
mode Off;
Off.name = "Off";
Off.value = ASRLED_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = ASRLED_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = ASRLED_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.speed_min = ASRLED_SPEED_MIN;
Breathing.speed_max = ASRLED_SPEED_MAX;
Breathing.speed = ASRLED_SPEED_DEFAULT;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
mode Strobe;
Strobe.name = "Strobe";
Strobe.value = ASRLED_MODE_STROBE;
Strobe.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Strobe.speed_min = ASRLED_SPEED_MIN;
Strobe.speed_max = ASRLED_SPEED_MAX;
Strobe.speed = ASRLED_SPEED_DEFAULT;
Strobe.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Strobe);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = ASRLED_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED;
SpectrumCycle.speed_min = ASRLED_SPEED_MIN;
SpectrumCycle.speed_max = ASRLED_SPEED_MAX;
SpectrumCycle.speed = ASRLED_SPEED_DEFAULT;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
mode Random;
Random.name = "Random";
Random.value = ASRLED_MODE_RANDOM;
Random.flags = MODE_FLAG_HAS_SPEED;
Random.speed_min = ASRLED_SPEED_MIN;
Random.speed_max = ASRLED_SPEED_MAX;
Random.speed = ASRLED_SPEED_DEFAULT;
Random.color_mode = MODE_COLORS_NONE;
modes.push_back(Random);
mode Music;
Music.name = "Music";
Music.value = ASRLED_MODE_MUSIC;
Music.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Music.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Music);
mode Wave;
Wave.name = "Wave";
Wave.value = ASRLED_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_SPEED;
Wave.speed_min = ASRLED_SPEED_MIN;
Wave.speed_max = ASRLED_SPEED_MAX;
Wave.speed = ASRLED_SPEED_DEFAULT;
Wave.color_mode = MODE_COLORS_NONE;
modes.push_back(Wave);
}
break;
case ASROCK_TYPE_POLYCHROME_V1:
{
description = "ASRock Polychrome v1 Device";
mode Off;
Off.name = "Off";
Off.value = POLYCHROME_V1_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = POLYCHROME_V1_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = POLYCHROME_V1_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.speed_min = POLYCHROME_V1_SPEED_MIN_BREATHING;
Breathing.speed_max = POLYCHROME_V1_SPEED_MAX_BREATHING;
Breathing.speed = POLYCHROME_V1_SPEED_DEFAULT_BREATHING;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
mode Strobe;
Strobe.name = "Strobe";
Strobe.value = POLYCHROME_V1_MODE_STROBE;
Strobe.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Strobe.speed_min = POLYCHROME_V1_SPEED_MIN_STROBE;
Strobe.speed_max = POLYCHROME_V1_SPEED_MAX_STROBE;
Strobe.speed = POLYCHROME_V1_SPEED_DEFAULT_STROBE;
Strobe.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Strobe);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = POLYCHROME_V1_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED;
SpectrumCycle.speed_min = POLYCHROME_V1_SPEED_MIN_CYCLE;
SpectrumCycle.speed_max = POLYCHROME_V1_SPEED_MAX_CYCLE;
SpectrumCycle.speed = POLYCHROME_V1_SPEED_DEFAULT_CYCLE;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
mode Random;
Random.name = "Random";
Random.value = POLYCHROME_V1_MODE_RANDOM;
Random.flags = MODE_FLAG_HAS_SPEED;
Random.speed_min = POLYCHROME_V1_SPEED_MIN_RANDOM;
Random.speed_max = POLYCHROME_V1_SPEED_MAX_RANDOM;
Random.speed = POLYCHROME_V1_SPEED_DEFAULT_RANDOM;
Random.color_mode = MODE_COLORS_NONE;
modes.push_back(Random);
mode Music;
Music.name = "Music";
Music.value = POLYCHROME_V1_MODE_MUSIC;
Music.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Music.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Music);
mode Wave;
Wave.name = "Wave";
Wave.value = POLYCHROME_V1_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_SPEED;
Wave.speed_min = POLYCHROME_V1_SPEED_MIN_WAVE;
Wave.speed_max = POLYCHROME_V1_SPEED_MAX_WAVE;
Wave.speed = POLYCHROME_V1_SPEED_DEFAULT_WAVE;
Wave.color_mode = MODE_COLORS_NONE;
modes.push_back(Wave);
/*---------------------------------------------------------------------*\
| Comment out until per zone modes are working. These are only for ARGB |
\*---------------------------------------------------------------------*/
/*
mode Spring;
Spring.name = "Spring";
Spring.value = POLYCHROME_V1_MODE_SPRING;
Spring.flags = MODE_FLAG_HAS_SPEED;
Spring.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Spring.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Spring.speed = POLYCHROME_V1_SPEED_DEFAULT_SPRING;
Spring.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Spring);
mode Stack;
Stack.name = "Stack";
Stack.value = POLYCHROME_V1_MODE_STACK;
Stack.flags = MODE_FLAG_HAS_SPEED;
Stack.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Stack.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Stack.speed = POLYCHROME_V1_SPEED_DEFAULT_STACK;
Stack.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Stack);
mode Cram;
Cram.name = "Cram";
Cram.value = POLYCHROME_V1_MODE_CRAM;
Cram.flags = MODE_FLAG_HAS_SPEED;
Cram.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Cram.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Cram.speed = POLYCHROME_V1_SPEED_DEFAULT_CRAM;
Cram.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Cram);
mode Scan;
Scan.name = "Scan";
Scan.value = POLYCHROME_V1_MODE_SCAN;
Scan.flags = MODE_FLAG_HAS_SPEED;
Scan.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Scan.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Scan.speed = POLYCHROME_V1_SPEED_DEFAULT_SCAN;
Scan.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Scan);
mode Neon;
Neon.name = "Neon";
Neon.value = POLYCHROME_V1_MODE_NEON;
Neon.flags = MODE_FLAG_HAS_SPEED;
Neon.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Neon.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Neon.speed = POLYCHROME_V1_SPEED_DEFAULT_NEON;
Neon.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Neon);
mode Water;
Water.name = "Water";
Water.value = POLYCHROME_V1_MODE_WATER;
Water.flags = MODE_FLAG_HAS_SPEED;
Water.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Water.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Water.speed = POLYCHROME_V1_SPEED_DEFAULT_WATER;
Water.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Water);
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = POLYCHROME_V1_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED;
Rainbow.speed_min = POLYCHROME_V1_SPEED_MIN_RAINBOW;
Rainbow.speed_max = POLYCHROME_V1_SPEED_MAX_RAINBOW;
Rainbow.speed = POLYCHROME_V1_SPEED_DEFAULT_RAINBOW;
Rainbow.color_mode = MODE_COLORS_NONE;
modes.push_back(Rainbow);
*/
}
break;
case ASROCK_TYPE_POLYCHROME_V2:
{
description = "ASRock Polychrome v2 Device";
mode Off;
Off.name = "Off";
Off.value = POLYCHROME_V2_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = POLYCHROME_V2_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = POLYCHROME_V2_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.speed_min = POLYCHROME_V2_SPEED_MIN;
Breathing.speed_max = POLYCHROME_V2_SPEED_MAX;
Breathing.speed = POLYCHROME_V2_SPEED_DEFAULT;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
mode Strobe;
Strobe.name = "Strobe";
Strobe.value = POLYCHROME_V2_MODE_STROBE;
Strobe.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Strobe.speed_min = POLYCHROME_V2_SPEED_MIN;
Strobe.speed_max = POLYCHROME_V2_SPEED_MAX;
Strobe.speed = POLYCHROME_V2_SPEED_DEFAULT;
Strobe.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Strobe);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = POLYCHROME_V2_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED;
SpectrumCycle.speed_min = POLYCHROME_V2_SPEED_MIN;
SpectrumCycle.speed_max = POLYCHROME_V2_SPEED_MAX;
SpectrumCycle.speed = POLYCHROME_V2_SPEED_DEFAULT;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
mode Random;
Random.name = "Random";
Random.value = POLYCHROME_V2_MODE_RANDOM;
Random.flags = MODE_FLAG_HAS_SPEED;
Random.speed_min = POLYCHROME_V2_SPEED_MIN;
Random.speed_max = POLYCHROME_V2_SPEED_MAX;
Random.speed = POLYCHROME_V2_SPEED_DEFAULT;
Random.color_mode = MODE_COLORS_NONE;
modes.push_back(Random);
mode Wave;
Wave.name = "Wave";
Wave.value = POLYCHROME_V2_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_SPEED;
Wave.speed_min = POLYCHROME_V2_SPEED_MIN;
Wave.speed_max = POLYCHROME_V2_SPEED_MAX;
Wave.speed = POLYCHROME_V2_SPEED_DEFAULT;
Wave.color_mode = MODE_COLORS_NONE;
modes.push_back(Wave);
mode Spring;
Spring.name = "Spring";
Spring.value = POLYCHROME_V2_MODE_SPRING;
Spring.flags = MODE_FLAG_HAS_SPEED;
Spring.speed_min = POLYCHROME_V2_SPEED_MIN;
Spring.speed_max = POLYCHROME_V2_SPEED_MAX;
Spring.speed = POLYCHROME_V2_SPEED_DEFAULT;
Spring.color_mode = MODE_COLORS_NONE;
modes.push_back(Spring);
mode Stack;
Stack.name = "Stack";
Stack.value = POLYCHROME_V2_MODE_STACK;
Stack.flags = MODE_FLAG_HAS_SPEED;
Stack.speed_min = POLYCHROME_V2_SPEED_MIN;
Stack.speed_max = POLYCHROME_V2_SPEED_MAX;
Stack.speed = POLYCHROME_V2_SPEED_DEFAULT;
Stack.color_mode = MODE_COLORS_NONE;
modes.push_back(Stack);
mode Cram;
Cram.name = "Cram";
Cram.value = POLYCHROME_V2_MODE_CRAM;
Cram.flags = MODE_FLAG_HAS_SPEED;
Cram.speed_min = POLYCHROME_V2_SPEED_MIN;
Cram.speed_max = POLYCHROME_V2_SPEED_MAX;
Cram.speed = POLYCHROME_V2_SPEED_DEFAULT;
Cram.color_mode = MODE_COLORS_NONE;
modes.push_back(Cram);
mode Scan;
Scan.name = "Scan";
Scan.value = POLYCHROME_V2_MODE_SCAN;
Scan.flags = MODE_FLAG_HAS_SPEED;
Scan.speed_min = POLYCHROME_V2_SPEED_MIN;
Scan.speed_max = POLYCHROME_V2_SPEED_MAX;
Scan.speed = POLYCHROME_V2_SPEED_DEFAULT;
Scan.color_mode = MODE_COLORS_NONE;
modes.push_back(Scan);
mode Neon;
Neon.name = "Neon";
Neon.value = POLYCHROME_V2_MODE_NEON;
Neon.flags = 0;
Neon.color_mode = MODE_COLORS_NONE;
modes.push_back(Neon);
mode Water;
Water.name = "Water";
Water.value = POLYCHROME_V2_MODE_WATER;
Water.flags = MODE_FLAG_HAS_SPEED;
Water.speed_min = POLYCHROME_V2_SPEED_MIN;
Water.speed_max = POLYCHROME_V2_SPEED_MAX;
Water.speed = POLYCHROME_V2_SPEED_DEFAULT;
Water.color_mode = MODE_COLORS_NONE;
modes.push_back(Water);
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = POLYCHROME_V2_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED;
Rainbow.speed_min = POLYCHROME_V2_SPEED_MIN;
Rainbow.speed_max = POLYCHROME_V2_SPEED_MAX;
Rainbow.speed = POLYCHROME_V2_SPEED_DEFAULT;
Rainbow.color_mode = MODE_COLORS_NONE;
modes.push_back(Rainbow);
}
break;
}
SetupZones();
}
RGBController_Polychrome::~RGBController_Polychrome()
{
delete polychrome;
}
void RGBController_Polychrome::SetupZones()
{
switch(polychrome->GetASRockType())
{
/*---------------------------------------------------------*\
| ASR LED motherboards only have a single zone/LED |
\*---------------------------------------------------------*/
case ASROCK_TYPE_ASRLED:
{
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
zone* new_zone = new zone();
/*---------------------------------------------------------*\
| Set single zone name to "Motherboard" |
\*---------------------------------------------------------*/
new_zone->name = "Motherboard";
new_zone->type = ZONE_TYPE_SINGLE;
new_zone->leds_min = 1;
new_zone->leds_max = 1;
new_zone->leds_count = 1;
new_zone->matrix_map = NULL;
/*---------------------------------------------------------*\
| Push new zone to zones vector |
\*---------------------------------------------------------*/
zones.push_back(*new_zone);
/*---------------------------------------------------------*\
| Set up LEDs |
\*---------------------------------------------------------*/
led* new_led = new led();
/*---------------------------------------------------------*\
| Set single LED name to "Motherboard" |
\*---------------------------------------------------------*/
new_led->name = "Motherboard";
/*---------------------------------------------------------*\
| Push new LED to LEDs vector |
\*---------------------------------------------------------*/
leds.push_back(*new_led);
}
break;
/*---------------------------------------------------------*\
| Polychrome motherboards should set up zones based on LED |
| configuration register read from device |
\*---------------------------------------------------------*/
case ASROCK_TYPE_POLYCHROME_V1:
case ASROCK_TYPE_POLYCHROME_V2:
{
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
for(unsigned int zone_idx = 0; zone_idx < POLYCHROME_ZONE_COUNT; zone_idx++)
{
if(polychrome->zone_led_count[zone_idx] > 0)
{
zone* new_zone = new zone();
/*---------------------------------------------------------*\
| Set zone name to channel name |
\*---------------------------------------------------------*/
if(polychrome->GetASRockType() == ASROCK_TYPE_POLYCHROME_V1)
{
new_zone->name = polychrome_v1_zone_names[zone_idx];
}
else
{
new_zone->name = polychrome_v2_zone_names[zone_idx];
}
if(zone_idx == POLYCHROME_ZONE_ADDRESSABLE)
{
new_zone->leds_min = 1;
new_zone->leds_max = 1;
new_zone->leds_count = 1;
}
else
{
new_zone->leds_min = polychrome->zone_led_count[zone_idx];
new_zone->leds_max = polychrome->zone_led_count[zone_idx];
new_zone->leds_count = polychrome->zone_led_count[zone_idx];
}
if(new_zone->leds_count > 1)
{
new_zone->type = ZONE_TYPE_LINEAR;
}
else
{
new_zone->type = ZONE_TYPE_SINGLE;
}
new_zone->matrix_map = NULL;
/*---------------------------------------------------------*\
| Push new zone to zones vector |
\*---------------------------------------------------------*/
zones.push_back(*new_zone);
}
}
unsigned int led_count = 0;
/*---------------------------------------------------------*\
| Set up LEDs |
\*---------------------------------------------------------*/
for(unsigned int zone_idx = 0; zone_idx < POLYCHROME_ZONE_COUNT; zone_idx++)
{
if(polychrome->zone_led_count[zone_idx] > 0)
{
for(unsigned int led_idx = 0; led_idx < polychrome->zone_led_count[zone_idx]; led_idx++)
{
/*---------------------------------------------------------*\
| Each zone only has one LED |
\*---------------------------------------------------------*/
led* new_led = new led();
if(polychrome->GetASRockType() == ASROCK_TYPE_POLYCHROME_V1)
{
new_led->name = polychrome_v1_zone_names[zone_idx];
}
else
{
new_led->name = polychrome_v2_zone_names[zone_idx];
}
new_led->name.append(" " + std::to_string(led_idx + 1));
new_led->value = 0;
if(polychrome->GetASRockType() == ASROCK_TYPE_POLYCHROME_V1)
{
new_led->value = zone_idx;
}
else if(zone_idx == POLYCHROME_ZONE_ADDRESSABLE)
{
new_led->value = 0x19;
}
/*---------------------------------------------------------*\
| Push new LED to LEDs vector |
\*---------------------------------------------------------*/
leds.push_back(*new_led);
led_count++;
if(zone_idx == POLYCHROME_ZONE_ADDRESSABLE)
{
break;
}
}
}
}
}
break;
}
SetupColors();
}
void RGBController_Polychrome::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_Polychrome::DeviceUpdateLEDs()
{
for (std::size_t led = 0; led < colors.size(); led++)
{
UpdateSingleLED(led);
}
}
void RGBController_Polychrome::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_Polychrome::UpdateSingleLED(int led)
{
unsigned char red = RGBGetRValue(colors[led]);
unsigned char grn = RGBGetGValue(colors[led]);
unsigned char blu = RGBGetBValue(colors[led]);
/*---------------------------------------------------------*\
| If the LED value is non-zero, this LED overrides the LED |
| index |
\*---------------------------------------------------------*/
if(leds[led].value != 0)
{
led = leds[led].value;
}
polychrome->SetColorsAndSpeed(led, red, grn, blu);
}
void RGBController_Polychrome::SetCustomMode()
{
active_mode = 1;
}
void RGBController_Polychrome::DeviceUpdateMode()
{
if(polychrome->GetASRockType() == ASROCK_TYPE_POLYCHROME_V1)
{
for(unsigned int led_idx = 0; led_idx <= leds.size(); led_idx++)
{
polychrome->SetMode(led_idx, modes[active_mode].value, modes[active_mode].speed);
}
}
else
{
polychrome->SetMode(0, modes[active_mode].value, modes[active_mode].speed);
}
DeviceUpdateLEDs();
}
@@ -1,361 +0,0 @@
/*-----------------------------------------*\
| ASRockPolychromeUSBController.cpp |
| |
| Driver for ASRock Polychrome USB |
| lighting controller |
| |
| Ed Kambulow (dredvard) 12/20/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include "ASRockPolychromeUSBController.h"
#include <cstring>
#include <stdio.h>
#include "dependencies/dmiinfo.h"
#define POLYCHROME_USB_READ_ZONE_CONFIG 0x11
#define POLYCHROME_USB_READ_HEADER 0x14
#define POLYCHROME_USB_WRITE_HEADER 0x15
#define POLYCHROME_USB_SET_ZONE 0x10
#define POLYCHROME_USB_INIT 0xA4
#define POLYCHROME_USB_COMMIT 0x12
PolychromeUSBController::PolychromeUSBController(hid_device* dev_handle, const char* path)
{
DMIInfo dmi;
dev = dev_handle;
device_name = "ASRock " + dmi.getMainboard();
location = path;
SetDeviceInfo();
}
PolychromeUSBController::~PolychromeUSBController()
{
}
unsigned int PolychromeUSBController::GetChannelCount()
{
return(device_info.size());
}
std::string PolychromeUSBController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string PolychromeUSBController::GetDeviceName()
{
return(device_name);
}
std::string PolychromeUSBController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void PolychromeUSBController::SetDeviceInfo()
{
PolychromeDeviceInfo newdev_info;
ReadConfigTables();
for (unsigned int zonecnt = 0; zonecnt < POLYCHROME_USB_ZONE_MAX_NUM; zonecnt++)
{
if(configtable[zonecnt] == 0x1E)
{
break;
}
newdev_info.num_leds = configtable[zonecnt];
switch (zonecnt)
{
/*-----------------------------------------*\
| Type: Addressable, configurable |
\*-----------------------------------------*/
case POLYCHROME_USB_ZONE_ARGB1:
case POLYCHROME_USB_ZONE_ARGB2:
newdev_info.device_type = PolychromeDeviceType::ADDRESSABLE;
break;
/*-----------------------------------------*\
| Type: Addressable, not configurable |
\*-----------------------------------------*/
case POLYCHROME_USB_ZONE_PCH:
case POLYCHROME_USB_ZONE_IOCOVER:
case POLYCHROME_USB_ZONE_PCB:
case POLYCHROME_USB_ZONE_AUDIO:
newdev_info.device_type = PolychromeDeviceType::FIXED;
break;
/*-----------------------------------------*\
| Type: Fixed |
\*-----------------------------------------*/
case POLYCHROME_USB_ZONE_RGB1:
case POLYCHROME_USB_ZONE_RGB2:
default:
newdev_info.device_type = PolychromeDeviceType::FIXED;
break;
}
device_info.push_back(newdev_info);
}
}
void PolychromeUSBController::WriteZone
(
unsigned char zone,
unsigned char mode,
unsigned char speed,
RGBColor rgb,
bool allzone = false
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet with leading 00 |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_SET_ZONE;
usb_buf[0x03] = zone;
usb_buf[0x04] = mode;
usb_buf[0x05] = RGBGetRValue(rgb);
usb_buf[0x06] = RGBGetGValue(rgb);
usb_buf[0x07] = RGBGetBValue(rgb);
usb_buf[0x08] = speed;
usb_buf[0x09] = 0xFF;
usb_buf[0x10] = allzone;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
};
void PolychromeUSBController::WriteRGSwap
(
bool ahdr1,
bool ahdr0,
bool hdr1,
bool hdr0
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet with leading 00 |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_WRITE_HEADER;
usb_buf[0x04] = POLYCHROME_USB_RGSWAP_CFG;
usb_buf[0x05] = ((ahdr1 << 3) & (ahdr0 << 2) & (hdr1 << 1) & hdr0) & 0x40;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
}
void PolychromeUSBController::WriteHeader
(
unsigned char cfg,
unsigned char* configstring,
unsigned int configsize
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet with leading 00 |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_WRITE_HEADER;
usb_buf[0x03] = cfg;
memcpy(&usb_buf[4], configstring, configsize);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
}
PolychromeZoneInfo PolychromeUSBController::GetZoneConfig(unsigned char zone)
{
unsigned char usb_buf[65];
PolychromeZoneInfo zoneinfo;
//unsigned char all;
unsigned char r;
unsigned char g;
unsigned char b;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_READ_ZONE_CONFIG;
usb_buf[0x03] = zone;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
/*-----------------------------------------------------*\
| Read response |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
hid_read(dev, usb_buf, 64);
r = usb_buf[0x05];
g = usb_buf[0x06];
b = usb_buf[0x07];
zoneinfo.mode = usb_buf[0x04];
zoneinfo.color = ToRGBColor(r,g,b);
zoneinfo.speed = usb_buf[0x08];
zoneinfo.zone = usb_buf[0x03];
//all = usb_buf[0x10];
return(zoneinfo);
}
void PolychromeUSBController::ReadConfigTables()
{
unsigned char usb_buf[65];
unsigned char maxzoneleds[8];
unsigned char rgbswap;
unsigned char header1;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up max led config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_READ_HEADER;
usb_buf[0x03] = POLYCHROME_USB_LEDCOUNT_CFG;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
/*-----------------------------------------------------*\
| Read response |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
hid_read(dev, usb_buf, 64);
/*-----------------------------------------------------*\
| Reads in format: RGB1, RGB2, ARGB1, ARGB2, PCH, IO, |
| PCB, AUDIO |
\*-----------------------------------------------------*/
memcpy(&maxzoneleds,&usb_buf[0x04],8);
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up RGB Swap table request packet |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_READ_HEADER;
usb_buf[0x03] = POLYCHROME_USB_RGSWAP_CFG;
hid_write(dev, usb_buf, 65);
memset(usb_buf, 0x00, sizeof(usb_buf));
hid_read(dev, usb_buf, 64);
/*-----------------------------------------------------*\
| Reads bitwise in format: AUDIO, PCB, IO, PCH, ARGB2, |
| ARGB1, RGB2, RGB1 if available |
\*-----------------------------------------------------*/
rgbswap=usb_buf[4];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Header1 config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_READ_HEADER;
usb_buf[0x03] = 0x01;
hid_write(dev, usb_buf, 64);
memset(usb_buf, 0x00, sizeof(usb_buf));
hid_read(dev, usb_buf, 64);
header1=usb_buf[4];
memcpy(configtable,&maxzoneleds,8);
configtable[8]=rgbswap;
configtable[9]=header1;
return;
}
void PolychromeUSBController::Commit()
{
/*-----------------------------------------------------*\
| Saves all Writes in Device - Will keep after powerup |
\*-----------------------------------------------------*/
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet with leading 00 |
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_COMMIT;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 64);
};
const std::vector<PolychromeDeviceInfo>& PolychromeUSBController::GetPolychromeDevices() const
{
return(device_info);
};
@@ -1,151 +0,0 @@
/*-----------------------------------------*\
| ASRockPolychromeUSBController.h |
| |
| Driver for ASRock Polychrome USB |
| lighting controller |
| |
| Ed Kambulow (dredvard) 12/20/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <hidapi/hidapi.h>
#include <string>
#pragma once
/*----------------------------------------------------------------------------------------------*\
| Definitions for Polychrome USB |
\*----------------------------------------------------------------------------------------------*/
#define POLYCHROME_USB_NUM_MODES 15 /* Number of Polychrome USB modes */
enum
{
POLYCHROME_USB_MODE_OFF = 0x00, /* OFF mode */
POLYCHROME_USB_MODE_STATIC = 0x01, /* Static color mode */
POLYCHROME_USB_MODE_BREATHING = 0x02, /* Breathing effect mode */
POLYCHROME_USB_MODE_STROBE = 0x03, /* Strobe effect mode */
POLYCHROME_USB_MODE_SPECTRUM_CYCLE = 0x04, /* Spectrum Cycle effect mode */
POLYCHROME_USB_MODE_RANDOM = 0x05, /* Random effect mode */
POLYCHROME_USB_MODE_MUSIC = 0x06, /* Random effect mode */
POLYCHROME_USB_MODE_WAVE = 0x07, /* Wave effect mode */
POLYCHROME_USB_MODE_SPRING = 0x08, /* Spring effect mode */
POLYCHROME_USB_MODE_STACK = 0x09, /* Stack effect mode */
POLYCHROME_USB_MODE_CRAM = 0x0A, /* Cram effect mode */
POLYCHROME_USB_MODE_SCAN = 0x0B, /* Scan effect mode */
POLYCHROME_USB_MODE_NEON = 0x0C, /* Neon effect mode */
POLYCHROME_USB_MODE_WATER = 0x0D, /* Water effect mode */
POLYCHROME_USB_MODE_RAINBOW = 0x0E, /* Rainbow effect mode */
};
enum
{
POLYCHROME_USB_SPEED_MIN = 0xFF, /* Slowest speed */
POLYCHROME_USB_SPEED_DEFAULT = 0xE0, /* Default speed */
POLYCHROME_USB_SPEED_MAX = 0x00, /* Fastest speed */
};
enum
{
POLYCHROME_USB_ZONE_MAX_NUM = 0x08, /* Total Max number of zones */
POLYCHROME_USB_ZONE_ADDRESSABLE_MAX = 0x64, /* Maxinum number of ARGB LEDs */
};
enum
{
POLYCHROME_USB_LEDCOUNT_CFG = 0x02, // Config for LED Count
POLYCHROME_USB_RGSWAP_CFG = 0x03, // Config for RGSWAP
POLYCHROME_USB_ZONE_UNAVAILABLE = 0x1E, // Value from LEDCOUNT CFG if zone not present
};
static const char* polychrome_USB_zone_names[] =
{
"RGB LED 1 Header",
"RGB LED 2 Header",
"Addressable Header 1",
"Addressable Header 2",
"PCH",
"IO Cover",
"PCB",
"Audio",
};
enum
{
POLYCHROME_USB_ZONE_RGB1 = 0x00, // RGB Header 1
POLYCHROME_USB_ZONE_RGB2 = 0X01, // RGB Header 2
POLYCHROME_USB_ZONE_ARGB1 = 0X02, // ARGB Header 1
POLYCHROME_USB_ZONE_ARGB2 = 0X03, // ARGB Header 2
POLYCHROME_USB_ZONE_PCH = 0X04, // PCH
POLYCHROME_USB_ZONE_IOCOVER = 0X05, // IOCOVER
POLYCHROME_USB_ZONE_PCB = 0X06, // PCB - Could be mixed swapped with 0x07
POLYCHROME_USB_ZONE_AUDIO = 0X07 // AUDIO
};
enum class PolychromeDeviceType
{
FIXED,
ADDRESSABLE,
};
struct PolychromeZoneInfo
{
unsigned char mode;
unsigned char zone;
unsigned char speed;
RGBColor color;
};
struct PolychromeDeviceInfo
{
unsigned char effect_channel;
unsigned char num_leds;
PolychromeDeviceType device_type;
};
class PolychromeUSBController
{
public:
unsigned char zone_led_count[8];
PolychromeUSBController(hid_device* dev_handle, const char* path);
~PolychromeUSBController();
unsigned int GetChannelCount();
std::string GetDeviceLocation();
std::string GetDeviceName();
const std::vector<PolychromeDeviceInfo>& GetPolychromeDevices() const;
std::string GetSerialString();
PolychromeZoneInfo GetZoneConfig (unsigned char zone);
void WriteZone
(
unsigned char zone,
unsigned char mode,
unsigned char speed,
RGBColor rgb,
bool allzone
);
void WriteHeader
(
unsigned char cfg,
unsigned char* configstring,
unsigned int configsize
);
protected:
hid_device* dev;
std::vector<PolychromeDeviceInfo> device_info;
std::string location;
void WriteRGSwap(bool ahdr1, bool ahdr0, bool hdr1, bool hdr0);
private:
unsigned int led_count;
std::string device_name;
unsigned char configtable[12];
void SetDeviceInfo();
void ReadConfigTables();
void Commit();
};
@@ -1,36 +0,0 @@
#include "Detector.h"
#include "ASRockPolychromeUSBController.h"
#include "RGBController.h"
#include "RGBController_ASRockPolychromeUSB.h"
#include "i2c_smbus.h"
#include "pci_ids.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <hidapi/hidapi.h>
/*---------------------------------------------------------*\
| ASRock vendor ID |
\*---------------------------------------------------------*/
#define ASROCK_VID 0x26CE
/*---------------------------------------------------------*\
| ASRock product ID |
\*---------------------------------------------------------*/
#define ASROCK_MOTHERBOARD_1_PID 0x01A2
#define ASROCK_DESKMINI_ADDRESSABLE_LED_STRIP_PID 0x01A6
void DetectPolychromeUSBControllers(hid_device_info* info, const std::string& /*name*/)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
PolychromeUSBController* controller = new PolychromeUSBController(dev, info->path);
RGBController_PolychromeUSB* rgb_controller = new RGBController_PolychromeUSB(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR("ASRock Polychrome USB", DetectPolychromeUSBControllers, ASROCK_VID, ASROCK_MOTHERBOARD_1_PID);
REGISTER_HID_DETECTOR("ASRock Deskmini Addressable LED Strip", DetectPolychromeUSBControllers, ASROCK_VID, ASROCK_DESKMINI_ADDRESSABLE_LED_STRIP_PID);
@@ -1,338 +0,0 @@
/*-----------------------------------------*\
| RGBController_ASRockPolychromeUSB.cpp |
| |
| Generic RGB Interface for OpenRGB |
| ASRock Polychrome USB Driver |
| |
| Ed Kambulow (Dredvard) 12/26/2020 |
\*-----------------------------------------*/
#include "RGBController_ASRockPolychromeUSB.h"
#include <string.h>
#define ASROCK_USB_MAX_ZONES 8
#define ASROCK_ADDRESSABLE_MAX_LEDS 100
RGBController_PolychromeUSB::RGBController_PolychromeUSB(PolychromeUSBController* polychrome_ptr)
{
polychrome = polychrome_ptr;
name = polychrome->GetDeviceName();
description = "ASRock Polychrome USB Device";
vendor = "ASRock";
type = DEVICE_TYPE_MOTHERBOARD;
location = polychrome->GetDeviceLocation();
mode Off;
Off.name = "Off";
Off.value = POLYCHROME_USB_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = POLYCHROME_USB_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = POLYCHROME_USB_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.speed_min = POLYCHROME_USB_SPEED_MIN;
Breathing.speed_max = POLYCHROME_USB_SPEED_MAX;
Breathing.speed = POLYCHROME_USB_SPEED_DEFAULT;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
mode Strobe;
Strobe.name = "Strobe";
Strobe.value = POLYCHROME_USB_MODE_STROBE;
Strobe.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Strobe.speed_min = POLYCHROME_USB_SPEED_MIN;
Strobe.speed_max = POLYCHROME_USB_SPEED_MAX;
Strobe.speed = POLYCHROME_USB_SPEED_DEFAULT;
Strobe.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Strobe);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = POLYCHROME_USB_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED;
SpectrumCycle.speed_min = POLYCHROME_USB_SPEED_MIN;
SpectrumCycle.speed_max = POLYCHROME_USB_SPEED_MAX;
SpectrumCycle.speed = POLYCHROME_USB_SPEED_DEFAULT;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
mode Random;
Random.name = "Random";
Random.value = POLYCHROME_USB_MODE_RANDOM;
Random.flags = MODE_FLAG_HAS_SPEED;
Random.speed_min = POLYCHROME_USB_SPEED_MIN;
Random.speed_max = POLYCHROME_USB_SPEED_MAX;
Random.speed = POLYCHROME_USB_SPEED_DEFAULT;
Random.color_mode = MODE_COLORS_NONE;
modes.push_back(Random);
mode Music;
Random.name = "Music";
Random.value = POLYCHROME_USB_MODE_RANDOM;
Random.flags = MODE_FLAG_HAS_BRIGHTNESS;
Random.color_mode = MODE_COLORS_NONE;
modes.push_back(Random);
mode Wave;
Wave.name = "Wave";
Wave.value = POLYCHROME_USB_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_SPEED;
Wave.speed_min = POLYCHROME_USB_SPEED_MIN;
Wave.speed_max = POLYCHROME_USB_SPEED_MAX;
Wave.speed = POLYCHROME_USB_SPEED_DEFAULT;
Wave.color_mode = MODE_COLORS_NONE;
modes.push_back(Wave);
mode Spring;
Spring.name = "Spring";
Spring.value = POLYCHROME_USB_MODE_SPRING;
Spring.flags = MODE_FLAG_HAS_SPEED;
Spring.speed_min = POLYCHROME_USB_SPEED_MIN;
Spring.speed_max = POLYCHROME_USB_SPEED_MAX;
Spring.speed = POLYCHROME_USB_SPEED_DEFAULT;
Spring.color_mode = MODE_COLORS_NONE;
modes.push_back(Spring);
mode Stack;
Stack.name = "Stack";
Stack.value = POLYCHROME_USB_MODE_STACK;
Stack.flags = MODE_FLAG_HAS_SPEED;
Stack.speed_min = POLYCHROME_USB_SPEED_MIN;
Stack.speed_max = POLYCHROME_USB_SPEED_MAX;
Stack.speed = POLYCHROME_USB_SPEED_DEFAULT;
Stack.color_mode = MODE_COLORS_NONE;
modes.push_back(Stack);
mode Cram;
Cram.name = "Cram";
Cram.value = POLYCHROME_USB_MODE_CRAM;
Cram.flags = MODE_FLAG_HAS_SPEED;
Cram.speed_min = POLYCHROME_USB_SPEED_MIN;
Cram.speed_max = POLYCHROME_USB_SPEED_MAX;
Cram.speed = POLYCHROME_USB_SPEED_DEFAULT;
Cram.color_mode = MODE_COLORS_NONE;
modes.push_back(Cram);
mode Scan;
Scan.name = "Scan";
Scan.value = POLYCHROME_USB_MODE_SCAN;
Scan.flags = MODE_FLAG_HAS_SPEED;
Scan.speed_min = POLYCHROME_USB_SPEED_MIN;
Scan.speed_max = POLYCHROME_USB_SPEED_MAX;
Scan.speed = POLYCHROME_USB_SPEED_DEFAULT;
Scan.color_mode = MODE_COLORS_NONE;
modes.push_back(Scan);
mode Neon;
Neon.name = "Neon";
Neon.value = POLYCHROME_USB_MODE_NEON;
Neon.flags = 0;
Neon.color_mode = MODE_COLORS_NONE;
modes.push_back(Neon);
mode Water;
Water.name = "Water";
Water.value = POLYCHROME_USB_MODE_WATER;
Water.flags = MODE_FLAG_HAS_SPEED;
Water.speed_min = POLYCHROME_USB_SPEED_MIN;
Water.speed_max = POLYCHROME_USB_SPEED_MAX;
Water.speed = POLYCHROME_USB_SPEED_DEFAULT;
Water.color_mode = MODE_COLORS_NONE;
modes.push_back(Water);
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = POLYCHROME_USB_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED;
Rainbow.speed_min = POLYCHROME_USB_SPEED_MIN;
Rainbow.speed_max = POLYCHROME_USB_SPEED_MAX;
Rainbow.speed = POLYCHROME_USB_SPEED_DEFAULT;
Rainbow.color_mode = MODE_COLORS_NONE;
modes.push_back(Rainbow);
SetupZones();
/*-------------------------------------------------*\
| Initialize active mode |
\*-------------------------------------------------*/
active_mode = GetDeviceMode(1);
}
void RGBController_PolychromeUSB::SetupZones()
{
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
leds.clear();
colors.clear();
zones.resize(polychrome->GetChannelCount());
/*-------------------------------------------------*\
| Set zones and leds |
\*-------------------------------------------------*/
for(unsigned int channel_idx = 0; channel_idx < zones.size(); channel_idx++)
{
PolychromeDeviceInfo device_info = polychrome->GetPolychromeDevices()[channel_idx];
zones[channel_idx].type = ZONE_TYPE_LINEAR;
if(device_info.device_type== PolychromeDeviceType::ADDRESSABLE)
{
zones[channel_idx].name = polychrome_USB_zone_names[channel_idx];
zones[channel_idx].leds_min = 0;
zones[channel_idx].leds_max = ASROCK_ADDRESSABLE_MAX_LEDS;
zones[channel_idx].leds_count = device_info.num_leds;
}
else if(device_info.device_type==PolychromeDeviceType::FIXED)
{
zones[channel_idx].name = polychrome_USB_zone_names[channel_idx];
zones[channel_idx].leds_min = device_info.num_leds;
zones[channel_idx].leds_max = device_info.num_leds;
zones[channel_idx].leds_count = device_info.num_leds;
}
for(unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++)
{
led new_led;
new_led.name = zones[channel_idx].name;
new_led.name.append(", LED ");
new_led.name.append(std::to_string(led_ch_idx + 1));
new_led.value = channel_idx;
leds.push_back(new_led);
}
zones[channel_idx].matrix_map = NULL;
}
SetupColors();
/*---------------------------------------------------------*\
| Initialize colors for each LED |
\*---------------------------------------------------------*/
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
unsigned char led = (unsigned char)leds[led_idx].value;
colors[led_idx] = polychrome->GetZoneConfig(led).color; // TODO Get addressable instead of zone idx
}
/*---------------------------------------------------------*\
| Initialize zone info to track zone, speed, mode |
| B550 Boards have modes, speed for each zone |
\*---------------------------------------------------------*/
for (unsigned int channel_idx = 0; channel_idx < zones.size(); channel_idx++)
{
PolychromeZoneInfo zoneinfo;
zoneinfo = polychrome->GetZoneConfig(channel_idx);
zones_info.push_back(zoneinfo);
}
}
void RGBController_PolychromeUSB::ResizeZone(int zone, int new_size)
{
unsigned char zonecfg[ASROCK_USB_MAX_ZONES];
/*---------------------------------------------------------*\
| This device does not currently support resizing zones |
\*---------------------------------------------------------*/
zones[zone].leds_count = (unsigned char) new_size;
memset(zonecfg, POLYCHROME_USB_ZONE_UNAVAILABLE, ASROCK_USB_MAX_ZONES);
for(unsigned int i = 0; i < zones.size(); i++)
{
zonecfg[i]=zones[i].leds_count;
}
// unsigned char zonecmd = POLYCHROME_USB_LEDCOUNT_CFG;
// WriteHeader(zonecmd, zonecfg, sizeof(zonecfg));
}
void RGBController_PolychromeUSB::DeviceUpdateLEDs()
{
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
unsigned char set_mode = zones_info[zone_idx].mode;
if (set_mode>modes.size())
{
set_mode = active_mode;
}
polychrome->WriteZone(zone_idx, set_mode, zones_info[zone_idx].speed, zones[zone_idx].colors[0], false);
}
}
void RGBController_PolychromeUSB::UpdateZoneLEDs(int zone)
{
unsigned char set_mode=zones_info[zone].mode;
if(set_mode > modes.size())
{
set_mode = active_mode;
}
polychrome->WriteZone(zone, set_mode, zones_info[zone].speed, zones[zone].colors[0], false);
}
void RGBController_PolychromeUSB::UpdateSingleLED(int led)
{
unsigned int channel = leds[led].value;
unsigned char set_mode = zones_info[channel].mode;
if(set_mode > modes.size())
{
set_mode = active_mode;
}
polychrome->WriteZone(channel, set_mode, zones_info[channel].speed, zones[channel].colors[0], false);
}
unsigned char RGBController_PolychromeUSB::GetDeviceMode(unsigned char zone)
{
int dev_mode;
dev_mode = polychrome->GetZoneConfig(zone).mode;
active_mode = dev_mode;
return(active_mode);
}
void RGBController_PolychromeUSB::SetCustomMode()
{
active_mode = POLYCHROME_USB_MODE_STATIC;
}
void RGBController_PolychromeUSB::DeviceUpdateMode()
{
for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
if(zones[zone_idx].leds_count > 0)
{
unsigned char set_mode =(unsigned char) modes[active_mode].value;
zones_info[zone_idx].mode =(unsigned char) modes[active_mode].value;
zones_info[zone_idx].speed =(unsigned char) modes[active_mode].speed;
if(set_mode > modes.size())
{
set_mode = active_mode;
}
polychrome->WriteZone(zone_idx, set_mode, zones_info[zone_idx].speed, zones[zone_idx].colors[0], false);
}
}
}
@@ -1,37 +0,0 @@
/*-----------------------------------------*\
| RGBController_ASRockPolychromeUSB.h |
| |
| Generic RGB Interface for OpenRGB |
| ASRock Polychrome USB Driver |
| |
| Ed Kambulow (Dredvard) 12/26/2020 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "ASRockPolychromeUSBController.h"
class RGBController_PolychromeUSB : public RGBController
{
public:
RGBController_PolychromeUSB(PolychromeUSBController* polychrome_ptr);
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
bool initializedMode;
PolychromeUSBController* polychrome;
std::vector<PolychromeZoneInfo> zones_info;
unsigned char GetDeviceMode(unsigned char zone);
};
@@ -1,122 +0,0 @@
/*-----------------------------------------*\
| AnnePro2Controller.cpp |
| |
| Driver for Obins Lab AnnePro2 keyboard |
| |
| Sergey Gavrilov (DrZlo13) 06/06/2021 |
\*-----------------------------------------*/
#include "AnnePro2Controller.h"
using namespace std::chrono_literals;
AnnePro2Controller::AnnePro2Controller(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
AnnePro2Controller::~AnnePro2Controller()
{
hid_close(dev);
}
std::string AnnePro2Controller::GetDeviceLocation()
{
return("HID: " + location);
}
std::string AnnePro2Controller::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void AnnePro2Controller::SendDirect(unsigned char frame_count, unsigned char * frame_data)
{
/*-------------------------------------------------------------*\
| Reverse engineered by https://github.com/manualmanul/Annemone |
\*-------------------------------------------------------------*/
const unsigned char hid_cmd_service_data_length = 4;
const unsigned char hid_cmd_service_data[hid_cmd_service_data_length] = {0, 123, 16, 65};
const unsigned char hid_cmd_static_message_length = 3;
const unsigned char hid_cmd_static_message[hid_cmd_static_message_length] = {0, 0, 125};
const unsigned char hid_cmd_command_info_length = 3;
const unsigned char hid_cmd_command_info[hid_cmd_command_info_length] = {32, 3, 255};
const unsigned char real_command_info_length = hid_cmd_command_info_length + 1;
const unsigned char max_hid_length = 64;
const unsigned char max_command_length = max_hid_length - hid_cmd_service_data_length - 2 - hid_cmd_static_message_length;
const unsigned char max_message_length = max_command_length - real_command_info_length;
const unsigned char messages_to_send_amount = frame_count / max_message_length + 1;
const unsigned char val_1 = frame_count % max_message_length;
const unsigned char val_2 = (0 == val_1) ? max_message_length : val_1;
unsigned char hid_command[max_hid_length];
unsigned char led_data = 0;
for(unsigned char p = 0; p < messages_to_send_amount; p++)
{
const unsigned char e = (messages_to_send_amount << 4) + p;
const unsigned char a = ((messages_to_send_amount - 1) == p) ? val_2 + real_command_info_length : max_message_length + real_command_info_length;
/*---------------------------------------------------------*\
| Service data |
\*---------------------------------------------------------*/
hid_command[0] = hid_cmd_service_data[0];
hid_command[1] = hid_cmd_service_data[1];
hid_command[2] = hid_cmd_service_data[2];
hid_command[3] = hid_cmd_service_data[3];
hid_command[4] = e;
hid_command[5] = a;
/*---------------------------------------------------------*\
| Static message |
\*---------------------------------------------------------*/
hid_command[6] = hid_cmd_static_message[0];
hid_command[7] = hid_cmd_static_message[1];
hid_command[8] = hid_cmd_static_message[2];
/*---------------------------------------------------------*\
| Command info |
\*---------------------------------------------------------*/
hid_command[9] = hid_cmd_command_info[0];
hid_command[10] = hid_cmd_command_info[1];
hid_command[11] = hid_cmd_command_info[2];
hid_command[12] = 2;
/*---------------------------------------------------------*\
| LED data |
\*---------------------------------------------------------*/
for(uint8_t i = 0; i < max_message_length; i++)
{
hid_command[13 + i] = frame_data[led_data];
led_data++;
}
hid_write(dev, hid_command, max_hid_length);
/*---------------------------------------------------------*\
| Needed due to Anne Pro 2 ignoring commands when they're |
| sent faster than 50ms apart from each other. |
\*---------------------------------------------------------*/
std::this_thread::sleep_for(50ms);
}
}
@@ -1,36 +0,0 @@
/*-----------------------------------------*\
| AnnePro2Controller.h |
| |
| Driver for Obins Lab AnnePro2 keyboard |
| |
| Sergey Gavrilov (DrZlo13) 06/06/2021 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include <string>
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
class AnnePro2Controller
{
public:
AnnePro2Controller(hid_device* dev_handle, const char* path);
~AnnePro2Controller();
std::string GetDeviceLocation();
std::string GetSerialString();
void SendDirect
(
unsigned char frame_count,
unsigned char * frame_data
);
private:
hid_device* dev;
std::string location;
};
@@ -1,36 +0,0 @@
#include "Detector.h"
#include "AnnePro2Controller.h"
#include "RGBController.h"
#include "RGBController_AnnePro2.h"
#include <hidapi/hidapi.h>
#define ANNE_PRO_2_VID 0x04D9
#define ANNE_PRO_2_PID_1 0x8008
#define ANNE_PRO_2_PID_2 0x8009
#define ANNE_PRO_2_PID_3 0xA292
#define ANNE_PRO_2_PID_4 0xA293
/******************************************************************************************\
* *
* DetectAnnePro2Controllers *
* *
* Tests the USB address to see if an Obins Lab AnnePro2 keyboard exists there. *
* *
\******************************************************************************************/
void DetectAnnePro2Controllers(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
if( dev )
{
AnnePro2Controller* controller = new AnnePro2Controller(dev, info->path);
RGBController_AnnePro2* rgb_controller = new RGBController_AnnePro2(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR_I("Anne Pro 2", DetectAnnePro2Controllers, ANNE_PRO_2_VID, ANNE_PRO_2_PID_1, 1);
REGISTER_HID_DETECTOR_I("Anne Pro 2", DetectAnnePro2Controllers, ANNE_PRO_2_VID, ANNE_PRO_2_PID_2, 1);
REGISTER_HID_DETECTOR_I("Anne Pro 2", DetectAnnePro2Controllers, ANNE_PRO_2_VID, ANNE_PRO_2_PID_3, 1);
REGISTER_HID_DETECTOR_I("Anne Pro 2", DetectAnnePro2Controllers, ANNE_PRO_2_VID, ANNE_PRO_2_PID_4, 1);
@@ -1,235 +0,0 @@
/*-----------------------------------------*\
| RGBController_AnnePro2.cpp |
| |
| Generic RGB Interface for Obins Lab |
| AnnePro2 keyboard |
| |
| Sergey Gavrilov (DrZlo13) 06/06/2021 |
\*-----------------------------------------*/
#include "RGBController_AnnePro2.h"
#define NA 0xFFFFFFFF
#define LED_REAL_COUNT (5*14)
#define LED_COUNT (LED_REAL_COUNT - 9)
static unsigned int matrix_map[5][14] =
{ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
{ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 },
{ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, NA },
{ 41, NA, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, NA },
{ 53, NA, 54, 55, NA, NA, 56, NA, NA, 57, 58, 59, 60, NA } };
static const char* zone_names[] =
{
"Keyboard",
};
static zone_type zone_types[] =
{
ZONE_TYPE_MATRIX
};
static const unsigned int zone_sizes[] =
{
LED_COUNT,
};
typedef struct
{
const char * name;
const unsigned char idx;
} led_type;
static const led_type led_names[] =
{
/* Key Label Index */
{ "Key: Escape", 0 },
{ "Key: 1", 1 },
{ "Key: 2", 2 },
{ "Key: 3", 3 },
{ "Key: 4", 4 },
{ "Key: 5", 5 },
{ "Key: 6", 6 },
{ "Key: 7", 7 },
{ "Key: 8", 8 },
{ "Key: 9", 9 },
{ "Key: 0", 10 },
{ "Key: -", 11 },
{ "Key: =", 12 },
{ "Key: Backspace", 13 },
{ "Key: Tab", 14 },
{ "Key: Q", 15 },
{ "Key: W", 16 },
{ "Key: E", 17 },
{ "Key: R", 18 },
{ "Key: T", 19 },
{ "Key: Y", 20 },
{ "Key: U", 21 },
{ "Key: I", 22 },
{ "Key: O", 23 },
{ "Key: P", 24 },
{ "Key: [", 25 },
{ "Key: ]", 26 },
{ "Key: \\ (ANSI)", 27 },
{ "Key: Caps Lock", 28 },
{ "Key: A", 29 },
{ "Key: S", 30 },
{ "Key: D", 31 },
{ "Key: F", 32 },
{ "Key: G", 33 },
{ "Key: H", 34 },
{ "Key: J", 35 },
{ "Key: K", 36 },
{ "Key: L", 37 },
{ "Key: ;", 38 },
{ "Key: '", 39 },
{ "Key: Enter", 40 },
{ "Key: Left Shift", 41 },
{ "Key: Z", 42 },
{ "Key: X", 43 },
{ "Key: C", 44 },
{ "Key: V", 45 },
{ "Key: B", 46 },
{ "Key: N", 47 },
{ "Key: M", 48 },
{ "Key: ,", 49 },
{ "Key: .", 50 },
{ "Key: /", 51 },
{ "Key: Right Shift", 52 },
{ "Key: Left Control", 53 },
{ "Key: Left Windows", 54 },
{ "Key: Left Alt", 55 },
{ "Key: Space", 56 },
{ "Key: Right Alt", 57 },
{ "Key: Right Fn", 58 },
{ "Key: Menu", 59 },
{ "Key: Right Control", 60 },
};
RGBController_AnnePro2::RGBController_AnnePro2(AnnePro2Controller* annepro2_ptr)
{
annepro2 = annepro2_ptr;
name = "Anne Pro 2";
vendor = "Obinslab";
type = DEVICE_TYPE_KEYBOARD;
description = "Obinslab Anne Pro 2 Device";
location = annepro2->GetDeviceLocation();
serial = annepro2->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = 0;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
SetupZones();
}
RGBController_AnnePro2::~RGBController_AnnePro2()
{
delete annepro2;
}
void RGBController_AnnePro2::SetupZones()
{
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
unsigned int total_led_count = 0;
for(unsigned int zone_idx = 0; zone_idx < 1; zone_idx++)
{
zone new_zone;
new_zone.name = zone_names[zone_idx];
new_zone.type = zone_types[zone_idx];
new_zone.leds_min = zone_sizes[zone_idx];
new_zone.leds_max = zone_sizes[zone_idx];
new_zone.leds_count = zone_sizes[zone_idx];
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
{
new_zone.matrix_map = new matrix_map_type;
new_zone.matrix_map->height = 5;
new_zone.matrix_map->width = 14;
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
}
else
{
new_zone.matrix_map = NULL;
}
zones.push_back(new_zone);
total_led_count += zone_sizes[zone_idx];
}
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
{
led new_led;
new_led.name = led_names[led_idx].name;
new_led.value = led_names[led_idx].idx;
leds.push_back(new_led);
}
SetupColors();
}
void RGBController_AnnePro2::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_AnnePro2::DeviceUpdateLEDs()
{
const unsigned char frame_buf_length = LED_REAL_COUNT * 3;
unsigned char frame_buf[frame_buf_length];
/*---------------------------------------------------------*\
| TODO: Send packets with multiple LED frames |
\*---------------------------------------------------------*/
std::size_t led_real_idx = 0;
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
frame_buf[(led_real_idx * 3) + 0] = RGBGetRValue(colors[led_idx]);
frame_buf[(led_real_idx * 3) + 1] = RGBGetGValue(colors[led_idx]);
frame_buf[(led_real_idx * 3) + 2] = RGBGetBValue(colors[led_idx]);
if(led_idx == 40 || led_idx == 41 || led_idx == 52 || led_idx == 53 || led_idx == 60)
{
led_real_idx++;
}
else if(led_idx == 55 || led_idx == 56)
{
led_real_idx++;
led_real_idx++;
}
led_real_idx++;
}
annepro2->SendDirect(frame_buf_length, frame_buf);
}
void RGBController_AnnePro2::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_AnnePro2::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_AnnePro2::SetCustomMode()
{
active_mode = 0;
}
void RGBController_AnnePro2::DeviceUpdateMode()
{
}
@@ -1,32 +0,0 @@
/*-----------------------------------------*\
| RGBController_AnnePro2.h |
| |
| Generic RGB Interface for Obins Lab |
| AnnePro2 keyboard |
| |
| Sergey Gavrilov (DrZlo13) 06/06/2021 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "AnnePro2Controller.h"
class RGBController_AnnePro2 : public RGBController
{
public:
RGBController_AnnePro2(AnnePro2Controller* annepro2_ptr);
~RGBController_AnnePro2();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
AnnePro2Controller* annepro2;
};
@@ -1,410 +0,0 @@
/*-----------------------------------------*\
| AsusAuraCoreController.cpp |
| |
| Driver for ASUS ROG Aura Core RGB |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 4/13/2020 |
\*-----------------------------------------*/
#include "AsusAuraCoreController.h"
#include <cstring>
#define AURA_CORE_MAX_MESSAGE_SIZE 64
AuraCoreController::AuraCoreController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
aura_device.aura_type = AURA_CORE_DEVICE_UNKNOWN;
aura_device.buff_size = 0;
aura_device.report_id = 0x5D;
aura_device.num_leds = 4;
aura_device.supports_direct = false;
IdentifyDevice();
Handshake();
}
AuraCoreController::~AuraCoreController()
{
hid_close(dev);
}
std::string AuraCoreController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string AuraCoreController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void AuraCoreController::SendBrightness
(
unsigned char brightness
)
{
unsigned char usb_buf[AURA_CORE_MAX_MESSAGE_SIZE];
if(aura_device.aura_type != AURA_CORE_DEVICE_UNKNOWN)
{
/*-----------------------------------------------------*\
| 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, aura_device.buff_size);
}
}
void AuraCoreController::SendUpdate
(
unsigned char zone,
unsigned char mode,
unsigned char speed,
unsigned char dir,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
unsigned char usb_buf[AURA_CORE_MAX_MESSAGE_SIZE];
if(aura_device.aura_type != AURA_CORE_DEVICE_UNKNOWN)
{
if(aura_device.aura_type == AURA_CORE_DEVICE_KEYBOARD)
{
zone += 1;
}
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = aura_device.report_id;
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;
usb_buf[0x08] = dir;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, aura_device.buff_size);
}
}
void AuraCoreController::SendSet()
{
unsigned char usb_buf[AURA_CORE_MAX_MESSAGE_SIZE];
if(aura_device.aura_type != AURA_CORE_DEVICE_UNKNOWN)
{
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = aura_device.report_id;
usb_buf[0x01] = AURA_CORE_COMMAND_SET;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, aura_device.buff_size);
}
}
void AuraCoreController::SendApply()
{
unsigned char usb_buf[AURA_CORE_MAX_MESSAGE_SIZE];
if(aura_device.aura_type != AURA_CORE_DEVICE_UNKNOWN)
{
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = aura_device.report_id;
usb_buf[0x01] = AURA_CORE_COMMAND_APPLY;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, aura_device.buff_size);
}
}
void AuraCoreController::InitDirectMode()
{
unsigned char usb_buf[AURA_CORE_MAX_MESSAGE_SIZE];
unsigned char msg_num = 0;
int led_count = aura_device.num_leds;
if(aura_device.supports_direct)
{
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = aura_device.report_id;
usb_buf[0x01] = AURA_CORE_COMMAND_DIRECT;
usb_buf[0x02] = 0xD0;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, aura_device.buff_size);
while(led_count > 0)
{
/*-----------------------------------------------------*\
| Set up second message packet |
\*-----------------------------------------------------*/
usb_buf[0x03] = 0x01;
usb_buf[0x04] = 0x02;
usb_buf[0x05] = 0x00;
usb_buf[0x06] = msg_num++;
usb_buf[0x07] = (led_count > aura_device.max_leds_per_message) ? aura_device.max_leds_per_message : led_count;
usb_buf[0x08] = 0x00;
/*-----------------------------------------------------*\
| Send packet 2 |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, aura_device.buff_size);
led_count -= aura_device.max_leds_per_message;
}
}
}
void AuraCoreController::UpdateDirect(std::vector<AuraColor>& color_set)
{
unsigned char usb_buf[AURA_CORE_MAX_MESSAGE_SIZE];
unsigned char msg_num = 0;
unsigned char color_index = 0;
unsigned char set_count = 0;
int led_count = aura_device.num_leds;
if(aura_device.supports_direct)
{
while(led_count > 0)
{
unsigned char msg_index = 0x09;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = aura_device.report_id;
usb_buf[0x01] = AURA_CORE_COMMAND_DIRECT;
usb_buf[0x02] = 0xD0;
usb_buf[0x03] = 0x01;
usb_buf[0x04] = 0x02;
usb_buf[0x05] = 0x00;
usb_buf[0x06] = msg_num++;
usb_buf[0x07] = (led_count > aura_device.max_leds_per_message) ? aura_device.max_leds_per_message : led_count;
usb_buf[0x08] = 0x00;
set_count = 0;
while( (msg_index < sizeof(usb_buf) ) &&
(led_count > 0 ) &&
(set_count < aura_device.max_leds_per_message) )
{
if(color_index < color_set.size())
{
usb_buf[msg_index++] = color_set[color_index].red;
usb_buf[msg_index++] = color_set[color_index].green;
usb_buf[msg_index++] = color_set[color_index].blue;
}
else
{
usb_buf[msg_index++] = 0;
usb_buf[msg_index++] = 0;
usb_buf[msg_index++] = 0;
}
led_count--;
color_index++;
set_count++;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, aura_device.buff_size);
}
}
}
void AuraCoreController::IdentifyDevice()
{
unsigned char usb_buf[AURA_CORE_MAX_MESSAGE_SIZE];
int num_bytes = 0;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| First, attempt to read the report from the Keyboard |
\*-----------------------------------------------------*/
usb_buf[0x00] = aura_device.report_id;
num_bytes = hid_get_feature_report(dev, usb_buf, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Currently, there is no need to attempt to read the |
| returned data. If the device responded,to the report,|
| we're good. |
\*-----------------------------------------------------*/
if(num_bytes > 0)
{
aura_device.aura_type = AURA_CORE_DEVICE_KEYBOARD;
aura_device.buff_size = 17;
aura_device.report_id = 0x5D;
aura_device.num_leds = 4;
aura_device.supports_direct = false;
}
else if(num_bytes == -1)
{
/*-------------------------------------------------*\
| First, attempt to read the report from the |
| Keyboard |
\*-------------------------------------------------*/
usb_buf[0] = 0x5E;
num_bytes = hid_get_feature_report(dev, usb_buf, sizeof(usb_buf));
if(num_bytes > 0)
{
/*---------------------------------------------*\
| Currently, there is no need to attempt to |
| read the returned data. If the device |
| responded,to the report, we're good. |
\*---------------------------------------------*/
aura_device.aura_type = AURA_CORE_DEVICE_GA15DH;
aura_device.buff_size = 64;
aura_device.report_id = 0x5E;
aura_device.num_leds = 20;
aura_device.max_leds_per_message = 16;
aura_device.supports_direct = true;
}
}
}
void AuraCoreController::Handshake()
{
unsigned char usb_buf[AURA_CORE_MAX_MESSAGE_SIZE];
if(aura_device.aura_type == AURA_CORE_DEVICE_GA15DH)
{
usb_buf[0] = 0x5E;
SendIdString();
hid_get_feature_report(dev, usb_buf, sizeof(usb_buf));
SendQuery();
hid_get_feature_report(dev, usb_buf, sizeof(usb_buf));
}
}
void AuraCoreController::SendIdString()
{
unsigned char usb_buf[AURA_CORE_MAX_MESSAGE_SIZE];
const char id[] = "ASUS Tech.Inc.";
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = aura_device.report_id;
/*-----------------------------------------------------*\
| Copy in string data |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x01], id, sizeof(id));
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, aura_device.buff_size);
}
void AuraCoreController::SendQuery()
{
unsigned char usb_buf[AURA_CORE_MAX_MESSAGE_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = aura_device.report_id;
usb_buf[0x01] = 0x05;
usb_buf[0x02] = 0x20;
usb_buf[0x03] = 0x31;
usb_buf[0x04] = 0x00;
usb_buf[0x05] = 0x10;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, usb_buf, aura_device.buff_size);
}
@@ -1,34 +0,0 @@
#include "Detector.h"
#include "AsusAuraCoreController.h"
#include "RGBController.h"
#include "RGBController_AsusAuraCore.h"
#include <hidapi/hidapi.h>
#define AURA_CORE_VID 0x0B05
/******************************************************************************************\
* *
* DetectAuraCoreControllers *
* *
* Tests the USB address to see if an Asus ROG Aura Core controller exists there *
* *
\******************************************************************************************/
void DetectAsusAuraCoreControllers(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
if( dev )
{
AuraCoreController* controller = new AuraCoreController(dev, info->path);
RGBController_AuraCore* rgb_controller = new RGBController_AuraCore(controller);
// Constructor sets the name
if(rgb_controller->type != DEVICE_TYPE_UNKNOWN)
{
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
}
REGISTER_HID_DETECTOR("ASUS Aura Core", DetectAsusAuraCoreControllers, AURA_CORE_VID, 0x1854);
REGISTER_HID_DETECTOR("ASUS Aura Core", DetectAsusAuraCoreControllers, AURA_CORE_VID, 0x1866);
REGISTER_HID_DETECTOR("ASUS Aura Core", DetectAsusAuraCoreControllers, AURA_CORE_VID, 0x1869);
@@ -1,319 +0,0 @@
/*-----------------------------------------*\
| RGBController_AsusAuraCore.cpp |
| |
| Generic RGB Interface for ROG Aura Core |
| |
| Adam Honse (CalcProgrammer1) 4/17/2020 |
\*-----------------------------------------*/
#include "RGBController_AsusAuraCore.h"
RGBController_AuraCore::RGBController_AuraCore(AuraCoreController* aura_ptr)
{
aura = aura_ptr;
name = "ASUS Aura Core Device";
vendor = "ASUS";
location = aura->GetDeviceLocation();
serial = aura->GetSerialString();
description = "ASUS Aura Core Device";
type = DEVICE_TYPE_UNKNOWN;
if(aura->aura_device.aura_type == AURA_CORE_DEVICE_KEYBOARD)
{
SetupKeyboard();
}
else if(aura->aura_device.aura_type == AURA_CORE_DEVICE_GA15DH)
{
SetupGA15DH();
}
SetupZones();
}
void RGBController_AuraCore::SetupKeyboard()
{
name = "ASUS Aura Keyboard";
vendor = "ASUS";
type = DEVICE_TYPE_KEYBOARD;
description = "ASUS Aura Core Device";
mode Static;
Static.name = "Static";
Static.value = AURA_CORE_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = AURA_CORE_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
mode ColorCycle;
ColorCycle.name = "Color Cycle";
ColorCycle.value = AURA_CORE_MODE_SPECTRUM_CYCLE;
ColorCycle.flags = 0;
ColorCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(ColorCycle);
}
void RGBController_AuraCore::SetupGA15DH()
{
name = "ASUS Aura GA15DH";
vendor = "ASUS";
type = DEVICE_TYPE_LEDSTRIP;
description = "ASUS Aura Core Device";
mode Static;
Static.name = "Static";
Static.value = AURA_CORE_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.colors_min = 1;
Static.colors_max = 1;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors.resize(1);
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = AURA_CORE_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Breathing.speed_min = AURA_CORE_SPEED_SLOW;
Breathing.speed_max = AURA_CORE_SPEED_FAST;
Breathing.speed = AURA_CORE_SPEED_NORMAL;
Breathing.colors_min = 1;
Breathing.colors_max = 2;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors.resize(2);
modes.push_back(Breathing);
mode ColorCycle;
ColorCycle.name = "Color Cycle";
ColorCycle.value = AURA_CORE_MODE_SPECTRUM_CYCLE;
ColorCycle.flags = MODE_FLAG_HAS_SPEED;
ColorCycle.speed_min = AURA_CORE_SPEED_SLOW;
ColorCycle.speed_max = AURA_CORE_SPEED_FAST;
ColorCycle.speed = AURA_CORE_SPEED_NORMAL;
ColorCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(ColorCycle);
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = AURA_CORE_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR;
Rainbow.speed_min = AURA_CORE_SPEED_SLOW;
Rainbow.speed_max = AURA_CORE_SPEED_FAST;
Rainbow.speed = AURA_CORE_SPEED_NORMAL;
Rainbow.direction = MODE_DIRECTION_RIGHT;
Rainbow.color_mode = MODE_COLORS_NONE;
modes.push_back(Rainbow);
mode Strobe;
Strobe.name = "Strobe";
Strobe.value = AURA_CORE_MODE_STROBE;
Strobe.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Strobe.colors_min = 1;
Strobe.colors_max = 1;
Strobe.color_mode = MODE_COLORS_MODE_SPECIFIC;
Strobe.colors.resize(1);
modes.push_back(Strobe);
mode Comet;
Comet.name = "Comet";
Comet.value = AURA_CORE_MODE_COMET;
Comet.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Comet.colors_min = 1;
Comet.colors_max = 1;
Comet.color_mode = MODE_COLORS_MODE_SPECIFIC;
Comet.colors.resize(1);
modes.push_back(Comet);
mode Flash;
Flash.name = "Flash & Dash";
Flash.value = AURA_CORE_MODE_FLASHNDASH;
Flash.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Flash.colors_min = 1;
Flash.colors_max = 1;
Flash.color_mode = MODE_COLORS_MODE_SPECIFIC;
Flash.colors.resize(1);
modes.push_back(Flash);
mode Irradiation;
Irradiation.name = "Irradiation";
Irradiation.value = AURA_CORE_MODE_IRRADIATION;
Irradiation.flags = 0;
Irradiation.color_mode = MODE_COLORS_NONE;
modes.push_back(Irradiation);
mode Direct;
Static.name = "Direct";
Static.value = AURA_CORE_MODE_DIRECT;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
}
RGBController_AuraCore::~RGBController_AuraCore()
{
delete aura;
}
void RGBController_AuraCore::SetupZones()
{
zone auraZone;
if(aura->aura_device.aura_type == AURA_CORE_DEVICE_KEYBOARD)
{
auraZone.name = "Keyboard";
auraZone.type = ZONE_TYPE_SINGLE;
auraZone.leds_min = 4;
auraZone.leds_max = 4;
auraZone.leds_count = 4;
auraZone.matrix_map = NULL;
}
else if(aura->aura_device.aura_type == AURA_CORE_DEVICE_GA15DH)
{
auraZone.name = "GA15DH";
auraZone.type = ZONE_TYPE_LINEAR;
auraZone.leds_min = 20;
auraZone.leds_max = 20;
auraZone.leds_count = 20;
auraZone.matrix_map = NULL;
}
else
{
auraZone.leds_count = 0;
}
zones.push_back(auraZone);
for(unsigned int led_idx = 0; led_idx < auraZone.leds_count; led_idx++)
{
led KeyLED;
KeyLED.name = auraZone.name + " ";
KeyLED.name.append(std::to_string(led_idx + 1));
leds.push_back(KeyLED);
}
SetupColors();
}
void RGBController_AuraCore::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_AuraCore::DeviceUpdateLEDs()
{
UpdateZoneLEDs(0);
}
void RGBController_AuraCore::UpdateZoneLEDs(int /*zone*/)
{
if(modes[active_mode].value == AURA_CORE_MODE_DIRECT)
{
std::vector<AuraColor> aura_colors;
std::vector<RGBColor>& color_set = colors;
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
color_set = modes[active_mode].colors;
}
for(unsigned int led_idx = 0; led_idx < leds.size(); led_idx++)
{
AuraColor new_color;
new_color.red = RGBGetRValue(color_set[led_idx]);
new_color.green = RGBGetGValue(color_set[led_idx]);
new_color.blue = RGBGetBValue(color_set[led_idx]);
aura_colors.push_back(new_color);
}
aura->UpdateDirect(aura_colors);
}
else if(modes[active_mode].color_mode == MODE_COLORS_PER_LED)
{
for(unsigned int led_idx = 0; led_idx < leds.size(); led_idx++)
{
UpdateSingleLED(led_idx);
}
}
else
{
UpdateSingleLED(0);
}
}
void RGBController_AuraCore::UpdateSingleLED(int led)
{
unsigned char speed = 0xFF;
unsigned char red = 0;
unsigned char green = 0;
unsigned char blue = 0;
unsigned char dir = 0;
mode& curr_mode = modes[active_mode];
if(curr_mode.color_mode == MODE_COLORS_PER_LED)
{
red = RGBGetRValue(colors[led]);
green = RGBGetGValue(colors[led]);
blue = RGBGetBValue(colors[led]);
}
else if(curr_mode.color_mode == MODE_COLORS_MODE_SPECIFIC)
{
red = RGBGetRValue(curr_mode.colors[led]);
green = RGBGetGValue(curr_mode.colors[led]);
blue = RGBGetBValue(curr_mode.colors[led]);
}
if(curr_mode.flags & MODE_FLAG_HAS_SPEED)
{
speed = curr_mode.speed;
}
if(curr_mode.flags & MODE_FLAG_HAS_DIRECTION_LR)
{
if(curr_mode.direction == MODE_DIRECTION_RIGHT)
{
dir = 1;
}
}
aura->SendUpdate
(
led,
curr_mode.value,
speed,
dir,
red,
green,
blue
);
aura->SendSet();
aura->SendApply();
}
void RGBController_AuraCore::SetCustomMode()
{
active_mode = 0;
}
void RGBController_AuraCore::DeviceUpdateMode()
{
if(modes[active_mode].value == AURA_CORE_MODE_DIRECT)
{
aura->InitDirectMode();
}
else
{
DeviceUpdateLEDs();
}
}
@@ -1,114 +0,0 @@
/*-----------------------------------------*\
| AsusAuraGPUControllerDetect.cpp |
| |
| Driver for ASUS Aura RGB on GPUs |
| |
| Jan Rettig (Klapstuhl) 14.02.2020 |
\*-----------------------------------------*/
#include "Detector.h"
#include "AsusAuraGPUController.h"
#include "RGBController.h"
#include "RGBController_AsusAuraGPU.h"
#include "i2c_smbus.h"
#include "pci_ids.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std::chrono_literals;
typedef struct
{
int pci_vendor;
int pci_device;
int pci_subsystem_vendor;
int pci_subsystem_device;
unsigned char controller_address;
const char * name;
} gpu_pci_device;
#define GPU_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
static const gpu_pci_device device_list[] =
{
{ NVIDIA_VEN, NVIDIA_GTX1060_DEV, ASUS_SUB_VEN, ASUS_GTX1060_STRIX, 0x29, "ASUS GTX 1060 Strix" },
{ NVIDIA_VEN, NVIDIA_GTX1070_DEV, ASUS_SUB_VEN, ASUS_GTX1070_STRIX_GAMING, 0x29, "ASUS GTX 1070 Strix Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1070_DEV, ASUS_SUB_VEN, ASUS_GTX1070_STRIX_OC, 0x29, "ASUS GTX 1070 Strix OC" },
{ NVIDIA_VEN, NVIDIA_GTX1080_DEV, ASUS_SUB_VEN, ASUS_GTX1080_STRIX, 0x29, "ASUS GTX 1080 Strix OC" },
{ NVIDIA_VEN, NVIDIA_GTX1080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080_A8G_GAMING, 0x29, "ASUS ROG Strix GTX1080 A8G Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080_O8G_GAMING, 0x29, "ASUS ROG Strix GTX1080 O8G Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1080TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080TI_GAMING, 0x29, "ASUS ROG Strix GTX1080 Ti Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1660TI_DEV, ASUS_SUB_VEN, ASUS_ROG_GTX1660TI_OC, 0x2A, "ASUS ROG GTX 1660 Ti OC 6G" },
{ NVIDIA_VEN, NVIDIA_RTX2060_TU106_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2060_EVO_GAMING, 0x2A, "ASUS ROG STRIX RTX 2060 EVO Gaming 6G" },
{ NVIDIA_VEN, NVIDIA_RTX2060S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2060S_A8G_EVO_GAMING, 0x2A, "ASUS ROG STRIX RTX 2060S A8G EVO Gaming 6G"},
{ NVIDIA_VEN, NVIDIA_RTX2070_OC_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2070_A8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2070 A8G Gaming 8G" },
{ NVIDIA_VEN, NVIDIA_RTX2070_OC_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2070_O8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2070 O8G Gaming 8G" },
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2070S_A8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2070S A8G Gaming 8G" },
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2070S_O8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2070S O8G Gaming 8G" },
{ NVIDIA_VEN, NVIDIA_RTX2080_A_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2080_O8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2080 O8G Gaming" },
{ NVIDIA_VEN, NVIDIA_RTX2080TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2080TI_O11G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2080 Ti O11G Gaming" },
{ AMD_GPU_VEN, AMD_VEGA10_DEV, ASUS_SUB_VEN, ASUS_VEGA64_STRIX, 0x29, "ASUS Vega 64 Strix" },
{ AMD_GPU_VEN, AMD_NAVI10_DEV, ASUS_SUB_VEN, ASUS_RX5700XT_STRIX_GAMING_OC, 0x2A, "ASUS RX 5700XT Strix Gaming OC" },
{ AMD_GPU_VEN, AMD_POLARIS_DEV, ASUS_SUB_VEN, ASUS_RX580_STRIX_GAMING_OC, 0x29, "ASUS RX 580 Strix Gaming OC" }
};
/******************************************************************************************\
* *
* TestForAuraGPUController *
* *
* Tests the given address to see if an Aura GPU controller exists there. *
* *
\******************************************************************************************/
bool TestForAsusAuraGPUController(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 DetectAsusAuraGPUControllers(std::vector<i2c_smbus_interface*> &busses)
{
AuraGPUController* new_aura_gpu;
RGBController_AuraGPU* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
for(unsigned int dev_idx = 0; dev_idx < GPU_NUM_DEVICES; dev_idx++)
{
if(busses[bus]->pci_vendor == device_list[dev_idx].pci_vendor &&
busses[bus]->pci_device == device_list[dev_idx].pci_device &&
busses[bus]->pci_subsystem_vendor == device_list[dev_idx].pci_subsystem_vendor &&
busses[bus]->pci_subsystem_device == device_list[dev_idx].pci_subsystem_device)
{
if (TestForAsusAuraGPUController(busses[bus], device_list[dev_idx].controller_address))
{
new_aura_gpu = new AuraGPUController(busses[bus], device_list[dev_idx].controller_address);
new_controller = new RGBController_AuraGPU(new_aura_gpu);
new_controller->name = device_list[dev_idx].name;
ResourceManager::get()->RegisterRGBController(new_controller);
}
}
}
}
} /* DetectAsusAuraGPUControllers() */
REGISTER_I2C_DETECTOR("ASUS Aura GPU", DetectAsusAuraGPUControllers);
@@ -1,115 +0,0 @@
/*-----------------------------------------*\
| AsusAuraKeyboardController.cpp |
| |
| Driver for ASUS Aura RGB USB |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 3/19/2020 |
\*-----------------------------------------*/
#include "AsusAuraKeyboardController.h"
#include <cstring>
AuraKeyboardController::AuraKeyboardController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
AuraKeyboardController::~AuraKeyboardController()
{
hid_close(dev);
}
std::string AuraKeyboardController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string AuraKeyboardController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void AuraKeyboardController::SendDirect
(
unsigned char frame_count,
unsigned char * frame_data
)
{
unsigned char usb_buf[65];
unsigned int packet_count = frame_count / 15 + (((frame_count % 15) == 0) ? 0 : 1);
unsigned int total_frame_idx = 0;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0xC0;
usb_buf[0x02] = 0x81;
usb_buf[0x03] = packet_count * 15;
usb_buf[0x04] = 0x00;
/*-----------------------------------------------------*\
| Copy in frame data and send packets until all data |
| has been sent |
\*-----------------------------------------------------*/
for(unsigned int packet_idx = 0; packet_idx < packet_count; packet_idx++)
{
unsigned int packet_data_size = 15 * 4;
if((frame_count - total_frame_idx) < 15)
{
packet_data_size = (frame_count - total_frame_idx) * 4;
memset(&usb_buf[0x05 + packet_data_size], 0xFF, (15*4) - packet_data_size);
}
memcpy(&usb_buf[0x05], &frame_data[packet_idx * 15 * 4], packet_data_size);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
/*-----------------------------------------------------*\
| Decrement remaining frame count |
\*-----------------------------------------------------*/
usb_buf[0x03] -= 0x0F;
total_frame_idx += 0x0F;
}
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0xC0;
usb_buf[0x02] = 0x81;
usb_buf[0x03] = 0x90;
/*-----------------------------------------------------*\
| Read to apply |
\*-----------------------------------------------------*/
hid_read(dev,usb_buf, 65);
}
@@ -1,36 +0,0 @@
/*-----------------------------------------*\
| AsusAuraKeyboardController.h |
| |
| Definitions and types for ASUS Aura |
| USB RGB lighting controller |
| |
| Adam Honse (CalcProgrammer1) 3/19/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
class AuraKeyboardController
{
public:
AuraKeyboardController(hid_device* dev_handle, const char* path);
virtual ~AuraKeyboardController();
std::string GetDeviceLocation();
std::string GetSerialString();
void SendDirect
(
unsigned char frame_count,
unsigned char * frame_data
);
private:
hid_device* dev;
std::string location;
};
@@ -1,80 +0,0 @@
/*-----------------------------------------*\
| AsusAuraMouseController.cpp |
| |
| Driver for ASUS Aura RGB USB |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 10/23/2020 |
\*-----------------------------------------*/
#include "AsusAuraMouseController.h"
#include <cstring>
AuraMouseController::AuraMouseController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
AuraMouseController::~AuraMouseController()
{
hid_close(dev);
}
std::string AuraMouseController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string AuraMouseController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void AuraMouseController::SendUpdate
(
unsigned char zone,
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] = 0x00;
usb_buf[0x01] = 0x51;
usb_buf[0x02] = 0x28;
usb_buf[0x03] = zone;
usb_buf[0x04] = 0x00;
usb_buf[0x05] = mode;
usb_buf[0x06] = 0x04;
usb_buf[0x07] = red;
usb_buf[0x08] = grn;
usb_buf[0x09] = blu;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
@@ -1,55 +0,0 @@
/*-----------------------------------------*\
| AsusAuraMouseController.h |
| |
| Definitions and types for ASUS Aura |
| USB RGB lighting controller |
| |
| Adam Honse (CalcProgrammer1) 10/23/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
enum
{
AURA_MOUSE_ZONE_LOGO = 0,
AURA_MOUSE_ZONE_SCROLL = 1,
AURA_MOUSE_ZONE_UNDERGLOW = 2,
AURA_MOUSE_ZONE_ALL = 3,
};
enum
{
AURA_MOUSE_MODE_STATIC = 0,
AURA_MOUSE_MODE_BREATHING = 1,
AURA_MOUSE_MODE_COLOR_CYCLE = 2,
AURA_MOUSE_MODE_REACTIVE = 3,
};
class AuraMouseController
{
public:
AuraMouseController(hid_device* dev_handle, const char* path);
virtual ~AuraMouseController();
std::string GetDeviceLocation();
std::string GetSerialString();
void SendUpdate
(
unsigned char zone,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
);
private:
hid_device* dev;
std::string location;
};
@@ -1,120 +0,0 @@
#include "Detector.h"
#include "AsusAuraAddressableController.h"
#include "AsusAuraKeyboardController.h"
#include "AsusAuraMainboardController.h"
#include "AsusAuraMouseController.h"
#include "RGBController.h"
#include "RGBController_AsusAuraUSB.h"
#include "RGBController_AsusAuraKeyboard.h"
#include "RGBController_AsusAuraMouse.h"
#include <stdexcept>
#include <hidapi/hidapi.h>
#include "dependencies/dmiinfo.h"
#define AURA_USB_VID 0x0B05
#define AURA_TERMINAL_PID 0x1889
#define AURA_ADDRESSABLE_1_PID 0x1867
#define AURA_ADDRESSABLE_2_PID 0x1872
#define AURA_ADDRESSABLE_3_PID 0x18A3
#define AURA_ADDRESSABLE_4_PID 0x18A5
#define AURA_MOTHERBOARD_1_PID 0x18F3
#define AURA_MOTHERBOARD_2_PID 0x1939
#define AURA_MOTHERBOARD_3_PID 0x19AF
#define AURA_ROG_GLADIUS_II_CORE_PID 0x18DD
#define AURA_ROG_GLADIUS_II_PID 0x1845
#define AURA_ROG_STRIX_FLARE_PID 0x1875
#define AURA_ROG_GLADIUS_II_ORIGIN_PID 0x1877
#define AURA_ROG_GLADIUS_II_ORIGIN_PNK_LTD_PID 0x18CD
#define AURA_ROG_STRIX_FLARE_PNK_LTD_PID 0x18CF
#define AURA_ROG_CHAKRAM_WIRELESS_PID 0x18E5
#define AURA_ROG_CHAKRAM_WIRED_1_PID 0x18E3
#define AURA_ROG_CHAKRAM_WIRED_2_PID 0x1958
void DetectAsusAuraUSBTerminal(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
AuraAddressableController* controller = new AuraAddressableController(dev, info->path);
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectAsusAuraUSBAddressable(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
DMIInfo dmi;
AuraAddressableController* controller = new AuraAddressableController(dev, info->path);
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
rgb_controller->name = "ASUS " + dmi.getMainboard() + " Addressable";
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectAsusAuraUSBMotherboards(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
try
{
DMIInfo dmi;
AuraMainboardController* controller = new AuraMainboardController(dev, info->path);
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
rgb_controller->name = "ASUS " + dmi.getMainboard();
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
catch(std::runtime_error&)
{
// reading the config table failed
}
}
}
void DetectAsusAuraUSBKeyboards(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
AuraKeyboardController* controller = new AuraKeyboardController(dev, info->path);
RGBController_AuraKeyboard* rgb_controller = new RGBController_AuraKeyboard(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectAsusAuraUSBMice(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
AuraMouseController* controller = new AuraMouseController(dev, info->path);
RGBController_AuraMouse* rgb_controller = new RGBController_AuraMouse(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR ("ASUS ROG AURA Terminal", DetectAsusAuraUSBTerminal, AURA_USB_VID, AURA_TERMINAL_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Addressable", DetectAsusAuraUSBAddressable, AURA_USB_VID, AURA_ADDRESSABLE_1_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Addressable", DetectAsusAuraUSBAddressable, AURA_USB_VID, AURA_ADDRESSABLE_2_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Addressable", DetectAsusAuraUSBAddressable, AURA_USB_VID, AURA_ADDRESSABLE_3_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Addressable", DetectAsusAuraUSBAddressable, AURA_USB_VID, AURA_ADDRESSABLE_4_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Motherboard", DetectAsusAuraUSBMotherboards, AURA_USB_VID, AURA_MOTHERBOARD_1_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Motherboard", DetectAsusAuraUSBMotherboards, AURA_USB_VID, AURA_MOTHERBOARD_2_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Motherboard", DetectAsusAuraUSBMotherboards, AURA_USB_VID, AURA_MOTHERBOARD_3_PID);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Core", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_CORE_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_PID, 2, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Origin", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_ORIGIN_PID, 2, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Origin PNK LTD", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_ORIGIN_PNK_LTD_PID, 2, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Chakram (Wireless)", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_CHAKRAM_WIRELESS_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("Asus ROG Chakram (Wired)", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_CHAKRAM_WIRED_1_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("Asus ROG Chakram (Wired)", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_CHAKRAM_WIRED_2_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Flare", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_FLARE_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Flare PNK LTD", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_FLARE_PNK_LTD_PID, 1, 0xFF00);
@@ -1,276 +0,0 @@
/*-----------------------------------------*\
| RGBController_AsusAuraKeyboard.cpp |
| |
| Generic RGB Interface for Asus Aura |
| USB controller driver |
| |
| Adam Honse (CalcProgrammer1) 3/19/2020 |
\*-----------------------------------------*/
#include "RGBController_AsusAuraKeyboard.h"
//0xFFFFFFFF indicates an unused entry in matrix
#define NA 0xFFFFFFFF
static unsigned int matrix_map[6][22] =
{ { 0, NA, 13, 18, 23, 28, 38, 43, 49, 54, 60, 65, 69, 70, NA, 76, 80, 85, NA, NA, NA, NA },
{ 1, 8, 14, 19, 24, 29, 34, 39, 44, 50, 55, 61, 66, 71, NA, 77, 81, 86, 89, 94, 98, 103 },
{ 2, NA, 9, 15, 20, 25, 30, 35, 40, 45, 51, 56, 62, 67, 72, 78, 82, 87, 90, 95, 99, 104 },
{ 3, NA, 10, 16, 21, 26, 31, 36, 41, 46, 52, 57, 63, 68, 73, NA, NA, NA, 91, 96, 100, NA },
{ 4, 6, 11, 17, 22, 27, 32, 37, 42, 47, 53, 58, NA, NA, 74, NA, 83, NA, 92, 97, 101, 105 },
{ 5, 7, 12, NA, NA, NA, NA, 33, NA, 48, NA, 59, 64, 75, NA, 79, 84, 88, 93, NA, 102, NA } };
static const char* zone_names[] =
{
"Keyboard",
"Logo",
"Underglow"
};
static zone_type zone_types[] =
{
ZONE_TYPE_MATRIX,
ZONE_TYPE_SINGLE,
ZONE_TYPE_SINGLE
};
static const unsigned int zone_sizes[] =
{
106,
1,
2,
};
typedef struct
{
const char * name;
const unsigned char idx;
} led_type;
static const led_type led_names[] =
{
/* Key Label Index */
{ "Key: Escape", 0x00 },
{ "Key: `", 0x01 },
{ "Key: Tab", 0x02 },
{ "Key: Caps Lock", 0x03 },
{ "Key: Left Shift", 0x04 },
{ "Key: Left Control", 0x05 },
{ "Key: \\ (ISO)", 0x0C },
{ "Key: Left Windows", 0x0D },
{ "Key: 1", 0x11 },
{ "Key: Q", 0x12 },
{ "Key: A", 0x13 },
{ "Key: Z", 0x14 },
{ "Key: Left Alt", 0x15 },
{ "Key: F1", 0x18 },
{ "Key: 2", 0x19 },
{ "Key: W", 0x1A },
{ "Key: S", 0x1B },
{ "Key: X", 0x1C },
{ "Key: F2", 0x20 },
{ "Key: 3", 0x21 },
{ "Key: E", 0x22 },
{ "Key: D", 0x23 },
{ "Key: C", 0x24 },
{ "Key: F3", 0x28 },
{ "Key: 4", 0x29 },
{ "Key: R", 0x2A },
{ "Key: F", 0x2B },
{ "Key: V", 0x2C },
{ "Key: F4", 0x30 },
{ "Key: 5", 0x31 },
{ "Key: T", 0x32 },
{ "Key: G", 0x33 },
{ "Key: B", 0x34 },
{ "Key: Space", 0x35 },
{ "Key: 6", 0x39 },
{ "Key: Y", 0x3A },
{ "Key: H", 0x3B },
{ "Key: N", 0x3C },
{ "Key: F5", 0x40 },
{ "Key: 7", 0x41 },
{ "Key: U", 0x42 },
{ "Key: J", 0x43 },
{ "Key: M", 0x44 },
{ "Key: F6", 0x48 },
{ "Key: 8", 0x49 },
{ "Key: I", 0x4A },
{ "Key: K", 0x4B },
{ "Key: ,", 0x4C },
{ "Key: Right Alt", 0x4D },
{ "Key: F7", 0x50 },
{ "Key: 9", 0x51 },
{ "Key: O", 0x52 },
{ "Key: L", 0x53 },
{ "Key: .", 0x54 },
{ "Key: F8", 0x58 },
{ "Key: 0", 0x59 },
{ "Key: P", 0x5A },
{ "Key: ;", 0x5B },
{ "Key: /", 0x5C },
{ "Key: Right Fn", 0x5D },
{ "Key: F9", 0x60 },
{ "Key: -", 0x61 },
{ "Key: [", 0x62 },
{ "Key: '", 0x63 },
{ "Key: Menu", 0x65 },
{ "Key: F10", 0x68 },
{ "Key: =", 0x69 },
{ "Key: ]", 0x6A },
{ "Key: #", 0x6B },
{ "Key: F11", 0x70 },
{ "Key: F12", 0x78 },
{ "Key: Backspace", 0x79 },
{ "Key: \\ (ANSI)", 0x7A },
{ "Key: Enter", 0x7B },
{ "Key: Right Shift", 0x7C },
{ "Key: Right Control", 0x7D },
{ "Key: Print Screen", 0x80 },
{ "Key: Insert", 0x81 },
{ "Key: Delete", 0x82 },
{ "Key: Left Arrow", 0x85 },
{ "Key: Scroll Lock", 0x88 },
{ "Key: Home", 0x89 },
{ "Key: End", 0x8A },
{ "Key: Up Arrow", 0x8C },
{ "Key: Down Arrow", 0x8D },
{ "Key: Pause/Break", 0x90 },
{ "Key: Page Up", 0x91 },
{ "Key: Page Down", 0x92 },
{ "Key: Right Arrow", 0x95 },
{ "Key: Num Lock", 0x99 },
{ "Key: Number Pad 7", 0x9A },
{ "Key: Number Pad 4", 0x9B },
{ "Key: Number Pad 1", 0x9C },
{ "Key: Number Pad 0", 0x9D },
{ "Key: Number Pad /", 0xA1 },
{ "Key: Number Pad 8", 0xA2 },
{ "Key: Number Pad 5", 0xA3 },
{ "Key: Number Pad 2", 0xA4 },
{ "Key: Number Pad *", 0xA9 },
{ "Key: Number Pad 9", 0xAA },
{ "Key: Number Pad 6", 0xAB },
{ "Key: Number Pad 3", 0xAC },
{ "Key: Number Pad .", 0xAD },
{ "Key: Number Pad -", 0xB1 },
{ "Key: Number Pad +", 0xB2 },
{ "Key: Number Pad Enter", 0xB4 },
{ "Logo", 0xB8 },
{ "Left Underglow", 0xB9 },
{ "Right Underglow", 0xBA },
};
RGBController_AuraKeyboard::RGBController_AuraKeyboard(AuraKeyboardController* aura_ptr)
{
aura = aura_ptr;
name = "ASUS Aura Keyboard";
vendor = "ASUS";
type = DEVICE_TYPE_KEYBOARD;
description = "ASUS Aura Keyboard Device";
location = aura->GetDeviceLocation();
serial = aura->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = 0;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
SetupZones();
}
RGBController_AuraKeyboard::~RGBController_AuraKeyboard()
{
delete aura;
}
void RGBController_AuraKeyboard::SetupZones()
{
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
unsigned int total_led_count = 0;
for(unsigned int zone_idx = 0; zone_idx < 3; zone_idx++)
{
zone new_zone;
new_zone.name = zone_names[zone_idx];
new_zone.type = zone_types[zone_idx];
new_zone.leds_min = zone_sizes[zone_idx];
new_zone.leds_max = zone_sizes[zone_idx];
new_zone.leds_count = zone_sizes[zone_idx];
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
{
new_zone.matrix_map = new matrix_map_type;
new_zone.matrix_map->height = 6;
new_zone.matrix_map->width = 22;
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
}
else
{
new_zone.matrix_map = NULL;
}
zones.push_back(new_zone);
total_led_count += zone_sizes[zone_idx];
}
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
{
led new_led;
new_led.name = led_names[led_idx].name;
new_led.value = led_names[led_idx].idx;
leds.push_back(new_led);
}
SetupColors();
}
void RGBController_AuraKeyboard::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_AuraKeyboard::DeviceUpdateLEDs()
{
unsigned char frame_buf[109 * 4];
/*---------------------------------------------------------*\
| TODO: Send packets with multiple LED frames |
\*---------------------------------------------------------*/
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
frame_buf[(led_idx * 4) + 0] = leds[led_idx].value;
frame_buf[(led_idx * 4) + 1] = RGBGetRValue(colors[led_idx]);
frame_buf[(led_idx * 4) + 2] = RGBGetGValue(colors[led_idx]);
frame_buf[(led_idx * 4) + 3] = RGBGetBValue(colors[led_idx]);
}
aura->SendDirect(109, frame_buf);
}
void RGBController_AuraKeyboard::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_AuraKeyboard::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_AuraKeyboard::SetCustomMode()
{
active_mode = 0;
}
void RGBController_AuraKeyboard::DeviceUpdateMode()
{
}
@@ -1,33 +0,0 @@
/*-----------------------------------------*\
| RGBController_AsusAuraKeyboard.h |
| |
| Generic RGB Interface for Asus Aura |
| USB controller driver |
| |
| Adam Honse (CalcProgrammer1) 3/19/2021 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "AsusAuraKeyboardController.h"
class RGBController_AuraKeyboard : public RGBController
{
public:
RGBController_AuraKeyboard(AuraKeyboardController* aura_ptr);
~RGBController_AuraKeyboard();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
AuraKeyboardController* aura;
};
@@ -1,204 +0,0 @@
/*-----------------------------------------*\
| RGBController_AsusAuraMouse.cpp |
| |
| Generic RGB Interface for Asus Aura |
| USB controller driver |
| |
| Adam Honse (CalcProgrammer1) 10/25/2020 |
\*-----------------------------------------*/
#include "RGBController_AsusAuraMouse.h"
RGBController_AuraMouse::RGBController_AuraMouse(AuraMouseController* aura_ptr)
{
aura = aura_ptr;
name = "ASUS Aura Mouse";
vendor = "ASUS";
type = DEVICE_TYPE_MOUSE;
description = "ASUS Aura Mouse Device";
location = aura->GetDeviceLocation();
serial = aura->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = AURA_MOUSE_MODE_STATIC;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = AURA_MOUSE_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = AURA_MOUSE_MODE_COLOR_CYCLE;
SpectrumCycle.flags = 0;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
mode Reactive;
Reactive.name = "Reactive";
Reactive.value = AURA_MOUSE_MODE_REACTIVE;
Reactive.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Reactive.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Reactive);
SetupZones();
}
RGBController_AuraMouse::~RGBController_AuraMouse()
{
delete aura;
}
void RGBController_AuraMouse::SetupZones()
{
zone logo_zone;
logo_zone.name = "Logo";
logo_zone.type = ZONE_TYPE_SINGLE;
logo_zone.leds_min = 1;
logo_zone.leds_max = 1;
logo_zone.leds_count = 1;
logo_zone.matrix_map = NULL;
zones.push_back(logo_zone);
led logo_led;
logo_led.name = "Logo";
leds.push_back(logo_led);
zone scroll_zone;
scroll_zone.name = "Scroll Wheel";
scroll_zone.type = ZONE_TYPE_SINGLE;
scroll_zone.leds_min = 1;
scroll_zone.leds_max = 1;
scroll_zone.leds_count = 1;
scroll_zone.matrix_map = NULL;
zones.push_back(scroll_zone);
led scroll_led;
scroll_led.name = "Scroll Wheel";
leds.push_back(scroll_led);
zone underglow_zone;
underglow_zone.name = "Underglow";
underglow_zone.type = ZONE_TYPE_SINGLE;
underglow_zone.leds_min = 1;
underglow_zone.leds_max = 1;
underglow_zone.leds_count = 1;
underglow_zone.matrix_map = NULL;
zones.push_back(underglow_zone);
led underglow_led;
underglow_led.name = "Underglow";
leds.push_back(underglow_led);
SetupColors();
}
void RGBController_AuraMouse::ResizeZone(int /*zone*/, int /*new_size*/)
{
}
void RGBController_AuraMouse::DeviceUpdateLEDs()
{
DeviceUpdateMode();
}
void RGBController_AuraMouse::UpdateZoneLEDs(int zone)
{
UpdateSingleLED(zone);
}
void RGBController_AuraMouse::UpdateSingleLED(int led)
{
unsigned char red = 0;
unsigned char grn = 0;
unsigned char blu = 0;
if(modes[active_mode].color_mode == MODE_COLORS_PER_LED)
{
if(led == 0)
{
red = RGBGetRValue(colors[led]);
grn = RGBGetGValue(colors[led]);
blu = RGBGetBValue(colors[led]);
aura->SendUpdate(AURA_MOUSE_ZONE_LOGO, modes[active_mode].value, red, grn, blu);
}
else if(led == 1)
{
red = RGBGetRValue(colors[led]);
grn = RGBGetGValue(colors[led]);
blu = RGBGetBValue(colors[led]);
aura->SendUpdate(AURA_MOUSE_ZONE_SCROLL, modes[active_mode].value, red, grn, blu);
}
else
{
red = RGBGetRValue(colors[led]);
grn = RGBGetGValue(colors[led]);
blu = RGBGetBValue(colors[led]);
aura->SendUpdate(AURA_MOUSE_ZONE_UNDERGLOW, modes[active_mode].value, red, grn, blu);
}
}
else
{
aura->SendUpdate(AURA_MOUSE_ZONE_ALL, modes[active_mode].value, red, grn, blu);
}
}
void RGBController_AuraMouse::SetCustomMode()
{
active_mode = 0;
}
void RGBController_AuraMouse::DeviceUpdateMode()
{
unsigned char red = 0;
unsigned char grn = 0;
unsigned char blu = 0;
if(modes[active_mode].color_mode == MODE_COLORS_PER_LED)
{
red = RGBGetRValue(colors[0]);
grn = RGBGetGValue(colors[0]);
blu = RGBGetBValue(colors[0]);
aura->SendUpdate(AURA_MOUSE_ZONE_LOGO, modes[active_mode].value, red, grn, blu);
red = RGBGetRValue(colors[1]);
grn = RGBGetGValue(colors[1]);
blu = RGBGetBValue(colors[1]);
aura->SendUpdate(AURA_MOUSE_ZONE_SCROLL, modes[active_mode].value, red, grn, blu);
red = RGBGetRValue(colors[2]);
grn = RGBGetGValue(colors[2]);
blu = RGBGetBValue(colors[2]);
aura->SendUpdate(AURA_MOUSE_ZONE_UNDERGLOW, modes[active_mode].value, red, grn, blu);
}
else
{
aura->SendUpdate(AURA_MOUSE_ZONE_ALL, modes[active_mode].value, red, grn, blu);
}
}
@@ -1,33 +0,0 @@
/*-----------------------------------------*\
| RGBController_AsusAuraMouse.h |
| |
| Generic RGB Interface for Asus Aura |
| USB controller driver |
| |
| Adam Honse (CalcProgrammer1) 10/25/2020 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "AsusAuraMouseController.h"
class RGBController_AuraMouse : public RGBController
{
public:
RGBController_AuraMouse(AuraMouseController* aura_ptr);
~RGBController_AuraMouse();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
AuraMouseController* aura;
};
@@ -1,48 +0,0 @@
#ifdef _WIN32
#include "RGBController_AsusTUFLaptopWMI.h"
#include "acpiwmi.h"
#include "Detector.h"
#include "wmi.h"
#include <string>
static void DetectAsusTUFLaptopWMIControllers(std::vector<RGBController*>&)
{
// Try to retrieve ProductID / Device name from WMI; Possibly can be rewritten to use wmi.cpp
// IF you encounter false detection ( e.g. if your laptop keyboard backlight uses USB interface
// instead of ACPI WMI) please add a WHITELIST by checking the
// `name` variable for model substrings like "FX505DU"
// For now, checking for "TUF Gaming" should suffice
Wmi wmi;
wmi.init();
std::vector<QueryObj> systemProduct;
if (wmi.query("SELECT * FROM Win32_ComputerSystemProduct", systemProduct))
{
return;
}
// There should only be one, a cycle is a precaution
if(systemProduct.size() != 1)
{
return;
}
std::string& name = systemProduct[0]["Name"];
if(name.find("TUF Gaming") == name.npos)
{
return;
}
if(AsWMI_Open())
{
RGBController* new_controller = new RGBController_AsusTUFLaptopWMI();
ResourceManager::get()->RegisterRGBController(new_controller);
// Success! No more if's
}
} /* DetectFaustusControllers() */
REGISTER_DETECTOR("TUF Laptop WMI", DetectAsusTUFLaptopWMIControllers);
#endif
@@ -1,143 +0,0 @@
#ifdef _WIN32
#include "RGBController_AsusTUFLaptopWMI.h"
#include "acpiwmi.h"
#include "ResourceManager.h"
#include "Detector.h"
#include "wmi.h"
#include <string>
using namespace std::chrono_literals;
RGBController_AsusTUFLaptopWMI::RGBController_AsusTUFLaptopWMI()
{
name = "ASUS TUF Keyboard";
vendor = "ASUS";
type = DEVICE_TYPE_KEYBOARD;
description = "WMI Device";
location = "\\\\.\\ATKACPI";
modes.resize(5);
modes[0].name = "Direct";
modes[0].value = 4;
modes[0].flags = MODE_FLAG_HAS_PER_LED_COLOR;
modes[0].color_mode = MODE_COLORS_PER_LED;
modes[1].name = "Static";
modes[1].value = 0;
modes[1].flags = MODE_FLAG_HAS_PER_LED_COLOR;
modes[1].color_mode = MODE_COLORS_PER_LED;
modes[2].name = "Breathing";
modes[2].value = 1;
modes[2].flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
modes[2].speed_min = 0;
modes[2].speed_max = 2;
modes[2].color_mode = MODE_COLORS_PER_LED;
modes[2].speed = 1;
modes[3].name = "Color Cycle";
modes[3].value = 2;
modes[3].flags = MODE_FLAG_HAS_SPEED;
modes[3].speed_min = 0;
modes[3].speed_max = 2;
modes[3].color_mode = MODE_COLORS_NONE;
modes[3].speed = 1;
modes[4].name = "Strobe";
modes[4].value = 0x0A;
modes[4].flags = MODE_FLAG_HAS_PER_LED_COLOR;
modes[4].color_mode = MODE_COLORS_PER_LED;
SetupZones();
}
RGBController_AsusTUFLaptopWMI::~RGBController_AsusTUFLaptopWMI()
{
AsWMI_Close();
}
void RGBController_AsusTUFLaptopWMI::SetupZones()
{
/*---------------------------------------------------------*\
| Set up zone |
\*---------------------------------------------------------*/
zones.resize(1);
zones[0].type = ZONE_TYPE_SINGLE;
zones[0].name = "Keyboard Backlight zone";
zones[0].leds_min = 1;
zones[0].leds_max = 1;
zones[0].leds_count = 1;
zones[0].matrix_map = NULL;
/*---------------------------------------------------------*\
| Set up LED |
\*---------------------------------------------------------*/
leds.resize(1);
leds[0].name = "Keyboard Backlight LED";
SetupColors();
}
void RGBController_AsusTUFLaptopWMI::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_AsusTUFLaptopWMI::DeviceUpdateLEDs()
{
uint8_t red = RGBGetRValue(colors[0]);
uint8_t green = RGBGetGValue(colors[0]);
uint8_t blue = RGBGetBValue(colors[0]);
uint8_t speed_byte = 0;
uint8_t mode = modes[active_mode].value;
uint8_t inv = 0;
if(mode == 4)
{
mode = 1;
inv = 4; // Any invalid mode, i.e. anything other than 0, 1, 2 and 10
}
if(mode == 1 || mode == 2)
{
switch(modes[active_mode].speed)
{
case 0: speed_byte = 0xE1; break;
case 1: speed_byte = 0xEB; break;
case 2: speed_byte = 0xF5; break;
}
}
int high = ((mode | ((red | (green << 8)) << 8)) << 8) | 0xB3;
int low = blue | (speed_byte << 8);
AsWMI_NB_DeviceControl_2arg(0x100056, high, low);
if(inv)
{
//std::this_thread::sleep_for(10ms);
high = ((inv | ((red | (green << 8)) << 8)) << 8) | 0xB3;
AsWMI_NB_DeviceControl_2arg(0x100056, high, low);
}
}
void RGBController_AsusTUFLaptopWMI::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_AsusTUFLaptopWMI::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_AsusTUFLaptopWMI::SetCustomMode()
{
SetMode(0);
}
void RGBController_AsusTUFLaptopWMI::DeviceUpdateMode()
{
DeviceUpdateLEDs();
}
#endif
@@ -1,29 +0,0 @@
#ifndef RGBCONTROLLER_ASUSTUFLAPTOPWMI_H
#define RGBCONTROLLER_ASUSTUFLAPTOPWMI_H
#ifdef _WIN32
#include "RGBController.h"
class RGBController_AsusTUFLaptopWMI : public RGBController
{
public:
RGBController_AsusTUFLaptopWMI();
virtual ~RGBController_AsusTUFLaptopWMI();
void SetupZones() override;
void ResizeZone(int zone, int new_size) override;
void DeviceUpdateLEDs() override;
void UpdateZoneLEDs(int zone) override;
void UpdateSingleLED(int led) override;
void DeviceUpdateMode() override;
void SetCustomMode() override;
};
#endif
#endif // RGBCONTROLLER_ASUSTUFLAPTOPWMI_H
@@ -0,0 +1,125 @@
/*-----------------------------------------*\
| 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,5 +1,5 @@
/*-----------------------------------------*\
| AsusAuraCoreController.h |
| AuraCoreController.h |
| |
| Definitions and types for ASUS ROG Aura |
| Core RGB lighting controller |
@@ -14,24 +14,11 @@
#pragma once
enum AuraCoreDeviceType
{
AURA_CORE_DEVICE_UNKNOWN = 0,
AURA_CORE_DEVICE_KEYBOARD = 1,
AURA_CORE_DEVICE_GA15DH = 2
};
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 */
AURA_CORE_MODE_RAINBOW = 3, /* Rainbow mode */
AURA_CORE_MODE_STROBE = 10, /* Strobe mode */
AURA_CORE_MODE_COMET = 11, /* Comet mode */
AURA_CORE_MODE_FLASHNDASH = 12, /* Flash & Dash mode */
AURA_CORE_MODE_IRRADIATION = 17, /* Irradiation mode */
AURA_CORE_MODE_DIRECT = 255 /* Not a real mode - but need a way to differentiate */
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
@@ -40,7 +27,6 @@ enum
AURA_CORE_COMMAND_SET = 0xB5, /* Set command */
AURA_CORE_COMMAND_APPLY = 0xB4, /* Apply command */
AURA_CORE_COMMAND_BRIGHTNESS = 0xBA, /* Brightness command */
AURA_CORE_COMMAND_DIRECT = 0xBC /* Set LEDs directly */
};
enum
@@ -59,34 +45,12 @@ enum
AURA_CORE_SPEED_FAST = 0xF5, /* Fastest speed */
};
struct AuraDeviceDescriptor
{
AuraCoreDeviceType aura_type;
unsigned char buff_size;
unsigned char report_id;
unsigned char num_leds;
unsigned char max_leds_per_message;
bool supports_direct;
};
struct AuraColor
{
unsigned char red;
unsigned char green;
unsigned char blue;
};
class AuraCoreController
{
public:
AuraDeviceDescriptor aura_device;
AuraCoreController(hid_device* dev_handle, const char* path);
AuraCoreController(hid_device* dev_handle);
~AuraCoreController();
std::string GetDeviceLocation();
std::string GetSerialString();
void SendBrightness
(
unsigned char brightness
@@ -97,7 +61,6 @@ public:
unsigned char zone,
unsigned char mode,
unsigned char speed,
unsigned char dir,
unsigned char red,
unsigned char green,
unsigned char blue
@@ -107,17 +70,7 @@ public:
void SendApply();
void InitDirectMode();
void UpdateDirect(std::vector<AuraColor>& color_set);
private:
hid_device* dev;
std::string location;
void IdentifyDevice();
void Handshake();
void SendIdString();
void SendQuery();
};
@@ -0,0 +1,45 @@
#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,12 +1,12 @@
/*-----------------------------------------*\
| AsusAuraGPUController.cpp |
| AuraGPUController.cpp |
| |
| Driver for ASUS Aura RGB on GPUs |
| |
| Jan Rettig (Klapstuhl) 14.02.2020 |
\*-----------------------------------------*/
#include "AsusAuraGPUController.h"
#include "AuraGPUController.h"
#include <cstring>
AuraGPUController::AuraGPUController(i2c_smbus_interface* bus, aura_gpu_dev_id dev)
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| AsusAuraGPUController.h |
| AuraGPUController.h |
| |
| Definitions for ASUS Aura RGB on GPUs |
| |
@@ -0,0 +1,85 @@
/*-----------------------------------------*\
| 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,5 +1,5 @@
/*-----------------------------------------*\
| AsusAuraSMBusController.cpp |
| AuraSMBusController.cpp |
| |
| Driver for ASUS Aura RGB lighting |
| controller |
@@ -7,24 +7,9 @@
| Adam Honse (CalcProgrammer1) 8/19/2018 |
\*-----------------------------------------*/
#include "AsusAuraSMBusController.h"
#include "AuraSMBusController.h"
#include <cstring>
static const char* aura_channels[] = /* Aura channel strings */
{
"Audio",
"Backplate",
"Back I/O",
"Center",
"Center",
"DRAM",
"PCIe",
"RGB Header",
"RGB Header 2",
"RGB Header",
"Unknown",
};
AuraSMBusController::AuraSMBusController(i2c_smbus_interface* bus, aura_dev_id dev)
{
this->bus = bus;
@@ -60,7 +45,7 @@ AuraSMBusController::AuraSMBusController(i2c_smbus_interface* bus, aura_dev_id d
{
direct_reg = AURA_REG_COLORS_DIRECT_V2;
effect_reg = AURA_REG_COLORS_EFFECT_V2;
channel_cfg = AURA_CONFIG_CHANNEL_V1;
channel_cfg = AURA_CONFIG_CHANNEL_V2;
}
// AUMA0-E6K5-0106 - Second generation motherboard controller
else if (strcmp(device_name, "AUMA0-E6K5-0106") == 0)
@@ -83,13 +68,6 @@ AuraSMBusController::AuraSMBusController(i2c_smbus_interface* bus, aura_dev_id d
effect_reg = AURA_REG_COLORS_EFFECT_V2;
channel_cfg = AURA_CONFIG_CHANNEL_V2;
}
// AUMA0-E8K4-0101 - Second generation motherboard controller
else if (strcmp(device_name, "AUMA0-E8K4-0101") == 0)
{
direct_reg = AURA_REG_COLORS_DIRECT_V2;
effect_reg = AURA_REG_COLORS_EFFECT_V2;
channel_cfg = AURA_CONFIG_CHANNEL_V2;
}
// Assume first generation controller if string does not match
else
{
@@ -116,7 +94,7 @@ std::string AuraSMBusController::GetDeviceLocation()
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
return_string.append(addr);
return("I2C: " + return_string);
return(return_string);
}
unsigned char AuraSMBusController::GetChannel(unsigned int led)
@@ -194,38 +172,38 @@ unsigned char AuraSMBusController::GetLEDBlue(unsigned int led)
return(AuraRegisterRead(direct_reg + ( 3 * led ) + 1));
}
void AuraSMBusController::SetAllColorsDirect(RGBColor* colors)
void AuraSMBusController::SetAllColorsDirect(unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char* color_buf = new unsigned char[led_count * 3];
unsigned char* colors = new unsigned char[led_count * 3];
for (unsigned int i = 0; i < (led_count * 3); i += 3)
{
color_buf[i + 0] = RGBGetRValue(colors[i / 3]);
color_buf[i + 1] = RGBGetBValue(colors[i / 3]);
color_buf[i + 2] = RGBGetGValue(colors[i / 3]);
colors[i + 0] = red;
colors[i + 1] = blue;
colors[i + 2] = green;
}
AuraRegisterWriteBlock(direct_reg, color_buf, led_count * 3);
AuraRegisterWriteBlock(direct_reg, colors, led_count * 3);
delete color_buf;
delete colors;
}
void AuraSMBusController::SetAllColorsEffect(RGBColor* colors)
void AuraSMBusController::SetAllColorsEffect(unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char* color_buf = new unsigned char[led_count * 3];
unsigned char* colors = new unsigned char[led_count * 3];
for (unsigned int i = 0; i < (led_count * 3); i += 3)
{
color_buf[i + 0] = RGBGetRValue(colors[i / 3]);
color_buf[i + 1] = RGBGetBValue(colors[i / 3]);
color_buf[i + 2] = RGBGetGValue(colors[i / 3]);
colors[i + 0] = red;
colors[i + 1] = blue;
colors[i + 2] = green;
}
AuraRegisterWriteBlock(effect_reg, color_buf, led_count * 3);
AuraRegisterWriteBlock(effect_reg, colors, led_count * 3);
AuraRegisterWrite(AURA_REG_APPLY, AURA_APPLY_VAL);
delete[] color_buf;
delete[] colors;
}
void AuraSMBusController::SetDirect(unsigned char direct)
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| AsusAuraSMBusController.h |
| AuraSMBusController.h |
| |
| Definitions and types for ASUS Aura RGB |
| lighting controller |
@@ -7,8 +7,6 @@
| Adam Honse (CalcProgrammer1) 8/19/2018 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include "i2c_smbus.h"
@@ -68,6 +66,21 @@ enum
AURA_LED_CHANNEL_RGB_HEADER_3 = 0x91, /* RGB Header 3 LED channel */
};
static const char* aura_channels[] = /* Aura channel strings */
{
"Audio",
"Backplate",
"Back I/O",
"Center",
"Center",
"DRAM",
"PCIe",
"RGB Header",
"RGB Header 2",
"RGB Header",
"Unknown",
};
enum
{
AURA_CONFIG_LED_COUNT = 0x02, /* LED Count configuration offset */
@@ -89,8 +102,8 @@ public:
unsigned char GetLEDRed(unsigned int led);
unsigned char GetLEDGreen(unsigned int led);
unsigned char GetLEDBlue(unsigned int led);
void SetAllColorsDirect(RGBColor* colors);
void SetAllColorsEffect(RGBColor* colors);
void SetAllColorsDirect(unsigned char red, unsigned char green, unsigned char blue);
void SetAllColorsEffect(unsigned char red, unsigned char green, unsigned char blue);
void SetDirect(unsigned char direct);
void SetLEDColorDirect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
void SetLEDColorEffect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
@@ -1,21 +1,17 @@
#include "Detector.h"
#include "AsusAuraSMBusController.h"
#include "LogManager.h"
#include "AuraSMBusController.h"
#include "RGBController.h"
#include "RGBController_AsusAuraSMBus.h"
#include "RGBController_AuraSMBus.h"
#include "i2c_smbus.h"
#include "pci_ids.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include "dependencies/dmiinfo.h"
using namespace std::chrono_literals;
/*----------------------------------------------------------------------*\
| This list contains the available SMBus addresses for mapping Aura RAM |
\*----------------------------------------------------------------------*/
#define AURA_RAM_ADDRESS_COUNT 23
#define AURA_RAM_ADDRESS_COUNT 22
static const unsigned char aura_ram_addresses[] =
{
@@ -38,7 +34,6 @@ static const unsigned char aura_ram_addresses[] =
0x66,
0x67,
0x39,
0x3A,
0x3B,
0x3C,
0x3D
@@ -66,7 +61,7 @@ static const unsigned char aura_mobo_addresses[] =
* *
\******************************************************************************************/
void AsusAuraRegisterWrite(i2c_smbus_interface* bus, aura_dev_id dev, aura_register reg, unsigned char val)
void AuraRegisterWrite(i2c_smbus_interface* bus, aura_dev_id dev, aura_register reg, unsigned char val)
{
//Write Aura register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
@@ -85,36 +80,25 @@ void AsusAuraRegisterWrite(i2c_smbus_interface* bus, aura_dev_id dev, aura_regis
* *
\******************************************************************************************/
bool TestForAsusAuraSMBusController(i2c_smbus_interface* bus, unsigned char address)
bool TestForAuraSMBusController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
LOG_DEBUG("Testing address %02X for Aura SMBus controller", address);
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
if (res >= 0)
{
pass = true;
LOG_DEBUG("Detected an I2C device at address %02X, testing register range for Aura SMBus", address);
for (int i = 0xA0; i < 0xB0; i++)
{
res = bus->i2c_smbus_read_byte_data(address, i);
if (res != (i - 0xA0))
{
LOG_DEBUG("Detection failed testing register %02X. Expected %02X, got %02X.", i, (i - 0xA0), res);
pass = false;
}
}
if(pass)
{
LOG_DEBUG("Detection successful, address %02X appears to be an Aura SMBus controller", address);
}
}
return(pass);
@@ -123,7 +107,7 @@ bool TestForAsusAuraSMBusController(i2c_smbus_interface* bus, unsigned char addr
/******************************************************************************************\
* *
* DetectAuraSMBusControllers *
* DetectAuraSMBusControllers *
* *
* 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 *
@@ -135,69 +119,7 @@ bool TestForAsusAuraSMBusController(i2c_smbus_interface* bus, unsigned char addr
* *
\******************************************************************************************/
void DetectAsusAuraSMBusDRAMControllers(std::vector<i2c_smbus_interface*> &busses)
{
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
int address_list_idx = -1;
IF_DRAM_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
{
LOG_DEBUG("Remapping Aura SMBus RAM modules on 0x77");
for (unsigned int slot = 0; slot < 8; slot++)
{
int res = busses[bus]->i2c_smbus_write_quick(0x77, I2C_SMBUS_WRITE);
if (res < 0)
{
LOG_DEBUG("No device detected at address 0x77, aborting remap");
break;
}
do
{
address_list_idx++;
if(address_list_idx < AURA_RAM_ADDRESS_COUNT)
{
LOG_DEBUG("Testing address %02X to see if there is a device there", aura_ram_addresses[address_list_idx]);
res = busses[bus]->i2c_smbus_write_quick(aura_ram_addresses[address_list_idx], I2C_SMBUS_WRITE);
}
else
{
break;
}
} while (res >= 0);
if(address_list_idx < AURA_RAM_ADDRESS_COUNT)
{
LOG_DEBUG("Remapping slot %d to address %02X", slot, aura_ram_addresses[address_list_idx]);
AsusAuraRegisterWrite(busses[bus], 0x77, AURA_REG_SLOT_INDEX, slot);
AsusAuraRegisterWrite(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 (TestForAsusAuraSMBusController(busses[bus], aura_ram_addresses[address_list_idx]))
{
AuraSMBusController* controller = new AuraSMBusController(busses[bus], aura_ram_addresses[address_list_idx]);
RGBController_AuraSMBus* rgb_controller = new RGBController_AuraSMBus(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
std::this_thread::sleep_for(1ms);
}
}
}
} /* DetectAuraSMBusDRAMControllers() */
void DetectAsusAuraSMBusMotherboardControllers(std::vector<i2c_smbus_interface*> &busses)
void DetectAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
{
AuraSMBusController* new_aura;
RGBController_AuraSMBus* new_controller;
@@ -206,26 +128,62 @@ void DetectAsusAuraSMBusMotherboardControllers(std::vector<i2c_smbus_interface*>
{
int address_list_idx = -1;
// Add Aura-enabled motherboard controllers
IF_MOBO_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
// Remap Aura-enabled RAM modules on 0x77
for (unsigned int slot = 0; slot < 8; slot++)
{
for (unsigned int address_list_idx = 0; address_list_idx < AURA_MOBO_ADDRESS_COUNT; address_list_idx++)
{
if (TestForAsusAuraSMBusController(busses[bus], aura_mobo_addresses[address_list_idx]))
{
DMIInfo dmi;
AuraSMBusController* controller = new AuraSMBusController(busses[bus], aura_mobo_addresses[address_list_idx]);
RGBController_AuraSMBus* rgb_controller = new RGBController_AuraSMBus(controller);
rgb_controller->name = "ASUS " + dmi.getMainboard();
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
int res = busses[bus]->i2c_smbus_write_quick(0x77, I2C_SMBUS_WRITE);
std::this_thread::sleep_for(1ms);
if (res < 0)
{
break;
}
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);
}
else
{
break;
}
} 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));
}
}
// 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]))
{
new_aura = new AuraSMBusController(busses[bus], aura_ram_addresses[address_list_idx]);
new_controller = new RGBController_AuraSMBus(new_aura);
rgb_controllers.push_back(new_controller);
}
std::this_thread::sleep_for(1ms);
}
// 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]))
{
new_aura = new AuraSMBusController(busses[bus], aura_mobo_addresses[address_list_idx]);
new_controller = new RGBController_AuraSMBus(new_aura);
rgb_controllers.push_back(new_controller);
}
std::this_thread::sleep_for(1ms);
}
}
} /* DetectAuraSMBusMotherboardControllers() */
REGISTER_I2C_DETECTOR("ASUS Aura SMBus DRAM", DetectAsusAuraSMBusDRAMControllers);
REGISTER_I2C_DETECTOR("ASUS Aura SMBus Motherboard", DetectAsusAuraSMBusMotherboardControllers);
} /* DetectAuraSMBusControllers() */
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| AsusAuraAddressableController.cpp |
| AuraAddressableController.cpp |
| |
| Driver for ASUS Aura RGB Addressable |
| lighting controller |
@@ -7,17 +7,17 @@
| Adam Honse (CalcProgrammer1) 1/18/2020 |
\*-----------------------------------------*/
#include "AsusAuraAddressableController.h"
#include "AuraAddressableController.h"
#include <cstring>
AuraAddressableController::AuraAddressableController(hid_device* dev_handle, const char* path) : AuraUSBController(dev_handle, path)
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, 0, AuraDeviceType::ADDRESSABLE});
device_info.push_back({0x01, (unsigned char)i, 0x01, AuraDeviceType::ADDRESSABLE});
}
}
@@ -40,7 +40,7 @@ void AuraAddressableController::SetChannelLEDs(unsigned char channel, RGBColor *
leds_to_send = num_colors - leds_sent;
}
for(unsigned int led_idx = 0; led_idx < leds_to_send; led_idx++)
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]);
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| AsusAuraAddressableController.h |
| AuraAddressableController.h |
| |
| Definitions and types for ASUS Aura |
| Addressable RGB lighting controller |
@@ -8,7 +8,7 @@
\*-----------------------------------------*/
#include "RGBController.h"
#include "AsusAuraUSBController.h"
#include "AuraUSBController.h"
#include <string>
#include <hidapi/hidapi.h>
@@ -23,7 +23,7 @@ enum
class AuraAddressableController : public AuraUSBController
{
public:
AuraAddressableController(hid_device* dev_handle, const char* path);
AuraAddressableController(hid_device* dev_handle);
~AuraAddressableController();
void SetChannelLEDs
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| AsusAuraMainboardController.cpp |
| AuraMainboardController.cpp |
| |
| Driver for ASUS Aura RGB USB mainboard |
| lighting controller |
@@ -7,31 +7,22 @@
| Martin Hartl (inlart) 4/25/2020 |
\*-----------------------------------------*/
#include "AsusAuraMainboardController.h"
#include "AuraMainboardController.h"
#include <cstring>
AuraMainboardController::AuraMainboardController(hid_device* dev_handle, const char* path) : AuraUSBController(dev_handle, path), mode(AURA_MODE_DIRECT)
AuraMainboardController::AuraMainboardController(hid_device* dev_handle) : AuraUSBController(dev_handle), mode(AURA_MODE_DIRECT)
{
unsigned char num_total_mainboard_leds = config_table[0x1B];
unsigned char num_rgb_headers = config_table[0x1D];
unsigned char num_addressable_headers = config_table[0x02];
if(num_total_mainboard_leds < num_rgb_headers)
{
num_rgb_headers = 0;
}
/*-----------------------------------------------------*\
| Add mainboard device |
\*-----------------------------------------------------*/
device_info.push_back({0x00, 0x04, num_total_mainboard_leds, num_rgb_headers, AuraDeviceType::FIXED});
device_info.push_back({0x00, 0x04, config_table[0x1B], AuraDeviceType::FIXED});
/*-----------------------------------------------------*\
| Add addressable devices |
\*-----------------------------------------------------*/
for(int i = 0; i < num_addressable_headers; i++)
for(int i = 0; i < config_table[0x02]; ++i)
{
device_info.push_back({0x01, (unsigned char)i, 0x01, 0, AuraDeviceType::ADDRESSABLE});
device_info.push_back({0x01, (unsigned char)i, 0x01, AuraDeviceType::ADDRESSABLE});
}
}
@@ -53,7 +44,7 @@ void AuraMainboardController::SetChannelLEDs(unsigned char channel, RGBColor * c
leds_to_send = num_colors - leds_sent;
}
for(unsigned int led_idx = 0; led_idx < leds_to_send; led_idx++)
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]);
@@ -71,6 +62,8 @@ void AuraMainboardController::SetChannelLEDs(unsigned char channel, RGBColor * c
leds_sent += leds_to_send;
}
SendCommit();
}
void AuraMainboardController::SetMode
@@ -111,13 +104,11 @@ void AuraMainboardController::SetMode
channel,
start_led,
device_info[channel].num_leds,
led_data
led_data,
device_info[channel].device_type == AuraDeviceType::FIXED
);
}
unsigned short AuraMainboardController::GetMask(int start, int size)
{
return(((1 << size) - 1) << start);
SendCommit();
}
void AuraMainboardController::SendEffect
@@ -151,14 +142,14 @@ void AuraMainboardController::SendEffect
void AuraMainboardController::SendColor
(
unsigned char /*channel*/,
unsigned char channel,
unsigned char start_led,
unsigned char led_count,
unsigned char* led_data
unsigned char* led_data,
bool fixed
)
{
unsigned short mask = GetMask(start_led, led_count);
unsigned char usb_buf[65];
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -170,8 +161,8 @@ void AuraMainboardController::SendColor
\*-----------------------------------------------------*/
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = AURA_MAINBOARD_CONTROL_MODE_EFFECT_COLOR;
usb_buf[0x02] = mask >> 8;
usb_buf[0x03] = mask & 0xff;
usb_buf[0x02] = channel;
usb_buf[0x03] = fixed ? 0xFF : 0x00;
usb_buf[0x04] = 0x00;
/*-----------------------------------------------------*\
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| AsusAuraMainboardController.h |
| AuraMainboardController.h |
| |
| Definitions and types for ASUS Aura |
| USB Mainboard RGB lighting controller |
@@ -8,7 +8,7 @@
\*-----------------------------------------*/
#include "RGBController.h"
#include "AsusAuraUSBController.h"
#include "AuraUSBController.h"
#include <string>
#include <hidapi/hidapi.h>
@@ -25,7 +25,7 @@ enum
class AuraMainboardController : public AuraUSBController
{
public:
AuraMainboardController(hid_device* dev_handle, const char* path);
AuraMainboardController(hid_device* dev_handle);
~AuraMainboardController();
void SetChannelLEDs
@@ -47,8 +47,6 @@ public:
private:
unsigned int mode;
unsigned short GetMask(int start, int size);
void SendEffect
(
unsigned char channel,
@@ -60,7 +58,8 @@ private:
unsigned char channel,
unsigned char start_led,
unsigned char led_count,
unsigned char* led_data
unsigned char* led_data,
bool fixed
);
void SendCommit();
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| AsusAuraUSBController.cpp |
| AuraUSBController.cpp |
| |
| Driver for ASUS Aura RGB USB |
| lighting controller |
@@ -7,14 +7,13 @@
| Martin Hartl (inlart) 4/25/2020 |
\*-----------------------------------------*/
#include "AsusAuraUSBController.h"
#include "AuraUSBController.h"
#include <cstring>
#include <stdexcept>
AuraUSBController::AuraUSBController(hid_device* dev_handle, const char* path)
AuraUSBController::AuraUSBController(hid_device* dev_handle)
{
dev = dev_handle;
location = path;
dev = dev_handle;
GetFirmwareVersion();
GetConfigTable();
@@ -22,39 +21,19 @@ AuraUSBController::AuraUSBController(hid_device* dev_handle, const char* path)
AuraUSBController::~AuraUSBController()
{
hid_close(dev);
}
unsigned int AuraUSBController::GetChannelCount()
{
return(device_info.size());
}
std::string AuraUSBController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string AuraUSBController::GetDeviceName()
{
return(device_name);
}
std::string AuraUSBController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
const std::vector<AuraDeviceInfo>& AuraUSBController::GetAuraDevices() const
{
return(device_info);
@@ -99,9 +78,11 @@ void AuraUSBController::GetConfigTable()
}
}
else
{
hid_close(dev);
{
if(dev)
{
hid_close(dev);
}
throw std::runtime_error("Could not read config table");
}
}
@@ -1,5 +1,5 @@
/*-----------------------------------------*\
| AsusAuraUSBController.h |
| AuraUSBController.h |
| |
| Definitions and types for ASUS Aura |
| USB RGB lighting controller |
@@ -53,21 +53,18 @@ struct AuraDeviceInfo
unsigned char effect_channel;
unsigned char direct_channel;
unsigned char num_leds;
unsigned char num_headers;
AuraDeviceType device_type;
};
class AuraUSBController
{
public:
AuraUSBController(hid_device* dev_handle, const char* path);
AuraUSBController(hid_device* dev_handle);
virtual ~AuraUSBController();
unsigned int GetChannelCount();
std::string GetDeviceLocation();
std::string GetDeviceName();
std::string GetSerialString();
const std::vector<AuraDeviceInfo>& GetAuraDevices() const;
@@ -91,7 +88,6 @@ protected:
hid_device* dev;
unsigned char config_table[60];
std::vector<AuraDeviceInfo> device_info;
std::string location;
void SendDirect
(
@@ -0,0 +1,77 @@
#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,308 +0,0 @@
/*-------------------------------------------------------------------*\
| CMARGBController.cpp |
| |
| Driver for Coolermaster ARGB USB Controller |
| |
| Chris M (Dr_No) 10th Oct 2020 |
| |
\*-------------------------------------------------------------------*/
#include "CMARGBcontroller.h"
#include <cstring>
static unsigned char argb_colour_index_data[2][2][2] =
{ //B0 B1
{ { 0x00, 0x03 }, //G0 R0
{ 0x02, 0x06 }, }, //G1 R0
{ { 0x01, 0x05 }, //G0 R1
{ 0x04, 0x07 }, } //G1 R1
};
CMARGBController::CMARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx)
{
const int szTemp = 256;
wchar_t tmpName[szTemp];
dev = dev_handle;
location = _path;
zone_index = _zone_idx;
hid_get_manufacturer_string(dev, tmpName, szTemp);
std::wstring wName = std::wstring(tmpName);
device_name = std::string(wName.begin(), wName.end());
hid_get_product_string(dev, tmpName, szTemp);
wName = std::wstring(tmpName);
device_name.append(" ").append(std::string(wName.begin(), wName.end()));
hid_get_serial_number_string(dev, tmpName, szTemp);
wName = std::wstring(tmpName);
serial = std::string(wName.begin(), wName.end());
GetStatus();
}
CMARGBController::~CMARGBController()
{
hid_close(dev);
}
void CMARGBController::GetStatus()
{
unsigned char buffer[CM_ARGB_PACKET_SIZE] = { 0x00, 0x80, 0x0B, 0x01 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
int rgb_offset = 0;
int zone;
if (argb_header_data[zone_index].digital)
{
zone = argb_header_data[zone_index].header;
buffer[CM_ARGB_COMMAND_BYTE] = 0x0B;
}
else
{
zone = 0x00;
buffer[CM_ARGB_COMMAND_BYTE] = 0x0A;
rgb_offset = 1;
}
/*---------------------------------------------------------*\
| If this is the group then just return the first status |
\*---------------------------------------------------------*/
buffer[CM_ARGB_ZONE_BYTE] = ( zone > 0x08 ) ? 0x01 : zone;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
current_mode = buffer[4 - rgb_offset];
bool_random = ( buffer[5 - rgb_offset] == 0x00 );
current_speed = buffer[6 - rgb_offset];
current_brightness = buffer[7 - rgb_offset];
current_red = buffer[8 - rgb_offset];
current_green = buffer[9 - rgb_offset];
current_blue = buffer[10 - rgb_offset];
}
std::string CMARGBController::GetDeviceName()
{
return device_name;
}
std::string CMARGBController::GetSerial()
{
return serial;
}
std::string CMARGBController::GetLocation()
{
return("HID: " + location);
}
unsigned char CMARGBController::GetZoneIndex()
{
return zone_index;
}
unsigned char CMARGBController::GetMode()
{
return current_mode;
}
unsigned char CMARGBController::GetLedRed()
{
return current_red;
}
unsigned char CMARGBController::GetLedGreen()
{
return current_green;
}
unsigned char CMARGBController::GetLedBlue()
{
return current_blue;
}
unsigned char CMARGBController::GetLedSpeed()
{
return current_speed;
}
bool CMARGBController::GetRandomColours()
{
return bool_random;
}
unsigned int CMARGBController::GetLargestColour(unsigned int red, unsigned int green, unsigned int blue)
{
unsigned int largest;
if ( red > green )
{
( red > blue ) ? largest = red : largest = blue;
}
else
{
( green > blue ) ? largest = green : largest = blue;
}
return (largest == 0) ? 1 : largest;
}
unsigned char CMARGBController::GetColourIndex(unsigned char red, unsigned char green, unsigned char blue)
{
/*---------------------------------------------------------------------------------------------------------*\
| The Cooler Master ARGB controller V0008 uses a limited colour pallette referenced by an index |
| Starting at 0x00 Random, 0x01 Red, 0x02 Green, 0x03 Blue, 0x04 Yellow, 0x05 Purple, 0x06 Cyan, 0x07 White |
| The index can be calculated by normalising the input colour, rounding those values |
| and using them as the indicies of a 3d array containing the correct index |
\*---------------------------------------------------------------------------------------------------------*/
unsigned int divisor = GetLargestColour( red, green, blue);
unsigned int r = round( red / divisor );
unsigned int g = round( green / divisor );
unsigned int b = round( blue / divisor );
unsigned char idx = argb_colour_index_data[r][g][b];
return idx;
}
void CMARGBController::SetLedCount(int zone, int led_count)
{
unsigned char buffer[CM_ARGB_PACKET_SIZE] = { 0x00, 0x80, 0x0D, 0x02 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
buffer[CM_ARGB_ZONE_BYTE] = zone;
buffer[CM_ARGB_MODE_BYTE] = led_count;
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = (0x0F - led_count > 0) ? 0x0F - led_count : 0x01;
hid_write(dev, buffer, buffer_size);
}
void CMARGBController::SetMode(unsigned char mode, unsigned char speed, RGBColor colour, bool random_colours)
{
bool needs_update = !( (current_mode == mode) && (current_speed == speed) && (current_brightness == 0xFF) && (ToRGBColor(current_red, current_green, current_blue) == colour));
if (needs_update)
{
current_mode = mode;
current_speed = speed;
current_brightness = 0xFF;
current_red = RGBGetRValue(colour);
current_green = RGBGetGValue(colour);
current_blue = RGBGetBValue(colour);
bool_random = random_colours;
SendUpdate();
}
}
void CMARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_count)
{
const unsigned char buffer_size = CM_ARGB_PACKET_SIZE;
unsigned char buffer[buffer_size] = { 0x00, 0x10, 0x02 };
unsigned char packet_count = 0;
std::vector<unsigned char> colours;
/*---------------------------------------------*\
| Set up the RGB triplets to send |
\*---------------------------------------------*/
for(unsigned int i = 0; i < led_count; i++)
{
RGBColor colour = led_colours[i];
colours.push_back( RGBGetRValue(colour) );
colours.push_back( RGBGetGValue(colour) );
colours.push_back( RGBGetBValue(colour) );
}
buffer[CM_ARGB_ZONE_BYTE] = argb_header_data[zone_index].header;
buffer[CM_ARGB_MODE_BYTE] = led_count;
unsigned char buffer_idx = CM_ARGB_MODE_BYTE + 1;
for(std::vector<unsigned char>::iterator it = colours.begin(); it != colours.end(); buffer_idx = 0)
{
/*-----------------------------------------------------------------*\
| Fill the write buffer till its full or the colour buffer is empty |
\*-----------------------------------------------------------------*/
buffer[CM_ARGB_REPORT_BYTE] = packet_count;
while (( buffer_idx < buffer_size) && ( it != colours.end() ))
{
buffer[buffer_idx] = *it;
buffer_idx++;
it++;
}
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
/*-----------------------------------------------------------------*\
| Reset the write buffer |
\*-----------------------------------------------------------------*/
memset(buffer, 0x00, buffer_size );
packet_count++;
}
buffer[CM_ARGB_REPORT_BYTE] = 0x82;
/*buffer[CM_ARGB_COMMAND_BYTE] = 0x62;
buffer[CM_ARGB_FUNCTION_BYTE] = 0x00;
buffer[CM_ARGB_ZONE_BYTE] = 0x73;
buffer[CM_ARGB_MODE_BYTE] = 0x00;
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = 0x33;
buffer[CM_ARGB_SPEED_BYTE] = 0x1B;*/
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
}
void CMARGBController::SendUpdate()
{
unsigned char buffer[CM_ARGB_PACKET_SIZE] = { 0x00 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
bool boolARGB_header = argb_header_data[zone_index].digital;
bool boolPassthru = ( current_mode == CM_ARGB_MODE_PASSTHRU ) || ( current_mode == CM_RGB_MODE_PASSTHRU );
bool boolDirect = ( current_mode == CM_ARGB_MODE_DIRECT );
unsigned char function = boolPassthru ? (boolARGB_header ? 0x02 : 0x04) : (boolARGB_header ? 0x01 : 0x03);
buffer[CM_ARGB_REPORT_BYTE] = 0x80;
buffer[CM_ARGB_COMMAND_BYTE] = 0x01;
buffer[CM_ARGB_FUNCTION_BYTE] = boolDirect ? 0x01 : function;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
/*-----------------------------------------------------------------*\
| Direct mode is now set up and no other mode packet is required |
\*-----------------------------------------------------------------*/
if(boolDirect)
{
return;
}
if(boolARGB_header)
{
buffer[CM_ARGB_COMMAND_BYTE] = 0x0b; //ARGB sends 0x0b (1011) RGB sends 0x04 (0100)
buffer[CM_ARGB_FUNCTION_BYTE] = (false) ? 0x01 : 0x02; //This controls direct mode TODO
buffer[CM_ARGB_ZONE_BYTE] = argb_header_data[zone_index].header;
buffer[CM_ARGB_MODE_BYTE] = current_mode;
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = bool_random ? 0x00 : 0x10;
buffer[CM_ARGB_SPEED_BYTE] = current_speed;
buffer[CM_ARGB_BRIGHTNESS_BYTE] = current_brightness;
buffer[CM_ARGB_RED_BYTE] = current_red;
buffer[CM_ARGB_GREEN_BYTE] = current_green;
buffer[CM_ARGB_BLUE_BYTE] = current_blue;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
}
else
{
buffer[CM_ARGB_COMMAND_BYTE] = boolPassthru ? 0x01 : 0x04; //ARGB sends 0x0b (1011) RGB sends 0x04 (0100)
buffer[CM_ARGB_MODE_BYTE + CM_RGB_OFFSET] = current_mode;
buffer[CM_ARGB_COLOUR_INDEX_BYTE + CM_RGB_OFFSET] = bool_random ? 0x00 : 0x10;
buffer[CM_ARGB_SPEED_BYTE + CM_RGB_OFFSET] = current_speed;
buffer[CM_ARGB_BRIGHTNESS_BYTE + CM_RGB_OFFSET] = current_brightness;
buffer[CM_ARGB_RED_BYTE + CM_RGB_OFFSET] = current_red;
buffer[CM_ARGB_GREEN_BYTE + CM_RGB_OFFSET] = current_green;
buffer[CM_ARGB_BLUE_BYTE + CM_RGB_OFFSET] = current_blue;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
}
}
@@ -1,137 +0,0 @@
/*-------------------------------------------------------------------*\
| CMARGBController.h |
| |
| Driver for Coolermaster ARGB USB Controller |
| |
| Chris M (Dr_No) 10th Oct 2020 |
| |
| Simple RGB device with 5 modes |
| |
\*-------------------------------------------------------------------*/
#include <string>
#include <array>
#include <cmath> //Needed by round()
#include <hidapi/hidapi.h>
#include "RGBController.h" //Needed to set the direct mode
#pragma once
#define CM_ARGB_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
#define CM_ARGB_HEADER_DATA_SIZE (sizeof(argb_header_data) / sizeof(argb_headers) )
#define CM_ARGB_INTERRUPT_TIMEOUT 250
#define CM_ARGB_PACKET_SIZE 65
#define CM_ARGB_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
#define CM_RGB_OFFSET -2
#define HID_MAX_STR 255
enum
{
CM_ARGB_REPORT_BYTE = 1,
CM_ARGB_COMMAND_BYTE = 2,
CM_ARGB_FUNCTION_BYTE = 3,
CM_ARGB_ZONE_BYTE = 4,
CM_ARGB_MODE_BYTE = 5,
CM_ARGB_COLOUR_INDEX_BYTE = 6,
CM_ARGB_SPEED_BYTE = 7,
CM_ARGB_BRIGHTNESS_BYTE = 8,
CM_ARGB_RED_BYTE = 9,
CM_ARGB_GREEN_BYTE = 10,
CM_ARGB_BLUE_BYTE = 11
};
struct argb_headers
{
const char* name;
unsigned char header;
bool digital;
unsigned int count;
};
static argb_headers argb_header_data[6] =
{
{ "RGB Header", 0xFE, false, 1 },
{ "Digital ARGB1", 0x01, true, 12 },
{ "Digital ARGB2", 0x02, true, 12 },
{ "Digital ARGB3", 0x04, true, 12 },
{ "Digital ARGB4", 0x08, true, 12 },
{ "All Digital ARGB", 0xFF, true, 12 }
};
enum
{
CM_RGB_MODE_MIRAGE = 0x01, //Mirage
CM_RGB_MODE_FLASH = 0x02, //Flash
CM_RGB_MODE_BREATHING = 0x03, //Breathing
CM_RGB_MODE_STATIC = 0x05, //Static
CM_RGB_MODE_OFF = 0x06, //Turn off
CM_RGB_MODE_PASSTHRU = 0xFF //Motherboard Pass Thru Mode
};
enum
{
CM_ARGB_MODE_OFF = 0x0B, //Turn off
CM_ARGB_MODE_SPECTRUM = 0x01, //Spectrum Mode
CM_ARGB_MODE_RELOAD = 0x02, //Reload Mode
CM_ARGB_MODE_RECOIL = 0x03, //Recoil Mode
CM_ARGB_MODE_BREATHING = 0x04, //Breathing Mode
CM_ARGB_MODE_REFILL = 0x05, //Refill Mode
CM_ARGB_MODE_DEMO = 0x06, //Demo Mode
CM_ARGB_MODE_FILLFLOW = 0x08, //Fill Flow Mode
CM_ARGB_MODE_RAINBOW = 0x09, //Rainbow Mode
CM_ARGB_MODE_STATIC = 0x0A, //Static Mode
CM_ARGB_MODE_DIRECT = 0xFE, //Direct Led Control
CM_ARGB_MODE_PASSTHRU = 0xFF //Motherboard Pass Thru Mode
};
enum
{
CM_ARGB_SPEED_SLOWEST = 0x00, // Slowest speed
CM_ARGB_SPEED_SLOW = 0x01, // Slower speed
CM_ARGB_SPEED_NORMAL = 0x02, // Normal speed
CM_ARGB_SPEED_FAST = 0x03, // Fast speed
CM_ARGB_SPEED_FASTEST = 0x04, // Fastest speed
};
class CMARGBController
{
public:
CMARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx);
~CMARGBController();
std::string GetDeviceName();
std::string GetSerial();
std::string GetLocation();
unsigned char GetZoneIndex();
unsigned char GetMode();
unsigned char GetLedRed();
unsigned char GetLedGreen();
unsigned char GetLedBlue();
unsigned char GetLedSpeed();
bool GetRandomColours();
void SetLedCount(int zone, int led_count);
void SetMode(unsigned char mode, unsigned char speed, RGBColor colour, bool random_colours);
void SetLedsDirect(RGBColor * led_colours, unsigned int led_count);
private:
std::string device_name;
std::string serial;
std::string location;
hid_device* dev;
unsigned char zone_index;
unsigned char current_mode;
unsigned char current_speed;
unsigned char current_red;
unsigned char current_green;
unsigned char current_blue;
unsigned char current_brightness;
bool bool_random;
unsigned int GetLargestColour(unsigned int red, unsigned int green, unsigned int blue);
unsigned char GetColourIndex(unsigned char red, unsigned char green, unsigned char blue);
void GetStatus();
void SendUpdate();
};
@@ -1,167 +0,0 @@
/*-------------------------------------------------------------------*\
| CMMKController.cpp |
| |
| Driver for Coolermaster MasterKeys Keyboards |
| |
| Lukas N (chmod222) 28th Jun 2020 |
| Tam D (too.manyhobbies) 25th Apr 2021 |
| |
\*-------------------------------------------------------------------*/
#include "CMMKController.h"
CMMKController::CMMKController(hid_device* dev, hid_device_info* dev_info)
{
location = dev_info->path;
const int szTemp = 256;
wchar_t tmpName[szTemp];
hid_get_manufacturer_string(dev, tmpName, szTemp);
std::wstring wName = std::wstring(tmpName);
device_name = std::string(wName.begin(), wName.end());
hid_get_product_string(dev, tmpName, szTemp);
wName = std::wstring(tmpName);
device_name.append(" ").append(std::string(wName.begin(), wName.end()));
cmmk_attach_path(&cmmk_handle, dev_info->path, dev_info->product_id, -1);
char buf[32] = {0};
cmmk_get_firmware_version(&cmmk_handle, buf, 32);
firmware_version = buf;
}
CMMKController::~CMMKController()
{
cmmk_detach(&cmmk_handle);
}
std::string CMMKController::GetDeviceName()
{
return device_name;
}
std::string CMMKController::GetLocation()
{
return location;
}
std::string CMMKController::GetFirmwareVersion()
{
return firmware_version;
}
void CMMKController::SetFirmwareControl()
{
ActivateMode(CMMK_FIRMWARE);
}
void CMMKController::SetManualControl()
{
ActivateMode(CMMK_MANUAL);
}
void CMMKController::SetSingle(int row, int col, struct rgb color)
{
cmmk_set_single_key(&cmmk_handle, row, col, &color);
}
void CMMKController::SetAll(struct cmmk_color_matrix const& colors)
{
cmmk_set_leds(&cmmk_handle, &colors);
}
void CMMKController::SetAllSingle(struct rgb color)
{
cmmk_set_all_single(&cmmk_handle, &color);
}
void CMMKController::SetMode(cmmk_effect_fully_lit eff)
{
ActivateEffect(CMMK_EFFECT_FULLY_LIT);
cmmk_set_effect_fully_lit(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_breathe eff)
{
ActivateEffect(CMMK_EFFECT_BREATHE);
cmmk_set_effect_breathe(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_cycle eff)
{
ActivateEffect(CMMK_EFFECT_CYCLE);
cmmk_set_effect_cycle(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_single eff)
{
ActivateEffect(CMMK_EFFECT_SINGLE);
cmmk_set_effect_single(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_wave eff)
{
ActivateEffect(CMMK_EFFECT_WAVE);
cmmk_set_effect_wave(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_ripple eff)
{
ActivateEffect(CMMK_EFFECT_RIPPLE);
cmmk_set_effect_ripple(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_cross eff)
{
ActivateEffect(CMMK_EFFECT_CROSS);
cmmk_set_effect_cross(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_raindrops eff)
{
ActivateEffect(CMMK_EFFECT_RAINDROPS);
cmmk_set_effect_raindrops(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_stars eff)
{
ActivateEffect(CMMK_EFFECT_STARS);
cmmk_set_effect_stars(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_snake eff)
{
ActivateEffect(CMMK_EFFECT_SNAKE);
cmmk_set_effect_snake(&cmmk_handle, &eff);
}
bool CMMKController::PositionValid(int y, int x)
{
return(cmmk_lookup_key_id(&cmmk_handle, y, x) >= 0);
}
void CMMKController::ActivateMode(int mode)
{
if (current_mode != mode)
{
cmmk_set_control_mode(&cmmk_handle, mode);
current_mode = mode;
current_effect = -1;
}
}
void CMMKController::ActivateEffect(int effect)
{
ActivateMode(CMMK_EFFECT);
if (current_effect != effect)
{
cmmk_set_active_effect(&cmmk_handle, (enum cmmk_effect_id)effect);
current_effect = effect;
}
}
@@ -1,58 +0,0 @@
/*-------------------------------------------------------------------*\
| CMMKController.h |
| |
| Driver for Coolermaster MasterKeys keyboards |
| |
| Lukas N (chmod222) 28th Jun 2020 |
| |
\*-------------------------------------------------------------------*/
#include <string>
#include <hidapi/hidapi.h>
#include <libcmmk/libcmmk.h>
#pragma once
class CMMKController
{
public:
CMMKController(hid_device* dev_handle, hid_device_info* dev_info);
~CMMKController();
std::string GetDeviceName();
std::string GetLocation();
std::string GetFirmwareVersion();
void SetFirmwareControl();
void SetManualControl();
void SetSingle(int row, int col, struct rgb color);
void SetAll(struct cmmk_color_matrix const& colors);
void SetAllSingle(struct rgb color);
void SetMode(cmmk_effect_fully_lit eff);
void SetMode(cmmk_effect_breathe eff);
void SetMode(cmmk_effect_cycle eff);
void SetMode(cmmk_effect_single eff);
void SetMode(cmmk_effect_wave eff);
void SetMode(cmmk_effect_ripple eff);
void SetMode(cmmk_effect_cross eff);
void SetMode(cmmk_effect_raindrops eff);
void SetMode(cmmk_effect_stars eff);
void SetMode(cmmk_effect_snake eff);
bool PositionValid(int y, int x);
private:
void ActivateMode(int mode);
void ActivateEffect(int effect);
int current_mode = -1;
int current_effect = -1;
std::string device_name;
std::string location;
std::string firmware_version;
mutable struct cmmk cmmk_handle;
};
@@ -9,42 +9,23 @@
#include "CMMP750Controller.h"
static unsigned char colour_mode_data[][6] =
CMMP750Controller::CMMP750Controller(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path)
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Off */
{ 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 */
};
int tmp_size = wcslen(_vendor);
static unsigned char speed_mode_data[9] =
{
0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 /* Speed Definition */
};
dev = dev_handle;
CMMP750Controller::CMMP750Controller(hid_device* dev_handle, char *_path)
{
dev = dev_handle;
location = _path;
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];
const int szTemp = 256;
wchar_t tmpName[szTemp];
location = _path;
hid_get_manufacturer_string(dev, tmpName, szTemp);
std::wstring wName = std::wstring(tmpName);
device_name = std::string(wName.begin(), wName.end());
hid_get_product_string(dev, tmpName, szTemp);
wName = std::wstring(tmpName);
device_name.append(" ").append(std::string(wName.begin(), wName.end()));
hid_get_serial_number_string(dev, tmpName, szTemp);
wName = std::wstring(tmpName);
serial = std::string(wName.begin(), wName.end());
GetStatus(); //When setting up device get current status
current_mode = MP750_MODE_STATIC;
current_speed = MP750_SPEED_NORMAL;
}
CMMP750Controller::~CMMP750Controller()
@@ -52,76 +33,19 @@ CMMP750Controller::~CMMP750Controller()
hid_close(dev);
}
void CMMP750Controller::GetStatus()
{
unsigned char buffer[0x41] = { 0x00 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
buffer[1] = 0x07;
hid_write(dev, buffer, buffer_size);
hid_read(dev, buffer, buffer_size);
if((buffer[0] == 0x80) && (buffer[1] == 0x05))
{
current_mode = buffer[2];
current_red = buffer[3];
current_green = buffer[4];
current_blue = buffer[5];
for(int i = 0; (speed_mode_data[i] >= buffer[6] && i <= MP750_SPEED_FASTEST); i++)
{
current_speed = i;
}
}
else
{
//Code should never reach here however just in case there is a failure set something
current_mode = CM_MP750_MODE_COLOR_CYCLE; //Unicorn Spew
current_red = 0xFF;
current_green = 0xFF;
current_blue = 0xFF;
current_speed = MP750_SPEED_NORMAL;
}
}
std::string CMMP750Controller::GetDeviceName()
char* CMMP750Controller::GetDeviceName()
{
return device_name;
}
std::string CMMP750Controller::GetSerial()
char* CMMP750Controller::GetSerial()
{
return serial;
}
std::string CMMP750Controller::GetLocation()
{
return("HID: " + location);
}
unsigned char CMMP750Controller::GetMode()
{
return current_mode;
}
unsigned char CMMP750Controller::GetLedRed()
{
return current_red;
}
unsigned char CMMP750Controller::GetLedGreen()
{
return current_green;
}
unsigned char CMMP750Controller::GetLedBlue()
{
return current_blue;
}
unsigned char CMMP750Controller::GetLedSpeed()
{
return current_speed;
return location;
}
void CMMP750Controller::SetMode(unsigned char mode, unsigned char speed)
@@ -143,27 +67,27 @@ void CMMP750Controller::SetColor(unsigned char red, unsigned char green, unsigne
void CMMP750Controller::SendUpdate()
{
unsigned char buffer[0x41] = { 0x00 };
unsigned char buffer[0x40] = { 0x00 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
for(std::size_t i = 0; i < CM_COLOUR_MODE_DATA_SIZE; i++)
for(int i = 0; i < CM_COLOUR_MODE_DATA_SIZE; i++)
{
buffer[i+1] = colour_mode_data[current_mode][i];
buffer[i] = colour_mode_data[current_mode][i];
}
if(current_mode > CM_MP750_MODE_BREATHING)
if(current_mode > MP750_MODE_BREATHING)
{
//If the mode is random colours set SPEED at BYTE2
buffer[CM_RED_BYTE] = speed_mode_data[current_speed];
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_speed];
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);
}
}
@@ -20,7 +20,7 @@
#pragma once
#define CM_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
#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 ]))
@@ -28,22 +28,38 @@
enum
{
CM_MODE_BYTE = 1,
CM_LENGTH_BYTE = 2,
CM_RED_BYTE = 3,
CM_GREEN_BYTE = 4,
CM_BLUE_BYTE = 5,
CM_SPEED_BYTE = 6
CM_MODE_BYTE = 0,
CM_RED_BYTE = 2,
CM_GREEN_BYTE = 3,
CM_BLUE_BYTE = 4,
CM_SPEED_BYTE = 5
};
enum
{
CM_MP750_MODE_OFF = 0x00, //Off
CM_MP750_MODE_STATIC = 0x01, //Static Mode
CM_MP750_MODE_BLINK = 0x02, //Blinking Mode
CM_MP750_MODE_BREATHING = 0x03, //Breathing Mode
CM_MP750_MODE_COLOR_CYCLE = 0x04, //Color Cycle Mode
CM_MP750_MODE_BREATH_CYCLE = 0x05 //Breathing Cycle Mode
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
@@ -62,24 +78,19 @@ enum
class CMMP750Controller
{
public:
CMMP750Controller(hid_device* dev_handle, char *_path);
CMMP750Controller(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path);
~CMMP750Controller();
std::string GetDeviceName();
std::string GetSerial();
char* GetDeviceName();
char* GetSerial();
std::string GetLocation();
unsigned char GetMode();
unsigned char GetLedRed();
unsigned char GetLedGreen();
unsigned char GetLedBlue();
unsigned char GetLedSpeed();
void SetMode(unsigned char mode, unsigned char speed);
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
private:
std::string device_name;
std::string serial;
char device_name[32];
char serial[32];
std::string location;
hid_device* dev;
@@ -90,6 +101,5 @@ private:
unsigned char current_green;
unsigned char current_blue;
void GetStatus();
void SendUpdate();
};
@@ -1,196 +0,0 @@
/*-------------------------------------------------------------------*\
| CMR6000Controller.cpp |
| |
| Driver for Coolermaster based AMD Radeon GPU (6000 series) |
| |
| Eric S (edbgon) 2nd Feb 2021 |
\*-------------------------------------------------------------------*/
#include "CMR6000Controller.h"
#include <cstring>
CMR6000Controller::CMR6000Controller(hid_device* dev_handle, char *_path)
{
dev = dev_handle;
location = _path;
const int szTemp = 256;
wchar_t tmpName[szTemp];
hid_get_manufacturer_string(dev, tmpName, szTemp);
std::wstring wName = std::wstring(tmpName);
device_name = std::string(wName.begin(), wName.end());
hid_get_product_string(dev, tmpName, szTemp);
wName = std::wstring(tmpName);
device_name.append(" ").append(std::string(wName.begin(), wName.end()));
hid_get_serial_number_string(dev, tmpName, szTemp);
wName = std::wstring(tmpName);
serial = std::string(wName.begin(), wName.end());
GetStatus(); //When setting up device get current status
}
CMR6000Controller::~CMR6000Controller()
{
if(dev)
{
hid_close(dev);
}
}
void CMR6000Controller::GetStatus()
{
unsigned char buffer[CM_6K_PACKET_SIZE] = { 0x00, 0x52, 0xA0, 0x01, 0x00, 0x00, 0x03 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
// Request mode
hid_write(dev, buffer, buffer_size);
hid_read(dev, buffer, buffer_size);
unsigned char cmdbuffer[CM_6K_PACKET_SIZE] = { 0x00, 0x52, 0x2C, 0x01, 0x00 };
int cmdbuffer_size = (sizeof(cmdbuffer) / sizeof(cmdbuffer[0]));
current_mode = buffer[0x0A];
cmdbuffer[0x05] = current_mode;
hid_write(dev, cmdbuffer, cmdbuffer_size);
hid_read(dev, cmdbuffer, cmdbuffer_size);
current_speed = cmdbuffer[0x05];
current_brightness = cmdbuffer[0x09];
current_red = cmdbuffer[0x0A];
current_green = cmdbuffer[0x0B];
current_blue = cmdbuffer[0x0C];
}
std::string CMR6000Controller::GetDeviceName()
{
return device_name;
}
std::string CMR6000Controller::GetSerial()
{
return serial;
}
std::string CMR6000Controller::GetLocation()
{
return("HID: " + location);
}
unsigned char CMR6000Controller::GetMode()
{
return current_mode;
}
unsigned char CMR6000Controller::GetLedRed()
{
return current_red;
}
unsigned char CMR6000Controller::GetLedGreen()
{
return current_green;
}
unsigned char CMR6000Controller::GetLedBlue()
{
return current_blue;
}
unsigned char CMR6000Controller::GetLedSpeed()
{
return current_speed;
}
bool CMR6000Controller::GetRandomColours()
{
return current_random;
}
void CMR6000Controller::SetMode(unsigned char mode, unsigned char speed, unsigned char red, unsigned char green, unsigned char blue, unsigned char random)
{
current_mode = mode;
current_speed = speed;
current_red = red;
current_green = green;
current_blue = blue;
current_random = random;
current_brightness = (current_mode == CM_MR6000_MODE_COLOR_CYCLE) ? 0x7F : 0xFF; //Color_Cycle brightness needs to be clamped to 0x7F to avoid wash out
SendUpdate();
}
void CMR6000Controller::SendUpdate()
{
if(current_mode == CM_MR6000_MODE_OFF)
{
unsigned char buffer[CM_6K_PACKET_SIZE] = { 0x00, 0x41, 0x43 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
hid_write(dev, buffer, buffer_size);
}
else
{
SendEnableCommand();
unsigned char buffer[CM_6K_PACKET_SIZE] = { 0x00 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
memset(buffer, 0xFF, buffer_size);
buffer[0x00] = 0x00;
buffer[0x01] = 0x51;
buffer[0x02] = 0x2C;
buffer[0x03] = 0x01;
buffer[0x04] = 0x00;
buffer[0x05] = current_mode;
buffer[0x06] = (current_mode == CM_MR6000_MODE_STATIC) ? 0xFF: current_speed;
buffer[0x07] = (current_mode == CM_MR6000_MODE_BREATHE)? current_random : 0x00; //random (A0)
buffer[0x08] = (current_mode == CM_MR6000_MODE_BREATHE)? 0x03 : 0xFF;
//buffer[0x09] = 0xFF;
buffer[0x0A] = current_brightness;
buffer[0x0B] = (current_mode == CM_MR6000_MODE_COLOR_CYCLE) ? 0xFF : current_red;
buffer[0x0C] = (current_mode == CM_MR6000_MODE_COLOR_CYCLE) ? 0xFF : current_green;
buffer[0x0D] = (current_mode == CM_MR6000_MODE_COLOR_CYCLE) ? 0xFF : current_blue;
buffer[0x0E] = 0x00;
buffer[0x0F] = 0x00;
buffer[0x10] = 0x00;
hid_write(dev, buffer, buffer_size);
SendColourConfig();
SendApplyCommand();
}
}
void CMR6000Controller::SendEnableCommand()
{
unsigned char buffer[CM_6K_PACKET_SIZE] = { 0x00, 0x41, 0x80 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_6K_INTERRUPT_TIMEOUT);
}
void CMR6000Controller::SendApplyCommand()
{
unsigned char buffer[CM_6K_PACKET_SIZE] = { 0x00, 0x51, 0x28, 0x00, 0x00, 0xE0 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_6K_INTERRUPT_TIMEOUT);
}
void CMR6000Controller::SendColourConfig()
{
unsigned char buffer[CM_6K_PACKET_SIZE] = { 0x00, 0x51, 0xA0, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x05, 0x06 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
for(int i = 0x0B; i < 0x1A; i++)
{
buffer[i] = current_mode;
}
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_6K_INTERRUPT_TIMEOUT);
}
@@ -1,82 +0,0 @@
/*-------------------------------------------------------------------*\
| CMR6000Controller.h |
| |
| Driver for Coolermaster based AMD Radeon GPU (6000 series) |
| |
| Eric S (edbgon) 2nd Feb 2021 |
\*-------------------------------------------------------------------*/
#include <string>
#include <array>
#include <hidapi/hidapi.h>
#pragma once
#define CM_6K_PACKET_SIZE 65 //Includes extra first byte for non HID Report packets
#define CM_6K_INTERRUPT_TIMEOUT 250
#define CM_6K_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
#define CM_6K_SERIAL_SIZE (sizeof(serial) / sizeof(serial[ 0 ]))
#define HID_MAX_STR 255
enum
{
CM_MR6000_MODE_STATIC = 0x00, //Static Mode
CM_MR6000_MODE_BREATHE = 0x01, //Breathe Mode
CM_MR6000_MODE_COLOR_CYCLE = 0x02, //Color cycle
CM_MR6000_MODE_OFF = 0xFF, //Off
};
enum
{
MR6000_CYCLE_SPEED_SLOWEST = 0x96, /* Slowest speed */
MR6000_CYCLE_SPEED_SLOW = 0x8C, /* Slow speed */
MR6000_CYCLE_SPEED_NORMAL = 0x80, /* Normal speed */
MR6000_CYCLE_SPEED_FAST = 0x6E, /* Fast speed */
MR6000_CYCLE_SPEED_FASTEST = 0x68, /* Fastest speed */
MR6000_BREATHE_SPEED_SLOWEST = 0x3C, /* Slowest speed */
MR6000_BREATHE_SPEED_SLOW = 0x37, /* Slow speed */
MR6000_BREATHE_SPEED_NORMAL = 0x31, /* Normal speed */
MR6000_BREATHE_SPEED_FAST = 0x2C, /* Fast speed */
MR6000_BREATHE_SPEED_FASTEST = 0x26, /* Fastest speed */
};
class CMR6000Controller
{
public:
CMR6000Controller(hid_device* dev_handle, char *_path);
~CMR6000Controller();
std::string GetDeviceName();
std::string GetSerial();
std::string GetLocation();
unsigned char GetMode();
unsigned char GetLedRed();
unsigned char GetLedGreen();
unsigned char GetLedBlue();
unsigned char GetLedSpeed();
bool GetRandomColours();
void SetMode(unsigned char mode, unsigned char speed, unsigned char red, unsigned char green, unsigned char blue, unsigned char random);
private:
std::string device_name;
std::string serial;
std::string location;
hid_device* dev;
unsigned char current_mode;
unsigned char current_speed;
unsigned char current_random;
unsigned char current_red;
unsigned char current_green;
unsigned char current_blue;
unsigned char current_brightness;
void GetStatus();
void SendUpdate();
void SendEnableCommand();
void SendApplyCommand();
void SendColourConfig();
};
@@ -1,237 +0,0 @@
/*-------------------------------------------------------------------*\
| CMSmallARGBController.cpp |
| |
| Driver for Coolermaster Small ARGB USB Controller |
| |
| Chris M (Dr_No) 31st Jan 2021 |
| |
| Simple RGB device with 5 modes |
| |
\*-------------------------------------------------------------------*/
#include "CMSmallARGBController.h"
#include <cstring>
CMSmallARGBController::CMSmallARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx)
{
const int szTemp = 256;
wchar_t tmpName[szTemp];
dev = dev_handle;
location = _path;
zone_index = _zone_idx;
current_speed = CM_SMALL_ARGB_SPEED_NORMAL;
hid_get_manufacturer_string(dev, tmpName, szTemp);
std::wstring wName = std::wstring(tmpName);
device_name = std::string(wName.begin(), wName.end());
hid_get_product_string(dev, tmpName, szTemp);
wName = std::wstring(tmpName);
device_name.append(" ").append(std::string(wName.begin(), wName.end()));
hid_get_serial_number_string(dev, tmpName, szTemp);
wName = std::wstring(tmpName);
serial = std::string(wName.begin(), wName.end());
GetStatus();
}
CMSmallARGBController::~CMSmallARGBController()
{
if(dev)
{
hid_close(dev);
}
}
void CMSmallARGBController::GetStatus()
{
unsigned char buffer[CM_SMALL_ARGB_PACKET_SIZE] = { 0x00, 0x80, 0x01, 0x01 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
int header = zone_index - 1;
buffer[CM_SMALL_ARGB_ZONE_BYTE] = header;
buffer[CM_SMALL_ARGB_MODE_BYTE] = 0x01;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_SMALL_ARGB_INTERRUPT_TIMEOUT);
memset(buffer, 0x00, buffer_size );
buffer[CM_SMALL_ARGB_COMMAND_BYTE] = 0x0B;
buffer[CM_SMALL_ARGB_FUNCTION_BYTE] = 0x01;
buffer[CM_SMALL_ARGB_ZONE_BYTE] = 0x01;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_SMALL_ARGB_INTERRUPT_TIMEOUT);
current_mode = buffer[4];
current_speed = buffer[5];
bool_random = buffer[6] == 0x00;
current_brightness = buffer[7];
current_red = buffer[8];
current_green = buffer[9];
current_blue = buffer[10];
}
std::string CMSmallARGBController::GetDeviceName()
{
return device_name;
}
std::string CMSmallARGBController::GetSerial()
{
return serial;
}
std::string CMSmallARGBController::GetLocation()
{
return("HID: " + location);
}
unsigned char CMSmallARGBController::GetZoneIndex()
{
return zone_index;
}
unsigned char CMSmallARGBController::GetMode()
{
return current_mode;
}
unsigned char CMSmallARGBController::GetLedRed()
{
return current_red;
}
unsigned char CMSmallARGBController::GetLedGreen()
{
return current_green;
}
unsigned char CMSmallARGBController::GetLedBlue()
{
return current_blue;
}
unsigned char CMSmallARGBController::GetLedSpeed()
{
return current_speed;
}
bool CMSmallARGBController::GetRandomColours()
{
return bool_random;
}
void CMSmallARGBController::SetLedCount(int zone, int led_count)
{
unsigned char buffer[CM_SMALL_ARGB_PACKET_SIZE] = { 0x00, 0x80, 0x0D, 0x02 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
buffer[CM_SMALL_ARGB_ZONE_BYTE] = zone;
buffer[CM_SMALL_ARGB_MODE_BYTE] = (0x0F - led_count > 0) ? 0x0F - led_count : 0x01;
buffer[CM_SMALL_ARGB_SPEED_BYTE] = led_count;
hid_write(dev, buffer, buffer_size);
}
void CMSmallARGBController::SetMode(unsigned char mode, unsigned char speed, RGBColor colour, bool random_colours)
{
current_mode = mode;
current_speed = speed;
current_red = RGBGetRValue(colour);
current_green = RGBGetGValue(colour);
current_blue = RGBGetBValue(colour);
bool_random = random_colours;
SendUpdate();
}
void CMSmallARGBController::SetLedsDirect(RGBColor* /*led_colours*/, unsigned int /*led_count*/)
{
// Mode not yet Tested
/*
const unsigned char buffer_size = 0x41;
unsigned char buffer[buffer_size] = { 0x00 };
unsigned char packet_count = 0x00;
std::vector<unsigned char> colours;
//Set up the RGB triplets to send
for(int i = 0; i < led_count; i++)
{
RGBColor colour = led_colours[i];
unsigned char r = RGBGetRValue(colour);
unsigned char g = RGBGetGValue(colour);
unsigned char b = RGBGetBValue(colour);
colours.push_back(r);
colours.push_back(g);
colours.push_back(b);
}
//buffer[CM_ARGB_REPORT_BYTE] = packet_count;
buffer[CM_SMALL_ARGB_COMMAND_BYTE] = 0x10;
buffer[CM_SMALL_ARGB_FUNCTION_BYTE] = 0x02;
buffer[CM_SMALL_ARGB_ZONE_BYTE] = small_argb_header_data[zone_index].header;
buffer[CM_SMALL_ARGB_MODE_BYTE] = 0x30; //30 might be the LED count??
unsigned char buffer_idx = CM_SMALL_ARGB_MODE_BYTE + 1; //Start colour info from
for (std::vector<unsigned char>::iterator it = colours.begin(); it != colours.end(); buffer_idx = 0)
{
//Fill the write buffer till its full or the colour buffer is empty
buffer[CM_SMALL_ARGB_REPORT_BYTE] = packet_count;
while (( buffer_idx < buffer_size) && ( it != colours.end() ))
{
buffer[buffer_idx] = *it;
buffer_idx++;
it++;
}
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_SMALL_ARGB_INTERRUPT_TIMEOUT);
//reset the write buffer
memset(buffer, 0x00, sizeof(buffer) );
packet_count++;
}
buffer[CM_SMALL_ARGB_REPORT_BYTE] = 0x82;
buffer[CM_SMALL_ARGB_COMMAND_BYTE] = 0x62;
buffer[CM_SMALL_ARGB_FUNCTION_BYTE] = 0x00;
buffer[CM_SMALL_ARGB_ZONE_BYTE] = 0x73;
buffer[CM_SMALL_ARGB_MODE_BYTE] = 0x00;
buffer[CM_SMALL_ARGB_SPEED_BYTE] = 0x33;
buffer[CM_SMALL_ARGB_COLOUR_INDEX_BYTE] = 0x18;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_SMALL_ARGB_INTERRUPT_TIMEOUT);
*/
}
void CMSmallARGBController::SendUpdate()
{
unsigned char buffer[CM_SMALL_ARGB_PACKET_SIZE] = { 0x00 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
bool boolPassthru = ( current_mode == CM_SMALL_ARGB_MODE_PASSTHRU );
bool boolDirect = ( current_mode == CM_SMALL_ARGB_MODE_DIRECT );
unsigned char function = boolPassthru ? 0x02 : 0x01;
buffer[CM_SMALL_ARGB_REPORT_BYTE] = 0x80;
buffer[CM_SMALL_ARGB_COMMAND_BYTE] = boolDirect ? 0x10 : 0x01;
buffer[CM_SMALL_ARGB_FUNCTION_BYTE] = boolDirect ? 0x01 : function;
buffer[CM_SMALL_ARGB_MODE_BYTE] = boolPassthru ? 0x00 : 0x02;
hid_write(dev, buffer, buffer_size);
buffer[CM_SMALL_ARGB_COMMAND_BYTE] = 0x0b;
buffer[CM_SMALL_ARGB_FUNCTION_BYTE] = (false) ? 0x01 : 0x02; //This controls custom mode TODO
buffer[CM_SMALL_ARGB_ZONE_BYTE] = small_argb_header_data[zone_index].header;
buffer[CM_SMALL_ARGB_MODE_BYTE] = current_mode;
buffer[CM_SMALL_ARGB_SPEED_BYTE] = current_speed;
buffer[CM_SMALL_ARGB_COLOUR_INDEX_BYTE] = (bool_random) ? 0x00 : 0x10; //This looks to still be the colour index and controls random colours
buffer[CM_SMALL_ARGB_BRIGHTNESS_BYTE] = 0xFF;
buffer[CM_SMALL_ARGB_RED_BYTE] = current_red;
buffer[CM_SMALL_ARGB_GREEN_BYTE] = current_green;
buffer[CM_SMALL_ARGB_BLUE_BYTE] = current_blue;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_SMALL_ARGB_INTERRUPT_TIMEOUT);
}
@@ -1,113 +0,0 @@
/*-------------------------------------------------------------------*\
| CMSmallARGBController.h |
| |
| Driver for Coolermaster Small ARGB USB Controller |
| |
| Chris M (Dr_No) 31st Jan 2021 |
| |
| Simple RGB device with 5 modes |
| |
\*-------------------------------------------------------------------*/
#include <string>
#include <array>
#include <hidapi/hidapi.h>
#include "RGBController.h" //Needed to set the direct mode
#pragma once
#define CM_SMALL_ARGB_PACKET_SIZE 65
#define CM_SMALL_ARGB_INTERRUPT_TIMEOUT 250
enum
{
CM_SMALL_ARGB_REPORT_BYTE = 1,
CM_SMALL_ARGB_COMMAND_BYTE = 2,
CM_SMALL_ARGB_FUNCTION_BYTE = 3,
CM_SMALL_ARGB_ZONE_BYTE = 4,
CM_SMALL_ARGB_MODE_BYTE = 5,
CM_SMALL_ARGB_SPEED_BYTE = 6,
CM_SMALL_ARGB_COLOUR_INDEX_BYTE = 7, //Not used on the small controller
CM_SMALL_ARGB_BRIGHTNESS_BYTE = 8, //0x00 thru 0xFF
CM_SMALL_ARGB_RED_BYTE = 9,
CM_SMALL_ARGB_GREEN_BYTE = 10,
CM_SMALL_ARGB_BLUE_BYTE = 11,
};
struct _argb_headers
{
const char* name;
unsigned char header;
bool digital;
unsigned int count;
};
static _argb_headers small_argb_header_data[1] =
{
{ "CM Small ARGB", 0x01, true, 12 }
};
enum
{
CM_SMALL_ARGB_MODE_SPECTRUM = 0x01, //Spectrum Mode
CM_SMALL_ARGB_MODE_RELOAD = 0x02, //Reload Mode
CM_SMALL_ARGB_MODE_RECOIL = 0x03, //Recoil Mode
CM_SMALL_ARGB_MODE_BREATHING = 0x04, //Breathing Mode
CM_SMALL_ARGB_MODE_REFILL = 0x05, //Refill Mode
CM_SMALL_ARGB_MODE_DEMO = 0x06, //Demo Mode
CM_SMALL_ARGB_MODE_OFF = 0x09, //Turn off
CM_SMALL_ARGB_MODE_DIRECT = 0xFE, //Direct Led Control (possibly N?A for small controller)
CM_SMALL_ARGB_MODE_PASSTHRU = 0xFF //Motherboard Pass Thru Mode
};
enum
{
CM_SMALL_ARGB_SPEED_SLOWEST = 0x00, // Slowest speed
CM_SMALL_ARGB_SPEED_SLOW = 0x01, // Slower speed
CM_SMALL_ARGB_SPEED_NORMAL = 0x02, // Normal speed
CM_SMALL_ARGB_SPEED_FAST = 0x03, // Fast speed
CM_SMALL_ARGB_SPEED_FASTEST = 0x04, // Fastest speed
};
class CMSmallARGBController
{
public:
CMSmallARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx);
~CMSmallARGBController();
std::string GetDeviceName();
std::string GetSerial();
std::string GetLocation();
unsigned char GetZoneIndex();
unsigned char GetMode();
unsigned char GetLedRed();
unsigned char GetLedGreen();
unsigned char GetLedBlue();
unsigned char GetLedSpeed();
bool GetRandomColours();
void SetLedCount(int zone, int led_count);
void SetMode(unsigned char mode, unsigned char speed, RGBColor colour, bool random_colours);
void SetLedsDirect(RGBColor * led_colours, unsigned int led_count);
private:
std::string device_name;
std::string serial;
std::string location;
hid_device* dev;
unsigned char zone_index;
unsigned char current_mode;
unsigned char current_speed;
unsigned char current_red;
unsigned char current_green;
unsigned char current_blue;
unsigned char current_brightness;
bool bool_random;
unsigned int GetLargestColour(unsigned int red, unsigned int green, unsigned int blue);
unsigned char GetColourIndex(unsigned char red, unsigned char green, unsigned char blue);
void GetStatus();
void SendUpdate();
};
@@ -1,30 +1,26 @@
#include "Detector.h"
#include "CMMP750Controller.h"
#include "CMARGBcontroller.h"
#include "CMSmallARGBController.h"
#include "CMR6000Controller.h"
#include "CMMKController.h"
#include "RGBController.h"
#include "RGBController_CMMP750Controller.h"
#include "RGBController_CMARGBController.h"
#include "RGBController_CMSmallARGBController.h"
#include "RGBController_CMR6000Controller.h"
#include "RGBController_CMMKController.h"
#include <hidapi/hidapi.h>
#define COOLERMASTER_VID 0x2516
#define COOLERMASTER_VID 0x2516
#define COOLERMASTER_MP750_XL_PID 0x0109
#define COOLERMASTER_MP750_MEDIUM_PID 0x0105
#define COOLERMASTER_ARGB_PID 0x1011
#define COOLERMASTER_SMALL_ARGB_PID 0x1000
#define COOLERMASTER_RADEON_6000_PID 0x014D
#define COOLERMASTER_MASTERKEYS_PRO_L_PID CMMK_USB_MASTERKEYS_MK750
#define COOLERMASTER_MASTERKEYS_PRO_L_WHITE_PID CMMK_USB_MASTERKEYS_PRO_L_WHITE
#define COOLERMASTER_MASTERKEYS_PRO_S_PID CMMK_USB_MASTERKEYS_PRO_S
#define COOLERMASTER_MASTERKEYS_MK750_PID CMMK_USB_MASTERKEYS_MK750
#define COOLERMASTER_MASTERKEYS_SK630_PID CMMK_USB_MASTERKEYS_SK630
#define COOLERMASTER_MASTERKEYS_SK650_PID CMMK_USB_MASTERKEYS_SK650
#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)
};
/******************************************************************************************\
* *
@@ -34,78 +30,37 @@
* *
\******************************************************************************************/
void DetectCoolerMasterMousemats(hid_device_info* info, const std::string&)
void DetectCoolerMasterControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CMMP750Controller* controller = new CMMP750Controller(dev, info->path);
RGBController_CMMP750Controller* rgb_controller = new RGBController_CMMP750Controller(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
hid_device_info* info;
void DetectCoolerMasterARGB(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
//Look for the passed in cm_pids
hid_init();
info = hid_enumerate(0x0, 0x0);
while(info)
{
for(std::size_t i = 0; i < CM_ARGB_HEADER_DATA_SIZE; i++)
hid_device* dev = NULL;
if(info->vendor_id == COOLERMASTER_VID)
{
CMARGBController* controller = new CMARGBController(dev, info->path, i);
RGBController_CMARGBController* rgb_controller = new RGBController_CMARGBController(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
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);
}
void DetectCoolerMasterSmallARGB(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CMSmallARGBController* controller = new CMSmallARGBController(dev, info->path, 0);
RGBController_CMSmallARGBController* rgb_controller = new RGBController_CMSmallARGBController(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectCoolerMasterGPU(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CMR6000Controller* controller = new CMR6000Controller(dev, info->path);
RGBController_CMR6000Controller* rgb_controller = new RGBController_CMR6000Controller(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectCoolerMasterKeyboards(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CMMKController* controller = new CMMKController(dev, info);
RGBController_CMMKController* rgb_controller = new RGBController_CMMKController(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 XL", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_XL_PID, 0xFF00, 1 );
REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 Medium", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_MEDIUM_PID, 0xFF00, 1 );
REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro L", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_PRO_L_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro L White", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_PRO_L_WHITE_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro S", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_PRO_S_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master MK570", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_MK750_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master SK630", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_SK630_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master SK650", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_SK650_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB", DetectCoolerMasterARGB, COOLERMASTER_VID, COOLERMASTER_ARGB_PID, 0, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master Smalll ARGB", DetectCoolerMasterSmallARGB, COOLERMASTER_VID, COOLERMASTER_SMALL_ARGB_PID, 0, 0xFF00, 1);
REGISTER_HID_DETECTOR_I ("Cooler Master Radeon 6000 GPU", DetectCoolerMasterGPU, COOLERMASTER_VID, COOLERMASTER_RADEON_6000_PID, 1 );
@@ -1,386 +0,0 @@
/*-------------------------------------------------------------------*\
| RGBController_CMARGBController.cpp |
| |
| Driver for Coolermaster ARGB Controller |
| |
| Chris M (Dr_No) 14th Oct 2020 |
| |
\*-------------------------------------------------------------------*/
#include "RGBController_CMARGBController.h"
RGBController_CMARGBController::RGBController_CMARGBController(CMARGBController *cmargb_ptr)
{
cmargb = cmargb_ptr;
unsigned char speed = cmargb->GetLedSpeed();
name = argb_header_data[cmargb->GetZoneIndex()].name;
vendor = "Cooler Master";
type = DEVICE_TYPE_LEDSTRIP;
description = cmargb->GetDeviceName();
version = "2.0 for FW0023";
serial = cmargb->GetSerial();
location = cmargb->GetLocation();
if(argb_header_data[cmargb->GetZoneIndex()].digital)
{
mode Off;
Off.name = "Turn Off";
Off.value = CM_ARGB_MODE_OFF;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Reload;
Reload.name = "Reload";
Reload.value = CM_ARGB_MODE_RELOAD;
Reload.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Reload.colors_min = 1;
Reload.colors_max = 1;
Reload.colors.resize(Reload.colors_max);
Reload.speed_min = CM_ARGB_SPEED_SLOWEST;
Reload.speed_max = CM_ARGB_SPEED_FASTEST;
Reload.color_mode = MODE_COLORS_MODE_SPECIFIC;
Reload.speed = speed;
modes.push_back(Reload);
mode Recoil;
Recoil.name = "Recoil";
Recoil.value = CM_ARGB_MODE_RECOIL;
Recoil.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Recoil.colors_min = 1;
Recoil.colors_max = 1;
Recoil.colors.resize(Recoil.colors_max);
Recoil.speed_min = CM_ARGB_SPEED_SLOWEST;
Recoil.speed_max = CM_ARGB_SPEED_FASTEST;
Recoil.color_mode = MODE_COLORS_MODE_SPECIFIC;
Recoil.speed = speed;
modes.push_back(Recoil);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = CM_ARGB_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(Breathing.colors_max);
Breathing.speed_min = CM_ARGB_SPEED_SLOWEST;
Breathing.speed_max = CM_ARGB_SPEED_FASTEST;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.speed = speed;
modes.push_back(Breathing);
mode Refill;
Refill.name = "Refill";
Refill.value = CM_ARGB_MODE_REFILL;
Refill.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Refill.colors_min = 1;
Refill.colors_max = 1;
Refill.colors.resize(Refill.colors_max);
Refill.speed_min = CM_ARGB_SPEED_SLOWEST;
Refill.speed_max = CM_ARGB_SPEED_FASTEST;
Refill.color_mode = MODE_COLORS_MODE_SPECIFIC;
Refill.speed = speed;
modes.push_back(Refill);
mode Demo;
Demo.name = "Demo";
Demo.value = CM_ARGB_MODE_DEMO;
Demo.flags = MODE_FLAG_HAS_SPEED;
Demo.speed_min = CM_ARGB_SPEED_SLOWEST;
Demo.speed_max = CM_ARGB_SPEED_FASTEST;
Demo.color_mode = MODE_COLORS_NONE;
Demo.speed = speed;
modes.push_back(Demo);
mode Spectrum;
Spectrum.name = "Spectrum";
Spectrum.value = CM_ARGB_MODE_SPECTRUM;
Spectrum.flags = MODE_FLAG_HAS_SPEED;
Spectrum.speed_min = CM_ARGB_SPEED_SLOWEST;
Spectrum.speed_max = CM_ARGB_SPEED_FASTEST;
Spectrum.color_mode = MODE_COLORS_NONE;
Spectrum.speed = speed;
modes.push_back(Spectrum);
mode FillFlow;
FillFlow.name = "Fill Flow";
FillFlow.value = CM_ARGB_MODE_FILLFLOW;
FillFlow.flags = MODE_FLAG_HAS_SPEED;
FillFlow.speed_min = CM_ARGB_SPEED_SLOWEST;
FillFlow.speed_max = CM_ARGB_SPEED_FASTEST;
FillFlow.color_mode = MODE_COLORS_NONE;
FillFlow.speed = speed;
modes.push_back(FillFlow);
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = CM_ARGB_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED;
Rainbow.speed_min = CM_ARGB_SPEED_SLOWEST;
Rainbow.speed_max = CM_ARGB_SPEED_FASTEST;
Rainbow.color_mode = MODE_COLORS_NONE;
Rainbow.speed = speed;
modes.push_back(Rainbow);
mode Static;
Static.name = "Static";
Static.value = CM_ARGB_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(Static.colors_max);
Static.speed_min = CM_ARGB_SPEED_SLOWEST;
Static.speed_max = CM_ARGB_SPEED_FASTEST;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.speed = speed;
modes.push_back(Static);
mode Direct;
Direct.name = "Direct";
Direct.value = CM_ARGB_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode PassThru;
PassThru.name = "Pass Thru";
PassThru.value = CM_ARGB_MODE_PASSTHRU;
PassThru.flags = 0;
PassThru.color_mode = MODE_COLORS_NONE;
modes.push_back(PassThru);
}
else
{
mode Static;
Static.name = "Static";
Static.value = CM_RGB_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(Static.colors_max);
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.speed = 0;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = CM_RGB_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(Breathing.colors_max);
Breathing.speed_min = CM_ARGB_SPEED_SLOWEST;
Breathing.speed_max = CM_ARGB_SPEED_FASTEST;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.speed = CM_ARGB_SPEED_NORMAL;
modes.push_back(Breathing);
mode Flash;
Flash.name = "Flash";
Flash.value = CM_RGB_MODE_FLASH;
Flash.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Flash.colors_min = 1;
Flash.colors_max = 1;
Flash.colors.resize(Flash.colors_max);
Flash.speed_min = CM_ARGB_SPEED_SLOWEST;
Flash.speed_max = CM_ARGB_SPEED_FASTEST;
Flash.color_mode = MODE_COLORS_MODE_SPECIFIC;
Flash.speed = CM_ARGB_SPEED_NORMAL;
modes.push_back(Flash);
mode Mirage;
Mirage.name = "Mirage";
Mirage.value = CM_RGB_MODE_MIRAGE;
Mirage.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Mirage.colors_min = 1;
Mirage.colors_max = 1;
Mirage.colors.resize(Mirage.colors_max);
Mirage.speed_min = CM_ARGB_SPEED_SLOWEST;
Mirage.speed_max = CM_ARGB_SPEED_FASTEST;
Mirage.color_mode = MODE_COLORS_MODE_SPECIFIC;
Mirage.speed = CM_ARGB_SPEED_NORMAL;
modes.push_back(Mirage);
mode PassThru;
PassThru.name = "Pass Thru";
PassThru.value = CM_RGB_MODE_PASSTHRU;
PassThru.color_mode = MODE_COLORS_NONE;
modes.push_back(PassThru);
mode Off;
Off.name = "Turn Off";
Off.value = CM_RGB_MODE_OFF;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
}
Init_Controller();
SetupZones();
int temp_mode = cmargb->GetMode();
for(std::size_t mode_idx = 0; mode_idx < modes.size() ; mode_idx++)
{
if (temp_mode == modes[mode_idx].value)
{
active_mode = mode_idx;
break;
}
}
if (modes[active_mode].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
{
modes[active_mode].colors[0] = ToRGBColor(cmargb->GetLedRed(), cmargb->GetLedGreen(), cmargb->GetLedBlue());
}
modes[active_mode].color_mode = (cmargb->GetRandomColours()) ? MODE_COLORS_RANDOM : MODE_COLORS_MODE_SPECIFIC;
if (modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
{
modes[active_mode].speed = cmargb->GetLedSpeed();
}
}
RGBController_CMARGBController::~RGBController_CMARGBController()
{
delete cmargb;
}
void RGBController_CMARGBController::Init_Controller()
{
int zone_idx = cmargb->GetZoneIndex();
int zone_led_count = argb_header_data[zone_idx].count;
/*-------------------------------------------------*\
| If argb_header_data[zone_idx].count == 1 then the |
| zone is ZONE_TYPE_SINGLE |
\*-------------------------------------------------*/
bool boolSingleLED = ( zone_led_count == 1 );
zone ARGB_zone;
ARGB_zone.name = std::to_string(zone_idx);
ARGB_zone.type = (boolSingleLED) ? ZONE_TYPE_SINGLE : ZONE_TYPE_LINEAR;
ARGB_zone.leds_min = 4;
ARGB_zone.leds_max = 48;
ARGB_zone.leds_count = zone_led_count;
ARGB_zone.matrix_map = NULL;
zones.push_back(ARGB_zone);
}
void RGBController_CMARGBController::SetupZones()
{
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
leds.clear();
colors.clear();
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
bool boolSingleLED = (zones[zone_idx].type == ZONE_TYPE_SINGLE);
if (!boolSingleLED)
{
cmargb->SetLedCount( std::stoi(zones[zone_idx].name), zones[zone_idx].leds_count);
}
for(unsigned int lp_idx = 0; lp_idx < zones[zone_idx].leds_count; lp_idx++)
{
led new_led;
unsigned int i = std::stoi(zones[zone_idx].name);
if(boolSingleLED)
{
new_led.name = i;
new_led.value = argb_header_data[i].header;
}
else
{
new_led.name = i;
new_led.name.append(" LED " + std::to_string(lp_idx));
new_led.value = argb_header_data[i].header;
}
leds.push_back(new_led);
}
}
SetupColors();
}
void RGBController_CMARGBController::ResizeZone(int zone, int new_size)
{
if((size_t) zone >= zones.size())
{
return;
}
uint8_t end_zone = last_zone(zone);
for(std::size_t zone_idx = first_zone(zone); zone_idx < end_zone; zone_idx++)
{
if(((unsigned int)new_size >= zones[zone_idx].leds_min) && ((unsigned int)new_size <= zones[zone_idx].leds_max))
{
zones[zone_idx].leds_count = new_size;
}
}
SetupZones();
}
void RGBController_CMARGBController::DeviceUpdateLEDs()
{
uint8_t end_zone = last_zone(cmargb->GetZoneIndex());
for(std::size_t zone_idx = first_zone(cmargb->GetZoneIndex()); zone_idx < end_zone; zone_idx++)
{
UpdateZoneLEDs(zone_idx);
}
}
void RGBController_CMARGBController::UpdateZoneLEDs(int /*zone*/)
{
//cmargb->SetLedsDirect( zones[zone].colors, zones[zone].leds_count );
}
void RGBController_CMARGBController::UpdateSingleLED(int led)
{
UpdateZoneLEDs(GetLED_Zone(led));
}
void RGBController_CMARGBController::SetCustomMode()
{
for(std::size_t mode_idx = 0; mode_idx < modes.size() ; mode_idx++)
{
if (modes[mode_idx].value == CM_ARGB_MODE_DIRECT)
{
active_mode = mode_idx;
break;
}
}
}
void RGBController_CMARGBController::DeviceUpdateMode()
{
bool random_colours = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
RGBColor colour = (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) ? modes[active_mode].colors[0] : 0;
cmargb->SetMode( modes[active_mode].value, modes[active_mode].speed, colour, random_colours );
}
int RGBController_CMARGBController::GetLED_Zone(int led_idx)
{
/*---------------------------------------------------------*\
| This may be more useful in the abstract RGBController.cpp |
\*---------------------------------------------------------*/
for(size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
int zone_start = zones[zone_idx].start_idx;
int zone_end = zone_start + zones[zone_idx].leds_count - 1;
if( zone_start <= led_idx && zone_end >= led_idx)
{
return(zone_idx);
}
}
return -1;
}
@@ -1,40 +0,0 @@
/*-------------------------------------------------------------------*\
| RGBController_CMARGBController.h |
| |
| Driver for Coolermaster ARGB Controller |
| |
| Chris M (Dr_No) 14th Oct 2020 |
| |
\*-------------------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CMARGBcontroller.h"
#include <vector>
#define first_zone(zn) ((zones.size() > 1) ? 1 : 0)
#define last_zone(zn) ((zones.size() > 1) ? 4 : 1)
class RGBController_CMARGBController : public RGBController
{
public:
RGBController_CMARGBController(CMARGBController* cmargb_ptr);
~RGBController_CMARGBController();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
void Init_Controller();
int GetDeviceMode();
int GetLED_Zone(int led_idx);
CMARGBController* cmargb;
};
@@ -1,467 +0,0 @@
/*-------------------------------------------------------------------*\
| RGBController_CMMKController.cpp |
| |
| Driver for Coolermaster MasterKeys keyboards |
| |
| Lukas N (chmod222) 28th Jun 2020 |
| Tam D (too.manyhobbies) 25th Apr 2021 |
| |
\*-------------------------------------------------------------------*/
#include "RGBController_CMMKController.h"
#include <sstream>
using namespace std::chrono_literals;
#define CMMK_SPEED_MIN CMMK_SPEED0
#define CMMK_SPEED_MID CMMK_SPEED2
#define CMMK_SPEED_MAX CMMK_SPEED4
#define CMMK_MODE_FIRMWARE 0xFF
#define CMMK_MODE_MANUAL 0x7F
RGBController_CMMKController::RGBController_CMMKController(CMMKController* cmmk_ctrl)
{
cmmk = cmmk_ctrl;
name = cmmk->GetDeviceName();
type = DEVICE_TYPE_KEYBOARD;
description = "Cooler Master MasterKeys Device";
version = cmmk->GetFirmwareVersion();
serial = "";
location = cmmk->GetLocation();
mode Direct;
Direct.name = "Direct";
Direct.value = CMMK_MODE_MANUAL;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Static;
Static.name = "Static";
Static.value = CMMK_EFFECT_FULLY_LIT;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(1);
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = CMMK_EFFECT_BREATHE;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Breathing.speed_min = 0x20;
Breathing.speed_max = 0x20;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(1);
modes.push_back(Breathing);
mode Cycle;
Cycle.name = "Spectrum Cycle";
Cycle.value = CMMK_EFFECT_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED;
Cycle.speed_min = CMMK_SPEED_MIN;
Cycle.speed_max = CMMK_SPEED_MAX;
Cycle.color_mode = MODE_COLORS_NONE;
modes.push_back(Cycle);
mode Reactive;
Reactive.name = "Reactive";
Reactive.value = CMMK_EFFECT_SINGLE;
Reactive.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Reactive.speed_min = CMMK_SPEED_MIN;
Reactive.speed_max = CMMK_SPEED_MAX;
Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC;
Reactive.colors_min = 2;
Reactive.colors_max = 2;
Reactive.colors.resize(2);
modes.push_back(Reactive);
mode Wave;
Wave.name = "Rainbow Wave";
Wave.value = CMMK_EFFECT_WAVE;
Wave.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD;
Wave.speed_min = CMMK_SPEED_MIN;
Wave.speed_max = CMMK_SPEED_MAX;
Wave.color_mode = MODE_COLORS_MODE_SPECIFIC;
Wave.colors_min = 1;
Wave.colors_max = 1;
Wave.colors.resize(1);
modes.push_back(Wave);
mode Ripple;
Ripple.name = "Ripple Effect";
Ripple.value = CMMK_EFFECT_RIPPLE;
Ripple.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED;
Ripple.speed_min = CMMK_SPEED_MIN;
Ripple.speed_max = CMMK_SPEED_MAX;
Ripple.colors_min = 2;
Ripple.colors_max = 2;
Ripple.colors.resize(2);
modes.push_back(Ripple);
mode Cross;
Cross.name = "Cross";
Cross.value = CMMK_EFFECT_CROSS;
Cross.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Cross.speed_min = CMMK_SPEED_MIN;
Cross.speed_max = CMMK_SPEED_MAX;
Cross.colors_min = 2;
Cross.colors_max = 2;
Cross.colors.resize(2);
modes.push_back(Cross);
mode Raindrops;
Raindrops.name = "Raindrops";
Raindrops.value = CMMK_EFFECT_RAINDROPS;
Raindrops.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Raindrops.speed_min = CMMK_SPEED_MIN;
Raindrops.speed_max = CMMK_SPEED_MAX;
Raindrops.colors_min = 2;
Raindrops.colors_max = 2;
Raindrops.colors.resize(2);
modes.push_back(Raindrops);
mode Stars;
Stars.name = "Starfield";
Stars.value = CMMK_EFFECT_STARS;
Stars.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Stars.speed_min = CMMK_SPEED_MIN;
Stars.speed_max = CMMK_SPEED_MAX;
Stars.colors_min = 2;
Stars.colors_max = 2;
Stars.colors.resize(2);
modes.push_back(Stars);
mode Snake;
Snake.name = "Snake";
Snake.value = CMMK_EFFECT_SNAKE;
Snake.flags = MODE_FLAG_HAS_SPEED;
Snake.speed_min = CMMK_SPEED_MIN;
Snake.speed_max = CMMK_SPEED_MAX;
modes.push_back(Snake);
mode FirmwareControl;
FirmwareControl.name = "Firmware Controlled";
FirmwareControl.value = 0xFF;
FirmwareControl.flags = 0;
modes.push_back(FirmwareControl);
SetupZones();
}
RGBController_CMMKController::~RGBController_CMMKController()
{
delete cmmk;
}
void RGBController_CMMKController::SetupMatrixMap()
{
for(int y = 0; y < CMMK_ROWS_MAX; y++)
{
for(int x = 0; x < CMMK_COLS_MAX; x++)
{
matrix_map[y][x] = 0xFFFFFFFF;
}
}
for(size_t i = 0; i < leds.size(); i++)
{
led& l = leds[i];
int y = (l.value & 0xFF00) >> 8;
int x = (l.value & 0xFF);
matrix_map[y][x] = i;
}
}
void RGBController_CMMKController::SetupZones()
{
for(int y = 0; y < CMMK_ROWS_MAX; y++)
{
for(int x = 0; x < CMMK_COLS_MAX; x++)
{
if(!cmmk->PositionValid(y, x))
{
continue;
}
std::stringstream namestrm;
led key;
namestrm << "Key @ Row " << (y + 1) << ", Column" << (x + 1);
key.name = namestrm.str();
key.value = (y & 0xFF) << 8 | (x & 0xFF);
leds.push_back(key);
}
}
zone KeyboardZone;
KeyboardZone.name = "Keyboard";
KeyboardZone.type = ZONE_TYPE_MATRIX;
KeyboardZone.leds_min = leds.size();
KeyboardZone.leds_max = leds.size();
KeyboardZone.leds_count = leds.size();
KeyboardZone.matrix_map = new matrix_map_type;
KeyboardZone.matrix_map->height = CMMK_ROWS_MAX;
KeyboardZone.matrix_map->width = CMMK_COLS_MAX;
KeyboardZone.matrix_map->map = (unsigned int *)&matrix_map;
zones.push_back(KeyboardZone);
SetupMatrixMap();
SetupColors();
}
void RGBController_CMMKController::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
struct rgb map_to_cmmk_rgb(RGBColor input)
{
return rgb
{
(uint8_t)RGBGetRValue(input),
(uint8_t)RGBGetGValue(input),
(uint8_t)RGBGetBValue(input)
};
}
enum cmmk_wave_direction map_to_cmmk_dir(int input)
{
switch(input)
{
case MODE_DIRECTION_LEFT:
return CMMK_RIGHT_TO_LEFT;
case MODE_DIRECTION_RIGHT:
return CMMK_LEFT_TO_RIGHT;
case MODE_DIRECTION_UP:
return CMMK_FRONT_TO_BACK;
case MODE_DIRECTION_DOWN:
return CMMK_BACK_TO_FRONT;
default:
return CMMK_RIGHT_TO_LEFT;
}
}
void copy_buffers(led* buf, RGBColor* colbuf, size_t n, struct cmmk_color_matrix& mat, std::atomic<bool>& dirty)
{
dirty.store(false);
for(size_t i = 0; i < n; i++)
{
led const& selected_led = buf[i];
int y = (selected_led.value & 0xFF00) >> 8;
int x = selected_led.value & 0xFF;
struct rgb col = map_to_cmmk_rgb(colbuf[i]);
struct rgb ecol = mat.data[y][x];
if(ecol.R != col.R || ecol.G != col.G || ecol.B != col.B)
{
dirty.store(true);
mat.data[y][x] = col;
}
}
}
void RGBController_CMMKController::DeviceUpdateLEDs()
{
copy_buffers(leds.data(), colors.data(), leds.size(), current_matrix, dirty);
if(force_update.load() || dirty.load())
{
cmmk->SetAll(current_matrix);
force_update.store(false);
}
}
void RGBController_CMMKController::UpdateZoneLEDs(int zone_idx)
{
zone& z = zones[zone_idx];
copy_buffers(z.leds, z.colors, z.leds_count, current_matrix, dirty);
if(force_update.load() || dirty.load())
{
cmmk->SetAll(current_matrix);
force_update.store(false);
}
}
void RGBController_CMMKController::UpdateSingleLED(int led_idx)
{
led& selected_led = leds[led_idx];
int y = (selected_led.value & 0xFF00) >> 8;
int x = selected_led.value & 0xFF;
current_matrix.data[y][x] = map_to_cmmk_rgb(colors[led_idx]);
cmmk->SetSingle(y, x, map_to_cmmk_rgb(colors[led_idx]));
dirty.store(false);
}
void RGBController_CMMKController::SetCustomMode()
{
active_mode = 1;
}
void RGBController_CMMKController::DeviceUpdateMode()
{
force_update.store(true);
switch(modes[active_mode].value)
{
case CMMK_MODE_FIRMWARE:
cmmk->SetFirmwareControl();
break;
case CMMK_MODE_MANUAL:
cmmk->SetManualControl();
break;
case CMMK_EFFECT_FULLY_LIT:
{
cmmk_effect_fully_lit fully_lit_effect;
fully_lit_effect.color = map_to_cmmk_rgb(modes[active_mode].colors[0]);
cmmk->SetMode(fully_lit_effect);
}
break;
case CMMK_EFFECT_BREATHE:
{
cmmk_effect_breathe breathe_effect;
breathe_effect.speed = (uint8_t)modes[active_mode].speed;
breathe_effect.color = map_to_cmmk_rgb(modes[active_mode].colors[0]);
cmmk->SetMode(breathe_effect);
}
break;
case CMMK_EFFECT_CYCLE:
{
cmmk_effect_cycle cycle_effect;
cycle_effect.speed = (uint8_t)modes[active_mode].speed;
cmmk->SetMode(cycle_effect);
}
break;
case CMMK_EFFECT_SINGLE:
{
cmmk_effect_single single_effect;
single_effect.speed = (uint8_t)modes[active_mode].speed;
single_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]);
single_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]);
cmmk->SetMode(single_effect);
}
break;
case CMMK_EFFECT_WAVE:
{
cmmk_effect_wave wave_effect;
wave_effect.speed = (uint8_t)modes[active_mode].speed;
wave_effect.direction = map_to_cmmk_dir(modes[active_mode].direction);
wave_effect.start = map_to_cmmk_rgb(modes[active_mode].colors[0]);
cmmk->SetMode(wave_effect);
}
break;
case CMMK_EFFECT_RIPPLE:
{
cmmk_effect_ripple ripple_effect;
ripple_effect.speed = (uint8_t)modes[active_mode].speed;
ripple_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]);
ripple_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]);
if(modes[active_mode].color_mode == MODE_COLORS_RANDOM)
{
ripple_effect.ripple_type = CMMK_RIPPLE_RANDOM_COLOR;
}
else
{
ripple_effect.ripple_type = CMMK_RIPPLE_GIVEN_COLOR;
}
cmmk->SetMode(ripple_effect);
}
break;
case CMMK_EFFECT_CROSS:
{
cmmk_effect_cross cross_effect;
cross_effect.speed = (uint8_t)modes[active_mode].speed;
cross_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]);
cross_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]);
cmmk->SetMode(cross_effect);
}
break;
case CMMK_EFFECT_RAINDROPS:
{
cmmk_effect_raindrops raindrops_effect;
raindrops_effect.speed = (uint8_t)modes[active_mode].speed;
raindrops_effect.interval = CMMK_SPEED_MID;
raindrops_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]);
raindrops_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]);
cmmk->SetMode(raindrops_effect);
}
break;
case CMMK_EFFECT_STARS:
{
cmmk_effect_stars stars_effect;
stars_effect.speed = (uint8_t)modes[active_mode].speed;
stars_effect.interval = CMMK_SPEED_MID;
stars_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]);
stars_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]);
cmmk->SetMode(stars_effect);
}
break;
case CMMK_EFFECT_SNAKE:
{
cmmk_effect_snake snake_effect;
snake_effect.speed = (uint8_t)modes[active_mode].speed;
cmmk->SetMode(snake_effect);
}
break;
}
}
@@ -1,42 +0,0 @@
/*-------------------------------------------------------------------*\
| RGBController_CMMKController.h |
| |
| Driver for Coolermaster MasterKeys keyboards |
| |
| Lukas N (chmod222) 28th Jun 2020 |
| Tam D (too.manyhobbies) 25th Apr 2021 |
| |
\*-------------------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CMMKController.h"
class RGBController_CMMKController : public RGBController
{
public:
RGBController_CMMKController(CMMKController* cmmk_ptr);
~RGBController_CMMKController();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
void SetupMatrixMap();
CMMKController* cmmk;
int matrix_map[CMMK_ROWS_MAX][CMMK_COLS_MAX];
struct cmmk_color_matrix current_matrix;
std::atomic<bool> dirty;
std::atomic<bool> force_update;
};
@@ -1,168 +0,0 @@
/*-------------------------------------------------------------------*\
| RGBController_CMMP750Controller.cpp |
| |
| Driver for Coolermaster MP750 mousepad |
| |
| Chris M (Dr_No) 18th Apr 2020 |
| |
\*-------------------------------------------------------------------*/
#include "RGBController_CMMP750Controller.h"
RGBController_CMMP750Controller::RGBController_CMMP750Controller(CMMP750Controller* cmmp_ptr)
{
cmmp750 = cmmp_ptr;
unsigned char speed = cmmp750->GetLedSpeed();
name = cmmp750->GetDeviceName();
vendor = "Cooler Master";
type = DEVICE_TYPE_MOUSEMAT;
description = cmmp750->GetDeviceName();
version = "1.0";
serial = cmmp750->GetSerial();
location = cmmp750->GetLocation();
mode Static;
Static.name = "Static";
Static.value = CM_MP750_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Blink;
Blink.name = "Blink";
Blink.value = CM_MP750_MODE_BLINK;
Blink.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Blink.speed_min = MP750_SPEED_SLOWEST;
Blink.speed_max = MP750_SPEED_FASTEST;
Blink.color_mode = MODE_COLORS_PER_LED;
Blink.speed = speed;
modes.push_back(Blink);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = CM_MP750_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.speed_min = MP750_SPEED_SLOWEST;
Breathing.speed_max = MP750_SPEED_FASTEST;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed = speed;
modes.push_back(Breathing);
mode ColorCycle;
ColorCycle.name = "Color Cycle";
ColorCycle.value = CM_MP750_MODE_COLOR_CYCLE;
ColorCycle.flags = MODE_FLAG_HAS_SPEED;
ColorCycle.speed_min = MP750_SPEED_SLOWEST;
ColorCycle.speed_max = MP750_SPEED_FASTEST;
ColorCycle.color_mode = MODE_COLORS_NONE;
ColorCycle.speed = speed;
modes.push_back(ColorCycle);
mode BreathCycle;
BreathCycle.name = "Breath Cycle";
BreathCycle.value = CM_MP750_MODE_BREATH_CYCLE;
BreathCycle.flags = MODE_FLAG_HAS_SPEED;
BreathCycle.speed_min = MP750_SPEED_SLOWEST;
BreathCycle.speed_max = MP750_SPEED_FASTEST;
BreathCycle.color_mode = MODE_COLORS_NONE;
BreathCycle.speed = speed;
modes.push_back(BreathCycle);
mode Off;
Off.name = "Turn Off";
Off.value = CM_MP750_MODE_OFF;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
SetupZones();
active_mode = GetDeviceMode();
}
RGBController_CMMP750Controller::~RGBController_CMMP750Controller()
{
delete cmmp750;
}
int RGBController_CMMP750Controller::GetDeviceMode()
{
int temp_mode = cmmp750->GetMode();
for(unsigned int i = 0; i < modes.size(); i++)
{
if (temp_mode == modes[i].value)
{
return i;
}
}
//If not found return 0
return 0;
}
void RGBController_CMMP750Controller::SetupZones()
{
zone MP_zone;
MP_zone.name = "Mousepad";
MP_zone.type = ZONE_TYPE_SINGLE;
MP_zone.leds_min = 1;
MP_zone.leds_max = 1;
MP_zone.leds_count = 1;
MP_zone.matrix_map = NULL;
zones.push_back(MP_zone);
led MP_led;
MP_led.name = "Mousepad LED";
leds.push_back(MP_led);
SetupColors();
/*---------------------------------------------------------*\
| Initialize colors for each LED |
\*---------------------------------------------------------*/
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
unsigned char red = cmmp750->GetLedRed();
unsigned char grn = cmmp750->GetLedGreen();
unsigned char blu = cmmp750->GetLedBlue();
colors[led_idx] = ToRGBColor(red, grn, blu);
}
}
void RGBController_CMMP750Controller::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_CMMP750Controller::DeviceUpdateLEDs()
{
unsigned char red = RGBGetRValue(colors[0]);
unsigned char grn = RGBGetGValue(colors[0]);
unsigned char blu = RGBGetBValue(colors[0]);
cmmp750->SetColor(red, grn, blu);
}
void RGBController_CMMP750Controller::UpdateZoneLEDs(int zone)
{
RGBColor color = colors[zone];
unsigned char red = RGBGetRValue(color);
unsigned char grn = RGBGetGValue(color);
unsigned char blu = RGBGetBValue(color);
cmmp750->SetColor(red, grn, blu);
}
void RGBController_CMMP750Controller::UpdateSingleLED(int led)
{
UpdateZoneLEDs(led);
}
void RGBController_CMMP750Controller::SetCustomMode()
{
active_mode = 0;
}
void RGBController_CMMP750Controller::DeviceUpdateMode()
{
cmmp750->SetMode(modes[active_mode].value, modes[active_mode].speed);
}
@@ -1,149 +0,0 @@
/*-------------------------------------------------------------------*\
| RGBController_CMR6000Controller.cpp |
| |
| Driver for Coolermaster based AMD Radeon GPU (6000 series) |
| |
| Eric S (edbgon) 2nd Feb 2021 |
\*-------------------------------------------------------------------*/
#include "RGBController_CMR6000Controller.h"
RGBController_CMR6000Controller::RGBController_CMR6000Controller(CMR6000Controller* cmmp_ptr)
{
cmr6000 = cmmp_ptr;
unsigned char speed = cmr6000->GetLedSpeed();
name = "AMD RX 6xxx GPU";
vendor = "Cooler Master";
type = DEVICE_TYPE_GPU;
description = cmr6000->GetDeviceName();
version = "1.0";
serial = cmr6000->GetSerial();
location = cmr6000->GetLocation();
mode Off;
Off.name = "Off";
Off.flags = 0;
Off.value = CM_MR6000_MODE_OFF;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = CM_MR6000_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(1);
modes.push_back(Static);
mode ColorCycle;
ColorCycle.name = "Color Cycle";
ColorCycle.value = CM_MR6000_MODE_COLOR_CYCLE;
ColorCycle.flags = MODE_FLAG_HAS_SPEED;
ColorCycle.speed_min = MR6000_CYCLE_SPEED_SLOWEST;
ColorCycle.speed = MR6000_CYCLE_SPEED_NORMAL;
ColorCycle.speed_max = MR6000_CYCLE_SPEED_FASTEST;
ColorCycle.color_mode = MODE_COLORS_NONE;
ColorCycle.speed = speed;
modes.push_back(ColorCycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = CM_MR6000_MODE_BREATHE;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Breathing.speed_min = MR6000_BREATHE_SPEED_SLOWEST;
Breathing.speed = MR6000_BREATHE_SPEED_NORMAL;
Breathing.speed_max = MR6000_BREATHE_SPEED_FASTEST;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(1);
Breathing.speed = speed;
modes.push_back(Breathing);
SetupZones();
active_mode = cmr6000->GetMode();
if (modes[active_mode].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
{
modes[active_mode].colors[0] = ToRGBColor(cmr6000->GetLedRed(), cmr6000->GetLedGreen(), cmr6000->GetLedBlue());
}
if (modes[active_mode].flags & MODE_FLAG_HAS_RANDOM_COLOR)
{
modes[active_mode].color_mode = (cmr6000->GetRandomColours()) ? MODE_COLORS_RANDOM : MODE_COLORS_MODE_SPECIFIC;
}
if (modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
{
modes[active_mode].speed = cmr6000->GetLedSpeed();
}
}
RGBController_CMR6000Controller::~RGBController_CMR6000Controller()
{
delete cmr6000;
}
void RGBController_CMR6000Controller::SetupZones()
{
zone GP_zone;
GP_zone.name = "GPU";
GP_zone.type = ZONE_TYPE_SINGLE;
GP_zone.leds_min = 1;
GP_zone.leds_max = 1;
GP_zone.leds_count = 1;
GP_zone.matrix_map = NULL;
zones.push_back(GP_zone);
led GP_led;
GP_led.name = "Logo";
leds.push_back(GP_led);
SetupColors();
}
void RGBController_CMR6000Controller::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_CMR6000Controller::DeviceUpdateLEDs()
{
unsigned char red = 0;
unsigned char grn = 0;
unsigned char blu = 0;
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
red = RGBGetRValue(modes[active_mode].colors[0]);
grn = RGBGetGValue(modes[active_mode].colors[0]);
blu = RGBGetBValue(modes[active_mode].colors[0]);
}
unsigned char rnd = (modes[active_mode].color_mode == MODE_COLORS_RANDOM) ? 0xA0 : 0x20;
cmr6000->SetMode(modes[active_mode].value, modes[active_mode].speed, red, grn, blu, rnd);
}
void RGBController_CMR6000Controller::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_CMR6000Controller::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_CMR6000Controller::SetCustomMode()
{
active_mode = 1;
}
void RGBController_CMR6000Controller::DeviceUpdateMode()
{
DeviceUpdateLEDs();
}
@@ -1,32 +0,0 @@
/*-------------------------------------------------------------------*\
| RGBController_CMR6000Controller.h |
| |
| Driver for Coolermaster based AMD Radeon GPU (6000 series) |
| |
| Eric S (edbgon) 2nd Feb 2021 |
\*-------------------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CMR6000Controller.h"
class RGBController_CMR6000Controller : public RGBController
{
public:
RGBController_CMR6000Controller(CMR6000Controller* cmmp_ptr);
~RGBController_CMR6000Controller();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
CMR6000Controller* cmr6000;
int GetDeviceMode();
};
@@ -1,251 +0,0 @@
/*-------------------------------------------------------------------*\
| RGBController_CMSmallARGBController.cpp |
| |
| Driver for Coolermaster Small ARGB USB Controller |
| |
| Chris M (Dr_No) 31st Jan 2021 |
| |
\*-------------------------------------------------------------------*/
#include "RGBController_CMSmallARGBController.h"
RGBController_CMSmallARGBController::RGBController_CMSmallARGBController(CMSmallARGBController *cmargb_ptr)
{
cmargb = cmargb_ptr;
unsigned char speed = cmargb->GetLedSpeed();
name = small_argb_header_data[cmargb->GetZoneIndex()].name;
vendor = "Cooler Master";
type = DEVICE_TYPE_LEDSTRIP;
description = cmargb->GetDeviceName();
version = "1.0";
serial = cmargb->GetSerial();
location = cmargb->GetLocation();
mode Off;
Off.name = "Turn Off";
Off.value = CM_SMALL_ARGB_MODE_OFF;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Reload;
Reload.name = "Reload";
Reload.value = CM_SMALL_ARGB_MODE_RELOAD;
Reload.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Reload.colors_min = 1;
Reload.colors_max = 1;
Reload.colors.resize(Reload.colors_max);
Reload.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Reload.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Reload.color_mode = MODE_COLORS_RANDOM;
Reload.speed = speed;
modes.push_back(Reload);
mode Recoil;
Recoil.name = "Recoil";
Recoil.value = CM_SMALL_ARGB_MODE_RECOIL;
Recoil.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Recoil.colors_min = 1;
Recoil.colors_max = 1;
Recoil.colors.resize(Recoil.colors_max);
Recoil.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Recoil.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Recoil.color_mode = MODE_COLORS_RANDOM;
Recoil.speed = speed;
modes.push_back(Recoil);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = CM_SMALL_ARGB_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(Breathing.colors_max);
Breathing.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Breathing.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Breathing.color_mode = MODE_COLORS_RANDOM;
Breathing.speed = speed;
modes.push_back(Breathing);
mode Refill;
Refill.name = "Refill";
Refill.value = CM_SMALL_ARGB_MODE_REFILL;
Refill.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Refill.colors_min = 1;
Refill.colors_max = 1;
Refill.colors.resize(Refill.colors_max);
Refill.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Refill.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Refill.color_mode = MODE_COLORS_RANDOM;
Refill.speed = speed;
modes.push_back(Refill);
mode Demo;
Demo.name = "Demo";
Demo.value = CM_SMALL_ARGB_MODE_DEMO;
Demo.flags = MODE_FLAG_HAS_SPEED;
Demo.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Demo.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Demo.color_mode = MODE_COLORS_NONE;
Demo.speed = speed;
modes.push_back(Demo);
mode Spectrum;
Spectrum.name = "Spectrum";
Spectrum.value = CM_SMALL_ARGB_MODE_SPECTRUM;
Spectrum.flags = MODE_FLAG_HAS_SPEED;
Spectrum.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Spectrum.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Spectrum.color_mode = MODE_COLORS_NONE;
Spectrum.speed = speed;
modes.push_back(Spectrum);
mode Direct;
Direct.name = "Direct";
Direct.value = CM_SMALL_ARGB_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode PassThru;
PassThru.name = "Pass Thru";
PassThru.value = CM_SMALL_ARGB_MODE_PASSTHRU;
PassThru.color_mode = MODE_COLORS_NONE;
modes.push_back(PassThru);
Init_Controller(); //Only processed on first run
SetupZones();
int temp_mode = cmargb->GetMode();
for(std::size_t mode_idx = 0; mode_idx < modes.size() ; mode_idx++)
{
if (temp_mode == modes[mode_idx].value)
{
active_mode = mode_idx;
break;
}
}
if (modes[active_mode].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
{
modes[active_mode].colors[0] = ToRGBColor(cmargb->GetLedRed(), cmargb->GetLedGreen(), cmargb->GetLedBlue());
}
modes[active_mode].color_mode = (cmargb->GetRandomColours()) ? MODE_COLORS_RANDOM : MODE_COLORS_MODE_SPECIFIC;
if (modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
{
modes[active_mode].speed = cmargb->GetLedSpeed();
}
}
RGBController_CMSmallARGBController::~RGBController_CMSmallARGBController()
{
delete cmargb;
}
void RGBController_CMSmallARGBController::Init_Controller()
{
int zone_idx = cmargb->GetZoneIndex();
int zone_led_count = small_argb_header_data[zone_idx].count;
bool boolSingleLED = ( zone_led_count == 1 ); //If argb_header_data[zone_idx].count == 1 then the zone is ZONE_TYPE_SINGLE
zone ARGB_zone;
ARGB_zone.name = std::to_string(zone_idx);
ARGB_zone.type = (boolSingleLED) ? ZONE_TYPE_SINGLE : ZONE_TYPE_LINEAR;
ARGB_zone.leds_min = CM_SMALL_ARGB_MIN_LEDS;
ARGB_zone.leds_max = CM_SMALL_ARGB_MAX_LEDS;
ARGB_zone.leds_count = zone_led_count;
ARGB_zone.matrix_map = NULL;
zones.push_back(ARGB_zone);
}
void RGBController_CMSmallARGBController::SetupZones()
{
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
leds.clear();
colors.clear();
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
bool boolSingleLED = (zones[zone_idx].type == ZONE_TYPE_SINGLE); //Calculated for later use
if (!boolSingleLED)
{
cmargb->SetLedCount(small_argb_header_data[zone_idx].header, zones[zone_idx].leds_count);
}
for(unsigned int lp_idx = 0; lp_idx < zones[zone_idx].leds_count; lp_idx++)
{
led new_led;
unsigned int i = std::stoi(zones[zone_idx].name);
if(boolSingleLED)
{
new_led.name = i;
new_led.value = small_argb_header_data[i].header;
}
else
{
new_led.name = i;
new_led.name.append(" LED " + std::to_string(lp_idx));
new_led.value = small_argb_header_data[i].header;
}
leds.push_back(new_led);
}
}
SetupColors();
}
void RGBController_CMSmallARGBController::ResizeZone(int zone, int new_size)
{
if((size_t) zone >= zones.size())
{
return;
}
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
{
zones[zone].leds_count = new_size;
SetupZones();
}
}
void RGBController_CMSmallARGBController::DeviceUpdateLEDs()
{
for(size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
UpdateZoneLEDs(zone_idx);
}
}
void RGBController_CMSmallARGBController::UpdateZoneLEDs(int /*zone*/)
{
//bool random_colours = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
//cmargb->SetLedsDirect(zones[zone].colors, random_colours);
}
void RGBController_CMSmallARGBController::UpdateSingleLED(int /*led*/)
{
//cmargb->SetMode( modes[active_mode].value, modes[active_mode].speed );
//cmargb->SetLedsDirect( zones[0].colors, zones[0].leds_count );
}
void RGBController_CMSmallARGBController::SetCustomMode()
{
active_mode = CM_SMALL_ARGB_MODE_DIRECT; //The small ARGB may not support "Direct" mode
}
void RGBController_CMSmallARGBController::DeviceUpdateMode()
{
bool random_colours = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
RGBColor colour = (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) ? modes[active_mode].colors[0] : 0;
cmargb->SetMode( modes[active_mode].value, modes[active_mode].speed, colour, random_colours );
}
@@ -1,38 +0,0 @@
/*-------------------------------------------------------------------*\
| RGBController_CMSmallARGBController.h |
| |
| Driver for Coolermaster Small ARGB USB Controller |
| |
| Chris M (Dr_No) 31st Jan 2021 |
| |
\*-------------------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CMSmallARGBController.h"
#include <vector>
#define CM_SMALL_ARGB_MIN_LEDS 4
#define CM_SMALL_ARGB_MAX_LEDS 48
class RGBController_CMSmallARGBController : public RGBController
{
public:
RGBController_CMSmallARGBController(CMSmallARGBController* cmargb_ptr);
~RGBController_CMSmallARGBController();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
void Init_Controller();
int GetDeviceMode();
CMSmallARGBController* cmargb;
};
@@ -1,276 +0,0 @@
/*---------------------------------------------------------*\
| CorsairCommanderCoreController.cpp |
| |
| Processing Code for Corsair Commander Core |
| |
| Jeff P. |
\*---------------------------------------------------------*/
#include "CorsairCommanderCoreController.h"
#include <cstring>
#include <iomanip>
#include <iostream>
using namespace std::chrono_literals;
CorsairCommanderCoreController::CorsairCommanderCoreController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
keepalive_thread_run = 1;
controller_ready = 0;
/*-----------------------------------------------------*\
| Initialize controller |
\*-----------------------------------------------------*/
InitController();
/*-----------------------------------------------------*\
| Start keepalive thread |
\*-----------------------------------------------------*/
keepalive_thread = new std::thread(&CorsairCommanderCoreController::KeepaliveThread, this);
}
CorsairCommanderCoreController::~CorsairCommanderCoreController()
{
/*-----------------------------------------------------*\
| Close keepalive thread |
\*-----------------------------------------------------*/
keepalive_thread_run = 0;
keepalive_thread->join();
delete keepalive_thread;
/*-----------------------------------------------------*\
| Close HID device |
\*-----------------------------------------------------*/
hid_close(dev);
}
void CorsairCommanderCoreController::InitController()
{
/*-----------------------------------------------------*\
| Packet sequence to put controller into direct mode |
\*-----------------------------------------------------*/
unsigned char buffarray[][5] =
{
{0x08, 0x01, 0x03, 0x00, 0x02},
{0x08, 0x0D, 0x00, 0x22, 0x00},
};
SendMultiPkt(buffarray, sizeof(buffarray) / sizeof(buffarray[0]), sizeof(buffarray)[0] / sizeof(buffarray[0][0]));
SetFanMode();
}
std::string CorsairCommanderCoreController::GetLocationString()
{
return("HID: " + location);
}
void CorsairCommanderCoreController::KeepaliveThread()
{
while(keepalive_thread_run.load())
{
if (controller_ready)
{
if((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::seconds(10))
{
SendCommit();
}
}
std::this_thread::sleep_for(1s);
}
}
void CorsairCommanderCoreController::SendCommit()
{
if(!lastcolors.empty())
{
/*-----------------------------------------------------*\
| If colors remain to be sent, send them |
\*-----------------------------------------------------*/
SetDirectColor(lastcolors, lastzones);
}
else
{
unsigned char usb_buf[1025];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Update last commit time |
\*-----------------------------------------------------*/
last_commit_time = std::chrono::steady_clock::now();
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
memset(usb_buf, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
usb_buf[0] = 0x00;
usb_buf[1] = 0x08;
usb_buf[2] = 0x06;
usb_buf[4] = 0xBD;
usb_buf[5] = 0x02;
usb_buf[8] = 0x12;
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
}
}
void CorsairCommanderCoreController::SendMultiPkt(unsigned char buffarray[][5], int r, int c)
{
/*---------------------------------------------------------*\
| Private function to send multiple packets |
\*---------------------------------------------------------*/
unsigned char* hidtemp = new unsigned char[CORSAIR_COMMANDER_CORE_PACKET_SIZE];
for(unsigned int i = 0; i < r; i++)
{
memset(hidtemp, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
for(unsigned int j = 0; j < c; j++)
{
hidtemp[j+1] = buffarray[i][j];
}
hid_write(dev, hidtemp, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
hid_read(dev, hidtemp, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
}
}
void CorsairCommanderCoreController::SetDirectColor
(
std::vector<RGBColor> colors,
std::vector<zone> zones
)
{
if(controller_ready == 1 && ((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::milliseconds(33)))
{
lastcolors = colors;
lastzones = zones;
int packet_offset = CORSAIR_COMMANDER_CORE_PREAMBLE_OFFSET;
int led_idx = 0;
int channel_idx = 0;
unsigned char* usb_buf = new unsigned char[CORSAIR_COMMANDER_CORE_PACKET_SIZE];
memset(usb_buf, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
/*-----------------------------------------------------*\
| Prepare color information packet |
\*-----------------------------------------------------*/
usb_buf[0] = 0x00;
usb_buf[1] = 0x08;
usb_buf[2] = 0x06;
usb_buf[4] = 0xBD;
usb_buf[5] = 0x02;
usb_buf[8] = 0x12;
for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
/*-------------------------------------------------*\
| Add led colors |
\*-------------------------------------------------*/
for(unsigned int i = led_idx; i < led_idx + zones[zone_idx].leds_count; i++)
{
usb_buf[packet_offset] = RGBGetRValue(colors[i]);
usb_buf[packet_offset+1] = RGBGetGValue(colors[i]);
usb_buf[packet_offset+2] = RGBGetBValue(colors[i]);
packet_offset = packet_offset + 3;
}
led_idx = led_idx + zones[zone_idx].leds_count;
/*-------------------------------------------------*\
| Move offset for pump zone with less than 29 LEDs |
\*-------------------------------------------------*/
if(zone_idx == 0)
{
packet_offset = packet_offset + 3 * (29 - zones[zone_idx].leds_count);
}
/*-------------------------------------------------*\
| Move offset for fans with less than 34 LEDs |
\*-------------------------------------------------*/
if(zone_idx != 0)
{
packet_offset = packet_offset + 3 * (34 - zones[zone_idx].leds_count);
}
channel_idx++;
}
/*-----------------------------------------------------*\
| Sending a direct mode color packet resets the timeout |
\*-----------------------------------------------------*/
last_commit_time = std::chrono::steady_clock::now();
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
}
}
void CorsairCommanderCoreController::SetFanMode()
{
/*--------------------------------------------------------------------------------------------------*\
| Force controller to 6 QL fan mode to expose maximum number of LEDs per rgb port (34 LEDs per port) |
\*--------------------------------------------------------------------------------------------------*/
unsigned char usb_buf[1025];
unsigned char buffarray4[][5] =
{
{0x08, 0x05, 0x01, 0x01, 0x00},
{0x08, 0x0D, 0x01, 0x1E, 0x00},
{0x08, 0x09, 0x01, 0x00, 0x00}
};
SendMultiPkt(buffarray4, sizeof(buffarray4) / sizeof(buffarray4[0]), sizeof(buffarray4)[0] / sizeof(buffarray4[0][0]));
memset(usb_buf, 0, sizeof(usb_buf));
usb_buf[0] = 0x00;
usb_buf[1] = 0x08;
usb_buf[2] = 0x06;
usb_buf[3] = 0x01;
usb_buf[4] = 0x11;
usb_buf[8] = 0x0D;
usb_buf[10] = 0x07;
usb_buf[11] = 0x01;
usb_buf[12] = 0x08;
for(unsigned int i = 13; i < 25; i = i + 2)
{
usb_buf[i] = 0x01;
usb_buf[i + 1] = 0x06;
}
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
hid_read(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
unsigned char buffarray2[][5] =
{
{0x08, 0x05, 0x01, 0x01, 0x00},
{0x08, 0x15, 0x01, 0x00, 0x00}
};
SendMultiPkt(buffarray2, sizeof(buffarray2) / sizeof(buffarray2[0]), sizeof(buffarray2)[0] / sizeof(buffarray2[0][0]));
memset(usb_buf, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
usb_buf[0] = 0x00;
usb_buf[1] = 0x08;
usb_buf[2] = 0x06;
usb_buf[4] = 0xBD;
usb_buf[5] = 0x02;
usb_buf[8] = 0x12;
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
hid_read(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
controller_ready = 1;
}
@@ -1,65 +0,0 @@
/*---------------------------------------------------------*\
| CorsairCommanderCoreController.h |
| |
| Definitions for Corsair Commander Core |
| Based on code by: |
| Adam Honse ([email protected]), 8/17/2020 |
| |
| Jeff P. |
\*---------------------------------------------------------*/
#include "RGBController.h"
#include <vector>
#include <chrono>
#include <hidapi/hidapi.h>
#pragma once
#define CORSAIR_COMMANDER_CORE_PACKET_SIZE 1025
#define CORSAIR_COMMANDER_CORE_PREAMBLE_OFFSET 10
#define CORSAIR_ELITE_CAPELLIX_PUMP_LED_OFFSET 87
#define CORSAIR_QL_FAN_ZONE_OFFSET 102
#define CORSAIR_COMMANDER_CORE_NUM_CHANNELS 6
enum
{
CORSAIR_COMMANDER_CORE_MODE_DIRECT = 0x00,
};
class CorsairCommanderCoreController
{
public:
CorsairCommanderCoreController(hid_device* dev_handle, const char* path);
~CorsairCommanderCoreController();
std::string GetLocationString();
void SetDirectColor
(
std::vector<RGBColor>,
std::vector<zone>
);
void KeepaliveThread();
void SetFanMode();
private:
hid_device* dev;
std::thread* keepalive_thread;
std::atomic<bool> keepalive_thread_run;
std::atomic<bool> controller_ready;
std::string location;
std::vector<RGBColor> lastcolors;
std::vector<zone> lastzones;
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
void SendMultiPkt
(
unsigned char buffarray[][5],
int r,
int c
);
void SendCommit();
void InitController();
};
@@ -1,41 +0,0 @@
#include "Detector.h"
#include "CorsairCommanderCoreController.h"
#include "RGBController.h"
#include "RGBController_CorsairCommanderCore.h"
#include <vector>
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| Corsair vendor ID |
\*-----------------------------------------------------*/
#define CORSAIR_VID 0x1B1C
/*-----------------------------------------------------*\
| Commander Core product IDs |
\*-----------------------------------------------------*/
#define CORSAIR_H150I_COMMANDER_CORE_PID 0x0C1C
/******************************************************************************************\
* *
* DetectCorsairCapellixControllers *
* *
* Tests the USB address to see if a Corsair RGB Cooler controller exists there. *
* *
\******************************************************************************************/
void DetectCorsairCapellixHIDControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CorsairCommanderCoreController* controller = new CorsairCommanderCoreController(dev, info->path);
RGBController_CorsairCommanderCore* rgb_controller = new RGBController_CorsairCommanderCore(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR_PU("Corsair Commander Core", DetectCorsairCapellixHIDControllers, CORSAIR_VID, CORSAIR_H150I_COMMANDER_CORE_PID, 0xFF42, 0x01);
@@ -1,125 +0,0 @@
/*-----------------------------------------*\
| RGBController_CorsairCapellix.cpp |
| |
| Generic RGB Interface for Corsair |
| Commander Core |
| |
| Jeff P. |
\*-----------------------------------------*/
#include "RGBController_CorsairCommanderCore.h"
RGBController_CorsairCommanderCore::RGBController_CorsairCommanderCore(CorsairCommanderCoreController* corsair_ptr)
{
corsair = corsair_ptr;
vendor = "Corsair";
description = "Corsair Commander Core";
type = DEVICE_TYPE_COOLER;
location = corsair->GetLocationString();
SetupZones();
mode Direct;
Direct.name = "Direct";
Direct.value = 0;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
}
RGBController_CorsairCommanderCore::~RGBController_CorsairCommanderCore()
{
delete corsair;
}
void RGBController_CorsairCommanderCore::SetupZones()
{
std::atomic<bool> first_run;
first_run = 0;
if(zones.size() == 0)
{
first_run = 1;
}
zones.resize(7);
zones[0].name = "Pump";
zones[0].type = ZONE_TYPE_LINEAR;
zones[0].leds_min = 0;
zones[0].leds_max = 29;
for(unsigned int i = 1; i < (CORSAIR_COMMANDER_CORE_NUM_CHANNELS + 1); i++)
{
zones[i].name = "RGB Port " + std::to_string(i);
zones[i].type = ZONE_TYPE_LINEAR;
zones[i].leds_min = 0;
zones[i].leds_max = 34;
if(first_run)
{
zones[i].leds_count = 0;
}
}
leds.clear();
colors.clear();
for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
for (unsigned int led_idx = 0; led_idx < zones[zone_idx].leds_count; led_idx++)
{
led new_led;
new_led.name = zones[zone_idx].name + " LED " + std::to_string(led_idx+1);
leds.push_back(new_led);
}
}
SetupColors();
}
void RGBController_CorsairCommanderCore::ResizeZone(int zone, int new_size)
{
if((size_t) zone >= zones.size())
{
return;
}
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
{
zones[zone].leds_count = new_size;
SetupZones();
}
}
void RGBController_CorsairCommanderCore::DeviceUpdateLEDs()
{
DeviceUpdateMode();
}
void RGBController_CorsairCommanderCore::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_CorsairCommanderCore::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_CorsairCommanderCore::SetCustomMode()
{
active_mode = 0;
}
void RGBController_CorsairCommanderCore::DeviceUpdateMode()
{
switch(modes[active_mode].value)
{
case CORSAIR_COMMANDER_CORE_MODE_DIRECT:
corsair->SetDirectColor(colors, zones);
break;
}
}
@@ -1,33 +0,0 @@
/*-----------------------------------------*\
| RGBController_CorsairCapellix.h |
| |
| Generic RGB Interface for Corsair |
| Commander Core |
| |
| Jeff P. |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CorsairCommanderCoreController.h"
class RGBController_CorsairCommanderCore : public RGBController
{
public:
RGBController_CorsairCommanderCore(CorsairCommanderCoreController* corsair_ptr);
~RGBController_CorsairCommanderCore();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
CorsairCommanderCoreController* corsair;
std::vector<int> fanleds{0};
};
@@ -1,126 +0,0 @@
/*------------------------------------------*\
| CorsairDominatorPlatinumController.cpp |
| |
| Drover for Corsair Domintator Platinum |
| RGB RAM lighting controller |
| |
| Erik Gilling (konkers) 9/25/2020 |
\*------------------------------------------*/
#include "CorsairDominatorPlatinumController.h"
#include <cstring>
using namespace std::chrono_literals;
CorsairDominatorPlatinumController::CorsairDominatorPlatinumController(i2c_smbus_interface *bus, corsair_dev_id dev)
{
this->bus = bus;
this->dev = dev;
led_data[0] = 0xc;
}
CorsairDominatorPlatinumController::~CorsairDominatorPlatinumController()
{
}
std::string CorsairDominatorPlatinumController::GetDeviceName()
{
return "Corsair Dominator Platinum RGB";
}
std::string CorsairDominatorPlatinumController::GetDeviceLocation()
{
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
return_string.append(addr);
return("I2C: " + return_string);
}
void CorsairDominatorPlatinumController::SetAllColors
(
unsigned char red,
unsigned char green,
unsigned char blue
)
{
for(unsigned int led = 0; led < CORSAIR_PLAT_LED_COUNT; led++)
{
SetLEDColor(led, red, green, blue);
}
}
void CorsairDominatorPlatinumController::SetLEDColor
(
unsigned int led,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
if(led >= CORSAIR_PLAT_LED_COUNT)
{
return;
}
unsigned int offset = (led * 3) + 1;
led_data[offset] = red;
led_data[offset + 1] = green;
led_data[offset + 2] = blue;
}
unsigned char CorsairDominatorPlatinumController::crc8
(
unsigned char init,
unsigned char poly,
unsigned char* data,
unsigned char len
)
{
unsigned char crc = init;
for(unsigned int i = 0; i < len; i++)
{
unsigned char val = data[i];
for(unsigned char mask = 0x80; mask != 0; mask >>= 1)
{
unsigned char bit;
if ((val & mask) != 0)
{
bit = (crc & 0x80) ^ 0x80;
}
else
{
bit = crc & 0x80;
}
if (bit == 0)
{
crc <<= 1;
}
else
{
crc = (crc << 1) ^ poly;
}
}
}
return crc;
}
void CorsairDominatorPlatinumController::ApplyColors()
{
unsigned char data[sizeof(led_data)];
memcpy(data, led_data, sizeof(led_data));
unsigned char crc = crc8(0x0, 0x7, data, sizeof(data) - 1);
data[sizeof(data) - 1] = crc;
bus->i2c_smbus_write_block_data(dev, 0x31, 0x20, data);
std::this_thread::sleep_for(800us);
bus->i2c_smbus_write_block_data(dev, 0x32, sizeof(data) - 0x20, data + 0x20);
std::this_thread::sleep_for(200us);
}
@@ -1,42 +0,0 @@
/*-----------------------------------------*\
| CorsairDominatorPlatinumController.h |
| |
| Definitions and types for Corsair |
| Domintator Platinum RGB RAM lighting |
| controller |
| |
| Erik Gilling (konkers) 9/25/2020 |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char corsair_dev_id;
class CorsairDominatorPlatinumController
{
public:
CorsairDominatorPlatinumController(i2c_smbus_interface *bus, corsair_dev_id dev);
~CorsairDominatorPlatinumController();
std::string GetDeviceName();
std::string GetDeviceLocation();
size_t GetLEDCount() { return CORSAIR_PLAT_LED_COUNT; }
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 ApplyColors();
bool WaitReady();
private:
static constexpr size_t CORSAIR_PLAT_LED_COUNT = 12;
unsigned char led_data[CORSAIR_PLAT_LED_COUNT * 3 + 2];
i2c_smbus_interface* bus;
corsair_dev_id dev;
static unsigned char crc8(unsigned char init, unsigned char poly, unsigned char *data, unsigned char len);
};
@@ -1,70 +0,0 @@
#include "Detector.h"
#include "CorsairDominatorPlatinumController.h"
#include "RGBController.h"
#include "RGBController_CorsairDominatorPlatinum.h"
#include "i2c_smbus.h"
#include "pci_ids.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std::chrono_literals;
bool TestForCorsairDominatorPlatinumController(i2c_smbus_interface *bus, unsigned char address)
{
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
if(res < 0)
{
return false;
}
res = bus->i2c_smbus_read_byte_data(address, 0x43);
if(res != 0x1b)
{
return false;
}
res = bus->i2c_smbus_read_byte_data(address, 0x44);
if(res != 0x04)
{
return false;
}
return true;
}
/******************************************************************************************\
* *
* DetectCorsairDominatorPlatinumControllers *
* *
* Detect Corsair Dominator Platinum controllers on the enumerated I2C busses. *
* *
* bus - pointer to i2c_smbus_interface where Aura device is connected *
* dev - I2C address of Aura device *
* *
\******************************************************************************************/
void DetectCorsairDominatorPlatinumControllers(std::vector<i2c_smbus_interface *> &busses)
{
for(unsigned int bus = 0; bus < busses.size(); bus++)
{
IF_DRAM_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
{
for(unsigned char addr = 0x58; addr <= 0x5f; addr++)
{
if(TestForCorsairDominatorPlatinumController(busses[bus], addr))
{
CorsairDominatorPlatinumController* new_controller = new CorsairDominatorPlatinumController(busses[bus], addr);
RGBController_CorsairDominatorPlatinum* new_rgbcontroller = new RGBController_CorsairDominatorPlatinum(new_controller);
ResourceManager::get()->RegisterRGBController(new_rgbcontroller);
}
std::this_thread::sleep_for(10ms);
}
}
}
}
REGISTER_I2C_DETECTOR("Corsair Dominator Platinum", DetectCorsairDominatorPlatinumControllers);
@@ -1,114 +0,0 @@
/*-------------------------------------------------*\
| RGBController_CorsairDominatorPlatinum.cpp |
| |
| Corsair Vengeance Pro RGB driver |
| |
| Erik Gilling (konkers) 9/25/2020 |
\*-------------------------------------------------*/
#include "RGBController_CorsairDominatorPlatinum.h"
RGBController_CorsairDominatorPlatinum::RGBController_CorsairDominatorPlatinum(CorsairDominatorPlatinumController* corsair_ptr)
{
corsair = corsair_ptr;
name = corsair->GetDeviceName();
vendor = "Corsair";
type = DEVICE_TYPE_DRAM;
description = "Corsair Dominator Platinum RGB Device";
location = corsair->GetDeviceLocation();
mode Direct;
Direct.name = "Direct";
Direct.value = 0;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.speed_min = 0;
Direct.speed_max = 0;
Direct.speed = 0;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
SetupZones();
active_mode = 0;
}
RGBController_CorsairDominatorPlatinum::~RGBController_CorsairDominatorPlatinum()
{
delete corsair;
}
void RGBController_CorsairDominatorPlatinum::SetupZones()
{
/*---------------------------------------------------------*\
| Set up zone |
\*---------------------------------------------------------*/
zone new_zone;
new_zone.name = "Corsair Platinum Zone";
new_zone.type = ZONE_TYPE_LINEAR;
new_zone.leds_min = corsair->GetLEDCount();
new_zone.leds_max = corsair->GetLEDCount();
new_zone.leds_count = corsair->GetLEDCount();
new_zone.matrix_map = NULL;
zones.push_back(new_zone);
/*---------------------------------------------------------*\
| Set up LEDs |
\*---------------------------------------------------------*/
for(std::size_t led_idx = 0; led_idx < zones[0].leds_count; led_idx++)
{
led *new_led = new led();
new_led->name = "Corsair Platinum LED ";
new_led->name.append(std::to_string(led_idx));
leds.push_back(*new_led);
}
SetupColors();
}
void RGBController_CorsairDominatorPlatinum::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_CorsairDominatorPlatinum::DeviceUpdateLEDs()
{
for(std::size_t led = 0; led < colors.size(); led++)
{
RGBColor color = colors[led];
unsigned char red = RGBGetRValue(color);
unsigned char grn = RGBGetGValue(color);
unsigned char blu = RGBGetBValue(color);
corsair->SetLEDColor(led, red, grn, blu);
}
corsair->ApplyColors();
}
void RGBController_CorsairDominatorPlatinum::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_CorsairDominatorPlatinum::UpdateSingleLED(int led)
{
RGBColor color = colors[led];
unsigned char red = RGBGetRValue(color);
unsigned char grn = RGBGetGValue(color);
unsigned char blu = RGBGetBValue(color);
corsair->SetLEDColor(led, red, grn, blu);
corsair->ApplyColors();
}
void RGBController_CorsairDominatorPlatinum::SetCustomMode()
{
active_mode = 0;
}
void RGBController_CorsairDominatorPlatinum::DeviceUpdateMode()
{
}
@@ -1,33 +0,0 @@
/*--------------------------------------------*\
| RGBController_CorsairDominatorPlatinum.h |
| |
| Corsair Dominator Platinum RGB driver |
| |
| Erik Gilling (konkers) 9/25/2020 |
\*--------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CorsairDominatorPlatinumController.h"
class RGBController_CorsairDominatorPlatinum : public RGBController
{
public:
RGBController_CorsairDominatorPlatinum(CorsairDominatorPlatinumController* corsair_ptr);
~RGBController_CorsairDominatorPlatinum();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
CorsairDominatorPlatinumController* corsair;
};
@@ -1,276 +0,0 @@
/*---------------------------------------------------------*\
| Processing Code for Corsair Hydro Series |
| |
| Adam Honse ([email protected]), 8/17/2020 |
\*---------------------------------------------------------*/
#include "CorsairHydroController.h"
#include <cstring>
#include <iomanip>
#include <sstream>
CorsairHydroController::CorsairHydroController(libusb_device_handle* dev_handle)
{
dev = dev_handle;
/*-----------------------------------------------------*\
| Fill in location string with USB ID |
\*-----------------------------------------------------*/
libusb_device_descriptor descriptor;
libusb_get_device_descriptor(libusb_get_device(dev_handle), &descriptor);
std::stringstream location_stream;
location_stream << std::hex << std::setfill('0') << std::setw(4) << descriptor.idVendor << ":" << std::hex << std::setfill('0') << std::setw(4) << descriptor.idProduct;
location = location_stream.str();
SendInit();
SendFirmwareRequest();
}
CorsairHydroController::~CorsairHydroController()
{
if(dev)
{
libusb_close(dev);
}
}
std::string CorsairHydroController::GetFirmwareString()
{
return(firmware_version);
}
std::string CorsairHydroController::GetLocation()
{
return("USB: " + location);
}
void CorsairHydroController::SetBlink
(
std::vector<RGBColor> & colors,
unsigned char speed
)
{
SendColors(colors);
SendSpeed(speed);
SendApplyBlink();
}
void CorsairHydroController::SetFixed
(
std::vector<RGBColor> & colors
)
{
SendColors(colors);
/*-----------------------------------------------------*\
| Fixed mode seems to just be shift mode with the same |
| value for both colors |
\*-----------------------------------------------------*/
SendApplyShift();
}
void CorsairHydroController::SetPulse
(
std::vector<RGBColor> & colors,
unsigned char speed
)
{
SendColors(colors);
SendSpeed(speed);
SendApplyPulse();
}
void CorsairHydroController::SetShift
(
std::vector<RGBColor> & colors,
unsigned char speed
)
{
SendColors(colors);
SendSpeed(speed);
SendApplyShift();
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void CorsairHydroController::SendApplyBlink()
{
unsigned char usb_buf[3];
int actual;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Apply Blink packet |
\*-----------------------------------------------------*/
usb_buf[0] = 0x58;
usb_buf[1] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_bulk_transfer(dev, 0x01, usb_buf, 2, &actual, 1000);
libusb_bulk_transfer(dev, 0x81, usb_buf, 3, &actual, 1000);
}
void CorsairHydroController::SendApplyPulse()
{
unsigned char usb_buf[3];
int actual;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Apply Pulse packet |
\*-----------------------------------------------------*/
usb_buf[0] = 0x52;
usb_buf[1] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_bulk_transfer(dev, 0x01, usb_buf, 2, &actual, 1000);
libusb_bulk_transfer(dev, 0x81, usb_buf, 3, &actual, 1000);
}
void CorsairHydroController::SendApplyShift()
{
unsigned char usb_buf[3];
int actual;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Apply Shift packet |
\*-----------------------------------------------------*/
usb_buf[0] = 0x55;
usb_buf[1] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_bulk_transfer(dev, 0x01, usb_buf, 2, &actual, 1000);
libusb_bulk_transfer(dev, 0x81, usb_buf, 3, &actual, 1000);
}
void CorsairHydroController::SendFirmwareRequest()
{
unsigned char usb_buf[8];
int actual;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Firmware Request packet |
\*-----------------------------------------------------*/
usb_buf[0] = 0xAA;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_bulk_transfer(dev, 0x01, usb_buf, 1, &actual, 1000);
libusb_bulk_transfer(dev, 0x81, usb_buf, 7, &actual, 1000);
firmware_version = std::to_string(usb_buf[3]) + "." + std::to_string(usb_buf[4]) + "." + std::to_string(usb_buf[5]) + "." + std::to_string(usb_buf[6]);
}
void CorsairHydroController::SendColors
(
std::vector<RGBColor> & colors
)
{
unsigned char usb_buf[23];
int actual;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Send Colors packet |
\*-----------------------------------------------------*/
usb_buf[0] = 0x56;
usb_buf[1] = colors.size();
/*---------------------------------------------------------*\
| Fill in colors from vector |
\*---------------------------------------------------------*/
for(std::size_t color_idx = 0; color_idx < colors.size(); color_idx++)
{
usb_buf[(color_idx * 3) + 2] = RGBGetRValue(colors[color_idx]);
usb_buf[(color_idx * 3) + 3] = RGBGetGValue(colors[color_idx]);
usb_buf[(color_idx * 3) + 4] = RGBGetBValue(colors[color_idx]);
/*---------------------------------------------------------*\
| If the color vector only has one entry, duplicate it, as |
| the controller appears to require two colors in order to |
| update. |
\*---------------------------------------------------------*/
if((color_idx == 0) && colors.size() == 1)
{
usb_buf[1] = colors.size() + 1;
usb_buf[(color_idx * 3) + 5] = RGBGetRValue(colors[color_idx]);
usb_buf[(color_idx * 3) + 6] = RGBGetGValue(colors[color_idx]);
usb_buf[(color_idx * 3) + 7] = RGBGetBValue(colors[color_idx]);
}
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_bulk_transfer(dev, 0x01, usb_buf, 2 + (usb_buf[1] * 3), &actual, 1000);
libusb_bulk_transfer(dev, 0x81, usb_buf, 3, &actual, 1000);
}
void CorsairHydroController::SendInit()
{
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_control_transfer( dev, 0x40, 0x00, 0xffff, 0x0000, NULL, 0, 0 );
libusb_control_transfer( dev, 0x40, 0x02, 0x0002, 0x0000, NULL, 0, 0 );
}
void CorsairHydroController::SendSpeed
(
unsigned char speed
)
{
unsigned char usb_buf[3];
int actual;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Send Speed packet |
\*-----------------------------------------------------*/
usb_buf[0] = 0x53;
usb_buf[1] = speed;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
libusb_bulk_transfer(dev, 0x01, usb_buf, 2, &actual, 1000);
libusb_bulk_transfer(dev, 0x81, usb_buf, 3, &actual, 1000);
}
@@ -1,89 +0,0 @@
/*---------------------------------------------------------*\
| Definitions for Corsair Hydro Series |
| |
| Adam Honse ([email protected]), 8/17/2020 |
\*---------------------------------------------------------*/
#include "RGBController.h"
#include <vector>
#include <libusb-1.0/libusb.h>
#pragma once
enum
{
CORSAIR_HYDRO_CMD_READ_PUMP_SPEED = 0x31,
CORSAIR_HYDRO_CMD_WRITE_PUMP_MODE = 0x32,
CORSAIR_HYDRO_CMD_READ_PUMP_MODE = 0x33,
CORSAIR_HYDRO_CMD_READ_FAN_SPEED = 0x41,
CORSAIR_HYDRO_CMD_READ_AIO_TEMP = 0xA9,
CORSAIR_HYDRO_CMD_READ_FIRMWARE = 0xAA,
};
enum
{
CORSAIR_HYDRO_PUMP_MODE_QUIET = 0x00,
CORSAIR_HYDRO_PUMP_MODE_BALANCED = 0x01,
CORSAIR_HYDRO_PUMP_MODE_PERFORMANCE = 0x02,
};
class CorsairHydroController
{
public:
CorsairHydroController(libusb_device_handle* dev_handle);
~CorsairHydroController();
unsigned char GetFanPercent(unsigned char fan_channel);
unsigned short GetFanRPM(unsigned char fan_channel);
std::string GetFirmwareString();
std::string GetLocation();
void SetBlink
(
std::vector<RGBColor> & colors,
unsigned char speed
);
void SetFixed
(
std::vector<RGBColor> & colors
);
void SetPulse
(
std::vector<RGBColor> & colors,
unsigned char speed
);
void SetShift
(
std::vector<RGBColor> & colors,
unsigned char speed
);
private:
libusb_device_handle* dev;
std::string firmware_version;
std::string location;
void SendApplyBlink();
void SendApplyPulse();
void SendApplyShift();
void SendColors
(
std::vector<RGBColor> & colors
);
void SendFirmwareRequest();
void SendInit();
void SendSpeed
(
unsigned char speed
);
};
@@ -1,77 +0,0 @@
#include "Detector.h"
#include "CorsairHydroController.h"
#include "RGBController.h"
#include "RGBController_CorsairHydro.h"
#include <vector>
#include <libusb-1.0/libusb.h>
/*-----------------------------------------------------*\
| Corsair vendor ID |
\*-----------------------------------------------------*/
#define CORSAIR_VID 0x1B1C
/*-----------------------------------------------------*\
| Keyboard Hydro Series product IDs |
\*-----------------------------------------------------*/
#define CORSAIR_H115I_PRO_RGB_PID 0x0C13
#define CORSAIR_H100I_PRO_RGB_PID 0x0C15
#define CORSAIR_H150I_PRO_RGB_PID 0x0C12
typedef struct
{
unsigned short usb_vid;
unsigned short usb_pid;
unsigned char usb_interface;
const char * name;
} corsair_hydro_device;
#define CORSAIR_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
static const corsair_hydro_device device_list[] =
{
/*-----------------------------------------------------------------------------------------------------*\
| Coolers |
\*-----------------------------------------------------------------------------------------------------*/
{ CORSAIR_VID, CORSAIR_H100I_PRO_RGB_PID, 0, "Corsair H100i PRO RGB" },
{ CORSAIR_VID, CORSAIR_H115I_PRO_RGB_PID, 0, "Corsair H115i PRO RGB" },
{ CORSAIR_VID, CORSAIR_H150I_PRO_RGB_PID, 0, "Corsair H150i PRO RGB" },
};
/******************************************************************************************\
* *
* DetectCorsairHydroControllers *
* *
* Tests the USB address to see if a Corsair RGB Cooler controller exists there. *
* *
\******************************************************************************************/
void DetectCorsairHydroControllers(std::vector<RGBController*>& rgb_controllers)
{
libusb_init(NULL);
#ifdef _WIN32
libusb_set_option(NULL, LIBUSB_OPTION_USE_USBDK);
#endif
for(std::size_t device_idx = 0; device_idx < CORSAIR_NUM_DEVICES; device_idx++)
{
libusb_device_handle * dev = libusb_open_device_with_vid_pid(NULL, device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for Corsair RGB Peripheral
if(dev)
{
libusb_detach_kernel_driver(dev, 0);
libusb_claim_interface(dev, 0);
CorsairHydroController* controller = new CorsairHydroController(dev);//, device_list[device_idx].usb_endpoint);
RGBController_CorsairHydro* rgb_controller = new RGBController_CorsairHydro(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
} /* DetectCorsairHydroControllers() */
REGISTER_DETECTOR("Corsair Hydro Series", DetectCorsairHydroControllers);
@@ -1,143 +0,0 @@
/*-----------------------------------------*\
| RGBController_CorsairHydro.cpp |
| |
| Generic RGB Interface for Corsair |
| Hydro Series |
| |
| Adam Honse (CalcProgrammer1) 8/18/2020 |
\*-----------------------------------------*/
#include "RGBController_CorsairHydro.h"
RGBController_CorsairHydro::RGBController_CorsairHydro(CorsairHydroController* corsair_ptr)
{
corsair = corsair_ptr;
vendor = "Corsair";
description = "Corsair Hydro Series Device";
version = corsair->GetFirmwareString();
type = DEVICE_TYPE_COOLER;
location = corsair->GetLocation();
mode Direct;
Direct.name = "Direct";
Direct.value = 0;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Blinking;
Blinking.name = "Blinking";
Blinking.value = 1;
Blinking.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Blinking.color_mode = MODE_COLORS_MODE_SPECIFIC;
Blinking.speed_min = 0x0F;
Blinking.speed_max = 0x05;
Blinking.speed = 0x0A;
Blinking.colors_min = 2;
Blinking.colors_max = 2;
Blinking.colors.resize(2);
modes.push_back(Blinking);
mode ColorShift;
ColorShift.name = "Color Shift";
ColorShift.value = 2;
ColorShift.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
ColorShift.color_mode = MODE_COLORS_MODE_SPECIFIC;
ColorShift.speed_min = 0x46;
ColorShift.speed_max = 0x0F;
ColorShift.speed = 0x28;
ColorShift.colors_min = 2;
ColorShift.colors_max = 2;
ColorShift.colors.resize(2);
modes.push_back(ColorShift);
mode Pulsing;
Pulsing.name = "Pulsing";
Pulsing.value = 3;
Pulsing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Pulsing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Pulsing.speed_min = 0x50;
Pulsing.speed_max = 0x1E;
Pulsing.speed = 0x37;
Pulsing.colors_min = 2;
Pulsing.colors_max = 2;
Pulsing.colors.resize(2);
modes.push_back(Pulsing);
SetupZones();
}
RGBController_CorsairHydro::~RGBController_CorsairHydro()
{
delete corsair;
}
void RGBController_CorsairHydro::SetupZones()
{
zone new_zone;
new_zone.name = "Pump Zone";
new_zone.type = ZONE_TYPE_SINGLE;
new_zone.leds_min = 1;
new_zone.leds_max = 1;
new_zone.leds_count = 1;
new_zone.matrix_map = NULL;
zones.push_back(new_zone);
led new_led;
new_led.name = "Pump LED";
leds.push_back(new_led);
SetupColors();
}
void RGBController_CorsairHydro::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_CorsairHydro::DeviceUpdateLEDs()
{
DeviceUpdateMode();
}
void RGBController_CorsairHydro::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_CorsairHydro::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_CorsairHydro::SetCustomMode()
{
active_mode = 0;
}
void RGBController_CorsairHydro::DeviceUpdateMode()
{
switch(modes[active_mode].value)
{
case 0:
corsair->SetFixed(colors);
break;
case 1:
corsair->SetBlink(modes[active_mode].colors, modes[active_mode].speed);
break;
case 2:
corsair->SetShift(modes[active_mode].colors, modes[active_mode].speed);
break;
case 3:
corsair->SetPulse(modes[active_mode].colors, modes[active_mode].speed);
break;
}
}
@@ -1,33 +0,0 @@
/*-----------------------------------------*\
| RGBController_CorsairHydro.h |
| |
| Generic RGB Interface for Corsair |
| Hydro Series |
| |
| Adam Honse (CalcProgrammer1) 8/17/2020 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CorsairHydroController.h"
class RGBController_CorsairHydro : public RGBController
{
public:
RGBController_CorsairHydro(CorsairHydroController* corsair_ptr);
~RGBController_CorsairHydro();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
CorsairHydroController* corsair;
};
@@ -1,245 +0,0 @@
/*-------------------------------------------------------------------*\
| CorsairHydroPlatinumController.cpp |
| |
| Driver for Corsair Hydro Platinum AIO Coolers |
| |
| Kasper 28th March 2021 |
| |
\*-------------------------------------------------------------------*/
#include "CorsairHydroPlatinumController.h"
#include <cstring>
static const uint8_t CRC_TABLE[256] =
{
0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
};
static const uint8_t MAGIC_1[61] =
{
0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
0x7f, 0x7f, 0x7f, 0xff, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff,
0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff,
0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff
};
static const uint8_t MAGIC_2[61] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff
};
static const uint8_t MAGIC_3[61] =
{
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff
};
CorsairHydroPlatinumController::CorsairHydroPlatinumController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
SendMagic(MAGIC_1, CORSAIR_HYDRO_PLATINUM_MAGIC_1);
SendMagic(MAGIC_2, CORSAIR_HYDRO_PLATINUM_MAGIC_2);
SendMagic(MAGIC_3, CORSAIR_HYDRO_PLATINUM_MAGIC_3);
}
CorsairHydroPlatinumController::~CorsairHydroPlatinumController()
{
hid_close(dev);
}
std::string CorsairHydroPlatinumController::GetLocation()
{
return location;
}
std::string CorsairHydroPlatinumController::GetFirmwareString()
{
return firmware_version;
}
void CorsairHydroPlatinumController::SetupColors(std::vector<RGBColor> colors)
{
unsigned int end_led = colors.size() >= 20 ? 20 : colors.size();
SendColors(colors, 0, end_led, CORSAIR_HYDRO_PLATINUM_SET_LIGHTING_1);
if(colors.size() > 20)
{
end_led = colors.size() >= 40 ? 40 : colors.size();
SendColors(colors, 20, end_led, CORSAIR_HYDRO_PLATINUM_SET_LIGHTING_2);
}
if(colors.size() > 40)
{
end_led = colors.size() >= 48 ? 48 : colors.size();
SendColors(colors, 40, end_led, CORSAIR_HYDRO_PLATINUM_SET_LIGHTING_3);
}
}
void CorsairHydroPlatinumController::SendMagic(const uint8_t* magic, unsigned int command)
{
unsigned char usb_buf[CORSAIR_HYDRO_PLATINUM_PACKET_SIZE];
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x3F;
usb_buf[0x02] = (GetSequenceNumber()) | command;
/*-----------------------------------------------------*\
| Copy the magic bytes into the buffer |
\*-----------------------------------------------------*/
memcpy(&usb_buf[3], magic, 61 * sizeof magic[0]);
/*-----------------------------------------------------*\
| The data sent to the PEC function should not contain |
| the first (report id), second (prefix) and |
| last (checksum) bytes |
\*-----------------------------------------------------*/
std::vector<unsigned char> checksum_array;
checksum_array.insert(checksum_array.begin(), std::begin(usb_buf) + 2, std::end(usb_buf) - 1);
usb_buf[64] = ComputePEC(static_cast<void*>(checksum_array.data()), 62);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
hid_read(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
if(firmware_version.empty())
{
firmware_version =
std::to_string(usb_buf[2] >> 4) + "."
+ std::to_string(usb_buf[2] & 0xf) + "."
+ std::to_string(usb_buf[3]);
}
/*-----------------------------------------------------*\
| This delay prevents the AIO from soft-locking when |
| using an EE. |
\*-----------------------------------------------------*/
std::this_thread::sleep_for(std::chrono::milliseconds(CORSAIR_HYDRO_PLATINUM_PACKET_DELAY));
}
void CorsairHydroPlatinumController::SendColors(std::vector<RGBColor> colors, unsigned int start, unsigned int end, unsigned int command)
{
unsigned char usb_buf[CORSAIR_HYDRO_PLATINUM_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x3F;
usb_buf[0x02] = (GetSequenceNumber()) | command;
unsigned int i = 0;
for(std::size_t color_idx = start; color_idx < end; color_idx++)
{
usb_buf[(i * 3) + 3] = RGBGetBValue(colors[color_idx]);
usb_buf[(i * 3) + 4] = RGBGetGValue(colors[color_idx]);
usb_buf[(i * 3) + 5] = RGBGetRValue(colors[color_idx]);
i++;
}
/*-----------------------------------------------------*\
| The data sent to the PEC function should not contain |
| the first (report id), second (prefix) and |
| last (checksum) bytes |
\*-----------------------------------------------------*/
std::vector<unsigned char> checksum_array;
checksum_array.insert(checksum_array.begin(), std::begin(usb_buf) + 2, std::end(usb_buf) - 1);
usb_buf[64] = ComputePEC(static_cast<void*>(checksum_array.data()), 62);
hid_write(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
hid_read(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
/*-----------------------------------------------------*\
| This delay prevents the AIO from soft-locking when |
| using an EE. |
\*-----------------------------------------------------*/
std::this_thread::sleep_for(std::chrono::milliseconds(CORSAIR_HYDRO_PLATINUM_PACKET_DELAY));
}
unsigned int CorsairHydroPlatinumController::GetSequenceNumber()
{
if(sequence_number < 31)
{
sequence_number++;
}
else
{
sequence_number = 1;
}
return(sequence_number << 3);
}
uint8_t CorsairHydroPlatinumController::ComputePEC(const void * data, size_t size)
{
uint8_t val = 0;
uint8_t * pos = (uint8_t *) data;
uint8_t * end = pos + size;
while (pos < end)
{
val = CRC_TABLE[val ^ *pos];
pos++;
}
return val;
}
@@ -1,52 +0,0 @@
/*-------------------------------------------------------------------*\
| CorsairHydroPlatinumController.h |
| |
| Driver for Corsair Hydro Platinum AIO Coolers |
| |
| Kasper 28th March 2021 |
| |
\*-------------------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include <vector>
#include <string>
#include <hidapi/hidapi.h>
#define CORSAIR_HYDRO_PLATINUM_PACKET_SIZE 65
#define CORSAIR_HYDRO_PLATINUM_PACKET_DELAY 5
enum
{
CORSAIR_HYDRO_PLATINUM_MAGIC_1 = 0b001,
CORSAIR_HYDRO_PLATINUM_MAGIC_2 = 0b010,
CORSAIR_HYDRO_PLATINUM_MAGIC_3 = 0b011,
CORSAIR_HYDRO_PLATINUM_SET_LIGHTING_1 = 0b100,
CORSAIR_HYDRO_PLATINUM_SET_LIGHTING_2 = 0b101,
CORSAIR_HYDRO_PLATINUM_SET_LIGHTING_3 = 0b110,
};
class CorsairHydroPlatinumController
{
public:
CorsairHydroPlatinumController(hid_device* dev_handle, const char* path);
~CorsairHydroPlatinumController();
std::string GetLocation();
std::string GetFirmwareString();
void SetupColors(std::vector<RGBColor> colors);
private:
hid_device* dev;
std::string location;
std::string firmware_version;
std::atomic<unsigned int> sequence_number;
void SendMagic(const uint8_t* magic, unsigned int command);
void SendColors(std::vector<RGBColor> colors, unsigned int start, unsigned int end, unsigned int command);
unsigned int GetSequenceNumber();
uint8_t ComputePEC(const void * data, size_t size);
};
@@ -1,49 +0,0 @@
/*-------------------------------------------------------------------*\
| CorsairHydroPlatinumControllerDetect.cpp |
| |
| Driver for Corsair Hydro Platinum AIO Coolers |
| |
| Kasper 28th March 2021 |
| |
\*-------------------------------------------------------------------*/
#include "Detector.h"
#include "CorsairHydroPlatinumController.h"
#include "RGBController.h"
#include "RGBController_CorsairHydroPlatinum.h"
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| Corsair vendor ID |
\*-----------------------------------------------------*/
#define CORSAIR_VID 0x1B1C
/*-----------------------------------------------------*\
| Product IDs |
\*-----------------------------------------------------*/
#define CORSAIR_HYDRO_H100I_PLATINUM_PID 0x0c18
#define CORSAIR_HYDRO_H100I_PLATINUM_SE_PID 0x0C19
#define CORSAIR_HYDRO_H115I_PLATINUM_PID 0x0c17
#define CORSAIR_HYDRO_H100I_PRO_XT_PID 0x0c20
#define CORSAIR_HYDRO_H115I_PRO_XT_PID 0x0c21
#define CORSAIR_HYDRO_H150I_PRO_XT_PID 0x0c22
void DetectCorsairHydroPlatinumControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if( dev )
{
CorsairHydroPlatinumController* controller = new CorsairHydroPlatinumController(dev, info->path);
RGBController_CorsairHydroPlatinum* rgb_controller = new RGBController_CorsairHydroPlatinum(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR("Corsair Hydro H100i Platinum", DetectCorsairHydroPlatinumControllers, CORSAIR_VID, CORSAIR_HYDRO_H100I_PLATINUM_PID );
REGISTER_HID_DETECTOR("Corsair Hydro H100i Platinum SE", DetectCorsairHydroPlatinumControllers, CORSAIR_VID, CORSAIR_HYDRO_H100I_PLATINUM_SE_PID );
REGISTER_HID_DETECTOR("Corsair Hydro H115i Platinum", DetectCorsairHydroPlatinumControllers, CORSAIR_VID, CORSAIR_HYDRO_H115I_PLATINUM_PID );
REGISTER_HID_DETECTOR("Corsair Hydro H100i Pro XT", DetectCorsairHydroPlatinumControllers, CORSAIR_VID, CORSAIR_HYDRO_H100I_PRO_XT_PID );
REGISTER_HID_DETECTOR("Corsair Hydro H115i Pro XT", DetectCorsairHydroPlatinumControllers, CORSAIR_VID, CORSAIR_HYDRO_H115I_PRO_XT_PID );
REGISTER_HID_DETECTOR("Corsair Hydro H150i Pro XT", DetectCorsairHydroPlatinumControllers, CORSAIR_VID, CORSAIR_HYDRO_H150I_PRO_XT_PID );
@@ -1,127 +0,0 @@
/*-------------------------------------------------------------------*\
| RGBController_CorsairHydroPlatinum.cpp |
| |
| Driver for Corsair Hydro Platinum AIO Coolers |
| |
| Kasper 28th March 2021 |
| |
\*-------------------------------------------------------------------*/
#include "RGBController_CorsairHydroPlatinum.h"
#define NA 0xFFFFFFFF
static unsigned int matrix_map[5][5] =
{
{ NA, 11, 12, 13, NA },
{ 10, NA, 1, NA, 14 },
{ 9, 0, NA, 2, 15 },
{ 8, NA, 3, NA, 4 },
{ NA, 7, 6, 5, NA }
};
RGBController_CorsairHydroPlatinum::RGBController_CorsairHydroPlatinum(CorsairHydroPlatinumController* corsair_ptr)
{
corsair = corsair_ptr;
name = "Corsair Hydro Platinum Series Device";
vendor = "Corsair";
description = "Corsair Hydro Platinum Series Device";
type = DEVICE_TYPE_COOLER;
location = corsair->GetLocation();
version = corsair->GetFirmwareString();
mode Direct;
Direct.name = "Direct";
Direct.value = 0;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
Init_Controller();
SetupZones();
}
void RGBController_CorsairHydroPlatinum::Init_Controller()
{
zone cpu_block_zone;
cpu_block_zone.name = "CPU Block";
cpu_block_zone.type = ZONE_TYPE_MATRIX;
cpu_block_zone.leds_min = 16;
cpu_block_zone.leds_max = 16;
cpu_block_zone.leds_count = 16;
cpu_block_zone.matrix_map = new matrix_map_type;
cpu_block_zone.matrix_map->height = 5;
cpu_block_zone.matrix_map->width = 5;
cpu_block_zone.matrix_map->map = (unsigned int *)&matrix_map;
zones.push_back(cpu_block_zone);
zone fans_zone;
fans_zone.name = "Fans";
fans_zone.type = ZONE_TYPE_LINEAR;
fans_zone.leds_min = 0;
fans_zone.leds_max = 32;
fans_zone.leds_count = 0;
fans_zone.matrix_map = NULL;
zones.push_back(fans_zone);
}
void RGBController_CorsairHydroPlatinum::SetupZones()
{
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
leds.clear();
colors.clear();
for (unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
for (unsigned int led_idx = 0; led_idx < zones[zone_idx].leds_count; led_idx++)
{
led new_led;
new_led.name = zones[zone_idx].name + " " + std::to_string(led_idx);;
leds.push_back(new_led);
}
}
SetupColors();
}
void RGBController_CorsairHydroPlatinum::ResizeZone(int zone, int new_size)
{
if((size_t) zone >= zones.size())
{
return;
}
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
{
zones[zone].leds_count = new_size;
SetupZones();
}
}
void RGBController_CorsairHydroPlatinum::DeviceUpdateLEDs()
{
corsair->SetupColors(colors);
}
void RGBController_CorsairHydroPlatinum::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_CorsairHydroPlatinum::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_CorsairHydroPlatinum::SetCustomMode()
{
active_mode = 0;
}
void RGBController_CorsairHydroPlatinum::DeviceUpdateMode()
{
}
@@ -1,34 +0,0 @@
/*-------------------------------------------------------------------*\
| RGBController_CorsairHydroPlatinum.h |
| |
| Driver for Corsair Hydro Platinum AIO Coolers |
| |
| Kasper 28th March 2021 |
| |
\*-------------------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CorsairHydroPlatinumController.h"
class RGBController_CorsairHydroPlatinum : public RGBController
{
public:
RGBController_CorsairHydroPlatinum(CorsairHydroPlatinumController* corsair_ptr);
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
CorsairHydroPlatinumController* corsair;
void Init_Controller();
};
@@ -11,12 +11,35 @@
#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;
CorsairLightingNodeController::CorsairLightingNodeController(hid_device* dev_handle, const char* path)
THREAD keepalive_thread(void *param)
{
dev = dev_handle;
location = path;
CorsairLightingNodeController* corsair = static_cast<CorsairLightingNodeController*>(param);
corsair->KeepaliveThread();
THREADRETURN
}
CorsairLightingNodeController::CorsairLightingNodeController(hid_device* dev_handle)
{
dev = dev_handle;
SendFirmwareRequest();
@@ -26,24 +49,23 @@ CorsairLightingNodeController::CorsairLightingNodeController(hid_device* dev_han
| to not revert back into rainbow mode. Start a thread |
| to continuously send a keepalive packet every 5s |
\*-----------------------------------------------------*/
keepalive_thread_run = 1;
keepalive_thread = new std::thread(&CorsairLightingNodeController::KeepaliveThread, this);
#ifdef WIN32
_beginthread(keepalive_thread, 0, this);
#else
pthread_t thread;
pthread_create(&thread, NULL, &keepalive_thread, this);
#endif
}
CorsairLightingNodeController::~CorsairLightingNodeController()
{
keepalive_thread_run = 0;
keepalive_thread->join();
delete keepalive_thread;
hid_close(dev);
}
void CorsairLightingNodeController::KeepaliveThread()
{
while(keepalive_thread_run.load())
while(1)
{
if((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::seconds(5))
if((clock() - last_commit_time) > 5000)
{
SendCommit();
}
@@ -56,27 +78,6 @@ std::string CorsairLightingNodeController::GetFirmwareString()
return(firmware_version);
}
std::string CorsairLightingNodeController::GetLocationString()
{
return("HID: " + location);
}
std::string CorsairLightingNodeController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void CorsairLightingNodeController::SetChannelEffect(unsigned char channel,
unsigned char num_leds,
unsigned char mode,
@@ -197,7 +198,7 @@ void CorsairLightingNodeController::SetChannelLEDs(unsigned char channel, RGBCol
void CorsairLightingNodeController::SendFirmwareRequest()
{
int actual;
unsigned char usb_buf[65];
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -207,14 +208,13 @@ void CorsairLightingNodeController::SendFirmwareRequest()
/*-----------------------------------------------------*\
| Set up Firmware Version Request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_FIRMWARE;
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_FIRMWARE;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
actual = hid_read(dev, usb_buf, 17);
hid_write(dev, usb_buf, 64);
actual = hid_read(dev, usb_buf, 16);
if(actual > 0)
{
@@ -231,7 +231,7 @@ void CorsairLightingNodeController::SendDirect
unsigned char* color_data
)
{
unsigned char usb_buf[65];
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -241,28 +241,27 @@ void CorsairLightingNodeController::SendDirect
/*-----------------------------------------------------*\
| Set up Direct packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_DIRECT;
usb_buf[0x02] = channel;
usb_buf[0x03] = start;
usb_buf[0x04] = count;
usb_buf[0x05] = color_channel;
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[0x06], color_data, count);
memcpy(&usb_buf[0x05], color_data, count);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 16);
}
void CorsairLightingNodeController::SendCommit()
{
unsigned char usb_buf[65];
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -272,20 +271,19 @@ void CorsairLightingNodeController::SendCommit()
/*-----------------------------------------------------*\
| Update last commit time |
\*-----------------------------------------------------*/
last_commit_time = std::chrono::steady_clock::now();
last_commit_time = clock();
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_COMMIT;
usb_buf[0x02] = 0xFF;
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_COMMIT;
usb_buf[0x01] = 0xFF;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 16);
}
void CorsairLightingNodeController::SendBegin
@@ -293,7 +291,7 @@ void CorsairLightingNodeController::SendBegin
unsigned char channel
)
{
unsigned char usb_buf[65];
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -303,15 +301,14 @@ void CorsairLightingNodeController::SendBegin
/*-----------------------------------------------------*\
| Set up Begin packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_BEGIN;
usb_buf[0x02] = channel;
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_BEGIN;
usb_buf[0x01] = channel;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 16);
}
void CorsairLightingNodeController::SendEffectConfig
@@ -337,7 +334,7 @@ void CorsairLightingNodeController::SendEffectConfig
unsigned short temperature_2
)
{
unsigned char usb_buf[65];
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -347,49 +344,48 @@ void CorsairLightingNodeController::SendEffectConfig
/*-----------------------------------------------------*\
| Set up Effect Config packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_EFFECT_CONFIG;
usb_buf[0x02] = channel;
usb_buf[0x03] = count;
usb_buf[0x04] = led_type;
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[0x05] = mode;
usb_buf[0x06] = speed;
usb_buf[0x07] = direction;
usb_buf[0x08] = change_style;
usb_buf[0x09] = 0;
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[0x0A] = color_0_red;
usb_buf[0x0B] = color_0_green;
usb_buf[0x0C] = color_0_blue;
usb_buf[0x0D] = color_1_red;
usb_buf[0x0E] = color_1_green;
usb_buf[0x0F] = color_1_blue;
usb_buf[0x10] = color_2_red;
usb_buf[0x11] = color_2_green;
usb_buf[0x12] = color_2_blue;
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[0x13] = (temperature_0 >> 8);
usb_buf[0x14] = (temperature_0 & 0xFF);
usb_buf[0x15] = (temperature_1 >> 8);
usb_buf[0x16] = (temperature_1 & 0xFF);
usb_buf[0x17] = (temperature_2 >> 8);
usb_buf[0x18] = (temperature_2 & 0xFF);
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, 65);
hid_read(dev, usb_buf, 17);
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 16);
}
void CorsairLightingNodeController::SendTemperature()
@@ -402,7 +398,7 @@ void CorsairLightingNodeController::SendReset
unsigned char channel
)
{
unsigned char usb_buf[65];
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -412,15 +408,14 @@ void CorsairLightingNodeController::SendReset
/*-----------------------------------------------------*\
| Set up Reset packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_RESET;
usb_buf[0x02] = channel;
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_RESET;
usb_buf[0x01] = channel;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 16);
}
void CorsairLightingNodeController::SendPortState
@@ -429,7 +424,7 @@ void CorsairLightingNodeController::SendPortState
unsigned char state
)
{
unsigned char usb_buf[65];
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -439,16 +434,15 @@ void CorsairLightingNodeController::SendPortState
/*-----------------------------------------------------*\
| Set up Port State packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_PORT_STATE;
usb_buf[0x02] = channel;
usb_buf[0x03] = state;
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, 65);
hid_read(dev, usb_buf, 17);
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 16);
}
void CorsairLightingNodeController::SendBrightness()
@@ -5,7 +5,6 @@
\*---------------------------------------------------------*/
#include "RGBController.h"
#include <chrono>
#include <vector>
#include <hidapi/hidapi.h>
@@ -79,12 +78,10 @@ enum
class CorsairLightingNodeController
{
public:
CorsairLightingNodeController(hid_device* dev_handle, const char* path);
CorsairLightingNodeController(hid_device* dev_handle);
~CorsairLightingNodeController();
std::string GetFirmwareString();
std::string GetLocationString();
std::string GetSerialString();
unsigned int GetStripsOnChannel(unsigned int channel);
@@ -112,10 +109,7 @@ public:
private:
hid_device* dev;
std::string firmware_version;
std::string location;
std::thread* keepalive_thread;
std::atomic<bool> keepalive_thread_run;
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
clock_t last_commit_time;
void SendFirmwareRequest();
@@ -1,4 +1,3 @@
#include "Detector.h"
#include "CorsairLightingNodeController.h"
#include "RGBController.h"
#include "RGBController_CorsairLightingNode.h"
@@ -12,7 +11,26 @@
#define CORSAIR_LS100_PID 0x0C1E
#define CORSAIR_1000D_OBSIDIAN_PID 0x1D00
#define CORSAIR_SPEC_OMEGA_RGB_PID 0x1D04
#define CORSAIR_LT100_PID 0x0C23
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" }
};
/******************************************************************************************\
* *
@@ -22,22 +40,40 @@
* *
\******************************************************************************************/
void DetectCorsairLightingNodeControllers(hid_device_info* info, const std::string& name)
void DetectCorsairLightingNodeControllers(std::vector<RGBController*> &rgb_controllers)
{
hid_device* dev = hid_open_path(info->path);
if( dev )
hid_device_info* info;
hid_device* dev;
hid_init();
for(std::size_t device_idx = 0; device_idx < CORSAIR_NUM_DEVICES; device_idx++)
{
CorsairLightingNodeController* controller = new CorsairLightingNodeController(dev, info->path);
RGBController_CorsairLightingNode* rgb_controller = new RGBController_CorsairLightingNode(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
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() */
REGISTER_HID_DETECTOR("Corsair Lighting Node Core", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_LIGHTING_NODE_CORE_PID); // 1 channel
REGISTER_HID_DETECTOR("Corsair Lighting Node Pro", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_LIGHTING_NODE_PRO_PID); // 2 channels
REGISTER_HID_DETECTOR("Corsair Commander Pro", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_COMMANDER_PRO_PID); // 2 channels
REGISTER_HID_DETECTOR("Corsair LS100 Lighting Kit", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_LS100_PID); // 1 channel
REGISTER_HID_DETECTOR("Corsair 1000D Obsidian", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_1000D_OBSIDIAN_PID); // 2 channels
REGISTER_HID_DETECTOR("Corsair SPEC OMEGA RGB", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_SPEC_OMEGA_RGB_PID); // 2 channels
REGISTER_HID_DETECTOR("Corsair LT100", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_LT100_PID); // 2 channels
@@ -20,63 +20,37 @@ static unsigned int keys[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x
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, 0x10, 114};
static unsigned int keys_k95_plat[] = {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,
0x10, 114, 0x0a, 0x16, 0x22, 0x2e, 0x3a, 0x46, 125,
144, 145, 146, 158, 160, 147, 148, 149, 150, 151, 152, 153,
154, 155, 159, 162, 161, 156, 157};
static unsigned int keys_k95[] = {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,
0x10, 114, 0x0a, 0x16, 0x22, 0x2e, 0x3a, 0x46, 0x52, 0x5e, 0x6a, 0x76, 0x3b, 0x47, 0x53,
0x5f, 0x6b, 0x77, 0x83, 0x8f, 0x0b, 0x17, 0x23, 0x2f};
136, 137, 139, 140, 141};
static unsigned int st100[] = { 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x04 };
static unsigned int key_mapping_k95_plat_ansi[] = { 0x31, 0x3f, 0x41, 0x42, 0x51, 0x53, 0x55, 0x6f, 0x7e, 0x7f, 0x80, 0x81 };
static unsigned int key_mapping_k95_plat_iso[] = { 0x3f, 0x41, 0x42, 0x48, 0x50, 0x53, 0x55, 0x6f, 0x7e, 0x7f, 0x80, 0x81 };
CorsairPeripheralController::CorsairPeripheralController(hid_device* dev_handle, const char* path)
static void send_usb_msg(hid_device* dev, char * data_pkt)
{
dev = dev_handle;
location = path;
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();
/*-----------------------------------------------------*\
| K55 and K95 Platinum require additional steps |
\*-----------------------------------------------------*/
if (logical_layout == CORSAIR_TYPE_K55 || logical_layout == CORSAIR_TYPE_K95_PLAT)
{
SpecialFunctionControl();
}
SpecialFunctionControl();
LightingControl();
if (logical_layout == CORSAIR_TYPE_K55 || logical_layout == CORSAIR_TYPE_K95_PLAT)
{
SetupK55AndK95LightingControl();
}
}
CorsairPeripheralController::~CorsairPeripheralController()
{
hid_close(dev);
}
device_type CorsairPeripheralController::GetDeviceType()
@@ -84,60 +58,17 @@ device_type CorsairPeripheralController::GetDeviceType()
return type;
}
std::string CorsairPeripheralController::GetDeviceLocation()
{
return("HID: " + location);
}
int CorsairPeripheralController::GetPhysicalLayout()
{
return physical_layout;
}
int CorsairPeripheralController::GetLogicalLayout()
{
return logical_layout;
}
std::string CorsairPeripheralController::GetFirmwareString()
{
return firmware_version;
}
std::string CorsairPeripheralController::GetName()
{
return name;
}
std::string CorsairPeripheralController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void CorsairPeripheralController::SetLEDs(std::vector<RGBColor>colors)
{
switch(type)
{
case DEVICE_TYPE_KEYBOARD:
if (logical_layout == CORSAIR_TYPE_K55)
{
SubmitKeyboardZonesColors(colors[0], colors[1], colors[2]);
}
else
{
SetLEDsKeyboardFull(colors);
}
SetLEDsKeyboardFull(colors);
break;
case DEVICE_TYPE_MOUSE:
@@ -172,10 +103,9 @@ void CorsairPeripheralController::SetLEDs(std::vector<RGBColor>colors)
void CorsairPeripheralController::SetLEDsKeyboardFull(std::vector<RGBColor> colors)
{
unsigned char red_val[168];
unsigned char grn_val[168];
unsigned char blu_val[168];
unsigned char data_sz = 24;
unsigned char red_val[144];
unsigned char grn_val[144];
unsigned char blu_val[144];
/*-----------------------------------------------------*\
| Zero out buffers |
@@ -190,26 +120,9 @@ void CorsairPeripheralController::SetLEDsKeyboardFull(std::vector<RGBColor> colo
for(std::size_t color_idx = 0; color_idx < colors.size(); color_idx++)
{
RGBColor color = colors[color_idx];
if (logical_layout == CORSAIR_TYPE_K95_PLAT)
{
red_val[keys_k95_plat[color_idx]] = RGBGetRValue(color);
grn_val[keys_k95_plat[color_idx]] = RGBGetGValue(color);
blu_val[keys_k95_plat[color_idx]] = RGBGetBValue(color);
data_sz = 48;
}
else if (logical_layout == CORSAIR_TYPE_K95)
{
red_val[keys_k95[color_idx]] = RGBGetRValue(color);
grn_val[keys_k95[color_idx]] = RGBGetGValue(color);
blu_val[keys_k95[color_idx]] = RGBGetBValue(color);
data_sz = 48; //untested
}
else
{
red_val[keys[color_idx]] = RGBGetRValue(color);
grn_val[keys[color_idx]] = RGBGetGValue(color);
blu_val[keys[color_idx]] = RGBGetBValue(color);
}
red_val[keys[color_idx]] = RGBGetRValue(color);
grn_val[keys[color_idx]] = RGBGetGValue(color);
blu_val[keys[color_idx]] = RGBGetBValue(color);
}
/*-----------------------------------------------------*\
@@ -217,7 +130,7 @@ void CorsairPeripheralController::SetLEDsKeyboardFull(std::vector<RGBColor> colo
\*-----------------------------------------------------*/
StreamPacket(1, 60, &red_val[0]);
StreamPacket(2, 60, &red_val[60]);
StreamPacket(3, data_sz, &red_val[120]);
StreamPacket(3, 24, &red_val[120]);
SubmitKeyboardFullColors(1, 3, 1);
/*-----------------------------------------------------*\
@@ -225,7 +138,7 @@ void CorsairPeripheralController::SetLEDsKeyboardFull(std::vector<RGBColor> colo
\*-----------------------------------------------------*/
StreamPacket(1, 60, &grn_val[0]);
StreamPacket(2, 60, &grn_val[60]);
StreamPacket(3, data_sz, &grn_val[120]);
StreamPacket(3, 24, &grn_val[120]);
SubmitKeyboardFullColors(2, 3, 1);
/*-----------------------------------------------------*\
@@ -233,7 +146,7 @@ void CorsairPeripheralController::SetLEDsKeyboardFull(std::vector<RGBColor> colo
\*-----------------------------------------------------*/
StreamPacket(1, 60, &blu_val[0]);
StreamPacket(2, 60, &blu_val[60]);
StreamPacket(3, data_sz, &blu_val[120]);
StreamPacket(3, 24, &blu_val[120]);
SubmitKeyboardFullColors(3, 3, 2);
}
@@ -314,18 +227,13 @@ void CorsairPeripheralController::SetLEDsKeyboardLimited(std::vector<RGBColor> c
SubmitKeyboardLimitedColors(216);
}
void CorsairPeripheralController::SetName(std::string device_name)
{
name = device_name;
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void CorsairPeripheralController::LightingControl()
{
char usb_buf[65];
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -335,10 +243,9 @@ void CorsairPeripheralController::LightingControl()
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_LIGHTING_CONTROL;
usb_buf[0x03] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
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 |
@@ -348,105 +255,31 @@ void CorsairPeripheralController::LightingControl()
{
default:
case DEVICE_TYPE_KEYBOARD:
usb_buf[0x05] = 0x03; // On K95 Platinum, this controls keyboard brightness
usb_buf[0x04] = 0x03;
break;
case DEVICE_TYPE_MOUSE:
usb_buf[0x05] = 0x01;
usb_buf[0x04] = 0x01;
break;
case DEVICE_TYPE_MOUSEMAT:
usb_buf[0x05] = 0x04;
usb_buf[0x04] = 0x04;
break;
case DEVICE_TYPE_HEADSET_STAND:
usb_buf[0x05] = 0x03;
usb_buf[0x04] = 0x03;
break;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
/*-----------------------------------------------------*\
| Probably a key mapping packet? |
\*-----------------------------------------------------*/
void CorsairPeripheralController::SetupK55AndK95LightingControl()
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up a packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_LIGHTING_CONTROL;
usb_buf[0x03] = 0x08;
usb_buf[0x05] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
unsigned int* skipped_identifiers = key_mapping_k95_plat_ansi;
int skipped_identifiers_count = sizeof(key_mapping_k95_plat_ansi) / sizeof(key_mapping_k95_plat_ansi[0]);
if (physical_layout == CORSAIR_LAYOUT_ISO)
{
skipped_identifiers = key_mapping_k95_plat_iso;
skipped_identifiers_count = sizeof(key_mapping_k95_plat_iso) / sizeof(key_mapping_k95_plat_iso[0]);
}
unsigned int identifier = 0;
for (int i = 0; i < 4; i++)
{
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up a packet - a sequence of 120 ids |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = 0x40;
usb_buf[0x03] = 0x1E;
for (int j = 0; j < 30; j++)
{
for (int j = 0; j < skipped_identifiers_count; j++)
{
if (identifier == skipped_identifiers[j])
{
identifier++;
}
}
usb_buf[5 + 2 * j] = identifier++;
usb_buf[5 + 2 * j + 1] = 0xC0;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
send_usb_msg(dev, usb_buf);
}
void CorsairPeripheralController::SpecialFunctionControl()
{
char usb_buf[65];
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -456,22 +289,20 @@ void CorsairPeripheralController::SpecialFunctionControl()
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SPECIAL_FUNCTION;
usb_buf[0x03] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_SPECIAL_FUNCTION;
usb_buf[0x02] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
send_usb_msg(dev, usb_buf);
}
void CorsairPeripheralController::ReadFirmwareInfo()
{
int actual;
char usb_buf[65];
char offset = 0;
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -481,17 +312,16 @@ void CorsairPeripheralController::ReadFirmwareInfo()
/*-----------------------------------------------------*\
| Set up Read Firmware Info packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_READ;
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
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, 65);
actual = hid_read_timeout(dev, (unsigned char*)usb_buf, 65, 1000);
hid_write(dev, (unsigned char*)usb_buf, 64);
actual = hid_read_timeout(dev, (unsigned char*)usb_buf, 64, 1000);
if(actual == 0)
{
@@ -503,13 +333,11 @@ void CorsairPeripheralController::ReadFirmwareInfo()
/*-------------------------------------------------*\
| Set up Read Firmware Info packet |
\*-------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_READ;
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
usb_buf[0x00] = CORSAIR_COMMAND_READ;
usb_buf[0x01] = CORSAIR_PROPERTY_FIRMWARE_INFO;
hid_send_feature_report(dev, (unsigned char*)usb_buf, 65);
actual = hid_get_feature_report(dev, (unsigned char*)usb_buf, 65);
offset = 1;
hid_write(dev, (unsigned char*)usb_buf, 64);
actual = hid_get_feature_report(dev, (unsigned char*)usb_buf, 64);
}
/*-----------------------------------------------------*\
@@ -518,65 +346,14 @@ void CorsairPeripheralController::ReadFirmwareInfo()
| 0xC1 Device is a mouse |
| 0xC2 Device is a mousepad or headset stand |
\*-----------------------------------------------------*/
switch((unsigned char)usb_buf[0x14 + offset])
switch((unsigned char)usb_buf[0x14])
{
case 0xC0:
{
unsigned short pid = (unsigned short)(usb_buf[0x0E] << 8) + (unsigned char)(usb_buf[0x0F]);
/*-----------------------------------------------------*\
| Get the correct Keyboard Type |
\*-----------------------------------------------------*/
switch(pid)
{
case 0x1B2D:
logical_layout = CORSAIR_TYPE_K95_PLAT;
break;
case 0x1B11:
logical_layout = CORSAIR_TYPE_K95;
break;
case 0x1B3D:
logical_layout = CORSAIR_TYPE_K55;
break;
default:
logical_layout = CORSAIR_TYPE_NORMAL;
}
/*-----------------------------------------------------*\
| Get the correct Keyboard Layout. |
| Currently unused but can be implemented in the future.|
\*-----------------------------------------------------*/
switch((unsigned char)usb_buf[0x17 + offset])
{
case CORSAIR_LAYOUT_ANSI:
physical_layout = CORSAIR_LAYOUT_ANSI;
break;
case CORSAIR_LAYOUT_ISO:
physical_layout = CORSAIR_LAYOUT_ISO;
break;
case CORSAIR_LAYOUT_ABNT:
physical_layout = CORSAIR_LAYOUT_ABNT;
break;
case CORSAIR_LAYOUT_JIS:
physical_layout = CORSAIR_LAYOUT_JIS;
break;
case CORSAIR_LAYOUT_DUBEOLSIK:
physical_layout = CORSAIR_LAYOUT_DUBEOLSIK;
break;
default:
physical_layout = CORSAIR_LAYOUT_ANSI;
}
}
type = DEVICE_TYPE_KEYBOARD;
break;
case 0xC1:
type = DEVICE_TYPE_MOUSE;
SpecialFunctionControl();
break;
case 0xC2:
@@ -587,12 +364,10 @@ void CorsairPeripheralController::ReadFirmwareInfo()
{
case 0x0A34:
type = DEVICE_TYPE_HEADSET_STAND;
SpecialFunctionControl();
break;
default:
type = DEVICE_TYPE_MOUSEMAT;
SpecialFunctionControl();
break;
}
}
@@ -608,7 +383,7 @@ void CorsairPeripheralController::ReadFirmwareInfo()
\*-----------------------------------------------------*/
if(type != DEVICE_TYPE_UNKNOWN)
{
firmware_version = std::to_string(usb_buf[0x09 + offset]) + "." + std::to_string(usb_buf[0x08 + offset]);
firmware_version = std::to_string(usb_buf[0x09]) + "." + std::to_string(usb_buf[0x08]);
}
}
@@ -619,7 +394,7 @@ void CorsairPeripheralController::StreamPacket
unsigned char* data_ptr
)
{
char usb_buf[65];
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -629,20 +404,19 @@ void CorsairPeripheralController::StreamPacket
/*-----------------------------------------------------*\
| Set up Stream packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_STREAM;
usb_buf[0x02] = packet_id;
usb_buf[0x03] = data_sz;
usb_buf[0x00] = CORSAIR_COMMAND_STREAM;
usb_buf[0x01] = packet_id;
usb_buf[0x02] = data_sz;
/*-----------------------------------------------------*\
| Copy in data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x05], data_ptr, data_sz);
memcpy(&usb_buf[0x04], data_ptr, data_sz);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
hid_write(dev, (unsigned char *)usb_buf, 64);
}
void CorsairPeripheralController::SubmitKeyboardFullColors
@@ -652,7 +426,7 @@ void CorsairPeripheralController::SubmitKeyboardFullColors
unsigned char finish_val
)
{
char usb_buf[65];
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -662,55 +436,16 @@ void CorsairPeripheralController::SubmitKeyboardFullColors
/*-----------------------------------------------------*\
| Set up Submit Keyboard 24-Bit Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_24;
usb_buf[0x03] = color_channel;
usb_buf[0x04] = packet_count;
usb_buf[0x05] = finish_val;
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, 65);
}
void CorsairPeripheralController::SubmitKeyboardZonesColors
(
RGBColor left,
RGBColor mid,
RGBColor right
)
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Keyboard 24-Bit Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_KBZONES_COLOR_24;
usb_buf[0x03] = 0x00;
usb_buf[0x04] = 0x00;
usb_buf[0x05] = RGBGetRValue(left);
usb_buf[0x06] = RGBGetGValue(left);
usb_buf[0x07] = RGBGetBValue(left);
usb_buf[0x08] = RGBGetRValue(mid);
usb_buf[0x09] = RGBGetGValue(mid);
usb_buf[0x0A] = RGBGetBValue(mid);
usb_buf[0x0B] = RGBGetRValue(right);
usb_buf[0x0C] = RGBGetGValue(right);
usb_buf[0x0D] = RGBGetBValue(right);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
hid_write(dev, (unsigned char *)usb_buf, 64);
}
void CorsairPeripheralController::SubmitKeyboardLimitedColors
@@ -718,7 +453,7 @@ void CorsairPeripheralController::SubmitKeyboardLimitedColors
unsigned char byte_count
)
{
char usb_buf[65];
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -728,15 +463,14 @@ void CorsairPeripheralController::SubmitKeyboardLimitedColors
/*-----------------------------------------------------*\
| Set up Submit Keyboard 9-Bit Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_9;
usb_buf[0x05] = byte_count;
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, 65);
hid_write(dev, (unsigned char *)usb_buf, 64);
}
void CorsairPeripheralController::SubmitMouseColors
@@ -745,7 +479,7 @@ void CorsairPeripheralController::SubmitMouseColors
RGBColor * color_data
)
{
char usb_buf[65];
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -755,27 +489,26 @@ void CorsairPeripheralController::SubmitMouseColors
/*-----------------------------------------------------*\
| Set up Submit Mouse Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
usb_buf[0x03] = num_zones;
usb_buf[0x04] = 0x00;
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) + 5] = zone_idx;
usb_buf[(zone_idx * 4) + 6] = RGBGetRValue(color_data[zone_idx]);
usb_buf[(zone_idx * 4) + 7] = RGBGetGValue(color_data[zone_idx]);
usb_buf[(zone_idx * 4) + 8] = RGBGetBValue(color_data[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, 65);
hid_write(dev, (unsigned char *)usb_buf, 64);
}
void CorsairPeripheralController::SubmitMousematColors
@@ -784,7 +517,7 @@ void CorsairPeripheralController::SubmitMousematColors
RGBColor * color_data
)
{
char usb_buf[65];
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -794,25 +527,24 @@ void CorsairPeripheralController::SubmitMousematColors
/*-----------------------------------------------------*\
| Set up Submit Mouse Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
usb_buf[0x03] = num_zones;
usb_buf[0x04] = 0x00;
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) + 5] = RGBGetRValue(color_data[zone_idx]);
usb_buf[(zone_idx * 3) + 6] = RGBGetGValue(color_data[zone_idx]);
usb_buf[(zone_idx * 3) + 7] = RGBGetBValue(color_data[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 |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
send_usb_msg(dev, usb_buf);
}
@@ -30,7 +30,6 @@ enum
CORSAIR_PROPERTY_LIGHTING_CONTROL = 0x05,
CORSAIR_PROPERTY_HARDWARE_PROFILE = 0x13,
CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR = 0x22,
CORSAIR_PROPERTY_SUBMIT_KBZONES_COLOR_24 = 0x25,
CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_9 = 0x27,
CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_24 = 0x28,
};
@@ -48,56 +47,28 @@ enum
CORSAIR_COLOR_CHANNEL_BLUE = 0x03
};
enum
{
CORSAIR_LAYOUT_ANSI = 0x00,
CORSAIR_LAYOUT_ISO = 0x01,
CORSAIR_LAYOUT_ABNT = 0x02,
CORSAIR_LAYOUT_JIS = 0x03,
CORSAIR_LAYOUT_DUBEOLSIK = 0x04
};
enum
{
CORSAIR_TYPE_NORMAL = 0,
CORSAIR_TYPE_K95_PLAT = 1,
CORSAIR_TYPE_K95 = 2,
CORSAIR_TYPE_K55 = 3
};
class CorsairPeripheralController
{
public:
CorsairPeripheralController(hid_device* dev_handle, const char* path);
CorsairPeripheralController(hid_device* dev_handle);
~CorsairPeripheralController();
int GetLogicalLayout();
int GetPhysicalLayout();
device_type GetDeviceType();
std::string GetDeviceLocation();
std::string GetFirmwareString();
std::string GetName();
std::string GetSerialString();
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);
void SetName(std::string device_name);
private:
hid_device* dev;
std::string firmware_version;
std::string location;
std::string name;
device_type type;
int physical_layout; //ANSI, ISO, etc.
int logical_layout; //Normal, K95 or K95 Platinum
void LightingControl();
void SetupK55AndK95LightingControl();
void SpecialFunctionControl();
void ReadFirmwareInfo();
@@ -116,14 +87,6 @@ private:
unsigned char finish_val
);
void SubmitKeyboardZonesColors
(
RGBColor left,
RGBColor mid,
RGBColor right
);
void SubmitKeyboardLimitedColors
(
unsigned char byte_count

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