Skip to content

Commit

Permalink
async: switch to async-fn-in-traits
Browse files Browse the repository at this point in the history
  • Loading branch information
Dirbaio committed Nov 1, 2022
1 parent 9eb6dab commit 703896b
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 254 deletions.
28 changes: 6 additions & 22 deletions embedded-hal-async/src/delay.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,17 @@
//! Delays
use core::future::Future;

/// Microsecond delay
pub trait DelayUs {
/// Enumeration of errors
type Error: core::fmt::Debug;

/// The future returned by the `delay_us` function.
type DelayUsFuture<'a>: Future<Output = Result<(), Self::Error>>
where
Self: 'a;

/// Pauses execution for at minimum `us` microseconds. Pause can be longer
/// if the implementation requires it due to precision/timing issues.
fn delay_us(&mut self, us: u32) -> Self::DelayUsFuture<'_>;

/// The future returned by the `delay_ms` function.
type DelayMsFuture<'a>: Future<Output = Result<(), Self::Error>>
where
Self: 'a;
async fn delay_us(&mut self, us: u32) -> Result<(), Self::Error>;

/// Pauses execution for at minimum `ms` milliseconds. Pause can be longer
/// if the implementation requires it due to precision/timing issues.
fn delay_ms(&mut self, ms: u32) -> Self::DelayMsFuture<'_>;
async fn delay_ms(&mut self, ms: u32) -> Result<(), Self::Error>;
}

impl<T> DelayUs for &mut T
Expand All @@ -32,15 +20,11 @@ where
{
type Error = T::Error;

type DelayUsFuture<'a> = T::DelayUsFuture<'a> where Self: 'a;

fn delay_us(&mut self, us: u32) -> Self::DelayUsFuture<'_> {
T::delay_us(self, us)
async fn delay_us(&mut self, us: u32) -> Result<(), T::Error> {
T::delay_us(self, us).await
}

type DelayMsFuture<'a> = T::DelayMsFuture<'a> where Self: 'a;

fn delay_ms(&mut self, ms: u32) -> Self::DelayMsFuture<'_> {
T::delay_ms(self, ms)
async fn delay_ms(&mut self, ms: u32) -> Result<(), T::Error> {
T::delay_ms(self, ms).await
}
}
67 changes: 15 additions & 52 deletions embedded-hal-async/src/digital.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,93 +16,56 @@
//! }
//! ```
use core::future::Future;

/// Asynchronously wait for GPIO pin state.
pub trait Wait: embedded_hal::digital::ErrorType {
/// The future returned by the `wait_for_high` function.
type WaitForHighFuture<'a>: Future<Output = Result<(), Self::Error>>
where
Self: 'a;

/// Wait until the pin is high. If it is already high, return immediately.
///
/// # Note for implementers
/// The pin may have switched back to low before the task was run after
/// being woken. The future should still resolve in that case.
fn wait_for_high(&mut self) -> Self::WaitForHighFuture<'_>;

/// The future returned by `wait_for_low`.
type WaitForLowFuture<'a>: Future<Output = Result<(), Self::Error>>
where
Self: 'a;
async fn wait_for_high(&mut self) -> Result<(), Self::Error>;

/// Wait until the pin is low. If it is already low, return immediately.
///
/// # Note for implementers
/// The pin may have switched back to high before the task was run after
/// being woken. The future should still resolve in that case.
fn wait_for_low(&mut self) -> Self::WaitForLowFuture<'_>;

/// The future returned from `wait_for_rising_edge`.
type WaitForRisingEdgeFuture<'a>: Future<Output = Result<(), Self::Error>>
where
Self: 'a;
async fn wait_for_low(&mut self) -> Result<(), Self::Error>;

/// Wait for the pin to undergo a transition from low to high.
///
/// If the pin is already high, this does *not* return immediately, it'll wait for the
/// pin to go low and then high again.
fn wait_for_rising_edge(&mut self) -> Self::WaitForRisingEdgeFuture<'_>;

/// The future returned from `wait_for_falling_edge`.
type WaitForFallingEdgeFuture<'a>: Future<Output = Result<(), Self::Error>>
where
Self: 'a;
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error>;

/// Wait for the pin to undergo a transition from high to low.
///
/// If the pin is already low, this does *not* return immediately, it'll wait for the
/// pin to go high and then low again.
fn wait_for_falling_edge(&mut self) -> Self::WaitForFallingEdgeFuture<'_>;

/// The future returned from `wait_for_any_edge`.
type WaitForAnyEdgeFuture<'a>: Future<Output = Result<(), Self::Error>>
where
Self: 'a;
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error>;

/// Wait for the pin to undergo any transition, i.e low to high OR high to low.
fn wait_for_any_edge(&mut self) -> Self::WaitForAnyEdgeFuture<'_>;
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error>;
}

impl<T: Wait> Wait for &mut T {
type WaitForHighFuture<'a> = T::WaitForHighFuture<'a> where Self: 'a;

fn wait_for_high(&mut self) -> Self::WaitForHighFuture<'_> {
T::wait_for_high(self)
async fn wait_for_high(&mut self) -> Result<(), T::Error> {
T::wait_for_high(self).await
}

type WaitForLowFuture<'a> = T::WaitForLowFuture<'a> where Self: 'a;

fn wait_for_low(&mut self) -> Self::WaitForLowFuture<'_> {
T::wait_for_low(self)
async fn wait_for_low(&mut self) -> Result<(), T::Error> {
T::wait_for_low(self).await
}

type WaitForRisingEdgeFuture<'a> = T::WaitForRisingEdgeFuture<'a> where Self: 'a;

fn wait_for_rising_edge(&mut self) -> Self::WaitForRisingEdgeFuture<'_> {
T::wait_for_rising_edge(self)
async fn wait_for_rising_edge(&mut self) -> Result<(), T::Error> {
T::wait_for_rising_edge(self).await
}

type WaitForFallingEdgeFuture<'a> = T::WaitForFallingEdgeFuture<'a> where Self: 'a;

fn wait_for_falling_edge(&mut self) -> Self::WaitForFallingEdgeFuture<'_> {
T::wait_for_falling_edge(self)
async fn wait_for_falling_edge(&mut self) -> Result<(), T::Error> {
T::wait_for_falling_edge(self).await
}

type WaitForAnyEdgeFuture<'a> = T::WaitForAnyEdgeFuture<'a> where Self: 'a;

fn wait_for_any_edge(&mut self) -> Self::WaitForAnyEdgeFuture<'_> {
T::wait_for_any_edge(self)
async fn wait_for_any_edge(&mut self) -> Result<(), T::Error> {
T::wait_for_any_edge(self).await
}
}
62 changes: 16 additions & 46 deletions embedded-hal-async/src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,13 @@
//! Since 7-bit addressing is the mode of the majority of I2C devices,
//! `SevenBitAddress` has been set as default mode and thus can be omitted if desired.
use core::future::Future;
pub use embedded_hal::i2c::Operation;
pub use embedded_hal::i2c::{
AddressMode, Error, ErrorKind, ErrorType, NoAcknowledgeSource, SevenBitAddress, TenBitAddress,
};

/// Async i2c
pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
/// Future returned by the `read` method.
type ReadFuture<'a>: Future<Output = Result<(), Self::Error>>
where
Self: 'a;

/// Reads enough bytes from slave with `address` to fill `buffer`
///
/// # I2C Events (contract)
Expand All @@ -47,12 +41,7 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
/// - `MAK` = master acknowledge
/// - `NMAK` = master no acknowledge
/// - `SP` = stop condition
fn read<'a>(&'a mut self, address: A, read: &'a mut [u8]) -> Self::ReadFuture<'a>;

/// Future returned by the `write` method.
type WriteFuture<'a>: Future<Output = Result<(), Self::Error>>
where
Self: 'a;
async fn read<'a>(&'a mut self, address: A, read: &'a mut [u8]) -> Result<(), Self::Error>;

/// Writes bytes to slave with address `address`
///
Expand All @@ -70,12 +59,7 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
/// - `SAK` = slave acknowledge
/// - `Bi` = ith byte of data
/// - `SP` = stop condition
fn write<'a>(&'a mut self, address: A, write: &'a [u8]) -> Self::WriteFuture<'a>;

/// Future returned by the `write_read` method.
type WriteReadFuture<'a>: Future<Output = Result<(), Self::Error>>
where
Self: 'a;
async fn write<'a>(&'a mut self, address: A, write: &'a [u8]) -> Result<(), Self::Error>;

/// Writes bytes to slave with address `address` and then reads enough bytes to fill `read` *in a
/// single transaction*.
Expand All @@ -99,18 +83,12 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
/// - `MAK` = master acknowledge
/// - `NMAK` = master no acknowledge
/// - `SP` = stop condition
fn write_read<'a>(
async fn write_read<'a>(
&'a mut self,
address: A,
write: &'a [u8],
read: &'a mut [u8],
) -> Self::WriteReadFuture<'a>;

/// Future returned by the `transaction` method.
type TransactionFuture<'a, 'b>: Future<Output = Result<(), Self::Error>>
where
Self: 'a,
'b: 'a;
) -> Result<(), Self::Error>;

/// Execute the provided operations on the I2C bus as a single transaction.
///
Expand All @@ -125,44 +103,36 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
/// - `SAD+R/W` = slave address followed by bit 1 to indicate reading or 0 to indicate writing
/// - `SR` = repeated start condition
/// - `SP` = stop condition
fn transaction<'a, 'b>(
async fn transaction<'a, 'b>(
&'a mut self,
address: A,
operations: &'a mut [Operation<'b>],
) -> Self::TransactionFuture<'a, 'b>;
) -> Result<(), Self::Error>;
}

impl<A: AddressMode, T: I2c<A>> I2c<A> for &mut T {
type ReadFuture<'a> = T::ReadFuture<'a> where Self: 'a;

fn read<'a>(&'a mut self, address: A, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
T::read(self, address, buffer)
async fn read<'a>(&'a mut self, address: A, buffer: &'a mut [u8]) -> Result<(), T::Error> {
T::read(self, address, buffer).await
}

type WriteFuture<'a> = T::WriteFuture<'a> where Self: 'a;

fn write<'a>(&'a mut self, address: A, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
T::write(self, address, bytes)
async fn write<'a>(&'a mut self, address: A, bytes: &'a [u8]) -> Result<(), T::Error> {
T::write(self, address, bytes).await
}

type WriteReadFuture<'a> = T::WriteReadFuture<'a> where Self: 'a;

fn write_read<'a>(
async fn write_read<'a>(
&'a mut self,
address: A,
bytes: &'a [u8],
buffer: &'a mut [u8],
) -> Self::WriteReadFuture<'a> {
T::write_read(self, address, bytes, buffer)
) -> Result<(), T::Error> {
T::write_read(self, address, bytes, buffer).await
}

type TransactionFuture<'a, 'b> = T::TransactionFuture<'a, 'b> where Self: 'a, 'b: 'a;

fn transaction<'a, 'b>(
async fn transaction<'a, 'b>(
&'a mut self,
address: A,
operations: &'a mut [Operation<'b>],
) -> Self::TransactionFuture<'a, 'b> {
T::transaction(self, address, operations)
) -> Result<(), T::Error> {
T::transaction(self, address, operations).await
}
}
1 change: 1 addition & 0 deletions embedded-hal-async/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#![warn(missing_docs)]
#![no_std]
#![feature(type_alias_impl_trait)]
#![feature(async_fn_in_trait)]

pub mod delay;
pub mod digital;
Expand Down
Loading

0 comments on commit 703896b

Please sign in to comment.