1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use crate::{read::*, AirQualitySensor, Reading, SensorError};
use embedded_hal_nb::{
    nb::block,
    serial::{Error as SerialError, Read},
};

/// A SEN0177 device connected via serial UART
pub struct Sen0177<R, E>
where
    R: Read<u8, Error = E>,
    E: SerialError,
{
    serial_port: R,
}

impl<R, E> Sen0177<R, E>
where
    R: Read<u8, Error = E>,
    E: SerialError,
{
    /// Creates a new sensor instance connected to UART `serial_port`
    pub fn new(serial_port: R) -> Self {
        Self { serial_port }
    }

    fn find_byte(&mut self, byte: u8, attempts: u32) -> Result<bool, SensorError<E>> {
        let mut attempts_left = attempts;
        let mut byte_read = 0u8;
        while byte_read != byte && attempts_left > 0 {
            byte_read = block!(self.serial_port.read())?;
            attempts_left -= 1;
        }
        Ok(byte_read == byte)
    }
}

impl<R, E> AirQualitySensor<E> for Sen0177<R, E>
where
    R: Read<u8, Error = E>,
    E: SerialError,
{
    fn read(&mut self) -> Result<Reading, SensorError<E>> {
        let mut attempts_left = 10;
        let mut byte_read = 0u8;
        while byte_read != MAGIC_BYTE_1
            && attempts_left > 0
            && self.find_byte(MAGIC_BYTE_0, PAYLOAD_LEN as u32 * 4)?
        {
            byte_read = block!(self.serial_port.read())?;
            attempts_left -= 1;
        }

        if byte_read == MAGIC_BYTE_1 {
            let mut buf: [u8; PAYLOAD_LEN] = [0; PAYLOAD_LEN];
            buf[0] = MAGIC_BYTE_0;
            buf[1] = MAGIC_BYTE_1;
            for buf_slot in buf[2..PAYLOAD_LEN].iter_mut() {
                *buf_slot = block!(self.serial_port.read())?;
            }

            parse_data(&buf)
        } else {
            Err(SensorError::BadMagic)
        }
    }
}