Skip to content

Commit 8725bc6

Browse files
committed
spi/blocking: group into read-only, write-only and read-write traits
1 parent 37edca7 commit 8725bc6

File tree

2 files changed

+58
-54
lines changed

2 files changed

+58
-54
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1414
- Fixed blanket impl of `DelayUs` not covering the `delay_ms` method.
1515
### Changed
1616
- `spi`: traits now enforce all impls on the same struct (eg `Transfer` and `Write`) have the same `Error` type.
17+
- `spi/blocking`: unified traits into `Read`, `Write`, `ReadWrite`.
18+
- `spi/blocking`: renamed Transactional `exec` to `batch`.
19+
- `spi/blocking`: Added `read_batch`, `write_batch` methods.
1720

1821
## [v1.0.0-alpha.6] - 2021-11-19
1922

src/spi/blocking.rs

+55-54
Original file line numberDiff line numberDiff line change
@@ -2,75 +2,54 @@
22
33
use super::ErrorType;
44

5-
/// Blocking transfer with separate buffers
6-
pub trait Transfer<W = u8>: ErrorType {
7-
/// Writes and reads simultaneously. `write` is written to the slave on MOSI and
8-
/// words received on MISO are stored in `read`.
9-
///
10-
/// It is allowed for `read` and `write` to have different lengths, even zero length.
11-
/// The transfer runs for `max(read.len(), write.len())` words. If `read` is shorter,
12-
/// incoming words after `read` has been filled will be discarded. If `write` is shorter,
13-
/// the value of words sent in MOSI after all `write` has been sent is implementation-defined,
14-
/// typically `0x00`, `0xFF`, or configurable.
15-
fn transfer(&mut self, read: &mut [W], write: &[W]) -> Result<(), Self::Error>;
16-
}
17-
18-
impl<T: Transfer<W>, W: Copy> Transfer<W> for &mut T {
19-
fn transfer(&mut self, read: &mut [W], write: &[W]) -> Result<(), Self::Error> {
20-
T::transfer(self, read, write)
21-
}
22-
}
23-
24-
/// Blocking transfer with single buffer (in-place)
25-
pub trait TransferInplace<W: Copy = u8>: ErrorType {
26-
/// Writes and reads simultaneously. The contents of `words` are
27-
/// written to the slave, and the received words are stored into the same
28-
/// `words` buffer, overwriting it.
29-
fn transfer_inplace(&mut self, words: &mut [W]) -> Result<(), Self::Error>;
30-
}
31-
32-
impl<T: TransferInplace<W>, W: Copy> TransferInplace<W> for &mut T {
33-
fn transfer_inplace(&mut self, words: &mut [W]) -> Result<(), Self::Error> {
34-
T::transfer_inplace(self, words)
35-
}
36-
}
37-
38-
/// Blocking read
5+
/// Blocking read-only SPI
396
pub trait Read<W: Copy = u8>: ErrorType {
407
/// Reads `words` from the slave.
418
///
429
/// The word value sent on MOSI during reading is implementation-defined,
4310
/// typically `0x00`, `0xFF`, or configurable.
4411
fn read(&mut self, words: &mut [W]) -> Result<(), Self::Error>;
12+
13+
/// Reads all slices in `words` from the slave as part of a single SPI transaction.
14+
///
15+
/// The word value sent on MOSI during reading is implementation-defined,
16+
/// typically `0x00`, `0xFF`, or configurable.
17+
fn read_transaction(&mut self, words: &mut [&mut [W]]) -> Result<(), Self::Error>;
4518
}
4619

4720
impl<T: Read<W>, W: Copy> Read<W> for &mut T {
4821
fn read(&mut self, words: &mut [W]) -> Result<(), Self::Error> {
4922
T::read(self, words)
5023
}
24+
25+
fn read_transaction(&mut self, words: &mut [&mut [W]]) -> Result<(), Self::Error> {
26+
T::read_transaction(self, words)
27+
}
5128
}
5229

53-
/// Blocking write
30+
/// Blocking write-only SPI
5431
pub trait Write<W: Copy = u8>: ErrorType {
5532
/// Writes `words` to the slave, ignoring all the incoming words
5633
fn write(&mut self, words: &[W]) -> Result<(), Self::Error>;
57-
}
5834

