feat: Block on uart calls, remove Option<> results

This commit is contained in:
Sergio Gasquez 2025-01-08 11:26:59 +01:00
parent f7de3bc2ab
commit 8dadabb5d4
2 changed files with 33 additions and 74 deletions

View File

@ -646,24 +646,17 @@ where
let count = data.len();
for &byte in data {
if self.write_byte(byte).is_none() {
return Err(Error::WouldBlock);
}
self.write_byte(byte);
}
Ok(count)
}
fn write_byte(&mut self, word: u8) -> Option<()> {
if self.tx_fifo_count() < UART_FIFO_SIZE {
self.register_block()
.fifo()
.write(|w| unsafe { w.rxfifo_rd_byte().bits(word) });
Some(())
} else {
None
}
fn write_byte(&mut self, word: u8) {
while self.tx_fifo_count() >= UART_FIFO_SIZE {}
self.register_block()
.fifo()
.write(|w| unsafe { w.rxfifo_rd_byte().bits(word) });
}
#[allow(clippy::useless_conversion)]
@ -679,12 +672,8 @@ where
}
/// Flush the transmit buffer of the UART
pub fn flush(&mut self) -> Option<()> {
if self.is_tx_idle() {
Some(())
} else {
None
}
pub fn flush(&mut self) {
while self.is_tx_idle() {}
}
/// Checks if the TX line is idle for this UART instance.
@ -830,7 +819,7 @@ where
}
/// Read a byte from the UART
pub fn read_byte(&mut self) -> Option<u8> {
pub fn read_byte(&mut self) -> u8 {
cfg_if::cfg_if! {
if #[cfg(esp32s2)] {
// On the ESP32-S2 we need to use PeriBus2 to read the FIFO:
@ -843,33 +832,25 @@ where
}
}
if self.rx_fifo_count() > 0 {
// https://docs.espressif.com/projects/esp-chip-errata/en/latest/esp32/03-errata-description/esp32/cpu-subsequent-access-halted-when-get-interrupted.html
cfg_if::cfg_if! {
if #[cfg(esp32)] {
let byte = crate::interrupt::free(|| fifo.read().rxfifo_rd_byte().bits());
} else {
let byte = fifo.read().rxfifo_rd_byte().bits();
}
while self.rx_fifo_count() == 0 {}
// https://docs.espressif.com/projects/esp-chip-errata/en/latest/esp32/03-errata-description/esp32/cpu-subsequent-access-halted-when-get-interrupted.html
cfg_if::cfg_if! {
if #[cfg(esp32)] {
let byte = crate::interrupt::free(|| fifo.read().rxfifo_rd_byte().bits());
} else {
let byte = fifo.read().rxfifo_rd_byte().bits();
}
Some(byte)
} else {
None
}
byte
}
/// Read all available bytes from the RX FIFO into the provided buffer and
/// returns the number of read bytes without blocking.
/// Read as many bytes from the UART as the provided buffer can hold.
pub fn read_bytes(&mut self, buf: &mut [u8]) -> usize {
let mut count = 0;
while count < buf.len() {
if let Some(byte) = self.read_byte() {
buf[count] = byte;
count += 1;
} else {
break;
}
buf[count] = self.read_byte();
count += 1;
}
count
}
@ -1137,17 +1118,17 @@ where
}
/// Write a byte out over the UART
pub fn write_byte(&mut self, word: u8) -> Option<()> {
pub fn write_byte(&mut self, word: u8) {
self.tx.write_byte(word)
}
/// Flush the transmit buffer of the UART
pub fn flush(&mut self) -> Option<()> {
pub fn flush(&mut self) {
self.tx.flush()
}
/// Read a byte from the UART
pub fn read_byte(&mut self) -> Option<u8> {
pub fn read_byte(&mut self) -> u8 {
self.rx.read_byte()
}
@ -1421,13 +1402,7 @@ where
}
fn flush(&mut self) -> Result<(), Self::Error> {
loop {
match self.flush() {
Some(_) => break,
None => { /* Wait */ }
}
}
self.flush();
Ok(())
}
}
@ -1651,7 +1626,7 @@ impl UartTx<'_, Async> {
}
for byte in &words[offset..next_offset] {
self.write_byte(*byte).unwrap(); // should never fail
self.write_byte(*byte);
count += 1;
}

View File

@ -5,7 +5,6 @@
#![no_std]
#![no_main]
use embedded_hal_nb::serial::{Read, Write};
use esp_hal::{
uart::{self, ClockSource, Uart},
Blocking,
@ -37,13 +36,8 @@ mod tests {
#[test]
fn test_send_receive(mut ctx: Context) {
ctx.uart.write(0x42).ok();
let read = loop {
if let Ok(byte) = ctx.uart.read() {
break byte;
}
};
ctx.uart.write_byte(0x42);
let read = ctx.uart.read_byte();
assert_eq!(read, 0x42);
}
@ -59,16 +53,9 @@ mod tests {
let mut i = 0;
while i < BUF_SIZE {
match ctx.uart.read() {
Ok(byte) => {
buffer[i] = byte;
i += 1;
}
Err(embedded_hal_nb::nb::Error::WouldBlock) => continue,
Err(embedded_hal_nb::nb::Error::Other(_)) => panic!(),
}
buffer[i] = ctx.uart.read_byte();
i += 1;
}
assert_eq!(data, buffer);
}
@ -97,12 +84,9 @@ mod tests {
.with_clock_source(clock_source),
)
.unwrap();
ctx.uart.write(byte_to_write).ok();
let read = loop {
if let Ok(byte) = ctx.uart.read() {
break byte;
}
};
ctx.uart.write_byte(byte_to_write);
let read = ctx.uart.read_byte();
assert_eq!(read, byte_to_write);
byte_to_write = !byte_to_write;
}