1#![no_std]
12
13mod reg;
14use reg::*;
15
16use core::fmt::Debug;
17
18use embedded_hal as hal;
19use hal::blocking::i2c::{Write, WriteRead};
20use cast::f32;
21
22#[derive(Debug)]
23pub enum Error<E> {
24 I2c(E),
26 InvalidData,
28 UnsupportedChip,
30}
31
32#[derive(Copy,Clone,PartialEq)]
36pub enum Mode {
37 Inactive,
38 Active,
39 TakingReading,
40}
41
42#[derive(Copy,Clone,PartialEq)]
46pub enum PressureAlt {
47 Pressure,
48 Altitude,
49}
50
51pub struct MPL3115A2<I2C> {
55 i2c: I2C,
57
58 mode: Mode,
60
61 pa: PressureAlt,
63}
64
65impl<I2C, E> MPL3115A2<I2C>
72where
73 I2C: WriteRead<Error = E> + Write<Error = E>,
74 E: Debug,
75{
76 pub fn new(i2c: I2C, pa: PressureAlt) -> Result<Self, Error<E>> {
78
79 let mut dev = Self {
81 i2c,
82 mode: Mode::Inactive,
83 pa: pa,
84 };
85
86 if dev.get_device_id()? != DEVICE_ID {
88 return Err(Error::UnsupportedChip);
89 }
90
91 dev.write_reg(Register::PT_DATA_CFG,EVENT_FLAGS).map_err(Error::I2c)?;
95
96 dev.change_reading_type(pa)?;
98
99 Ok(dev)
100 }
101
102 pub fn destroy(self) -> I2C {
104 self.i2c
105 }
106
107 pub fn get_device_id(&mut self) -> Result<u8, Error<E>> {
109 self.read_reg(Register::WHO_AM_I).map_err(Error::I2c)
110 }
111
112 pub fn activate(&mut self) -> Result<(), Error<E>> {
114 self.reg_set_bits(Register::CTRL_REG1, DEVICE_EN).map_err(Error::I2c)?;
115 self.mode = Mode::Active;
116 Ok(())
117 }
118
119 pub fn deactivate(&mut self) -> Result<(), Error<E>> {
121 self.reg_reset_bits(Register::CTRL_REG1, DEVICE_EN).map_err(Error::I2c)?;
122 self.mode = Mode::Inactive;
123 Ok(())
124 }
125
126 pub fn change_reading_type(&mut self, pa: PressureAlt) -> Result<(), Error<E>> {
128
129 match pa {
130 PressureAlt::Altitude => {
131 self.reg_set_bits(Register::CTRL_REG1, ALT_EN).map_err(Error::I2c)?;
132 },
133 PressureAlt::Pressure => {
134 self.reg_reset_bits(Register::CTRL_REG1, ALT_EN).map_err(Error::I2c)?;
135 }
136 }
137
138 self.pa = pa;
139 Ok(())
140 }
141
142 pub fn take_one_pa_reading(&mut self) -> Result<f32, Error<E>> {
144 self.start_reading()?;
146
147 while ! self.check_pa_reading()? {
149
150 }
151
152 self.get_pa_reading()
154 }
155
156 pub fn take_one_temp_reading(&mut self) -> Result<f32, Error<E>> {
158 self.start_reading()?;
160
161 while ! self.check_temp_reading()? {
163
164 }
165
166 self.get_temp_reading()
168 }
169
170 pub fn start_reading(&mut self) -> Result<(), Error<E>> {
173
174 self.reg_reset_bits(Register::CTRL_REG1, ONE_SHOT).map_err(Error::I2c)?;
175 self.reg_set_bits(Register::CTRL_REG1, ONE_SHOT).map_err(Error::I2c)?;
176
177 self.mode = Mode::TakingReading;
179 Ok(())
180 }
181
182 pub fn check_pa_reading(&mut self) -> Result<bool, Error<E>> {
184 let status_reg = self.read_reg(Register::STATUS).map_err(Error::I2c)?;
185 Ok(status_reg & PDR != 0)
186 }
187
188 pub fn check_temp_reading(&mut self) -> Result<bool, Error<E>> {
190 let status_reg = self.read_reg(Register::STATUS).map_err(Error::I2c)?;
191
192 Ok(status_reg & TDR != 0)
193 }
194
195 pub fn get_pa_reading(&mut self) -> Result<f32, Error<E>> {
197
198 let mut buf = [0u8; 3];
200 self.read_regs(Register::OUT_P_MSB, &mut buf).map_err(Error::I2c)?;
201
202 self.mode = Mode::Active;
204
205 match self.pa {
210 PressureAlt::Altitude => {
211
212 let lsb = buf[2]>>4;
213 let tempcsb = f32(lsb)/16.0;
214 let int_buf = [buf[0], buf[1]];
215
216 let altitude = f32( i16::from_be_bytes(int_buf)) + tempcsb;
217
218 Ok(altitude)
219 },
220 PressureAlt::Pressure => {
221 let int_buf = [0u8, buf[0], buf[1], buf[2]];
224 let mut pressure_whole: u32 = u32::from_be_bytes(int_buf);
225 pressure_whole >>= 6; buf[2] &= 0b0011_0000; buf[2] >>= 4; let pressure_decimal = f32(buf[2])/4.0; let pressure = f32(pressure_whole) + pressure_decimal;
232
233 Ok(pressure)
234
235 }
236
237 }
238 }
239
240
241 pub fn get_temp_reading(&mut self) -> Result<f32, Error<E>> {
243
244 let mut buf = [0u8; 2];
246 self.read_regs(Register::OUT_T_MSB, &mut buf).map_err(Error::I2c)?;
247
248 self.mode = Mode::Active;
250
251 let mut neg_sign = false;
254
255 if buf[0] > 0x7F
257 {
258 let mut foo = u16::from_be_bytes(buf);
259 foo = !foo + 1; buf = foo.to_be_bytes();
261 buf[1] = buf[1] & 0xF0;
262 neg_sign = true;
263 }
264
265 let templsb = f32(buf[1]>>4)/16.0; let mut temperature = f32(buf[0]) + templsb;
272
273 if neg_sign {
274 temperature = 0.0 - temperature;
275 }
276
277 Ok(temperature)
278 }
279
280
281 pub fn set_oversample_rate(&mut self, mut sample_rate: u8) -> Result<(), Error<E>> {
290 if sample_rate > 7 {
291 sample_rate = 7; }
293 sample_rate <<= 3; let mut temp_setting = self.read_reg(Register::CTRL_REG1).map_err(Error::I2c)?; temp_setting &= 0b1100_0111; temp_setting |= sample_rate; self.write_reg(Register::CTRL_REG1,temp_setting).map_err(Error::I2c)
299 }
300
301 #[inline]
302 fn read_reg(&mut self, reg: Register) -> Result<u8, E> {
303 let mut buf = [0u8];
304 self.i2c.write_read(I2C_SAD, &[reg.addr()], &mut buf)?;
305 Ok(buf[0])
306 }
307
308 #[inline]
309 fn read_regs(&mut self, reg: Register, buffer: &mut [u8]) -> Result<(), E> {
310 self.i2c
311 .write_read(I2C_SAD, &[reg.addr()], buffer)
312 }
313
314 #[inline]
315 fn write_reg(&mut self, reg: Register, val: u8) -> Result<(), E> {
316 self.i2c.write(I2C_SAD, &[reg.addr(), val])
317 }
318
319 #[inline]
320 fn modify_reg<F>(&mut self, reg: Register, f: F) -> Result<(), E>
321 where
322 F: FnOnce(u8) -> u8,
323 {
324 let r = self.read_reg(reg)?;
325 self.write_reg(reg, f(r))?;
326 Ok(())
327 }
328
329 #[inline]
330 fn reg_set_bits(&mut self, reg: Register, bits: u8) -> Result<(), E> {
331 self.modify_reg(reg, |v| v | bits)
332 }
333
334 #[inline]
335 fn reg_reset_bits(&mut self, reg: Register, bits: u8) -> Result<(), E> {
336 self.modify_reg(reg, |v| v & !bits)
337 }
338
339 #[inline]
340 fn reg_xset_bits(&mut self, reg: Register, bits: u8, set: bool) -> Result<(), E> {
341 if set {
342 self.reg_set_bits(reg, bits)
343 } else {
344 self.reg_reset_bits(reg, bits)
345 }
346 }
347}
348
349
350
351