windows-service = "0.6"
+# HIDAPI is a library which allows an application to interface with
+# USB and Bluetooth HID-Class devices.
hidapi = "2.4"
+
libc = "0.2"
wmi = "0.13"
crc = "3.0"
-* Add the support for A770 RGB
+* Mother board: [ASUS ROG CROSSHAIR VIII HERO] Registering RGB controller
+* Corsair: [Corsair Lighting Node Pro] Registering RGB controller
+* RTX 3080:
+ 6319 |Info: Registering I2C interface: Nuvoton NCT6798D SMBus at 200 Device 0000:0000 Subsystem: 0000:0000
+ 6325 |Info: Registering I2C interface: NVidia NvAPI I2C on GPU 0 Device 10DE:2208 Subsystem: 1458:4087
+ 7280 |Info: Registering I2C interface: AMD SMBus at 0x0B00 Device 1022:790B Subsystem: 1043:87C0
+ 7280 |Info: Registering I2C interface: AMD SMBus at 0x0B20 Device 1022:790B Subsystem: 1043:87C0
+
+
+
+[ok] Add the support for A770 RGB
[ok] Add parameters "--install-service" and "--uninstall-service", see: https://github.com/mullvad/windows-service-rs/blob/main/examples/install_service.rs
[ok] Add a parameter (using clap) "--no-service" to run it without the service system
[ok] Create the service and test it
--- /dev/null
+use std::str;
+
+use crate::rgb::RGB;
+
+/*
+ * Doc:
+ * - https://blog.inlart.com/post/openrgb-asus-x570/
+ * - https://openrgb-wiki.readthedocs.io/en/latest/asus/ASUS-Aura-USB/
+ */
+
+const AURA_REQUEST_FIRMWARE_VERSION: u8 = 0x82;
+const AURA_REQUEST_CONFIG_TABLE: u8 = 0xB0;
+
+const VID: u16 = 0x0B05; // Vendor ID: ASUS.
+
+const PID_650_E: u16 = 0x19AF; // Product ID: AURA LED Controller.
+const PID_CROSSHAIR: u16 = 0x18F3; // Product ID: AURA LED Controller.
+
+pub enum Motherboard {
+ Asus650e,
+ AsusCrosshairVIIIHero,
+}
+
+pub struct Device {
+ device: hidapi::HidDevice,
+ motherboard: Motherboard,
+}
+
+impl Device {
+ pub fn new(api: &hidapi::HidApi, motherboard: Motherboard) -> Self {
+ Device {
+ device: api
+ .open(
+ VID,
+ match motherboard {
+ Motherboard::Asus650e => PID_650_E,
+ Motherboard::AsusCrosshairVIIIHero => PID_CROSSHAIR,
+ },
+ )
+ .unwrap(),
+ motherboard,
+ }
+ }
+
+ pub fn get_firmware_string(&self) -> String {
+ let mut buffer = [0u8; 65];
+ buffer[0] = 0xEC;
+ buffer[1] = AURA_REQUEST_FIRMWARE_VERSION;
+ let n_write = self.device.write(&buffer).unwrap();
+ assert_eq!(n_write, 65);
+
+ buffer.fill(0);
+ let n_read = self.device.read(&mut buffer).unwrap();
+ assert_eq!(n_read, 65);
+ assert_eq!(buffer[0], 0xEC);
+ assert_eq!(buffer[1], 0x02);
+
+ String::from(str::from_utf8(&buffer[2..17]).unwrap())
+ }
+
+ /*
+ Example of configuration table:
+ - Positions 0 and 1 always 1E and 9F.
+ - Value 02 is the number of adressable channels.
+ 1E 9F 02 01 00 00
+ 78 3C 00 01 00 00
+ 78 3C 00 00 00 00
+ 00 00 00 00 00 00
+ 00 00 00 08 0A 02
+ 01 F4 00 00 00 00
+ 00 00 00 00 00 00
+ 00 00 00 00 00 00
+ 00 00 00 00 00 00
+ 00 00 00 00 00 00
+ */
+ pub fn get_configuration_table(&self) -> [u8; 60] {
+ let mut buffer = [0u8; 65];
+ buffer[0] = 0xEC;
+ buffer[1] = AURA_REQUEST_CONFIG_TABLE;
+ let n_write = self.device.write(&buffer).unwrap();
+ assert_eq!(n_write, 65);
+
+ buffer.fill(0);
+ let n_read = self.device.read(&mut buffer).unwrap();
+ assert_eq!(n_read, 65);
+ assert_eq!(buffer[0], 0xEC);
+ assert_eq!(buffer[1], 0x30);
+
+ buffer[4..64]
+ .try_into()
+ .expect("slice with incorrect length")
+ }
+
+ pub fn set_fixed_mode(&self) {
+ let mut buffer = [0u8; 65];
+ buffer[0] = 0xEC;
+ buffer[1] = 0x35; // Control mode.
+ buffer[4] = 0x00; // Shutdown effect.
+ buffer[5] = 0x01; // Mode id: static.
+
+ for channel_effect_id in 0..2 {
+ buffer[2] = channel_effect_id; // Channel effect id: Fixed.
+ let n_write = self.device.write(&buffer).unwrap();
+ assert_eq!(n_write, 65);
+ }
+ }
+
+ pub fn set_color(&self, color: &RGB) {
+ let mut buffer = [0u8; 65];
+ buffer[0] = 0xEC;
+ buffer[1] = 0x36;
+
+ let start_led = 0u32;
+ let nb_of_leds = 16u32;
+ let mask = ((1u32 << nb_of_leds) - 1u32) << start_led;
+
+ buffer[2] = (mask >> 8) as u8; // 16 bits LED mask: first part.
+ buffer[3] = (mask & 0xFF) as u8; // 16 bits LED mask: second part.
+
+ for n in start_led as usize..(start_led + nb_of_leds) as usize {
+ buffer[5 + 3 * n] = color.red;
+ buffer[5 + 3 * n + 1] = color.green;
+ buffer[5 + 3 * n + 2] = color.blue;
+ }
+
+ let n_write = self.device.write(&buffer).unwrap();
+ assert_eq!(n_write, 65);
+ }
+
+ pub fn save_current_color(&self) {
+ let mut buffer = [0u8; 65];
+ buffer[0] = 0xEC;
+ buffer[1] = 0x3F;
+ buffer[2] = 0x55;
+
+ let n_write = self.device.write(&buffer).unwrap();
+ assert_eq!(n_write, 65);
+ }
+}
+++ /dev/null
-use std::str;
-
-use crate::rgb::RGB;
-
-/*
- * Doc:
- * - https://blog.inlart.com/post/openrgb-asus-x570/
- * - https://openrgb-wiki.readthedocs.io/en/latest/asus/ASUS-Aura-USB/
- */
-
-const AURA_REQUEST_FIRMWARE_VERSION: u8 = 0x82;
-const AURA_REQUEST_CONFIG_TABLE: u8 = 0xB0;
-
-const VID: u16 = 0x0B05; // Vendor ID: ASUS.
-const PID: u16 = 0x19AF; // Product ID: AURA LED Controller.
-
-pub fn get_device(api: &hidapi::HidApi) -> hidapi::HidDevice {
- api.open(VID, PID).unwrap()
-}
-
-pub fn get_firmware_string(device: &hidapi::HidDevice) -> String {
- let mut buffer = [0u8; 65];
- buffer[0] = 0xEC;
- buffer[1] = AURA_REQUEST_FIRMWARE_VERSION;
- let n_write = device.write(&buffer).unwrap();
- assert_eq!(n_write, 65);
-
- buffer.fill(0);
- let n_read = device.read(&mut buffer).unwrap();
- assert_eq!(n_read, 65);
- assert_eq!(buffer[0], 0xEC);
- assert_eq!(buffer[1], 0x02);
-
- String::from(str::from_utf8(&buffer[2..17]).unwrap())
-}
-
-pub fn get_configuration_table(device: &hidapi::HidDevice) -> [u8; 60] {
- let mut buffer = [0u8; 65];
- buffer[0] = 0xEC;
- buffer[1] = AURA_REQUEST_CONFIG_TABLE;
- let n_write = device.write(&buffer).unwrap();
- assert_eq!(n_write, 65);
-
- buffer.fill(0);
- let n_read = device.read(&mut buffer).unwrap();
- assert_eq!(n_read, 65);
- assert_eq!(buffer[0], 0xEC);
- assert_eq!(buffer[1], 0x30);
-
- buffer[4..64]
- .try_into()
- .expect("slice with incorrect length")
-}
-
-// TODO: it seems this doesn't work.
-// The mode is set by OpenRGB prior launching temp2RGB for the moment.
-pub fn set_fixed_mode(device: &hidapi::HidDevice) {
- let mut buffer = [0u8; 65];
- buffer[0] = 0xEC;
- buffer[1] = 0x35;
- buffer[2] = 0x00; // Channel effect id = Fixed.
- buffer[5] = 0x01; // Mode id = static.
-
- let n_write = device.write(&buffer).unwrap();
- assert_eq!(n_write, 65);
-}
-
-pub fn set_color(device: &hidapi::HidDevice, color: &RGB) {
- let mut buffer = [0u8; 65];
- buffer[0] = 0xEC;
- buffer[1] = 0x36;
- buffer[2] = 0x00; // 16 bits LED mask: first part.
- buffer[3] = 0x02; // 16 bits LED mask: second part.
-
- // Don't know why the first LED isn't used.
- // buffer[5] = color.red;
- // buffer[6] = color.green;
- // buffer[7] = color.blue;
-
- // // Set second LED.
- buffer[8] = color.red;
- buffer[9] = color.green;
- buffer[10] = color.blue;
-
- let n_write = device.write(&buffer).unwrap();
- assert_eq!(n_write, 65);
-}
-
-pub fn save_current_color(device: &hidapi::HidDevice) {
- let mut buffer = [0u8; 65];
- buffer[0] = 0xEC;
- buffer[1] = 0x3F;
- buffer[2] = 0x55;
-
- let n_write = device.write(&buffer).unwrap();
- assert_eq!(n_write, 65);
-}
-use crate::{a770, b650_e, corsair_vengeance, rgb, sensors_jiji, winring0};
+use crate::{a770, corsair_vengeance, rgb, sensors_jiji, winring0, AsusAuraUSB};
pub trait Machine {
fn set_color(&mut self, color: &rgb::RGB);
pub struct MachineJiji {
ram: Vec<corsair_vengeance::Controller>,
- b650e_device: hidapi::HidDevice,
+ b650e_device: AsusAuraUSB::Device,
a770: a770::A770,
sensors: sensors_jiji::Sensors,
}
corsair_vengeance::Controller::new(0x19),
corsair_vengeance::Controller::new(0x1B),
],
- b650e_device: b650_e::get_device(&api),
+ b650e_device: AsusAuraUSB::Device::new(&api, AsusAuraUSB::Motherboard::Asus650e),
a770: a770::A770::new(),
sensors: sensors_jiji::Sensors::new(),
};
- b650_e::set_fixed_mode(&machine.b650e_device);
+ machine.b650e_device.set_fixed_mode();
machine
}
}
for controller in &self.ram {
controller.set_color(&color);
}
- b650_e::set_color(&self.b650e_device, &color);
+ self.b650e_device.set_color(&color);
self.a770.set_color(color.red, color.green, color.blue);
}
fn get_gpu_tmp(&self) -> f32 {
extern crate windows_service;
use std::{
- collections::HashMap,
env,
ffi::OsString,
sync::{
service_dispatcher,
service_manager::{ServiceManager, ServiceManagerAccess},
};
-use wmi::{COMLibrary, Variant, WMIConnection};
-
-use crate::rgb::RGB;
define_windows_service!(ffi_service_main, service_main);
include!(concat!(env!("OUT_DIR"), "/intel_arc.rs"));
}
+mod AsusAuraUSB;
mod a770;
-mod b650_e;
mod machine;
mod main_loop;
// mod common;
// mod roccat; Disabled.
mod sensors_jiji;
mod settings;
+mod tests;
mod timer;
fn main() -> Result<()> {
let completed: Arc<AtomicBool> = Arc::new(AtomicBool::new(false));
main_loop::main_loop(completed.clone());
} else if args.contains(&"--tests".to_string()) {
- tests();
+ tests::tests();
} else if args.contains(&"--install-service".to_string()) {
println!("Installing service...");
install_service()?;
Ok(())
}
-
-fn tests() {
- println!("Running some tests...");
-
- // test_b650_e();
- // list_usb_devices();
- // test_roccat();
- // test_wmi();
- // test_corsair();
- test_a770();
- // test_read_temp();
-
- println!("Press any key to continue...");
- std::io::stdin().read_line(&mut String::new()).unwrap();
-}
-
-fn test_wmi() {
- let com_con = COMLibrary::new().unwrap();
- let wmi_con = WMIConnection::new(com_con.into()).unwrap();
-
- //let results: Vec<HashMap<String, Variant>> = wmi_con.raw_query("SELECT * FROM Win32_PnPSignedDriver WHERE Description LIKE '%SMBUS%' OR Description LIKE '%SM BUS%'").unwrap();
- //let results: Vec<HashMap<String, Variant>> = wmi_con.raw_query("SELECT * FROM Win32_PnPSignedDriver WHERE Description LIKE 'Intel(R) NF I2C Host Controller'").unwrap();
- let results: Vec<HashMap<String, Variant>> = wmi_con
- .raw_query("SELECT * FROM Win32_PnPSignedDriver")
- .unwrap();
- //let results: Vec<HashMap<String, Variant>> = wmi_con.raw_query("SELECT * FROM Win32_PnPAllocatedResource").unwrap();
-
- for os in results {
- println!("-------------------");
- println!("{:#?}", os);
- }
-}
-fn list_usb_devices() {
- let api = hidapi::HidApi::new().unwrap();
- for device in api.device_list() {
- println!("{:?}", device);
- println!("name: {}", device.product_string().unwrap());
- println!("interface number: {}", device.interface_number());
- println!("page: {}", device.usage_page());
- println!("usage: {}", device.usage());
- println!("----");
- }
-}
-
-// fn test_roccat() {
-// let api = hidapi::HidApi::new().unwrap();
-// let roccat_device = roccat::get_device(&api);
-
-// let manufacturer = roccat_device.get_manufacturer_string().unwrap();
-// dbg!(manufacturer);
-
-// let product = roccat_device.get_product_string().unwrap();
-// dbg!(product);
-
-// let serial = roccat_device.get_serial_number_string().unwrap();
-// dbg!(serial);
-
-// roccat::init(&roccat_device);
-// roccat::set_color(
-// &roccat_device,
-// &RGB {
-// red: 0,
-// green: 255,
-// blue: 40,
-// },
-// );
-// }
-
-fn test_b650_e() {
- let api = hidapi::HidApi::new().unwrap();
-
- let b650e_device = b650_e::get_device(&api);
-
- println!("Firmware: {}", b650_e::get_firmware_string(&b650e_device));
-
- let configuration = b650_e::get_configuration_table(&b650e_device);
- println!("Configuration:");
- for i in 0..60 {
- print!("{:02X} ", configuration[i]);
- if (i + 1) % 6 == 0 {
- println!("");
- }
- }
-
- // Only once, at start.
- b650_e::set_fixed_mode(&b650e_device);
-
- b650_e::set_color(
- &b650e_device,
- &RGB {
- red: 255,
- green: 0,
- blue: 0,
- },
- );
- b650_e::save_current_color(&b650e_device);
-}
-
-fn test_corsair() {
- let corsair_controllers = [
- corsair_vengeance::Controller::new(0x19),
- corsair_vengeance::Controller::new(0x1B),
- ];
- for controller in corsair_controllers {
- controller.set_color(&RGB {
- red: 255,
- green: 0,
- blue: 0,
- });
- }
-}
-
-fn test_a770() {
- // a770::set_rgb(255, 0, 0);
- let mut a770 = a770::A770::new();
- a770.set_color(255, 0, 0);
-}
-
-fn test_read_temp() {
- let sensors = sensors_jiji::Sensors::new();
- println!("temp cpu: {}", sensors.read_cpu_temp());
- println!("temp gpu: {}", sensors.read_gpu_temp());
-}
--- /dev/null
+use std::collections::HashMap;
+
+use wmi::{COMLibrary, Variant, WMIConnection};
+
+use crate::{a770, corsair_vengeance, rgb::RGB, sensors_jiji, AsusAuraUSB};
+
+pub fn tests() {
+ println!("Running some tests...");
+
+ test_asus_aura_usb(AsusAuraUSB::Motherboard::AsusCrosshairVIIIHero);
+ // list_usb_devices();
+ // test_roccat();
+ // test_wmi();
+ // test_corsair();
+ // test_a770();
+ // test_read_temp();
+
+ println!("Press any key to continue...");
+ std::io::stdin().read_line(&mut String::new()).unwrap();
+}
+
+fn test_wmi() {
+ let com_con = COMLibrary::new().unwrap();
+ let wmi_con = WMIConnection::new(com_con.into()).unwrap();
+
+ //let results: Vec<HashMap<String, Variant>> = wmi_con.raw_query("SELECT * FROM Win32_PnPSignedDriver WHERE Description LIKE '%SMBUS%' OR Description LIKE '%SM BUS%'").unwrap();
+ //let results: Vec<HashMap<String, Variant>> = wmi_con.raw_query("SELECT * FROM Win32_PnPSignedDriver WHERE Description LIKE 'Intel(R) NF I2C Host Controller'").unwrap();
+ let results: Vec<HashMap<String, Variant>> = wmi_con
+ .raw_query("SELECT * FROM Win32_PnPSignedDriver")
+ .unwrap();
+ //let results: Vec<HashMap<String, Variant>> = wmi_con.raw_query("SELECT * FROM Win32_PnPAllocatedResource").unwrap();
+
+ for os in results {
+ println!("-------------------");
+ println!("{:#?}", os);
+ }
+}
+
+fn list_usb_devices() {
+ let api = hidapi::HidApi::new().unwrap();
+ for device in api.device_list() {
+ println!("{:?}", device);
+ println!("name: {}", device.product_string().unwrap());
+ println!("interface number: {}", device.interface_number());
+ println!("page: {}", device.usage_page());
+ println!("usage: {}", device.usage());
+ println!("----");
+ }
+}
+
+// fn test_roccat() {
+// let api = hidapi::HidApi::new().unwrap();
+// let roccat_device = roccat::get_device(&api);
+
+// let manufacturer = roccat_device.get_manufacturer_string().unwrap();
+// dbg!(manufacturer);
+
+// let product = roccat_device.get_product_string().unwrap();
+// dbg!(product);
+
+// let serial = roccat_device.get_serial_number_string().unwrap();
+// dbg!(serial);
+
+// roccat::init(&roccat_device);
+// roccat::set_color(
+// &roccat_device,
+// &RGB {
+// red: 0,
+// green: 255,
+// blue: 40,
+// },
+// );
+// }
+
+fn test_asus_aura_usb(motherboard: AsusAuraUSB::Motherboard) {
+ let api = hidapi::HidApi::new().unwrap();
+
+ let device = AsusAuraUSB::Device::new(&api, motherboard);
+
+ println!("Firmware: {}", device.get_firmware_string());
+
+ let configuration = device.get_configuration_table();
+ println!("Configuration:");
+ for i in 0..60 {
+ print!("{:02X} ", configuration[i]);
+ if (i + 1) % 6 == 0 {
+ println!("");
+ }
+ }
+ println!("Number of addressable header: {}", configuration[0x02]);
+ println!("Number of leds: {}", configuration[0x1B]);
+ println!("Number of RGB headers: {}", configuration[0x1D]);
+
+ // Only once, at start.
+ device.set_fixed_mode();
+
+ device.set_color(&RGB {
+ red: 0,
+ green: 0,
+ blue: 255,
+ });
+
+ device.save_current_color();
+}
+
+fn test_corsair() {
+ let corsair_controllers = [
+ corsair_vengeance::Controller::new(0x19),
+ corsair_vengeance::Controller::new(0x1B),
+ ];
+ for controller in corsair_controllers {
+ controller.set_color(&RGB {
+ red: 0,
+ green: 0,
+ blue: 255,
+ });
+ }
+}
+
+fn test_a770() {
+ // a770::set_rgb(255, 0, 0);
+ let mut a770 = a770::A770::new();
+ a770.set_color(255, 0, 0);
+}
+
+fn test_read_temp() {
+ let sensors = sensors_jiji::Sensors::new();
+ println!("temp cpu: {}", sensors.read_cpu_temp());
+ println!("temp gpu: {}", sensors.read_gpu_temp());
+}