|
4 | 4 | //! traits. To save boilerplate when that's the case a `Default` marker trait may be provided.
|
5 | 5 | //! Implementing that marker trait will opt in your type into a blanket implementation.
|
6 | 6 |
|
7 |
| -/// Blocking transfer |
| 7 | +/// Blocking transfer with separate buffers |
8 | 8 | pub trait Transfer<W> {
|
9 | 9 | /// Error type
|
10 | 10 | type Error: crate::spi::Error;
|
11 | 11 |
|
| 12 | + /// Writes and reads simultaneously. `write` is written to the slave on MOSI and |
| 13 | + /// words received on MISO are stored in `read`. |
| 14 | + /// |
| 15 | + /// It is allowed for `read` and `write` to have different lengths, even zero length. |
| 16 | + /// The transfer runs for `max(read.len(), write.len())` words. If `read` is shorter, |
| 17 | + /// incoming words after `read` has been filled will be discarded. If `write` is shorter, |
| 18 | + /// the value of words sent in MOSI after all `write` has been sent is implementation-defined, |
| 19 | + /// typically `0x00`, `0xFF`, or configurable. |
| 20 | + fn transfer(&mut self, read: &mut [W], write: &[W]) -> Result<(), Self::Error>; |
| 21 | +} |
| 22 | + |
| 23 | +impl<T: Transfer<W>, W> Transfer<W> for &mut T { |
| 24 | + type Error = T::Error; |
| 25 | + |
| 26 | + fn transfer(&mut self, read: &mut [W], write: &[W]) -> Result<(), Self::Error> { |
| 27 | + T::transfer(self, read, write) |
| 28 | + } |
| 29 | +} |
| 30 | + |
| 31 | +/// Blocking transfer with single buffer (in-place) |
| 32 | +pub trait TransferInplace<W> { |
| 33 | + /// Error type |
| 34 | + type Error: core::fmt::Debug; |
| 35 | + |
12 | 36 | /// Writes and reads simultaneously. The contents of `words` are
|
13 | 37 | /// written to the slave, and the received words are stored into the same
|
14 | 38 | /// `words` buffer, overwriting it.
|
15 |
| - fn transfer(&mut self, words: &mut [W]) -> Result<(), Self::Error>; |
| 39 | + fn transfer_inplace(&mut self, words: &mut [W]) -> Result<(), Self::Error>; |
16 | 40 | }
|
17 | 41 |
|
18 |
| -impl<T: Transfer<W>, W> Transfer<W> for &mut T { |
| 42 | +impl<T: TransferInplace<W>, W> TransferInplace<W> for &mut T { |
19 | 43 | type Error = T::Error;
|
20 | 44 |
|
21 |
| - fn transfer(&mut self, words: &mut [W]) -> Result<(), Self::Error> { |
22 |
| - T::transfer(self, words) |
| 45 | + fn transfer_inplace(&mut self, words: &mut [W]) -> Result<(), Self::Error> { |
| 46 | + T::transfer_inplace(self, words) |
| 47 | + } |
| 48 | +} |
| 49 | + |
| 50 | +/// Blocking read |
| 51 | +pub trait Read<W> { |
| 52 | + /// Error type |
| 53 | + type Error; |
| 54 | + |
| 55 | + /// Reads `words` to the slave. The word value sent on MOSI during |
| 56 | + /// reading is implementation-defined, typically `0x00`, `0xFF`, or configurable. |
| 57 | + fn read(&mut self, words: &mut [W]) -> Result<(), Self::Error>; |
| 58 | +} |
| 59 | + |
| 60 | +impl<T: Read<W>, W> Read<W> for &mut T { |
| 61 | + type Error = T::Error; |
| 62 | + |
| 63 | + fn read(&mut self, words: &mut [W]) -> Result<(), Self::Error> { |
| 64 | + T::read(self, words) |
23 | 65 | }
|
24 | 66 | }
|
25 | 67 |
|
@@ -67,10 +109,14 @@ impl<T: WriteIter<W>, W> WriteIter<W> for &mut T {
|
67 | 109 | /// This allows composition of SPI operations into a single bus transaction
|
68 | 110 | #[derive(Debug, PartialEq)]
|
69 | 111 | pub enum Operation<'a, W: 'static> {
|
| 112 | + /// Read data into the provided buffer. |
| 113 | + Read(&'a mut [W]), |
70 | 114 | /// Write data from the provided buffer, discarding read data
|
71 | 115 | Write(&'a [W]),
|
72 | 116 | /// Write data out while reading data into the provided buffer
|
73 |
| - Transfer(&'a mut [W]), |
| 117 | + Transfer(&'a mut [W], &'a [W]), |
| 118 | + /// Write data out while reading data into the provided buffer |
| 119 | + TransferInplace(&'a mut [W]), |
74 | 120 | }
|
75 | 121 |
|
76 | 122 | /// Transactional trait allows multiple actions to be executed
|
|
0 commit comments