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,53 @@ 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
+ pub trait Default < W > : crate :: nb:: spi:: FullDuplex < W > { }
65
+
66
+ impl < W , S > crate :: blocking:: spi:: ReadWrite < W > for S
67
+ where
68
+ S : Default < W > ,
69
+ W : Clone + core:: default:: Default ,
70
+ {
71
+ type Error = S :: Error ;
72
+
73
+ fn read_write ( & mut self , read : & mut [ W ] , write : & [ W ] ) -> Result < ( ) , S :: Error > {
74
+ for i in 0 ..core:: cmp:: max ( read. len ( ) , write. len ( ) ) {
75
+ let word_out = if i < write. len ( ) {
76
+ write[ i] . clone ( )
77
+ } else {
78
+ W :: default ( )
79
+ } ;
80
+ nb:: block!( self . write( word_out. clone( ) ) ) ?;
81
+
82
+ let word_in = nb:: block!( self . read( ) ) ?;
83
+ if i < read. len ( ) {
84
+ read[ i] = word_in;
85
+ }
86
+ }
87
+
88
+ Ok ( ( ) )
89
+ }
90
+ }
91
+ }
92
+
93
+ /// Blocking simultaneous read+write with separate buffers
94
+ pub mod read_write_inplace {
36
95
/// Default implementation of `blocking::spi::Transfer<W>` for implementers of
37
96
/// `nonblocking::spi::FullDuplex<W>`
38
97
pub trait Default < W > : crate :: nb:: spi:: FullDuplex < W > { }
39
98
40
- impl < W , S > crate :: blocking:: spi:: Transfer < W > for S
99
+ impl < W , S > crate :: blocking:: spi:: ReadWriteInplace < W > for S
41
100
where
42
101
S : Default < W > ,
43
102
W : Clone ,
44
103
{
45
104
type Error = S :: Error ;
46
105
47
- fn transfer ( & mut self , words : & mut [ W ] ) -> Result < ( ) , S :: Error > {
106
+ fn read_write_inplace ( & mut self , words : & mut [ W ] ) -> Result < ( ) , S :: Error > {
48
107
for word in words. iter_mut ( ) {
49
108
nb:: block!( self . write( word. clone( ) ) ) ?;
50
109
* word = nb:: block!( self . read( ) ) ?;
@@ -78,6 +137,29 @@ pub mod write {
78
137
}
79
138
}
80
139
}
140
+ /// Blocking write
141
+ pub mod read {
142
+ /// Default implementation of `blocking::spi::Read<W>` for implementers
143
+ /// of `nonblocking::spi::FullDuplex<W>`
144
+ pub trait Default < W > : crate :: nb:: spi:: FullDuplex < W > { }
145
+
146
+ impl < W , S > crate :: blocking:: spi:: Read < W > for S
147
+ where
148
+ S : Default < W > ,
149
+ W : core:: default:: Default ,
150
+ {
151
+ type Error = S :: Error ;
152
+
153
+ fn read ( & mut self , words : & mut [ W ] ) -> Result < ( ) , S :: Error > {
154
+ for word in words. iter_mut ( ) {
155
+ nb:: block!( self . write( W :: default ( ) ) ) ?;
156
+ * word = nb:: block!( self . read( ) ) ?;
157
+ }
158
+
159
+ Ok ( ( ) )
160
+ }
161
+ }
162
+ }
81
163
82
164
/// Blocking write (iterator version)
83
165
pub mod write_iter {
@@ -129,15 +211,15 @@ pub trait Transactional<W: 'static> {
129
211
130
212
/// Blocking transactional impl over spi::Write and spi::Transfer
131
213
pub mod transactional {
132
- use super :: { Operation , Transfer , Write } ;
214
+ use super :: { Operation , ReadWriteInplace , Write } ;
133
215
134
216
/// Default implementation of `blocking::spi::Transactional<W>` for implementers of
135
217
/// `spi::Write<W>` and `spi::Transfer<W>`
136
- pub trait Default < W > : Write < W > + Transfer < W > { }
218
+ pub trait Default < W > : Write < W > + ReadWriteInplace < W > { }
137
219
138
220
impl < W : ' static , E , S > super :: Transactional < W > for S
139
221
where
140
- S : self :: Default < W > + Write < W , Error = E > + Transfer < W , Error = E > ,
222
+ S : self :: Default < W > + Write < W , Error = E > + ReadWriteInplace < W , Error = E > ,
141
223
W : Copy + Clone ,
142
224
{
143
225
type Error = E ;
@@ -146,7 +228,7 @@ pub mod transactional {
146
228
for op in operations {
147
229
match op {
148
230
Operation :: Write ( w) => self . write ( w) ?,
149
- Operation :: Transfer ( t) => self . transfer ( t) . map ( |_| ( ) ) ?,
231
+ Operation :: Transfer ( t) => self . read_write_inplace ( t) . map ( |_| ( ) ) ?,
150
232
}
151
233
}
152
234
0 commit comments