tof_control/device/
cy8c9560a.rs

1#![allow(unused)]
2use crate::constant::*;
3
4use i2c_linux_sys::i2c_smbus_read_i2c_block_data;
5use i2cdev::core::*;
6use i2cdev::linux::{LinuxI2CDevice, LinuxI2CError};
7
8// Register
9const INPUT_PORT_0: u16 = 0x00;
10const INPUT_PORT_1: u16 = 0x01;
11const INPUT_PORT_2: u16 = 0x02;
12const INPUT_PORT_3: u16 = 0x03;
13const INPUT_PORT_4: u16 = 0x04;
14const INPUT_PORT_5: u16 = 0x05;
15const INPUT_PORT_6: u16 = 0x06;
16const INPUT_PORT_7: u16 = 0x07;
17const OUTPUT_PORT_0: u16 = 0x08;
18const OUTPUT_PORT_1: u16 = 0x09;
19const OUTPUT_PORT_2: u16 = 0x0A;
20const OUTPUT_PORT_3: u16 = 0x0B;
21const OUTPUT_PORT_4: u16 = 0x0C;
22const OUTPUT_PORT_5: u16 = 0x0D;
23const OUTPUT_PORT_6: u16 = 0x0E;
24const OUTPUT_PORT_7: u16 = 0x0F;
25const INTERRUPT_STATUS_PORT_0: u16 = 0x10;
26const INTERRUPT_STATUS_PORT_1: u16 = 0x11;
27const INTERRUPT_STATUS_PORT_2: u16 = 0x12;
28const INTERRUPT_STATUS_PORT_3: u16 = 0x13;
29const INTERRUPT_STATUS_PORT_4: u16 = 0x14;
30const INTERRUPT_STATUS_PORT_5: u16 = 0x15;
31const INTERRUPT_STATUS_PORT_6: u16 = 0x16;
32const INTERRUPT_STATUS_PORT_7: u16 = 0x17;
33const PORT_SELECT: u16 = 0x18;
34const INTERRUPT_MASK: u16 = 0x19;
35const PIN_DIRECTION: u16 = 0x1C;
36const DRIVE_MODE_PULL_UP: u16 = 0x1D;
37const DRIVE_MODE_PULL_DOWN: u16 = 0x1E;
38const DRIVE_MODE_OPEN_DRAIN_HIGH: u16 = 0x1F;
39const DRIVE_MODE_OPEN_DRAIN_LOW: u16 = 0x20;
40const DRIVE_MODE_STRONG: u16 = 0x21;
41const DRIVE_MODE_SLOW_STRONG: u16 = 0x22;
42const DRIVE_MODE_HIGH_Z: u16 = 0x23;
43const ENABLE_REGISTER: u16 = 0x2D;
44const DEVICE_INFO: u16 = 0x2E;
45const COMMAND: u16 = 0x30;
46
47#[derive(Copy, Clone)]
48pub struct CY8C9560A {
49    bus: u8,
50    address: u16,
51}
52
53impl CY8C9560A {
54    pub fn new(bus: u8, address: u16) -> Self {
55        Self { bus, address }
56    }
57    pub fn read_device_info(&self) -> Result<(u8, u8), LinuxI2CError> {
58        let mut dev = LinuxI2CDevice::new(&format!("/dev/i2c-{}", self.bus), self.address)?;
59        let device_info = dev.smbus_read_byte_data(DEVICE_INFO as u8)?;
60        let device_family = (device_info & 0xF0) >> 4;
61        let device_setting = device_info & 0x01;
62
63        Ok((device_family, device_setting))
64    }
65    pub fn read_enable_register(&self) -> Result<u8, LinuxI2CError> {
66        let mut dev = LinuxI2CDevice::new(&format!("/dev/i2c-{}", self.bus), self.address)?;
67        let enable_register = dev.smbus_read_byte_data(ENABLE_REGISTER as u8)?;
68
69        Ok(enable_register)
70    }
71    pub fn enable_eeprom(&self) -> Result<(), LinuxI2CError> {
72        let mut dev = LinuxI2CDevice::new(&format!("/dev/i2c-{}", self.bus), self.address)?;
73        let eeprom_enable_sequence: [u8; 4] = [0x43, 0x4D, 0x53, 0x02];
74        dev.smbus_write_i2c_block_data(ENABLE_REGISTER as u8, &eeprom_enable_sequence)?;
75
76        Ok(())
77    }
78    pub fn store_config_eeprom_por(&self) -> Result<(), LinuxI2CError> {
79        let mut dev = LinuxI2CDevice::new(&format!("/dev/i2c-{}", self.bus), self.address)?;
80        dev.smbus_write_byte_data(COMMAND as u8, 0x01)?;
81
82        Ok(())
83    }
84    pub fn reset_config_eeprom_por(&self) -> Result<(), LinuxI2CError> {
85        let mut dev = LinuxI2CDevice::new(&format!("/dev/i2c-{}", self.bus), self.address)?;
86        dev.smbus_write_byte_data(COMMAND as u8, 0x02)?;
87
88        Ok(())
89    }
90    pub fn read_port_status(&self, port: u8) -> Result<u8, LinuxI2CError> {
91        let mut dev = LinuxI2CDevice::new(&format!("/dev/i2c-{}", self.bus), self.address)?;
92        let port_status = dev.smbus_read_byte_data(match port {
93            0 => INPUT_PORT_0 as u8,
94            1 => INPUT_PORT_1 as u8,
95            2 => INPUT_PORT_2 as u8,
96            3 => INPUT_PORT_3 as u8,
97            4 => INPUT_PORT_4 as u8,
98            5 => INPUT_PORT_5 as u8,
99            6 => INPUT_PORT_6 as u8,
100            7 => INPUT_PORT_7 as u8,
101            _ => 0xFF,
102        })?;
103
104        Ok(port_status)
105    }
106    pub fn initialize_all_outputs(&self) -> Result<(), LinuxI2CError> {
107        for i in 0..8 {
108            self.set_output_port(i, 0xFF)?;
109        }
110
111        Ok(())
112    }
113    pub fn set_output_port(&self, port: u8, value: u8) -> Result<(), LinuxI2CError> {
114        let mut dev = LinuxI2CDevice::new(&format!("/dev/i2c-{}", self.bus), self.address)?;
115        dev.smbus_write_byte_data(
116            match port {
117                0 => OUTPUT_PORT_0 as u8,
118                1 => OUTPUT_PORT_1 as u8,
119                2 => OUTPUT_PORT_2 as u8,
120                3 => OUTPUT_PORT_3 as u8,
121                4 => OUTPUT_PORT_4 as u8,
122                5 => OUTPUT_PORT_5 as u8,
123                6 => OUTPUT_PORT_6 as u8,
124                7 => OUTPUT_PORT_7 as u8,
125                _ => 0xFF,
126            },
127            value,
128        )?;
129
130        Ok(())
131    }
132    pub fn select_port(&self, port: u8) -> Result<(), LinuxI2CError> {
133        let mut dev = LinuxI2CDevice::new(&format!("/dev/i2c-{}", self.bus), self.address)?;
134        dev.smbus_write_byte_data(PORT_SELECT as u8, port)?;
135
136        Ok(())
137    }
138    pub fn set_interrupt_mask_port(&self, value: u8) -> Result<(), LinuxI2CError> {
139        let mut dev = LinuxI2CDevice::new(&format!("/dev/i2c-{}", self.bus), self.address)?;
140        dev.smbus_write_byte_data(INTERRUPT_MASK as u8, value)?;
141
142        Ok(())
143    }
144    pub fn set_pin_direction(&self, value: u8) -> Result<(), LinuxI2CError> {
145        let mut dev = LinuxI2CDevice::new(&format!("/dev/i2c-{}", self.bus), self.address)?;
146        dev.smbus_write_byte_data(PIN_DIRECTION as u8, value)?;
147
148        Ok(())
149    }
150    pub fn set_drive_mode(&self, mode: u8) -> Result<(), LinuxI2CError> {
151        let mut dev = LinuxI2CDevice::new(&format!("/dev/i2c-{}", self.bus), self.address)?;
152        dev.smbus_write_byte_data(
153            match mode {
154                0 => DRIVE_MODE_PULL_UP as u8,
155                1 => DRIVE_MODE_PULL_DOWN as u8,
156                2 => DRIVE_MODE_OPEN_DRAIN_HIGH as u8,
157                3 => DRIVE_MODE_OPEN_DRAIN_LOW as u8,
158                4 => DRIVE_MODE_STRONG as u8,
159                5 => DRIVE_MODE_SLOW_STRONG as u8,
160                6 => DRIVE_MODE_HIGH_Z as u8,
161                _ => 0xFF,
162            },
163            0x01,
164        )?;
165
166        Ok(())
167    }
168    // Set RF Switch (HMC849)
169    pub fn set_rf_switch(&self, channel: u8, mode: u8) -> Result<(), LinuxI2CError> {
170        match channel {
171            0 => match mode {
172                0 => {
173                    let value: u8 = (0x3F & !0x30) | 0x20;
174                    self.set_output_port(7, value)?;
175                }
176                1 => {
177                    let value: u8 = (0x3F & !0x30) | 0x10;
178                    self.set_output_port(7, value)?;
179                }
180                2 => {
181                    let value: u8 = (0x3F & !0x30) | 0x00;
182                    self.set_output_port(7, value)?;
183                }
184                _ => {
185                    self.set_output_port(7, 0x3F)?;
186                }
187            },
188            1 => match mode {
189                0 => {
190                    let value: u8 = (0x3F | 0x0C) & 0x0C;
191                    self.set_output_port(7, value)?;
192                }
193                1 => {
194                    let value: u8 = (0x3F & !0x0C) | 0x04;
195                    self.set_output_port(7, value)?;
196                }
197                2 => {
198                    let value: u8 = (0x3F & !0x0C) | 0x00;
199                    self.set_output_port(7, value)?;
200                }
201                _ => {
202                    self.set_output_port(7, 0x3F)?;
203                }
204            },
205            2 => match mode {
206                0 => {
207                    let value: u8 = (0x3F | 0x03) & 0x03;
208                    self.set_output_port(7, value)?;
209                }
210                1 => {
211                    let value: u8 = (0x3F & !0x03) | 0x01;
212                    self.set_output_port(7, value)?;
213                }
214                2 => {
215                    let value: u8 = (0x3F & !0x03) | 0x00;
216                    self.set_output_port(7, value)?;
217                }
218                _ => {
219                    self.set_output_port(7, 0x3F)?;
220                }
221            },
222            3 => match mode {
223                0 => {
224                    let value: u8 = (0x03 | 0x03) & 0x03;
225                    self.set_output_port(2, value)?;
226                }
227                1 => {
228                    let value: u8 = (0x03 & !0x03) | 0x01;
229                    self.set_output_port(2, value)?;
230                }
231                2 => {
232                    let value: u8 = (0x03 & !0x03) | 0x00;
233                    self.set_output_port(2, value)?;
234                }
235                _ => {
236                    self.set_output_port(2, 0x03)?;
237                }
238            },
239            4 => match mode {
240                0 => {
241                    let value: u8 = (0x33 | 0x03) & 0x03;
242                    self.set_output_port(5, value)?;
243                }
244                1 => {
245                    let value: u8 = (0x33 & !0x03) | 0x02;
246                    self.set_output_port(5, value)?;
247                }
248                2 => {
249                    let value: u8 = (0x33 & !0x03) | 0x00;
250                    self.set_output_port(5, value)?;
251                }
252                _ => {
253                    self.set_output_port(5, 0x33)?;
254                }
255            },
256            5 => match mode {
257                0 => {
258                    let value: u8 = (0x33 | 0x30) & 0x30;
259                    self.set_output_port(5, value)?;
260                }
261                1 => {
262                    let value: u8 = (0x33 & !0x30) | 0x10;
263                    self.set_output_port(5, value)?;
264                }
265                2 => {
266                    let value: u8 = (0x33 & !0x30) | 0x00;
267                    self.set_output_port(5, value)?;
268                }
269                _ => {
270                    self.set_output_port(5, 0x33)?;
271                }
272            },
273            6 => match mode {
274                0 => {
275                    let value: u8 = (0xFC | 0xC0) & 0xC0;
276                    self.set_output_port(4, value)?;
277                }
278                1 => {
279                    let value: u8 = (0xFC & !0xC0) | 0x80;
280                    self.set_output_port(4, value)?;
281                }
282                2 => {
283                    let value: u8 = (0xFC & !0xC0) | 0x00;
284                    self.set_output_port(4, value)?;
285                }
286                _ => {
287                    self.set_output_port(4, 0xFC)?;
288                }
289            },
290            7 => match mode {
291                0 => {
292                    let value: u8 = (0xFC | 0x30) & 0x30;
293                    self.set_output_port(4, value)?;
294                }
295                1 => {
296                    let value: u8 = (0xFC & !0x30) | 0x20;
297                    self.set_output_port(4, value)?;
298                }
299                2 => {
300                    let value: u8 = (0xFC & !0x30) | 0x00;
301                    self.set_output_port(4, value)?;
302                }
303                _ => {
304                    self.set_output_port(4, 0xFC)?;
305                }
306            },
307            8 => match mode {
308                0 => {
309                    let value: u8 = (0xFC | 0x0C) & 0x0C;
310                    self.set_output_port(4, value)?;
311                }
312                1 => {
313                    let value: u8 = (0xFC & !0x0C) | 0x08;
314                    self.set_output_port(4, value)?;
315                }
316                2 => {
317                    let value: u8 = (0xFC & !0x0C) | 0x00;
318                    self.set_output_port(4, value)?;
319                }
320                _ => {
321                    self.set_output_port(4, 0xFC)?;
322                }
323            },
324            _ => {}
325        };
326
327        Ok(())
328    }
329    // neet to check!
330    pub fn reset_clock_synthesizer(&self) -> Result<(), LinuxI2CError> {
331        let mut value = (0x03 & !0x02) | 0 << 1;
332        value = (value & !0x01) | 1;
333
334        self.set_output_port(3, value)?;
335
336        Ok(())
337    }
338    // neet to check!
339    pub fn enable_tcal_clock(&self) -> Result<(), LinuxI2CError> {
340        let mut value: u16 = (0x3F | 0x80) | (0x01 << 8);
341        self.set_output_port(7, value as u8)?;
342
343        value = (0x3F | 0x40) | (0x01 << 7);
344        self.set_output_port(7, value as u8)?;
345
346        Ok(())
347    }
348    pub fn disable_tcal_clock(&self) -> Result<(), LinuxI2CError> {
349        let mut value: u16 = (0x3F | 0x80);
350        self.set_output_port(7, value as u8)?;
351
352        value = (0x3F | 0x40);
353        self.set_output_port(7, value as u8)?;
354
355        Ok(())
356    }
357}