Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UART: Move RX/TX pin assignment from constructor to builder functions #2904

Merged
merged 7 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions esp-hal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `adc::{AdcCalSource, Attenuation, Resolution}` now implement `Hash` and `defmt::Format` (#2840)
- `rtc_cntl::{RtcFastClock, RtcSlowClock, RtcCalSel}` now implement `PartialEq`, `Eq`, `Hash` and `defmt::Format` (#2840)
- Added `tsens::TemperatureSensor` peripheral for ESP32C6 and ESP32C3 (#2875)
- Added `with_rx()` and `with_tx()` methods to Uart, UartRx, and UartTx ()

### Changed

Expand Down
17 changes: 17 additions & 0 deletions esp-hal/MIGRATING-0.22.md
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,23 @@ e.g.
+ GlitchOccurred
```

RX/TX pin assignment moved from constructors to builder functions.

e.g.

```diff
let mut uart1 = Uart::new(
peripherals.UART1,
- Config::default(),
- peripherals.GPIO1,
- peripherals.GPIO2,
- ).unwrap();
+ Config::default())
+ .unwrap()
+ .with_rx(peripherals.GPIO1)
+ .with_tx(peripherals.GPIO2);
```

## Spi `with_miso` has been split

Previously, `with_miso` set up the provided pin as an input and output, which was necessary for half duplex.
Expand Down
135 changes: 79 additions & 56 deletions esp-hal/src/uart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
//!
//! let mut uart1 = Uart::new(
//! peripherals.UART1,
//! Config::default(),
//! peripherals.GPIO1,
//! peripherals.GPIO2,
//! ).unwrap();
//! Config::default())
//! .unwrap()
//! .with_rx(peripherals.GPIO1)
//! .with_tx(peripherals.GPIO2);
//! # }
//! ```
//!
Expand Down Expand Up @@ -57,9 +57,9 @@
//! # let mut uart1 = Uart::new(
//! # peripherals.UART1,
//! # Config::default(),
//! # peripherals.GPIO1,
//! # peripherals.GPIO2,
//! # ).unwrap();
//! # ).unwrap()
//! # .with_rx(peripherals.GPIO1)
//! # .with_tx(peripherals.GPIO2);
//! // Write bytes out over the UART:
//! uart1.write_bytes(b"Hello, world!").expect("write error!");
//! # }
Expand All @@ -72,9 +72,9 @@
//! # let mut uart1 = Uart::new(
//! # peripherals.UART1,
//! # Config::default(),
//! # peripherals.GPIO1,
//! # peripherals.GPIO2,
//! # ).unwrap();
//! # ).unwrap()
//! # .with_rx(peripherals.GPIO1)
//! # .with_tx(peripherals.GPIO2);
//! // The UART can be split into separate Transmit and Receive components:
//! let (mut rx, mut tx) = uart1.split();
//!
Expand All @@ -93,10 +93,10 @@
//! let (_, tx) = peripherals.GPIO1.split();
//! let mut uart1 = Uart::new(
//! peripherals.UART1,
//! Config::default(),
//! rx.inverted(),
//! tx.inverted(),
//! ).unwrap();
//! Config::default())
//! .unwrap()
//! .with_rx(rx.inverted())
//! .with_tx(tx.inverted());
//! # }
//! ```
//!
Expand All @@ -107,14 +107,14 @@
//!
//! let tx = UartTx::new(
//! peripherals.UART0,
//! Config::default(),
//! peripherals.GPIO1,
//! ).unwrap();
//! Config::default())
//! .unwrap()
//! .with_tx(peripherals.GPIO1);
//! let rx = UartRx::new(
//! peripherals.UART1,
//! Config::default(),
//! peripherals.GPIO2,
//! ).unwrap();
//! Config::default())
//! .unwrap()
//! .with_rx(peripherals.GPIO2);
//! # }
//! ```
//!
Expand Down Expand Up @@ -156,10 +156,10 @@
//!
//! let mut uart0 = Uart::new(
//! peripherals.UART0,
//! config,
//! tx_pin,
//! rx_pin
//! ).unwrap();
//! config)
//! .unwrap()
//! .with_rx(rx_pin)
//! .with_tx(tx_pin);
//!
//! uart0.set_interrupt_handler(interrupt_handler);
//!
Expand Down Expand Up @@ -499,24 +499,6 @@ where
}
}

fn with_rx(self, rx: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
crate::into_mapped_ref!(rx);
rx.init_input(Pull::Up, Internal);
self.uart.info().rx_signal.connect_to(rx);

self
}

