1
1
//! Blocking SPI API
2
2
3
- /// Blocking transfer
3
+ /// Blocking transfer with separate buffers
4
4
pub trait Transfer < W > {
5
5
/// Error type
6
6
type Error ;
7
7
8
+ /// Writes and reads simultaneously. `write` is written to the slave on MOSI and
9
+ /// words received on MISO are stored in `read`.
10
+ ///
11
+ /// It is allowed for `read` and `write` to have different lengths, even zero length.
12
+ /// The transfer runs for `max(read.len(), write.len())` words. If `read` is shorter,
13
+ /// incoming words after `read` has been filled will be discarded. If `write` is shorter,
14
+ /// the value of words sent in MOSI after all `write` has been sent is implementation defined,
15
+ /// typically `0x00`, `0xFF`, or configurable.
16
+ fn transfer ( & mut self , read : & mut [ W ] , write : & [ W ] ) -> Result < ( ) , Self :: Error > ;
17
+ }
18
+
19
+ /// Blocking transfer with single buffer
20
+ pub trait TransferInplace < W > {
21
+ /// Error type
22
+ type Error ;
23
+
8
24
/// Writes and reads simultaneously. The contents of `words` are
9
25
/// written to the slave, and the received words are stored into the same
10
26
/// `words` buffer, overwriting it.
11
- fn transfer ( & mut self , words : & mut [ W ] ) -> Result < ( ) , Self :: Error > ;
27
+ fn transfer_inplace ( & mut self , words : & mut [ W ] ) -> Result < ( ) , Self :: Error > ;
12
28
}
13
29
14
30
/// Blocking write
@@ -20,6 +36,16 @@ pub trait Write<W> {
20
36
fn write ( & mut self , words : & [ W ] ) -> Result < ( ) , Self :: Error > ;
21
37
}
22
38
39
+ /// Blocking read
40
+ pub trait Read < W > {
41
+ /// Error type
42
+ type Error ;
43
+
44
+ /// Reads `words` to the slave. The word value sent on MOSI during
45
+ /// reading is implementation defined, typically `0x00`, `0xFF`, or configurable.
46
+ fn read ( & mut self , words : & mut [ W ] ) -> Result < ( ) , Self :: Error > ;
47
+ }
48
+
23
49
/// Blocking write (iterator version)
24
50
pub trait WriteIter < W > {
25
51
/// Error type
@@ -31,20 +57,56 @@ pub trait WriteIter<W> {
31
57
WI : IntoIterator < Item = W > ;
32
58
}
33
59
34
- /// Blocking transfer
60
+ /// Blocking transfer with separate buffers
35
61
pub mod transfer {
36
62
/// Default implementation of `blocking::spi::Transfer<W>` for implementers of
37
63
/// `nonblocking::spi::FullDuplex<W>`
64
+ ///
65
+ /// If `read` is longer than `write`, `W::default()` (which is typically 0) is sent on MOSI
66
+ /// to fill the remaining bytes.
38
67
pub trait Default < W > : crate :: nb:: spi:: FullDuplex < W > { }
39
68
40
69
impl < W , S > crate :: blocking:: spi:: Transfer < W > for S
70
+ where
71
+ S : Default < W > ,
72
+ W : Clone + core:: default:: Default ,
73
+ {
74
+ type Error = S :: Error ;
75
+
76
+ fn transfer ( & mut self , read : & mut [ W ] , write : & [ W ] ) -> Result < ( ) , S :: Error > {
77
+ for i in 0 ..core:: cmp:: max ( read. len ( ) , write. len ( ) ) {
78
+ let word_out = if i < write. len ( ) {
79
+ write[ i] . clone ( )
80
+ } else {
81
+ W :: default ( )
82
+ } ;
83
+ nb:: block!( self . write( word_out. clone( ) ) ) ?;
84
+
85
+ let word_in = nb:: block!( self . read( ) ) ?;
86
+ if i < read. len ( ) {
87
+ read[ i] = word_in;
88
+ }
89
+ }
90
+
91
+ Ok ( ( ) )
92
+ }
93
+ }
94
+ }
95
+
96
+ /// Blocking simultaneous read+write with separate buffers
97
+ pub mod transfer_inplace {
98
+ /// Default implementation of `blocking::spi::Transfer<W>` for implementers of
99
+ /// `nonblocking::spi::FullDuplex<W>`
100
+ pub trait Default < W > : crate :: nb:: spi:: FullDuplex < W > { }
101
+
102
+ impl < W , S > crate :: blocking:: spi:: TransferInplace < W > for S
41
103
where
42
104
S : Default < W > ,
43
105
W : Clone ,
44
106
{
45
107
type Error = S :: Error ;
46
108
47
- fn transfer ( & mut self , words : & mut [ W ] ) -> Result < ( ) , S :: Error > {
109
+ fn transfer_inplace ( & mut self , words : & mut [ W ] ) -> Result < ( ) , S :: Error > {
48
110
for word in words. iter_mut ( ) {
49
111
nb:: block!( self . write( word. clone( ) ) ) ?;
50
112
* word = nb:: block!( self . read( ) ) ?;
@@ -79,6 +141,32 @@ pub mod write {
79
141
}
80
142
}
81
143
144
+ /// Blocking read
145
+ pub mod read {
146
+ /// Default implementation of `blocking::spi::Read<W>` for implementers
147
+ /// of `nonblocking::spi::FullDuplex<W>`
148
+ ///
149
+ /// During the read, `W::default()` (which is typically 0) is sent on MOSI.
150
+ pub trait Default < W > : crate :: nb:: spi:: FullDuplex < W > { }
151
+
152
+ impl < W , S > crate :: blocking:: spi:: Read < W > for S
153
+ where
154
+ S : Default < W > ,
155
+ W : core:: default:: Default ,
156
+ {
157
+ type Error = S :: Error ;
158
+
159
+ fn read ( & mut self , words : & mut [ W ] ) -> Result < ( ) , S :: Error > {
160
+ for word in words. iter_mut ( ) {
161
+ nb:: block!( self . write( W :: default ( ) ) ) ?;
162
+ * word = nb:: block!( self . read( ) ) ?;
163
+ }
164
+
165
+ Ok ( ( ) )
166
+ }
167
+ }
168
+ }
169
+
82
170
/// Blocking write (iterator version)
83
171
pub mod write_iter {
84
172
/// Default implementation of `blocking::spi::WriteIter<W>` for implementers of
@@ -129,15 +217,15 @@ pub trait Transactional<W: 'static> {
129
217
130
218
/// Blocking transactional impl over spi::Write and spi::Transfer
131
219
pub mod transactional {
132
- use super :: { Operation , Transfer , Write } ;
220
+ use super :: { Operation , TransferInplace , Write } ;
133
221
134
222
/// Default implementation of `blocking::spi::Transactional<W>` for implementers of
135
223
/// `spi::Write<W>` and `spi::Transfer<W>`
136
- pub trait Default < W > : Write < W > + Transfer < W > { }
224
+ pub trait Default < W > : Write < W > + TransferInplace < W > { }
137
225
138
226
impl < W : ' static , E , S > super :: Transactional < W > for S
139
227
where
140
- S : self :: Default < W > + Write < W , Error = E > + Transfer < W , Error = E > ,
228
+ S : self :: Default < W > + Write < W , Error = E > + TransferInplace < W , Error = E > ,
141
229
W : Copy + Clone ,
142
230
{
143
231
type Error = E ;
@@ -146,7 +234,7 @@ pub mod transactional {
146
234
for op in operations {
147
235
match op {
148
236
Operation :: Write ( w) => self . write ( w) ?,
149
- Operation :: Transfer ( t) => self . transfer ( t) . map ( |_| ( ) ) ?,
237
+ Operation :: Transfer ( t) => self . transfer_inplace ( t) . map ( |_| ( ) ) ?,
150
238
}
151
239
}
152
240
0 commit comments