Don't use embedded_dma in nrf uarte.

This commit is contained in:
Dario Nieuwenhuis 2021-01-02 19:14:54 +01:00
parent 396d7650ca
commit 3c7e7220b3
2 changed files with 26 additions and 38 deletions

View File

@ -28,6 +28,7 @@ async fn run(mut uart: uarte::Uarte<pac::UARTE0>) {
info!("wrote hello in uart!"); info!("wrote hello in uart!");
loop { loop {
let buf_len = buf.len();
info!("reading..."); info!("reading...");
// `receive()` doesn't return until the buffer has been completely filled with // `receive()` doesn't return until the buffer has been completely filled with
@ -37,19 +38,17 @@ async fn run(mut uart: uarte::Uarte<pac::UARTE0>) {
// 1 second timer, effectively adding a timeout to the receive operation. // 1 second timer, effectively adding a timeout to the receive operation.
let recv_fut = uart.receive(&mut buf); let recv_fut = uart.receive(&mut buf);
let timer_fut = Timer::after(Duration::from_millis(1000)); let timer_fut = Timer::after(Duration::from_millis(1000));
let received = match select(recv_fut, timer_fut).await { let received_len = match select(recv_fut, timer_fut).await {
// recv_fut completed first, so we've received `buf_len` bytes. // recv_fut completed first, so we've received `buf_len` bytes.
Either::Left((buf, _)) => buf, Either::Left(_) => buf_len,
// timer_fut completed first. `select` gives us back the future that didn't complete, which // timer_fut completed first. `select` gives us back the future that didn't complete, which
// is `recv_fut` in this case, so we can do further stuff with it. // is `recv_fut` in this case, so we can do further stuff with it.
// //
// The recv_fut would stop the uart read automatically when dropped. However, we want to know how // The recv_fut would stop the uart read automatically when dropped. However, we want to know how
// many bytes have been received, so we have to "gracefully stop" it with `.stop()`. // many bytes have been received, so we have to "gracefully stop" it with `.stop()`.
Either::Right((_, recv_fut)) => { Either::Right((_, recv_fut)) => recv_fut.stop().await,
let (buf, n) = recv_fut.stop().await;
&buf[..n]
}
}; };
let received = &mut buf[..received_len];
if received.len() > 0 { if received.len() > 0 {
info!("read done, got {:[u8]}", received); info!("read done, got {:[u8]}", received);

View File

@ -10,7 +10,6 @@ use core::sync::atomic::{compiler_fence, Ordering};
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use embassy::util::Signal; use embassy::util::Signal;
use embedded_dma::{ReadBuffer, WriteBuffer};
use crate::fmt::{assert, *}; use crate::fmt::{assert, *};
#[cfg(any(feature = "52833", feature = "52840"))] #[cfg(any(feature = "52833", feature = "52840"))]
@ -145,10 +144,7 @@ where
/// `tx_buffer` is marked as static as per `embedded-dma` requirements. /// `tx_buffer` is marked as static as per `embedded-dma` requirements.
/// It it safe to use a buffer with a non static lifetime if memory is not /// It it safe to use a buffer with a non static lifetime if memory is not
/// reused until the future has finished. /// reused until the future has finished.
pub fn send<'a, B>(&'a mut self, tx_buffer: B) -> SendFuture<'a, T, B> pub fn send<'a>(&'a mut self, tx_buffer: &'a [u8]) -> SendFuture<'a, T> {
where
B: ReadBuffer<Word = u8>,
{
// Panic if TX is running which can happen if the user has called // Panic if TX is running which can happen if the user has called
// `mem::forget()` on a previous future after polling it once. // `mem::forget()` on a previous future after polling it once.
assert!(!self.tx_started()); assert!(!self.tx_started());
@ -175,10 +171,7 @@ where
/// `rx_buffer` is marked as static as per `embedded-dma` requirements. /// `rx_buffer` is marked as static as per `embedded-dma` requirements.
/// It it safe to use a buffer with a non static lifetime if memory is not /// It it safe to use a buffer with a non static lifetime if memory is not
/// reused until the future has finished. /// reused until the future has finished.
pub fn receive<'a, B>(&'a mut self, rx_buffer: B) -> ReceiveFuture<'a, T, B> pub fn receive<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> ReceiveFuture<'a, T> {
where
B: WriteBuffer<Word = u8>,
{
// Panic if RX is running which can happen if the user has called // Panic if RX is running which can happen if the user has called
// `mem::forget()` on a previous future after polling it once. // `mem::forget()` on a previous future after polling it once.
assert!(!self.rx_started()); assert!(!self.rx_started());
@ -187,7 +180,7 @@ where
ReceiveFuture { ReceiveFuture {
uarte: self, uarte: self,
buf: Some(rx_buffer), buf: rx_buffer,
} }
} }
@ -239,15 +232,15 @@ where
} }
/// Future for the [`Uarte::send()`] method. /// Future for the [`Uarte::send()`] method.
pub struct SendFuture<'a, T, B> pub struct SendFuture<'a, T>
where where
T: Instance, T: Instance,
{ {
uarte: &'a Uarte<T>, uarte: &'a Uarte<T>,
buf: B, buf: &'a [u8],
} }
impl<'a, T, B> Drop for SendFuture<'a, T, B> impl<'a, T> Drop for SendFuture<'a, T>
where where
T: Instance, T: Instance,
{ {
@ -266,10 +259,9 @@ where
} }
} }
impl<'a, T, B> Future for SendFuture<'a, T, B> impl<'a, T> Future for SendFuture<'a, T>
where where
T: Instance, T: Instance,
B: ReadBuffer<Word = u8>,
{ {
type Output = (); type Output = ();
@ -281,7 +273,8 @@ where
T::state().tx_done.reset(); T::state().tx_done.reset();
let (ptr, len) = unsafe { buf.read_buffer() }; let ptr = buf.as_ptr();
let len = buf.len();
assert!(len <= EASY_DMA_SIZE); assert!(len <= EASY_DMA_SIZE);
// TODO: panic if buffer is not in SRAM // TODO: panic if buffer is not in SRAM
@ -301,15 +294,15 @@ where
} }
/// Future for the [`Uarte::receive()`] method. /// Future for the [`Uarte::receive()`] method.
pub struct ReceiveFuture<'a, T, B> pub struct ReceiveFuture<'a, T>
where where
T: Instance, T: Instance,
{ {
uarte: &'a Uarte<T>, uarte: &'a Uarte<T>,
buf: Option<B>, buf: &'a mut [u8],
} }
impl<'a, T, B> Drop for ReceiveFuture<'a, T, B> impl<'a, T> Drop for ReceiveFuture<'a, T>
where where
T: Instance, T: Instance,
{ {
@ -327,14 +320,13 @@ where
} }
} }
impl<'a, T, B> Future for ReceiveFuture<'a, T, B> impl<'a, T> Future for ReceiveFuture<'a, T>
where where
T: Instance, T: Instance,
B: WriteBuffer<Word = u8>,
{ {
type Output = B; type Output = ();
fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<B> { fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let Self { uarte, buf } = unsafe { self.get_unchecked_mut() }; let Self { uarte, buf } = unsafe { self.get_unchecked_mut() };
if !uarte.rx_started() { if !uarte.rx_started() {
@ -342,7 +334,8 @@ where
T::state().rx_done.reset(); T::state().rx_done.reset();
let (ptr, len) = unsafe { buf.as_mut().unwrap().write_buffer() }; let ptr = buf.as_ptr();
let len = buf.len();
assert!(len <= EASY_DMA_SIZE); assert!(len <= EASY_DMA_SIZE);
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
@ -356,24 +349,20 @@ where
uarte.tasks_startrx.write(|w| unsafe { w.bits(1) }); uarte.tasks_startrx.write(|w| unsafe { w.bits(1) });
} }
T::state() T::state().rx_done.poll_wait(cx).map(|_| ())
.rx_done
.poll_wait(cx)
.map(|_| buf.take().unwrap())
} }
} }
/// Future for the [`receive()`] method. /// Future for the [`receive()`] method.
impl<'a, T, B> ReceiveFuture<'a, T, B> impl<'a, T> ReceiveFuture<'a, T>
where where
T: Instance, T: Instance,
{ {
/// Stops the ongoing reception and returns the number of bytes received. /// Stops the ongoing reception and returns the number of bytes received.
pub async fn stop(mut self) -> (B, usize) { pub async fn stop(self) -> usize {
let buf = self.buf.take().unwrap();
drop(self); drop(self);
let len = T::state().rx_done.wait().await; let len = T::state().rx_done.wait().await;
(buf, len as _) len as _
} }
} }