From 67ee20cd4885f95143749b8878eeb705d4e9df1d Mon Sep 17 00:00:00 2001 From: David Sawatzke Date: Wed, 2 Jan 2019 21:18:54 +0100 Subject: [PATCH 1/4] Add non-blocking spi send trait --- src/prelude.rs | 2 ++ src/spi.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/prelude.rs b/src/prelude.rs index 4d17043ad..55f0b5d8d 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -28,6 +28,8 @@ pub use digital::ToggleableOutputPin as _embedded_hal_digital_ToggleableOutputPi pub use serial::Read as _embedded_hal_serial_Read; pub use serial::Write as _embedded_hal_serial_Write; pub use spi::FullDuplex as _embedded_hal_spi_FullDuplex; +#[cfg(feature = "unproven")] +pub use spi::Send as _embedded_hal_spi_Send; pub use timer::CountDown as _embedded_hal_timer_CountDown; #[cfg(feature = "unproven")] pub use watchdog::Watchdog as _embedded_hal_watchdog_Watchdog; diff --git a/src/spi.rs b/src/spi.rs index b91e6d68b..7086fb448 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -26,6 +26,52 @@ pub trait FullDuplex { fn send(&mut self, word: Word) -> nb::Result<(), Self::Error>; } +/// Write (master mode) +/// +/// # Notes +/// +/// - It's the task of the user of this interface to manage the slave select lines +#[cfg(feature = "unproven")] +pub trait Send { + /// An enumeration of SPI errors + type Error; + + /// Sends a word to the slave + fn send(&mut self, word: Word) -> nb::Result<(), Self::Error>; +} + +/// Write (master mode) +#[cfg(feature = "unproven")] +pub mod full_duplex { + /// Default implementation of `spi::FullDuplex` for implementers of + /// `spi::Send` + /// + /// Also needs a `send` method to return the byte read during the last send + pub trait Default: ::spi::Send { + /// Reads the word stored in the shift register + /// + /// **NOTE** A word must be sent to the slave before attempting to call this + /// method. + fn read(&mut self) -> nb::Result; + } + + impl ::spi::FullDuplex for S + where + S: Default, + W: Clone, + { + type Error = S::Error; + + fn read(&mut self) -> nb::Result { + self.read() + } + + fn send(&mut self, word: W) -> nb::Result<(), Self::Error> { + self.send(word) + } + } +} + /// Clock polarity #[derive(Clone, Copy, PartialEq, Eq)] pub enum Polarity { @@ -75,4 +121,4 @@ pub const MODE_2: Mode = Mode { pub const MODE_3: Mode = Mode { polarity: Polarity::IdleHigh, phase: Phase::CaptureOnSecondTransition, -}; \ No newline at end of file +}; From 2d1c5f4676a4dd5bd28ef1c4b1c8762074337aa2 Mon Sep 17 00:00:00 2001 From: David Sawatzke Date: Thu, 3 Jan 2019 16:06:04 +0100 Subject: [PATCH 2/4] Add spi flush call to check for end of transfer --- src/spi.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/spi.rs b/src/spi.rs index 7086fb448..be58a7355 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -31,6 +31,8 @@ pub trait FullDuplex { /// # Notes /// /// - It's the task of the user of this interface to manage the slave select lines +/// +/// - The slave select line shouldn't be released before the `flush` call succeeds #[cfg(feature = "unproven")] pub trait Send { /// An enumeration of SPI errors @@ -38,6 +40,9 @@ pub trait Send { /// Sends a word to the slave fn send(&mut self, word: Word) -> nb::Result<(), Self::Error>; + + /// Ensures that none of the previously written words are still buffered + fn flush(&mut self) -> nb::Result<(), Self::Error>; } /// Write (master mode) From 906629813973e588a1b65b56f4050fade978f1c1 Mon Sep 17 00:00:00 2001 From: David Sawatzke Date: Fri, 4 Jan 2019 02:06:09 +0100 Subject: [PATCH 3/4] Use `completed` instead of `flush` --- src/spi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spi.rs b/src/spi.rs index be58a7355..0e059f17c 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -42,7 +42,7 @@ pub trait Send { fn send(&mut self, word: Word) -> nb::Result<(), Self::Error>; /// Ensures that none of the previously written words are still buffered - fn flush(&mut self) -> nb::Result<(), Self::Error>; + fn completed(&mut self) -> nb::Result<(), Self::Error>; } /// Write (master mode) From 06204c61a36c83464c09223b65517dbadc322ead Mon Sep 17 00:00:00 2001 From: David Sawatzke Date: Fri, 4 Jan 2019 02:15:49 +0100 Subject: [PATCH 4/4] Implement `Send` for FullDuplex --- src/spi.rs | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/src/spi.rs b/src/spi.rs index 0e059f17c..92387a237 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -47,33 +47,14 @@ pub trait Send { /// Write (master mode) #[cfg(feature = "unproven")] -pub mod full_duplex { - /// Default implementation of `spi::FullDuplex` for implementers of - /// `spi::Send` - /// - /// Also needs a `send` method to return the byte read during the last send - pub trait Default: ::spi::Send { - /// Reads the word stored in the shift register - /// - /// **NOTE** A word must be sent to the slave before attempting to call this - /// method. - fn read(&mut self) -> nb::Result; +impl Send for FullDuplex { + type Error = E; + fn send(&mut self, word: W) -> nb::Result<(), Self::Error> { + self.send(word) } - impl ::spi::FullDuplex for S - where - S: Default, - W: Clone, - { - type Error = S::Error; - - fn read(&mut self) -> nb::Result { - self.read() - } - - fn send(&mut self, word: W) -> nb::Result<(), Self::Error> { - self.send(word) - } + fn completed(&mut self) -> nb::Result<(), Self::Error> { + self.read().map(|_| ()) } }