627: Update Rust nightly, embedded-hal 1.0, embedded-hal-async. r=Dirbaio a=Dirbaio

Includes the SpiDevice/SpiBus split.  https://github.com/rust-embedded/embedded-hal/pull/351
Includes the GAT where clause location change. https://github.com/rust-lang/rust/issues/89122


Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
This commit is contained in:
bors[bot] 2022-03-10 23:38:47 +00:00 committed by GitHub
commit db8050b388
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 732 additions and 855 deletions

View File

@ -97,7 +97,7 @@ impl<'a, S: PeripheralState> PeripheralMutex<'a, S> {
// Interrupts' priorities can only be changed with raw embassy `Interrupts`, // Interrupts' priorities can only be changed with raw embassy `Interrupts`,
// which can't safely store a `PeripheralMutex` across invocations. // which can't safely store a `PeripheralMutex` across invocations.
// - We can't have preempted a with() call because the irq is disabled during it. // - We can't have preempted a with() call because the irq is disabled during it.
let state = unsafe { &mut *(p as *mut S) }; let state = &mut *(p as *mut S);
state.on_interrupt(); state.on_interrupt();
}); });
irq.set_handler_context(state_ptr as *mut ()); irq.set_handler_context(state_ptr as *mut ());

View File

@ -18,8 +18,8 @@ log = { version = "0.4.14", optional = true }
embassy = { version = "0.1.0", path = "../embassy", default-features = false } embassy = { version = "0.1.0", path = "../embassy", default-features = false }
embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true } embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true }
embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.7", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"} embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2"}
embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common", default-features = false } embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common", default-features = false }
futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] } futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
embedded-hal = { version = "0.2", features = ["unproven"] } embedded-hal = { version = "0.2", features = ["unproven"] }

View File

@ -78,7 +78,7 @@ impl<'a> SubGhzRadio<'a> {
// This is safe because we only get interrupts when configured for, so // This is safe because we only get interrupts when configured for, so
// the radio will be awaiting on the signal at this point. If not, the ISR will // the radio will be awaiting on the signal at this point. If not, the ISR will
// anyway only adjust the state in the IRQ signal state. // anyway only adjust the state in the IRQ signal state.
let state = unsafe { &mut *(p as *mut StateInner<'a>) }; let state = &mut *(p as *mut StateInner<'a>);
state.on_interrupt(); state.on_interrupt();
}); });
irq.set_handler_context(state_ptr as *mut ()); irq.set_handler_context(state_ptr as *mut ());

View File

@ -20,7 +20,7 @@ pub trait RadioSwitch {
/// Semtech Sx127x radio peripheral /// Semtech Sx127x radio peripheral
pub struct Sx127xRadio<SPI, CS, RESET, E, I, RFS> pub struct Sx127xRadio<SPI, CS, RESET, E, I, RFS>
where where
SPI: ReadWrite<u8, Error = E> + 'static, SPI: SpiBus<u8, Error = E> + 'static,
E: 'static, E: 'static,
CS: OutputPin + 'static, CS: OutputPin + 'static,
RESET: OutputPin + 'static, RESET: OutputPin + 'static,
@ -42,7 +42,7 @@ pub enum State {
impl<SPI, CS, RESET, E, I, RFS> Sx127xRadio<SPI, CS, RESET, E, I, RFS> impl<SPI, CS, RESET, E, I, RFS> Sx127xRadio<SPI, CS, RESET, E, I, RFS>
where where
SPI: ReadWrite<u8, Error = E> + 'static, SPI: SpiBus<u8, Error = E> + 'static,
CS: OutputPin + 'static, CS: OutputPin + 'static,
RESET: OutputPin + 'static, RESET: OutputPin + 'static,
I: Wait + 'static, I: Wait + 'static,
@ -64,7 +64,7 @@ where
impl<SPI, CS, RESET, E, I, RFS> Timings for Sx127xRadio<SPI, CS, RESET, E, I, RFS> impl<SPI, CS, RESET, E, I, RFS> Timings for Sx127xRadio<SPI, CS, RESET, E, I, RFS>
where where
SPI: ReadWrite<u8, Error = E> + 'static, SPI: SpiBus<u8, Error = E> + 'static,
CS: OutputPin + 'static, CS: OutputPin + 'static,
RESET: OutputPin + 'static, RESET: OutputPin + 'static,
I: Wait + 'static, I: Wait + 'static,
@ -80,7 +80,7 @@ where
impl<SPI, CS, RESET, E, I, RFS> PhyRxTx for Sx127xRadio<SPI, CS, RESET, E, I, RFS> impl<SPI, CS, RESET, E, I, RFS> PhyRxTx for Sx127xRadio<SPI, CS, RESET, E, I, RFS>
where where
SPI: ReadWrite<u8, Error = E> + 'static, SPI: SpiBus<u8, Error = E> + 'static,
CS: OutputPin + 'static, CS: OutputPin + 'static,
E: 'static, E: 'static,
RESET: OutputPin + 'static, RESET: OutputPin + 'static,
@ -89,15 +89,14 @@ where
{ {
type PhyError = Sx127xError; type PhyError = Sx127xError;
type TxFuture<'m> type TxFuture<'m> = impl Future<Output = Result<u32, Self::PhyError>> + 'm
where where
SPI: 'm, SPI: 'm,
CS: 'm, CS: 'm,
RESET: 'm, RESET: 'm,
E: 'm, E: 'm,
I: 'm, I: 'm,
RFS: 'm, RFS: 'm;
= impl Future<Output = Result<u32, Self::PhyError>> + 'm;
fn tx<'m>(&'m mut self, config: TxConfig, buf: &'m [u8]) -> Self::TxFuture<'m> { fn tx<'m>(&'m mut self, config: TxConfig, buf: &'m [u8]) -> Self::TxFuture<'m> {
trace!("TX START"); trace!("TX START");
@ -137,15 +136,14 @@ where
} }
} }
type RxFuture<'m> type RxFuture<'m> = impl Future<Output = Result<(usize, RxQuality), Self::PhyError>> + 'm
where where
SPI: 'm, SPI: 'm,
CS: 'm, CS: 'm,
RESET: 'm, RESET: 'm,
E: 'm, E: 'm,
I: 'm, I: 'm,
RFS: 'm, RFS: 'm;
= impl Future<Output = Result<(usize, RxQuality), Self::PhyError>> + 'm;
fn rx<'m>(&'m mut self, config: RfConfig, buf: &'m mut [u8]) -> Self::RxFuture<'m> { fn rx<'m>(&'m mut self, config: RfConfig, buf: &'m mut [u8]) -> Self::RxFuture<'m> {
trace!("RX START"); trace!("RX START");

View File

@ -8,7 +8,7 @@
use bit_field::BitField; use bit_field::BitField;
use embassy::time::{Duration, Timer}; use embassy::time::{Duration, Timer};
use embedded_hal::digital::v2::OutputPin; use embedded_hal::digital::v2::OutputPin;
use embedded_hal_async::spi::ReadWrite; use embedded_hal_async::spi::SpiBus;
mod register; mod register;
use self::register::PaConfig; use self::register::PaConfig;
@ -48,7 +48,7 @@ const VERSION_CHECK: u8 = 0x09;
impl<SPI, CS, RESET, E> LoRa<SPI, CS, RESET> impl<SPI, CS, RESET, E> LoRa<SPI, CS, RESET>
where where
SPI: ReadWrite<u8, Error = E>, SPI: SpiBus<u8, Error = E>,
CS: OutputPin, CS: OutputPin,
RESET: OutputPin, RESET: OutputPin,
{ {

View File

@ -63,8 +63,8 @@ embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["n
embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" } embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.7", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
defmt = { version = "0.3", optional = true } defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true } log = { version = "0.4.14", optional = true }

View File

@ -108,7 +108,7 @@ unsafe fn handle_gpiote_interrupt() {
for i in 0..CHANNEL_COUNT { for i in 0..CHANNEL_COUNT {
if g.events_in[i].read().bits() != 0 { if g.events_in[i].read().bits() != 0 {
g.intenclr.write(|w| unsafe { w.bits(1 << i) }); g.intenclr.write(|w| w.bits(1 << i));
CHANNEL_WAKERS[i].wake(); CHANNEL_WAKERS[i].wake();
} }
} }
@ -481,102 +481,72 @@ mod eh1 {
} }
} }
#[cfg(all(feature = "unstable-traits", feature = "nightly"))] cfg_if::cfg_if! {
mod eh1a { if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
use super::*; use futures::FutureExt;
use futures::FutureExt;
impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Input<'d, T> { impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Input<'d, T> {
type WaitForHighFuture<'a> type WaitForHighFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> { fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> {
self.wait_for_high().map(Ok) self.wait_for_high().map(Ok)
}
type WaitForLowFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> {
self.wait_for_low().map(Ok)
}
type WaitForRisingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> {
self.wait_for_rising_edge().map(Ok)
}
type WaitForFallingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> {
self.wait_for_falling_edge().map(Ok)
}
type WaitForAnyEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> {
self.wait_for_any_edge().map(Ok)
}
} }
type WaitForLowFuture<'a> impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Flex<'d, T> {
where type WaitForHighFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> { fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> {
self.wait_for_low().map(Ok) self.wait_for_high().map(Ok)
} }
type WaitForRisingEdgeFuture<'a> type WaitForLowFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> { fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> {
self.wait_for_rising_edge().map(Ok) self.wait_for_low().map(Ok)
} }
type WaitForFallingEdgeFuture<'a> type WaitForRisingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> { fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> {
self.wait_for_falling_edge().map(Ok) self.wait_for_rising_edge().map(Ok)
} }
type WaitForAnyEdgeFuture<'a> type WaitForFallingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> { fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> {
self.wait_for_any_edge().map(Ok) self.wait_for_falling_edge().map(Ok)
} }
}
impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Flex<'d, T> { type WaitForAnyEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
type WaitForHighFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> { fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> {
self.wait_for_high().map(Ok) self.wait_for_any_edge().map(Ok)
} }
type WaitForLowFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> {
self.wait_for_low().map(Ok)
}
type WaitForRisingEdgeFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> {
self.wait_for_rising_edge().map(Ok)
}
type WaitForFallingEdgeFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> {
self.wait_for_falling_edge().map(Ok)
}
type WaitForAnyEdgeFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> {
self.wait_for_any_edge().map(Ok)
} }
} }
} }

