aboutsummaryrefslogtreecommitdiff
path: root/embassy-rp/src/uart
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-rp/src/uart')
-rw-r--r--embassy-rp/src/uart/buffered.rs13
-rw-r--r--embassy-rp/src/uart/mod.rs28
2 files changed, 33 insertions, 8 deletions
diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs
index 02649ad81..fdb8ce776 100644
--- a/embassy-rp/src/uart/buffered.rs
+++ b/embassy-rp/src/uart/buffered.rs
@@ -1,8 +1,8 @@
1//! Buffered UART driver. 1//! Buffered UART driver.
2use core::future::Future; 2use core::future::Future;
3use core::slice; 3use core::slice;
4use core::sync::atomic::{AtomicU8, Ordering};
4 5
5use atomic_polyfill::AtomicU8;
6use embassy_hal_internal::atomic_ring_buffer::RingBuffer; 6use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
7 7
8use super::*; 8use super::*;
@@ -241,7 +241,11 @@ impl BufferedUartRx {
241 } 241 }
242 242
243 fn get_rx_error(state: &State) -> Option<Error> { 243 fn get_rx_error(state: &State) -> Option<Error> {
244 let errs = state.rx_error.swap(0, Ordering::Relaxed); 244 let errs = critical_section::with(|_| {
245 let val = state.rx_error.load(Ordering::Relaxed);
246 state.rx_error.store(0, Ordering::Relaxed);
247 val
248 });
245 if errs & RXE_OVERRUN != 0 { 249 if errs & RXE_OVERRUN != 0 {
246 Some(Error::Overrun) 250 Some(Error::Overrun)
247 } else if errs & RXE_BREAK != 0 { 251 } else if errs & RXE_BREAK != 0 {
@@ -555,7 +559,10 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for BufferedInterr
555 } 559 }
556 let dr = r.uartdr().read(); 560 let dr = r.uartdr().read();
557 if (dr.0 >> 8) != 0 { 561 if (dr.0 >> 8) != 0 {
558 s.rx_error.fetch_or((dr.0 >> 8) as u8, Ordering::Relaxed); 562 critical_section::with(|_| {
563 let val = s.rx_error.load(Ordering::Relaxed);
564 s.rx_error.store(val | ((dr.0 >> 8) as u8), Ordering::Relaxed);
565 });
559 error = true; 566 error = true;
560 // only fill the buffer with valid characters. the current character is fine 567 // only fill the buffer with valid characters. the current character is fine
561 // if the error is an overrun, but if we add it to the buffer we'll report 568 // if the error is an overrun, but if we add it to the buffer we'll report
diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs
index 8be87a5d2..b7b569dd5 100644
--- a/embassy-rp/src/uart/mod.rs
+++ b/embassy-rp/src/uart/mod.rs
@@ -1,9 +1,9 @@
1//! UART driver. 1//! UART driver.
2use core::future::poll_fn; 2use core::future::poll_fn;
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use core::sync::atomic::{AtomicU16, Ordering};
4use core::task::Poll; 5use core::task::Poll;
5 6
6use atomic_polyfill::{AtomicU16, Ordering};
7use embassy_futures::select::{Either, select}; 7use embassy_futures::select::{Either, select};
8use embassy_hal_internal::{Peri, PeripheralType}; 8use embassy_hal_internal::{Peri, PeripheralType};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
@@ -456,7 +456,12 @@ impl<'d> UartRx<'d, Async> {
456 transfer, 456 transfer,
457 poll_fn(|cx| { 457 poll_fn(|cx| {
458 self.dma_state.rx_err_waker.register(cx.waker()); 458 self.dma_state.rx_err_waker.register(cx.waker());
459 match self.dma_state.rx_errs.swap(0, Ordering::Relaxed) { 459 let rx_errs = critical_section::with(|_| {
460 let val = self.dma_state.rx_errs.load(Ordering::Relaxed);
461 self.dma_state.rx_errs.store(0, Ordering::Relaxed);
462 val
463 });
464 match rx_errs {
460 0 => Poll::Pending, 465 0 => Poll::Pending,
461 e => Poll::Ready(Uartris(e as u32)), 466 e => Poll::Ready(Uartris(e as u32)),
462 } 467 }
@@ -468,7 +473,11 @@ impl<'d> UartRx<'d, Async> {
468 Either::First(()) => { 473 Either::First(()) => {
469 // We're here because the DMA finished, BUT if an error occurred on the LAST 474 // We're here because the DMA finished, BUT if an error occurred on the LAST
470 // byte, then we may still need to grab the error state! 475 // byte, then we may still need to grab the error state!
471 Uartris(self.dma_state.rx_errs.swap(0, Ordering::Relaxed) as u32) 476 Uartris(critical_section::with(|_| {
477 let val = self.dma_state.rx_errs.load(Ordering::Relaxed);
478 self.dma_state.rx_errs.store(0, Ordering::Relaxed);
479 val
480 }) as u32)
472 } 481 }
473 Either::Second(e) => { 482 Either::Second(e) => {
474 // We're here because we errored, which means this is the error that 483 // We're here because we errored, which means this is the error that
@@ -616,7 +625,12 @@ impl<'d> UartRx<'d, Async> {
616 transfer, 625 transfer,
617 poll_fn(|cx| { 626 poll_fn(|cx| {
618 self.dma_state.rx_err_waker.register(cx.waker()); 627 self.dma_state.rx_err_waker.register(cx.waker());
619 match self.dma_state.rx_errs.swap(0, Ordering::Relaxed) { 628 let rx_errs = critical_section::with(|_| {
629 let val = self.dma_state.rx_errs.load(Ordering::Relaxed);
630 self.dma_state.rx_errs.store(0, Ordering::Relaxed);
631 val
632 });
633 match rx_errs {
620 0 => Poll::Pending, 634 0 => Poll::Pending,
621 e => Poll::Ready(Uartris(e as u32)), 635 e => Poll::Ready(Uartris(e as u32)),
622 } 636 }
@@ -629,7 +643,11 @@ impl<'d> UartRx<'d, Async> {
629 Either::First(()) => { 643 Either::First(()) => {
630 // We're here because the DMA finished, BUT if an error occurred on the LAST 644 // We're here because the DMA finished, BUT if an error occurred on the LAST
631 // byte, then we may still need to grab the error state! 645 // byte, then we may still need to grab the error state!
632 Uartris(self.dma_state.rx_errs.swap(0, Ordering::Relaxed) as u32) 646 Uartris(critical_section::with(|_| {
647 let val = self.dma_state.rx_errs.load(Ordering::Relaxed);
648 self.dma_state.rx_errs.store(0, Ordering::Relaxed);
649 val
650 }) as u32)
633 } 651 }
634 Either::Second(e) => { 652 Either::Second(e) => {
635 // We're here because we errored, which means this is the error that 653 // We're here because we errored, which means this is the error that