Skip to content

Commit

Permalink
Merge #192
Browse files Browse the repository at this point in the history
192: [towards 1.0]: Fallible proven traits r=thejpster a=eldruin

Here some work towards 1.0 following #177 (comment).

Co-authored-by: Diego Barrios Romero <eldruin@gmail.com>
  • Loading branch information
bors[bot] and eldruin committed Mar 16, 2020
2 parents 62a5dc6 + ee56d1e commit 88412b9
Show file tree
Hide file tree
Showing 22 changed files with 231 additions and 939 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- A nonblocking trait for interfacing with random number generation hardware.

### Changed
- The current versions of `InputPin` have been proven. These are `digital::v1::InputPin`
and `digital::v2::InputPin`.
- All traits have been marked as proven (`unproven` feature has been removed).
- All trait methods have been made fallible.
- All trait methods have been renamed `try_*` (i.e. `try_send`) for consistency.
- The minimum supported Rust version is 1.35 due to [this issue](https://github.com/rust-lang/rust/issues/54973).

## [v0.2.3] - 2019-05-09

Expand Down
9 changes: 2 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,10 @@ readme = "README.md"
repository = "https://github.com/rust-embedded/embedded-hal"
version = "0.2.3"

[dependencies.nb]
version = "0.1.1"
[dependencies]
nb = { version = "0.1.1", features = ["unstable"] }

[dev-dependencies]
stm32f3 = { version = "0.8", features = ["stm32f303", "rt"] }
futures = "0.1.17"

[features]
unproven = ["nb/unstable"]

[package.metadata.docs.rs]
features = ["unproven"]
3 changes: 1 addition & 2 deletions ci/script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ set -euxo pipefail

main() {
cargo check --target $TARGET
cargo check --target $TARGET --features unproven
cargo fmt -- --check

if [ $TRAVIS_RUST_VERSION = nightly ]; then
cargo test --target $TARGET --features unproven
cargo test --target $TARGET
fi
}

Expand Down
22 changes: 7 additions & 15 deletions src/adc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Analog-digital conversion traits

#[cfg(feature = "unproven")]
use nb;

/// A marker trait to identify MCU pins that can be used as inputs to an ADC channel.
Expand All @@ -10,7 +9,7 @@ use nb;
/// between the physical interface and the ADC sampling buffer.
///
/// ```
/// # use std::marker::PhantomData;
/// # use core::marker::PhantomData;
/// # use embedded_hal::adc::Channel;
///
/// struct Adc1; // Example ADC with single bank of 8 channels
Expand All @@ -21,7 +20,7 @@ use nb;
/// impl Channel<Adc1> for Gpio1Pin1<Analog> {
/// type ID = u8; // ADC channels are identified numerically
///
/// fn channel() -> u8 { 7_u8 } // GPIO pin 1 is connected to ADC channel 7
/// const CHANNEL: u8 = 7_u8; // GPIO pin 1 is connected to ADC channel 7
/// }
///
/// struct Adc2; // ADC with two banks of 16 channels
Expand All @@ -32,10 +31,9 @@ use nb;
/// impl Channel<Adc2> for Gpio2PinA<AltFun> {
/// type ID = (u8, u8); // ADC channels are identified by bank number and channel number
///
/// fn channel() -> (u8, u8) { (0, 3) } // bank 0 channel 3
/// const CHANNEL: (u8, u8) = (0, 3); // bank 0 channel 3
/// }
/// ```
#[cfg(feature = "unproven")]
pub trait Channel<ADC> {
/// Channel ID type
///
Expand All @@ -46,12 +44,7 @@ pub trait Channel<ADC> {

/// Get the specific ID that identifies this channel, for example `0_u8` for the first ADC
/// channel, if Self::ID is u8.
fn channel() -> Self::ID;

// `channel` is a function due to [this reported
// issue](https://github.com/rust-lang/rust/issues/54973). Something about blanket impls
// combined with `type ID; const CHANNEL: Self::ID;` causes problems.
//const CHANNEL: Self::ID;
const CHANNEL: Self::ID;
}

/// ADCs that sample on single channels per request, and do so at the time of the request.
Expand All @@ -76,16 +69,15 @@ pub trait Channel<ADC> {
/// {
/// type Error = ();
///
/// fn read(&mut self, _pin: &mut PIN) -> nb::Result<WORD, Self::Error> {
/// let chan = 1 << PIN::channel();
/// fn try_read(&mut self, _pin: &mut PIN) -> nb::Result<WORD, Self::Error> {
/// let chan = 1 << PIN::CHANNEL;
/// self.power_up();
/// let result = self.do_conversion(chan);
/// self.power_down();
/// Ok(result.into())
/// }
/// }
/// ```
#[cfg(feature = "unproven")]
pub trait OneShot<ADC, Word, Pin: Channel<ADC>> {
/// Error type returned by ADC methods
type Error;
Expand All @@ -94,5 +86,5 @@ pub trait OneShot<ADC, Word, Pin: Channel<ADC>> {
///
/// 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<Word, Self::Error>;
fn try_read(&mut self, pin: &mut Pin) -> nb::Result<Word, Self::Error>;
}
10 changes: 8 additions & 2 deletions src/blocking/delay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,21 @@
/// `UXX` denotes the range type of the delay time. `UXX` can be `u8`, `u16`, etc. A single type can
/// implement this trait for different types of `UXX`.
pub trait DelayMs<UXX> {
/// Enumeration of `DelayMs` errors
type Error;

/// Pauses execution for `ms` milliseconds
fn delay_ms(&mut self, ms: UXX);
fn try_delay_ms(&mut self, ms: UXX) -> Result<(), Self::Error>;
}

/// Microsecond delay
///
/// `UXX` denotes the range type of the delay time. `UXX` can be `u8`, `u16`, etc. A single type can
/// implement this trait for different types of `UXX`.
pub trait DelayUs<UXX> {
/// Enumeration of `DelayMs` errors
type Error;

/// Pauses execution for `us` microseconds
fn delay_us(&mut self, us: UXX);
fn try_delay_us(&mut self, us: UXX) -> Result<(), Self::Error>;
}
12 changes: 5 additions & 7 deletions src/blocking/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub trait Read {
/// - `MAK` = master acknowledge
/// - `NMAK` = master no acknowledge
/// - `SP` = stop condition
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error>;
fn try_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error>;
}

/// Blocking write
Expand All @@ -52,11 +52,10 @@ pub trait Write {
/// - `SAK` = slave acknowledge
/// - `Bi` = ith byte of data
/// - `SP` = stop condition
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error>;
fn try_write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error>;
}

/// Blocking write (iterator version)
#[cfg(feature = "unproven")]
pub trait WriteIter {
/// Error type
type Error;
Expand All @@ -66,7 +65,7 @@ pub trait WriteIter {
/// # I2C Events (contract)
///
/// Same as `Write`
fn write<B>(&mut self, addr: u8, bytes: B) -> Result<(), Self::Error>
fn try_write<B>(&mut self, addr: u8, bytes: B) -> Result<(), Self::Error>
where
B: IntoIterator<Item = u8>;
}
Expand Down Expand Up @@ -98,7 +97,7 @@ pub trait WriteRead {
/// - `MAK` = master acknowledge
/// - `NMAK` = master no acknowledge
/// - `SP` = stop condition
fn write_read(
fn try_write_read(
&mut self,
address: u8,
bytes: &[u8],
Expand All @@ -107,7 +106,6 @@ pub trait WriteRead {
}

/// Blocking write (iterator version) + read
#[cfg(feature = "unproven")]
pub trait WriteIterRead {
/// Error type
type Error;
Expand All @@ -118,7 +116,7 @@ pub trait WriteIterRead {
/// # I2C Events (contract)
///
/// Same as the `WriteRead` trait
fn write_iter_read<B>(
fn try_write_iter_read<B>(
&mut self,
address: u8,
bytes: B,
Expand Down
5 changes: 1 addition & 4 deletions src/blocking/rng.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
//! Blocking hardware random number generator

/// Blocking read
///
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
#[cfg(feature = "unproven")]
pub trait Read {
/// Error type
type Error;
Expand All @@ -15,5 +12,5 @@ pub trait Read {
///
/// If this function returns an error, it is unspecified how many bytes it has read, but it
/// will never read more than would be necessary to completely fill the buffer.
fn read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error>;
fn try_read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error>;
}
16 changes: 8 additions & 8 deletions src/blocking/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ pub trait Write<Word> {
/// An implementation can choose to buffer the write, returning `Ok(())`
/// after the complete slice has been written to a buffer, but before all
/// words have been sent via the serial interface. To make sure that
/// everything has been sent, call [`bflush`] after this function returns.
/// everything has been sent, call [`try_bflush`] after this function returns.
///
/// [`bflush`]: #tymethod.bflush
fn bwrite_all(&mut self, buffer: &[Word]) -> Result<(), Self::Error>;
/// [`try_bflush`]: #tymethod.bflush
fn try_bwrite_all(&mut self, buffer: &[Word]) -> Result<(), Self::Error>;

/// Block until the serial interface has sent all buffered words
fn bflush(&mut self) -> Result<(), Self::Error>;
fn try_bflush(&mut self) -> Result<(), Self::Error>;
}

/// Blocking serial write
Expand All @@ -38,16 +38,16 @@ pub mod write {
{
type Error = S::Error;

fn bwrite_all(&mut self, buffer: &[Word]) -> Result<(), Self::Error> {
fn try_bwrite_all(&mut self, buffer: &[Word]) -> Result<(), Self::Error> {
for word in buffer {
block!(self.write(word.clone()))?;
block!(self.try_write(word.clone()))?;
}

Ok(())
}

fn bflush(&mut self) -> Result<(), Self::Error> {
block!(self.flush())?;
fn try_bflush(&mut self) -> Result<(), Self::Error> {
block!(self.try_flush())?;
Ok(())
}
}
Expand Down
26 changes: 12 additions & 14 deletions src/blocking/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub trait Transfer<W> {
type Error;

/// Sends `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 try_transfer<'w>(&mut self, words: &'w mut [W]) -> Result<&'w [W], Self::Error>;
}

/// Blocking write
Expand All @@ -15,17 +15,16 @@ pub trait Write<W> {
type Error;

/// Sends `words` to the slave, ignoring all the incoming words
fn write(&mut self, words: &[W]) -> Result<(), Self::Error>;
fn try_write(&mut self, words: &[W]) -> Result<(), Self::Error>;
}

/// Blocking write (iterator version)
#[cfg(feature = "unproven")]
pub trait WriteIter<W> {
/// Error type
type Error;

/// Sends `words` to the slave, ignoring all the incoming words
fn write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error>
fn try_write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error>
where
WI: IntoIterator<Item = W>;
}
Expand All @@ -43,10 +42,10 @@ pub mod transfer {
{
type Error = S::Error;

fn transfer<'w>(&mut self, words: &'w mut [W]) -> Result<&'w [W], S::Error> {
fn try_transfer<'w>(&mut self, words: &'w mut [W]) -> Result<&'w [W], S::Error> {
for word in words.iter_mut() {
block!(self.send(word.clone()))?;
*word = block!(self.read())?;
block!(self.try_send(word.clone()))?;
*word = block!(self.try_read())?;
}

Ok(words)
Expand All @@ -66,10 +65,10 @@ pub mod write {
{
type Error = S::Error;

fn write(&mut self, words: &[W]) -> Result<(), S::Error> {
fn try_write(&mut self, words: &[W]) -> Result<(), S::Error> {
for word in words {
block!(self.send(word.clone()))?;
block!(self.read())?;
block!(self.try_send(word.clone()))?;
block!(self.try_read())?;
}

Ok(())
Expand All @@ -78,7 +77,6 @@ pub mod write {
}

/// Blocking write (iterator version)
#[cfg(feature = "unproven")]
pub mod write_iter {
/// Default implementation of `blocking::spi::WriteIter<W>` for implementers of
/// `spi::FullDuplex<W>`
Expand All @@ -91,13 +89,13 @@ pub mod write_iter {
{
type Error = S::Error;

fn write_iter<WI>(&mut self, words: WI) -> Result<(), S::Error>
fn try_write_iter<WI>(&mut self, words: WI) -> Result<(), S::Error>
where
WI: IntoIterator<Item = W>,
{
for word in words.into_iter() {
block!(self.send(word.clone()))?;
block!(self.read())?;
block!(self.try_send(word.clone()))?;
block!(self.try_read())?;
}

Ok(())
Expand Down
Loading

0 comments on commit 88412b9

Please sign in to comment.