View File

@ -455,43 +455,25 @@ mod eh1 {
type Error = Error; type Error = Error;
} }
impl<'d, T: Instance> embedded_hal_1::spi::blocking::Read<u8> for Spim<'d, T> { impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusFlush for Spim<'d, T> {
fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusRead<u8> for Spim<'d, T> {
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
self.blocking_transfer(words, &[]) self.blocking_transfer(words, &[])
} }
fn read_transaction(&mut self, words: &mut [&mut [u8]]) -> Result<(), Self::Error> {
for buf in words {
self.blocking_read(buf)?
}
Ok(())
}
} }
impl<'d, T: Instance> embedded_hal_1::spi::blocking::Write<u8> for Spim<'d, T> { impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusWrite<u8> for Spim<'d, T> {
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
self.blocking_write(words) self.blocking_write(words)
} }
fn write_transaction(&mut self, words: &[&[u8]]) -> Result<(), Self::Error> {
for buf in words {
self.blocking_write(buf)?
}
Ok(())
}
fn write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error>
where
WI: IntoIterator<Item = u8>,
{
for w in words {
self.blocking_write(&[w])?;
}
Ok(())
}
} }
impl<'d, T: Instance> embedded_hal_1::spi::blocking::ReadWrite<u8> for Spim<'d, T> { impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBus<u8> for Spim<'d, T> {
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
self.blocking_transfer(read, write) self.blocking_transfer(read, write)
} }
@ -499,128 +481,51 @@ mod eh1 {
fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
self.blocking_transfer_in_place(words) self.blocking_transfer_in_place(words)
} }
fn transaction<'a>(
&mut self,
operations: &mut [embedded_hal_1::spi::blocking::Operation<'a, u8>],
) -> Result<(), Self::Error> {
use embedded_hal_1::spi::blocking::Operation;
for o in operations {
match o {
Operation::Read(b) => self.blocking_read(b)?,
Operation::Write(b) => self.blocking_write(b)?,
Operation::Transfer(r, w) => self.blocking_transfer(r, w)?,
Operation::TransferInPlace(b) => self.blocking_transfer_in_place(b)?,
}
}
Ok(())
}
} }
} }
#[cfg(all(feature = "unstable-traits", feature = "nightly"))] cfg_if::cfg_if! {
mod eh1a { if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
use super::*; use core::future::Future;
use core::future::Future;
impl<'d, T: Instance> embedded_hal_async::spi::Read<u8> for Spim<'d, T> { impl<'d, T: Instance> embedded_hal_async::spi::SpiBusFlush for Spim<'d, T> {
type ReadFuture<'a> type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn read<'a>(&'a mut self, words: &'a mut [u8]) -> Self::ReadFuture<'a> { fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
self.read(words) async move { Ok(()) }
}
type ReadTransactionFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn read_transaction<'a>(
&'a mut self,
words: &'a mut [&'a mut [u8]],
) -> Self::ReadTransactionFuture<'a> {
async move {
for buf in words {
self.read(buf).await?
}
Ok(())
} }
} }
}
impl<'d, T: Instance> embedded_hal_async::spi::Write<u8> for Spim<'d, T> { impl<'d, T: Instance> embedded_hal_async::spi::SpiBusRead<u8> for Spim<'d, T> {
type WriteFuture<'a> type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { fn read<'a>(&'a mut self, words: &'a mut [u8]) -> Self::ReadFuture<'a> {
self.write(data) self.read(words)
}
type WriteTransactionFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn write_transaction<'a>(
&'a mut self,
words: &'a [&'a [u8]],
) -> Self::WriteTransactionFuture<'a> {
async move {
for buf in words {
self.write(buf).await?
}
Ok(())
} }
} }
}
impl<'d, T: Instance> embedded_hal_async::spi::ReadWrite<u8> for Spim<'d, T> { impl<'d, T: Instance> embedded_hal_async::spi::SpiBusWrite<u8> for Spim<'d, T> {
type TransferFuture<'a> type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> { fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
self.transfer(rx, tx) self.write(data)
}
} }
type TransferInPlaceFuture<'a> impl<'d, T: Instance> embedded_hal_async::spi::SpiBus<u8> for Spim<'d, T> {
where type TransferFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn transfer_in_place<'a>( fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> {
&'a mut self, self.transfer(rx, tx)
words: &'a mut [u8], }
) -> Self::TransferInPlaceFuture<'a> {
self.transfer_in_place(words)
}
type TransactionFuture<'a> type TransferInPlaceFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn transaction<'a>( fn transfer_in_place<'a>(
&'a mut self, &'a mut self,
operations: &'a mut [embedded_hal_async::spi::Operation<'a, u8>], words: &'a mut [u8],
) -> Self::TransactionFuture<'a> { ) -> Self::TransferInPlaceFuture<'a> {
use embedded_hal_1::spi::blocking::Operation; self.transfer_in_place(words)
async move {
for o in operations {
match o {
Operation::Read(b) => self.read(b).await?,
Operation::Write(b) => self.write(b).await?,
Operation::Transfer(r, w) => self.transfer(r, w).await?,
Operation::TransferInPlace(b) => self.transfer_in_place(b).await?,
}
}
Ok(())
} }
} }
} }

View File

