Skip to content

Commit 8209ec7

Browse files
committed
Reduce FIFO threshold in read_exact_async
1 parent ed53656 commit 8209ec7

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

esp-hal/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2323
- RMT: `ChannelCreator::configure_tx` and `ChannelCreator::configure_rx` don't take a pin anymore, instead `Channel::with_pin` has been added. (#4302)
2424
- RMT: Configuration errors have been split out of `rmt::Error` into the new `rmt::ConfigError` enum. (#4494)
2525
- RMT: `Rmt::new()` now returns `Error::UnreachableTargetFrequency` instead of panicking when requesting 0 Hz. (#4509)
26+
- UART: changed the FIFO threshold in `read_exact_async` to reduce the likelyhood of `FifoOverflowed` errors. (#?)
2627

2728
- Internal clock configuration rework (#4501)
2829

esp-hal/src/uart/mod.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,21 +1072,17 @@ impl<'d> UartRx<'d, Async> {
10721072
async fn wait_for_buffered_data(
10731073
&mut self,
10741074
minimum: usize,
1075-
preferred: usize,
1075+
max_threshold: u16,
10761076
listen_for_timeout: bool,
10771077
) -> Result<(), RxError> {
10781078
while self.uart.info().rx_fifo_count() < (minimum as u16).min(Info::RX_FIFO_MAX_THRHD) {
1079-
let amount = u16::try_from(preferred)
1080-
.unwrap_or(Info::RX_FIFO_MAX_THRHD)
1081-
.min(Info::RX_FIFO_MAX_THRHD);
1082-
10831079
let current = self.uart.info().rx_fifo_full_threshold();
1084-
let _guard = if current > amount {
1080+
let _guard = if current > max_threshold {
10851081
// We're ignoring the user configuration here to ensure that this is not waiting
10861082
// for more data than the buffer. We'll restore the original value after the
10871083
// future resolved.
10881084
let info = self.uart.info();
1089-
unwrap!(info.set_rx_fifo_full_threshold(amount));
1085+
unwrap!(info.set_rx_fifo_full_threshold(max_threshold));
10901086
Some(OnDrop::new(|| {
10911087
unwrap!(info.set_rx_fifo_full_threshold(current));
10921088
}))
@@ -1153,7 +1149,12 @@ impl<'d> UartRx<'d, Async> {
11531149
return Ok(0);
11541150
}
11551151

1156-
self.wait_for_buffered_data(1, buf.len(), true).await?;
1152+
self.wait_for_buffered_data(
1153+
1,
1154+
buf.len().min(Info::RX_FIFO_MAX_THRHD as usize) as u16,
1155+
true,
1156+
)
1157+
.await?;
11571158

11581159
self.read_buffered(buf)
11591160
}
@@ -1177,8 +1178,16 @@ impl<'d> UartRx<'d, Async> {
11771178
// No point in listening for timeouts, as we're waiting for an exact amount of
11781179
// data. On ESP32 and S2, the timeout interrupt can't be cleared unless the FIFO
11791180
// is empty, so listening could cause an infinite loop here.
1180-
self.wait_for_buffered_data(buf.len(), buf.len(), false)
1181-
.await?;
1181+
//
1182+
// The threshold is set to 75% of the FIFO to reduce the likelihood of overflows.
1183+
self.wait_for_buffered_data(
1184+
buf.len(),
1185+
buf.len()
1186+
.min((Info::RX_FIFO_MAX_THRHD - Info::RX_FIFO_MAX_THRHD / 4) as usize)
1187+
as u16,
1188+
false,
1189+
)
1190+
.await?;
11821191

11831192
let read = self.uart.info().read_buffered(buf)?;
11841193
buf = &mut buf[read..];

0 commit comments

Comments
 (0)