fn with_tx(self, tx: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
crate::into_mapped_ref!(tx);
// Make sure we don't cause an unexpected low pulse on the pin.
tx.set_output_high(true, Internal);
tx.set_to_push_pull_output(Internal);
self.uart.info().tx_signal.connect_to(tx);

self
}

fn init(self, config: Config) -> Result<Uart<'d, Dm, T>, ConfigError> {
let rx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral);
let tx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral);
Expand Down Expand Up @@ -642,6 +624,20 @@ where
self
}

/// Assign the TX pin for UART instance.
///
/// Sets the specified pin to push-pull output and connects it to the UART
/// TX signal.
pub fn with_tx(self, tx: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
crate::into_mapped_ref!(tx);
// Make sure we don't cause an unexpected low pulse on the pin.
tx.set_output_high(true, Internal);
tx.set_to_push_pull_output(Internal);
self.uart.info().tx_signal.connect_to(tx);

self
}

/// Change the configuration.
///
/// Note that this also changes the configuration of the RX half.
Expand Down Expand Up @@ -736,9 +732,8 @@ impl<'d> UartTx<'d, Blocking> {
pub fn new(
uart: impl Peripheral<P = impl Instance> + 'd,
config: Config,
tx: impl Peripheral<P = impl PeripheralOutput> + 'd,
) -> Result<Self, ConfigError> {
Self::new_typed(uart.map_into(), config, tx)
Self::new_typed(uart.map_into(), config)
}
}

Expand All @@ -750,10 +745,8 @@ where
pub fn new_typed(
uart: impl Peripheral<P = T> + 'd,
config: Config,
tx: impl Peripheral<P = impl PeripheralOutput> + 'd,
) -> Result<Self, ConfigError> {
let (_, uart_tx) = UartBuilder::<'d, Blocking, T>::new(uart)
.with_tx(tx)
.init(config)?
.split();

Expand Down Expand Up @@ -833,6 +826,17 @@ where
self
}

/// Assign the RX pin for UART instance.
///
/// Sets the specified pin to input and connects it to the UART RX signal.
pub fn with_rx(self, rx: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
crate::into_mapped_ref!(rx);
rx.init_input(Pull::Up, Internal);
self.uart.info().rx_signal.connect_to(rx);

self
}

/// Change the configuration.
///
/// Note that this also changes the configuration of the TX half.
Expand Down Expand Up @@ -950,9 +954,8 @@ impl<'d> UartRx<'d, Blocking> {
pub fn new(
uart: impl Peripheral<P = impl Instance> + 'd,
config: Config,
rx: impl Peripheral<P = impl PeripheralInput> + 'd,
) -> Result<Self, ConfigError> {
UartRx::new_typed(uart.map_into(), config, rx)
UartRx::new_typed(uart.map_into(), config)
}
}

Expand All @@ -964,9 +967,8 @@ where
pub fn new_typed(
uart: impl Peripheral<P = T> + 'd,
config: Config,
rx: impl Peripheral<P = impl PeripheralInput> + 'd,
) -> Result<Self, ConfigError> {
let (uart_rx, _) = UartBuilder::new(uart).with_rx(rx).init(config)?.split();
let (uart_rx, _) = UartBuilder::new(uart).init(config)?.split();

Ok(uart_rx)
}
Expand Down Expand Up @@ -1015,10 +1017,8 @@ impl<'d> Uart<'d, Blocking> {
pub fn new(
uart: impl Peripheral<P = impl Instance> + 'd,
config: Config,
rx: impl Peripheral<P = impl PeripheralInput> + 'd,
tx: impl Peripheral<P = impl PeripheralOutput> + 'd,
) -> Result<Self, ConfigError> {
Self::new_typed(uart.map_into(), config, rx, tx)
Self::new_typed(uart.map_into(), config)
}
}

Expand All @@ -1030,10 +1030,8 @@ where
pub fn new_typed(
uart: impl Peripheral<P = T> + 'd,
config: Config,
rx: impl Peripheral<P = impl PeripheralInput> + 'd,
tx: impl Peripheral<P = impl PeripheralOutput> + 'd,
) -> Result<Self, ConfigError> {
UartBuilder::new(uart).with_tx(tx).with_rx(rx).init(config)
JurajSadel marked this conversation as resolved.
Show resolved Hide resolved
UartBuilder::new(uart).init(config)
}

/// Reconfigures the driver to operate in [`Async`] mode.
Expand All @@ -1043,6 +1041,31 @@ where
tx: self.tx.into_async(),
}
}

/// Assign the RX pin for UART instance.
///
/// Sets the specified pin to input and connects it to the UART RX signal.
pub fn with_rx(self, rx: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
crate::into_mapped_ref!(rx);
rx.init_input(Pull::Up, Internal);
self.rx.uart.info().rx_signal.connect_to(rx);

self
}

