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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// use eh1::spi::{SpiBusRead, SpiBusWrite};

// #[cfg(feature = "async")]
// use eha0a::spi::{SpiBusRead as SpiBusReadAsync, SpiBusWrite as SpiBusWriteAsync};

/// BME280 bus.
#[derive(Debug)]
pub struct Bme280Bus<SPI> {
    spi: SPI,
}

/// SPI mode for the BME280.
///
/// The BME280 also supports mode 3.
pub const MODE: eh1::spi::Mode = eh1::spi::MODE_0;

impl<SPI> Bme280Bus<SPI> {
    /// Creates a new `Bme280Bus` from a SPI peripheral and a chip select
    /// digital I/O pin.
    ///
    /// # Safety
    ///
    /// The chip select pin must be high before being passed to this function.
    ///
    /// # Example
    ///
    /// ```
    /// # let spi = ehm::eh1::spi::Mock::new(&[]);
    /// use bme280_multibus::spi1::Bme280Bus;
    ///
    /// let mut bme: Bme280Bus<_> = Bme280Bus::new(spi);
    /// # bme.free().done();
    /// # Ok::<(), ehm::eh1::MockError>(())
    /// ```
    #[inline]
    #[allow(clippy::unnecessary_safety_doc)]
    pub fn new(spi: SPI) -> Self {
        Bme280Bus { spi }
    }

    /// Free the SPI bus and CS pin from the BME280.
    ///
    /// # Example
    ///
    /// ```
    /// # let spi = ehm::eh1::spi::Mock::new(&[]);
    /// use bme280_multibus::spi1::Bme280Bus;
    ///
    /// let mut bme: Bme280Bus<_> = Bme280Bus::new(spi);
    /// let mut spi = bme.free();
    /// # spi.done();
    /// # Ok::<(), ehm::eh1::MockError>(())
    /// ```
    #[inline]
    pub fn free(self) -> SPI {
        self.spi
    }
}

impl<SPI> crate::Bme280Bus for Bme280Bus<SPI>
where
    SPI: eh1::spi::SpiDevice,
{
    type Error = SPI::Error;

    fn read_regs(&mut self, reg: u8, buf: &mut [u8]) -> Result<(), Self::Error> {
        let a = &[reg | (1 << 7)];
        let mut ops = [
            eh1::spi::Operation::Write(a),
            eh1::spi::Operation::Read(buf),
        ];
        self.spi.transaction(&mut ops)
    }

    fn write_reg(&mut self, reg: u8, data: u8) -> Result<(), Self::Error> {
        let buf = &[reg & !(1 << 7), data];
        let mut ops = [eh1::spi::Operation::Write(buf)];
        self.spi.transaction(&mut ops)
    }
}

#[cfg(feature = "async")]
impl<SPI> crate::Bme280BusAsync for Bme280Bus<SPI>
where
    SPI: eha0a::spi::SpiDevice,
{
    type Error = SPI::Error;

    async fn read_regs(&mut self, reg: u8, buf: &mut [u8]) -> Result<(), Self::Error> {
        let a = &[reg | (1 << 7)];
        let mut ops = [
            eh1::spi::Operation::Write(a),
            eh1::spi::Operation::Read(buf),
        ];
        self.spi.transaction(&mut ops).await
    }

    async fn write_reg(&mut self, reg: u8, data: u8) -> Result<(), Self::Error> {
        let buf = &[reg & !(1 << 7), data];
        let mut ops = [eh1::spi::Operation::Write(buf)];
        self.spi.transaction(&mut ops).await
    }
}