diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 8a0c85d2..9e1128e3 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -161,6 +161,10 @@ pub struct Config { /// Set this to true to invert RX pin signal values (VDD =0/mark, Gnd = 1/idle). #[cfg(any(usart_v3, usart_v4))] pub invert_rx: bool, + + /// enable single wire half duplex communication. Only the tx pin is used. Needs an external + /// pull up + pub half_duplex: bool, } impl Default for Config { @@ -180,6 +184,7 @@ impl Default for Config { invert_tx: false, #[cfg(any(usart_v3, usart_v4))] invert_rx: false, + half_duplex: false, } } } @@ -811,19 +816,27 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { let r = T::regs(); // Some chips do not have swap_rx_tx bit - cfg_if::cfg_if! { - if #[cfg(any(usart_v3, usart_v4))] { - if config.swap_rx_tx { - let (rx, tx) = (tx, rx); - rx.set_as_af(rx.af_num(), AFType::Input); - tx.set_as_af(tx.af_num(), AFType::OutputPushPull); + if config.half_duplex { + if config.swap_rx_tx { + rx.set_as_af(rx.af_num(), AFType::OutputOpenDrain); + } else { + tx.set_as_af(tx.af_num(), AFType::OutputOpenDrain); + } + } else { + cfg_if::cfg_if! { + if #[cfg(any(usart_v3, usart_v4))] { + if config.swap_rx_tx { + let (rx, tx) = (tx, rx); + rx.set_as_af(rx.af_num(), AFType::Input); + tx.set_as_af(tx.af_num(), AFType::OutputPushPull); + } else { + rx.set_as_af(rx.af_num(), AFType::Input); + tx.set_as_af(tx.af_num(), AFType::OutputPushPull); + } } else { rx.set_as_af(rx.af_num(), AFType::Input); tx.set_as_af(tx.af_num(), AFType::OutputPushPull); } - } else { - rx.set_as_af(rx.af_num(), AFType::Input); - tx.set_as_af(tx.af_num(), AFType::OutputPushPull); } } @@ -1039,6 +1052,7 @@ fn configure( #[cfg(not(usart_v1))] r.cr3().modify(|w| { w.set_onebit(config.assume_noise_free); + w.set_hdsel(config.half_duplex); }); r.cr1().write(|w| {