33//! [`embedded-hal`]: https://docs.rs/embedded-hal
44//!
55
6+ use std:: cmp:: Ordering ;
67use std:: fmt;
78use std:: io;
89use std:: ops;
@@ -64,9 +65,24 @@ mod embedded_hal_impl {
6465 }
6566
6667 fn transfer ( & mut self , read : & mut [ u8 ] , write : & [ u8 ] ) -> Result < ( ) , Self :: Error > {
67- self . 0
68- . transfer ( & mut SpidevTransfer :: read_write ( write, read) )
69- . map_err ( |err| SPIError { err } )
68+ let read_len = read. len ( ) ;
69+ match read_len. cmp ( & write. len ( ) ) {
70+ Ordering :: Less => self . 0 . transfer_multiple ( & mut [
71+ SpidevTransfer :: read_write ( & write[ ..read_len] , read) ,
72+ SpidevTransfer :: write ( & write[ read_len..] ) ,
73+ ] ) ,
74+ Ordering :: Equal => self
75+ . 0
76+ . transfer ( & mut SpidevTransfer :: read_write ( write, read) ) ,
77+ Ordering :: Greater => {
78+ let ( read1, read2) = read. split_at_mut ( write. len ( ) ) ;
79+ self . 0 . transfer_multiple ( & mut [
80+ SpidevTransfer :: read_write ( write, read1) ,
81+ SpidevTransfer :: read ( read2) ,
82+ ] )
83+ }
84+ }
85+ . map_err ( |err| SPIError { err } )
7086 }
7187
7288 fn transfer_in_place ( & mut self , words : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
@@ -82,7 +98,7 @@ mod embedded_hal_impl {
8298 }
8399
84100 impl SpiDevice for Spidev {
85- ///Perform a transaction against the device. [Read more][transaction]
101+ /// Perform a transaction against the device. [Read more][transaction]
86102 ///
87103 /// [Delay operations][delay] are capped to 65535 microseconds.
88104 ///
@@ -92,24 +108,37 @@ mod embedded_hal_impl {
92108 & mut self ,
93109 operations : & mut [ SpiOperation < ' _ , u8 > ] ,
94110 ) -> Result < ( ) , Self :: Error > {
95- let mut transfers: Vec < _ > = operations
96- . iter_mut ( )
97- . map ( |op| match op {
98- SpiOperation :: Read ( buf) => SpidevTransfer :: read ( buf) ,
99- SpiOperation :: Write ( buf) => SpidevTransfer :: write ( buf) ,
100- SpiOperation :: Transfer ( read, write) => SpidevTransfer :: read_write ( write, read) ,
111+ let mut transfers = Vec :: with_capacity ( operations. len ( ) ) ;
112+ for op in operations {
113+ match op {
114+ SpiOperation :: Read ( buf) => transfers. push ( SpidevTransfer :: read ( buf) ) ,
115+ SpiOperation :: Write ( buf) => transfers. push ( SpidevTransfer :: write ( buf) ) ,
116+ SpiOperation :: Transfer ( read, write) => match read. len ( ) . cmp ( & write. len ( ) ) {
117+ Ordering :: Less => {
118+ let n = read. len ( ) ;
119+ transfers. push ( SpidevTransfer :: read_write ( & write[ ..n] , read) ) ;
120+ transfers. push ( SpidevTransfer :: write ( & write[ n..] ) ) ;
121+ }
122+ Ordering :: Equal => transfers. push ( SpidevTransfer :: read_write ( write, read) ) ,
123+ Ordering :: Greater => {
124+ let ( read1, read2) = read. split_at_mut ( write. len ( ) ) ;
125+ transfers. push ( SpidevTransfer :: read_write ( write, read1) ) ;
126+ transfers. push ( SpidevTransfer :: read ( read2) ) ;
127+ }
128+ } ,
101129 SpiOperation :: TransferInPlace ( buf) => {
102130 let tx = unsafe {
103131 let p = buf. as_ptr ( ) ;
104132 std:: slice:: from_raw_parts ( p, buf. len ( ) )
105133 } ;
106- SpidevTransfer :: read_write ( tx, buf)
134+ transfers . push ( SpidevTransfer :: read_write ( tx, buf) ) ;
107135 }
108136 SpiOperation :: DelayUs ( us) => {
109- SpidevTransfer :: delay ( ( * us) . try_into ( ) . unwrap_or ( u16:: MAX ) )
137+ let us = ( * us) . try_into ( ) . unwrap_or ( u16:: MAX ) ;
138+ transfers. push ( SpidevTransfer :: delay ( us) ) ;
110139 }
111- } )
112- . collect ( ) ;
140+ }
141+ }
113142 self . 0
114143 . transfer_multiple ( & mut transfers)
115144 . map_err ( |err| SPIError { err } ) ?;
0 commit comments