From d7ff8803c1b3fa3a2ad2d6ed61e3fc232d1258de Mon Sep 17 00:00:00 2001 From: Greg Burri Date: Wed, 20 Sep 2023 01:36:11 +0200 Subject: [PATCH] Move tests in a separate module Tweak the Asus aura USB RGB module --- Cargo.toml | 3 + TODO.md | 12 +++- src/AsusAuraUSB.rs | 139 +++++++++++++++++++++++++++++++++++++++++++++ src/b650_e.rs | 97 ------------------------------- src/machine.rs | 10 ++-- src/main.rs | 132 +----------------------------------------- src/tests.rs | 130 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 291 insertions(+), 232 deletions(-) create mode 100644 src/AsusAuraUSB.rs delete mode 100644 src/b650_e.rs create mode 100644 src/tests.rs diff --git a/Cargo.toml b/Cargo.toml index 59c3461..ee00d9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,10 @@ log = "0.4" 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" diff --git a/TODO.md b/TODO.md index 004ff8e..9c79855 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,15 @@ -* 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 diff --git a/src/AsusAuraUSB.rs b/src/AsusAuraUSB.rs new file mode 100644 index 0000000..74face1 --- /dev/null +++ b/src/AsusAuraUSB.rs @@ -0,0 +1,139 @@ +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); + } +} diff --git a/src/b650_e.rs b/src/b650_e.rs deleted file mode 100644 index b571675..0000000 --- a/src/b650_e.rs +++ /dev/null @@ -1,97 +0,0 @@ -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); -} diff --git a/src/machine.rs b/src/machine.rs index 2c64735..d1ff5c4 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -1,4 +1,4 @@ -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); @@ -8,7 +8,7 @@ pub trait Machine { pub struct MachineJiji { ram: Vec, - b650e_device: hidapi::HidDevice, + b650e_device: AsusAuraUSB::Device, a770: a770::A770, sensors: sensors_jiji::Sensors, } @@ -21,11 +21,11 @@ impl MachineJiji { 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 } } @@ -35,7 +35,7 @@ impl Machine for MachineJiji { 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 { diff --git a/src/main.rs b/src/main.rs index 29a9343..a819b71 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,6 @@ extern crate windows_service; use std::{ - collections::HashMap, env, ffi::OsString, sync::{ @@ -25,9 +24,6 @@ use windows_service::{ service_dispatcher, service_manager::{ServiceManager, ServiceManagerAccess}, }; -use wmi::{COMLibrary, Variant, WMIConnection}; - -use crate::rgb::RGB; define_windows_service!(ffi_service_main, service_main); @@ -41,8 +37,8 @@ mod intel_arc { include!(concat!(env!("OUT_DIR"), "/intel_arc.rs")); } +mod AsusAuraUSB; mod a770; -mod b650_e; mod machine; mod main_loop; // mod common; @@ -53,6 +49,7 @@ mod rgb; // mod roccat; Disabled. mod sensors_jiji; mod settings; +mod tests; mod timer; fn main() -> Result<()> { @@ -86,7 +83,7 @@ fn main() -> Result<()> { let completed: Arc = 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()?; @@ -237,126 +234,3 @@ fn run_service(_arguments: Vec) -> Result<(), windows_service::Error> 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> = wmi_con.raw_query("SELECT * FROM Win32_PnPSignedDriver WHERE Description LIKE '%SMBUS%' OR Description LIKE '%SM BUS%'").unwrap(); - //let results: Vec> = wmi_con.raw_query("SELECT * FROM Win32_PnPSignedDriver WHERE Description LIKE 'Intel(R) NF I2C Host Controller'").unwrap(); - let results: Vec> = wmi_con - .raw_query("SELECT * FROM Win32_PnPSignedDriver") - .unwrap(); - //let results: Vec> = 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()); -} diff --git a/src/tests.rs b/src/tests.rs new file mode 100644 index 0000000..08e6bd0 --- /dev/null +++ b/src/tests.rs @@ -0,0 +1,130 @@ +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> = wmi_con.raw_query("SELECT * FROM Win32_PnPSignedDriver WHERE Description LIKE '%SMBUS%' OR Description LIKE '%SM BUS%'").unwrap(); + //let results: Vec> = wmi_con.raw_query("SELECT * FROM Win32_PnPSignedDriver WHERE Description LIKE 'Intel(R) NF I2C Host Controller'").unwrap(); + let results: Vec> = wmi_con + .raw_query("SELECT * FROM Win32_PnPSignedDriver") + .unwrap(); + //let results: Vec> = 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()); +} -- 2.45.1