11//! Blocking SPI API
22
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 > {
521 /// Error type
622 type Error ;
723
824 /// Writes and reads simultaneously. The contents of `words` are
925 /// written to the slave, and the received words are stored into the same
1026 /// `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 > ;
1228}
1329
1430/// Blocking write
@@ -20,6 +36,16 @@ pub trait Write<W> {
2036 fn write ( & mut self , words : & [ W ] ) -> Result < ( ) , Self :: Error > ;
2137}
2238
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+
2349/// Blocking write (iterator version)
2450pub trait WriteIter < W > {
2551 /// Error type
@@ -31,20 +57,56 @@ pub trait WriteIter<W> {
3157 WI : IntoIterator < Item = W > ;
3258}
3359
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 {
3698 /// Default implementation of `blocking::spi::Transfer<W>` for implementers of
3799 /// `nonblocking::spi::FullDuplex<W>`
38100 pub trait Default < W > : crate :: nb:: spi:: FullDuplex < W > { }
39101
40- impl < W , S > crate :: blocking:: spi:: Transfer < W > for S
102+ impl < W , S > crate :: blocking:: spi:: ReadWriteInplace < W > for S
41103 where
42104 S : Default < W > ,
43105 W : Clone ,
44106 {
45107 type Error = S :: Error ;
46108
47- fn transfer ( & mut self , words : & mut [ W ] ) -> Result < ( ) , S :: Error > {
109+ fn read_write_inplace ( & mut self , words : & mut [ W ] ) -> Result < ( ) , S :: Error > {
48110 for word in words. iter_mut ( ) {
49111 nb:: block!( self . write( word. clone( ) ) ) ?;
50112 * word = nb:: block!( self . read( ) ) ?;
@@ -78,6 +140,31 @@ pub mod write {
78140 }
79141 }
80142}
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+ }
81168
82169/// Blocking write (iterator version)
83170pub mod write_iter {
@@ -129,15 +216,15 @@ pub trait Transactional<W: 'static> {
129216
130217/// Blocking transactional impl over spi::Write and spi::Transfer
131218pub mod transactional {
132- use super :: { Operation , Transfer , Write } ;
219+ use super :: { Operation , ReadWriteInplace , Write } ;
133220
134221 /// Default implementation of `blocking::spi::Transactional<W>` for implementers of
135222 /// `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 > { }
137224
138225 impl < W : ' static , E , S > super :: Transactional < W > for S
139226 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 > ,
141228 W : Copy + Clone ,
142229 {
143230 type Error = E ;
@@ -146,7 +233,7 @@ pub mod transactional {
146233 for op in operations {
147234 match op {
148235 Operation :: Write ( w) => self . write ( w) ?,
149- Operation :: Transfer ( t) => self . transfer ( t) . map ( |_| ( ) ) ?,
236+ Operation :: Transfer ( t) => self . read_write_inplace ( t) . map ( |_| ( ) ) ?,
150237 }
151238 }
152239
0 commit comments