@@ -8,20 +8,25 @@ use std::io;
88use std:: ops;
99use std:: path:: Path ;
1010
11+ use crate :: Delay ;
12+ use spidev:: SpidevTransfer ;
13+
1114/// Newtype around [`spidev::Spidev`] that implements the `embedded-hal` traits
1215///
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 ) ;
1518
1619impl Spidev {
1720 /// See [`spidev::Spidev::open`][0] for details.
1821 ///
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
2023 pub fn open < P > ( path : P ) -> Result < Self , SPIError >
2124 where
2225 P : AsRef < Path > ,
2326 {
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 ( ) )
2530 }
2631}
2732
@@ -41,37 +46,25 @@ impl ops::DerefMut for Spidev {
4146
4247mod embedded_hal_impl {
4348 use super :: * ;
49+ use embedded_hal:: delay:: DelayUs ;
4450 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 } ;
4952 use spidev:: SpidevTransfer ;
5053 use std:: io:: { Read , Write } ;
5154
5255 impl ErrorType for Spidev {
5356 type Error = SPIError ;
5457 }
5558
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 {
6360 fn read ( & mut self , words : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
6461 self . 0 . read_exact ( words) . map_err ( |err| SPIError { err } )
6562 }
66- }
6763
68- impl SpiBusWrite < u8 > for Spidev {
6964 fn write ( & mut self , words : & [ u8 ] ) -> Result < ( ) , Self :: Error > {
7065 self . 0 . write_all ( words) . map_err ( |err| SPIError { err } )
7166 }
72- }
7367
74- impl SpiBus < u8 > for Spidev {
7568 fn transfer ( & mut self , read : & mut [ u8 ] , write : & [ u8 ] ) -> Result < ( ) , Self :: Error > {
7669 self . 0
7770 . transfer ( & mut SpidevTransfer :: read_write ( write, read) )
@@ -84,33 +77,9 @@ mod embedded_hal_impl {
8477 . transfer ( & mut SpidevTransfer :: read_write ( & tx, words) )
8578 . map_err ( |err| SPIError { err } )
8679 }
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- }
10280
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 } )
11483 }
11584 }
11685
@@ -119,30 +88,62 @@ mod embedded_hal_impl {
11988 & mut self ,
12089 operations : & mut [ SpiOperation < ' _ , u8 > ] ,
12190 ) -> 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+ }
128101 SpiOperation :: TransferInPlace ( buf) => {
129102 let tx = unsafe {
130103 let p = buf. as_ptr ( ) ;
131104 std:: slice:: from_raw_parts ( p, buf. len ( ) )
132105 } ;
133- SpidevTransfer :: read_write ( tx, buf)
106+ spidev_transfers . push ( SpidevTransfer :: read_write ( tx, buf) )
134107 }
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+
141137 Ok ( ( ) )
142138 }
143139 }
144140}
145141
142+ enum Operation < ' a , ' b > {
143+ Transfers ( Vec < SpidevTransfer < ' a , ' b > > ) ,
144+ Delay ( u32 ) ,
145+ }
146+
146147/// Error type wrapping [io::Error](io::Error) to implement [embedded_hal::spi::ErrorKind]
147148#[ derive( Debug ) ]
148149pub struct SPIError {
@@ -163,6 +164,7 @@ impl From<io::Error> for SPIError {
163164}
164165
165166impl embedded_hal:: spi:: Error for SPIError {
167+ #[ allow( clippy:: match_single_binding) ]
166168 fn kind ( & self ) -> embedded_hal:: spi:: ErrorKind {
167169 use embedded_hal:: spi:: ErrorKind ;
168170 // TODO: match any errors here if we can find any that are relevant
0 commit comments