From 1598e623c8de3c6fb3fe81bc8d402fc3d9c7080c Mon Sep 17 00:00:00 2001 From: Greg Burri Date: Mon, 17 Feb 2025 17:56:09 +0100 Subject: [PATCH] Split machine module in sub modules. Add gigabyte_rgb_fusion module --- Cargo.toml | 11 +- src/gigabyte_rgb_fusion_usb.rs | 206 ++++++++++++++++++++++ src/lian_li_sl_infinity.rs | 6 +- src/machine/jiji.rs | 57 ++++++ src/{machine.rs => machine/lyss_metal.rs} | 91 ++-------- src/machine/lyss_metal2.rs | 114 ++++++++++++ src/machine/mod.rs | 21 +++ src/main.rs | 3 +- src/main_loop.rs | 15 +- src/piix4_i2c.rs | 15 +- src/settings.rs | 1 + src/tests.rs | 21 ++- 12 files changed, 453 insertions(+), 108 deletions(-) create mode 100644 src/gigabyte_rgb_fusion_usb.rs create mode 100644 src/machine/jiji.rs rename src/{machine.rs => machine/lyss_metal.rs} (54%) create mode 100644 src/machine/lyss_metal2.rs create mode 100644 src/machine/mod.rs diff --git a/Cargo.toml b/Cargo.toml index 82d89af..ce95993 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,11 +10,12 @@ edition = "2021" [dependencies] serde = { version = "1.0", features = ["derive"] } -ron = "0.8" # Rust object notation, to load configuration files. +# Rust object notation, to load configuration files. +ron = "0.8" num = "0.4" -dirs = "5.0" +dirs = "6.0" anyhow = "1.0" flexi_logger = "0.29" @@ -31,14 +32,14 @@ hidapi = "2.6" nvapi = "0.1" libc = "0.2" -wmi = "0.13" +wmi = "0.15" crc = "3.2" # libloading = "0.8" # netcorehost = "0.15" [dependencies.windows] -version = "0.58" +version = "0.59" features = [ "Win32_Foundation", "Win32_Security", @@ -54,7 +55,7 @@ features = [ ] [build-dependencies] -bindgen = "0.70" +bindgen = "0.71" [profile.release] # strip = "debuginfo" diff --git a/src/gigabyte_rgb_fusion_usb.rs b/src/gigabyte_rgb_fusion_usb.rs new file mode 100644 index 0000000..c9667be --- /dev/null +++ b/src/gigabyte_rgb_fusion_usb.rs @@ -0,0 +1,206 @@ +use std::{str, time::Duration}; + +use crate::rgb::RGB; + +const VID: u16 = 0x048D; // Vendor ID: Gigabyte. +const PID: u16 = 0x5711; // Product ID. + +/* +HidDeviceInfo { vendor_id: 1165, product_id: 22289 } +name: GIGABYTE Device +interface number: 1 +page: 65417 +usage: 204 +*/ + +pub struct Device { + device: hidapi::HidDevice, +} + +impl Device { + pub fn new(api: &hidapi::HidApi) -> anyhow::Result { + let d = api + .device_list() + .find(|d| d.vendor_id() == VID && d.product_id() == PID && d.usage() == 204) + .unwrap() + .open_device(api) + .unwrap(); + + let device = Device { device: d }; + + // Initialization? + let mut buffer = [0u8; 64]; + buffer[0] = 0xCC; + buffer[1] = 0x60; + device.device.send_feature_report(&buffer)?; + + Ok(device) + } + + pub fn test_raw_data(&self) -> anyhow::Result<()> { + loop { + self.send_str( + " +// cc20010000000000 000000015a00b727 610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +cc22040000000000 000000015a00b727 610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc23080000000000 000000015a00b727 610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc24100000000000 000000015a006127 b70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc25200000000000 000000015a00b727 610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc26400000000000 000000015a00b727 610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc27800000000000 000000015a00b727 610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc91000200000000 000000015a00b727 610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc92000400000000 000000015a00b727 610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc34110100000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + +cc580000392761b7 2761b72761b72761 b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b70000 +// cc583900392761b7 2761b72761b72761 b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b70000 +// cc587200392761b7 2761b72761b72761 b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b70000 +// cc58ab00092761b7 2761b72761b70000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + +// Arctic freezer 3 +cc620000392761b7 2761b72761b72761 b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b70000 +cc623900392761b7 2761b72761b72761 b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b70000 +// cc627200392761b7 2761b72761b72761 b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b72761b70000 +// cc62ab00092761b7 2761b72761b70000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")?; + std::thread::sleep(Duration::from_secs(1)); + self.send_str( + " +// cc20010000000000 000000015a0043ab 350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +cc22040000000000 000000015a0043ab 350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc23080000000000 000000015a0043ab 350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc24100000000000 000000015a0035ab 430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc25200000000000 000000015a0043ab 350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc26400000000000 000000015a0043ab 350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc27800000000000 000000015a0043ab 350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc91000200000000 000000015a0043ab 350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc92000400000000 000000015a0043ab 350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc28ff0700000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// cc34110100000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + +cc58000039ab4543 ab4543ab4543ab45 43ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab45430000 +// cc58390039ab4543 ab4543ab4543ab45 43ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab45430000 +// cc58720039ab4543 ab4543ab4543ab45 43ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab45430000 +// cc58ab0009ab4543 ab4543ab45430000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + +// Arctic freezer 3 +cc62000039 ab4543 ab4543 ab4543 ab4543 ab4543 ab4543 ab4543 ab4543 ab4543 ab4543 ab4543 ab4543 ab4543 ab4543 ab4543 ab4543 ab4543 ab4543 ab4543 0000 +cc62390039ab4543 ab4543ab4543ab45 43ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab45430000 +// cc62720039ab4543 ab4543ab4543ab45 43ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab4543ab45430000 +// cc62ab0009ab4543 ab4543ab45430000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +")?; + std::thread::sleep(Duration::from_secs(1)); + } + } + + fn line_to_bytes(line: &str) -> Vec { + let line = line.replace(" ", ""); + let mut buffer = vec![0u8; line.len() / 2]; + for i in 0..buffer.len() { + buffer[i] = u8::from_str_radix(&line[2 * i..2 * i + 2], 16).unwrap(); + } + + println!("buffer: {:?}", buffer); + buffer + } + + fn send_str(&self, buffer: &str) -> anyhow::Result<()> { + println!("------"); + for line in buffer.lines() { + let line = line.trim(); + if line.is_empty() || line.starts_with("//") { + continue; + } + + let buffer = Self::line_to_bytes(line); + self.device.send_feature_report(&buffer)?; + } + Ok(()) + } + + const NB_LEDS_PER_PACKET: usize = 19; + + fn set_color_device(&self, color: &RGB, device: u8, nb_leds: usize) -> anyhow::Result<()> { + let nb_packets = (nb_leds - 1) / Self::NB_LEDS_PER_PACKET + 1; + for i in 0..nb_packets { + let mut buffer = [0u8; 64]; + let nb_leds_in_packet = if i == nb_packets - 1 && nb_leds % Self::NB_LEDS_PER_PACKET > 0 + { + nb_leds % Self::NB_LEDS_PER_PACKET + } else { + Self::NB_LEDS_PER_PACKET + }; + + buffer[0] = 0xCC; + buffer[1] = device; + buffer[2] = (i * Self::NB_LEDS_PER_PACKET) as u8 * 3; + buffer[4] = nb_leds_in_packet as u8 * 3; + + for j in 0..nb_leds_in_packet { + buffer[5 + 3 * j] = color.green; + buffer[5 + 3 * j + 1] = color.red; + buffer[5 + 3 * j + 2] = color.blue; + } + + // println!("BUFFER: {:?}", buffer); // Debug. + self.device.send_feature_report(&buffer)?; + } + + Ok(()) + } + + fn set_color_motherboard(&self, color: &RGB) -> anyhow::Result<()> { + { + let mut buffer = [0u8; 64]; + buffer[0] = 0xCC; + buffer[1] = 0x22; + buffer[2] = 0x04; + + buffer[11] = 0x01; + buffer[12] = 0x5a; + + buffer[14] = color.blue; + buffer[15] = color.green; + buffer[16] = color.red; + + self.device.send_feature_report(&buffer)?; + } + { + let mut buffer = [0u8; 64]; + buffer[0] = 0xCC; + buffer[1] = 0x28; + buffer[2] = 0xFF; + buffer[3] = 0x07; + + self.device.send_feature_report(&buffer)?; + } + + Ok(()) + } + + pub fn set_color(&self, color: &RGB) { + // Motherboard & GPU power cables. + self.set_color_device(color, 0x58, 19).unwrap(); + + // Arctic freezer 3. + self.set_color_device(color, 0x62, 38).unwrap(); + + self.set_color_motherboard(color).unwrap(); + } +} diff --git a/src/lian_li_sl_infinity.rs b/src/lian_li_sl_infinity.rs index d16a4a3..cd3e149 100644 --- a/src/lian_li_sl_infinity.rs +++ b/src/lian_li_sl_infinity.rs @@ -25,11 +25,9 @@ pub struct Device { impl Device { pub fn new(api: &hidapi::HidApi) -> Self { - let device = Device { + Self { device: api.open(LIANLI_VID, LIANLI_UNI_HUB_SLINF_PID).unwrap(), - }; - - device + } } fn send_start_action(&self, channel_id: u8) { diff --git a/src/machine/jiji.rs b/src/machine/jiji.rs new file mode 100644 index 0000000..402d9a4 --- /dev/null +++ b/src/machine/jiji.rs @@ -0,0 +1,57 @@ +use crate::{asus_aura_usb, corsair_vengeance, cpu_temperature, rgb}; + +use super::Machine; + +pub struct MachineJiji { + ram: Vec, + b650e_device: asus_aura_usb::Device, + // a770: a770::A770, + // gpu_devices: intel_arc::Devices, + gpus: Vec, +} + +impl MachineJiji { + pub fn new() -> anyhow::Result { + let api = hidapi::HidApi::new().unwrap(); + Ok(MachineJiji { + ram: vec![ + corsair_vengeance::Controller::new(0x19), + corsair_vengeance::Controller::new(0x1B), + ], + b650e_device: asus_aura_usb::Device::new(&api, asus_aura_usb::Motherboard::Asus650e)?, + // a770: a770::A770::new()?, + // gpu_devices: unsafe { intel_arc::GetDevices() }, + gpus: nvapi::PhysicalGpu::enumerate()?, + }) + } +} + +impl Machine for MachineJiji { + fn set_color_1(&mut self, color: &rgb::RGB) { + for controller in &self.ram { + controller.set_color(color); + } + self.b650e_device.set_color(color).unwrap(); + } + + fn set_color_2(&mut self, color: &rgb::RGB) {} // No color 2. + + fn get_gpu_tmp(&self) -> f32 { + // unsafe { intel_arc::GetTemperature(self.gpu_devices, 0) as f32 } + self.gpus[0].thermal_settings(None).unwrap()[0] + .current_temperature + .0 as f32 + } + + fn get_cpu_tmp(&self) -> f32 { + cpu_temperature::read() + } +} + +// impl Drop for MachineJiji { +// fn drop(&mut self) { +// unsafe { +// intel_arc::FreeDevices(self.gpu_devices); +// } +// } +// } diff --git a/src/machine.rs b/src/machine/lyss_metal.rs similarity index 54% rename from src/machine.rs rename to src/machine/lyss_metal.rs index 1d7bb2e..ba4cc43 100644 --- a/src/machine.rs +++ b/src/machine/lyss_metal.rs @@ -1,80 +1,8 @@ -use log::error; use nvapi::sys::i2c; -use crate::{ - /*a770,*/ asus_aura_usb, corsair_lighting_pro, corsair_vengeance, cpu_temperature, - intel_arc, lian_li_sl_infinity, rgb, -}; +use crate::{asus_aura_usb, corsair_lighting_pro, cpu_temperature, lian_li_sl_infinity, rgb}; -const RGB_FUSION2_GPU_REG_COLOR: u8 = 0x40; -const RGB_FUSION2_GPU_REG_MODE: u8 = 0x88; - -const GIGABYTE_RTX3080TI_VISION_OC_ADDR: u8 = 0x63; - -pub trait Machine { - fn set_color(&mut self, color: &rgb::RGB) { - self.set_color_1(&color); - self.set_color_2(&color); - } - fn set_color_1(&mut self, color: &rgb::RGB); - fn set_color_2(&mut self, color: &rgb::RGB); - fn get_gpu_tmp(&self) -> f32; - fn get_cpu_tmp(&self) -> f32; -} - -pub struct MachineJiji { - ram: Vec, - b650e_device: asus_aura_usb::Device, - // a770: a770::A770, - // gpu_devices: intel_arc::Devices, - gpus: Vec, -} - -impl MachineJiji { - pub fn new() -> anyhow::Result { - let api = hidapi::HidApi::new().unwrap(); - Ok(MachineJiji { - ram: vec![ - corsair_vengeance::Controller::new(0x19), - corsair_vengeance::Controller::new(0x1B), - ], - b650e_device: asus_aura_usb::Device::new(&api, asus_aura_usb::Motherboard::Asus650e)?, - // a770: a770::A770::new()?, - // gpu_devices: unsafe { intel_arc::GetDevices() }, - gpus: nvapi::PhysicalGpu::enumerate()?, - }) - } -} - -impl Machine for MachineJiji { - fn set_color_1(&mut self, color: &rgb::RGB) { - for controller in &self.ram { - controller.set_color(&color); - } - self.b650e_device.set_color(&color).unwrap(); - } - - fn set_color_2(&mut self, color: &rgb::RGB) {} // No color 2. - - fn get_gpu_tmp(&self) -> f32 { - // unsafe { intel_arc::GetTemperature(self.gpu_devices, 0) as f32 } - self.gpus[0].thermal_settings(None).unwrap()[0] - .current_temperature - .0 as f32 - } - - fn get_cpu_tmp(&self) -> f32 { - cpu_temperature::read() - } -} - -// impl Drop for MachineJiji { -// fn drop(&mut self) { -// unsafe { -// intel_arc::FreeDevices(self.gpu_devices); -// } -// } -// } +use super::Machine; pub struct MachineLyssMetal { crosshair_device: asus_aura_usb::Device, @@ -89,7 +17,7 @@ impl MachineLyssMetal { nvapi::initialize().expect("Unable to initialize nvapi (Nvidia API)"); - let machine = MachineLyssMetal { + let machine = Self { crosshair_device: asus_aura_usb::Device::new( &api, asus_aura_usb::Motherboard::AsusCrosshairVIIIHero, @@ -117,6 +45,7 @@ impl MachineLyssMetal { // * Controllers\GigabyteRGBFusion2GPUController\GigabyteRGBFusion2GPUController.cpp // * i2c_smbus\i2c_smbus_nvapi.cpp // Implementation of nvapi-rs: https://github.com/arcnmx/nvapi-rs/blob/master/src/gpu.rs#L645 + // Reference API doc: https://docs.nvidia.com/gameworks/content/gameworkslibrary/coresdk/nvapi/structNV__I2C__INFO__V3.html pub fn test_i2c(&self) { // Test from 'GigabyteRGBFusion2GPUControllerDetect.cpp' let data = [0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; @@ -125,7 +54,7 @@ impl MachineLyssMetal { 0, Some(1), false, - GIGABYTE_RTX3080TI_VISION_OC_ADDR, + super::GIGABYTE_RTX3080TI_VISION_OC_ADDR, &[], &data, i2c::I2cSpeed::Default, @@ -135,7 +64,7 @@ impl MachineLyssMetal { fn set_mode_3080ti(&self) { let data = [ - RGB_FUSION2_GPU_REG_MODE, + super::RGB_FUSION2_GPU_REG_MODE, 0x01, // Mode (1: static). 0x00, // Speed. 0x63, // Brightness max. @@ -149,7 +78,7 @@ impl MachineLyssMetal { 0, Some(1), false, - GIGABYTE_RTX3080TI_VISION_OC_ADDR, + super::GIGABYTE_RTX3080TI_VISION_OC_ADDR, &[], &data, i2c::I2cSpeed::Default, @@ -165,13 +94,13 @@ impl MachineLyssMetal { impl Machine for MachineLyssMetal { fn set_color_1(&mut self, color: &rgb::RGB) { - self.crosshair_device.set_color(&color).unwrap(); - self.corsair_lignting_pro.set_color(&color); + self.crosshair_device.set_color(color).unwrap(); + self.corsair_lignting_pro.set_color(color); // self.set_color_3080ti(&color); // TODO. } fn set_color_2(&mut self, color: &rgb::RGB) { - self.lian_li_sl_infinity.set_color(&color); + self.lian_li_sl_infinity.set_color(color); } fn get_gpu_tmp(&self) -> f32 { diff --git a/src/machine/lyss_metal2.rs b/src/machine/lyss_metal2.rs new file mode 100644 index 0000000..f96d213 --- /dev/null +++ b/src/machine/lyss_metal2.rs @@ -0,0 +1,114 @@ +use nvapi::sys::i2c; + +use crate::{ + corsair_lighting_pro, cpu_temperature, gigabyte_rgb_fusion_usb, lian_li_sl_infinity, rgb, +}; + +use super::Machine; + +pub struct MachineLyssMetal2 { + fusion_device: gigabyte_rgb_fusion_usb::Device, + corsair_lignting_pro: corsair_lighting_pro::Device, + lian_li_sl_infinity: lian_li_sl_infinity::Device, + gpus: Vec, +} + +impl MachineLyssMetal2 { + pub fn new() -> anyhow::Result { + let api = hidapi::HidApi::new()?; + + nvapi::initialize().expect("Unable to initialize nvapi (Nvidia API)"); + + let machine = Self { + fusion_device: gigabyte_rgb_fusion_usb::Device::new(&api)?, + corsair_lignting_pro: corsair_lighting_pro::Device::new( + &api, + &rgb::RGB { + red: 0, + green: 255, + blue: 40, + }, + ), + lian_li_sl_infinity: lian_li_sl_infinity::Device::new(&api), + gpus: nvapi::PhysicalGpu::enumerate()?, + }; + + // machine.set_mode_3080ti(); + Ok(machine) + } + + // Doesn't work: "Error: NotSupported". + // From OpenRGB, see the following files: + // * Controllers\GigabyteRGBFusion2GPUController\GigabyteRGBFusion2GPUControllerDetect.cpp + // * Controllers\GigabyteRGBFusion2GPUController\RGBController_GigabyteRGBFusion2GPU.cpp + // * Controllers\GigabyteRGBFusion2GPUController\GigabyteRGBFusion2GPUController.cpp + // * i2c_smbus\i2c_smbus_nvapi.cpp + // Implementation of nvapi-rs: https://github.com/arcnmx/nvapi-rs/blob/master/src/gpu.rs#L645 + // Reference API doc: https://docs.nvidia.com/gameworks/content/gameworkslibrary/coresdk/nvapi/structNV__I2C__INFO__V3.html + pub fn test_i2c(&self) { + // Test from 'GigabyteRGBFusion2GPUControllerDetect.cpp' + let data = [0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + self.gpus[0] + .i2c_write( + 0, + Some(1), + false, + super::GIGABYTE_RTX3080TI_VISION_OC_ADDR, + &[], + &data, + i2c::I2cSpeed::Default, + ) + .expect("Error"); + } + + fn set_mode_3080ti(&self) { + let data = [ + super::RGB_FUSION2_GPU_REG_MODE, + 0x01, // Mode (1: static). + 0x00, // Speed. + 0x63, // Brightness max. + 0x00, // Mistery flag. + 0x01, // Zone. + 0x00, + 0x00, + ]; + self.gpus[0] + .i2c_write( + 0, + Some(1), + false, + super::GIGABYTE_RTX3080TI_VISION_OC_ADDR, + &[], + &data, + i2c::I2cSpeed::Default, + ) + .expect("Error"); + } + + fn set_color_3080ti(&self, color: &rgb::RGB) { + // TODO. + self.test_i2c(); + } +} + +impl Machine for MachineLyssMetal2 { + fn set_color_1(&mut self, color: &rgb::RGB) { + self.corsair_lignting_pro.set_color(color); + self.fusion_device.set_color(color); + // self.set_color_3080ti(&color); // TODO. + } + + fn set_color_2(&mut self, color: &rgb::RGB) { + self.lian_li_sl_infinity.set_color(color); + } + + fn get_gpu_tmp(&self) -> f32 { + self.gpus[0].thermal_settings(None).unwrap()[0] + .current_temperature + .0 as f32 + } + + fn get_cpu_tmp(&self) -> f32 { + cpu_temperature::read() + } +} diff --git a/src/machine/mod.rs b/src/machine/mod.rs new file mode 100644 index 0000000..0ed2ff5 --- /dev/null +++ b/src/machine/mod.rs @@ -0,0 +1,21 @@ +use crate::rgb; + +pub mod jiji; +pub mod lyss_metal; +pub mod lyss_metal2; + +const RGB_FUSION2_GPU_REG_COLOR: u8 = 0x40; +const RGB_FUSION2_GPU_REG_MODE: u8 = 0x88; + +const GIGABYTE_RTX3080TI_VISION_OC_ADDR: u8 = 0x63; + +pub trait Machine { + fn set_color(&mut self, color: &rgb::RGB) { + self.set_color_1(color); + self.set_color_2(color); + } + fn set_color_1(&mut self, color: &rgb::RGB); + fn set_color_2(&mut self, color: &rgb::RGB); + fn get_gpu_tmp(&self) -> f32; + fn get_cpu_tmp(&self) -> f32; +} diff --git a/src/main.rs b/src/main.rs index a0443f7..ff87264 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,6 +38,7 @@ mod intel_arc { mod a770; mod asus_aura_usb; mod corsair_lighting_pro; +mod gigabyte_rgb_fusion_usb; mod lian_li_sl_infinity; mod machine; mod main_loop; @@ -183,7 +184,7 @@ fn run_service(_arguments: Vec) -> Result<(), windows_service::Error> let completed_event_handler = Arc::clone(&completed); - info!("Setuping the event handler..."); + info!("Setup the event handler..."); let event_handler = move |control_event| -> ServiceControlHandlerResult { match control_event { diff --git a/src/main_loop.rs b/src/main_loop.rs index a11c36b..1d523b3 100644 --- a/src/main_loop.rs +++ b/src/main_loop.rs @@ -35,15 +35,20 @@ pub fn main_loop(completed: Arc) { }; let settings = settings::Settings::read(&file_conf_path).expect("Cannot load settings"); - println!("Settings: {settings:?}"); + println!("Settings: {settings:?} from {file_conf_path}"); let mut machine: Box = match settings.machine_name { settings::MachineName::Jiji => { - Box::new(machine::MachineJiji::new().expect("Unable to create MachineJiji")) - } - settings::MachineName::LyssMetal => { - Box::new(machine::MachineLyssMetal::new().expect("Unable to create MachineLyssMetal")) + Box::new(machine::jiji::MachineJiji::new().expect("Unable to create MachineJiji")) } + settings::MachineName::LyssMetal => Box::new( + machine::lyss_metal::MachineLyssMetal::new() + .expect("Unable to create MachineLyssMetal"), + ), + settings::MachineName::LyssMetal2 => Box::new( + machine::lyss_metal2::MachineLyssMetal2::new() + .expect("Unable to create MachineLyssMetal2"), + ), }; let mut kernel = [0f32; consts::KERNEL_SIZE_SAMPLES]; diff --git a/src/piix4_i2c.rs b/src/piix4_i2c.rs index 7acc572..7397459 100644 --- a/src/piix4_i2c.rs +++ b/src/piix4_i2c.rs @@ -88,18 +88,17 @@ impl I2c { ); let mut data_block = [0u8; I2C_BLOCK_MAX + 2]; data_block[0] = l as u8; - data_block[1..l + 1].copy_from_slice(&data); + data_block[1..l + 1].copy_from_slice(data); unsafe { - match self.i2c_smbus_xfer( + if let Err(error) = self.i2c_smbus_xfer( addr, AccessType::Write, command, TransactionType::I2cSmbusBlockData, Some(&data_block), ) { - Err(error) => println!("Error when writing block (I2c): {error:?}"), - Ok(_) => (), + println!("Error when writing block (I2c): {error:?}"); } } } @@ -129,7 +128,7 @@ impl I2c { TransactionType::I2cSmbusQuick => { self.write_io_port_byte( SMBusAddressOffsets::Smbhstadd, - addr << 1 | access_type as u8, + (addr << 1) | access_type as u8, ); Piix4TransactionType::Piix4Quick } @@ -139,7 +138,7 @@ impl I2c { TransactionType::I2cSmbusBlockData => { self.write_io_port_byte( SMBusAddressOffsets::Smbhstadd, - addr << 1 | access_type as u8, + (addr << 1) | access_type as u8, ); self.write_io_port_byte(SMBusAddressOffsets::Smbhstcmd, command); if let AccessType::Write = access_type { @@ -188,7 +187,7 @@ impl I2c { for i in 1..=l { data[i] = self.read_io_port_byte(SMBusAddressOffsets::Smbblkdat); } - return Ok(XferResult::BlockData(data)); + Ok(XferResult::BlockData(data)) } } } @@ -237,7 +236,7 @@ impl I2c { self.write_io_port_byte(SMBusAddressOffsets::Smbhststs, res); } - return Ok(()); + Ok(()) } unsafe fn write_io_port_byte(&self, op: SMBusAddressOffsets, value: u8) { diff --git a/src/settings.rs b/src/settings.rs index 511cb8c..43ae03d 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -12,6 +12,7 @@ use crate::rgb::RGB; pub enum MachineName { Jiji, LyssMetal, + LyssMetal2, } #[derive(Debug, Deserialize, Serialize)] diff --git a/src/tests.rs b/src/tests.rs index b49081e..c7ea81c 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -4,7 +4,7 @@ use wmi::{COMLibrary, Variant, WMIConnection}; use crate::{ a770, asus_aura_usb, corsair_lighting_pro, corsair_vengeance, cpu_temperature, - lian_li_sl_infinity, machine, rgb::RGB, winring0, wrapper_winring0, + gigabyte_rgb_fusion_usb, lian_li_sl_infinity, machine, rgb::RGB, winring0, wrapper_winring0, }; pub fn tests() { @@ -14,7 +14,7 @@ pub fn tests() { // test_asus_aura_usb(asus_aura_usb::Motherboard::Asus650e); // test_corsair_lighting_pro(); - test_lianli_sl_infinity(); + // test_lianli_sl_infinity(); // list_usb_devices(); // test_roccat(); // test_wmi(); @@ -24,6 +24,7 @@ pub fn tests() { // test_read_temperature_cpu(); // test_read_temperature_a770(); // test_read_temperature_3080(); + test_gigabyte_fusion(); winring0::deinit(); @@ -31,6 +32,17 @@ pub fn tests() { std::io::stdin().read_line(&mut String::new()).unwrap(); } +fn test_gigabyte_fusion() { + let api = hidapi::HidApi::new().unwrap(); + let device = gigabyte_rgb_fusion_usb::Device::new(&api).unwrap(); + // device.test_raw_data().unwrap(); + device.set_color(&RGB { + red: 0xFF, + green: 0x00, + blue: 0x00, + }); +} + fn test_wmi() { let com_con = COMLibrary::new().unwrap(); let wmi_con = WMIConnection::new(com_con.into()).unwrap(); @@ -170,7 +182,8 @@ fn test_a770() { } fn test_3080ti() { - let machine: &mut dyn machine::Machine = &mut machine::MachineLyssMetal::new().unwrap(); + let machine: &mut dyn machine::Machine = + &mut machine::lyss_metal::MachineLyssMetal::new().unwrap(); machine.set_color(&RGB { red: 255, @@ -188,7 +201,7 @@ fn test_read_temperature_cpu() { } fn test_read_temperature_a770() { - let jiji: &dyn machine::Machine = &machine::MachineJiji::new().unwrap(); + let jiji: &dyn machine::Machine = &machine::jiji::MachineJiji::new().unwrap(); println!("temp gpu: {}", jiji.get_gpu_tmp()); } -- 2.49.0