Skip to content

Commit 240b205

Browse files
authored
esp-hal-common: uart/ESP32: fix get_rx_fifo_count() (#804)
Currently the `get_rx_fifo_count()` is using `fifo_cnt`, which is unreliable for ESP32, according to the errata: https://www.espressif.com/sites/default/files/documentation/esp32_errata_en.pdf section 3.17 This commit is fixing the code for the ESP32 according to the workaround example. Main discussion and my debugging results: https://github.com/esp-rs/esp-hal/discussions/765
1 parent 434a327 commit 240b205

2 files changed

Lines changed: 37 additions & 2 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
- Add new_no_miso to Spi FullDuplexMode (#794)
1818
- Add UART support for splitting into TX and RX (#754)
1919
- Async support for I2S (#801)
20+
- UART/ESP32: fix calculating FIFO counter with `get_rx_fifo_count()` (#804)
2021

2122
### Changed
2223

‎esp-hal-common/src/uart.rs‎

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -891,12 +891,46 @@ pub trait Instance {
891891
}
892892

893893
fn get_rx_fifo_count() -> u16 {
894-
Self::register_block()
894+
let fifo_cnt: u16 = Self::register_block()
895895
.status
896896
.read()
897897
.rxfifo_cnt()
898898
.bits()
899-
.into()
899+
.into();
900+
901+
// Calculate the real count based on the FIFO read and write offset address:
902+
// https://www.espressif.com/sites/default/files/documentation/esp32_errata_en.pdf
903+
// section 3.17
904+
#[cfg(esp32)]
905+
{
906+
let rd_addr: u16 = Self::register_block()
907+
.mem_rx_status
908+
.read()
909+
.mem_rx_rd_addr()
910+
.bits()
911+
.into();
912+
let wr_addr: u16 = Self::register_block()
913+
.mem_rx_status
914+
.read()
915+
.mem_rx_wr_addr()
916+
.bits()
917+
.into();
918+
919+
if wr_addr > rd_addr {
920+
wr_addr - rd_addr
921+
} else if wr_addr < rd_addr {
922+
(wr_addr + UART_FIFO_SIZE) - rd_addr
923+
} else {
924+
if fifo_cnt > 0 {
925+
UART_FIFO_SIZE
926+
} else {
927+
0
928+
}
929+
}
930+
}
931+
932+
#[cfg(not(esp32))]
933+
fifo_cnt
900934
}
901935

902936
fn is_tx_idle() -> bool {

0 commit comments

Comments
 (0)