nrf/uart: share waker state between buffered and nonbuffered.
This commit is contained in:
parent
1f17fdf84e
commit
4fbe18f821
2 changed files with 18 additions and 19 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue