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}