[dependencies]
serde = { version = "1.0", features = ["derive"] }
-ron = "0.8" # Rust object notation, to load configuration files.
+ron = "0.8" # Rust object notation, to load configuration files.
num = "0.4"
dirs = "5.0"
anyhow = "1.0"
-flexi_logger = "0.26"
+flexi_logger = "0.27"
+log-panics = { version = "2", features = ["with-backtrace"] }
log = "0.4"
windows-service = "0.6"
wmi = "0.13"
crc = "3.0"
-libloading = "0.8"
+# libloading = "0.8"
# netcorehost = "0.15"
[dependencies.windows]
bindgen = "0.68"
[profile.release]
-strip = "debuginfo"
+# strip = "debuginfo"
codegen-units = 1
lto = true
// internal static \u0024ArrayType\u0024\u0024\u0024BY08E \u003FA0x171ed149\u002E\u003FprevData\u0040\u003F1\u003F\u003FSetLEDBehavior\u0040CVGAAdaptor\u0040\u0040UEAA_NEEEEEEEEE\u0040Z\u00404PAEA;
// public static __FnPtr<_ctl_result_t (_ctl_init_args_t*, _ctl_api_handle_t**)> __m2mep\u0040\u003FctlInit\u0040\u0040\u0024\u0024J0YA\u003FAW4_ctl_result_t\u0040\u0040PEAU_ctl_init_args_t\u0040\u0040PEAPEAU_ctl_api_handle_t\u0040\u0040\u0040Z;
+use log::error;
+
use std::{
io::prelude::*,
net::TcpStream,
}
impl A770 {
- pub fn new() -> Self {
- A770 {
- process: Command::new(r"IntelOC.exe")
- .spawn()
- .expect("failed to execute process"),
- stream: TcpStream::connect("127.0.0.1:6577").unwrap(),
- }
+ pub fn new() -> anyhow::Result<Self> {
+ Ok(A770 {
+ process: Command::new(r"IntelOC.exe").spawn()?,
+ stream: TcpStream::connect("127.0.0.1:6577")?,
+ })
}
- pub fn set_color(&mut self, r: u8, g: u8, b: u8) {
+ pub fn set_color(&mut self, r: u8, g: u8, b: u8) -> anyhow::Result<()> {
let buffer: [u8; 3] = [r, g, b];
- self.stream.write(&buffer).unwrap();
+ self.stream.write(&buffer).map(|_| ())?;
+ Ok(())
}
}
impl Drop for A770 {
fn drop(&mut self) {
- self.process.kill().unwrap();
- self.process.try_wait().unwrap();
+ if let Err(error) = self.process.kill().and(self.process.try_wait()) {
+ error!("Unable to kill the child process: {:?}", error);
+ }
}
}
}
impl Device {
- pub fn new(api: &hidapi::HidApi, motherboard: Motherboard) -> Self {
+ pub fn new(api: &hidapi::HidApi, motherboard: Motherboard) -> anyhow::Result<Self> {
let device = Device {
- device: api
- .open(
- VID,
- match motherboard {
- Motherboard::Asus650e => PID_650_E,
- Motherboard::AsusCrosshairVIIIHero => PID_CROSSHAIR,
- },
- )
- .unwrap(),
+ device: api.open(
+ VID,
+ match motherboard {
+ Motherboard::Asus650e => PID_650_E,
+ Motherboard::AsusCrosshairVIIIHero => PID_CROSSHAIR,
+ },
+ )?,
motherboard,
};
- device.set_fixed_mode();
- device
+ device.set_fixed_mode()?;
+ Ok(device)
}
- pub fn get_firmware_string(&self) -> String {
+ pub fn get_firmware_string(&self) -> anyhow::Result<String> {
let mut buffer = [0u8; 65];
buffer[0] = 0xEC;
buffer[1] = AURA_REQUEST_FIRMWARE_VERSION;
- let n_write = self.device.write(&buffer).unwrap();
+ let n_write = self.device.write(&buffer)?;
assert_eq!(n_write, 65);
buffer.fill(0);
- let n_read = self.device.read(&mut buffer).unwrap();
+ let n_read = self.device.read(&mut buffer)?;
assert_eq!(n_read, 65);
assert_eq!(buffer[0], 0xEC);
assert_eq!(buffer[1], 0x02);
- String::from(str::from_utf8(&buffer[2..17]).unwrap())
+ Ok(String::from(str::from_utf8(&buffer[2..17])?))
}
/*
00 00 00 00 00 00
00 00 00 00 00 00
*/
- pub fn get_configuration_table(&self) -> [u8; 60] {
+ pub fn get_configuration_table(&self) -> anyhow::Result<[u8; 60]> {
let mut buffer = [0u8; 65];
buffer[0] = 0xEC;
buffer[1] = AURA_REQUEST_CONFIG_TABLE;
- let n_write = self.device.write(&buffer).unwrap();
+ let n_write = self.device.write(&buffer)?;
assert_eq!(n_write, 65);
buffer.fill(0);
- let n_read = self.device.read(&mut buffer).unwrap();
+ let n_read = self.device.read(&mut buffer)?;
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")
+ Ok(buffer[4..64].try_into()?)
}
- fn set_fixed_mode(&self) {
+ fn set_fixed_mode(&self) -> anyhow::Result<()> {
let mut buffer = [0u8; 65];
buffer[0] = 0xEC;
buffer[1] = 0x35; // Control mode.
for channel_effect_id in 0..2 {
buffer[2] = channel_effect_id; // Channel effect id: Fixed.
- let n_write = self.device.write(&buffer).unwrap();
+ let n_write = self.device.write(&buffer)?;
assert_eq!(n_write, 65);
}
+ Ok(())
}
- pub fn set_color(&self, color: &RGB) {
+ pub fn set_color(&self, color: &RGB) -> anyhow::Result<()> {
let mut buffer = [0u8; 65];
buffer[0] = 0xEC;
buffer[1] = 0x36;
buffer[5 + 3 * n + 2] = color.blue;
}
- let n_write = self.device.write(&buffer).unwrap();
+ let n_write = self.device.write(&buffer)?;
assert_eq!(n_write, 65);
+ Ok(())
}
- pub fn save_current_color(&self) {
+ pub fn save_current_color(&self) -> anyhow::Result<()> {
let mut buffer = [0u8; 65];
buffer[0] = 0xEC;
buffer[1] = 0x3F;
buffer[2] = 0x55;
- let n_write = self.device.write(&buffer).unwrap();
+ let n_write = self.device.write(&buffer)?;
assert_eq!(n_write, 65);
+ Ok(())
}
}
+use log::error;
+use nvapi::sys::i2c;
+
use crate::{
a770, asus_aura_usb, corsair_lighting_pro, corsair_vengeance, cpu_temperature, intel_arc, 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);
fn get_gpu_tmp(&self) -> f32;
}
impl MachineJiji {
- pub fn new() -> Self {
+ pub fn new() -> anyhow::Result<Self> {
let api = hidapi::HidApi::new().unwrap();
- MachineJiji {
+ 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(),
+ b650e_device: asus_aura_usb::Device::new(&api, asus_aura_usb::Motherboard::Asus650e)?,
+ a770: a770::A770::new()?,
gpu_devices: unsafe { intel_arc::GetDevices() },
- }
+ })
}
}
controller.set_color(&color);
}
self.b650e_device.set_color(&color);
- self.a770.set_color(color.red, color.green, color.blue);
+ if let Err(error) = self.a770.set_color(color.red, color.green, color.blue) {
+ error!("Unable to set color: {:?}", error);
+ }
}
fn get_gpu_tmp(&self) -> f32 {
}
impl MachineLyssMetal {
- pub fn new() -> Self {
- let api = hidapi::HidApi::new().unwrap();
+ pub fn new() -> anyhow::Result<Self> {
+ let api = hidapi::HidApi::new()?;
nvapi::initialize().expect("Unable to initialize nvapi (Nvidia API)");
- MachineLyssMetal {
+ let machine = MachineLyssMetal {
crosshair_device: asus_aura_usb::Device::new(
&api,
asus_aura_usb::Motherboard::AsusCrosshairVIIIHero,
- ),
+ )?,
corsair_lignting_pro: corsair_lighting_pro::Device::new(
&api,
&rgb::RGB {
blue: 40,
},
),
- gpus: nvapi::PhysicalGpu::enumerate().unwrap(),
- }
+ 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
+ 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,
+ GIGABYTE_RTX3080TI_VISION_OC_ADDR,
+ &[],
+ &data,
+ i2c::I2cSpeed::Default,
+ )
+ .expect("Error");
+ }
+
+ fn set_mode_3080ti(&self) {
+ let data = [
+ 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,
+ GIGABYTE_RTX3080TI_VISION_OC_ADDR,
+ &[],
+ &data,
+ i2c::I2cSpeed::Default,
+ )
+ .expect("Error");
+ }
+
+ fn set_color_3080ti(&self, color: &rgb::RGB) {
+ // TODO.
+ self.test_i2c();
}
}
fn set_color(&mut self, color: &rgb::RGB) {
self.crosshair_device.set_color(&color);
self.corsair_lignting_pro.set_color(&color);
+ // self.set_color_3080ti(&color); // TODO.
}
fn get_gpu_tmp(&self) -> f32 {
.print_message()
.start()?;
+ log_panics::init();
+
let args: Vec<String> = env::args().collect();
info!("Temperature to RGB");
println!("Settings: {settings:?}");
let mut machine: Box<dyn machine::Machine> = match settings.machine_name {
- settings::MachineName::Jiji => Box::new(machine::MachineJiji::new()),
- settings::MachineName::LyssMetal => Box::new(machine::MachineLyssMetal::new()),
+ 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"))
+ }
};
let mut kernel = [0f32; consts::KERNEL_SIZE_SAMPLES];
winring0::init();
- test_asus_aura_usb(asus_aura_usb::Motherboard::AsusCrosshairVIIIHero);
+ // test_asus_aura_usb(asus_aura_usb::Motherboard::AsusCrosshairVIIIHero);
// test_corsair_lighting_pro();
// list_usb_devices();
// test_roccat();
// test_wmi();
// test_corsair();
// test_a770();
+ test_3080ti();
// test_read_temperature_cpu();
// test_read_temperature_a770()
// test_read_temperature_3080();
fn test_asus_aura_usb(motherboard: asus_aura_usb::Motherboard) {
let api = hidapi::HidApi::new().unwrap();
- let device = asus_aura_usb::Device::new(&api, motherboard);
+ let device = asus_aura_usb::Device::new(&api, motherboard).unwrap();
- println!("Firmware: {}", device.get_firmware_string());
+ println!("Firmware: {}", device.get_firmware_string().unwrap());
- let configuration = device.get_configuration_table();
+ let configuration = device.get_configuration_table().unwrap();
println!("Configuration:");
for i in 0..60 {
print!("{:02X} ", configuration[i]);
println!("Number of leds: {}", configuration[0x1B]);
println!("Number of RGB headers: {}", configuration[0x1D]);
- device.set_color(&RGB {
- red: 0,
- green: 0,
- blue: 255,
- });
+ device
+ .set_color(&RGB {
+ red: 0,
+ green: 0,
+ blue: 255,
+ })
+ .unwrap();
- device.save_current_color();
+ device.save_current_color().unwrap();
}
fn test_corsair_lighting_pro() {
fn test_a770() {
// a770::set_rgb(255, 0, 0);
- let mut a770 = a770::A770::new();
- a770.set_color(255, 0, 0);
+ let mut a770 = a770::A770::new().unwrap();
+ a770.set_color(255, 0, 0).unwrap();
+}
+
+fn test_3080ti() {
+ let machine: &mut dyn machine::Machine = &mut machine::MachineLyssMetal::new().unwrap();
+
+ machine.set_color(&RGB {
+ red: 255,
+ green: 0,
+ blue: 0,
+ });
}
const F17H_M01H_THM_TCON_CUR_TMP: u32 = 0x00059800;
}
fn test_read_temperature_a770() {
- let jiji: &dyn machine::Machine = &machine::MachineJiji::new();
+ let jiji: &dyn machine::Machine = &machine::MachineJiji::new().unwrap();
println!("temp gpu: {}", jiji.get_gpu_tmp());
}