diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 2dbafc92337..225422b22df 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -54,6 +54,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Removed `AnyInputOnlyPin` in favour of `AnyPin`. (#2071) - Removed the following functions from `GpioPin`: `is_high`, `is_low`, `set_high`, `set_low`, `set_state`, `is_set_high`, `is_set_low`, `toggle`. (#2094) - Removed `Rtc::get_time_raw` (#1883) +- Removed `_with_default_pins` UART constructors (#2132) +- Removed `uart::{DefaultRxPin, DefaultTxPin}` (#2132) ## [0.20.1] - 2024-08-30 diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index a3e7d75de1b..c1b064ac944 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -133,7 +133,7 @@ use crate::{ clock::Clocks, gpio::{InputPin, InputSignal, OutputPin, OutputSignal}, interrupt::InterruptHandler, - peripheral::Peripheral, + peripheral::{Peripheral, PeripheralRef}, peripherals::{uart0::RegisterBlock, Interrupt}, private::Internal, system::PeripheralClockControl, @@ -150,67 +150,6 @@ use crate::soc::constants::RC_FAST_CLK; #[cfg(any(esp32, esp32s2))] use crate::soc::constants::REF_TICK; -// Default TX and RX pins for Uart/Serial communication (UART0) -cfg_if::cfg_if! { - if #[cfg(esp32)] { - /// Default TX pin for UART0 on ESP32. - /// Corresponds to GPIO1. - pub type DefaultTxPin = crate::gpio::GpioPin<1>; - - /// Default RX pin for UART0 on ESP32. - /// Corresponds to GPIO3. - pub type DefaultRxPin = crate::gpio::GpioPin<3>; - } else if #[cfg(esp32c2)] { - /// Default TX pin for UART0 on ESP32-C2. - /// Corresponds to GPIO20. - pub type DefaultTxPin = crate::gpio::GpioPin<20>; - - /// Default RX pin for UART0 on ESP32-C2. - /// Corresponds to GPIO19. - pub type DefaultRxPin = crate::gpio::GpioPin<19>; - } else if #[cfg(esp32c3)] { - /// Default TX pin for UART0 on ESP32-C3. - /// Corresponds to GPIO21. - pub type DefaultTxPin = crate::gpio::GpioPin<21>; - - /// Default RX pin for UART0 on ESP32-C3. - /// Corresponds to GPIO20. - pub type DefaultRxPin = crate::gpio::GpioPin<20>; - } else if #[cfg(esp32c6)] { - /// Default TX pin for UART0 on ESP32-C6. - /// Corresponds to GPIO16. - pub type DefaultTxPin = crate::gpio::GpioPin<16>; - - /// Default RX pin for UART0 on ESP32-C6. - /// Corresponds to GPIO17. - pub type DefaultRxPin = crate::gpio::GpioPin<17>; - } else if #[cfg(esp32h2)] { - /// Default TX pin for UART0 on ESP32-H2. - /// Corresponds to GPIO24. - pub type DefaultTxPin = crate::gpio::GpioPin<24>; - - /// Default RX pin for UART0 on ESP32-H2. - /// Corresponds to GPIO23. - pub type DefaultRxPin = crate::gpio::GpioPin<23>; - } else if #[cfg(esp32s2)] { - /// Default TX pin for UART0 on ESP32-S2. - /// Corresponds to GPIO43. - pub type DefaultTxPin = crate::gpio::GpioPin<43>; - - /// Default RX pin for UART0 on ESP32-S2. - /// Corresponds to GPIO44. - pub type DefaultRxPin = crate::gpio::GpioPin<44>; - } else if #[cfg(esp32s3)] { - /// Default TX pin for UART0 on ESP32-S3. - /// Corresponds to GPIO43. - pub type DefaultTxPin = crate::gpio::GpioPin<43>; - - /// Default RX pin for UART0 on ESP32-S3. - /// Corresponds to GPIO44. - pub type DefaultRxPin = crate::gpio::GpioPin<44>; - } -} - /// UART Error #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -494,6 +433,77 @@ pub mod config { } } +struct UartBuilder<'d, T, M> { + _uart: PeripheralRef<'d, T>, + phantom: PhantomData, +} + +impl<'d, T, M> UartBuilder<'d, T, M> +where + T: Instance, + M: Mode, +{ + fn new(uart: impl Peripheral

+ 'd) -> Self { + crate::into_ref!(uart); + Self { + _uart: uart, + phantom: PhantomData, + } + } + + fn with_rx(self, rx: impl Peripheral

+ 'd) -> Self { + crate::into_ref!(rx); + rx.init_input(false, false, Internal); + rx.connect_input_to_peripheral(T::rx_signal(), Internal); + + self + } + + fn with_tx(self, tx: impl Peripheral

+ 'd) -> Self { + crate::into_ref!(tx); + tx.set_to_push_pull_output(Internal); + tx.connect_peripheral_to_output(T::tx_signal(), Internal); + + self + } + + fn init(self, config: Config) -> Result, Error> { + let mut serial = Uart { + rx: UartRx::new_inner(&config), + tx: UartTx::new_inner(), + }; + serial.init(); + + serial + .rx + .set_rx_fifo_full_threshold(config.rx_fifo_full_threshold)?; + serial.rx.set_rx_timeout(config.rx_timeout)?; + serial.change_baud_internal(config.baudrate, config.clock_source); + serial.change_data_bits(config.data_bits); + serial.change_parity(config.parity); + serial.change_stop_bits(config.stop_bits); + + // Setting err_wr_mask stops uart from storing data when data is wrong according + // to reference manual + T::register_block() + .conf0() + .modify(|_, w| w.err_wr_mask().set_bit()); + + // Reset Tx/Rx FIFOs + serial.rxfifo_reset(); + serial.txfifo_reset(); + crate::rom::ets_delay_us(15); + + // Make sure we are starting in a "clean state" - previous operations might have + // run into error conditions + T::register_block() + .int_clr() + .write(|w| unsafe { w.bits(u32::MAX) }); + + Ok(serial) + } +} + /// UART (Full-duplex) pub struct Uart<'d, T, M> { rx: UartRx<'d, T, M>, @@ -585,11 +595,10 @@ where config: Config, tx: impl Peripheral

+ 'd, ) -> Result { - crate::into_ref!(tx); - tx.set_to_push_pull_output(Internal); - tx.connect_peripheral_to_output(T::tx_signal(), Internal); - - let (_, uart_tx) = Uart::<'d, T, Blocking>::new_with_config_inner(uart, config)?.split(); + let (_, uart_tx) = UartBuilder::<'d, T, Blocking>::new(uart) + .with_tx(tx) + .init(config)? + .split(); Ok(uart_tx) } @@ -600,13 +609,13 @@ where T: Instance, M: Mode, { - fn new_inner(#[cfg(not(esp32))] symbol_len: u8) -> Self { + fn new_inner(_config: &Config) -> Self { Self { phantom: PhantomData, at_cmd_config: None, rx_timeout_config: None, #[cfg(not(esp32))] - symbol_len, + symbol_len: _config.symbol_length(), } } @@ -726,22 +735,31 @@ where /// - `esp32c2`, `esp32c3`, `esp32c6`, `esp32h2`, esp32s2`, esp32s3`: The /// value you pass times the symbol size must be <= **0x3FF** fn set_rx_timeout(&mut self, timeout: Option) -> Result<(), Error> { - #[cfg(esp32)] - const MAX_THRHD: u8 = 0x7F; // 7 bits - #[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2, esp32s2, esp32s3))] - const MAX_THRHD: u16 = 0x3FF; // 10 bits + cfg_if::cfg_if! { + if #[cfg(esp32)] { + const MAX_THRHD: u8 = 0x7F; // 7 bits + } else { + const MAX_THRHD: u16 = 0x3FF; // 10 bits + } + } - #[cfg(esp32)] - let reg_thrhd = &T::register_block().conf1(); - #[cfg(any(esp32c6, esp32h2))] - let reg_thrhd = &T::register_block().tout_conf(); - #[cfg(any(esp32c2, esp32c3, esp32s2, esp32s3))] - let reg_thrhd = &T::register_block().mem_conf(); + cfg_if::cfg_if! { + if #[cfg(esp32)] { + let reg_thrhd = &T::register_block().conf1(); + } else if #[cfg(any(esp32c6, esp32h2))] { + let reg_thrhd = &T::register_block().tout_conf(); + } else { + let reg_thrhd = &T::register_block().mem_conf(); + } + } - #[cfg(any(esp32c6, esp32h2))] - let reg_en = &T::register_block().tout_conf(); - #[cfg(any(esp32, esp32c2, esp32c3, esp32s2, esp32s3))] - let reg_en = &T::register_block().conf1(); + cfg_if::cfg_if! { + if #[cfg(any(esp32c6, esp32h2))] { + let reg_en = &T::register_block().tout_conf(); + } else { + let reg_en = &T::register_block().conf1(); + } + } match timeout { None => { @@ -790,11 +808,7 @@ where config: Config, rx: impl Peripheral

+ 'd, ) -> Result { - crate::into_ref!(rx); - rx.init_input(false, false, Internal); - rx.connect_input_to_peripheral(T::rx_signal(), Internal); - - let (uart_rx, _) = Uart::<'d, T, Blocking>::new_with_config_inner(uart, config)?.split(); + let (uart_rx, _) = UartBuilder::new(uart).with_rx(rx).init(config)?.split(); Ok(uart_rx) } @@ -812,14 +826,12 @@ where rx: impl Peripheral

+ 'd, tx: impl Peripheral

+ 'd, ) -> Result { - crate::into_ref!(tx); - crate::into_ref!(rx); - tx.set_to_push_pull_output(Internal); - tx.connect_peripheral_to_output(T::tx_signal(), Internal); + let this = UartBuilder::new(uart) + .with_tx(tx) + .with_rx(rx) + .init(config)?; - rx.init_input(false, false, Internal); - rx.connect_input_to_peripheral(T::rx_signal(), Internal); - Self::new_with_config_inner(uart, config) + Ok(this) } /// Create a new UART instance with defaults in [`Blocking`] mode. @@ -828,29 +840,7 @@ where rx: impl Peripheral

+ 'd, tx: impl Peripheral

+ 'd, ) -> Result { - crate::into_ref!(tx); - crate::into_ref!(rx); - tx.set_to_push_pull_output(Internal); - tx.connect_peripheral_to_output(T::tx_signal(), Internal); - - rx.init_input(false, false, Internal); - rx.connect_input_to_peripheral(T::rx_signal(), Internal); - Self::new_inner(uart) - } - - /// Create a new UART instance with defaults in [`Blocking`] mode. - /// Verify that the default pins (DefaultTxPin and DefaultRxPin) are used. - pub fn new_with_default_pins( - uart: impl Peripheral

+ 'd, - rx: &mut DefaultRxPin, - tx: &mut DefaultTxPin, - ) -> Result { - tx.set_to_push_pull_output(Internal); - tx.connect_peripheral_to_output(T::tx_signal(), Internal); - - rx.init_input(false, false, Internal); - rx.connect_input_to_peripheral(T::rx_signal(), Internal); - Self::new_inner(uart) + Self::new_with_config(uart, Default::default(), rx, tx) } } @@ -859,49 +849,6 @@ where T: Instance + 'd, M: Mode, { - pub(crate) fn new_with_config_inner( - _uart: impl Peripheral

+ 'd, - config: Config, - ) -> Result { - Self::init(); - - let mut serial = Uart { - rx: UartRx::new_inner( - #[cfg(not(esp32))] - config.symbol_length(), - ), - tx: UartTx::new_inner(), - }; - - serial - .rx - .set_rx_fifo_full_threshold(config.rx_fifo_full_threshold)?; - serial.rx.set_rx_timeout(config.rx_timeout)?; - serial.change_baud_internal(config.baudrate, config.clock_source); - serial.change_data_bits(config.data_bits); - serial.change_parity(config.parity); - serial.change_stop_bits(config.stop_bits); - - // Setting err_wr_mask stops uart from storing data when data is wrong according - // to reference manual - T::register_block() - .conf0() - .modify(|_, w| w.err_wr_mask().set_bit()); - - // Reset Tx/Rx FIFOs - serial.rxfifo_reset(); - serial.txfifo_reset(); - crate::rom::ets_delay_us(15); - - // Make sure we are starting in a "clean state" - previous operations might have - // run into error conditions - T::register_block() - .int_clr() - .write(|w| unsafe { w.bits(u32::MAX) }); - - Ok(serial) - } - fn inner_set_interrupt_handler(&mut self, handler: InterruptHandler) { unsafe { crate::interrupt::bind_interrupt(T::interrupt(), handler.handler()); @@ -909,10 +856,6 @@ where } } - fn new_inner(uart: impl Peripheral

+ 'd) -> Result { - Self::new_with_config_inner(uart, Default::default()) - } - /// Configure CTS pin pub fn with_cts(self, cts: impl Peripheral

+ 'd) -> Self { crate::into_ref!(cts); @@ -1273,23 +1216,6 @@ where .write(|w| unsafe { w.clkdiv().bits(divider).frag().bits(0) }); } - #[cfg(any(esp32c2, esp32c3, esp32s3))] - #[inline(always)] - fn init() { - let system = unsafe { crate::peripherals::SYSTEM::steal() }; - if !system.perip_clk_en0().read().uart_mem_clk_en().bit() { - system - .perip_clk_en0() - .modify(|_, w| w.uart_mem_clk_en().set_bit()); - } - - // initialize peripheral by setting clk_enable and clearing uart_reset bits - T::enable_peripheral(); - Self::uart_peripheral_reset(); - T::disable_rx_interrupts(); - T::disable_tx_interrupts(); - } - /// Modify UART baud rate and reset TX/RX fifo. pub fn change_baud(&mut self, baudrate: u32, clock_source: ClockSource) { self.change_baud_internal(baudrate, clock_source); @@ -1297,23 +1223,25 @@ where self.rxfifo_reset(); } - #[cfg(any(esp32c6, esp32h2))] #[inline(always)] - fn init() { - T::register_block() - .conf0() - .modify(|_, w| w.mem_clk_en().set_bit()); - - // initialize peripheral by setting clk_enable and clearing uart_reset bits - T::enable_peripheral(); - Self::uart_peripheral_reset(); - T::disable_rx_interrupts(); - T::disable_tx_interrupts(); - } + fn init(&self) { + cfg_if::cfg_if! { + if #[cfg(any(esp32, esp32s2))] { + // Nothing to do + } else if #[cfg(any(esp32c2, esp32c3, esp32s3))] { + let system = unsafe { crate::peripherals::SYSTEM::steal() }; + if !system.perip_clk_en0().read().uart_mem_clk_en().bit() { + system + .perip_clk_en0() + .modify(|_, w| w.uart_mem_clk_en().set_bit()); + } + } else { + T::register_block() + .conf0() + .modify(|_, w| w.mem_clk_en().set_bit()); + } + }; - #[cfg(any(esp32, esp32s2))] - #[inline(always)] - fn init() { T::enable_peripheral(); Self::uart_peripheral_reset(); T::disable_rx_interrupts(); @@ -2136,14 +2064,10 @@ mod asynch { rx: impl Peripheral

+ 'd, tx: impl Peripheral

+ 'd, ) -> Result { - crate::into_ref!(rx); - crate::into_ref!(tx); - tx.set_to_push_pull_output(Internal); - tx.connect_peripheral_to_output(T::tx_signal(), Internal); - - rx.init_input(false, false, Internal); - rx.connect_input_to_peripheral(T::rx_signal(), Internal); - let mut this = Self::new_with_config_inner(uart, config)?; + let mut this = UartBuilder::new(uart) + .with_tx(tx) + .with_rx(rx) + .init(config)?; this.inner_set_interrupt_handler(match T::uart_number() { #[cfg(uart0)] @@ -2166,15 +2090,6 @@ mod asynch { ) -> Result { Self::new_async_with_config(uart, Default::default(), rx, tx) } - - /// Create a new UART instance with defaults in [`Async`] mode. - pub fn new_async_with_default_pins( - uart: impl Peripheral

+ 'd, - rx: DefaultRxPin, - tx: DefaultTxPin, - ) -> Result { - Self::new_async_with_config(uart, Default::default(), rx, tx) - } } impl Uart<'_, T, Async> @@ -2217,11 +2132,7 @@ mod asynch { config: Config, tx: impl Peripheral

+ 'd, ) -> Result { - crate::into_ref!(tx); - tx.set_to_push_pull_output(Internal); - tx.connect_peripheral_to_output(T::tx_signal(), Internal); - - let mut uart = Uart::<'d, T, Async>::new_with_config_inner(uart, config)?; + let mut uart = UartBuilder::new(uart).with_tx(tx).init(config)?; uart.inner_set_interrupt_handler(match T::uart_number() { #[cfg(uart0)] @@ -2302,11 +2213,7 @@ mod asynch { config: Config, rx: impl Peripheral

+ 'd, ) -> Result { - crate::into_ref!(rx); - rx.init_input(false, false, Internal); - rx.connect_input_to_peripheral(T::rx_signal(), Internal); - - let mut uart = Uart::<'d, T, Async>::new_with_config_inner(uart, config)?; + let mut uart = UartBuilder::new(uart).with_rx(rx).init(config)?; uart.inner_set_interrupt_handler(match T::uart_number() { #[cfg(uart0)] diff --git a/examples/src/bin/hello_world.rs b/examples/src/bin/hello_world.rs index 44d18dc9a7e..b4e280c1f0a 100644 --- a/examples/src/bin/hello_world.rs +++ b/examples/src/bin/hello_world.rs @@ -42,8 +42,7 @@ fn main() -> ! { } } - let mut uart0 = - Uart::new_with_default_pins(peripherals.UART0, &mut rx_pin, &mut tx_pin).unwrap(); + let mut uart0 = Uart::new(peripherals.UART0, &mut rx_pin, &mut tx_pin).unwrap(); loop { writeln!(uart0, "Hello world!").unwrap(); diff --git a/examples/src/bin/ieee802154_sniffer.rs b/examples/src/bin/ieee802154_sniffer.rs index 8544f9c61bc..6f36699e0ac 100644 --- a/examples/src/bin/ieee802154_sniffer.rs +++ b/examples/src/bin/ieee802154_sniffer.rs @@ -27,8 +27,7 @@ fn main() -> ! { } } - let mut uart0 = - Uart::new_with_default_pins(peripherals.UART0, &mut rx_pin, &mut tx_pin).unwrap(); + let mut uart0 = Uart::new(peripherals.UART0, &mut rx_pin, &mut tx_pin).unwrap(); // read two characters which get parsed as the channel let mut cnt = 0; diff --git a/hil-test/tests/uart_async.rs b/hil-test/tests/uart_async.rs index a98efad19d2..b4309fff1b0 100644 --- a/hil-test/tests/uart_async.rs +++ b/hil-test/tests/uart_async.rs @@ -7,7 +7,7 @@ //! Connect TX and RX pins. //% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 -//% FEATURES: generic-queue +//% FEATURES: generic-queue, defmt #![no_std] #![no_main]