nrf/uart: share waker state between buffered and nonbuffered.

This commit is contained in:
Dario Nieuwenhuis 2024-02-21 22:29:37 +01:00
parent 1f17fdf84e
commit 4fbe18f821
2 changed files with 18 additions and 19 deletions

View file

@ -17,7 +17,6 @@ use core::task::Poll;
use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker;
// Re-export SVD variants to allow user to directly set values
pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
@ -35,11 +34,9 @@ mod sealed {
use super::*;
pub struct State {
pub tx_waker: AtomicWaker,
pub tx_buf: RingBuffer,
pub tx_count: AtomicUsize,
pub rx_waker: AtomicWaker,
pub rx_buf: RingBuffer,
pub rx_started: AtomicBool,
pub rx_started_count: AtomicU8,
@ -61,11 +58,9 @@ pub(crate) use sealed::State;
impl State {
pub(crate) const fn new() -> Self {
Self {
tx_waker: AtomicWaker::new(),
tx_buf: RingBuffer::new(),
tx_count: AtomicUsize::new(0),
rx_waker: AtomicWaker::new(),
rx_buf: RingBuffer::new(),
rx_started: AtomicBool::new(false),
rx_started_count: AtomicU8::new(0),
@ -84,6 +79,7 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt
unsafe fn on_interrupt() {
//trace!("irq: start");
let r = U::regs();
let ss = U::state();
let s = U::buffered_state();
if let Some(mut rx) = unsafe { s.rx_buf.try_writer() } {
@ -104,7 +100,7 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt
if r.inten.read().rxdrdy().bit_is_set() && r.events_rxdrdy.read().bits() != 0 {
r.intenclr.write(|w| w.rxdrdy().clear());
r.events_rxdrdy.reset();
s.rx_waker.wake();
ss.rx_waker.wake();
}
if r.events_endrx.read().bits() != 0 {
@ -190,7 +186,7 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt
let n = s.tx_count.load(Ordering::Relaxed);
//trace!(" irq_tx: endtx {:?}", n);
tx.pop_done(n);
s.tx_waker.wake();
ss.tx_waker.wake();
s.tx_count.store(0, Ordering::Relaxed);
}
@ -477,13 +473,14 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
pub async fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
poll_fn(move |cx| {
//trace!("poll_write: {:?}", buf.len());
let ss = U::state();
let s = U::buffered_state();
let mut tx = unsafe { s.tx_buf.writer() };
let tx_buf = tx.push_slice();
if tx_buf.is_empty() {
//trace!("poll_write: pending");
s.tx_waker.register(cx.waker());
ss.tx_waker.register(cx.waker());
return Poll::Pending;
}
@ -505,10 +502,11 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
pub async fn flush(&mut self) -> Result<(), Error> {
poll_fn(move |cx| {
//trace!("poll_flush");
let ss = U::state();
let s = U::buffered_state();
if !s.tx_buf.is_empty() {
//trace!("poll_flush: pending");
s.tx_waker.register(cx.waker());
ss.tx_waker.register(cx.waker());
return Poll::Pending;
}
@ -567,6 +565,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
let r = U::regs();
let s = U::buffered_state();
let ss = U::state();
// Read the RXDRDY counter.
T::regs().tasks_capture[0].write(|w| unsafe { w.bits(1) });
@ -590,7 +589,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
let len = s.rx_buf.len();
if start == end {
//trace!(" empty");
s.rx_waker.register(cx.waker());
ss.rx_waker.register(cx.waker());
r.intenset.write(|w| w.rxdrdy().set_bit());
return Poll::Pending;
}

View file

@ -115,7 +115,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
let endrx = r.events_endrx.read().bits();
let error = r.events_error.read().bits();
if endrx != 0 || error != 0 {
s.endrx_waker.wake();
s.rx_waker.wake();
if endrx != 0 {
r.intenclr.write(|w| w.endrx().clear());
}
@ -124,7 +124,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
}
}
if r.events_endtx.read().bits() != 0 {
s.endtx_waker.wake();
s.tx_waker.wake();
r.intenclr.write(|w| w.endtx().clear());
}
}
@ -433,7 +433,7 @@ impl<'d, T: Instance> UarteTx<'d, T> {
r.tasks_starttx.write(|w| unsafe { w.bits(1) });
poll_fn(|cx| {
s.endtx_waker.register(cx.waker());
s.tx_waker.register(cx.waker());
if r.events_endtx.read().bits() != 0 {
return Poll::Ready(());
}
@ -680,7 +680,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
r.tasks_startrx.write(|w| unsafe { w.bits(1) });
let result = poll_fn(|cx| {
s.endrx_waker.register(cx.waker());
s.rx_waker.register(cx.waker());
if let Err(e) = self.check_and_clear_errors() {
r.tasks_stoprx.write(|w| unsafe { w.bits(1) });
@ -827,7 +827,7 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> {
r.tasks_startrx.write(|w| unsafe { w.bits(1) });
let result = poll_fn(|cx| {
s.endrx_waker.register(cx.waker());
s.rx_waker.register(cx.waker());
if let Err(e) = self.rx.check_and_clear_errors() {
r.tasks_stoprx.write(|w| unsafe { w.bits(1) });
@ -970,15 +970,15 @@ pub(crate) mod sealed {
use super::*;
pub struct State {
pub endrx_waker: AtomicWaker,
pub endtx_waker: AtomicWaker,
pub rx_waker: AtomicWaker,
pub tx_waker: AtomicWaker,
pub tx_rx_refcount: AtomicU8,
}
impl State {
pub const fn new() -> Self {
Self {
endrx_waker: AtomicWaker::new(),
endtx_waker: AtomicWaker::new(),
rx_waker: AtomicWaker::new(),
tx_waker: AtomicWaker::new(),
tx_rx_refcount: AtomicU8::new(0),
}
}