Multiple API fixes in UART driver (#2851)

* Close a number of issues

doctest update

fmt

* changelog entry

* dumb

* addressing reviews

* Add an entry to migration guide
This commit is contained in:
Kirill Mikhailov 2024-12-20 15:01:11 +01:00 committed by GitHub
parent 286219707c
commit 62c72947dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 36 additions and 32 deletions

View File

@ -87,6 +87,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `crate::Mode` was renamed to `crate::DriverMode` (#2828) - `crate::Mode` was renamed to `crate::DriverMode` (#2828)
- Renamed some I2C error variants (#2844) - Renamed some I2C error variants (#2844)
- I2C: Replaced potential panics with errors. (#2831) - I2C: Replaced potential panics with errors. (#2831)
- UART: Make `AtCmdConfig` and `ConfigError` non-exhaustive (#2851)
- UART: Make `AtCmdConfig` use builder-lite pattern (#2851)
### Fixed ### Fixed
@ -94,6 +96,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- User-bound GPIO interrupt handlers should no longer interfere with async pins. (#2625) - User-bound GPIO interrupt handlers should no longer interfere with async pins. (#2625)
- `spi::master::Spi::{into_async, into_blocking}` are now correctly available on the typed driver, to. (#2674) - `spi::master::Spi::{into_async, into_blocking}` are now correctly available on the typed driver, to. (#2674)
- It is no longer possible to safely conjure `GpioPin` instances (#2688) - It is no longer possible to safely conjure `GpioPin` instances (#2688)
- UART: Public API follows `C-WORD_ORDER` Rust API standard (`VerbObject` order) (#2851)
### Removed ### Removed

View File

@ -336,3 +336,10 @@ The reexports that were previously part of the prelude are available through oth
- `esp_hal::timer::Timer` - `esp_hal::timer::Timer`
- `esp_hal::interrupt::InterruptConfigurable` - `esp_hal::interrupt::InterruptConfigurable`
- The `entry` macro can be imported as `esp_hal::entry`, while other macros are found under `esp_hal::macros` - The `entry` macro can be imported as `esp_hal::entry`, while other macros are found under `esp_hal::macros`
## `AtCmdConfig` now uses builder-lite pattern
```diff
- uart0.set_at_cmd(AtCmdConfig::new(None, None, None, b'#', None));
+ uart0.set_at_cmd(AtCmdConfig::default().with_cmd_char(b'#'));
```

View File

@ -164,7 +164,7 @@
//! uart0.set_interrupt_handler(interrupt_handler); //! uart0.set_interrupt_handler(interrupt_handler);
//! //!
//! critical_section::with(|cs| { //! critical_section::with(|cs| {
//! uart0.set_at_cmd(AtCmdConfig::new(None, None, None, b'#', None)); //! uart0.set_at_cmd(AtCmdConfig::default().with_cmd_char(b'#'));
//! uart0.listen(UartInterrupt::AtCmd | UartInterrupt::RxFifoFull); //! uart0.listen(UartInterrupt::AtCmd | UartInterrupt::RxFifoFull);
//! //!
//! SERIAL.borrow_ref_mut(cs).replace(uart0); //! SERIAL.borrow_ref_mut(cs).replace(uart0);
@ -250,6 +250,7 @@ use crate::{
}; };
const UART_FIFO_SIZE: u16 = 128; const UART_FIFO_SIZE: u16 = 128;
const CMD_CHAR_DEFAULT: u8 = 0x2b;
/// UART Error /// UART Error
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
@ -510,6 +511,9 @@ impl Default for Config {
} }
} }
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, procmacros::BuilderLite)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
/// Configuration for the AT-CMD detection functionality /// Configuration for the AT-CMD detection functionality
pub struct AtCmdConfig { pub struct AtCmdConfig {
/// Optional idle time before the AT command detection begins, in clock /// Optional idle time before the AT command detection begins, in clock
@ -524,28 +528,17 @@ pub struct AtCmdConfig {
/// The character that triggers the AT command detection. /// The character that triggers the AT command detection.
pub cmd_char: u8, pub cmd_char: u8,
/// Optional number of characters to detect as part of the AT command. /// Optional number of characters to detect as part of the AT command.
pub char_num: Option<u8>, pub char_num: u8,
} }
impl AtCmdConfig { impl Default for AtCmdConfig {
/// Creates a new `AtCmdConfig` with the specified configuration. fn default() -> Self {
///
/// This function sets up the AT command detection parameters, including
/// pre- and post-idle times, a gap timeout, the triggering command
/// character, and the number of characters to detect.
pub fn new(
pre_idle_count: Option<u16>,
post_idle_count: Option<u16>,
gap_timeout: Option<u16>,
cmd_char: u8,
char_num: Option<u8>,
) -> AtCmdConfig {
Self { Self {
pre_idle_count, pre_idle_count: None,
post_idle_count, post_idle_count: None,
gap_timeout, gap_timeout: None,
cmd_char, cmd_char: CMD_CHAR_DEFAULT,
char_num, char_num: 1,
} }
} }
} }
@ -631,6 +624,7 @@ pub struct UartRx<'d, Dm, T = AnyUart> {
/// A configuration error. /// A configuration error.
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
pub enum ConfigError { pub enum ConfigError {
/// The requested timeout is not supported. /// The requested timeout is not supported.
UnsupportedTimeout, UnsupportedTimeout,
@ -752,7 +746,7 @@ where
} }
/// Flush the transmit buffer of the UART /// Flush the transmit buffer of the UART
pub fn flush_tx(&mut self) -> nb::Result<(), Error> { pub fn flush(&mut self) -> nb::Result<(), Error> {
if self.is_tx_idle() { if self.is_tx_idle() {
Ok(()) Ok(())
} else { } else {
@ -1219,7 +1213,7 @@ where
register_block.at_cmd_char().write(|w| unsafe { register_block.at_cmd_char().write(|w| unsafe {
w.at_cmd_char().bits(config.cmd_char); w.at_cmd_char().bits(config.cmd_char);
w.char_num().bits(config.char_num.unwrap_or(1)) w.char_num().bits(config.char_num)
}); });
if let Some(pre_idle_count) = config.pre_idle_count { if let Some(pre_idle_count) = config.pre_idle_count {
@ -1254,8 +1248,8 @@ where
} }
/// Flush the transmit buffer of the UART /// Flush the transmit buffer of the UART
pub fn flush_tx(&mut self) -> nb::Result<(), Error> { pub fn flush(&mut self) -> nb::Result<(), Error> {
self.tx.flush_tx() self.tx.flush()
} }
/// Read a byte from the UART /// Read a byte from the UART
@ -1477,7 +1471,7 @@ where
} }
fn flush(&mut self) -> nb::Result<(), Self::Error> { fn flush(&mut self) -> nb::Result<(), Self::Error> {
self.flush_tx() self.flush()
} }
} }
@ -1491,7 +1485,7 @@ where
} }
fn flush(&mut self) -> nb::Result<(), Self::Error> { fn flush(&mut self) -> nb::Result<(), Self::Error> {
self.flush_tx() self.flush()
} }
} }
@ -1581,7 +1575,7 @@ where
} }
fn flush(&mut self) -> Result<(), Self::Error> { fn flush(&mut self) -> Result<(), Self::Error> {
self.tx.flush() embedded_io::Write::flush(&mut self.tx)
} }
} }
@ -1598,7 +1592,7 @@ where
fn flush(&mut self) -> Result<(), Self::Error> { fn flush(&mut self) -> Result<(), Self::Error> {
loop { loop {
match self.flush_tx() { match self.flush() {
Ok(_) => break, Ok(_) => break,
Err(nb::Error::WouldBlock) => { /* Wait */ } Err(nb::Error::WouldBlock) => { /* Wait */ }
Err(nb::Error::Other(e)) => return Err(e), Err(nb::Error::Other(e)) => return Err(e),

View File

@ -92,7 +92,7 @@ async fn main(spawner: Spawner) {
let mut uart0 = Uart::new(peripherals.UART0, config, rx_pin, tx_pin) let mut uart0 = Uart::new(peripherals.UART0, config, rx_pin, tx_pin)
.unwrap() .unwrap()
.into_async(); .into_async();
uart0.set_at_cmd(AtCmdConfig::new(None, None, None, AT_CMD, None)); uart0.set_at_cmd(AtCmdConfig::default().with_cmd_char(AT_CMD));
let (rx, tx) = uart0.split(); let (rx, tx) = uart0.split();

View File

@ -31,7 +31,7 @@ mod tests {
// set up TX and send a byte // set up TX and send a byte
let mut tx = UartTx::new(peripherals.UART0, uart::Config::default(), tx).unwrap(); let mut tx = UartTx::new(peripherals.UART0, uart::Config::default(), tx).unwrap();
tx.flush_tx().unwrap(); tx.flush().unwrap();
tx.write_bytes(&[0x42]).unwrap(); tx.write_bytes(&[0x42]).unwrap();
let read = block!(rx.read_byte()); let read = block!(rx.read_byte());

View File

@ -38,7 +38,7 @@ mod tests {
fn test_send_receive(mut ctx: Context) { fn test_send_receive(mut ctx: Context) {
let byte = [0x42]; let byte = [0x42];
ctx.tx.flush_tx().unwrap(); ctx.tx.flush().unwrap();
ctx.tx.write_bytes(&byte).unwrap(); ctx.tx.write_bytes(&byte).unwrap();
let read = block!(ctx.rx.read_byte()); let read = block!(ctx.rx.read_byte());
@ -50,7 +50,7 @@ mod tests {
let bytes = [0x42, 0x43, 0x44]; let bytes = [0x42, 0x43, 0x44];
let mut buf = [0u8; 3]; let mut buf = [0u8; 3];
ctx.tx.flush_tx().unwrap(); ctx.tx.flush().unwrap();
ctx.tx.write_bytes(&bytes).unwrap(); ctx.tx.write_bytes(&bytes).unwrap();
ctx.rx.read_bytes(&mut buf).unwrap(); ctx.rx.read_bytes(&mut buf).unwrap();