Skip to content

Commit f8110e6

Browse files
committed
spi: enforce all traits (nb+blocking) have the same Error type.
1 parent a0bd3dc commit f8110e6

File tree

3 files changed

+23
-42
lines changed

3 files changed

+23
-42
lines changed

src/spi/blocking.rs

Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
//! Blocking SPI API
22
3-
/// Blocking transfer with separate buffers
4-
pub trait Transfer<W = u8> {
5-
/// Error type
6-
type Error: crate::spi::Error;
3+
use super::ErrorType;
74

5+
/// Blocking transfer with separate buffers
6+
pub trait Transfer<W = u8>: ErrorType {
87
/// Writes and reads simultaneously. `write` is written to the slave on MOSI and
98
/// words received on MISO are stored in `read`.
109
///
@@ -17,37 +16,27 @@ pub trait Transfer<W = u8> {
1716
}
1817

1918
impl<T: Transfer<W>, W> Transfer<W> for &mut T {
20-
type Error = T::Error;
21-
2219
fn transfer(&mut self, read: &mut [W], write: &[W]) -> Result<(), Self::Error> {
2320
T::transfer(self, read, write)
2421
}
2522
}
2623

2724
/// Blocking transfer with single buffer (in-place)
28-
pub trait TransferInplace<W = u8> {
29-
/// Error type
30-
type Error: crate::spi::Error;
31-
25+
pub trait TransferInplace<W = u8>: ErrorType {
3226
/// Writes and reads simultaneously. The contents of `words` are
3327
/// written to the slave, and the received words are stored into the same
3428
/// `words` buffer, overwriting it.
3529
fn transfer_inplace(&mut self, words: &mut [W]) -> Result<(), Self::Error>;
3630
}
3731

3832
impl<T: TransferInplace<W>, W> TransferInplace<W> for &mut T {
39-
type Error = T::Error;
40-
4133
fn transfer_inplace(&mut self, words: &mut [W]) -> Result<(), Self::Error> {
4234
T::transfer_inplace(self, words)
4335
}
4436
}
4537

4638
/// Blocking read
47-
pub trait Read<W = u8> {
48-
/// Error type
49-
type Error: crate::spi::Error;
50-
39+
pub trait Read<W = u8>: ErrorType {
5140
/// Reads `words` from the slave.
5241
///
5342
/// The word value sent on MOSI during reading is implementation-defined,
@@ -56,44 +45,32 @@ pub trait Read<W = u8> {
5645
}
5746

5847
impl<T: Read<W>, W> Read<W> for &mut T {
59-
type Error = T::Error;
60-
6148
fn read(&mut self, words: &mut [W]) -> Result<(), Self::Error> {
6249
T::read(self, words)
6350
}
6451
}
6552

6653
/// Blocking write
67-
pub trait Write<W = u8> {
68-
/// Error type
69-
type Error: crate::spi::Error;
70-
54+
pub trait Write<W = u8>: ErrorType {
7155
/// Writes `words` to the slave, ignoring all the incoming words
7256
fn write(&mut self, words: &[W]) -> Result<(), Self::Error>;
7357
}
7458

7559
impl<T: Write<W>, W> Write<W> for &mut T {
76-
type Error = T::Error;
77-
7860
fn write(&mut self, words: &[W]) -> Result<(), Self::Error> {
7961
T::write(self, words)
8062
}
8163
}
8264

8365
/// Blocking write (iterator version)
84-
pub trait WriteIter<W = u8> {
85-
/// Error type
86-
type Error: crate::spi::Error;
87-
66+
pub trait WriteIter<W = u8>: ErrorType {
8867
/// Writes `words` to the slave, ignoring all the incoming words
8968
fn write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error>
9069
where
9170
WI: IntoIterator<Item = W>;
9271
}
9372

9473
impl<T: WriteIter<W>, W> WriteIter<W> for &mut T {
95-
type Error = T::Error;
96-
9774
fn write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error>
9875
where
9976
WI: IntoIterator<Item = W>,
@@ -119,17 +96,12 @@ pub enum Operation<'a, W: 'static = u8> {
11996

12097
/// Transactional trait allows multiple actions to be executed
12198
/// as part of a single SPI transaction
122-
pub trait Transactional<W: 'static = u8> {
123-
/// Associated error type
124-
type Error: crate::spi::Error;
125-
99+
pub trait Transactional<W: 'static = u8>: ErrorType {
126100
/// Execute the provided transactions
127101
fn exec<'a>(&mut self, operations: &mut [Operation<'a, W>]) -> Result<(), Self::Error>;
128102
}
129103

130104
impl<T: Transactional<W>, W: 'static> Transactional<W> for &mut T {
131-
type Error = T::Error;
132-
133105
fn exec<'a>(&mut self, operations: &mut [Operation<'a, W>]) -> Result<(), Self::Error> {
134106
T::exec(self, operations)
135107
}

src/spi/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,15 @@ impl core::fmt::Display for ErrorKind {
113113
}
114114
}
115115
}
116+
117+
/// SPI error type trait
118+
///
119+
/// This just defines the error type, to be used by the other SPI traits.
120+
pub trait ErrorType {
121+
/// Error type
122+
type Error: Error;
123+
}
124+
125+
impl<T: ErrorType> ErrorType for &mut T {
126+
type Error = T::Error;
127+
}

src/spi/nb.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Serial Peripheral Interface
22
3+
use super::ErrorType;
4+
35
/// Full duplex (master mode)
46
///
57
/// # Notes
@@ -16,10 +18,7 @@
1618
///
1719
/// - Some SPIs can work with 8-bit *and* 16-bit words. You can overload this trait with different
1820
/// `Word` types to allow operation in both modes.
19-
pub trait FullDuplex<Word = u8> {
20-
/// An enumeration of SPI errors
21-
type Error: crate::spi::Error;
22-
21+
pub trait FullDuplex<Word = u8>: ErrorType {
2322
/// Reads the word stored in the shift register
2423
///
2524
/// **NOTE** A word must be sent to the slave before attempting to call this
@@ -31,8 +30,6 @@ pub trait FullDuplex<Word = u8> {
3130
}
3231

3332
impl<T: FullDuplex<Word>, Word> FullDuplex<Word> for &mut T {
34-
type Error = T::Error;
35-
3633
fn read(&mut self) -> nb::Result<Word, Self::Error> {
3734
T::read(self)
3835
}

0 commit comments

Comments
 (0)