From 8b2dbcfc5da4d910087a6d309b6aacef6d198038 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 19 Dec 2021 09:19:27 +0100 Subject: [PATCH 1/2] spi: enforce all traits (nb+blocking) have the same Error type. --- src/spi/blocking.rs | 44 ++++++++------------------------------------ src/spi/mod.rs | 12 ++++++++++++ src/spi/nb.rs | 9 +++------ 3 files changed, 23 insertions(+), 42 deletions(-) diff --git a/src/spi/blocking.rs b/src/spi/blocking.rs index d7f215605..8aa82b627 100644 --- a/src/spi/blocking.rs +++ b/src/spi/blocking.rs @@ -1,10 +1,9 @@ //! Blocking SPI API -/// Blocking transfer with separate buffers -pub trait Transfer { - /// Error type - type Error: crate::spi::Error; +use super::ErrorType; +/// Blocking transfer with separate buffers +pub trait Transfer: ErrorType { /// Writes and reads simultaneously. `write` is written to the slave on MOSI and /// words received on MISO are stored in `read`. /// @@ -17,18 +16,13 @@ pub trait Transfer { } impl, W: Copy> Transfer for &mut T { - type Error = T::Error; - fn transfer(&mut self, read: &mut [W], write: &[W]) -> Result<(), Self::Error> { T::transfer(self, read, write) } } /// Blocking transfer with single buffer (in-place) -pub trait TransferInplace { - /// Error type - type Error: crate::spi::Error; - +pub trait TransferInplace: ErrorType { /// Writes and reads simultaneously. The contents of `words` are /// written to the slave, and the received words are stored into the same /// `words` buffer, overwriting it. @@ -36,18 +30,13 @@ pub trait TransferInplace { } impl, W: Copy> TransferInplace for &mut T { - type Error = T::Error; - fn transfer_inplace(&mut self, words: &mut [W]) -> Result<(), Self::Error> { T::transfer_inplace(self, words) } } /// Blocking read -pub trait Read { - /// Error type - type Error: crate::spi::Error; - +pub trait Read: ErrorType { /// Reads `words` from the slave. /// /// The word value sent on MOSI during reading is implementation-defined, @@ -56,35 +45,25 @@ pub trait Read { } impl, W: Copy> Read for &mut T { - type Error = T::Error; - fn read(&mut self, words: &mut [W]) -> Result<(), Self::Error> { T::read(self, words) } } /// Blocking write -pub trait Write { - /// Error type - type Error: crate::spi::Error; - +pub trait Write: ErrorType { /// Writes `words` to the slave, ignoring all the incoming words fn write(&mut self, words: &[W]) -> Result<(), Self::Error>; } impl, W: Copy> Write for &mut T { - type Error = T::Error; - fn write(&mut self, words: &[W]) -> Result<(), Self::Error> { T::write(self, words) } } /// Blocking write (iterator version) -pub trait WriteIter { - /// Error type - type Error: crate::spi::Error; - +pub trait WriteIter: ErrorType { /// Writes `words` to the slave, ignoring all the incoming words fn write_iter(&mut self, words: WI) -> Result<(), Self::Error> where @@ -92,8 +71,6 @@ pub trait WriteIter { } impl, W: Copy> WriteIter for &mut T { - type Error = T::Error; - fn write_iter(&mut self, words: WI) -> Result<(), Self::Error> where WI: IntoIterator, @@ -119,17 +96,12 @@ pub enum Operation<'a, W: 'static + Copy = u8> { /// Transactional trait allows multiple actions to be executed /// as part of a single SPI transaction -pub trait Transactional { - /// Associated error type - type Error: crate::spi::Error; - +pub trait Transactional: ErrorType { /// Execute the provided transactions fn exec<'a>(&mut self, operations: &mut [Operation<'a, W>]) -> Result<(), Self::Error>; } impl, W: 'static + Copy> Transactional for &mut T { - type Error = T::Error; - fn exec<'a>(&mut self, operations: &mut [Operation<'a, W>]) -> Result<(), Self::Error> { T::exec(self, operations) } diff --git a/src/spi/mod.rs b/src/spi/mod.rs index 048de49a4..a1924251c 100644 --- a/src/spi/mod.rs +++ b/src/spi/mod.rs @@ -113,3 +113,15 @@ impl core::fmt::Display for ErrorKind { } } } + +/// SPI error type trait +/// +/// This just defines the error type, to be used by the other SPI traits. +pub trait ErrorType { + /// Error type + type Error: Error; +} + +impl ErrorType for &mut T { + type Error = T::Error; +} diff --git a/src/spi/nb.rs b/src/spi/nb.rs index 03778db99..9a2fc12f6 100644 --- a/src/spi/nb.rs +++ b/src/spi/nb.rs @@ -1,5 +1,7 @@ //! Serial Peripheral Interface +use super::ErrorType; + /// Full duplex (master mode) /// /// # Notes @@ -16,10 +18,7 @@ /// /// - Some SPIs can work with 8-bit *and* 16-bit words. You can overload this trait with different /// `Word` types to allow operation in both modes. -pub trait FullDuplex { - /// An enumeration of SPI errors - type Error: crate::spi::Error; - +pub trait FullDuplex: ErrorType { /// Reads the word stored in the shift register /// /// **NOTE** A word must be sent to the slave before attempting to call this @@ -31,8 +30,6 @@ pub trait FullDuplex { } impl, Word: Copy> FullDuplex for &mut T { - type Error = T::Error; - fn read(&mut self) -> nb::Result { T::read(self) } From 37edca7a3b25f97099f036ad69b6d25c834a127c Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 19 Dec 2021 09:36:35 +0100 Subject: [PATCH 2/2] Add changelog. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 177bf3908..9ebf29485 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - Fixed blanket impl of `DelayUs` not covering the `delay_ms` method. +### Changed +- `spi`: traits now enforce all impls on the same struct (eg `Transfer` and `Write`) have the same `Error` type. ## [v1.0.0-alpha.6] - 2021-11-19