# USB and Bluetooth HID-Class devices.
hidapi = "2.4"
+# Nvidia API.
+nvapi = "0.1"
+
libc = "0.2"
wmi = "0.13"
crc = "3.0"
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,
- }
+ let device =
+ Device {
+ device: api
+ .open(
+ VID,
+ match motherboard {
+ Motherboard::Asus650e => PID_650_E,
+ Motherboard::AsusCrosshairVIIIHero => PID_CROSSHAIR,
+ },
+ )
+ .unwrap(),
+ motherboard,
+ };
+
+ device.set_fixed_mode();
+ device
}
pub fn get_firmware_string(&self) -> String {
.expect("slice with incorrect length")
}
- pub fn set_fixed_mode(&self) {
+ fn set_fixed_mode(&self) {
let mut buffer = [0u8; 65];
buffer[0] = 0xEC;
buffer[1] = 0x35; // Control mode.
const CORSAIR_LIGHTING_NODE_MODE_STATIC: u8 = 0x04; // Static mode
+const CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_RED: u8 = 0x00;
+const CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_GREEN: u8 = 0x01;
+const CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_BLUE: u8 = 0x02;
+
const CHANNEL_COUNT: u8 = 2;
+const NB_LEDS: u8 = 20;
pub struct Device {
device: hidapi::HidDevice,
}
impl Device {
- pub fn new(api: &hidapi::HidApi) -> Self {
+ pub fn new(api: &hidapi::HidApi, initial_color: &RGB) -> Self {
let device = Device {
device: api
.open(CORSAIR_VID, CORSAIR_LIGHTING_NODE_PRO_PID)
device.send_reset(channel_id);
device.send_begin(channel_id);
device.send_port_state(channel_id, CORSAIR_LIGHTING_NODE_PORT_STATE_HARDWARE);
- device.send_effect_config(
- channel_id,
- &RGB {
- red: 0x00,
- green: 0x00,
- blue: 0x00,
- },
- );
+ device.send_effect_config(channel_id, initial_color);
device.send_commit(channel_id);
}
device
}
- pub fn set_color(&self, color: &RGB) {
- for channel_id in 0..CHANNEL_COUNT {
- self.send_effect_config(channel_id, color);
- }
- }
-
fn send_reset(&self, channel_id: u8) {
let mut buffer = [0u8; 65];
buffer[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_RESET;
let n_read = self.device.read(&mut buffer[0..16]).unwrap();
assert_eq!(n_read, 16);
+ assert_eq!(buffer[0], 0);
}
fn send_begin(&self, channel_id: u8) {
let n_read = self.device.read(&mut buffer[0..16]).unwrap();
assert_eq!(n_read, 16);
+ assert_eq!(buffer[0], 0);
}
fn send_port_state(&self, channel_id: u8, state: u8) {
let n_read = self.device.read(&mut buffer[0..16]).unwrap();
assert_eq!(n_read, 16);
+ assert_eq!(buffer[0], 0);
}
fn send_effect_config(&self, channel_id: u8, color: &RGB) {
+ println!("{color:?}");
+
let mut buffer = [0u8; 65];
buffer[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_EFFECT_CONFIG;
buffer[0x02] = channel_id;
buffer[0x03] = 0x00; // count.
- buffer[0x04] = 0x1E; // led type.
+ buffer[0x04] = NB_LEDS; // led type. (number of leds!?).
buffer[0x05] = CORSAIR_LIGHTING_NODE_MODE_STATIC; // mode: static.
buffer[0x06] = 0x00; // speed.
buffer[0x07] = 0x00; // direction.
let n_read = self.device.read(&mut buffer[0..16]).unwrap();
assert_eq!(n_read, 16);
+ assert_eq!(buffer[0], 0);
}
fn send_commit(&self, channel_id: u8) {
let n_read = self.device.read(&mut buffer[0..16]).unwrap();
assert_eq!(n_read, 16);
+ assert_eq!(buffer[0], 0);
+ }
+
+ pub fn set_color(&self, color: &RGB) {
+ // println!("set_color: {color:?}");
+ for channel_id in 0..CHANNEL_COUNT {
+ self.send_port_state(channel_id, CORSAIR_LIGHTING_NODE_PORT_STATE_SOFTWARE);
+
+ let mut buffer = [0u8; 65];
+
+ for color_channel in [
+ CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_RED,
+ CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_GREEN,
+ CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_BLUE,
+ ] {
+ buffer[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_DIRECT;
+ buffer[0x02] = channel_id;
+ buffer[0x04] = NB_LEDS; // Number of color;
+ buffer[0x05] = color_channel;
+
+ let color_component = match color_channel {
+ 0 => color.red,
+ 1 => color.green,
+ _ => color.blue,
+ };
+
+ for n in 0..NB_LEDS {
+ buffer[0x06 + n as usize] = color_component;
+ }
+
+ let n_write = self.device.write(&buffer).unwrap();
+ assert_eq!(n_write, 65);
+
+ let n_read = self.device.read(&mut buffer[0..16]).unwrap();
+ assert_eq!(n_read, 16);
+ assert_eq!(buffer[0], 0);
+ }
+
+ self.send_commit(channel_id);
+ }
}
}
-use crate::{a770, asus_aura_usb, corsair_vengeance, cpu_temperature, intel_arc, rgb};
+use crate::{
+ a770, asus_aura_usb, corsair_lighting_pro, corsair_vengeance, cpu_temperature, intel_arc, rgb,
+};
pub trait Machine {
fn set_color(&mut self, color: &rgb::RGB);
impl MachineJiji {
pub fn new() -> Self {
let api = hidapi::HidApi::new().unwrap();
- let machine = MachineJiji {
+ 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() },
- };
- machine.b650e_device.set_fixed_mode();
- machine
+ }
}
}
}
}
-struct MachineLyssMetal {}
+pub struct MachineLyssMetal {
+ crosshair_device: asus_aura_usb::Device,
+ corsair_lignting_pro: corsair_lighting_pro::Device,
+ gpus: Vec<nvapi::PhysicalGpu>,
+}
+
+impl MachineLyssMetal {
+ pub fn new() -> Self {
+ let api = hidapi::HidApi::new().unwrap();
+
+ nvapi::initialize().expect("Unable to initialize nvapi (Nvidia API)");
+
+ 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 {
+ red: 0,
+ green: 255,
+ blue: 40,
+ },
+ ),
+ gpus: nvapi::PhysicalGpu::enumerate().unwrap(),
+ }
+ }
+}
+
+impl Machine for MachineLyssMetal {
+ fn set_color(&mut self, color: &rgb::RGB) {
+ self.crosshair_device.set_color(&color);
+ self.corsair_lignting_pro.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()
+ }
+}
let settings = settings::Settings::read(consts::FILE_CONF).expect("Cannot load settings");
println!("Settings: {settings:?}");
- let machine: &mut dyn machine::Machine = &mut machine::MachineJiji::new();
+ 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()),
+ };
let mut kernel = [0f32; consts::KERNEL_SIZE_SAMPLES];
let mut current_pos = 0usize;
// Partial implementation for PCI IDE ISA Xcelerator.
+// https://www.kernel.org/doc/html/latest/i2c/summary.html
use std::time::Duration;
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_read_temperature_cpu();
- // test_read_temperatur_a770
+ // test_read_temperature_cpu();
+ // test_read_temperature_a770()
+ // test_read_temperature_3080();
winring0::deinit();
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,
fn test_corsair_lighting_pro() {
let api = hidapi::HidApi::new().unwrap();
- let device = corsair_lighting_pro::Device::new(&api);
-
- device.set_color(&RGB {
- red: 0,
- green: 0,
- blue: 255,
- });
+ let device = corsair_lighting_pro::Device::new(
+ &api,
+ &RGB {
+ red: 0,
+ green: 255,
+ blue: 0,
+ },
+ );
+
+ for i in 0..=255 {
+ if i % 10 == 0 || i == 255 || i == 0 {
+ device.set_color(&RGB {
+ red: i as u8,
+ green: 255u8 - i as u8,
+ blue: 0,
+ });
+ std::thread::sleep(std::time::Duration::from_millis(200));
+ }
+ }
}
fn test_corsair() {
corsair_vengeance::Controller::new(0x19),
corsair_vengeance::Controller::new(0x1B),
];
+
for controller in corsair_controllers {
controller.set_color(&RGB {
red: 0,
println!("temp cpu: {}", cpu_temperature::read())
}
-fn test_read_temperatur_a770() {
+fn test_read_temperature_a770() {
let jiji: &dyn machine::Machine = &machine::MachineJiji::new();
println!("temp gpu: {}", jiji.get_gpu_tmp());
}
+fn test_read_temperature_3080() {
+ nvapi::initialize().expect("Unable to initialize nvapi (Nvidia API)");
+ // if let Ok(gpus) = {
+ // for gpu in gpus {
+ // let thermal = gpu.thermal_settings(None).unwrap()[0];
+ // println!("{:?}", thermal.current_temperature.0)
+ // }
+ // }
+ let gpus = nvapi::PhysicalGpu::enumerate().unwrap();
+ let gpu = &gpus[0];
+ let sensor = gpu.thermal_settings(None).unwrap()[0];
+ println!("{:?}", sensor.current_temperature.0);
+ nvapi::unload().unwrap();
+}