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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use embedded_hal as hal;
use hal::digital::v2::OutputPin;
use super::SensorInterface;
use crate::Error;
pub struct SpiInterface<SPI, CSN> {
spi: SPI,
csn: CSN,
use_sloppy_reads: bool,
}
impl<SPI, CSN, CommE, PinE> SpiInterface<SPI, CSN>
where
SPI: hal::blocking::spi::Write<u8, Error = CommE>
+ hal::blocking::spi::Transfer<u8, Error = CommE>,
CSN: OutputPin<Error = PinE>,
{
const DIR_READ: u8 = 0x80;
pub fn new(spi: SPI, csn: CSN, use_sloppy_reads: bool) -> Self {
let mut inst = Self { spi, csn, use_sloppy_reads };
let _ = inst.csn.set_low();
let _ = inst.csn.set_high();
inst
}
fn transfer_block(&mut self, block: &mut [u8]) -> Result<(), Error<CommE, PinE>> {
let _ = self.csn.set_low();
let rc = self.spi.transfer(block);
let _ = self.csn.set_high();
let _ = rc.map_err(Error::Comm)?;
Ok(())
}
}
impl<SPI, CSN, CommE, PinE> SensorInterface for SpiInterface<SPI, CSN>
where
SPI: hal::blocking::spi::Write<u8, Error = CommE>
+ hal::blocking::spi::Transfer<u8, Error = CommE>,
CSN: OutputPin<Error = PinE>,
{
type InterfaceError = Error<CommE, PinE>;
fn register_read(&mut self, reg: u8) -> Result<u8, Self::InterfaceError> {
const DIR_READ: u8 = 0x80;
if self.use_sloppy_reads {
let mut cmd: [u8; 3] = [reg | DIR_READ, 0, 0];
self.transfer_block(&mut cmd)?;
Ok(cmd[2])
}
else {
let mut cmd: [u8; 2] = [reg | DIR_READ, 0];
self.transfer_block(&mut cmd)?;
Ok(cmd[1])
}
}
fn register_write(&mut self, reg: u8, val: u8) -> Result<(), Self::InterfaceError> {
let mut cmd: [u8; 2] = [reg, val];
self.transfer_block(&mut cmd)?;
Ok(())
}
fn read_vec3_i16(&mut self, reg: u8) -> Result<[i16; 3], Self::InterfaceError> {
let mut resp: [u8; 6] = [0; 6];
if self.use_sloppy_reads {
let mut block: [u8; 8] = [0; 8];
block[0] = reg | Self::DIR_READ;
self.transfer_block(&mut block)?;
resp.copy_from_slice(&block[2..8]);
}
else {
let mut block: [u8; 7] = [0; 7];
block[0] = reg | Self::DIR_READ;
self.transfer_block(&mut block)?;
resp.copy_from_slice(&block[1..7]);
};
Ok([
(resp[1] as i16) << 8 | (resp[0] as i16),
(resp[3] as i16) << 8 | (resp[2] as i16),
(resp[5] as i16) << 8 | (resp[4] as i16),
])
}
}