1212
1313#![ deny( missing_docs) ]
1414
15- extern crate cast;
16- extern crate core;
17- extern crate embedded_hal as hal;
18- pub extern crate i2cdev;
19- pub extern crate nb;
20- pub extern crate serial_core;
21- pub extern crate serial_unix;
22- pub extern crate spidev;
15+ use cast;
16+ pub use i2cdev;
17+ pub use nb;
18+ pub use serial_core;
19+ pub use serial_unix;
20+ pub use spidev;
2321
2422#[ cfg( feature = "gpio_sysfs" ) ]
25- pub extern crate sysfs_gpio;
23+ pub use sysfs_gpio;
2624
2725#[ cfg( feature = "gpio_cdev" ) ]
28- pub extern crate gpio_cdev;
26+ pub use gpio_cdev;
27+
2928
3029use core:: convert:: Infallible ;
3130use std:: io:: { self , Write } ;
@@ -34,7 +33,7 @@ use std::time::Duration;
3433use std:: { ops, thread} ;
3534
3635use cast:: { u32, u64} ;
37- use hal :: blocking:: i2c:: Operation as I2cOperation ;
36+ use embedded_hal :: blocking:: i2c:: Operation as I2cOperation ;
3837use i2cdev:: core:: { I2CDevice , I2CMessage , I2CTransfer } ;
3938use i2cdev:: linux:: LinuxI2CMessage ;
4039use spidev:: SpidevTransfer ;
@@ -63,7 +62,7 @@ pub use sysfs_pin::SysfsPin;
6362/// Empty struct that provides delay functionality on top of `thread::sleep`
6463pub struct Delay ;
6564
66- impl hal :: blocking:: delay:: DelayUs < u8 > for Delay {
65+ impl embedded_hal :: blocking:: delay:: DelayUs < u8 > for Delay {
6766 type Error = Infallible ;
6867
6968 fn try_delay_us ( & mut self , n : u8 ) -> Result < ( ) , Self :: Error > {
@@ -72,7 +71,7 @@ impl hal::blocking::delay::DelayUs<u8> for Delay {
7271 }
7372}
7473
75- impl hal :: blocking:: delay:: DelayUs < u16 > for Delay {
74+ impl embedded_hal :: blocking:: delay:: DelayUs < u16 > for Delay {
7675 type Error = Infallible ;
7776
7877 fn try_delay_us ( & mut self , n : u16 ) -> Result < ( ) , Self :: Error > {
@@ -81,7 +80,7 @@ impl hal::blocking::delay::DelayUs<u16> for Delay {
8180 }
8281}
8382
84- impl hal :: blocking:: delay:: DelayUs < u32 > for Delay {
83+ impl embedded_hal :: blocking:: delay:: DelayUs < u32 > for Delay {
8584 type Error = Infallible ;
8685
8786 fn try_delay_us ( & mut self , n : u32 ) -> Result < ( ) , Self :: Error > {
@@ -93,7 +92,7 @@ impl hal::blocking::delay::DelayUs<u32> for Delay {
9392 }
9493}
9594
96- impl hal :: blocking:: delay:: DelayUs < u64 > for Delay {
95+ impl embedded_hal :: blocking:: delay:: DelayUs < u64 > for Delay {
9796 type Error = Infallible ;
9897
9998 fn try_delay_us ( & mut self , n : u64 ) -> Result < ( ) , Self :: Error > {
@@ -105,7 +104,7 @@ impl hal::blocking::delay::DelayUs<u64> for Delay {
105104 }
106105}
107106
108- impl hal :: blocking:: delay:: DelayMs < u8 > for Delay {
107+ impl embedded_hal :: blocking:: delay:: DelayMs < u8 > for Delay {
109108 type Error = Infallible ;
110109
111110 fn try_delay_ms ( & mut self , n : u8 ) -> Result < ( ) , Self :: Error > {
@@ -114,7 +113,7 @@ impl hal::blocking::delay::DelayMs<u8> for Delay {
114113 }
115114}
116115
117- impl hal :: blocking:: delay:: DelayMs < u16 > for Delay {
116+ impl embedded_hal :: blocking:: delay:: DelayMs < u16 > for Delay {
118117 type Error = Infallible ;
119118
120119 fn try_delay_ms ( & mut self , n : u16 ) -> Result < ( ) , Self :: Error > {
@@ -123,7 +122,7 @@ impl hal::blocking::delay::DelayMs<u16> for Delay {
123122 }
124123}
125124
126- impl hal :: blocking:: delay:: DelayMs < u32 > for Delay {
125+ impl embedded_hal :: blocking:: delay:: DelayMs < u32 > for Delay {
127126 type Error = Infallible ;
128127
129128 fn try_delay_ms ( & mut self , n : u32 ) -> Result < ( ) , Self :: Error > {
@@ -132,7 +131,7 @@ impl hal::blocking::delay::DelayMs<u32> for Delay {
132131 }
133132}
134133
135- impl hal :: blocking:: delay:: DelayMs < u64 > for Delay {
134+ impl embedded_hal :: blocking:: delay:: DelayMs < u64 > for Delay {
136135 type Error = Infallible ;
137136
138137 fn try_delay_ms ( & mut self , n : u64 ) -> Result < ( ) , Self :: Error > {
@@ -175,7 +174,7 @@ impl I2cdev {
175174 }
176175}
177176
178- impl hal :: blocking:: i2c:: Read for I2cdev {
177+ impl embedded_hal :: blocking:: i2c:: Read for I2cdev {
179178 type Error = i2cdev:: linux:: LinuxI2CError ;
180179
181180 fn try_read ( & mut self , address : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
@@ -184,7 +183,7 @@ impl hal::blocking::i2c::Read for I2cdev {
184183 }
185184}
186185
187- impl hal :: blocking:: i2c:: Write for I2cdev {
186+ impl embedded_hal :: blocking:: i2c:: Write for I2cdev {
188187 type Error = i2cdev:: linux:: LinuxI2CError ;
189188
190189 fn try_write ( & mut self , address : u8 , bytes : & [ u8 ] ) -> Result < ( ) , Self :: Error > {
@@ -193,7 +192,7 @@ impl hal::blocking::i2c::Write for I2cdev {
193192 }
194193}
195194
196- impl hal :: blocking:: i2c:: WriteRead for I2cdev {
195+ impl embedded_hal :: blocking:: i2c:: WriteRead for I2cdev {
197196 type Error = i2cdev:: linux:: LinuxI2CError ;
198197
199198 fn try_write_read (
@@ -203,12 +202,15 @@ impl hal::blocking::i2c::WriteRead for I2cdev {
203202 buffer : & mut [ u8 ] ,
204203 ) -> Result < ( ) , Self :: Error > {
205204 self . set_address ( address) ?;
206- let mut messages = [ LinuxI2CMessage :: write ( bytes) , LinuxI2CMessage :: read ( buffer) ] ;
205+ let mut messages = [
206+ LinuxI2CMessage :: write ( bytes) ,
207+ LinuxI2CMessage :: read ( buffer) ,
208+ ] ;
207209 self . inner . transfer ( & mut messages) . map ( drop)
208210 }
209211}
210212
211- impl hal :: blocking:: i2c:: Transactional for I2cdev {
213+ impl embedded_hal :: blocking:: i2c:: Transactional for I2cdev {
212214 type Error = i2cdev:: linux:: LinuxI2CError ;
213215
214216 fn try_exec ( & mut self , address : u8 , operations : & mut [ I2cOperation ] ) -> Result < ( ) , Self :: Error >
@@ -259,7 +261,7 @@ impl Spidev {
259261 }
260262}
261263
262- impl hal :: blocking:: spi:: Transfer < u8 > for Spidev {
264+ impl embedded_hal :: blocking:: spi:: Transfer < u8 > for Spidev {
263265 type Error = io:: Error ;
264266
265267 fn try_transfer < ' b > ( & mut self , buffer : & ' b mut [ u8 ] ) -> io:: Result < & ' b [ u8 ] > {
@@ -270,14 +272,44 @@ impl hal::blocking::spi::Transfer<u8> for Spidev {
270272 }
271273}
272274
273- impl hal :: blocking:: spi:: Write < u8 > for Spidev {
275+ impl embedded_hal :: blocking:: spi:: Write < u8 > for Spidev {
274276 type Error = io:: Error ;
275277
276278 fn try_write ( & mut self , buffer : & [ u8 ] ) -> io:: Result < ( ) > {
277279 self . 0 . write_all ( buffer)
278280 }
279281}
280282
283+ pub use embedded_hal:: blocking:: spi:: { Operation as SpiOperation } ;
284+
285+ /// Transactional implementation batches SPI operations into a single transaction
286+ impl embedded_hal:: blocking:: spi:: Transactional < u8 > for Spidev {
287+ type Error = io:: Error ;
288+
289+ fn try_exec < ' a > ( & mut self , operations : & mut [ SpiOperation < ' a , u8 > ] ) -> Result < ( ) , Self :: Error > {
290+
291+ // Map types from generic to linux objects
292+ let mut messages: Vec < _ > = operations. iter_mut ( ) . map ( |a| {
293+ match a {
294+ SpiOperation :: Write ( w) => SpidevTransfer :: write ( w) ,
295+ SpiOperation :: Transfer ( r) => {
296+ // Clone read to write pointer
297+ // SPIdev is okay with having w == r but this is tricky to achieve in safe rust
298+ let w = unsafe {
299+ let p = r. as_ptr ( ) ;
300+ std:: slice:: from_raw_parts ( p, r. len ( ) )
301+ } ;
302+
303+ SpidevTransfer :: read_write ( w, r)
304+ } ,
305+ }
306+ } ) . collect ( ) ;
307+
308+ // Execute transfer
309+ self . 0 . transfer_multiple ( & mut messages)
310+ }
311+ }
312+
281313impl ops:: Deref for Spidev {
282314 type Target = spidev:: Spidev ;
283315
0 commit comments