diff options
| -rw-r--r-- | embassy-nrf-examples/src/bin/spim.rs | 9 | ||||
| -rw-r--r-- | embassy-nrf/src/spim.rs | 28 | ||||
| -rw-r--r-- | embassy-traits/src/spi.rs | 21 |
3 files changed, 43 insertions, 15 deletions
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 @@ | |||
| 6 | 6 | ||
| 7 | #[path = "../example_common.rs"] | 7 | #[path = "../example_common.rs"] |
| 8 | mod example_common; | 8 | mod example_common; |
| 9 | use embassy_traits::spi::FullDuplex; | ||
| 9 | use example_common::*; | 10 | use example_common::*; |
| 10 | 11 | ||
| 11 | use cortex_m_rt::entry; | 12 | use cortex_m_rt::entry; |
| @@ -49,7 +50,7 @@ async fn run() { | |||
| 49 | ncs.set_low().unwrap(); | 50 | ncs.set_low().unwrap(); |
| 50 | cortex_m::asm::delay(5); | 51 | cortex_m::asm::delay(5); |
| 51 | let tx = [0xFF]; | 52 | let tx = [0xFF]; |
| 52 | unwrap!(spim.as_mut().send_receive(&tx, &mut []).await); | 53 | unwrap!(spim.as_mut().read_write(&mut [], &tx).await); |
| 53 | cortex_m::asm::delay(10); | 54 | cortex_m::asm::delay(10); |
| 54 | ncs.set_high().unwrap(); | 55 | ncs.set_high().unwrap(); |
| 55 | 56 | ||
| @@ -62,7 +63,7 @@ async fn run() { | |||
| 62 | ncs.set_low().unwrap(); | 63 | ncs.set_low().unwrap(); |
| 63 | cortex_m::asm::delay(5000); | 64 | cortex_m::asm::delay(5000); |
| 64 | let tx = [0b000_11101, 0]; | 65 | let tx = [0b000_11101, 0]; |
| 65 | unwrap!(spim.as_mut().send_receive(&tx, &mut rx).await); | 66 | unwrap!(spim.as_mut().read_write(&mut rx, &tx).await); |
| 66 | cortex_m::asm::delay(5000); | 67 | cortex_m::asm::delay(5000); |
| 67 | ncs.set_high().unwrap(); | 68 | ncs.set_high().unwrap(); |
| 68 | info!("estat: {=[?]}", rx); | 69 | info!("estat: {=[?]}", rx); |
| @@ -72,7 +73,7 @@ async fn run() { | |||
| 72 | ncs.set_low().unwrap(); | 73 | ncs.set_low().unwrap(); |
| 73 | cortex_m::asm::delay(5); | 74 | cortex_m::asm::delay(5); |
| 74 | let tx = [0b100_11111, 0b11]; | 75 | let tx = [0b100_11111, 0b11]; |
| 75 | unwrap!(spim.as_mut().send_receive(&tx, &mut rx).await); | 76 | unwrap!(spim.as_mut().read_write(&mut rx, &tx).await); |
| 76 | cortex_m::asm::delay(10); | 77 | cortex_m::asm::delay(10); |
| 77 | ncs.set_high().unwrap(); | 78 | ncs.set_high().unwrap(); |
| 78 | 79 | ||
| @@ -81,7 +82,7 @@ async fn run() { | |||
| 81 | ncs.set_low().unwrap(); | 82 | ncs.set_low().unwrap(); |
| 82 | cortex_m::asm::delay(5); | 83 | cortex_m::asm::delay(5); |
| 83 | let tx = [0b000_10010, 0]; | 84 | let tx = [0b000_10010, 0]; |
| 84 | unwrap!(spim.as_mut().send_receive(&tx, &mut rx).await); | 85 | unwrap!(spim.as_mut().read_write(&mut rx, &tx).await); |
| 85 | cortex_m::asm::delay(10); | 86 | cortex_m::asm::delay(10); |
| 86 | ncs.set_high().unwrap(); | 87 | ncs.set_high().unwrap(); |
| 87 | 88 | ||
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; | |||
| 2 | use core::pin::Pin; | 2 | use core::pin::Pin; |
| 3 | use core::sync::atomic::{compiler_fence, Ordering}; | 3 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 4 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | use embassy::traits; | ||
| 5 | use embassy::util::WakerRegistration; | 6 | use embassy::util::WakerRegistration; |
| 6 | use embassy_extras::peripheral::{PeripheralMutex, PeripheralState}; | 7 | use embassy_extras::peripheral::{PeripheralMutex, PeripheralState}; |
| 7 | use futures::future::poll_fn; | 8 | use futures::future::poll_fn; |
| 9 | use traits::spi::FullDuplex; | ||
| 8 | 10 | ||
| 9 | use crate::interrupt::{self, Interrupt}; | 11 | use crate::interrupt::{self, Interrupt}; |
| 10 | use crate::{pac, slice_in_ram_or}; | 12 | use crate::{pac, slice_in_ram_or}; |
| @@ -123,15 +125,33 @@ impl<T: Instance> Spim<T> { | |||
| 123 | let (state, irq) = self.inner().free(); | 125 | let (state, irq) = self.inner().free(); |
| 124 | (state.spim, irq) | 126 | (state.spim, irq) |
| 125 | } | 127 | } |
| 128 | } | ||
| 129 | |||
| 130 | impl<T: Instance> FullDuplex<u8> for Spim<T> { | ||
| 131 | type Error = Error; | ||
| 132 | |||
| 133 | #[rustfmt::skip] | ||
| 134 | type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; | ||
| 135 | #[rustfmt::skip] | ||
| 136 | type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; | ||
| 137 | #[rustfmt::skip] | ||
| 138 | type WriteReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; | ||
| 139 | |||
| 140 | fn read<'a>(self: Pin<&'a mut Self>, data: &'a mut [u8]) -> Self::ReadFuture<'a> { | ||
| 141 | async move { todo!() } | ||
| 142 | } | ||
| 143 | fn write<'a>(self: Pin<&'a mut Self>, data: &'a [u8]) -> Self::WriteFuture<'a> { | ||
| 144 | async move { todo!() } | ||
| 145 | } | ||
| 126 | 146 | ||
| 127 | pub fn send_receive<'a>( | 147 | fn read_write<'a>( |
| 128 | mut self: Pin<&'a mut Self>, | 148 | mut self: Pin<&'a mut Self>, |
| 129 | tx: &'a [u8], | ||
| 130 | rx: &'a mut [u8], | 149 | rx: &'a mut [u8], |
| 131 | ) -> impl Future<Output = Result<(), Error>> + 'a { | 150 | tx: &'a [u8], |
| 151 | ) -> Self::WriteReadFuture<'a> { | ||
| 132 | async move { | 152 | async move { |
| 133 | slice_in_ram_or(tx, Error::DMABufferNotInDataMemory)?; | ||
| 134 | slice_in_ram_or(rx, Error::DMABufferNotInDataMemory)?; | 153 | slice_in_ram_or(rx, Error::DMABufferNotInDataMemory)?; |
| 154 | slice_in_ram_or(tx, Error::DMABufferNotInDataMemory)?; | ||
| 135 | 155 | ||
| 136 | self.as_mut().inner().with(|s, _irq| { | 156 | self.as_mut().inner().with(|s, _irq| { |
| 137 | // Conservative compiler fence to prevent optimizations that do not | 157 | // 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 @@ | |||
| 1 | //! Async SPI API | 1 | //! Async SPI API |
| 2 | 2 | ||
| 3 | use core::future::Future; | 3 | use core::future::Future; |
| 4 | use core::pin::Pin; | ||
| 4 | 5 | ||
| 5 | /// Full duplex (master mode) | 6 | /// Full duplex (master mode) |
| 6 | /// | 7 | /// |
| @@ -22,15 +23,21 @@ pub trait FullDuplex<Word> { | |||
| 22 | /// An enumeration of SPI errors | 23 | /// An enumeration of SPI errors |
| 23 | type Error; | 24 | type Error; |
| 24 | 25 | ||
| 25 | type WriteFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a; | 26 | type WriteFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a |
| 26 | type ReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a; | 27 | where |
| 27 | type WriteReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a; | 28 | Self: 'a; |
| 29 | type ReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a | ||
| 30 | where | ||
| 31 | Self: 'a; | ||
| 32 | type WriteReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a | ||
| 33 | where | ||
| 34 | Self: 'a; | ||
| 28 | 35 | ||
| 29 | fn read<'a>(&'a mut self, data: &'a mut [Word]) -> Self::ReadFuture<'_>; | 36 | fn read<'a>(self: Pin<&'a mut Self>, data: &'a mut [Word]) -> Self::ReadFuture<'a>; |
| 30 | fn write<'a>(&'a mut self, data: &'a [Word]) -> Self::WriteFuture<'_>; | 37 | fn write<'a>(self: Pin<&'a mut Self>, data: &'a [Word]) -> Self::WriteFuture<'a>; |
| 31 | fn read_write<'a>( | 38 | fn read_write<'a>( |
| 32 | &mut self, | 39 | self: Pin<&'a mut Self>, |
| 33 | read: &'a mut [Word], | 40 | read: &'a mut [Word], |
| 34 | write: &'a [Word], | 41 | write: &'a [Word], |
| 35 | ) -> Self::WriteReadFuture<'_>; | 42 | ) -> Self::WriteReadFuture<'a>; |
| 36 | } | 43 | } |
