Skip to content

Commit

Permalink
hal-async: fix warnings for latest nightly (1.75.0)
Browse files Browse the repository at this point in the history
Fixes `cargo check` warnings for the latest nightly version (`1.75.0`).

Recommended public API signatures for async trait functions has changed
to recommending the desugared version for compatibility with different
`async` runtimes.
  • Loading branch information
rmsyn committed Oct 15, 2023
1 parent 129282e commit 5034eda
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 84 deletions.
18 changes: 12 additions & 6 deletions embedded-hal-async/src/delay.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
//! Delays.

use core::future::Future;

/// Microsecond delay.
pub trait DelayUs {
/// Pauses execution for at minimum `us` microseconds. Pause can be longer
/// if the implementation requires it due to precision/timing issues.
async fn delay_us(&mut self, us: u32);
fn delay_us(&mut self, us: u32) -> impl Future<Output = ()>;

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

impl<T> DelayUs for &mut T
where
T: DelayUs + ?Sized,
{
#[inline]
async fn delay_us(&mut self, us: u32) {
T::delay_us(self, us).await;
fn delay_us(&mut self, us: u32) -> impl Future<Output = ()> {
async move {
T::delay_us(self, us).await;
}
}

#[inline]
async fn delay_ms(&mut self, ms: u32) {
T::delay_ms(self, ms).await;
fn delay_ms(&mut self, ms: u32) -> impl Future<Output = ()> {
async move {
T::delay_ms(self, ms).await;
}
}
}
32 changes: 17 additions & 15 deletions embedded-hal-async/src/digital.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,61 +16,63 @@
//! }
//! ```

use core::future::Future;

/// Asynchronously wait for GPIO pin state.
pub trait Wait: embedded_hal::digital::ErrorType {
/// 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.
async fn wait_for_high(&mut self) -> Result<(), Self::Error>;
fn wait_for_high(&mut self) -> impl Future<Output = 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.
async fn wait_for_low(&mut self) -> Result<(), Self::Error>;
fn wait_for_low(&mut self) -> impl Future<Output = 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.
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error>;
fn wait_for_rising_edge(&mut self) -> impl Future<Output = 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.
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error>;
fn wait_for_falling_edge(&mut self) -> impl Future<Output = Result<(), Self::Error>>;

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

impl<T: Wait + ?Sized> Wait for &mut T {
#[inline]
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
T::wait_for_high(self).await
fn wait_for_high(&mut self) -> impl Future<Output = Result<(), Self::Error>> {
async move { T::wait_for_high(self).await }
}

#[inline]
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
T::wait_for_low(self).await
fn wait_for_low(&mut self) -> impl Future<Output = Result<(), Self::Error>> {
async move { T::wait_for_low(self).await }
}

#[inline]
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
T::wait_for_rising_edge(self).await
fn wait_for_rising_edge(&mut self) -> impl Future<Output = Result<(), Self::Error>> {
async move { T::wait_for_rising_edge(self).await }
}

#[inline]
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
T::wait_for_falling_edge(self).await
fn wait_for_falling_edge(&mut self) -> impl Future<Output = Result<(), Self::Error>> {
async move { T::wait_for_falling_edge(self).await }
}

#[inline]
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
T::wait_for_any_edge(self).await
fn wait_for_any_edge(&mut self) -> impl Future<Output = Result<(), Self::Error>> {
async move { T::wait_for_any_edge(self).await }
}
}
66 changes: 41 additions & 25 deletions embedded-hal-async/src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
//! 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,
Expand All @@ -42,9 +44,15 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
/// - `NMAK` = master no acknowledge
/// - `SP` = stop condition
#[inline]
async fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> {
self.transaction(address, &mut [Operation::Read(read)])
.await
fn read(
&mut self,
address: A,
read: &mut [u8],
) -> impl Future<Output = Result<(), Self::Error>> {
async move {
self.transaction(address, &mut [Operation::Read(read)])
.await
}
}

/// Writes bytes to slave with address `address`.
Expand All @@ -64,9 +72,11 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
/// - `Bi` = ith byte of data
/// - `SP` = stop condition
#[inline]
async fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> {
self.transaction(address, &mut [Operation::Write(write)])
.await
fn write(&mut self, address: A, write: &[u8]) -> impl Future<Output = Result<(), Self::Error>> {
async move {
self.transaction(address, &mut [Operation::Write(write)])
.await
}
}

/// Writes bytes to slave with address `address` and then reads enough bytes to fill `read` *in a
Expand All @@ -92,17 +102,19 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
/// - `NMAK` = master no acknowledge
/// - `SP` = stop condition
#[inline]
async fn write_read(
fn write_read(
&mut self,
address: A,
write: &[u8],
read: &mut [u8],
) -> Result<(), Self::Error> {
self.transaction(
address,
&mut [Operation::Write(write), Operation::Read(read)],
)
.await
) -> impl Future<Output = Result<(), Self::Error>> {
async move {
self.transaction(
address,
&mut [Operation::Write(write), Operation::Read(read)],
)
.await
}
}

/// Execute the provided operations on the I2C bus as a single transaction.
Expand All @@ -118,40 +130,44 @@ 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
async fn transaction(
fn transaction(
&mut self,
address: A,
operations: &mut [Operation<'_>],
) -> Result<(), Self::Error>;
) -> impl Future<Output = Result<(), Self::Error>>;
}

impl<A: AddressMode, T: I2c<A> + ?Sized> I2c<A> for &mut T {
#[inline]
async fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> {
T::read(self, address, read).await
fn read(
&mut self,
address: A,
read: &mut [u8],
) -> impl Future<Output = Result<(), Self::Error>> {
async move { T::read(self, address, read).await }
}

#[inline]
async fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> {
T::write(self, address, write).await
fn write(&mut self, address: A, write: &[u8]) -> impl Future<Output = Result<(), Self::Error>> {
async move { T::write(self, address, write).await }
}

#[inline]
async fn write_read(
fn write_read(
&mut self,
address: A,
write: &[u8],
read: &mut [u8],
) -> Result<(), Self::Error> {
T::write_read(self, address, write, read).await
) -> impl Future<Output = Result<(), Self::Error>> {
async move { T::write_read(self, address, write, read).await }
}

#[inline]
async fn transaction(
fn transaction(
&mut self,
address: A,
operations: &mut [Operation<'_>],
) -> Result<(), Self::Error> {
T::transaction(self, address, operations).await
) -> impl Future<Output = Result<(), Self::Error>> {
async move { T::transaction(self, address, operations).await }
}
}
Loading

0 comments on commit 5034eda

Please sign in to comment.