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
118
119
120
121
122
123
124
125
126
use std::io;
use std::ops;
use std::path::Path;
pub struct Spidev(pub spidev::Spidev);
impl Spidev {
pub fn open<P>(path: P) -> Result<Self, SPIError>
where
P: AsRef<Path>,
{
spidev::Spidev::open(path).map(Spidev).map_err(|e| e.into())
}
}
impl ops::Deref for Spidev {
type Target = spidev::Spidev;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl ops::DerefMut for Spidev {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
mod embedded_hal_impl {
use super::*;
use embedded_hal::spi::blocking::{SpiBus, SpiBusFlush, SpiBusRead, SpiBusWrite, SpiDevice};
use embedded_hal::spi::ErrorType;
use spidev::SpidevTransfer;
use std::io::{Read, Write};
impl ErrorType for Spidev {
type Error = SPIError;
}
impl SpiBusFlush for Spidev {
fn flush(&mut self) -> Result<(), Self::Error> {
self.0.flush().map_err(|err| SPIError { err })
}
}
impl SpiBusRead<u8> for Spidev {
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
self.0.read_exact(words).map_err(|err| SPIError { err })
}
}
impl SpiBusWrite<u8> for Spidev {
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
self.0.write_all(words).map_err(|err| SPIError { err })
}
}
impl SpiBus<u8> for Spidev {
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
self.0
.transfer(&mut SpidevTransfer::read_write(write, read))
.map_err(|err| SPIError { err })
}
fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
let tx = words.to_owned();
self.0
.transfer(&mut SpidevTransfer::read_write(&tx, words))
.map_err(|err| SPIError { err })
}
}
impl SpiDevice for Spidev {
type Bus = Spidev;
fn transaction<R>(
&mut self,
f: impl FnOnce(&mut Self::Bus) -> Result<R, <Self::Bus as ErrorType>::Error>,
) -> Result<R, Self::Error> {
let result = f(self)?;
self.flush()?;
Ok(result)
}
}
}
#[derive(Debug)]
pub struct SPIError {
err: io::Error,
}
impl SPIError {
pub fn inner(&self) -> &io::Error {
&self.err
}
}
impl From<io::Error> for SPIError {
fn from(err: io::Error) -> Self {
Self { err }
}
}
impl embedded_hal::spi::Error for SPIError {
fn kind(&self) -> embedded_hal::spi::ErrorKind {
use embedded_hal::spi::ErrorKind;
match self.err.kind() {
_ => ErrorKind::Other,
}
}
}