@ -743,52 +743,43 @@ mod eh1 {
} }
} }
#[cfg(all(feature = "unstable-traits", feature = "nightly"))] cfg_if::cfg_if! {
impl<'d, T: Instance> embedded_hal_async::i2c::I2c for Twim<'d, T> { if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
type ReadFuture<'a> impl<'d, T: Instance> embedded_hal_async::i2c::I2c for Twim<'d, T> {
where type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
self.read(address, buffer) self.read(address, buffer)
} }
type WriteFuture<'a> type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> { fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
self.write(address, bytes) self.write(address, bytes)
} }
type WriteReadFuture<'a> type WriteReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn write_read<'a>( fn write_read<'a>(
&'a mut self, &'a mut self,
address: u8, address: u8,
wr_buffer: &'a [u8], wr_buffer: &'a [u8],
rd_buffer: &'a mut [u8], rd_buffer: &'a mut [u8],
) -> Self::WriteReadFuture<'a> { ) -> Self::WriteReadFuture<'a> {
self.write_read(address, wr_buffer, rd_buffer) self.write_read(address, wr_buffer, rd_buffer)
} }
type TransactionFuture<'a> type TransactionFuture<'a, 'b> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a, 'b: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn transaction<'a>( fn transaction<'a, 'b>(
&'a mut self, &'a mut self,
address: u8, address: u8,
operations: &mut [embedded_hal_async::i2c::Operation<'a>], operations: &'a mut [embedded_hal_async::i2c::Operation<'b>],
) -> Self::TransactionFuture<'a> { ) -> Self::TransactionFuture<'a, 'b> {
let _ = address; let _ = address;
let _ = operations; let _ = operations;
async move { todo!() } async move { todo!() }
}
}
} }
} }

View File

@ -934,105 +934,78 @@ mod eh1 {
} }
} }
#[cfg(all(feature = "unstable-traits", feature = "nightly"))] cfg_if::cfg_if! {
mod eh1a { if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
use super::*; use core::future::Future;
use core::future::Future;
impl<'d, T: Instance> embedded_hal_async::serial::Read for Uarte<'d, T> { impl<'d, T: Instance> embedded_hal_async::serial::Read for Uarte<'d, T> {
type ReadFuture<'a> type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
self.read(buffer) self.read(buffer)
} }
}
impl<'d, T: Instance> embedded_hal_async::serial::Write for Uarte<'d, T> {
type WriteFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> {
self.write(buffer)
} }
type FlushFuture<'a> impl<'d, T: Instance> embedded_hal_async::serial::Write for Uarte<'d, T> {
where type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> {
async move { Ok(()) } self.write(buffer)
} }
}
impl<'d, T: Instance> embedded_hal_async::serial::Write for UarteTx<'d, T> { type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
type WriteFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> { fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
self.write(buffer) async move { Ok(()) }
}
} }
type FlushFuture<'a> impl<'d, T: Instance> embedded_hal_async::serial::Write for UarteTx<'d, T> {
where type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> {
async move { Ok(()) } self.write(buffer)
} }
}
impl<'d, T: Instance> embedded_hal_async::serial::Read for UarteRx<'d, T> { type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
type ReadFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
self.read(buffer) async move { Ok(()) }
} }
}
impl<'d, U: Instance, T: TimerInstance> embedded_hal_async::serial::Read
for UarteWithIdle<'d, U, T>
{
type ReadFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
self.read(buffer)
}
}
impl<'d, U: Instance, T: TimerInstance> embedded_hal_async::serial::Write
for UarteWithIdle<'d, U, T>
{
type WriteFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> {
self.write(buffer)
} }
type FlushFuture<'a> impl<'d, T: Instance> embedded_hal_async::serial::Read for UarteRx<'d, T> {
where type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
async move { Ok(()) } self.read(buffer)
}
}
impl<'d, U: Instance, T: TimerInstance> embedded_hal_async::serial::Read
for UarteWithIdle<'d, U, T>
{
type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
self.read(buffer)
}
}
impl<'d, U: Instance, T: TimerInstance> embedded_hal_async::serial::Write
for UarteWithIdle<'d, U, T>
{
type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> {
self.write(buffer)
}
type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
async move { Ok(()) }
}
} }
} }
} }

View File

@ -34,5 +34,5 @@ rp2040-pac2 = { git = "https://github.com/embassy-rs/rp2040-pac2", rev="9ad7223a
#rp2040-pac2 = { path = "../../rp/rp2040-pac2", features = ["rt"] } #rp2040-pac2 = { path = "../../rp/rp2040-pac2", features = ["rt"] }
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.7", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}

View File

@ -342,43 +342,25 @@ mod eh1 {
type Error = Error; type Error = Error;
} }
impl<'d, T: Instance> embedded_hal_1::spi::blocking::Read<u8> for Spi<'d, T> { impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusFlush for Spi<'d, T> {
fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusRead<u8> for Spi<'d, T> {
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
self.blocking_transfer(words, &[]) self.blocking_transfer(words, &[])
} }
fn read_transaction(&mut self, words: &mut [&mut [u8]]) -> Result<(), Self::Error> {
for buf in words {
self.blocking_read(buf)?
}
Ok(())
}
} }
impl<'d, T: Instance> embedded_hal_1::spi::blocking::Write<u8> for Spi<'d, T> { impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusWrite<u8> for Spi<'d, T> {
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
self.blocking_write(words) self.blocking_write(words)
} }
fn write_transaction(&mut self, words: &[&[u8]]) -> Result<(), Self::Error> {
for buf in words {
self.blocking_write(buf)?
}
Ok(())
}
fn write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error>
where
WI: IntoIterator<Item = u8>,
{
for w in words {
self.blocking_write(&[w])?;
}
Ok(())
}
} }
impl<'d, T: Instance> embedded_hal_1::spi::blocking::ReadWrite<u8> for Spi<'d, T> { impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBus<u8> for Spi<'d, T> {
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
self.blocking_transfer(read, write) self.blocking_transfer(read, write)
} }
@ -386,21 +368,5 @@ mod eh1 {
fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
self.blocking_transfer_in_place(words) self.blocking_transfer_in_place(words)
} }
fn transaction<'a>(
&mut self,
operations: &mut [embedded_hal_1::spi::blocking::Operation<'a, u8>],
) -> Result<(), Self::Error> {
use embedded_hal_1::spi::blocking::Operation;
for o in operations {
match o {
Operation::Read(b) => self.blocking_read(b)?,
Operation::Write(b) => self.blocking_write(b)?,
Operation::Transfer(r, w) => self.blocking_transfer(r, w)?,
Operation::TransferInPlace(b) => self.blocking_transfer_in_place(b)?,
}
}
Ok(())
}
} }
} }

View File

@ -35,8 +35,8 @@ embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
embassy-net = { version = "0.1.0", path = "../embassy-net", default-features = false, optional = true } embassy-net = { version = "0.1.0", path = "../embassy-net", default-features = false, optional = true }
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.7", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
defmt = { version = "0.3", optional = true } defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true } log = { version = "0.4.14", optional = true }

View File

