@@ -8,20 +8,25 @@ use std::io;
8
8
use std:: ops;
9
9
use std:: path:: Path ;
10
10
11
+ use crate :: Delay ;
12
+ use spidev:: SpidevTransfer ;
13
+
11
14
/// Newtype around [`spidev::Spidev`] that implements the `embedded-hal` traits
12
15
///
13
- /// [`spidev::Spidev`]: https://docs.rs/spidev/0.5.0 /spidev/struct.Spidev.html
14
- pub struct Spidev ( pub spidev:: Spidev ) ;
16
+ /// [`spidev::Spidev`]: https://docs.rs/spidev/0.5.spidev /spidev/struct.Spidev.html
17
+ pub struct Spidev ( pub spidev:: Spidev , Delay ) ;
15
18
16
19
impl Spidev {
17
20
/// See [`spidev::Spidev::open`][0] for details.
18
21
///
19
- /// [0]: https://docs.rs/spidev/0.5.0 /spidev/struct.Spidev.html#method.open
22
+ /// [0]: https://docs.rs/spidev/0.5.spidev /spidev/struct.Spidev.html#method.open
20
23
pub fn open < P > ( path : P ) -> Result < Self , SPIError >
21
24
where
22
25
P : AsRef < Path > ,
23
26
{
24
- spidev:: Spidev :: open ( path) . map ( Spidev ) . map_err ( |e| e. into ( ) )
27
+ spidev:: Spidev :: open ( path)
28
+ . map ( |spidev| Spidev ( spidev, Delay { } ) )
29
+ . map_err ( |e| e. into ( ) )
25
30
}
26
31
}
27
32
@@ -41,37 +46,25 @@ impl ops::DerefMut for Spidev {
41
46
42
47
mod embedded_hal_impl {
43
48
use super :: * ;
49
+ use embedded_hal:: delay:: DelayUs ;
44
50
use embedded_hal:: spi:: ErrorType ;
45
- use embedded_hal:: spi:: {
46
- Operation as SpiOperation , SpiBus , SpiBusFlush , SpiBusRead , SpiBusWrite , SpiDevice ,
47
- SpiDeviceRead , SpiDeviceWrite ,
48
- } ;
51
+ use embedded_hal:: spi:: { Operation as SpiOperation , SpiBus , SpiDevice } ;
49
52
use spidev:: SpidevTransfer ;
50
53
use std:: io:: { Read , Write } ;
51
54
52
55
impl ErrorType for Spidev {
53
56
type Error = SPIError ;
54
57
}
55
58
56
- impl SpiBusFlush for Spidev {
57
- fn flush ( & mut self ) -> Result < ( ) , Self :: Error > {
58
- self . 0 . flush ( ) . map_err ( |err| SPIError { err } )
59
- }
60
- }
61
-
62
- impl SpiBusRead < u8 > for Spidev {
59
+ impl SpiBus < u8 > for Spidev {
63
60
fn read ( & mut self , words : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
64
61
self . 0 . read_exact ( words) . map_err ( |err| SPIError { err } )
65
62
}
66
- }
67
63
68
- impl SpiBusWrite < u8 > for Spidev {
69
64
fn write ( & mut self , words : & [ u8 ] ) -> Result < ( ) , Self :: Error > {
70
65
self . 0 . write_all ( words) . map_err ( |err| SPIError { err } )
71
66
}
72
- }
73
67
74
- impl SpiBus < u8 > for Spidev {
75
68
fn transfer ( & mut self , read : & mut [ u8 ] , write : & [ u8 ] ) -> Result < ( ) , Self :: Error > {
76
69
self . 0
77
70
. transfer ( & mut SpidevTransfer :: read_write ( write, read) )
@@ -84,33 +77,9 @@ mod embedded_hal_impl {
84
77
. transfer ( & mut SpidevTransfer :: read_write ( & tx, words) )
85
78
. map_err ( |err| SPIError { err } )
86
79
}
87
- }
88
-
89
- impl SpiDeviceRead for Spidev {
90
- fn read_transaction ( & mut self , operations : & mut [ & mut [ u8 ] ] ) -> Result < ( ) , Self :: Error > {
91
- let mut transfers: Vec < _ > = operations
92
- . iter_mut ( )
93
- . map ( |op| SpidevTransfer :: read ( op) )
94
- . collect ( ) ;
95
- self . 0
96
- . transfer_multiple ( & mut transfers)
97
- . map_err ( |err| SPIError { err } ) ?;
98
- self . flush ( ) ?;
99
- Ok ( ( ) )
100
- }
101
- }
102
80
103
- impl SpiDeviceWrite for Spidev {
104
- fn write_transaction ( & mut self , operations : & [ & [ u8 ] ] ) -> Result < ( ) , Self :: Error > {
105
- let mut transfers: Vec < _ > = operations
106
- . iter ( )
107
- . map ( |op| SpidevTransfer :: write ( op) )
108
- . collect ( ) ;
109
- self . 0
110
- . transfer_multiple ( & mut transfers)
111
- . map_err ( |err| SPIError { err } ) ?;
112
- self . flush ( ) ?;
113
- Ok ( ( ) )
81
+ fn flush ( & mut self ) -> Result < ( ) , Self :: Error > {
82
+ self . 0 . flush ( ) . map_err ( |err| SPIError { err } )
114
83
}
115
84
}
116
85
@@ -119,30 +88,62 @@ mod embedded_hal_impl {
119
88
& mut self ,
120
89
operations : & mut [ SpiOperation < ' _ , u8 > ] ,
121
90
) -> Result < ( ) , Self :: Error > {
122
- let mut transfers: Vec < _ > = operations
123
- . iter_mut ( )
124
- . map ( |op| match op {
125
- SpiOperation :: Read ( buf) => SpidevTransfer :: read ( buf) ,
126
- SpiOperation :: Write ( buf) => SpidevTransfer :: write ( buf) ,
127
- SpiOperation :: Transfer ( read, write) => SpidevTransfer :: read_write ( write, read) ,
91
+ let mut spidev_ops: Vec < Operation > = vec ! [ ] ;
92
+ let mut spidev_transfers: Vec < SpidevTransfer > = vec ! [ ] ;
93
+
94
+ for op in operations {
95
+ match op {
96
+ SpiOperation :: Read ( buf) => spidev_transfers. push ( SpidevTransfer :: read ( buf) ) ,
97
+ SpiOperation :: Write ( buf) => spidev_transfers. push ( SpidevTransfer :: write ( buf) ) ,
98
+ SpiOperation :: Transfer ( read, write) => {
99
+ spidev_transfers. push ( SpidevTransfer :: read_write ( write, read) )
100
+ }
128
101
SpiOperation :: TransferInPlace ( buf) => {
129
102
let tx = unsafe {
130
103
let p = buf. as_ptr ( ) ;
131
104
std:: slice:: from_raw_parts ( p, buf. len ( ) )
132
105
} ;
133
- SpidevTransfer :: read_write ( tx, buf)
106
+ spidev_transfers . push ( SpidevTransfer :: read_write ( tx, buf) )
134
107
}
135
- } )
136
- . collect ( ) ;
137
- self . 0
138
- . transfer_multiple ( & mut transfers)
139
- . map_err ( |err| SPIError { err } ) ?;
140
- self . flush ( ) ?;
108
+ SpiOperation :: DelayUs ( us) => {
109
+ if !spidev_transfers. is_empty ( ) {
110
+ let mut transfers: Vec < SpidevTransfer > = vec ! [ ] ;
111
+ std:: mem:: swap ( & mut transfers, & mut spidev_transfers) ;
112
+ spidev_ops. push ( Operation :: Transfers ( transfers) ) ;
113
+ }
114
+ spidev_ops. push ( Operation :: Delay ( us. to_owned ( ) ) ) ;
115
+ }
116
+ }
117
+ }
118
+
119
+ if !spidev_transfers. is_empty ( ) {
120
+ spidev_ops. push ( Operation :: Transfers ( spidev_transfers) ) ;
121
+ }
122
+
123
+ for op in spidev_ops {
124
+ match op {
125
+ Operation :: Transfers ( mut transfers) => {
126
+ self . 0
127
+ . transfer_multiple ( & mut transfers)
128
+ . map_err ( |err| SPIError { err } ) ?;
129
+ self . flush ( ) ?;
130
+ }
131
+ Operation :: Delay ( us) => {
132
+ self . 1 . delay_us ( us) ;
133
+ }
134
+ }
135
+ }
136
+
141
137
Ok ( ( ) )
142
138
}
143
139
}
144
140
}
145
141
142
+ enum Operation < ' a , ' b > {
143
+ Transfers ( Vec < SpidevTransfer < ' a , ' b > > ) ,
144
+ Delay ( u32 ) ,
145
+ }
146
+
146
147
/// Error type wrapping [io::Error](io::Error) to implement [embedded_hal::spi::ErrorKind]
147
148
#[ derive( Debug ) ]
148
149
pub struct SPIError {
@@ -163,6 +164,7 @@ impl From<io::Error> for SPIError {
163
164
}
164
165
165
166
impl embedded_hal:: spi:: Error for SPIError {
167
+ #[ allow( clippy:: match_single_binding) ]
166
168
fn kind ( & self ) -> embedded_hal:: spi:: ErrorKind {
167
169
use embedded_hal:: spi:: ErrorKind ;
168
170
// TODO: match any errors here if we can find any that are relevant
0 commit comments