59-
impl<T: Write<W>, W: Copy> Write<W> for &mut T {
60-
fn write(&mut self, words: &[W]) -> Result<(), Self::Error> {
61-
T::write(self, words)
62-
}
63-
}
35+
/// Writes all slices in `words` to the slave as part of a single SPI transaction, ignoring all the incoming words
36+
fn write_transaction(&mut self, words: &[&[W]]) -> Result<(), Self::Error>;
6437

65-
/// Blocking write (iterator version)
66-
pub trait WriteIter<W: Copy = u8>: ErrorType {
6738
/// Writes `words` to the slave, ignoring all the incoming words
6839
fn write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error>
6940
where
7041
WI: IntoIterator<Item = W>;
7142
}
7243

73-
impl<T: WriteIter<W>, W: Copy> WriteIter<W> for &mut T {
44+
impl<T: Write<W>, W: Copy> Write<W> for &mut T {
45+
fn write(&mut self, words: &[W]) -> Result<(), Self::Error> {
46+
T::write(self, words)
47+
}
48+
49+
fn write_transaction(&mut self, words: &[&[W]]) -> Result<(), Self::Error> {
50+
T::write_transaction(self, words)
51+
}
52+
7453
fn write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error>
7554
where
7655
WI: IntoIterator<Item = W>,
@@ -79,7 +58,7 @@ impl<T: WriteIter<W>, W: Copy> WriteIter<W> for &mut T {
7958
}
8059
}
8160

82-
/// Operation for transactional SPI trait
61+
/// Operation for ReadWrite::transaction
8362
///
8463
/// This allows composition of SPI operations into a single bus transaction
8564
#[derive(Debug, PartialEq)]
@@ -91,18 +70,40 @@ pub enum Operation<'a, W: 'static + Copy = u8> {
9170
/// Write data out while reading data into the provided buffer
9271
Transfer(&'a mut [W], &'a [W]),
9372
/// Write data out while reading data into the provided buffer
94-
TransferInplace(&'a mut [W]),
73+
TransferInPlace(&'a mut [W]),
9574
}
9675

97-
/// Transactional trait allows multiple actions to be executed
98-
/// as part of a single SPI transaction
99-
pub trait Transactional<W: 'static + Copy = u8>: ErrorType {
100-
/// Execute the provided transactions
101-
fn exec<'a>(&mut self, operations: &mut [Operation<'a, W>]) -> Result<(), Self::Error>;
76+
/// Blocking read-write SPI
77+
pub trait ReadWrite<W: Copy = u8>: Read<W> + Write<W> {
78+
/// Writes and reads simultaneously. `write` is written to the slave on MOSI and
79+
/// words received on MISO are stored in `read`.
80+
///
81+
/// It is allowed for `read` and `write` to have different lengths, even zero length.
82+
/// The transfer runs for `max(read.len(), write.len())` words. If `read` is shorter,
83+
/// incoming words after `read` has been filled will be discarded. If `write` is shorter,
84+
/// the value of words sent in MOSI after all `write` has been sent is implementation-defined,
85+
/// typically `0x00`, `0xFF`, or configurable.
86+
fn transfer(&mut self, read: &mut [W], write: &[W]) -> Result<(), Self::Error>;
87+
88+
/// Writes and reads simultaneously. The contents of `words` are
89+
/// written to the slave, and the received words are stored into the same
90+
/// `words` buffer, overwriting it.
91+
fn transfer_in_place(&mut self, words: &mut [W]) -> Result<(), Self::Error>;
92+
93+
/// Execute multiple actions as part of a single SPI transaction
94+
fn transaction<'a>(&mut self, operations: &mut [Operation<'a, W>]) -> Result<(), Self::Error>;
10295
}
10396

104-
impl<T: Transactional<W>, W: 'static + Copy> Transactional<W> for &mut T {
105-
fn exec<'a>(&mut self, operations: &mut [Operation<'a, W>]) -> Result<(), Self::Error> {
106-
T::exec(self, operations)
97+
impl<T: ReadWrite<W>, W: Copy> ReadWrite<W> for &mut T {
98+
fn transfer(&mut self, read: &mut [W], write: &[W]) -> Result<(), Self::Error> {
99+
T::transfer(self, read, write)
100+
}
101+
102+
fn transfer_in_place(&mut self, words: &mut [W]) -> Result<(), Self::Error> {
103+
T::transfer_in_place(self, words)
104+
}
105+
106+
fn transaction<'a>(&mut self, operations: &mut [Operation<'a, W>]) -> Result<(), Self::Error> {
107+
T::transaction(self, operations)
107108
}
108109
}

0 commit comments

Comments
 (0)