bmp280_core/
bus.rs

1use core::convert::Infallible;
2
3use embedded_hal::blocking::delay::DelayUs;
4use embedded_hal::blocking::i2c;
5use embedded_hal::blocking::spi;
6use embedded_hal::digital::v2::OutputPin;
7
8use super::registers::Register;
9
10pub trait Bus {
11    type Error;
12    fn write(&mut self, reg: Register, value: u8) -> Result<(), Self::Error>;
13    fn read(&mut self, reg: Register) -> Result<u8, Self::Error>;
14    fn reads(&mut self, reg: Register, output: &mut [u8]) -> Result<(), Self::Error>;
15}
16
17#[derive(Debug)]
18pub enum SpiError<WE, TE, OE> {
19    WriteError(WE),
20    TransferError(TE),
21    OutputPinError(OE),
22}
23
24pub struct DummyOutputPin {}
25
26impl OutputPin for DummyOutputPin {
27    type Error = Infallible;
28    fn set_high(&mut self) -> Result<(), Infallible> {
29        Ok(())
30    }
31
32    fn set_low(&mut self) -> Result<(), Infallible> {
33        Ok(())
34    }
35}
36
37pub struct SpiBus<SPI, CS, D> {
38    spi: SPI,
39    cs: CS,
40    delay: D,
41}
42
43impl<SPI, CS, D> SpiBus<SPI, CS, D>
44where
45    SPI: spi::Transfer<u8> + spi::Write<u8>,
46    CS: OutputPin,
47    D: DelayUs<u8>,
48{
49    pub fn new(spi: SPI, cs: CS, delay: D) -> Self {
50        Self { spi, cs, delay }
51    }
52
53    pub fn free(self) -> (SPI, CS, D) {
54        (self.spi, self.cs, self.delay)
55    }
56}
57
58impl<WE, TE, OE, SPI, CS, D> SpiBus<SPI, CS, D>
59where
60    SPI: spi::Transfer<u8, Error = TE> + spi::Write<u8, Error = WE>,
61    CS: OutputPin<Error = OE>,
62{
63    fn chip_select(&mut self, select: bool) -> Result<(), SpiError<WE, TE, OE>> {
64        if select { self.cs.set_low() } else { self.cs.set_high() }
65            .map_err(|e| SpiError::OutputPinError(e))
66    }
67}
68
69impl<WE, TE, OE, SPI, CS, D> Bus for SpiBus<SPI, CS, D>
70where
71    SPI: spi::Transfer<u8, Error = TE> + spi::Write<u8, Error = WE>,
72    CS: OutputPin<Error = OE>,
73    D: DelayUs<u8>,
74{
75    type Error = SpiError<WE, TE, OE>;
76
77    fn write(&mut self, reg: Register, value: u8) -> Result<(), Self::Error> {
78        self.chip_select(true)?;
79        let result = self.spi.write(&[reg as u8 & 0x7F, value]);
80        self.chip_select(false)?;
81        self.delay.delay_us(1);
82        result.map_err(|e| SpiError::WriteError(e))
83    }
84
85    fn read(&mut self, reg: Register) -> Result<u8, Self::Error> {
86        let mut value = [0u8];
87        self.chip_select(true)?;
88        self.spi.write(&[reg as u8 | 0x80]).map_err(|e| SpiError::WriteError(e))?;
89        self.spi.transfer(&mut value).map_err(|e| SpiError::TransferError(e))?;
90        self.chip_select(false)?;
91        Ok(value[0])
92    }
93
94    fn reads(&mut self, reg: Register, output: &mut [u8]) -> Result<(), Self::Error> {
95        self.chip_select(true)?;
96        self.spi.write(&[reg as u8 | 0x80]).map_err(|e| SpiError::WriteError(e))?;
97        self.spi.transfer(output).map_err(|e| SpiError::TransferError(e))?;
98        self.chip_select(false)?;
99        Ok(())
100    }
101}
102
103#[derive(Debug)]
104pub enum I2cError<WE, RE> {
105    WriteError(WE),
106    ReadError(RE),
107}
108
109pub struct I2cBus<I2C> {
110    i2c: I2C,
111    addr: I2cAddress,
112}
113
114#[derive(Copy, Clone)]
115pub enum I2cAddress {
116    SdoToGnd = 0x76,
117    SdoToInterfaceSupplyVoltage = 0x77,
118}
119
120impl<I2C> I2cBus<I2C> {
121    pub fn new(i2c: I2C, addr: I2cAddress) -> Self {
122        Self { i2c, addr }
123    }
124
125    pub fn free(self) -> I2C {
126        return self.i2c;
127    }
128}
129
130impl<I2C, WE, RE> Bus for I2cBus<I2C>
131where
132    I2C: i2c::WriteRead<Error = RE> + i2c::Write<Error = WE>,
133{
134    type Error = I2cError<WE, RE>;
135
136    fn write(&mut self, reg: Register, value: u8) -> Result<(), Self::Error> {
137        let result = self.i2c.write(self.addr as u8, &[reg as u8, value]);
138        result.map_err(|e| I2cError::WriteError(e))
139    }
140
141    fn read(&mut self, reg: Register) -> Result<u8, Self::Error> {
142        let mut value = [0u8];
143        self.i2c
144            .write_read(self.addr as u8, &[reg as u8], &mut value)
145            .map_err(|e| I2cError::ReadError(e))?;
146        Ok(value[0])
147    }
148
149    fn reads(&mut self, reg: Register, output: &mut [u8]) -> Result<(), Self::Error> {
150        self.i2c.write_read(self.addr as u8, &[reg as u8], output).map_err(|e| I2cError::ReadError(e))?;
151        Ok(())
152    }
153}