@ -45,7 +45,7 @@ pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> {
macro_rules! config_pins { macro_rules! config_pins {
($($pin:ident),*) => { ($($pin:ident),*) => {
// NOTE(unsafe) Exclusive access to the registers // NOTE(unsafe) Exclusive access to the registers
critical_section::with(|_| unsafe { critical_section::with(|_| {
$( $(
$pin.set_as_af($pin.af_num(), AFType::OutputPushPull); $pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
$pin.set_speed(Speed::VeryHigh); $pin.set_speed(Speed::VeryHigh);

View File

@ -36,7 +36,7 @@ pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> {
macro_rules! config_pins { macro_rules! config_pins {
($($pin:ident),*) => { ($($pin:ident),*) => {
// NOTE(unsafe) Exclusive access to the registers // NOTE(unsafe) Exclusive access to the registers
critical_section::with(|_| unsafe { critical_section::with(|_| {
$( $(
$pin.set_as_af($pin.af_num(), AFType::OutputPushPull); $pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
$pin.set_speed(Speed::VeryHigh); $pin.set_speed(Speed::VeryHigh);

View File

@ -165,55 +165,40 @@ mod eh1 {
} }
} }
} }
#[cfg(all(feature = "unstable-traits", feature = "nightly"))] cfg_if::cfg_if! {
mod eh1a { if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
use super::*; use futures::FutureExt;
use futures::FutureExt;
impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for ExtiInput<'d, T> { impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for ExtiInput<'d, T> {
type WaitForHighFuture<'a> type WaitForHighFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> { fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> {
self.wait_for_high().map(Ok) self.wait_for_high().map(Ok)
} }
type WaitForLowFuture<'a> type WaitForLowFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> { fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> {
self.wait_for_low().map(Ok) self.wait_for_low().map(Ok)
} }
type WaitForRisingEdgeFuture<'a> type WaitForRisingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> { fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> {
self.wait_for_rising_edge().map(Ok) self.wait_for_rising_edge().map(Ok)
} }
type WaitForFallingEdgeFuture<'a> type WaitForFallingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> { fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> {
self.wait_for_falling_edge().map(Ok) self.wait_for_falling_edge().map(Ok)
} }
type WaitForAnyEdgeFuture<'a> type WaitForAnyEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> { fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> {
self.wait_for_any_edge().map(Ok) self.wait_for_any_edge().map(Ok)
}
} }
} }
} }

View File

@ -917,58 +917,46 @@ mod eh1 {
} }
} }
#[cfg(all(feature = "unstable-traits", feature = "nightly"))] cfg_if::cfg_if! {
mod eh1a { if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
use super::super::{RxDma, TxDma}; use super::{RxDma, TxDma};
use super::*; use core::future::Future;
use core::future::Future;
impl<'d, T: Instance, TXDMA: TxDma<T>, RXDMA: RxDma<T>> embedded_hal_async::i2c::I2c impl<'d, T: Instance, TXDMA: TxDma<T>, RXDMA: RxDma<T>> embedded_hal_async::i2c::I2c
for I2c<'d, T, TXDMA, RXDMA> for I2c<'d, T, TXDMA, RXDMA>
{ {
type ReadFuture<'a> type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
self.read(address, buffer) self.read(address, buffer)
} }
type WriteFuture<'a> type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
Self: 'a, self.write(address, bytes)
= impl Future<Output = Result<(), Self::Error>> + 'a; }
fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
self.write(address, bytes)
}
type WriteReadFuture<'a> type WriteReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where fn write_read<'a>(
Self: 'a, &'a mut self,
= impl Future<Output = Result<(), Self::Error>> + 'a; address: u8,
fn write_read<'a>( bytes: &'a [u8],
&'a mut self, buffer: &'a mut [u8],
address: u8, ) -> Self::WriteReadFuture<'a> {
bytes: &'a [u8], self.write_read(address, bytes, buffer)
buffer: &'a mut [u8], }
) -> Self::WriteReadFuture<'a> {
self.write_read(address, bytes, buffer)
}
type TransactionFuture<'a> type TransactionFuture<'a, 'b> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a, 'b: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn transaction<'a>( fn transaction<'a, 'b>(
&'a mut self, &'a mut self,
address: u8, address: u8,
operations: &mut [embedded_hal_async::i2c::Operation<'a>], operations: &'a mut [embedded_hal_async::i2c::Operation<'b>],
) -> Self::TransactionFuture<'a> { ) -> Self::TransactionFuture<'a, 'b> {
let _ = address; let _ = address;
let _ = operations; let _ = operations;
async move { todo!() } async move { todo!() }
}
} }
} }
} }

View File

@ -445,6 +445,15 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
Ok(()) Ok(())
} }
pub fn blocking_read<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> {
self.set_word_size(W::WORDSIZE);
let regs = T::regs();
for word in words.iter_mut() {
*word = transfer_word(regs, W::default())?;
}
Ok(())
}
pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> {
self.set_word_size(W::WORDSIZE); self.set_word_size(W::WORDSIZE);
let regs = T::regs(); let regs = T::regs();
@ -453,6 +462,21 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
} }
Ok(()) Ok(())
} }
pub fn blocking_transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> {
self.set_word_size(W::WORDSIZE);
let regs = T::regs();
let len = read.len().max(write.len());
for i in 0..len {
let wb = write.get(i).copied().unwrap_or_default();
let rb = transfer_word(regs, wb)?;
if let Some(r) = read.get_mut(i) {
*r = rb;
}
}
Ok(())
}
} }
impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> {
@ -669,6 +693,34 @@ mod eh1 {
type Error = Error; type Error = Error;
} }
impl<'d, T: Instance, Tx, Rx> embedded_hal_1::spi::blocking::SpiBusFlush for Spi<'d, T, Tx, Rx> {
fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusRead<u8> for Spi<'d, T, NoDma, NoDma> {
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
self.blocking_read(words)
}
}
impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusWrite<u8> for Spi<'d, T, NoDma, NoDma> {
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
self.blocking_write(words)
}
}
impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBus<u8> for Spi<'d, T, NoDma, NoDma> {
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
self.blocking_transfer(read, write)
}
fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
self.blocking_transfer_in_place(words)
}
}
impl embedded_hal_1::spi::Error for Error { impl embedded_hal_1::spi::Error for Error {
fn kind(&self) -> embedded_hal_1::spi::ErrorKind { fn kind(&self) -> embedded_hal_1::spi::ErrorKind {
match *self { match *self {
@ -681,115 +733,55 @@ mod eh1 {
} }
} }
#[cfg(all(feature = "unstable-traits", feature = "nightly"))] cfg_if::cfg_if! {
mod eh1a { if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
use super::*; use core::future::Future;
use core::future::Future; impl<'d, T: Instance, Tx, Rx> embedded_hal_async::spi::SpiBusFlush for Spi<'d, T, Tx, Rx> {
type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
impl<'d, T: Instance, Tx: TxDma<T>, Rx> embedded_hal_async::spi::Write<u8> for Spi<'d, T, Tx, Rx> { fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
type WriteFuture<'a> async { Ok(()) }
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
self.write(data)
}
type WriteTransactionFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn write_transaction<'a>(
&'a mut self,
words: &'a [&'a [u8]],
) -> Self::WriteTransactionFuture<'a> {
async move {
for buf in words {
self.write(buf).await?
}
Ok(())
} }
} }
}
impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>> embedded_hal_async::spi::Read<u8> impl<'d, T: Instance, Tx: TxDma<T>, Rx> embedded_hal_async::spi::SpiBusWrite<u8>
for Spi<'d, T, Tx, Rx> for Spi<'d, T, Tx, Rx>
{ {
type ReadFuture<'a> type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
self.read(data) self.write(data)
}
type ReadTransactionFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn read_transaction<'a>(
&'a mut self,
words: &'a mut [&'a mut [u8]],
) -> Self::ReadTransactionFuture<'a> {
async move {
for buf in words {
self.read(buf).await?
}
Ok(())
} }
} }
}
impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>> embedded_hal_async::spi::ReadWrite<u8> impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>> embedded_hal_async::spi::SpiBusRead<u8>
for Spi<'d, T, Tx, Rx> for Spi<'d, T, Tx, Rx>
{ {
type TransferFuture<'a> type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> { fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
self.transfer(rx, tx) self.read(data)
}
} }
type TransferInPlaceFuture<'a> impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>> embedded_hal_async::spi::SpiBus<u8>
where for Spi<'d, T, Tx, Rx>
Self: 'a, {
= impl Future<Output = Result<(), Self::Error>> + 'a; type TransferFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
fn transfer_in_place<'a>( fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> {
&'a mut self, self.transfer(rx, tx)
words: &'a mut [u8], }
) -> Self::TransferInPlaceFuture<'a> {
// TODO: Implement async version
let result = self.blocking_transfer_in_place(words);
async move { result }
}
type TransactionFuture<'a> type TransferInPlaceFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn transaction<'a>( fn transfer_in_place<'a>(
&'a mut self, &'a mut self,
operations: &'a mut [embedded_hal_async::spi::Operation<'a, u8>], words: &'a mut [u8],
) -> Self::TransactionFuture<'a> { ) -> Self::TransferInPlaceFuture<'a> {
use embedded_hal_1::spi::blocking::Operation; // TODO: Implement async version
async move { let result = self.blocking_transfer_in_place(words);
for o in operations { async move { result }
match o {
Operation::Read(b) => self.read(b).await?,
Operation::Write(b) => self.write(b).await?,
Operation::Transfer(r, w) => self.transfer(r, w).await?,
Operation::TransferInPlace(b) => self.transfer_in_place(b).await?,
}
}
Ok(())
} }
} }
} }
@ -862,7 +854,7 @@ pub(crate) mod sealed {
} }
} }
pub trait Word: Copy + 'static + sealed::Word {} pub trait Word: Copy + 'static + sealed::Word + Default {}
impl Word for u8 {} impl Word for u8 {}
impl Word for u16 {} impl Word for u16 {}

