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
use core::convert::Infallible;

use embedded_hal::blocking::spi;
use embedded_hal::digital::v2::OutputPin;

use super::registers::Register;

pub trait Bus {
    type Error;
    fn write(&mut self, reg: Register, value: u8) -> Result<(), Self::Error>;
    fn read(&mut self, reg: Register) -> Result<u8, Self::Error>;
    fn reads(&mut self, reg: Register, output: &mut [u8]) -> Result<(), Self::Error>;
}

#[derive(Debug)]
pub enum SpiError<WE, TE, OE> {
    WriteError(WE),
    TransferError(TE),
    OutputPinError(OE),
}

pub trait DelayNs<T> {
    fn delay_ns(&mut self, ns: T);
}

pub struct DummyOutputPin {}

impl OutputPin for DummyOutputPin {
    type Error = Infallible;
    fn set_high(&mut self) -> Result<(), Infallible> {
        Ok(())
    }

    fn set_low(&mut self) -> Result<(), Infallible> {
        Ok(())
    }
}

pub struct SpiBus<'a, SPI, CS, D> {
    spi: SPI,
    cs: &'a mut CS,
    delay: D,
}

impl<'a, SPI, CS, D> SpiBus<'a, SPI, CS, D>
where
    SPI: spi::Transfer<u8> + spi::Write<u8>,
    CS: OutputPin,
    D: DelayNs<u16>,
{
    pub fn new(spi: SPI, cs: &'a mut CS, delay: D) -> Self {
        Self { spi, cs, delay }
    }
}

impl<'a, WE, TE, OE, SPI, CS, D> SpiBus<'a, SPI, CS, D>
where
    SPI: spi::Transfer<u8, Error = TE> + spi::Write<u8, Error = WE>,
    CS: OutputPin<Error = OE>,
{
    fn chip_select(&mut self, select: bool) -> Result<(), SpiError<WE, TE, OE>> {
        if select { self.cs.set_low() } else { self.cs.set_high() }
            .map_err(|e| SpiError::OutputPinError(e))
    }
}

impl<'a, WE, TE, OE, SPI, CS, D> Bus for SpiBus<'a, SPI, CS, D>
where
    SPI: spi::Transfer<u8, Error = TE> + spi::Write<u8, Error = WE>,
    CS: OutputPin<Error = OE>,
    D: DelayNs<u16>,
{
    type Error = SpiError<WE, TE, OE>;

    fn write(&mut self, reg: Register, value: u8) -> Result<(), Self::Error> {
        self.chip_select(true)?;
        let result = self.spi.write(&[reg as u8 & 0x7F, value]);
        self.chip_select(false)?;
        self.delay.delay_ns(1000);
        result.map_err(|e| SpiError::WriteError(e))
    }

    fn read(&mut self, reg: Register) -> Result<u8, Self::Error> {
        let mut value = [0u8];
        self.chip_select(true)?;
        self.spi.write(&[reg as u8 | 0x80]).map_err(|e| SpiError::WriteError(e))?;
        self.spi.transfer(&mut value).map_err(|e| SpiError::TransferError(e))?;
        self.chip_select(false)?;
        Ok(value[0])
    }

    fn reads(&mut self, reg: Register, output: &mut [u8]) -> Result<(), Self::Error> {
        self.chip_select(true)?;
        self.spi.write(&[reg as u8 | 0x80]).map_err(|e| SpiError::WriteError(e))?;
        self.spi.transfer(output).map_err(|e| SpiError::TransferError(e))?;
        self.chip_select(false)?;
        Ok(())
    }
}