diff options
Diffstat (limited to 'embassy-nrf/src/buffered_uarte.rs')
| -rw-r--r-- | embassy-nrf/src/buffered_uarte.rs | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 40c679190..b1eb5c81a 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs | |||
| @@ -9,27 +9,27 @@ | |||
| 9 | //! Please also see [crate::uarte] to understand when [BufferedUarte] should be used. | 9 | //! Please also see [crate::uarte] to understand when [BufferedUarte] should be used. |
| 10 | 10 | ||
| 11 | use core::cmp::min; | 11 | use core::cmp::min; |
| 12 | use core::future::{poll_fn, Future}; | 12 | use core::future::{Future, poll_fn}; |
| 13 | use core::marker::PhantomData; | 13 | use core::marker::PhantomData; |
| 14 | use core::slice; | 14 | use core::slice; |
| 15 | use core::sync::atomic::{compiler_fence, AtomicBool, AtomicU8, AtomicUsize, Ordering}; | 15 | use core::sync::atomic::{AtomicBool, AtomicU8, AtomicUsize, Ordering, compiler_fence}; |
| 16 | use core::task::Poll; | 16 | use core::task::Poll; |
| 17 | 17 | ||
| 18 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; | ||
| 19 | use embassy_hal_internal::Peri; | 18 | use embassy_hal_internal::Peri; |
| 19 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; | ||
| 20 | use pac::uarte::vals; | 20 | use pac::uarte::vals; |
| 21 | // Re-export SVD variants to allow user to directly set values | 21 | // Re-export SVD variants to allow user to directly set values |
| 22 | pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; | 22 | pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; |
| 23 | 23 | ||
| 24 | use crate::gpio::{AnyPin, Pin as GpioPin}; | 24 | use crate::gpio::{AnyPin, Pin as GpioPin}; |
| 25 | use crate::interrupt::typelevel::Interrupt; | ||
| 26 | use crate::interrupt::InterruptExt; | 25 | use crate::interrupt::InterruptExt; |
| 26 | use crate::interrupt::typelevel::Interrupt; | ||
| 27 | use crate::ppi::{ | 27 | use crate::ppi::{ |
| 28 | self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task, | 28 | self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task, |
| 29 | }; | 29 | }; |
| 30 | use crate::timer::{Instance as TimerInstance, Timer}; | 30 | use crate::timer::{Instance as TimerInstance, Timer}; |
| 31 | use crate::uarte::{configure, configure_rx_pins, configure_tx_pins, drop_tx_rx, Config, Instance as UarteInstance}; | 31 | use crate::uarte::{Config, Instance as UarteInstance, configure, configure_rx_pins, configure_tx_pins, drop_tx_rx}; |
| 32 | use crate::{interrupt, pac, EASY_DMA_SIZE}; | 32 | use crate::{EASY_DMA_SIZE, interrupt, pac}; |
| 33 | 33 | ||
| 34 | pub(crate) struct State { | 34 | pub(crate) struct State { |
| 35 | tx_buf: RingBuffer, | 35 | tx_buf: RingBuffer, |
| @@ -40,6 +40,7 @@ pub(crate) struct State { | |||
| 40 | rx_started_count: AtomicU8, | 40 | rx_started_count: AtomicU8, |
| 41 | rx_ended_count: AtomicU8, | 41 | rx_ended_count: AtomicU8, |
| 42 | rx_ppi_ch: AtomicU8, | 42 | rx_ppi_ch: AtomicU8, |
| 43 | rx_overrun: AtomicBool, | ||
| 43 | } | 44 | } |
| 44 | 45 | ||
| 45 | /// UART error. | 46 | /// UART error. |
| @@ -47,7 +48,8 @@ pub(crate) struct State { | |||
| 47 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 48 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 48 | #[non_exhaustive] | 49 | #[non_exhaustive] |
| 49 | pub enum Error { | 50 | pub enum Error { |
| 50 | // No errors for now | 51 | /// Buffer Overrun |
| 52 | Overrun, | ||
| 51 | } | 53 | } |
| 52 | 54 | ||
| 53 | impl State { | 55 | impl State { |
| @@ -61,6 +63,7 @@ impl State { | |||
| 61 | rx_started_count: AtomicU8::new(0), | 63 | rx_started_count: AtomicU8::new(0), |
| 62 | rx_ended_count: AtomicU8::new(0), | 64 | rx_ended_count: AtomicU8::new(0), |
| 63 | rx_ppi_ch: AtomicU8::new(0), | 65 | rx_ppi_ch: AtomicU8::new(0), |
| 66 | rx_overrun: AtomicBool::new(false), | ||
| 64 | } | 67 | } |
| 65 | } | 68 | } |
| 66 | } | 69 | } |
| @@ -87,7 +90,8 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 87 | r.errorsrc().write_value(errs); | 90 | r.errorsrc().write_value(errs); |
| 88 | 91 | ||
| 89 | if errs.overrun() { | 92 | if errs.overrun() { |
| 90 | panic!("BufferedUarte overrun"); | 93 | s.rx_overrun.store(true, Ordering::Release); |
| 94 | ss.rx_waker.wake(); | ||
| 91 | } | 95 | } |
| 92 | } | 96 | } |
| 93 | 97 | ||
| @@ -689,6 +693,7 @@ impl<'d> BufferedUarteRx<'d> { | |||
| 689 | buffered_state.rx_started_count.store(0, Ordering::Relaxed); | 693 | buffered_state.rx_started_count.store(0, Ordering::Relaxed); |
| 690 | buffered_state.rx_ended_count.store(0, Ordering::Relaxed); | 694 | buffered_state.rx_ended_count.store(0, Ordering::Relaxed); |
| 691 | buffered_state.rx_started.store(false, Ordering::Relaxed); | 695 | buffered_state.rx_started.store(false, Ordering::Relaxed); |
| 696 | buffered_state.rx_overrun.store(false, Ordering::Relaxed); | ||
| 692 | let rx_len = rx_buffer.len().min(EASY_DMA_SIZE * 2); | 697 | let rx_len = rx_buffer.len().min(EASY_DMA_SIZE * 2); |
| 693 | unsafe { buffered_state.rx_buf.init(rx_buffer.as_mut_ptr(), rx_len) }; | 698 | unsafe { buffered_state.rx_buf.init(rx_buffer.as_mut_ptr(), rx_len) }; |
| 694 | 699 | ||
| @@ -762,6 +767,10 @@ impl<'d> BufferedUarteRx<'d> { | |||
| 762 | compiler_fence(Ordering::SeqCst); | 767 | compiler_fence(Ordering::SeqCst); |
| 763 | //trace!("poll_read"); | 768 | //trace!("poll_read"); |
| 764 | 769 | ||
| 770 | if s.rx_overrun.swap(false, Ordering::Acquire) { | ||
| 771 | return Poll::Ready(Err(Error::Overrun)); | ||
| 772 | } | ||
| 773 | |||
| 765 | // Read the RXDRDY counter. | 774 | // Read the RXDRDY counter. |
| 766 | timer.cc(0).capture(); | 775 | timer.cc(0).capture(); |
| 767 | let mut end = timer.cc(0).read() as usize; | 776 | let mut end = timer.cc(0).read() as usize; |
| @@ -820,6 +829,9 @@ impl<'d> BufferedUarteRx<'d> { | |||
| 820 | /// we are ready to read if there is data in the buffer | 829 | /// we are ready to read if there is data in the buffer |
| 821 | fn read_ready(&self) -> Result<bool, Error> { | 830 | fn read_ready(&self) -> Result<bool, Error> { |
| 822 | let state = self.buffered_state; | 831 | let state = self.buffered_state; |
| 832 | if state.rx_overrun.swap(false, Ordering::Acquire) { | ||
| 833 | return Err(Error::Overrun); | ||
| 834 | } | ||
| 823 | Ok(!state.rx_buf.is_empty()) | 835 | Ok(!state.rx_buf.is_empty()) |
| 824 | } | 836 | } |
| 825 | } | 837 | } |
| @@ -854,7 +866,9 @@ mod _embedded_io { | |||
| 854 | 866 | ||
| 855 | impl embedded_io_async::Error for Error { | 867 | impl embedded_io_async::Error for Error { |
| 856 | fn kind(&self) -> embedded_io_async::ErrorKind { | 868 | fn kind(&self) -> embedded_io_async::ErrorKind { |
| 857 | match *self {} | 869 | match *self { |
| 870 | Error::Overrun => embedded_io_async::ErrorKind::OutOfMemory, | ||
| 871 | } | ||
| 858 | } | 872 | } |
| 859 | } | 873 | } |
| 860 | 874 | ||