View File

@ -275,45 +275,36 @@ mod eh1 {
} }
} }
#[cfg(all(feature = "unstable-traits", feature = "nightly"))] cfg_if::cfg_if! {
mod eh1a { if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
use super::*; use core::future::Future;
use core::future::Future;
impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Write for Uart<'d, T, TxDma, RxDma> impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Write for Uart<'d, T, TxDma, RxDma>
where
TxDma: crate::usart::TxDma<T>,
{
type WriteFuture<'a>
where where
Self: 'a, TxDma: crate::usart::TxDma<T>,
= impl Future<Output = Result<(), Self::Error>> + 'a; {
type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
self.write(buf) self.write(buf)
}
type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
async move { Ok(()) }
}
} }
type FlushFuture<'a> impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Read for Uart<'d, T, TxDma, RxDma>
where where
Self: 'a, RxDma: crate::usart::RxDma<T>,
= impl Future<Output = Result<(), Self::Error>> + 'a; {
type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
async move { Ok(()) } self.read(buf)
} }
}
impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Read for Uart<'d, T, TxDma, RxDma>
where
RxDma: crate::usart::RxDma<T>,
{
type ReadFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
self.read(buf)
} }
} }
} }

View File

@ -9,8 +9,8 @@ std = []
[dependencies] [dependencies]
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy" } embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.7", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2" }
embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"} embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2"}
embedded-storage = "0.3.0" embedded-storage = "0.3.0"
embedded-storage-async = "0.3.0" embedded-storage-async = "0.3.0"
nb = "1.0.0" nb = "1.0.0"

View File

@ -39,18 +39,9 @@ where
+ blocking::i2c::Read<Error = E> + blocking::i2c::Read<Error = E>
+ blocking::i2c::Write<Error = E>, + blocking::i2c::Write<Error = E>,
{ {
type WriteFuture<'a> type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
Self: 'a, type WriteReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
= impl Future<Output = Result<(), Self::Error>> + 'a;
type ReadFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
type WriteReadFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
async move { self.wrapped.read(address, buffer) } async move { self.wrapped.read(address, buffer) }
@ -69,16 +60,13 @@ where
async move { self.wrapped.write_read(address, bytes, buffer) } async move { self.wrapped.write_read(address, bytes, buffer) }
} }
type TransactionFuture<'a> type TransactionFuture<'a, 'b> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a, 'b: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn transaction<'a>( fn transaction<'a, 'b>(
&'a mut self, &'a mut self,
address: u8, address: u8,
operations: &mut [embedded_hal_async::i2c::Operation<'a>], operations: &'a mut [embedded_hal_async::i2c::Operation<'b>],
) -> Self::TransactionFuture<'a> { ) -> Self::TransactionFuture<'a, 'b> {
let _ = address; let _ = address;
let _ = operations; let _ = operations;
async move { todo!() } async move { todo!() }
@ -97,15 +85,12 @@ where
type Error = E; type Error = E;
} }
impl<T, E> embedded_hal_async::spi::ReadWrite<u8> for BlockingAsync<T> impl<T, E> embedded_hal_async::spi::SpiBus<u8> for BlockingAsync<T>
where where
E: embedded_hal_1::spi::Error + 'static, E: embedded_hal_1::spi::Error + 'static,
T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>, T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
{ {
type TransferFuture<'a> type TransferFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn transfer<'a>(&'a mut self, read: &'a mut [u8], write: &'a [u8]) -> Self::TransferFuture<'a> { fn transfer<'a>(&'a mut self, read: &'a mut [u8], write: &'a [u8]) -> Self::TransferFuture<'a> {
async move { async move {
@ -118,37 +103,31 @@ where
} }
} }
type TransferInPlaceFuture<'a> type TransferInPlaceFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn transfer_in_place<'a>(&'a mut self, _: &'a mut [u8]) -> Self::TransferInPlaceFuture<'a> { fn transfer_in_place<'a>(&'a mut self, _: &'a mut [u8]) -> Self::TransferInPlaceFuture<'a> {
async move { todo!() } async move { todo!() }
} }
type TransactionFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn transaction<'a>(
&'a mut self,
_: &'a mut [embedded_hal_async::spi::Operation<'a, u8>],
) -> Self::TransactionFuture<'a> {
async move { todo!() }
}
} }
impl<T, E> embedded_hal_async::spi::Write<u8> for BlockingAsync<T> impl<T, E> embedded_hal_async::spi::SpiBusFlush for BlockingAsync<T>
where where
E: embedded_hal_1::spi::Error + 'static, E: embedded_hal_1::spi::Error + 'static,
T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>, T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
{ {
type WriteFuture<'a> type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a, fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
= impl Future<Output = Result<(), Self::Error>> + 'a; async move { Ok(()) }
}
}
impl<T, E> embedded_hal_async::spi::SpiBusWrite<u8> for BlockingAsync<T>
where
E: embedded_hal_1::spi::Error + 'static,
T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
{
type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
async move { async move {
@ -156,26 +135,14 @@ where
Ok(()) Ok(())
} }
} }
type WriteTransactionFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn write_transaction<'a>(&'a mut self, _: &'a [&'a [u8]]) -> Self::WriteTransactionFuture<'a> {
async move { todo!() }
}
} }
impl<T, E> embedded_hal_async::spi::Read<u8> for BlockingAsync<T> impl<T, E> embedded_hal_async::spi::SpiBusRead<u8> for BlockingAsync<T>
where where
E: embedded_hal_1::spi::Error + 'static, E: embedded_hal_1::spi::Error + 'static,
T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>, T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
{ {
type ReadFuture<'a> type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
async move { async move {
@ -183,18 +150,6 @@ where
Ok(()) Ok(())
} }
} }
type ReadTransactionFuture<'a>
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn read_transaction<'a>(
&'a mut self,
_: &'a mut [&'a mut [u8]],
) -> Self::ReadTransactionFuture<'a> {
async move { todo!() }
}
} }
// Uart implementatinos // Uart implementatinos
@ -211,10 +166,7 @@ where
T: serial::Read<u8, Error = E>, T: serial::Read<u8, Error = E>,
E: embedded_hal_1::serial::Error + 'static, E: embedded_hal_1::serial::Error + 'static,
{ {
type ReadFuture<'a> type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where T: 'a;
where
T: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
async move { async move {
let mut pos = 0; let mut pos = 0;
@ -238,18 +190,12 @@ where
T: blocking::serial::Write<u8, Error = E> + serial::Read<u8, Error = E>, T: blocking::serial::Write<u8, Error = E> + serial::Read<u8, Error = E>,
E: embedded_hal_1::serial::Error + 'static, E: embedded_hal_1::serial::Error + 'static,
{ {
type WriteFuture<'a> type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where T: 'a;
where
T: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
async move { self.wrapped.bwrite_all(buf) } async move { self.wrapped.bwrite_all(buf) }
} }
type FlushFuture<'a> type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where T: 'a;
where
T: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
async move { self.wrapped.bflush() } async move { self.wrapped.bflush() }
} }
@ -273,18 +219,12 @@ where
const WRITE_SIZE: usize = <T as NorFlash>::WRITE_SIZE; const WRITE_SIZE: usize = <T as NorFlash>::WRITE_SIZE;
const ERASE_SIZE: usize = <T as NorFlash>::ERASE_SIZE; const ERASE_SIZE: usize = <T as NorFlash>::ERASE_SIZE;
type WriteFuture<'a> type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn write<'a>(&'a mut self, offset: u32, data: &'a [u8]) -> Self::WriteFuture<'a> { fn write<'a>(&'a mut self, offset: u32, data: &'a [u8]) -> Self::WriteFuture<'a> {
async move { self.wrapped.write(offset, data) } async move { self.wrapped.write(offset, data) }
} }
type EraseFuture<'a> type EraseFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn erase<'a>(&'a mut self, from: u32, to: u32) -> Self::EraseFuture<'a> { fn erase<'a>(&'a mut self, from: u32, to: u32) -> Self::EraseFuture<'a> {
async move { self.wrapped.erase(from, to) } async move { self.wrapped.erase(from, to) }
} }
@ -295,10 +235,7 @@ where
T: ReadNorFlash, T: ReadNorFlash,
{ {
const READ_SIZE: usize = <T as ReadNorFlash>::READ_SIZE; const READ_SIZE: usize = <T as ReadNorFlash>::READ_SIZE;
type ReadFuture<'a> type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn read<'a>(&'a mut self, address: u32, data: &'a mut [u8]) -> Self::ReadFuture<'a> { fn read<'a>(&'a mut self, address: u32, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
async move { self.wrapped.read(address, data) } async move { self.wrapped.read(address, data) }
} }

View File

@ -55,8 +55,8 @@ defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true } log = { version = "0.4.14", optional = true }
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" } embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" }
embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.7", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
futures = { version = "0.3.17", default-features = false, features = [ "cfg-target-has-atomic", "unstable" ] } futures = { version = "0.3.17", default-features = false, features = [ "cfg-target-has-atomic", "unstable" ] }
pin-project = { version = "1.0.8", default-features = false } pin-project = { version = "1.0.8", default-features = false }

