1
1
//! Blocking SPI API
2
2
3
- /// Blocking transfer
4
- pub trait Transfer < W > {
3
+ /// Blocking simultaneous read+write with separate buffers
4
+ pub trait ReadWrite < W > {
5
+ /// Error type
6
+ type Error ;
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 read_write ( & mut self , read : & mut [ W ] , write : & [ W ] ) -> Result < ( ) , Self :: Error > ;
17
+ }
18
+
19
+ /// Blocking simultaneous read+write with a single buffer
20
+ pub trait ReadWriteInplace < W > {
5
21
/// Error type
6
22
type Error ;
7
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 read_write_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
35
- pub mod transfer {
60
+ /// Blocking simultaneous read+write with separate buffers
61
+ pub mod read_write {
62
+ /// Default implementation of `blocking::spi::ReadWrite<W>` for implementers of
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.
67
+ pub trait Default < W > : crate :: nb:: spi:: FullDuplex < W > { }
68
+
69
+ impl < W , S > crate :: blocking:: spi:: ReadWrite < W > for S
70
+ where
71
+ S : Default < W > ,
72
+ W : Clone + core:: default:: Default ,
73
+ {
74
+ type Error = S :: Error ;
75
+
76
+ fn read_write ( & 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 read_write_inplace {
36
98
/// Default implementation of `blocking::spi::Transfer<W>` for implementers of
37
99
/// `nonblocking::spi::FullDuplex<W>`
38
100
pub trait Default < W > : crate :: nb:: spi:: FullDuplex < W > { }
39
101
40
- impl < W , S > crate :: blocking:: spi:: Transfer < W > for S
102
+ impl < W , S > crate :: blocking:: spi:: ReadWriteInplace < 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 read_write_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( ) ) ?;
@@ -78,6 +140,31 @@ pub mod write {
78
140
}
79
141
}
80
142
}
143
+ /// Blocking write
144
+ pub mod read {
145
+ /// Default implementation of `blocking::spi::Read<W>` for implementers
146
+ /// of `nonblocking::spi::FullDuplex<W>`
147
+ ///
148
+ /// During the read, `W::default()` (which is typically 0) is sent on MOSI.
149
+ pub trait Default < W > : crate :: nb:: spi:: FullDuplex < W > { }
150
+
151
+ impl < W , S > crate :: blocking:: spi:: Read < W > for S
152
+ where
153
+ S : Default < W > ,
154
+ W : core:: default:: Default ,
155
+ {
156
+ type Error = S :: Error ;
157
+
158
+ fn read ( & mut self , words : & mut [ W ] ) -> Result < ( ) , S :: Error > {
159
+ for word in words. iter_mut ( ) {
160
+ nb:: block!( self . write( W :: default ( ) ) ) ?;
161
+ * word = nb:: block!( self . read( ) ) ?;
162
+ }
163
+
164
+ Ok ( ( ) )
165
+ }
166
+ }
167
+ }
81
168
82
169
/// Blocking write (iterator version)
83
170
pub mod write_iter {
@@ -129,15 +216,15 @@ pub trait Transactional<W: 'static> {
129
216
130
217
/// Blocking transactional impl over spi::Write and spi::Transfer
131
218
pub mod transactional {
132
- use super :: { Operation , Transfer , Write } ;
219
+ use super :: { Operation , ReadWriteInplace , Write } ;
133
220
134
221
/// Default implementation of `blocking::spi::Transactional<W>` for implementers of
135
222
/// `spi::Write<W>` and `spi::Transfer<W>`
136
- pub trait Default < W > : Write < W > + Transfer < W > { }
223
+ pub trait Default < W > : Write < W > + ReadWriteInplace < W > { }
137
224
138
225
impl < W : ' static , E , S > super :: Transactional < W > for S
139
226
where
140
- S : self :: Default < W > + Write < W , Error = E > + Transfer < W , Error = E > ,
227
+ S : self :: Default < W > + Write < W , Error = E > + ReadWriteInplace < W , Error = E > ,
141
228
W : Copy + Clone ,
142
229
{
143
230
type Error = E ;
@@ -146,7 +233,7 @@ pub mod transactional {
146
233
for op in operations {
147
234
match op {
148
235
Operation :: Write ( w) => self . write ( w) ?,
149
- Operation :: Transfer ( t) => self . transfer ( t) . map ( |_| ( ) ) ?,
236
+ Operation :: Transfer ( t) => self . read_write_inplace ( t) . map ( |_| ( ) ) ?,
150
237
}
151
238
}
152
239
0 commit comments