#[non_exhaustive]pub enum BbqRxMode {
Efficiency,
MaxFrame {
size: usize,
},
}Expand description
RX Reception mode
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Efficiency
Default mode, attempts to utilize the ring buffer as maximally as possible.
In this mode, the interrupt will use whatever space is available, up to 1/4 the total ring buffer size, or the max DMA transfer size, whichever is smaller. however this may mean that if we are at the “end” of the ring buffer, some transfers may be smaller, meaning we need to “reload” the interrupt more often.
At slower UART rates (like 115_200), this is probably acceptable, as we have roughly 347us to service the “end of transfer” interrupt and reload the next DMA transfer. However at higher speeds (like 4_000_000), this time shrinks to 10us, meaning that critical sections (including defmt logging) may cause us to lose data.
If you know your maximum frame/burst size, you can instead use [RxMode::MaxFrame],
which will never allow “short” grants, with the trade off that we may reduce the
total usable capacity temporarily if we need to wrap around the ring buffer early.
MaxFrame
Max Frame mode, ensures that dma transfers always have exactly size bytes available
In this mode, we will always make DMA transfers of the given size. This is intended for
cases where we are receving bursts of data <= size, ideally with a short gap between
bursts. This means that we will receive an IDLE interrupt, and switch over receiving grants
in the quiet period, avoiding potentially latency-sensitive DMA transfer updates while
data is still being transferred. This is especially useful at higher baudrates.
The tradeoff here is that we can temporarily “waste” up to (size - 1) bytes if we
are forced to wrap-around the ring buffer early. For example if there is only 1023 bytes
in the ring buffer before it wraps around, and size = 1024, we will be forced to wrap
around the ring early, skipping that capacity. In some cases, where the required 1024
bytes are not available at the beginning of the ring buffer either, we will not begin
a transfer at all, potentially losing data if capacity is not freed up before the next
transfer starts (each time the ring buffer is drained, we will automatically re-start
receiving if enough capacity is made available).
size must be <= (capacity / 4).