View File

@ -1,12 +1,7 @@
#![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)] #![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)]
#![cfg_attr( #![cfg_attr(
feature = "nightly", feature = "nightly",
feature( feature(generic_associated_types, type_alias_impl_trait)
const_fn_trait_bound,
const_fn_fn_ptr_basics,
generic_associated_types,
type_alias_impl_trait
)
)] )]
#![allow(clippy::new_without_default)] #![allow(clippy::new_without_default)]

View File

@ -31,32 +31,26 @@ mod eh1 {
} }
} }
#[cfg(all(feature = "unstable-traits", feature = "nightly"))] cfg_if::cfg_if! {
mod eh1a { if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
use super::*; use crate::time::Timer;
use crate::time::Timer; use core::future::Future;
use core::future::Future; use futures::FutureExt;
use futures::FutureExt;
impl embedded_hal_async::delay::DelayUs for Delay { impl embedded_hal_async::delay::DelayUs for Delay {
type Error = core::convert::Infallible; type Error = core::convert::Infallible;
type DelayUsFuture<'a> type DelayUsFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn delay_us(&mut self, micros: u32) -> Self::DelayUsFuture<'_> { fn delay_us(&mut self, micros: u32) -> Self::DelayUsFuture<'_> {
Timer::after(Duration::from_micros(micros as _)).map(Ok) Timer::after(Duration::from_micros(micros as _)).map(Ok)
} }
type DelayMsFuture<'a> type DelayMsFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
where
Self: 'a,
= impl Future<Output = Result<(), Self::Error>> + 'a;
fn delay_ms(&mut self, millis: u32) -> Self::DelayMsFuture<'_> { fn delay_ms(&mut self, millis: u32) -> Self::DelayMsFuture<'_> {
Timer::after(Duration::from_millis(millis as _)).map(Ok) Timer::after(Duration::from_millis(millis as _)).map(Ok)
}
} }
} }
} }

View File

@ -6,7 +6,7 @@ version = "0.1.0"
[features] [features]
default = ["nightly"] default = ["nightly"]
nightly = ["embassy-nrf/nightly"] nightly = ["embassy-nrf/nightly", "embassy-nrf/unstable-traits"]
[dependencies] [dependencies]
embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] }

View File

