3
3
//! [`embedded-hal`]: https://docs.rs/embedded-hal
4
4
//!
5
5
6
+ use std:: cmp:: Ordering ;
6
7
use std:: fmt;
7
8
use std:: io;
8
9
use std:: ops;
@@ -64,9 +65,24 @@ mod embedded_hal_impl {
64
65
}
65
66
66
67
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 } )
70
86
}
71
87
72
88
fn transfer_in_place ( & mut self , words : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
@@ -82,7 +98,7 @@ mod embedded_hal_impl {
82
98
}
83
99
84
100
impl SpiDevice for Spidev {
85
- ///Perform a transaction against the device. [Read more][transaction]
101
+ /// Perform a transaction against the device. [Read more][transaction]
86
102
///
87
103
/// [Delay operations][delay] are capped to 65535 microseconds.
88
104
///
@@ -92,24 +108,37 @@ mod embedded_hal_impl {
92
108
& mut self ,
93
109
operations : & mut [ SpiOperation < ' _ , u8 > ] ,
94
110
) -> 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
+ } ,
101
129
SpiOperation :: TransferInPlace ( buf) => {
102
130
let tx = unsafe {
103
131
let p = buf. as_ptr ( ) ;
104
132
std:: slice:: from_raw_parts ( p, buf. len ( ) )
105
133
} ;
106
- SpidevTransfer :: read_write ( tx, buf)
134
+ transfers . push ( SpidevTransfer :: read_write ( tx, buf) ) ;
107
135
}
108
136
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) ) ;
110
139
}
111
- } )
112
- . collect ( ) ;
140
+ }
141
+ }
113
142
self . 0
114
143
. transfer_multiple ( & mut transfers)
115
144
. map_err ( |err| SPIError { err } ) ?;
0 commit comments