tof_control/device/
max11617.rs

1#![allow(unused)]
2use crate::constant::*;
3
4use i2cdev::core::*;
5use i2cdev::linux::{LinuxI2CDevice, LinuxI2CError};
6
7// Register
8const SETUP: u16 = 0x80;
9const CONFIG: u16 = 0x00;
10// Setup Parameters
11const SETUP_VDD_AI_NC_OFF: u16 = 0x00; // Reference Voltage = Vdd, AIN_/REF = Analog Input, REF = Not Connected, Internal Reference State = Always Off
12const SETUP_ER_RI_RI_OFF: u16 = 0x20; // Reference Voltage = External Reference, AIN_/REF = Reference Input, REF = Reference Input, Internal Reference State = Always Off
13const SETUP_IR_AI_NC_OFF: u16 = 0x40; // Reference Voltage = Internal Reference, AIN_/REF = Analog Input, REF = Not Connected, Internal Reference State = Always Off
14const SETUP_IR_AI_NC_ON: u16 = 0x50; // Reference Voltage = Internal Reference, AIN_/REF = Analog Input, REF = Not Connected, Internal Reference State = Always On
15const SETUP_IR_RO_RO_OFF: u16 = 0x60; // Reference Voltage = Internal Reference, AIN_/REF = Reference Output, REF = Reference Output, Internal Reference State = Always Off
16const SETUP_IR_RO_RO_ON: u16 = 0x70; // Reference Voltage = Internal Reference, AIN_/REF = Reference Output, REF = Reference Output, Internal Reference State = Always On
17const SETUP_INT_CLK: u16 = 0x00; // Internal Clock
18const SETUP_EXT_CLK: u16 = 0x08; // External Clock
19const SETUP_UNI: u16 = 0x00; // Unipolar
20const SETUP_BIP: u16 = 0x04; // Bipolar
21const SETUP_RST: u16 = 0x00; // Reset
22const SETUP_NA: u16 = 0x01; // No Action
23                            // Configuration Parameters
24const CONFIG_SCAN_0: u16 = 0x00; // Scans up from AIN0 to the input selected by CS3-CS0.
25const CONFIG_SCAN_1: u16 = 0x20; // Converts the input selected by CS3-CS0 eight times.
26const CONFIG_SCAN_2: u16 = 0x40; // Scans up from AIN6 to the input selected by CS3-CS0.
27const CONFIG_SCAN_3: u16 = 0x60; // Converts channel selected by CS3-CS0.
28const CONFIG_DIF: u16 = 0x00; // Differential
29const CONFIG_SGL: u16 = 0x01; // Single-ended
30
31pub struct MAX11617 {
32    bus: u8,
33    address: u16,
34}
35
36impl MAX11617 {
37    pub fn new(bus: u8, address: u16) -> Self {
38        Self { bus, address }
39    }
40    pub fn setup(&self) -> Result<(), LinuxI2CError> {
41        let mut dev = LinuxI2CDevice::new(&format!("/dev/i2c-{}", self.bus), self.address)?;
42        let setup_reg = SETUP | SETUP_ER_RI_RI_OFF | SETUP_INT_CLK | SETUP_UNI | SETUP_RST;
43
44        dev.smbus_write_i2c_block_data(0x00, &setup_reg.to_be_bytes())
45    }
46    fn config(&self, channel: u8, dev: &mut LinuxI2CDevice) -> u16 {
47        let config_reg = CONFIG | CONFIG_SCAN_3 | self.channel_selector(channel) | CONFIG_SGL;
48        dev.smbus_write_i2c_block_data(0x00, &config_reg.to_be_bytes())
49            .expect("cannot configure MAX11617");
50
51        config_reg
52    }
53    fn channel_selector(&self, channel: u8) -> u16 {
54        let channel_reg = match channel {
55            0 => 0x00,
56            1 => 0x02,
57            2 => 0x04,
58            3 => 0x06,
59            4 => 0x08,
60            5 => 0x0A,
61            6 => 0x0C,
62            7 => 0x0E,
63            8 => 0x10,
64            9 => 0x12,
65            10 => 0x14,
66            11 => 0x16,
67            _ => 0x00,
68        };
69
70        channel_reg
71    }
72    pub fn read(&self, channel: u8) -> Result<f32, LinuxI2CError> {
73        let mut dev = LinuxI2CDevice::new(&format!("/dev/i2c-{}", self.bus), self.address)?;
74        let config = self.config(channel, &mut dev);
75        let voltage_raw = dev.smbus_read_i2c_block_data(config as u8, 2)?;
76        let voltage_adc = ((voltage_raw[0] as u16 & 0x0F) << 8) | (voltage_raw[1] as u16 & 0xFF);
77        let voltage = voltage_adc as f32 * PB_ADC_REF_VOLTAGE / 4096.0;
78
79        Ok(voltage)
80    }
81}