Add half duplex support

This commit is contained in:
Max Känner 2023-12-22 17:03:35 +01:00
parent 4695e46a59
commit a2ebede411

View File

@ -161,6 +161,10 @@ pub struct Config {
/// Set this to true to invert RX pin signal values (V<sub>DD</sub> =0/mark, Gnd = 1/idle). /// Set this to true to invert RX pin signal values (V<sub>DD</sub> =0/mark, Gnd = 1/idle).
#[cfg(any(usart_v3, usart_v4))] #[cfg(any(usart_v3, usart_v4))]
pub invert_rx: bool, 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 { impl Default for Config {
@ -180,6 +184,7 @@ impl Default for Config {
invert_tx: false, invert_tx: false,
#[cfg(any(usart_v3, usart_v4))] #[cfg(any(usart_v3, usart_v4))]
invert_rx: false, invert_rx: false,
half_duplex: false,
} }
} }
} }
@ -811,6 +816,13 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
let r = T::regs(); let r = T::regs();
// Some chips do not have swap_rx_tx bit // Some chips do not have swap_rx_tx bit
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! { cfg_if::cfg_if! {
if #[cfg(any(usart_v3, usart_v4))] { if #[cfg(any(usart_v3, usart_v4))] {
if config.swap_rx_tx { if config.swap_rx_tx {
@ -826,6 +838,7 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
tx.set_as_af(tx.af_num(), AFType::OutputPushPull); tx.set_as_af(tx.af_num(), AFType::OutputPushPull);
} }
} }
}
configure(r, &config, T::frequency(), T::KIND, true, true)?; configure(r, &config, T::frequency(), T::KIND, true, true)?;
@ -1039,6 +1052,7 @@ fn configure(
#[cfg(not(usart_v1))] #[cfg(not(usart_v1))]
r.cr3().modify(|w| { r.cr3().modify(|w| {
w.set_onebit(config.assume_noise_free); w.set_onebit(config.assume_noise_free);
w.set_hdsel(config.half_duplex);
}); });
r.cr1().write(|w| { r.cr1().write(|w| {