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 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 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.
-
If
eager_reads
is enabled inconfig
, the UART interrupt is enabled on all data reception and the call will only wait for at least one byte 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, 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 data byte. The data is still copied using DMA, but
there is nevertheless additional processing overhead for each byte.
Implementations§
Source§impl<'d> RingBufferedUartRx<'d>
impl<'d> RingBufferedUartRx<'d>
Sourcepub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError>
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError>
Reconfigure the driver
Sourcepub fn start_uart(&mut self)
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.
Sourcepub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error>
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.
Sourcepub fn set_baudrate(&self, baudrate: u32) -> Result<(), ConfigError>
pub fn set_baudrate(&self, baudrate: u32) -> Result<(), ConfigError>
Set baudrate
Trait Implementations§
Source§impl Drop for RingBufferedUartRx<'_>
impl Drop for RingBufferedUartRx<'_>
Source§impl ErrorType for RingBufferedUartRx<'_>
impl ErrorType for RingBufferedUartRx<'_>
Source§impl Read for RingBufferedUartRx<'_>
impl Read for RingBufferedUartRx<'_>
Source§async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>
Source§async fn read_exact(
&mut self,
buf: &mut [u8],
) -> Result<(), ReadExactError<Self::Error>>
async fn read_exact( &mut self, buf: &mut [u8], ) -> Result<(), ReadExactError<Self::Error>>
buf
. Read moreSource§impl Read for RingBufferedUartRx<'_>
impl Read for RingBufferedUartRx<'_>
Source§impl ReadReady for RingBufferedUartRx<'_>
impl ReadReady for RingBufferedUartRx<'_>
Source§impl<'d> SetConfig for RingBufferedUartRx<'d>
impl<'d> SetConfig for RingBufferedUartRx<'d>
Source§type ConfigError = ConfigError
type ConfigError = ConfigError
set_config
fails.