1use crate::{hal::blocking::i2c::Read, Error, IaqCore, Measurement};
2use nb;
3
4const DEV_ADDR: u8 = 0x5A;
5
6impl<E, I2C> IaqCore<I2C>
7where
8 I2C: Read<Error = E>,
9{
10 pub fn new(i2c: I2C) -> Self {
12 IaqCore { i2c }
13 }
14
15 pub fn destroy(self) -> I2C {
17 self.i2c
18 }
19
20 pub fn data(&mut self) -> nb::Result<Measurement, Error<E>> {
24 let mut data = [0; 9];
25 self.read(&mut data)?;
26 Ok(Measurement {
27 co2: (u16::from(data[0]) << 8) | u16::from(data[1]),
28 tvoc: (u16::from(data[7]) << 8) | u16::from(data[8]),
29 resistance: (u32::from(data[4]) << 16) | (u32::from(data[5]) << 8) | u32::from(data[6]),
30 })
31 }
32
33 pub fn co2(&mut self) -> nb::Result<u16, Error<E>> {
37 let mut data = [0; 3];
38 self.read(&mut data)?;
39 Ok((u16::from(data[0]) << 8) | u16::from(data[1]))
40 }
41
42 pub fn tvoc(&mut self) -> nb::Result<u16, Error<E>> {
46 let mut data = [0; 9];
47 self.read(&mut data)?;
48 Ok((u16::from(data[7]) << 8) | u16::from(data[8]))
49 }
50
51 pub fn resistance(&mut self) -> nb::Result<u32, Error<E>> {
55 let mut data = [0; 7];
56 self.read(&mut data)?;
57 Ok((u32::from(data[4]) << 16) | (u32::from(data[5]) << 8) | u32::from(data[6]))
58 }
59
60 fn read(&mut self, data: &mut [u8]) -> nb::Result<(), Error<E>> {
61 self.i2c.read(DEV_ADDR, data).map_err(Error::I2C)?;
62 Self::check_status(data[2])
63 }
64
65 fn check_status(status: u8) -> nb::Result<(), Error<E>> {
66 if status == 0x80 {
67 Err(nb::Error::Other(Error::Device))
68 } else if status == 0 {
69 Ok(())
70 } else {
71 Err(nb::Error::WouldBlock)
73 }
74 }
75}