Replace some unwrap by Result
[temp2RGB.git] / src / machine.rs
1 use log::error;
2 use nvapi::sys::i2c;
3
4 use crate::{
5 a770, asus_aura_usb, corsair_lighting_pro, corsair_vengeance, cpu_temperature, intel_arc, rgb,
6 };
7
8 const RGB_FUSION2_GPU_REG_COLOR: u8 = 0x40;
9 const RGB_FUSION2_GPU_REG_MODE: u8 = 0x88;
10
11 const GIGABYTE_RTX3080TI_VISION_OC_ADDR: u8 = 0x63;
12
13 pub trait Machine {
14 fn set_color(&mut self, color: &rgb::RGB);
15 fn get_gpu_tmp(&self) -> f32;
16 fn get_cpu_tmp(&self) -> f32;
17 }
18
19 pub struct MachineJiji {
20 ram: Vec<corsair_vengeance::Controller>,
21 b650e_device: asus_aura_usb::Device,
22 a770: a770::A770,
23 gpu_devices: intel_arc::Devices,
24 }
25
26 impl MachineJiji {
27 pub fn new() -> anyhow::Result<Self> {
28 let api = hidapi::HidApi::new().unwrap();
29 Ok(MachineJiji {
30 ram: vec![
31 corsair_vengeance::Controller::new(0x19),
32 corsair_vengeance::Controller::new(0x1B),
33 ],
34 b650e_device: asus_aura_usb::Device::new(&api, asus_aura_usb::Motherboard::Asus650e)?,
35 a770: a770::A770::new()?,
36 gpu_devices: unsafe { intel_arc::GetDevices() },
37 })
38 }
39 }
40
41 impl Machine for MachineJiji {
42 fn set_color(&mut self, color: &rgb::RGB) {
43 for controller in &self.ram {
44 controller.set_color(&color);
45 }
46 self.b650e_device.set_color(&color);
47 if let Err(error) = self.a770.set_color(color.red, color.green, color.blue) {
48 error!("Unable to set color: {:?}", error);
49 }
50 }
51
52 fn get_gpu_tmp(&self) -> f32 {
53 unsafe { intel_arc::GetTemperature(self.gpu_devices, 0) as f32 }
54 }
55
56 fn get_cpu_tmp(&self) -> f32 {
57 cpu_temperature::read()
58 }
59 }
60
61 impl Drop for MachineJiji {
62 fn drop(&mut self) {
63 unsafe {
64 intel_arc::FreeDevices(self.gpu_devices);
65 }
66 }
67 }
68
69 pub struct MachineLyssMetal {
70 crosshair_device: asus_aura_usb::Device,
71 corsair_lignting_pro: corsair_lighting_pro::Device,
72 gpus: Vec<nvapi::PhysicalGpu>,
73 }
74
75 impl MachineLyssMetal {
76 pub fn new() -> anyhow::Result<Self> {
77 let api = hidapi::HidApi::new()?;
78
79 nvapi::initialize().expect("Unable to initialize nvapi (Nvidia API)");
80
81 let machine = MachineLyssMetal {
82 crosshair_device: asus_aura_usb::Device::new(
83 &api,
84 asus_aura_usb::Motherboard::AsusCrosshairVIIIHero,
85 )?,
86 corsair_lignting_pro: corsair_lighting_pro::Device::new(
87 &api,
88 &rgb::RGB {
89 red: 0,
90 green: 255,
91 blue: 40,
92 },
93 ),
94 gpus: nvapi::PhysicalGpu::enumerate()?,
95 };
96
97 // machine.set_mode_3080ti();
98 Ok(machine)
99 }
100
101 // Doesn't work: "Error: NotSupported".
102 // From OpenRGB, see the following files:
103 // * Controllers\GigabyteRGBFusion2GPUController\GigabyteRGBFusion2GPUControllerDetect.cpp
104 // * Controllers\GigabyteRGBFusion2GPUController\RGBController_GigabyteRGBFusion2GPU.cpp
105 // * Controllers\GigabyteRGBFusion2GPUController\GigabyteRGBFusion2GPUController.cpp
106 // * i2c_smbus\i2c_smbus_nvapi.cpp
107 // Implementation of nvapi-rs: https://github.com/arcnmx/nvapi-rs/blob/master/src/gpu.rs#L645
108 pub fn test_i2c(&self) {
109 // Test from 'GigabyteRGBFusion2GPUControllerDetect.cpp'
110 let data = [0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
111 self.gpus[0]
112 .i2c_write(
113 0,
114 Some(1),
115 false,
116 GIGABYTE_RTX3080TI_VISION_OC_ADDR,
117 &[],
118 &data,
119 i2c::I2cSpeed::Default,
120 )
121 .expect("Error");
122 }
123
124 fn set_mode_3080ti(&self) {
125 let data = [
126 RGB_FUSION2_GPU_REG_MODE,
127 0x01, // Mode (1: static).
128 0x00, // Speed.
129 0x63, // Brightness max.
130 0x00, // Mistery flag.
131 0x01, // Zone.
132 0x00,
133 0x00,
134 ];
135 self.gpus[0]
136 .i2c_write(
137 0,
138 Some(1),
139 false,
140 GIGABYTE_RTX3080TI_VISION_OC_ADDR,
141 &[],
142 &data,
143 i2c::I2cSpeed::Default,
144 )
145 .expect("Error");
146 }
147
148 fn set_color_3080ti(&self, color: &rgb::RGB) {
149 // TODO.
150 self.test_i2c();
151 }
152 }
153
154 impl Machine for MachineLyssMetal {
155 fn set_color(&mut self, color: &rgb::RGB) {
156 self.crosshair_device.set_color(&color);
157 self.corsair_lignting_pro.set_color(&color);
158 // self.set_color_3080ti(&color); // TODO.
159 }
160
161 fn get_gpu_tmp(&self) -> f32 {
162 self.gpus[0].thermal_settings(None).unwrap()[0]
163 .current_temperature
164 .0 as f32
165 }
166
167 fn get_cpu_tmp(&self) -> f32 {
168 cpu_temperature::read()
169 }
170 }