/// Assign the TX pin for UART instance.
///
/// Sets the specified pin to push-pull output and connects it to the UART
/// TX signal.
pub fn with_tx(self, tx: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
crate::into_mapped_ref!(tx);
// Make sure we don't cause an unexpected low pulse on the pin.
tx.set_output_high(true, Internal);
tx.set_to_push_pull_output(Internal);
self.tx.uart.info().tx_signal.connect_to(tx);

self
}
}

impl<'d, T> Uart<'d, Async, T>
Expand Down
4 changes: 3 additions & 1 deletion examples/src/bin/embassy_serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,10 @@ async fn main(spawner: Spawner) {

let config = Config::default().with_rx_fifo_full_threshold(READ_BUF_SIZE as u16);

let mut uart0 = Uart::new(peripherals.UART0, config, rx_pin, tx_pin)
let mut uart0 = Uart::new(peripherals.UART0, config)
.unwrap()
.with_tx(tx_pin)
.with_rx(rx_pin)
.into_async();
uart0.set_at_cmd(AtCmdConfig::default().with_cmd_char(AT_CMD));

Expand Down
15 changes: 6 additions & 9 deletions examples/src/bin/ieee802154_sniffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,16 @@ fn main() -> ! {
// Default pins for Uart/Serial communication
cfg_if::cfg_if! {
if #[cfg(feature = "esp32c6")] {
let (mut tx_pin, mut rx_pin) = (peripherals.GPIO16, peripherals.GPIO17);
let (tx_pin, rx_pin) = (peripherals.GPIO16, peripherals.GPIO17);
} else if #[cfg(feature = "esp32h2")] {
let (mut tx_pin, mut rx_pin) = (peripherals.GPIO24, peripherals.GPIO23);
let (tx_pin, rx_pin) = (peripherals.GPIO24, peripherals.GPIO23);
}
}

let mut uart0 = Uart::new(
peripherals.UART0,
uart::Config::default(),
&mut rx_pin,
&mut tx_pin,
)
.unwrap();
let mut uart0 = Uart::new(peripherals.UART0, uart::Config::default())
.unwrap()
.with_tx(tx_pin)
.with_rx(rx_pin);

// read two characters which get parsed as the channel
let mut cnt = 0;
Expand Down
5 changes: 4 additions & 1 deletion hil-test/tests/uart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ mod tests {

let (rx, tx) = pin.split();

let uart = Uart::new(peripherals.UART1, uart::Config::default(), rx, tx).unwrap();
let uart = Uart::new(peripherals.UART1, uart::Config::default())
.unwrap()
.with_tx(tx)
.with_rx(rx);

Context { uart }
}
Expand Down
4 changes: 3 additions & 1 deletion hil-test/tests/uart_async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ mod tests {

let (rx, tx) = hil_test::common_test_pins!(peripherals);

let uart = Uart::new(peripherals.UART0, uart::Config::default(), rx, tx)
let uart = Uart::new(peripherals.UART0, uart::Config::default())
.unwrap()
.with_tx(tx)
.with_rx(rx)
.into_async();

Context { uart }
Expand Down
8 changes: 6 additions & 2 deletions hil-test/tests/uart_regression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,19 @@ mod tests {

let (rx, mut tx) = hil_test::common_test_pins!(peripherals);

let mut rx = UartRx::new(peripherals.UART1, uart::Config::default(), rx).unwrap();
let mut rx = UartRx::new(peripherals.UART1, uart::Config::default())
.unwrap()
.with_rx(rx);

// start reception
_ = rx.read_byte(); // this will just return WouldBlock

unsafe { tx.set_output_high(false, esp_hal::Internal::conjure()) };

// 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())
.unwrap()
.with_tx(tx);

tx.flush().unwrap();
tx.write_bytes(&[0x42]).unwrap();
Expand Down
8 changes: 6 additions & 2 deletions hil-test/tests/uart_tx_rx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ mod tests {

let (rx, tx) = hil_test::common_test_pins!(peripherals);

let tx = UartTx::new(peripherals.UART0, uart::Config::default(), tx).unwrap();
let rx = UartRx::new(peripherals.UART1, uart::Config::default(), rx).unwrap();
let tx = UartTx::new(peripherals.UART0, uart::Config::default())
.unwrap()
.with_tx(tx);
let rx = UartRx::new(peripherals.UART1, uart::Config::default())
.unwrap()
.with_rx(rx);

Context { rx, tx }
}
Expand Down
Loading
Loading