diff --git a/embassy-hal-common/src/peripheral.rs b/embassy-hal-common/src/peripheral.rs index dcf9d3a2..89420a42 100644 --- a/embassy-hal-common/src/peripheral.rs +++ b/embassy-hal-common/src/peripheral.rs @@ -97,7 +97,7 @@ impl<'a, S: PeripheralState> PeripheralMutex<'a, S> { // Interrupts' priorities can only be changed with raw embassy `Interrupts`, // which can't safely store a `PeripheralMutex` across invocations. // - 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(); }); irq.set_handler_context(state_ptr as *mut ()); diff --git a/embassy-lora/Cargo.toml b/embassy-lora/Cargo.toml index c2764152..dfd26254 100644 --- a/embassy-lora/Cargo.toml +++ b/embassy-lora/Cargo.toml @@ -18,8 +18,8 @@ log = { version = "0.4.14", optional = true } embassy = { version = "0.1.0", path = "../embassy", default-features = false } 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-async = { version = "0.0.1", 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", optional = true} +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 } futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] } embedded-hal = { version = "0.2", features = ["unproven"] } diff --git a/embassy-lora/src/stm32wl/mod.rs b/embassy-lora/src/stm32wl/mod.rs index 783140cb..7dc750cf 100644 --- a/embassy-lora/src/stm32wl/mod.rs +++ b/embassy-lora/src/stm32wl/mod.rs @@ -78,7 +78,7 @@ impl<'a> SubGhzRadio<'a> { // 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 // 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(); }); irq.set_handler_context(state_ptr as *mut ()); diff --git a/embassy-lora/src/sx127x/mod.rs b/embassy-lora/src/sx127x/mod.rs index 6a15dab8..c70f3358 100644 --- a/embassy-lora/src/sx127x/mod.rs +++ b/embassy-lora/src/sx127x/mod.rs @@ -20,7 +20,7 @@ pub trait RadioSwitch { /// Semtech Sx127x radio peripheral pub struct Sx127xRadio where - SPI: ReadWrite + 'static, + SPI: SpiBus + 'static, E: 'static, CS: OutputPin + 'static, RESET: OutputPin + 'static, @@ -42,7 +42,7 @@ pub enum State { impl Sx127xRadio where - SPI: ReadWrite + 'static, + SPI: SpiBus + 'static, CS: OutputPin + 'static, RESET: OutputPin + 'static, I: Wait + 'static, @@ -64,7 +64,7 @@ where impl Timings for Sx127xRadio where - SPI: ReadWrite + 'static, + SPI: SpiBus + 'static, CS: OutputPin + 'static, RESET: OutputPin + 'static, I: Wait + 'static, @@ -80,7 +80,7 @@ where impl PhyRxTx for Sx127xRadio where - SPI: ReadWrite + 'static, + SPI: SpiBus + 'static, CS: OutputPin + 'static, E: 'static, RESET: OutputPin + 'static, @@ -89,15 +89,14 @@ where { type PhyError = Sx127xError; - type TxFuture<'m> + type TxFuture<'m> = impl Future> + 'm where SPI: 'm, CS: 'm, RESET: 'm, E: 'm, I: 'm, - RFS: 'm, - = impl Future> + 'm; + RFS: 'm; fn tx<'m>(&'m mut self, config: TxConfig, buf: &'m [u8]) -> Self::TxFuture<'m> { trace!("TX START"); @@ -137,15 +136,14 @@ where } } - type RxFuture<'m> + type RxFuture<'m> = impl Future> + 'm where SPI: 'm, CS: 'm, RESET: 'm, E: 'm, I: 'm, - RFS: 'm, - = impl Future> + 'm; + RFS: 'm; fn rx<'m>(&'m mut self, config: RfConfig, buf: &'m mut [u8]) -> Self::RxFuture<'m> { trace!("RX START"); diff --git a/embassy-lora/src/sx127x/sx127x_lora/mod.rs b/embassy-lora/src/sx127x/sx127x_lora/mod.rs index 6fbd3a4b..62eaf0a9 100644 --- a/embassy-lora/src/sx127x/sx127x_lora/mod.rs +++ b/embassy-lora/src/sx127x/sx127x_lora/mod.rs @@ -8,7 +8,7 @@ use bit_field::BitField; use embassy::time::{Duration, Timer}; use embedded_hal::digital::v2::OutputPin; -use embedded_hal_async::spi::ReadWrite; +use embedded_hal_async::spi::SpiBus; mod register; use self::register::PaConfig; @@ -48,7 +48,7 @@ const VERSION_CHECK: u8 = 0x09; impl LoRa where - SPI: ReadWrite, + SPI: SpiBus, CS: OutputPin, RESET: OutputPin, { diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index d8bac322..5c0450eb 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -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" } 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-async = { version = "0.0.1", 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 = "embassy2", optional = true} defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index b856c2df..32b5d908 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -108,7 +108,7 @@ unsafe fn handle_gpiote_interrupt() { for i in 0..CHANNEL_COUNT { 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(); } } @@ -481,102 +481,72 @@ mod eh1 { } } -#[cfg(all(feature = "unstable-traits", feature = "nightly"))] -mod eh1a { - use super::*; - use futures::FutureExt; +cfg_if::cfg_if! { + if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] { + use futures::FutureExt; - impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Input<'d, T> { - type WaitForHighFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Input<'d, T> { + type WaitForHighFuture<'a> = impl Future> + 'a where Self: 'a; - fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> { - self.wait_for_high().map(Ok) + fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> { + self.wait_for_high().map(Ok) + } + + type WaitForLowFuture<'a> = impl Future> + '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> + '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> + '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> + '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> - where - Self: 'a, - = impl Future> + 'a; + impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Flex<'d, T> { + type WaitForHighFuture<'a> = impl Future> + 'a where Self: 'a; - fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> { - self.wait_for_low().map(Ok) - } + fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> { + self.wait_for_high().map(Ok) + } - type WaitForRisingEdgeFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type WaitForLowFuture<'a> = impl Future> + 'a where Self: 'a; - fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> { - self.wait_for_rising_edge().map(Ok) - } + fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> { + self.wait_for_low().map(Ok) + } - type WaitForFallingEdgeFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type WaitForRisingEdgeFuture<'a> = impl Future> + 'a where Self: 'a; - fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> { - self.wait_for_falling_edge().map(Ok) - } + fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> { + self.wait_for_rising_edge().map(Ok) + } - type WaitForAnyEdgeFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type WaitForFallingEdgeFuture<'a> = impl Future> + 'a where Self: 'a; - fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> { - self.wait_for_any_edge().map(Ok) - } - } + fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> { + self.wait_for_falling_edge().map(Ok) + } - impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Flex<'d, T> { - type WaitForHighFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type WaitForAnyEdgeFuture<'a> = impl Future> + 'a where Self: 'a; - fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> { - self.wait_for_high().map(Ok) - } - - type WaitForLowFuture<'a> - where - Self: 'a, - = impl Future> + '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> + '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> + '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> + 'a; - - fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> { - self.wait_for_any_edge().map(Ok) + fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> { + self.wait_for_any_edge().map(Ok) + } } } } diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index 5d88b232..f97a1c0f 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs @@ -455,43 +455,25 @@ mod eh1 { type Error = Error; } - impl<'d, T: Instance> embedded_hal_1::spi::blocking::Read 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 for Spim<'d, T> { fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { 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 for Spim<'d, T> { + impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusWrite for Spim<'d, T> { fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { 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(&mut self, words: WI) -> Result<(), Self::Error> - where - WI: IntoIterator, - { - for w in words { - self.blocking_write(&[w])?; - } - Ok(()) - } } - impl<'d, T: Instance> embedded_hal_1::spi::blocking::ReadWrite for Spim<'d, T> { + impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBus for Spim<'d, T> { fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { self.blocking_transfer(read, write) } @@ -499,128 +481,51 @@ mod eh1 { fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { 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"))] -mod eh1a { - use super::*; - use core::future::Future; +cfg_if::cfg_if! { + if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] { + use core::future::Future; - impl<'d, T: Instance> embedded_hal_async::spi::Read for Spim<'d, T> { - type ReadFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + impl<'d, T: Instance> embedded_hal_async::spi::SpiBusFlush for Spim<'d, T> { + type FlushFuture<'a> = impl Future> + 'a where Self: 'a; - fn read<'a>(&'a mut self, words: &'a mut [u8]) -> Self::ReadFuture<'a> { - self.read(words) - } - - type ReadTransactionFuture<'a> - where - Self: 'a, - = impl Future> + '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(()) + fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { + async move { Ok(()) } } } - } - impl<'d, T: Instance> embedded_hal_async::spi::Write for Spim<'d, T> { - type WriteFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + impl<'d, T: Instance> embedded_hal_async::spi::SpiBusRead for Spim<'d, T> { + type ReadFuture<'a> = impl Future> + 'a where Self: 'a; - fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { - self.write(data) - } - - type WriteTransactionFuture<'a> - where - Self: 'a, - = impl Future> + '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(()) + fn read<'a>(&'a mut self, words: &'a mut [u8]) -> Self::ReadFuture<'a> { + self.read(words) } } - } - impl<'d, T: Instance> embedded_hal_async::spi::ReadWrite for Spim<'d, T> { - type TransferFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + impl<'d, T: Instance> embedded_hal_async::spi::SpiBusWrite for Spim<'d, T> { + type WriteFuture<'a> = impl Future> + 'a where Self: 'a; - fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> { - self.transfer(rx, tx) + fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { + self.write(data) + } } - type TransferInPlaceFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + impl<'d, T: Instance> embedded_hal_async::spi::SpiBus for Spim<'d, T> { + type TransferFuture<'a> = impl Future> + 'a where Self: 'a; - fn transfer_in_place<'a>( - &'a mut self, - words: &'a mut [u8], - ) -> Self::TransferInPlaceFuture<'a> { - self.transfer_in_place(words) - } + fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> { + self.transfer(rx, tx) + } - type TransactionFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type TransferInPlaceFuture<'a> = impl Future> + 'a where Self: 'a; - fn transaction<'a>( - &'a mut self, - operations: &'a mut [embedded_hal_async::spi::Operation<'a, u8>], - ) -> Self::TransactionFuture<'a> { - use embedded_hal_1::spi::blocking::Operation; - 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(()) + fn transfer_in_place<'a>( + &'a mut self, + words: &'a mut [u8], + ) -> Self::TransferInPlaceFuture<'a> { + self.transfer_in_place(words) } } } diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 40705477..9bee16f3 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs @@ -743,52 +743,43 @@ mod eh1 { } } -#[cfg(all(feature = "unstable-traits", feature = "nightly"))] -impl<'d, T: Instance> embedded_hal_async::i2c::I2c for Twim<'d, T> { - type ReadFuture<'a> - where - Self: 'a, - = impl Future> + 'a; +cfg_if::cfg_if! { + if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] { + impl<'d, T: Instance> embedded_hal_async::i2c::I2c for Twim<'d, T> { + type ReadFuture<'a> = impl Future> + 'a where Self: 'a; - fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { - self.read(address, buffer) - } + fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { + self.read(address, buffer) + } - type WriteFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type WriteFuture<'a> = impl Future> + 'a where Self: 'a; - fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> { - self.write(address, bytes) - } + fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> { + self.write(address, bytes) + } - type WriteReadFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type WriteReadFuture<'a> = impl Future> + 'a where Self: 'a; - fn write_read<'a>( - &'a mut self, - address: u8, - wr_buffer: &'a [u8], - rd_buffer: &'a mut [u8], - ) -> Self::WriteReadFuture<'a> { - self.write_read(address, wr_buffer, rd_buffer) - } + fn write_read<'a>( + &'a mut self, + address: u8, + wr_buffer: &'a [u8], + rd_buffer: &'a mut [u8], + ) -> Self::WriteReadFuture<'a> { + self.write_read(address, wr_buffer, rd_buffer) + } - type TransactionFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type TransactionFuture<'a, 'b> = impl Future> + 'a where Self: 'a, 'b: 'a; - fn transaction<'a>( - &'a mut self, - address: u8, - operations: &mut [embedded_hal_async::i2c::Operation<'a>], - ) -> Self::TransactionFuture<'a> { - let _ = address; - let _ = operations; - async move { todo!() } + fn transaction<'a, 'b>( + &'a mut self, + address: u8, + operations: &'a mut [embedded_hal_async::i2c::Operation<'b>], + ) -> Self::TransactionFuture<'a, 'b> { + let _ = address; + let _ = operations; + async move { todo!() } + } + } } } diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 111c8341..2b01dd07 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -934,105 +934,78 @@ mod eh1 { } } -#[cfg(all(feature = "unstable-traits", feature = "nightly"))] -mod eh1a { - use super::*; - use core::future::Future; +cfg_if::cfg_if! { + if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] { + use core::future::Future; - impl<'d, T: Instance> embedded_hal_async::serial::Read for Uarte<'d, T> { - type ReadFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + impl<'d, T: Instance> embedded_hal_async::serial::Read for Uarte<'d, T> { + type ReadFuture<'a> = impl Future> + 'a where Self: 'a; - fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { - self.read(buffer) - } - } - - impl<'d, T: Instance> embedded_hal_async::serial::Write for Uarte<'d, T> { - type WriteFuture<'a> - where - Self: 'a, - = impl Future> + 'a; - - fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> { - self.write(buffer) + fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { + self.read(buffer) + } } - type FlushFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + impl<'d, T: Instance> embedded_hal_async::serial::Write for Uarte<'d, T> { + type WriteFuture<'a> = impl Future> + 'a where Self: 'a; - fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { - async move { Ok(()) } - } - } + fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> { + self.write(buffer) + } - impl<'d, T: Instance> embedded_hal_async::serial::Write for UarteTx<'d, T> { - type WriteFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type FlushFuture<'a> = impl Future> + 'a where Self: 'a; - fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> { - self.write(buffer) + fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { + async move { Ok(()) } + } } - type FlushFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + impl<'d, T: Instance> embedded_hal_async::serial::Write for UarteTx<'d, T> { + type WriteFuture<'a> = impl Future> + 'a where Self: 'a; - fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { - async move { Ok(()) } - } - } + fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> { + self.write(buffer) + } - impl<'d, T: Instance> embedded_hal_async::serial::Read for UarteRx<'d, T> { - type ReadFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type FlushFuture<'a> = impl Future> + '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::Read - for UarteWithIdle<'d, U, T> - { - type ReadFuture<'a> - where - Self: 'a, - = impl Future> + '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> + 'a; - - fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> { - self.write(buffer) + fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { + async move { Ok(()) } + } } - type FlushFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + impl<'d, T: Instance> embedded_hal_async::serial::Read for UarteRx<'d, T> { + type ReadFuture<'a> = impl Future> + 'a where Self: 'a; - fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { - async move { Ok(()) } + 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::Read + for UarteWithIdle<'d, U, T> + { + type ReadFuture<'a> = impl Future> + '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> + 'a where Self: 'a; + + fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> { + self.write(buffer) + } + + type FlushFuture<'a> = impl Future> + 'a where Self: 'a; + + fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { + async move { Ok(()) } + } } } } diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index a957af6b..37cd77f8 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml @@ -34,5 +34,5 @@ rp2040-pac2 = { git = "https://github.com/embassy-rs/rp2040-pac2", rev="9ad7223a #rp2040-pac2 = { path = "../../rp/rp2040-pac2", features = ["rt"] } 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-async = { version = "0.0.1", 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 = "embassy2", optional = true} diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs index 549e1bd0..8b90ba28 100644 --- a/embassy-rp/src/spi.rs +++ b/embassy-rp/src/spi.rs @@ -342,43 +342,25 @@ mod eh1 { type Error = Error; } - impl<'d, T: Instance> embedded_hal_1::spi::blocking::Read 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 for Spi<'d, T> { fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { 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 for Spi<'d, T> { + impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusWrite for Spi<'d, T> { fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { 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(&mut self, words: WI) -> Result<(), Self::Error> - where - WI: IntoIterator, - { - for w in words { - self.blocking_write(&[w])?; - } - Ok(()) - } } - impl<'d, T: Instance> embedded_hal_1::spi::blocking::ReadWrite for Spi<'d, T> { + impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBus for Spi<'d, T> { fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { self.blocking_transfer(read, write) } @@ -386,21 +368,5 @@ mod eh1 { fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { 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(()) - } } } diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 116bba2a..44c78dfe 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -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 } 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-async = { version = "0.0.1", 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 = "embassy2", optional = true} defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } diff --git a/embassy-stm32/src/eth/v1c/mod.rs b/embassy-stm32/src/eth/v1c/mod.rs index 044e2cc9..8abe2e17 100644 --- a/embassy-stm32/src/eth/v1c/mod.rs +++ b/embassy-stm32/src/eth/v1c/mod.rs @@ -45,7 +45,7 @@ pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> { macro_rules! config_pins { ($($pin:ident),*) => { // 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_speed(Speed::VeryHigh); diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index 34b0bc09..023ec7a0 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs @@ -36,7 +36,7 @@ pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> { macro_rules! config_pins { ($($pin:ident),*) => { // 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_speed(Speed::VeryHigh); diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 47307530..8858bb64 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs @@ -165,55 +165,40 @@ mod eh1 { } } } -#[cfg(all(feature = "unstable-traits", feature = "nightly"))] -mod eh1a { - use super::*; - use futures::FutureExt; +cfg_if::cfg_if! { + if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] { + use futures::FutureExt; - impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for ExtiInput<'d, T> { - type WaitForHighFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for ExtiInput<'d, T> { + type WaitForHighFuture<'a> = impl Future> + 'a where Self: 'a; - fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> { - self.wait_for_high().map(Ok) - } + fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> { + self.wait_for_high().map(Ok) + } - type WaitForLowFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type WaitForLowFuture<'a> = impl Future> + 'a where Self: 'a; - fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> { - self.wait_for_low().map(Ok) - } + 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> + 'a; + type WaitForRisingEdgeFuture<'a> = impl Future> + 'a where Self: 'a; - fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> { - self.wait_for_rising_edge().map(Ok) - } + 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> + 'a; + type WaitForFallingEdgeFuture<'a> = impl Future> + 'a where Self: 'a; - fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> { - self.wait_for_falling_edge().map(Ok) - } + 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> + 'a; + type WaitForAnyEdgeFuture<'a> = impl Future> + 'a where Self: 'a; - fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> { - self.wait_for_any_edge().map(Ok) + fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> { + self.wait_for_any_edge().map(Ok) + } } } } diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 2c46237d..5e9de8fd 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -917,58 +917,46 @@ mod eh1 { } } -#[cfg(all(feature = "unstable-traits", feature = "nightly"))] -mod eh1a { - use super::super::{RxDma, TxDma}; - use super::*; - use core::future::Future; +cfg_if::cfg_if! { + if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] { + use super::{RxDma, TxDma}; + use core::future::Future; - impl<'d, T: Instance, TXDMA: TxDma, RXDMA: RxDma> embedded_hal_async::i2c::I2c - for I2c<'d, T, TXDMA, RXDMA> - { - type ReadFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + impl<'d, T: Instance, TXDMA: TxDma, RXDMA: RxDma> embedded_hal_async::i2c::I2c + for I2c<'d, T, TXDMA, RXDMA> + { + type ReadFuture<'a> = impl Future> + 'a where Self: 'a; - fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { - self.read(address, buffer) - } + fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { + self.read(address, buffer) + } - type WriteFuture<'a> - where - Self: 'a, - = impl Future> + 'a; - fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> { - self.write(address, bytes) - } + type WriteFuture<'a> = impl Future> + 'a where Self: 'a; + fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> { + self.write(address, bytes) + } - type WriteReadFuture<'a> - where - Self: 'a, - = impl Future> + 'a; - fn write_read<'a>( - &'a mut self, - address: u8, - bytes: &'a [u8], - buffer: &'a mut [u8], - ) -> Self::WriteReadFuture<'a> { - self.write_read(address, bytes, buffer) - } + type WriteReadFuture<'a> = impl Future> + 'a where Self: 'a; + fn write_read<'a>( + &'a mut self, + address: u8, + bytes: &'a [u8], + buffer: &'a mut [u8], + ) -> Self::WriteReadFuture<'a> { + self.write_read(address, bytes, buffer) + } - type TransactionFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type TransactionFuture<'a, 'b> = impl Future> + 'a where Self: 'a, 'b: 'a; - fn transaction<'a>( - &'a mut self, - address: u8, - operations: &mut [embedded_hal_async::i2c::Operation<'a>], - ) -> Self::TransactionFuture<'a> { - let _ = address; - let _ = operations; - async move { todo!() } + fn transaction<'a, 'b>( + &'a mut self, + address: u8, + operations: &'a mut [embedded_hal_async::i2c::Operation<'b>], + ) -> Self::TransactionFuture<'a, 'b> { + let _ = address; + let _ = operations; + async move { todo!() } + } } } } diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index e3b64728..3352b24d 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -445,6 +445,15 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { Ok(()) } + pub fn blocking_read(&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(&mut self, words: &mut [W]) -> Result<(), Error> { self.set_word_size(W::WORDSIZE); let regs = T::regs(); @@ -453,6 +462,21 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } Ok(()) } + + pub fn blocking_transfer(&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> { @@ -669,6 +693,34 @@ mod eh1 { 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 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 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 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 { fn kind(&self) -> embedded_hal_1::spi::ErrorKind { match *self { @@ -681,115 +733,55 @@ mod eh1 { } } -#[cfg(all(feature = "unstable-traits", feature = "nightly"))] -mod eh1a { - use super::*; - use core::future::Future; +cfg_if::cfg_if! { + if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] { + 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> + 'a where Self: 'a; - impl<'d, T: Instance, Tx: TxDma, Rx> embedded_hal_async::spi::Write for Spi<'d, T, Tx, Rx> { - type WriteFuture<'a> - where - Self: 'a, - = impl Future> + 'a; - - fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { - self.write(data) - } - - type WriteTransactionFuture<'a> - where - Self: 'a, - = impl Future> + '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(()) + fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { + async { Ok(()) } } } - } - impl<'d, T: Instance, Tx: TxDma, Rx: RxDma> embedded_hal_async::spi::Read - for Spi<'d, T, Tx, Rx> - { - type ReadFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + impl<'d, T: Instance, Tx: TxDma, Rx> embedded_hal_async::spi::SpiBusWrite + for Spi<'d, T, Tx, Rx> + { + type WriteFuture<'a> = impl Future> + 'a where Self: 'a; - fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { - self.read(data) - } - - type ReadTransactionFuture<'a> - where - Self: 'a, - = impl Future> + '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(()) + fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { + self.write(data) } } - } - impl<'d, T: Instance, Tx: TxDma, Rx: RxDma> embedded_hal_async::spi::ReadWrite - for Spi<'d, T, Tx, Rx> - { - type TransferFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + impl<'d, T: Instance, Tx: TxDma, Rx: RxDma> embedded_hal_async::spi::SpiBusRead + for Spi<'d, T, Tx, Rx> + { + type ReadFuture<'a> = impl Future> + 'a where Self: 'a; - fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> { - self.transfer(rx, tx) + fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { + self.read(data) + } } - type TransferInPlaceFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + impl<'d, T: Instance, Tx: TxDma, Rx: RxDma> embedded_hal_async::spi::SpiBus + for Spi<'d, T, Tx, Rx> + { + type TransferFuture<'a> = impl Future> + 'a where Self: 'a; - fn transfer_in_place<'a>( - &'a mut self, - words: &'a mut [u8], - ) -> Self::TransferInPlaceFuture<'a> { - // TODO: Implement async version - let result = self.blocking_transfer_in_place(words); - async move { result } - } + fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> { + self.transfer(rx, tx) + } - type TransactionFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type TransferInPlaceFuture<'a> = impl Future> + 'a where Self: 'a; - fn transaction<'a>( - &'a mut self, - operations: &'a mut [embedded_hal_async::spi::Operation<'a, u8>], - ) -> Self::TransactionFuture<'a> { - use embedded_hal_1::spi::blocking::Operation; - 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(()) + fn transfer_in_place<'a>( + &'a mut self, + words: &'a mut [u8], + ) -> Self::TransferInPlaceFuture<'a> { + // TODO: Implement async version + let result = self.blocking_transfer_in_place(words); + async move { result } } } } @@ -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 u16 {} diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 60e60712..a62c49c7 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -275,45 +275,36 @@ mod eh1 { } } -#[cfg(all(feature = "unstable-traits", feature = "nightly"))] -mod eh1a { - use super::*; - use core::future::Future; +cfg_if::cfg_if! { + if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] { + use core::future::Future; - impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Write for Uart<'d, T, TxDma, RxDma> - where - TxDma: crate::usart::TxDma, - { - type WriteFuture<'a> + impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Write for Uart<'d, T, TxDma, RxDma> where - Self: 'a, - = impl Future> + 'a; + TxDma: crate::usart::TxDma, + { + type WriteFuture<'a> = impl Future> + 'a where Self: 'a; - fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { - self.write(buf) + fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { + self.write(buf) + } + + type FlushFuture<'a> = impl Future> + '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 - Self: 'a, - = impl Future> + 'a; + RxDma: crate::usart::RxDma, + { + type ReadFuture<'a> = impl Future> + 'a where Self: 'a; - fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { - async move { Ok(()) } - } - } - - impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Read for Uart<'d, T, TxDma, RxDma> - where - RxDma: crate::usart::RxDma, - { - type ReadFuture<'a> - where - Self: 'a, - = impl Future> + 'a; - - fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { - self.read(buf) + fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { + self.read(buf) + } } } } diff --git a/embassy-traits/Cargo.toml b/embassy-traits/Cargo.toml index fa2082ef..e23259eb 100644 --- a/embassy-traits/Cargo.toml +++ b/embassy-traits/Cargo.toml @@ -9,8 +9,8 @@ std = [] [dependencies] 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-async = { version = "0.0.1", 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 = "embassy2"} embedded-storage = "0.3.0" embedded-storage-async = "0.3.0" nb = "1.0.0" diff --git a/embassy-traits/src/adapter.rs b/embassy-traits/src/adapter.rs index 735f9aac..b709f389 100644 --- a/embassy-traits/src/adapter.rs +++ b/embassy-traits/src/adapter.rs @@ -39,18 +39,9 @@ where + blocking::i2c::Read + blocking::i2c::Write, { - type WriteFuture<'a> - where - Self: 'a, - = impl Future> + 'a; - type ReadFuture<'a> - where - Self: 'a, - = impl Future> + 'a; - type WriteReadFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type WriteFuture<'a> = impl Future> + 'a where Self: 'a; + type ReadFuture<'a> = impl Future> + 'a where Self: 'a; + type WriteReadFuture<'a> = impl Future> + 'a where Self: 'a; fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { async move { self.wrapped.read(address, buffer) } @@ -69,16 +60,13 @@ where async move { self.wrapped.write_read(address, bytes, buffer) } } - type TransactionFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type TransactionFuture<'a, 'b> = impl Future> + 'a where Self: 'a, 'b: 'a; - fn transaction<'a>( + fn transaction<'a, 'b>( &'a mut self, address: u8, - operations: &mut [embedded_hal_async::i2c::Operation<'a>], - ) -> Self::TransactionFuture<'a> { + operations: &'a mut [embedded_hal_async::i2c::Operation<'b>], + ) -> Self::TransactionFuture<'a, 'b> { let _ = address; let _ = operations; async move { todo!() } @@ -97,15 +85,12 @@ where type Error = E; } -impl embedded_hal_async::spi::ReadWrite for BlockingAsync +impl embedded_hal_async::spi::SpiBus for BlockingAsync where E: embedded_hal_1::spi::Error + 'static, T: blocking::spi::Transfer + blocking::spi::Write, { - type TransferFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type TransferFuture<'a> = impl Future> + 'a where Self: 'a; fn transfer<'a>(&'a mut self, read: &'a mut [u8], write: &'a [u8]) -> Self::TransferFuture<'a> { async move { @@ -118,37 +103,31 @@ where } } - type TransferInPlaceFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type TransferInPlaceFuture<'a> = impl Future> + 'a where Self: 'a; fn transfer_in_place<'a>(&'a mut self, _: &'a mut [u8]) -> Self::TransferInPlaceFuture<'a> { async move { todo!() } } - - type TransactionFuture<'a> - where - Self: 'a, - = impl Future> + 'a; - - fn transaction<'a>( - &'a mut self, - _: &'a mut [embedded_hal_async::spi::Operation<'a, u8>], - ) -> Self::TransactionFuture<'a> { - async move { todo!() } - } } -impl embedded_hal_async::spi::Write for BlockingAsync +impl embedded_hal_async::spi::SpiBusFlush for BlockingAsync where E: embedded_hal_1::spi::Error + 'static, T: blocking::spi::Transfer + blocking::spi::Write, { - type WriteFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type FlushFuture<'a> = impl Future> + 'a where Self: 'a; + + fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { + async move { Ok(()) } + } +} + +impl embedded_hal_async::spi::SpiBusWrite for BlockingAsync +where + E: embedded_hal_1::spi::Error + 'static, + T: blocking::spi::Transfer + blocking::spi::Write, +{ + type WriteFuture<'a> = impl Future> + 'a where Self: 'a; fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { async move { @@ -156,26 +135,14 @@ where Ok(()) } } - - type WriteTransactionFuture<'a> - where - Self: 'a, - = impl Future> + 'a; - - fn write_transaction<'a>(&'a mut self, _: &'a [&'a [u8]]) -> Self::WriteTransactionFuture<'a> { - async move { todo!() } - } } -impl embedded_hal_async::spi::Read for BlockingAsync +impl embedded_hal_async::spi::SpiBusRead for BlockingAsync where E: embedded_hal_1::spi::Error + 'static, T: blocking::spi::Transfer + blocking::spi::Write, { - type ReadFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type ReadFuture<'a> = impl Future> + 'a where Self: 'a; fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { async move { @@ -183,18 +150,6 @@ where Ok(()) } } - - type ReadTransactionFuture<'a> - where - Self: 'a, - = impl Future> + 'a; - - fn read_transaction<'a>( - &'a mut self, - _: &'a mut [&'a mut [u8]], - ) -> Self::ReadTransactionFuture<'a> { - async move { todo!() } - } } // Uart implementatinos @@ -211,10 +166,7 @@ where T: serial::Read, E: embedded_hal_1::serial::Error + 'static, { - type ReadFuture<'a> - where - T: 'a, - = impl Future> + 'a; + type ReadFuture<'a> = impl Future> + 'a where T: 'a; fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { async move { let mut pos = 0; @@ -238,18 +190,12 @@ where T: blocking::serial::Write + serial::Read, E: embedded_hal_1::serial::Error + 'static, { - type WriteFuture<'a> - where - T: 'a, - = impl Future> + 'a; + type WriteFuture<'a> = impl Future> + 'a where T: 'a; fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { async move { self.wrapped.bwrite_all(buf) } } - type FlushFuture<'a> - where - T: 'a, - = impl Future> + 'a; + type FlushFuture<'a> = impl Future> + 'a where T: 'a; fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { async move { self.wrapped.bflush() } } @@ -273,18 +219,12 @@ where const WRITE_SIZE: usize = ::WRITE_SIZE; const ERASE_SIZE: usize = ::ERASE_SIZE; - type WriteFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type WriteFuture<'a> = impl Future> + 'a where Self: 'a; fn write<'a>(&'a mut self, offset: u32, data: &'a [u8]) -> Self::WriteFuture<'a> { async move { self.wrapped.write(offset, data) } } - type EraseFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type EraseFuture<'a> = impl Future> + 'a where Self: 'a; fn erase<'a>(&'a mut self, from: u32, to: u32) -> Self::EraseFuture<'a> { async move { self.wrapped.erase(from, to) } } @@ -295,10 +235,7 @@ where T: ReadNorFlash, { const READ_SIZE: usize = ::READ_SIZE; - type ReadFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type ReadFuture<'a> = impl Future> + 'a where Self: 'a; fn read<'a>(&'a mut self, address: u32, data: &'a mut [u8]) -> Self::ReadFuture<'a> { async move { self.wrapped.read(address, data) } } diff --git a/embassy/Cargo.toml b/embassy/Cargo.toml index 9b7e7207..902a3bcb 100644 --- a/embassy/Cargo.toml +++ b/embassy/Cargo.toml @@ -55,8 +55,8 @@ defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } 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-async = { version = "0.0.1", 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 = "embassy2", optional = true} futures = { version = "0.3.17", default-features = false, features = [ "cfg-target-has-atomic", "unstable" ] } pin-project = { version = "1.0.8", default-features = false } diff --git a/embassy/src/lib.rs b/embassy/src/lib.rs index acc71e10..6b24b598 100644 --- a/embassy/src/lib.rs +++ b/embassy/src/lib.rs @@ -1,12 +1,7 @@ #![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)] #![cfg_attr( feature = "nightly", - feature( - const_fn_trait_bound, - const_fn_fn_ptr_basics, - generic_associated_types, - type_alias_impl_trait - ) + feature(generic_associated_types, type_alias_impl_trait) )] #![allow(clippy::new_without_default)] diff --git a/embassy/src/time/delay.rs b/embassy/src/time/delay.rs index 27ec61fe..06ed8ec4 100644 --- a/embassy/src/time/delay.rs +++ b/embassy/src/time/delay.rs @@ -31,32 +31,26 @@ mod eh1 { } } -#[cfg(all(feature = "unstable-traits", feature = "nightly"))] -mod eh1a { - use super::*; - use crate::time::Timer; - use core::future::Future; - use futures::FutureExt; +cfg_if::cfg_if! { + if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] { + use crate::time::Timer; + use core::future::Future; + use futures::FutureExt; - impl embedded_hal_async::delay::DelayUs for Delay { - type Error = core::convert::Infallible; + impl embedded_hal_async::delay::DelayUs for Delay { + type Error = core::convert::Infallible; - type DelayUsFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type DelayUsFuture<'a> = impl Future> + 'a where Self: 'a; - fn delay_us(&mut self, micros: u32) -> Self::DelayUsFuture<'_> { - Timer::after(Duration::from_micros(micros as _)).map(Ok) - } + fn delay_us(&mut self, micros: u32) -> Self::DelayUsFuture<'_> { + Timer::after(Duration::from_micros(micros as _)).map(Ok) + } - type DelayMsFuture<'a> - where - Self: 'a, - = impl Future> + 'a; + type DelayMsFuture<'a> = impl Future> + 'a where Self: 'a; - fn delay_ms(&mut self, millis: u32) -> Self::DelayMsFuture<'_> { - Timer::after(Duration::from_millis(millis as _)).map(Ok) + fn delay_ms(&mut self, millis: u32) -> Self::DelayMsFuture<'_> { + Timer::after(Duration::from_millis(millis as _)).map(Ok) + } } } } diff --git a/examples/nrf/Cargo.toml b/examples/nrf/Cargo.toml index 2d9c9953..7fdc27ff 100644 --- a/examples/nrf/Cargo.toml +++ b/examples/nrf/Cargo.toml @@ -6,7 +6,7 @@ version = "0.1.0" [features] default = ["nightly"] -nightly = ["embassy-nrf/nightly"] +nightly = ["embassy-nrf/nightly", "embassy-nrf/unstable-traits"] [dependencies] embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index c067fbbc..830e5417 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -1,6 +1,6 @@ [package] authors = ["Dario Nieuwenhuis "] -edition = "2018" +edition = "2021" name = "embassy-rp-examples" version = "0.1.0" @@ -15,9 +15,12 @@ defmt-rtt = "0.3" cortex-m = "0.7.3" cortex-m-rt = "0.7.0" -embedded-hal = "0.2.6" panic-probe = { version = "0.3", features = ["print-defmt"] } futures = { version = "0.3.17", default-features = false, features = ["async-await", "cfg-target-has-atomic", "unstable"] } display-interface-spi = "0.4.1" embedded-graphics = "0.7.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 } diff --git a/examples/rp/src/bin/spi_display.rs b/examples/rp/src/bin/spi_display.rs index 01149c25..b2854afc 100644 --- a/examples/rp/src/bin/spi_display.rs +++ b/examples/rp/src/bin/spi_display.rs @@ -6,16 +6,14 @@ mod example_common; use core::cell::RefCell; -use core::fmt::Debug; use defmt::*; -use display_interface_spi::SPIInterfaceNoCS; use embassy::executor::Spawner; use embassy::time::Delay; -use embassy_rp::peripherals; +use embassy_rp::gpio::{Level, Output}; use embassy_rp::spi; use embassy_rp::spi::Spi; -use embassy_rp::{gpio, Peripherals}; +use embassy_rp::Peripherals; use embedded_graphics::image::{Image, ImageRawLE}; use embedded_graphics::mono_font::ascii::FONT_10X20; use embedded_graphics::mono_font::MonoTextStyle; @@ -23,9 +21,15 @@ use embedded_graphics::pixelcolor::Rgb565; use embedded_graphics::prelude::*; use embedded_graphics::primitives::{PrimitiveStyleBuilder, Rectangle}; use embedded_graphics::text::Text; -use gpio::{Level, Output}; 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] async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); @@ -42,17 +46,16 @@ async fn main(_spawner: Spawner, p: Peripherals) { // create SPI let mut config = spi::Config::default(); - config.frequency = DISPLAY_FREQ; + config.frequency = TOUCH_FREQ; // use the lowest freq config.phase = spi::Phase::CaptureOnSecondTransition; config.polarity = spi::Polarity::IdleHigh; - let spi = RefCell::new(SpiState { - last_mode: SpiMode::Display, - spi: Spi::new(p.SPI1, clk, mosi, miso, config), - display_cs: Output::new(display_cs, Level::Low), - }); + let spi_bus = RefCell::new(Spi::new(p.SPI1, clk, mosi, miso, config)); - 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 rst = Output::new(rst, Level::Low); @@ -62,7 +65,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { let _bl = Output::new(bl, Level::High); // display interface abstraction from SPI and DC - let di = SPIInterfaceNoCS::new(DisplaySpi(&spi), dcx); + let di = SPIDeviceInterface::new(display_spi, dcx); // create driver 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)] -enum SpiMode { - Display, - Touch, -} +mod shared_spi { + use core::cell::RefCell; + use core::fmt::Debug; -struct SpiState { - spi: Spi<'static, peripherals::SPI1>, - display_cs: Output<'static, peripherals::PIN_9>, + use embedded_hal::digital::blocking::OutputPin; + use embedded_hal::spi; + use embedded_hal::spi::blocking::SpiDevice; - last_mode: SpiMode, -} + #[derive(Copy, Clone, Eq, PartialEq, Debug)] + pub enum SpiDeviceWithCsError { + #[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; -const TOUCH_FREQ: u32 = 200_000; - -struct DisplaySpi<'a>(&'a RefCell); -impl<'a> embedded_hal::blocking::spi::Write for DisplaySpi<'a> { - type Error = core::convert::Infallible; - - fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { - let this = &mut *self.0.borrow_mut(); - if this.last_mode != SpiMode::Display { - this.spi.set_frequency(DISPLAY_FREQ); - this.display_cs.set_low(); - this.last_mode = SpiMode::Display; + impl spi::Error for SpiDeviceWithCsError + where + BUS: spi::Error + Debug, + CS: Debug, + { + fn kind(&self) -> spi::ErrorKind { + match self { + Self::Spi(e) => e.kind(), + Self::Cs(_) => spi::ErrorKind::Other, + } } - this.spi.write(words).unwrap(); - Ok(()) } -} -struct TouchSpi<'a>(&'a RefCell); -impl<'a> embedded_hal::blocking::spi::Transfer for TouchSpi<'a> { - type Error = core::convert::Infallible; + pub struct SpiDeviceWithCs<'a, BUS, CS> { + bus: &'a RefCell, + cs: CS, + } - fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { - let this = &mut *self.0.borrow_mut(); - if this.last_mode != SpiMode::Touch { - this.spi.set_frequency(TOUCH_FREQ); - this.display_cs.set_high(); - this.last_mode = SpiMode::Touch; + impl<'a, BUS, CS> SpiDeviceWithCs<'a, BUS, CS> { + pub fn new(bus: &'a RefCell, cs: CS) -> Self { + Self { bus, cs } } - 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, - CS: embedded_hal::digital::v2::OutputPin, -> { - spi: SPI, - cs: CS, -} - -impl, CS: embedded_hal::digital::v2::OutputPin> - Touch -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)> { - self.cs.set_low().unwrap(); - let mut buf = [0x90, 0x00, 0x00, 0xd0, 0x00, 0x00]; - self.spi.transfer(&mut buf).unwrap(); - self.cs.set_high().unwrap(); + impl<'a, BUS, CS> spi::ErrorType for SpiDeviceWithCs<'a, BUS, CS> + where + BUS: spi::ErrorType, + CS: OutputPin, + { + type Error = SpiDeviceWithCsError; + } - let x = ((buf[1] as u32) << 5 | (buf[2] as u32) >> 3) as i32; - let y = ((buf[4] as u32) << 5 | (buf[5] as u32) >> 3) as i32; + impl<'a, BUS, CS> SpiDevice for SpiDeviceWithCs<'a, BUS, CS> + where + BUS: spi::blocking::SpiBusFlush, + CS: OutputPin, + { + type Bus = BUS; - let cal = &CALIBRATION; + fn transaction( + &mut self, + f: impl FnOnce(&mut Self::Bus) -> Result, + ) -> Result { + 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 y = ((y - cal.y1) * cal.sy / (cal.y2 - cal.y1)).clamp(0, cal.sy); - if x == 0 && y == 0 { - None - } else { - Some((x, y)) + let f_res = f(&mut bus); + + // On failure, it's important to still flush and deassert CS. + let flush_res = bus.flush(); + let cs_res = self.cs.set_high(); + + 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: SPI, + } + + impl Touch + 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: SPI, + dc: DC, + } + + impl SPIDeviceInterface + 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 WriteOnlyDataCommand for SPIDeviceInterface + 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(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!(), } } } diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index 8b644165..c53f04e1 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -8,7 +8,7 @@ resolver = "2" [dependencies] 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-rtt = "0.3" diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index 2929f539..2e761df8 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -19,7 +19,7 @@ defmt-rtt = "0.3" cortex-m = "0.7.3" cortex-m-rt = "0.7.0" 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"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.7.5", default-features = false } diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 1d5a83fa..4b1f9a91 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml @@ -18,7 +18,7 @@ defmt-rtt = "0.3" cortex-m = "0.7.3" cortex-m-rt = "0.7.0" 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"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.7.5", default-features = false } diff --git a/examples/stm32l4/src/bin/spi_blocking_async.rs b/examples/stm32l4/src/bin/spi_blocking_async.rs index bcd2e32d..89925d30 100644 --- a/examples/stm32l4/src/bin/spi_blocking_async.rs +++ b/examples/stm32l4/src/bin/spi_blocking_async.rs @@ -12,7 +12,7 @@ use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::time::Hertz; use embassy_stm32::Peripherals; use embassy_traits::adapter::BlockingAsync; -use embedded_hal_async::spi::ReadWrite; +use embedded_hal_async::spi::SpiBus; use example_common::*; #[embassy::main] diff --git a/rust-toolchain.toml b/rust-toolchain.toml index fe15a4c6..72a83246 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,6 @@ # Before upgrading check that everything is available on all tier1 targets here: # https://rust-lang.github.io/rustup-components-history [toolchain] -channel = "nightly-2022-02-20" +channel = "nightly-2022-03-10" components = [ "rust-src", "rustfmt" ] targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabihf", "thumbv8m.main-none-eabihf", "wasm32-unknown-unknown" ] diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 041ec76a..9893b028 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -23,7 +23,7 @@ defmt-rtt = "0.3.0" cortex-m = "0.7.3" cortex-m-rt = "0.7.0" 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"] } [profile.dev]