diff --git a/CHANGELOG.md b/CHANGELOG.md index 504c383a1..16f63e504 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). importing the `nb` crate directly in dependendent crates. - `blocking::Serial`: renamed `bwrite_all` to `write`, `bflush` to `flush. - Removed `prelude` to avoid method name conflicts between different flavors (blocking, nb) of the same trait. Traits must now be manually imported. +- The serial, spi, and adc traits where changed to use associated `Word` types instead of type parameters ### Removed - Removed random number generation (`rng`) traits in favor of [rand_core](https://crates.io/crates/rand_core). diff --git a/src/blocking/serial.rs b/src/blocking/serial.rs index 5967414a1..515446a15 100644 --- a/src/blocking/serial.rs +++ b/src/blocking/serial.rs @@ -1,7 +1,10 @@ //! Blocking serial API /// Write half of a serial interface (blocking variant) -pub trait Write { +pub trait Write { + /// Word type + type Word; + /// The type of error that can occur when writing type Error; @@ -13,7 +16,7 @@ pub trait Write { /// everything has been sent, call [`flush`] after this function returns. /// /// [`flush`]: #tymethod.flush - fn write(&mut self, buffer: &[Word]) -> Result<(), Self::Error>; + fn write(&mut self, buffer: &[Self::Word]) -> Result<(), Self::Error>; /// Block until the serial interface has sent all buffered words fn flush(&mut self) -> Result<(), Self::Error>; @@ -29,16 +32,17 @@ pub mod write { /// /// [`nonblocking::serial::Write`]: ../../nonblocking/serial/trait.Write.html /// [`blocking::serial::Write`]: ../trait.Write.html - pub trait Default: crate::nb::serial::Write {} + pub trait Default: crate::nb::serial::Write {} - impl crate::blocking::serial::Write for S + impl crate::blocking::serial::Write for S where - S: Default, - Word: Clone, + S: Default, + S::Word: Clone, { + type Word = S::Word; type Error = S::Error; - fn write(&mut self, buffer: &[Word]) -> Result<(), Self::Error> { + fn write(&mut self, buffer: &[Self::Word]) -> Result<(), Self::Error> { for word in buffer { nb::block!(self.write(word.clone()))?; } diff --git a/src/blocking/spi.rs b/src/blocking/spi.rs index 571f7b32a..8c54d40af 100644 --- a/src/blocking/spi.rs +++ b/src/blocking/spi.rs @@ -1,48 +1,64 @@ //! Blocking SPI API /// Blocking transfer -pub trait Transfer { +pub trait Transfer { + /// Word type + type Word; + /// Error type type Error; /// Writes `words` to the slave. Returns the `words` received from the slave - fn transfer<'w>(&mut self, words: &'w mut [W]) -> Result<&'w [W], Self::Error>; + fn transfer<'w>( + &mut self, + words: &'w mut [Self::Word], + ) -> Result<&'w [Self::Word], Self::Error>; } /// Blocking write -pub trait Write { +pub trait Write { + /// Word type + type Word; + /// Error type type Error; /// Writes `words` to the slave, ignoring all the incoming words - fn write(&mut self, words: &[W]) -> Result<(), Self::Error>; + fn write(&mut self, words: &[Self::Word]) -> Result<(), Self::Error>; } /// Blocking write (iterator version) -pub trait WriteIter { +pub trait WriteIter { + /// Word type + type Word; + /// Error type type Error; /// Writes `words` to the slave, ignoring all the incoming words fn write_iter(&mut self, words: WI) -> Result<(), Self::Error> where - WI: IntoIterator; + WI: IntoIterator; } /// Blocking transfer pub mod transfer { /// Default implementation of `blocking::spi::Transfer` for implementers of /// `nonblocking::spi::FullDuplex` - pub trait Default: crate::nb::spi::FullDuplex {} + pub trait Default: crate::nb::spi::FullDuplex {} - impl crate::blocking::spi::Transfer for S + impl crate::blocking::spi::Transfer for S where - S: Default, - W: Clone, + S: Default, + S::Word: Clone, { + type Word = S::Word; type Error = S::Error; - fn transfer<'w>(&mut self, words: &'w mut [W]) -> Result<&'w [W], S::Error> { + fn transfer<'w>( + &mut self, + words: &'w mut [Self::Word], + ) -> Result<&'w [Self::Word], S::Error> { for word in words.iter_mut() { nb::block!(self.write(word.clone()))?; *word = nb::block!(self.read())?; @@ -57,16 +73,17 @@ pub mod transfer { pub mod write { /// Default implementation of `blocking::spi::Write` for implementers /// of `nonblocking::spi::FullDuplex` - pub trait Default: crate::nb::spi::FullDuplex {} + pub trait Default: crate::nb::spi::FullDuplex {} - impl crate::blocking::spi::Write for S + impl crate::blocking::spi::Write for S where - S: Default, - W: Clone, + S: Default, + S::Word: Clone, { + type Word = S::Word; type Error = S::Error; - fn write(&mut self, words: &[W]) -> Result<(), S::Error> { + fn write(&mut self, words: &[Self::Word]) -> Result<(), S::Error> { for word in words { nb::block!(self.write(word.clone()))?; nb::block!(self.read())?; @@ -81,18 +98,19 @@ pub mod write { pub mod write_iter { /// Default implementation of `blocking::spi::WriteIter` for implementers of /// `nonblocking::spi::FullDuplex` - pub trait Default: crate::nb::spi::FullDuplex {} + pub trait Default: crate::nb::spi::FullDuplex {} - impl crate::blocking::spi::WriteIter for S + impl crate::blocking::spi::WriteIter for S where - S: Default, - W: Clone, + S: Default, + S::Word: Clone, { + type Word = S::Word; type Error = S::Error; fn write_iter(&mut self, words: WI) -> Result<(), S::Error> where - WI: IntoIterator, + WI: IntoIterator, { for word in words.into_iter() { nb::block!(self.write(word.clone()))?; @@ -117,12 +135,16 @@ pub enum Operation<'a, W: 'static> { /// Transactional trait allows multiple actions to be executed /// as part of a single SPI transaction -pub trait Transactional { +pub trait Transactional { + /// Word type + type Word: 'static; + /// Associated error type type Error; /// Execute the provided transactions - fn exec<'a>(&mut self, operations: &mut [Operation<'a, W>]) -> Result<(), Self::Error>; + fn exec<'a>(&mut self, operations: &mut [Operation<'a, Self::Word>]) + -> Result<(), Self::Error>; } /// Blocking transactional impl over spi::Write and spi::Transfer @@ -131,13 +153,14 @@ pub mod transactional { /// Default implementation of `blocking::spi::Transactional` for implementers of /// `spi::Write` and `spi::Transfer` - pub trait Default: Write + Transfer {} + pub trait Default: Write + Transfer {} - impl super::Transactional for S + impl super::Transactional for S where - S: self::Default + Write + Transfer, + S: self::Default + Write + Transfer, W: Copy + Clone, { + type Word = W; type Error = E; fn exec<'a>(&mut self, operations: &mut [super::Operation<'a, W>]) -> Result<(), E> { diff --git a/src/fmt.rs b/src/fmt.rs index 81e23cef5..55b63dfe5 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -3,7 +3,7 @@ //! TODO write example of usage use core::fmt::{Result, Write}; -impl Write for dyn crate::nb::serial::Write + '_ +impl Write for dyn crate::nb::serial::Write + '_ where Word: From, { diff --git a/src/lib.rs b/src/lib.rs index 1dbb6dd49..1a0541cd1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -248,7 +248,7 @@ //! //! fn write_all(serial: &mut S, buffer: &[u8]) -> Result<(), S::Error> //! where -//! S: hal::nb::serial::Write +//! S: hal::nb::serial::Write //! { //! for &byte in buffer { //! block!(serial.write(byte))?; @@ -283,7 +283,7 @@ //! ) -> Result> //! where //! T: hal::nb::timer::CountDown, -//! S: hal::nb::serial::Read, +//! S: hal::nb::serial::Read, //! { //! timer.start(timeout).map_err(Error::TimedOut)?; //! @@ -326,7 +326,7 @@ //! //! fn flush(serial: &mut S, cb: &mut CircularBuffer) //! where -//! S: hal::nb::serial::Write, +//! S: hal::nb::serial::Write, //! { //! loop { //! if let Some(byte) = cb.peek() { @@ -390,7 +390,8 @@ //! # fn deref_mut(&mut self) -> &mut T { self.0 } //! # } //! # struct Serial1; -//! # impl hal::nb::serial::Write for Serial1 { +//! # impl hal::nb::serial::Write for Serial1 { +//! # type Word = u8; //! # type Error = Infallible; //! # fn write(&mut self, _: u8) -> nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } //! # fn flush(&mut self) -> nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } diff --git a/src/nb/adc.rs b/src/nb/adc.rs index 17de484dd..752e059db 100644 --- a/src/nb/adc.rs +++ b/src/nb/adc.rs @@ -64,23 +64,26 @@ pub trait Channel { /// # pub fn do_conversion(&mut self, chan: u8) -> u16 { 0xAA55_u16 } /// # } /// -/// impl OneShot for MyAdc +/// impl OneShot for MyAdc /// where -/// WORD: From, /// PIN: Channel, /// { +/// type Word = u16; /// type Error = (); /// -/// fn read(&mut self, pin: &mut PIN) -> nb::Result { +/// fn read(&mut self, pin: &mut PIN) -> nb::Result { /// let chan = 1 << pin.channel(); /// self.power_up(); /// let result = self.do_conversion(chan); /// self.power_down(); -/// Ok(result.into()) +/// Ok(result) /// } /// } /// ``` -pub trait OneShot> { +pub trait OneShot> { + /// Word type + type Word; + /// Error type returned by ADC methods type Error; @@ -88,5 +91,5 @@ pub trait OneShot> { /// /// This method takes a `Pin` reference, as it is expected that the ADC will be able to sample /// whatever channel underlies the pin. - fn read(&mut self, pin: &mut Pin) -> nb::Result; + fn read(&mut self, pin: &mut Pin) -> nb::Result; } diff --git a/src/nb/serial.rs b/src/nb/serial.rs index 407e75300..7a3acca1b 100644 --- a/src/nb/serial.rs +++ b/src/nb/serial.rs @@ -4,21 +4,27 @@ /// /// Some serial interfaces support different data sizes (8 bits, 9 bits, etc.); /// This can be encoded in this trait via the `Word` type parameter. -pub trait Read { +pub trait Read { + /// Word type + type Word; + /// Read error type Error; /// Reads a single word from the serial interface - fn read(&mut self) -> nb::Result; + fn read(&mut self) -> nb::Result; } /// Write half of a serial interface -pub trait Write { +pub trait Write { + /// Word type + type Word; + /// Write error type Error; /// Writes a single word to the serial interface - fn write(&mut self, word: Word) -> nb::Result<(), Self::Error>; + fn write(&mut self, word: Self::Word) -> nb::Result<(), Self::Error>; /// Ensures that none of the previously written words are still buffered fn flush(&mut self) -> nb::Result<(), Self::Error>; diff --git a/src/nb/spi.rs b/src/nb/spi.rs index 6eb7fc233..7b9b8b3ad 100644 --- a/src/nb/spi.rs +++ b/src/nb/spi.rs @@ -13,10 +13,10 @@ /// /// - Data is only guaranteed to be clocked out when the `read` call succeeds. /// The slave select line shouldn't be released before that. -/// -/// - 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 { +pub trait FullDuplex { + /// Word type + type Word; + /// An enumeration of SPI errors type Error; @@ -24,10 +24,10 @@ pub trait FullDuplex { /// /// **NOTE** A word must be sent to the slave before attempting to call this /// method. - fn read(&mut self) -> nb::Result; + fn read(&mut self) -> nb::Result; /// Writes a word to the slave - fn write(&mut self, word: Word) -> nb::Result<(), Self::Error>; + fn write(&mut self, word: Self::Word) -> nb::Result<(), Self::Error>; } /// Clock polarity