embassy-stm32

Crates

git

Versions

stm32l4r5vi

Flavors

Skip to main content

RingBufferedUartRx

Struct RingBufferedUartRx 

Source
pub struct RingBufferedUartRx<'d, W: UsartWord = u8> { /* private fields */ }
Expand description

Rx-only Ring-buffered UART Driver

Created with UartRx::into_ring_buffered

§Notes on ‘waiting for words’

The read(buf) (but not read()) function may need to wait for words to arrive, if the ring buffer does not contain enough words to fill the buffer passed by the caller of the function, or is empty.

Waiting for words operates in one of three modes, depending on the behavior of the sender, the size of the buffer passed to the function, and the configuration:

  • If the sender sends intermittently, the ‘idle line’ condition will be detected when the sender stops, and any words in the ring buffer will be returned. If there are no words in the buffer, the check will be repeated each time the ‘idle line’ condition is detected, so if the sender sends just a single word, it will be returned once the ‘idle line’ condition is detected.

  • If the sender sends continuously, the call will wait until the DMA controller indicates that it has written to either the middle word or last word of the ring buffer (‘half transfer’ or ‘transfer complete’, respectively). This does not indicate the buffer is half-full or full, though, because the DMA controller does not detect those conditions; it sends an interrupt when those specific buffer addresses have been written.

  • If eager_reads is enabled in config, the UART interrupt is enabled on all data reception and the call will only wait for at least one word to be available before returning.

In the first two cases this will result in variable latency due to the buffering effect. For example, if the baudrate is 2400 bps, and the configuration is 8 data bits (so each word is one byte), no parity bit, and one stop bit, then a byte will be received every ~4.16ms. If the ring buffer is 32 bytes, then a ‘wait for bytes’ delay may have to wait for 16 bytes in the worst case, resulting in a delay (latency) of ~62.46ms for the first byte in the ring buffer. If the sender sends only 6 bytes and then stops, but the buffer was empty when the read function was called, then those bytes may not be returned until ~24.96ms after the first byte was received (time for 5 additional bytes plus the ‘idle frame’ which triggers the ‘idle line’ condition).

Applications subject to this latency must be careful if they also apply timeouts during reception, as it may appear (to them) that the sender has stopped sending when it did not. In the example above, a 50ms timeout (12 bytes at 2400bps) might seem to be reasonable to detect that the sender has stopped sending, but would be falsely triggered in the worst-case buffer delay scenario.

Note: Enabling eager_reads with RingBufferedUartRx will enable an UART RXNE interrupt, which will cause an interrupt to occur on every received word. The data is still copied using DMA, but there is nevertheless additional processing overhead for each word.

Implementations§

Source§

impl<'d, W: UsartWord> RingBufferedUartRx<'d, W>

Source

pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError>

Reconfigure the driver

Source

pub fn start_uart(&mut self)

Configure and start the DMA backed UART receiver

Note: This is also done automatically by the read functions if required.

Source

pub fn clear(&mut self)

Clears ring buffer.

Source

pub async fn read(&mut self, buf: &mut [W]) -> Result<usize, Error>

Read words that are available in the ring buffer, or wait for words to become available and return them. Returns the number of words read into buf.

Background reception is started if necessary (if start_uart() had not previously been called, or if an error was detected which caused background reception to be stopped).

Background reception is terminated when an error is returned. It must be started again by calling start_uart() or by calling a read function again.

Source

pub fn set_baudrate(&self, baudrate: u32) -> Result<(), ConfigError>

Set baudrate

Trait Implementations§

Source§

impl<W: UsartWord> Drop for RingBufferedUartRx<'_, W>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl<W: UsartWord> ErrorType for RingBufferedUartRx<'_, W>

Source§

type Error = Error

Error type of all the IO operations on this type.
Source§

impl<W: UsartWord> ErrorType for RingBufferedUartRx<'_, W>

Source§

type Error = Error

Error type
Source§

impl Read for RingBufferedUartRx<'_, u8>

Source§

async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>

Read some bytes from this source into the specified buffer, returning how many bytes were read. Read more
Source§

async fn read_exact( &mut self, buf: &mut [u8], ) -> Result<(), ReadExactError<Self::Error>>

Read the exact number of bytes required to fill buf. Read more
Source§

impl Read for RingBufferedUartRx<'_, u8>

Source§

fn read(&mut self) -> Result<u8, Self::Error>

Reads a single word from the serial interface
Source§

impl<W: UsartWord> ReadReady for RingBufferedUartRx<'_, W>

Source§

fn read_ready(&mut self) -> Result<bool, Self::Error>

Get whether the reader is ready for immediately reading. Read more
Source§

impl<'d, W: UsartWord> SetConfig for RingBufferedUartRx<'d, W>

Source§

type Config = Config

The configuration type used by this driver.
Source§

type ConfigError = ConfigError

The error type that can occur if set_config fails.
Source§

fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError>

Set the configuration of the driver.

Auto Trait Implementations§

§

impl<'d, W = u8> !RefUnwindSafe for RingBufferedUartRx<'d, W>

§

impl<'d, W = u8> !UnwindSafe for RingBufferedUartRx<'d, W>

§

impl<'d, W> Freeze for RingBufferedUartRx<'d, W>
where ReadableRingBuffer<'d, W>: Freeze,

§

impl<'d, W> Send for RingBufferedUartRx<'d, W>
where ReadableRingBuffer<'d, W>: Send,

§

impl<'d, W> Sync for RingBufferedUartRx<'d, W>
where ReadableRingBuffer<'d, W>: Sync,

§

impl<'d, W> Unpin for RingBufferedUartRx<'d, W>
where ReadableRingBuffer<'d, W>: Unpin,

§

impl<'d, W> UnsafeUnpin for RingBufferedUartRx<'d, W>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.