nrf/spim: do not use PeripheralMutex
This commit is contained in:
parent
ba6e0a4058
commit
f36cbe5e0c
@ -6,7 +6,7 @@
|
||||
|
||||
#[path = "../example_common.rs"]
|
||||
mod example_common;
|
||||
use embassy_nrf::gpio::{Level, Output};
|
||||
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
||||
use embassy_nrf::peripherals::Peripherals;
|
||||
use embassy_traits::spi::FullDuplex;
|
||||
use example_common::*;
|
||||
@ -37,7 +37,7 @@ async fn run() {
|
||||
let spim = spim::Spim::new(p.spim3, irq, p.p0_29, p.p0_28, p.p0_30, config);
|
||||
pin_mut!(spim);
|
||||
|
||||
let mut ncs = Output::new(p.p0_31, Level::High);
|
||||
let mut ncs = Output::new(p.p0_31, Level::High, OutputDrive::Standard);
|
||||
|
||||
// Example on how to talk to an ENC28J60 chip
|
||||
|
||||
|
@ -4,8 +4,7 @@ use core::pin::Pin;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::Poll;
|
||||
use embassy::traits;
|
||||
use embassy::util::{PeripheralBorrow, WakerRegistration};
|
||||
use embassy_extras::peripheral::{PeripheralMutex, PeripheralState};
|
||||
use embassy::util::{wake_on_interrupt, PeripheralBorrow};
|
||||
use futures::future::poll_fn;
|
||||
use traits::spi::FullDuplex;
|
||||
|
||||
@ -26,13 +25,9 @@ pub enum Error {
|
||||
DMABufferNotInDataMemory,
|
||||
}
|
||||
|
||||
struct State<T: Instance> {
|
||||
spim: T,
|
||||
waker: WakerRegistration,
|
||||
}
|
||||
|
||||
pub struct Spim<'d, T: Instance> {
|
||||
inner: PeripheralMutex<State<T>>,
|
||||
spim: T,
|
||||
irq: T::Interrupt,
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
}
|
||||
|
||||
@ -130,20 +125,11 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||
r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) });
|
||||
|
||||
Self {
|
||||
inner: PeripheralMutex::new(
|
||||
State {
|
||||
spim,
|
||||
waker: WakerRegistration::new(),
|
||||
},
|
||||
irq,
|
||||
),
|
||||
spim,
|
||||
irq,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn inner(self: Pin<&mut Self>) -> Pin<&mut PeripheralMutex<State<T>>> {
|
||||
unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> FullDuplex<u8> for Spim<'d, T> {
|
||||
@ -157,69 +143,69 @@ impl<'d, T: Instance> FullDuplex<u8> for Spim<'d, T> {
|
||||
type WriteReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn read<'a>(self: Pin<&'a mut Self>, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||
async move { todo!() }
|
||||
self.read_write(data, &[])
|
||||
}
|
||||
fn write<'a>(self: Pin<&'a mut Self>, data: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||
async move { todo!() }
|
||||
self.read_write(&mut [], data)
|
||||
}
|
||||
|
||||
fn read_write<'a>(
|
||||
mut self: Pin<&'a mut Self>,
|
||||
self: Pin<&'a mut Self>,
|
||||
rx: &'a mut [u8],
|
||||
tx: &'a [u8],
|
||||
) -> Self::WriteReadFuture<'a> {
|
||||
async move {
|
||||
let this = unsafe { self.get_unchecked_mut() };
|
||||
slice_in_ram_or(rx, Error::DMABufferNotInDataMemory)?;
|
||||
slice_in_ram_or(tx, Error::DMABufferNotInDataMemory)?;
|
||||
|
||||
self.as_mut().inner().register_interrupt();
|
||||
self.as_mut().inner().with(|s, _irq| {
|
||||
// Conservative compiler fence to prevent optimizations that do not
|
||||
// take in to account actions by DMA. The fence has been placed here,
|
||||
// before any DMA action has started.
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
// Conservative compiler fence to prevent optimizations that do not
|
||||
// take in to account actions by DMA. The fence has been placed here,
|
||||
// before any DMA action has started.
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
let r = s.spim.regs();
|
||||
let r = this.spim.regs();
|
||||
|
||||
// Set up the DMA write.
|
||||
r.txd
|
||||
.ptr
|
||||
.write(|w| unsafe { w.ptr().bits(tx.as_ptr() as u32) });
|
||||
r.txd
|
||||
.maxcnt
|
||||
.write(|w| unsafe { w.maxcnt().bits(tx.len() as _) });
|
||||
// Set up the DMA write.
|
||||
r.txd
|
||||
.ptr
|
||||
.write(|w| unsafe { w.ptr().bits(tx.as_ptr() as u32) });
|
||||
r.txd
|
||||
.maxcnt
|
||||
.write(|w| unsafe { w.maxcnt().bits(tx.len() as _) });
|
||||
|
||||
// Set up the DMA read.
|
||||
r.rxd
|
||||
.ptr
|
||||
.write(|w| unsafe { w.ptr().bits(rx.as_mut_ptr() as u32) });
|
||||
r.rxd
|
||||
.maxcnt
|
||||
.write(|w| unsafe { w.maxcnt().bits(rx.len() as _) });
|
||||
// Set up the DMA read.
|
||||
r.rxd
|
||||
.ptr
|
||||
.write(|w| unsafe { w.ptr().bits(rx.as_mut_ptr() as u32) });
|
||||
r.rxd
|
||||
.maxcnt
|
||||
.write(|w| unsafe { w.maxcnt().bits(rx.len() as _) });
|
||||
|
||||
// Reset and enable the event
|
||||
r.events_end.reset();
|
||||
r.intenset.write(|w| w.end().set());
|
||||
// Reset and enable the event
|
||||
r.events_end.reset();
|
||||
r.intenset.write(|w| w.end().set());
|
||||
|
||||
// Start SPI transaction.
|
||||
r.tasks_start.write(|w| unsafe { w.bits(1) });
|
||||
// Start SPI transaction.
|
||||
r.tasks_start.write(|w| unsafe { w.bits(1) });
|
||||
|
||||
// Conservative compiler fence to prevent optimizations that do not
|
||||
// take in to account actions by DMA. The fence has been placed here,
|
||||
// after all possible DMA actions have completed.
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
});
|
||||
// Conservative compiler fence to prevent optimizations that do not
|
||||
// take in to account actions by DMA. The fence has been placed here,
|
||||
// after all possible DMA actions have completed.
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
// Wait for 'end' event.
|
||||
poll_fn(|cx| {
|
||||
self.as_mut().inner().with(|s, _irq| {
|
||||
let r = s.spim.regs();
|
||||
if r.events_end.read().bits() != 0 {
|
||||
return Poll::Ready(());
|
||||
}
|
||||
s.waker.register(cx.waker());
|
||||
Poll::Pending
|
||||
})
|
||||
let r = this.spim.regs();
|
||||
|
||||
if r.events_end.read().bits() != 0 {
|
||||
r.events_end.reset();
|
||||
return Poll::Ready(());
|
||||
}
|
||||
|
||||
wake_on_interrupt(&mut this.irq, cx.waker());
|
||||
|
||||
Poll::Pending
|
||||
})
|
||||
.await;
|
||||
|
||||
@ -228,16 +214,6 @@ impl<'d, T: Instance> FullDuplex<u8> for Spim<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<U: Instance> PeripheralState for State<U> {
|
||||
type Interrupt = U::Interrupt;
|
||||
fn on_interrupt(&mut self) {
|
||||
if self.spim.regs().events_end.read().bits() != 0 {
|
||||
self.spim.regs().intenclr.write(|w| w.end().clear());
|
||||
self.waker.wake()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod sealed {
|
||||
use super::*;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user