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
//! SPI Interface
//!
//! TO DO: COMPLETE THIS (CURRENTLY JUST A COPY-PASTE FROM ANOTHER CRATE)
//!
use Interface;
use ;
/*
/// R/W bit should be high for SPI Read operation
const SPI_READ: u8 = 0x80;
/// Magnetometer MS bit. When 0, does not increment the address; when 1, increments the address in multiple reads. (Refer to page 34)
const MS_BIT: u8 = 0x40;
/// Errors in this crate
#[derive(Debug)]
pub enum Error<CommE, PinE> {
/// Communication error
Comm(CommE),
/// Pin setting error
Pin(PinE),
}
/// This combines the SPI Interface and chip select pins
pub struct SpiInterface<SPI, AG, M> {
spi: SPI,
ag_cs: AG,
m_cs: M,
}
impl<SPI, AG, M, CommE, PinE> SpiInterface<SPI, AG, M>
where
SPI: Transfer<u8, Error = CommE> + Write<u8, Error = CommE>,
AG: OutputPin<Error = PinE>,
M: OutputPin<Error = PinE>,
{
/// Initializes an Interface with `SPI` instance and AG and M chip select `OutputPin`s
/// # Arguments
/// * `spi` - SPI instance
/// * `ag_cs` - Chip Select pin for Accelerometer/Gyroscope
/// * `m_cs` - Chip Select pin for Magnetometer
pub fn init(spi: SPI, ag_cs: AG, m_cs: M) -> Self {
Self { spi, ag_cs, m_cs }
}
}
/// Implementation of `Interface`
impl<SPI, AG, M, CommE, PinE> Interface for SpiInterface<SPI, AG, M>
where
SPI: Transfer<u8, Error = CommE> + Write<u8, Error = CommE>,
AG: OutputPin<Error = PinE>,
M: OutputPin<Error = PinE>,
{
type Error = Error<CommE, PinE>;
fn write(&mut self, sensor: Sensor, addr: u8, value: u8) -> Result<(), Self::Error> {
let bytes = [addr, value];
match sensor {
Accelerometer | Gyro | Temperature => {
self.ag_cs.set_low().map_err(Error::Pin)?;
self.spi.write(&bytes).map_err(Error::Comm)?;
self.ag_cs.set_high().map_err(Error::Pin)?;
}
Magnetometer => {
self.m_cs.set_low().map_err(Error::Pin)?;
self.spi.write(&bytes).map_err(Error::Comm)?;
self.m_cs.set_high().map_err(Error::Pin)?;
}
}
Ok(())
}
fn read(&mut self, sensor: Sensor, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
match sensor {
Accelerometer | Gyro | Temperature => {
self.ag_cs.set_low().map_err(Error::Pin)?;
self.spi.write(&[SPI_READ | addr]).map_err(Error::Comm)?;
self.spi.transfer(buffer).map_err(Error::Comm)?;
self.ag_cs.set_high().map_err(Error::Pin)?;
}
Magnetometer => {
self.m_cs.set_low().map_err(Error::Pin)?;
self.spi
.write(&[SPI_READ | MS_BIT | addr])
.map_err(Error::Comm)?;
self.spi.transfer(buffer).map_err(Error::Comm)?;
self.m_cs.set_high().map_err(Error::Pin)?;
}
}
Ok(())
}
}
*/