@ -1,6 +1,6 @@
[package] [package]
authors = ["Dario Nieuwenhuis <dirbaio@dirbaio.net>"] authors = ["Dario Nieuwenhuis <dirbaio@dirbaio.net>"]
edition = "2018" edition = "2021"
name = "embassy-rp-examples" name = "embassy-rp-examples"
version = "0.1.0" version = "0.1.0"
@ -15,9 +15,12 @@ defmt-rtt = "0.3"
cortex-m = "0.7.3" cortex-m = "0.7.3"
cortex-m-rt = "0.7.0" cortex-m-rt = "0.7.0"
embedded-hal = "0.2.6"
panic-probe = { version = "0.3", features = ["print-defmt"] } panic-probe = { version = "0.3", features = ["print-defmt"] }
futures = { version = "0.3.17", default-features = false, features = ["async-await", "cfg-target-has-atomic", "unstable"] } futures = { version = "0.3.17", default-features = false, features = ["async-await", "cfg-target-has-atomic", "unstable"] }
display-interface-spi = "0.4.1" display-interface-spi = "0.4.1"
embedded-graphics = "0.7.1" embedded-graphics = "0.7.1"
st7789 = "0.6.1" st7789 = "0.6.1"
embedded-hal = { version = "1.0.0-alpha.7", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2" }
display-interface = "0.4.1"
byte-slice-cast = { version = "1.2.0", default-features = false }

View File

@ -6,16 +6,14 @@
mod example_common; mod example_common;
use core::cell::RefCell; use core::cell::RefCell;
use core::fmt::Debug;
use defmt::*; use defmt::*;
use display_interface_spi::SPIInterfaceNoCS;
use embassy::executor::Spawner; use embassy::executor::Spawner;
use embassy::time::Delay; use embassy::time::Delay;
use embassy_rp::peripherals; use embassy_rp::gpio::{Level, Output};
use embassy_rp::spi; use embassy_rp::spi;
use embassy_rp::spi::Spi; use embassy_rp::spi::Spi;
use embassy_rp::{gpio, Peripherals}; use embassy_rp::Peripherals;
use embedded_graphics::image::{Image, ImageRawLE}; use embedded_graphics::image::{Image, ImageRawLE};
use embedded_graphics::mono_font::ascii::FONT_10X20; use embedded_graphics::mono_font::ascii::FONT_10X20;
use embedded_graphics::mono_font::MonoTextStyle; use embedded_graphics::mono_font::MonoTextStyle;
@ -23,9 +21,15 @@ use embedded_graphics::pixelcolor::Rgb565;
use embedded_graphics::prelude::*; use embedded_graphics::prelude::*;
use embedded_graphics::primitives::{PrimitiveStyleBuilder, Rectangle}; use embedded_graphics::primitives::{PrimitiveStyleBuilder, Rectangle};
use embedded_graphics::text::Text; use embedded_graphics::text::Text;
use gpio::{Level, Output};
use st7789::{Orientation, ST7789}; use st7789::{Orientation, ST7789};
use crate::my_display_interface::SPIDeviceInterface;
use crate::shared_spi::SpiDeviceWithCs;
use crate::touch::Touch;
//const DISPLAY_FREQ: u32 = 64_000_000;
const TOUCH_FREQ: u32 = 200_000;
#[embassy::main] #[embassy::main]
async fn main(_spawner: Spawner, p: Peripherals) { async fn main(_spawner: Spawner, p: Peripherals) {
info!("Hello World!"); info!("Hello World!");
@ -42,17 +46,16 @@ async fn main(_spawner: Spawner, p: Peripherals) {
// create SPI // create SPI
let mut config = spi::Config::default(); let mut config = spi::Config::default();
config.frequency = DISPLAY_FREQ; config.frequency = TOUCH_FREQ; // use the lowest freq
config.phase = spi::Phase::CaptureOnSecondTransition; config.phase = spi::Phase::CaptureOnSecondTransition;
config.polarity = spi::Polarity::IdleHigh; config.polarity = spi::Polarity::IdleHigh;
let spi = RefCell::new(SpiState { let spi_bus = RefCell::new(Spi::new(p.SPI1, clk, mosi, miso, config));
last_mode: SpiMode::Display,
spi: Spi::new(p.SPI1, clk, mosi, miso, config),
display_cs: Output::new(display_cs, Level::Low),
});
let mut touch = Touch::new(TouchSpi(&spi), Output::new(touch_cs, Level::High)); let display_spi = SpiDeviceWithCs::new(&spi_bus, Output::new(display_cs, Level::High));
let touch_spi = SpiDeviceWithCs::new(&spi_bus, Output::new(touch_cs, Level::High));
let mut touch = Touch::new(touch_spi);
let dcx = Output::new(dcx, Level::Low); let dcx = Output::new(dcx, Level::Low);
let rst = Output::new(rst, Level::Low); let rst = Output::new(rst, Level::Low);
@ -62,7 +65,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
let _bl = Output::new(bl, Level::High); let _bl = Output::new(bl, Level::High);
// display interface abstraction from SPI and DC // display interface abstraction from SPI and DC
let di = SPIInterfaceNoCS::new(DisplaySpi(&spi), dcx); let di = SPIDeviceInterface::new(display_spi, dcx);
// create driver // create driver
let mut display = ST7789::new(di, rst, 240, 320); let mut display = ST7789::new(di, rst, 240, 320);
@ -104,107 +107,293 @@ async fn main(_spawner: Spawner, p: Peripherals) {
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)] mod shared_spi {
enum SpiMode { use core::cell::RefCell;
Display, use core::fmt::Debug;
Touch,
}
struct SpiState { use embedded_hal::digital::blocking::OutputPin;
spi: Spi<'static, peripherals::SPI1>, use embedded_hal::spi;
display_cs: Output<'static, peripherals::PIN_9>, use embedded_hal::spi::blocking::SpiDevice;
last_mode: SpiMode, #[derive(Copy, Clone, Eq, PartialEq, Debug)]
} pub enum SpiDeviceWithCsError<BUS, CS> {
#[allow(unused)] // will probably use in the future when adding a flush() to SpiBus
Spi(BUS),
Cs(CS),
}
const DISPLAY_FREQ: u32 = 64_000_000; impl<BUS, CS> spi::Error for SpiDeviceWithCsError<BUS, CS>
const TOUCH_FREQ: u32 = 200_000; where
BUS: spi::Error + Debug,
struct DisplaySpi<'a>(&'a RefCell<SpiState>); CS: Debug,
impl<'a> embedded_hal::blocking::spi::Write<u8> for DisplaySpi<'a> { {
type Error = core::convert::Infallible; fn kind(&self) -> spi::ErrorKind {
match self {
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { Self::Spi(e) => e.kind(),
let this = &mut *self.0.borrow_mut(); Self::Cs(_) => spi::ErrorKind::Other,
if this.last_mode != SpiMode::Display { }
this.spi.set_frequency(DISPLAY_FREQ);
this.display_cs.set_low();
this.last_mode = SpiMode::Display;
} }
this.spi.write(words).unwrap();
Ok(())
} }
}
struct TouchSpi<'a>(&'a RefCell<SpiState>); pub struct SpiDeviceWithCs<'a, BUS, CS> {
impl<'a> embedded_hal::blocking::spi::Transfer<u8> for TouchSpi<'a> { bus: &'a RefCell<BUS>,
type Error = core::convert::Infallible; cs: CS,
}
fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { impl<'a, BUS, CS> SpiDeviceWithCs<'a, BUS, CS> {
let this = &mut *self.0.borrow_mut(); pub fn new(bus: &'a RefCell<BUS>, cs: CS) -> Self {
if this.last_mode != SpiMode::Touch { Self { bus, cs }
this.spi.set_frequency(TOUCH_FREQ);
this.display_cs.set_high();
this.last_mode = SpiMode::Touch;
} }
this.spi.transfer(words).unwrap();
Ok(words)
}
}
struct Calibration {
x1: i32,
x2: i32,
y1: i32,
y2: i32,
sx: i32,
sy: i32,
}
const CALIBRATION: Calibration = Calibration {
x1: 3880,
x2: 340,
y1: 262,
y2: 3850,
sx: 320,
sy: 240,
};
struct Touch<
SPI: embedded_hal::blocking::spi::Transfer<u8>,
CS: embedded_hal::digital::v2::OutputPin,
> {
spi: SPI,
cs: CS,
}
impl<SPI: embedded_hal::blocking::spi::Transfer<u8>, CS: embedded_hal::digital::v2::OutputPin>
Touch<SPI, CS>
where
SPI::Error: Debug,
CS::Error: Debug,
{
pub fn new(spi: SPI, cs: CS) -> Self {
Self { spi, cs }
} }
pub fn read(&mut self) -> Option<(i32, i32)> { impl<'a, BUS, CS> spi::ErrorType for SpiDeviceWithCs<'a, BUS, CS>
self.cs.set_low().unwrap(); where
let mut buf = [0x90, 0x00, 0x00, 0xd0, 0x00, 0x00]; BUS: spi::ErrorType,
self.spi.transfer(&mut buf).unwrap(); CS: OutputPin,
self.cs.set_high().unwrap(); {
type Error = SpiDeviceWithCsError<BUS::Error, CS::Error>;
}
let x = ((buf[1] as u32) << 5 | (buf[2] as u32) >> 3) as i32; impl<'a, BUS, CS> SpiDevice for SpiDeviceWithCs<'a, BUS, CS>
let y = ((buf[4] as u32) << 5 | (buf[5] as u32) >> 3) as i32; where
BUS: spi::blocking::SpiBusFlush,
CS: OutputPin,
{
type Bus = BUS;
let cal = &CALIBRATION; fn transaction<R>(
&mut self,
f: impl FnOnce(&mut Self::Bus) -> Result<R, BUS::Error>,
) -> Result<R, Self::Error> {
let mut bus = self.bus.borrow_mut();
self.cs.set_low().map_err(SpiDeviceWithCsError::Cs)?;
let x = ((x - cal.x1) * cal.sx / (cal.x2 - cal.x1)).clamp(0, cal.sx); let f_res = f(&mut bus);
let y = ((y - cal.y1) * cal.sy / (cal.y2 - cal.y1)).clamp(0, cal.sy);
if x == 0 && y == 0 { // On failure, it's important to still flush and deassert CS.
None let flush_res = bus.flush();
} else { let cs_res = self.cs.set_high();
Some((x, y))
let f_res = f_res.map_err(SpiDeviceWithCsError::Spi)?;
flush_res.map_err(SpiDeviceWithCsError::Spi)?;
cs_res.map_err(SpiDeviceWithCsError::Cs)?;
Ok(f_res)
}
}
}
/// Driver for the XPT2046 resistive touchscreen sensor
mod touch {
use embedded_hal::spi::blocking::{SpiBus, SpiBusRead, SpiBusWrite, SpiDevice};
struct Calibration {
x1: i32,
x2: i32,
y1: i32,
y2: i32,
sx: i32,
sy: i32,
}
const CALIBRATION: Calibration = Calibration {
x1: 3880,
x2: 340,
y1: 262,
y2: 3850,
sx: 320,
sy: 240,
};
pub struct Touch<SPI: SpiDevice> {
spi: SPI,
}
impl<SPI> Touch<SPI>
where
SPI: SpiDevice,
SPI::Bus: SpiBus,
{
pub fn new(spi: SPI) -> Self {
Self { spi }
}
pub fn read(&mut self) -> Option<(i32, i32)> {
let mut x = [0; 2];
let mut y = [0; 2];
self.spi
.transaction(|bus| {
bus.write(&[0x90])?;
bus.read(&mut x)?;
bus.write(&[0xd0])?;
bus.read(&mut y)?;
Ok(())
})
.unwrap();
let x = (u16::from_be_bytes(x) >> 3) as i32;
let y = (u16::from_be_bytes(y) >> 3) as i32;
let cal = &CALIBRATION;
let x = ((x - cal.x1) * cal.sx / (cal.x2 - cal.x1)).clamp(0, cal.sx);
let y = ((y - cal.y1) * cal.sy / (cal.y2 - cal.y1)).clamp(0, cal.sy);
if x == 0 && y == 0 {
None
} else {
Some((x, y))
}
}
}
}
mod my_display_interface {
use display_interface::{DataFormat, DisplayError, WriteOnlyDataCommand};
use embedded_hal::digital::blocking::OutputPin;
use embedded_hal::spi::blocking::{SpiBusWrite, SpiDevice};
/// SPI display interface.
///
/// This combines the SPI peripheral and a data/command pin
pub struct SPIDeviceInterface<SPI, DC> {
spi: SPI,
dc: DC,
}
impl<SPI, DC> SPIDeviceInterface<SPI, DC>
where
SPI: SpiDevice,
SPI::Bus: SpiBusWrite,
DC: OutputPin,
{
/// Create new SPI interface for communciation with a display driver
pub fn new(spi: SPI, dc: DC) -> Self {
Self { spi, dc }
}
}
impl<SPI, DC> WriteOnlyDataCommand for SPIDeviceInterface<SPI, DC>
where
SPI: SpiDevice,
SPI::Bus: SpiBusWrite,
DC: OutputPin,
{
fn send_commands(&mut self, cmds: DataFormat<'_>) -> Result<(), DisplayError> {
let r = self.spi.transaction(|bus| {
// 1 = data, 0 = command
if let Err(_) = self.dc.set_low() {
return Ok(Err(DisplayError::DCError));
}
// Send words over SPI
send_u8(bus, cmds)?;
Ok(Ok(()))
});
r.map_err(|_| DisplayError::BusWriteError)?
}
fn send_data(&mut self, buf: DataFormat<'_>) -> Result<(), DisplayError> {
let r = self.spi.transaction(|bus| {
// 1 = data, 0 = command
if let Err(_) = self.dc.set_high() {
return Ok(Err(DisplayError::DCError));
}
// Send words over SPI
send_u8(bus, buf)?;
Ok(Ok(()))
});
r.map_err(|_| DisplayError::BusWriteError)?
}
}
fn send_u8<T: SpiBusWrite>(spi: &mut T, words: DataFormat<'_>) -> Result<(), T::Error> {
match words {
DataFormat::U8(slice) => spi.write(slice),
DataFormat::U16(slice) => {
use byte_slice_cast::*;
spi.write(slice.as_byte_slice())
}
DataFormat::U16LE(slice) => {
use byte_slice_cast::*;
for v in slice.as_mut() {
*v = v.to_le();
}
spi.write(slice.as_byte_slice())
}
DataFormat::U16BE(slice) => {
use byte_slice_cast::*;
for v in slice.as_mut() {
*v = v.to_be();
}
spi.write(slice.as_byte_slice())
}
DataFormat::U8Iter(iter) => {
let mut buf = [0; 32];
let mut i = 0;
for v in iter.into_iter() {
buf[i] = v;
i += 1;
if i == buf.len() {
spi.write(&buf)?;
i = 0;
}
}
if i > 0 {
spi.write(&buf[..i])?;
}
Ok(())
}
DataFormat::U16LEIter(iter) => {
use byte_slice_cast::*;
let mut buf = [0; 32];
let mut i = 0;
for v in iter.map(u16::to_le) {
buf[i] = v;
i += 1;
if i == buf.len() {
spi.write(&buf.as_byte_slice())?;
i = 0;
}
}
if i > 0 {
spi.write(&buf[..i].as_byte_slice())?;
}
Ok(())
}
DataFormat::U16BEIter(iter) => {
use byte_slice_cast::*;
let mut buf = [0; 64];
let mut i = 0;
let len = buf.len();
for v in iter.map(u16::to_be) {
buf[i] = v;
i += 1;
if i == len {
spi.write(&buf.as_byte_slice())?;
i = 0;
}
}
if i > 0 {
spi.write(&buf[..i].as_byte_slice())?;
}
Ok(())
}
_ => unimplemented!(),
} }
} }
} }

