embassy-stm32

Crates

git

Versions

stm32f100c6

Flavors

Struct RingBufferedUartRx

Source
pub struct RingBufferedUartRx<'d> { /* private fields */ }
Expand description

Rx-only Ring-buffered UART Driver

Created with UartRx::into_ring_buffered

§Notes on ‘waiting for bytes’

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

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

  • If the sender sends intermittently, the ‘idle line’ condition will be detected when the sender stops, and any bytes in the ring buffer will be returned. If there are no bytes in the buffer, the check will be repeated each time the ‘idle line’ condition is detected, so if the sender sends just a single byte, 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 byte or last byte 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.

In both 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, 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: This latency is caused by the limited capabilities of the STM32 DMA controller; since it cannot generate an interrupt when it stores a byte into an empty ring buffer, or in any other configurable conditions, it is not possible to take notice of the contents of the ring buffer more quickly without introducing polling. As a result the latency can be reduced by calling the read functions repeatedly with smaller buffers to receive the available bytes, as each call to a read function will explicitly check the ring buffer for available bytes.

Implementations§

Source§

impl<'d> RingBufferedUartRx<'d>

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 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error>

Read bytes that are available in the ring buffer, or wait for bytes to become available and return them.

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 Drop for RingBufferedUartRx<'_>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl ErrorType for RingBufferedUartRx<'_>

Source§

type Error = Error

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

impl ErrorType for RingBufferedUartRx<'_>

Source§

type Error = Error

Error type
Source§

impl Read for RingBufferedUartRx<'_>

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<'_>

Source§

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

Reads a single word from the serial interface
Source§

impl ReadReady for RingBufferedUartRx<'_>

Source§

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

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

impl<'d> SetConfig for RingBufferedUartRx<'d>

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> Freeze for RingBufferedUartRx<'d>

§

impl<'d> !RefUnwindSafe for RingBufferedUartRx<'d>

§

impl<'d> Send for RingBufferedUartRx<'d>

§

impl<'d> Sync for RingBufferedUartRx<'d>

§

impl<'d> Unpin for RingBufferedUartRx<'d>

§

impl<'d> !UnwindSafe for RingBufferedUartRx<'d>

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 = Infallible

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.