lps22hb/
sensor.rs

1//! Functions related to sensor measurements: reading value or status, setting offset and reference
2//!
3//! TO DO: add reference pressure setting
4
5use super::*;
6
7#[derive(Debug)]
8/// Contents of the STATUS register (pressure and temperature overrun and data availability flags)
9pub struct DataStatus {
10    pub temp_overrun: bool,
11    pub press_overrun: bool,
12    pub temp_available: bool,
13    pub press_available: bool,
14}
15
16impl<T, E> LPS22HB<T>
17where
18    T: Interface<Error = E>,
19{
20    /// Read the device ID ("who am I")
21    pub fn get_device_id(&mut self) -> Result<u8, T::Error> {
22        let mut data = [0u8; 1];
23        self.interface.read(Registers::WHO_AM_I.addr(), &mut data)?;
24        let whoami = data[0];
25        Ok(whoami)
26    }
27
28    /// Raw sensor reading (3 bytes of pressure data and 2 bytes of temperature data)
29    fn read_sensor_raw(&mut self) -> Result<(i32, i32), T::Error> {
30        let mut data = [0u8; 5];
31        self.interface
32            .read(Registers::PRESS_OUT_XL.addr(), &mut data)?;
33        let p: i32 = (data[2] as i32) << 16 | (data[1] as i32) << 8 | (data[0] as i32);
34        let t: i32 = (data[4] as i32) << 8 | (data[3] as i32);
35        Ok((p, t))
36    }
37
38    /// Calculated pressure reading in hPa
39    pub fn read_pressure(&mut self) -> Result<f32, T::Error> {
40        let (p, _t) = self.read_sensor_raw()?;
41        let pressure: f32 = (p as f32) / PRESS_SCALE;
42        Ok(pressure)
43    }
44
45    /// Calculated temperaure reading in degrees Celsius
46    pub fn read_temperature(&mut self) -> Result<f32, T::Error> {
47        let (_p, t) = self.read_sensor_raw()?;
48        let temperature: f32 = (t as f32) / TEMP_SCALE;
49        Ok(temperature)
50    }
51
52    /// Calculated reference pressure reading in hPa
53    pub fn read_reference_pressure(&mut self) -> Result<f32, T::Error> {
54        let mut data = [0u8; 3];
55        self.interface.read(Registers::REF_P_XL.addr(), &mut data)?;
56        let p: i32 = (data[2] as i32) << 16 | (data[1] as i32) << 8 | (data[0] as i32);
57        let pressure: f32 = (p as f32) / PRESS_SCALE;
58        Ok(pressure)
59    }
60
61    /// Read pressure offset value, 16-bit data that can be used to implement One-Point Calibration (OPC) after soldering.
62    pub fn read_pressure_offset(&mut self) -> Result<i16, T::Error> {
63        let mut data = [0u8; 2];
64        self.interface.read(Registers::RPDS_L.addr(), &mut data)?;
65        let o: i16 = (data[1] as i16) << 8 | (data[0] as i16);
66        Ok(o)
67    }
68
69    /// Set the pressure offset value (VALUE IN hPA!)
70    pub fn set_pressure_offset(&mut self, offset: u16) -> Result<(), T::Error> {
71        let mut payload = [0u8; 2];
72        let offset = offset * 16;
73
74        payload[0] = (offset & 0xff) as u8; // lower byte
75        payload[1] = (offset >> 8) as u8; // upper byte
76
77        self.interface.write(Registers::RPDS_L.addr(), payload[0])?;
78        self.interface.write(Registers::RPDS_H.addr(), payload[1])?;
79
80        Ok(())
81    }
82
83    /// Get all the flags from the STATUS_REG register
84    pub fn get_data_status(&mut self) -> Result<DataStatus, T::Error> {
85        let status = DataStatus {
86            /// Has new temperature data overwritten the previous one?
87            temp_overrun: self.is_register_bit_flag_high(Registers::STATUS, Bitmasks::T_OR)?,
88            /// Has new pressure data overwritten the previous one?
89            press_overrun: self.is_register_bit_flag_high(Registers::STATUS, Bitmasks::P_OR)?,
90            /// Is new temperature data available?
91            temp_available: self.is_register_bit_flag_high(Registers::STATUS, Bitmasks::T_DA)?,
92            /// Is new pressure data available?            
93            press_available: self.is_register_bit_flag_high(Registers::STATUS, Bitmasks::P_DA)?,
94        };
95        Ok(status)
96    }
97
98    /// Triggers the one-shot mode, and a new acquisition starts when it is required.
99    /// Enabling this mode is possible only if the device was previously in power-down mode.
100    /// Once the acquisition is completed and the output registers updated,
101    /// the device automatically enters in power-down mode. ONE_SHOT bit self-clears itself.
102    pub fn one_shot(&mut self) -> Result<(), T::Error> {
103        self.set_datarate(ODR::PowerDown)?; // make sure that Power down/one shot mode is enabled
104        self.set_register_bit_flag(Registers::CTRL_REG2, Bitmasks::ONE_SHOT)?;
105        Ok(())
106    }
107
108    // --- THESE FUNCTIONS CAN BE REMOVED ---
109
110    /*
111
112    /// Has new pressure data overwritten the previous one?
113    pub fn pressure_data_overrun(&mut self) -> Result<bool, T::Error> {
114        self.is_register_bit_flag_high(Registers::STATUS, Bitmasks::P_OR)
115    }
116
117    /// Has new temperature data overwritten the previous one?
118    pub fn temperature_data_overrun(&mut self) -> Result<bool, T::Error> {
119        self.is_register_bit_flag_high(Registers::STATUS, Bitmasks::T_OR)
120    }
121
122    /// Is new pressure data available?
123    pub fn pressure_data_available(&mut self) -> Result<bool, T::Error> {
124        self.is_register_bit_flag_high(Registers::STATUS, Bitmasks::P_DA)
125    }
126
127    /// Is new temperature data available?
128    pub fn temperature_data_available(&mut self) -> Result<bool, T::Error> {
129        self.is_register_bit_flag_high(Registers::STATUS, Bitmasks::T_DA)
130    }
131
132     */
133}