View File

@ -8,7 +8,7 @@ resolver = "2"
[dependencies] [dependencies]
embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "unstable-traits"] } embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "unstable-traits"] }
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "usb-otg"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "usb-otg"] }
defmt = "0.3" defmt = "0.3"
defmt-rtt = "0.3" defmt-rtt = "0.3"

View File

@ -19,7 +19,7 @@ defmt-rtt = "0.3"
cortex-m = "0.7.3" cortex-m = "0.7.3"
cortex-m-rt = "0.7.0" cortex-m-rt = "0.7.0"
embedded-hal = "0.2.6" embedded-hal = "0.2.6"
embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"} embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2"}
panic-probe = { version = "0.3", features = ["print-defmt"] } panic-probe = { version = "0.3", features = ["print-defmt"] }
futures = { version = "0.3.17", default-features = false, features = ["async-await"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
heapless = { version = "0.7.5", default-features = false } heapless = { version = "0.7.5", default-features = false }

View File

@ -18,7 +18,7 @@ defmt-rtt = "0.3"
cortex-m = "0.7.3" cortex-m = "0.7.3"
cortex-m-rt = "0.7.0" cortex-m-rt = "0.7.0"
embedded-hal = "0.2.6" embedded-hal = "0.2.6"
embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"} embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2"}
panic-probe = { version = "0.3", features = ["print-defmt"] } panic-probe = { version = "0.3", features = ["print-defmt"] }
futures = { version = "0.3.17", default-features = false, features = ["async-await"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
heapless = { version = "0.7.5", default-features = false } heapless = { version = "0.7.5", default-features = false }

View File

@ -12,7 +12,7 @@ use embassy_stm32::spi::{Config, Spi};
use embassy_stm32::time::Hertz; use embassy_stm32::time::Hertz;
use embassy_stm32::Peripherals; use embassy_stm32::Peripherals;
use embassy_traits::adapter::BlockingAsync; use embassy_traits::adapter::BlockingAsync;
use embedded_hal_async::spi::ReadWrite; use embedded_hal_async::spi::SpiBus;
use example_common::*; use example_common::*;
#[embassy::main] #[embassy::main]

View File

@ -1,6 +1,6 @@
# Before upgrading check that everything is available on all tier1 targets here: # Before upgrading check that everything is available on all tier1 targets here:
# https://rust-lang.github.io/rustup-components-history # https://rust-lang.github.io/rustup-components-history
[toolchain] [toolchain]
channel = "nightly-2022-02-20" channel = "nightly-2022-03-10"
components = [ "rust-src", "rustfmt" ] components = [ "rust-src", "rustfmt" ]
targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabihf", "thumbv8m.main-none-eabihf", "wasm32-unknown-unknown" ] targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabihf", "thumbv8m.main-none-eabihf", "wasm32-unknown-unknown" ]

View File

@ -23,7 +23,7 @@ defmt-rtt = "0.3.0"
cortex-m = "0.7.3" cortex-m = "0.7.3"
cortex-m-rt = "0.7.0" cortex-m-rt = "0.7.0"
embedded-hal = "0.2.6" embedded-hal = "0.2.6"
embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"} embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2"}
panic-probe = { version = "0.3.0", features = ["print-defmt"] } panic-probe = { version = "0.3.0", features = ["print-defmt"] }
[profile.dev] [profile.dev]