Move tests in a separate module
authorGreg Burri <greg.burri@gmail.com>
Tue, 19 Sep 2023 23:36:11 +0000 (01:36 +0200)
committerGreg Burri <greg.burri@gmail.com>
Tue, 19 Sep 2023 23:36:11 +0000 (01:36 +0200)
Tweak the Asus aura USB RGB module

Cargo.toml
TODO.md
src/AsusAuraUSB.rs [new file with mode: 0644]
src/b650_e.rs [deleted file]
src/machine.rs
src/main.rs
src/tests.rs [new file with mode: 0644]

index 59c3461..ee00d9c 100644 (file)
@@ -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 (file)
--- 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 (file)
index 0000000..74face1
--- /dev/null
@@ -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 (file)
index b571675..0000000
+++ /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);
-}
index 2c64735..d1ff5c4 100644 (file)
@@ -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<corsair_vengeance::Controller>,
-    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 {
index 29a9343..a819b71 100644 (file)
@@ -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<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()?;
@@ -237,126 +234,3 @@ fn run_service(_arguments: Vec<OsString>) -> 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<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());
-}
diff --git a/src/tests.rs b/src/tests.rs
new file mode 100644 (file)
index 0000000..08e6bd0
--- /dev/null
@@ -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<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());
+}