diff --git a/embassy-nrf-examples/src/bin/spim.rs b/embassy-nrf-examples/src/bin/spim.rs index d6b3a5f87..d3d942e4e 100644 --- a/embassy-nrf-examples/src/bin/spim.rs +++ b/embassy-nrf-examples/src/bin/spim.rs @@ -6,6 +6,7 @@ #[path = "../example_common.rs"] mod example_common; +use embassy_traits::spi::FullDuplex; use example_common::*; use cortex_m_rt::entry; @@ -49,7 +50,7 @@ async fn run() { ncs.set_low().unwrap(); cortex_m::asm::delay(5); let tx = [0xFF]; - unwrap!(spim.as_mut().send_receive(&tx, &mut []).await); + unwrap!(spim.as_mut().read_write(&mut [], &tx).await); cortex_m::asm::delay(10); ncs.set_high().unwrap(); @@ -62,7 +63,7 @@ async fn run() { ncs.set_low().unwrap(); cortex_m::asm::delay(5000); let tx = [0b000_11101, 0]; - unwrap!(spim.as_mut().send_receive(&tx, &mut rx).await); + unwrap!(spim.as_mut().read_write(&mut rx, &tx).await); cortex_m::asm::delay(5000); ncs.set_high().unwrap(); info!("estat: {=[?]}", rx); @@ -72,7 +73,7 @@ async fn run() { ncs.set_low().unwrap(); cortex_m::asm::delay(5); let tx = [0b100_11111, 0b11]; - unwrap!(spim.as_mut().send_receive(&tx, &mut rx).await); + unwrap!(spim.as_mut().read_write(&mut rx, &tx).await); cortex_m::asm::delay(10); ncs.set_high().unwrap(); @@ -81,7 +82,7 @@ async fn run() { ncs.set_low().unwrap(); cortex_m::asm::delay(5); let tx = [0b000_10010, 0]; - unwrap!(spim.as_mut().send_receive(&tx, &mut rx).await); + unwrap!(spim.as_mut().read_write(&mut rx, &tx).await); cortex_m::asm::delay(10); ncs.set_high().unwrap(); diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index 4921bae3b..61d415e02 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs @@ -2,9 +2,11 @@ use core::future::Future; use core::pin::Pin; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; +use embassy::traits; use embassy::util::WakerRegistration; use embassy_extras::peripheral::{PeripheralMutex, PeripheralState}; use futures::future::poll_fn; +use traits::spi::FullDuplex; use crate::interrupt::{self, Interrupt}; use crate::{pac, slice_in_ram_or}; @@ -123,15 +125,33 @@ impl Spim { let (state, irq) = self.inner().free(); (state.spim, irq) } +} - pub fn send_receive<'a>( +impl FullDuplex for Spim { + type Error = Error; + + #[rustfmt::skip] + type WriteFuture<'a> where Self: 'a = impl Future> + 'a; + #[rustfmt::skip] + type ReadFuture<'a> where Self: 'a = impl Future> + 'a; + #[rustfmt::skip] + type WriteReadFuture<'a> where Self: 'a = impl Future> + 'a; + + fn read<'a>(self: Pin<&'a mut Self>, data: &'a mut [u8]) -> Self::ReadFuture<'a> { + async move { todo!() } + } + fn write<'a>(self: Pin<&'a mut Self>, data: &'a [u8]) -> Self::WriteFuture<'a> { + async move { todo!() } + } + + fn read_write<'a>( mut self: Pin<&'a mut Self>, - tx: &'a [u8], rx: &'a mut [u8], - ) -> impl Future> + 'a { + tx: &'a [u8], + ) -> Self::WriteReadFuture<'a> { async move { - slice_in_ram_or(tx, Error::DMABufferNotInDataMemory)?; slice_in_ram_or(rx, Error::DMABufferNotInDataMemory)?; + slice_in_ram_or(tx, Error::DMABufferNotInDataMemory)?; self.as_mut().inner().with(|s, _irq| { // Conservative compiler fence to prevent optimizations that do not diff --git a/embassy-traits/src/spi.rs b/embassy-traits/src/spi.rs index d0cf29e6d..9f08e7402 100644 --- a/embassy-traits/src/spi.rs +++ b/embassy-traits/src/spi.rs @@ -1,6 +1,7 @@ //! Async SPI API use core::future::Future; +use core::pin::Pin; /// Full duplex (master mode) /// @@ -22,15 +23,21 @@ pub trait FullDuplex { /// An enumeration of SPI errors type Error; - type WriteFuture<'a>: Future> + 'a; - type ReadFuture<'a>: Future> + 'a; - type WriteReadFuture<'a>: Future> + 'a; + type WriteFuture<'a>: Future> + 'a + where + Self: 'a; + type ReadFuture<'a>: Future> + 'a + where + Self: 'a; + type WriteReadFuture<'a>: Future> + 'a + where + Self: 'a; - fn read<'a>(&'a mut self, data: &'a mut [Word]) -> Self::ReadFuture<'_>; - fn write<'a>(&'a mut self, data: &'a [Word]) -> Self::WriteFuture<'_>; + fn read<'a>(self: Pin<&'a mut Self>, data: &'a mut [Word]) -> Self::ReadFuture<'a>; + fn write<'a>(self: Pin<&'a mut Self>, data: &'a [Word]) -> Self::WriteFuture<'a>; fn read_write<'a>( - &mut self, + self: Pin<&'a mut Self>, read: &'a mut [Word], write: &'a [Word], - ) -> Self::WriteReadFuture<'_>; + ) -> Self::WriteReadFuture<'a>; }