Stm32 usart: make pin modes of cts, tx, rts and de configurable

This commit is contained in:
Anton Pöhl 2025-03-13 10:52:41 +01:00
parent cae954a87e
commit e3cec4a246
2 changed files with 84 additions and 34 deletions

View File

@ -16,7 +16,7 @@ use super::{
sr, tdr, Config, ConfigError, CtsPin, Duplex, Error, HalfDuplexConfig, HalfDuplexReadback, Info, Instance, Regs, sr, tdr, Config, ConfigError, CtsPin, Duplex, Error, HalfDuplexConfig, HalfDuplexReadback, Info, Instance, Regs,
RtsPin, RxPin, TxPin, RtsPin, RxPin, TxPin,
}; };
use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; use crate::gpio::{AfType, AnyPin, Pull, SealedPin as _};
use crate::interrupt::{self, InterruptExt}; use crate::interrupt::{self, InterruptExt};
use crate::time::Hertz; use crate::time::Hertz;
@ -217,8 +217,8 @@ impl<'d> BufferedUart<'d> {
) -> Result<Self, ConfigError> { ) -> Result<Self, ConfigError> {
Self::new_inner( Self::new_inner(
peri, peri,
new_pin!(rx, AfType::input(config.rx_pull)), new_pin!(rx, config.rx_af()),
new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(tx, config.tx_af()),
None, None,
None, None,
None, None,
@ -242,10 +242,10 @@ impl<'d> BufferedUart<'d> {
) -> Result<Self, ConfigError> { ) -> Result<Self, ConfigError> {
Self::new_inner( Self::new_inner(
peri, peri,
new_pin!(rx, AfType::input(Pull::None)), new_pin!(rx, config.rx_af()),
new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(tx, config.tx_af()),
new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(rts, config.rts_config.af_type()),
new_pin!(cts, AfType::input(Pull::None)), new_pin!(cts, AfType::input(config.cts_pull)),
None, None,
tx_buffer, tx_buffer,
rx_buffer, rx_buffer,
@ -266,8 +266,8 @@ impl<'d> BufferedUart<'d> {
) -> Result<Self, ConfigError> { ) -> Result<Self, ConfigError> {
Self::new_inner( Self::new_inner(
peri, peri,
new_pin!(rx, AfType::input(Pull::None)), new_pin!(rx, config.rx_af()),
new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(tx, config.tx_af()),
None, None,
None, None,
new_pin!(rts, AfType::input(Pull::None)), // RTS mapped used as DE new_pin!(rts, AfType::input(Pull::None)), // RTS mapped used as DE
@ -290,8 +290,8 @@ impl<'d> BufferedUart<'d> {
) -> Result<Self, ConfigError> { ) -> Result<Self, ConfigError> {
Self::new_inner( Self::new_inner(
peri, peri,
new_pin!(rx, AfType::input(Pull::None)), new_pin!(rx, config.rx_af()),
new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(tx, config.tx_af()),
new_pin!(rts, AfType::input(Pull::None)), new_pin!(rts, AfType::input(Pull::None)),
None, // no CTS None, // no CTS
None, // no DE None, // no DE
@ -315,11 +315,11 @@ impl<'d> BufferedUart<'d> {
) -> Result<Self, ConfigError> { ) -> Result<Self, ConfigError> {
Self::new_inner( Self::new_inner(
peri, peri,
new_pin!(rx, AfType::input(config.rx_pull)), new_pin!(rx, config.rx_af()),
new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(tx, config.tx_af()),
None, None,
None, None,
new_pin!(de, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(de, config.de_config.af_type()),
tx_buffer, tx_buffer,
rx_buffer, rx_buffer,
config, config,

View File

@ -136,6 +136,40 @@ pub enum HalfDuplexReadback {
Readback, Readback,
} }
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
/// Half duplex IO mode
pub enum OutputConfig {
/// Push pull allows for faster baudrates, no internal pullup
PushPull,
#[cfg(not(gpio_v1))]
/// Push pull with internal pull up resistor
PushPullPullUp,
#[cfg(not(gpio_v1))]
/// Push pull with internal pull down resistor
PushPullPullDown,
/// Open drain output using external pull down resistor
OpenDrainExternal,
#[cfg(not(gpio_v1))]
/// Open drain output using internal pull up resistor
OpenDrainInternal,
}
impl OutputConfig {
const fn af_type(self) -> AfType {
match self {
OutputConfig::PushPull => AfType::output(OutputType::PushPull, Speed::Medium),
#[cfg(not(gpio_v1))]
OutputConfig::PushPullPullUp => AfType::output_pull(OutputType::OpenDrain, Speed::Medium, Pull::Up),
#[cfg(not(gpio_v1))]
OutputConfig::PushPullPullDown => AfType::output_pull(OutputType::OpenDrain, Speed::Medium, Pull::Down),
OutputConfig::OpenDrainExternal => AfType::output(OutputType::OpenDrain, Speed::Medium),
#[cfg(not(gpio_v1))]
OutputConfig::OpenDrainInternal => AfType::output_pull(OutputType::OpenDrain, Speed::Medium, Pull::Up),
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
/// Duplex mode /// Duplex mode
@ -208,6 +242,18 @@ pub struct Config {
/// Set the pull configuration for the RX pin. /// Set the pull configuration for the RX pin.
pub rx_pull: Pull, pub rx_pull: Pull,
/// Set the pull configuration for the CTS pin.
pub cts_pull: Pull,
/// Set the pin configuration for the TX pin.
pub tx_config: OutputConfig,
/// Set the pin configuration for the RTS pin.
pub rts_config: OutputConfig,
/// Set the pin configuration for the DE pin.
pub de_config: OutputConfig,
// private: set by new_half_duplex, not by the user. // private: set by new_half_duplex, not by the user.
duplex: Duplex, duplex: Duplex,
} }
@ -218,13 +264,13 @@ impl Config {
if self.swap_rx_tx { if self.swap_rx_tx {
return AfType::input(self.rx_pull); return AfType::input(self.rx_pull);
}; };
AfType::output(OutputType::PushPull, Speed::Medium) self.tx_config.af_type()
} }
fn rx_af(&self) -> AfType { fn rx_af(&self) -> AfType {
#[cfg(any(usart_v3, usart_v4))] #[cfg(any(usart_v3, usart_v4))]
if self.swap_rx_tx { if self.swap_rx_tx {
return AfType::output(OutputType::PushPull, Speed::Medium); return self.tx_config.af_type();
}; };
AfType::input(self.rx_pull) AfType::input(self.rx_pull)
} }
@ -248,6 +294,10 @@ impl Default for Config {
#[cfg(any(usart_v3, usart_v4))] #[cfg(any(usart_v3, usart_v4))]
invert_rx: false, invert_rx: false,
rx_pull: Pull::None, rx_pull: Pull::None,
cts_pull: Pull::None,
tx_config: OutputConfig::PushPull,
rts_config: OutputConfig::PushPull,
de_config: OutputConfig::PushPull,
duplex: Duplex::Full, duplex: Duplex::Full,
} }
} }
@ -426,7 +476,7 @@ impl<'d> UartTx<'d, Async> {
) -> Result<Self, ConfigError> { ) -> Result<Self, ConfigError> {
Self::new_inner( Self::new_inner(
peri, peri,
new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(tx, config.tx_af()),
None, None,
new_dma!(tx_dma), new_dma!(tx_dma),
config, config,
@ -443,8 +493,8 @@ impl<'d> UartTx<'d, Async> {
) -> Result<Self, ConfigError> { ) -> Result<Self, ConfigError> {
Self::new_inner( Self::new_inner(
peri, peri,
new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(tx, config.tx_af()),
new_pin!(cts, AfType::input(Pull::None)), new_pin!(cts, AfType::input(config.cts_pull)),
new_dma!(tx_dma), new_dma!(tx_dma),
config, config,
) )
@ -484,7 +534,7 @@ impl<'d> UartTx<'d, Blocking> {
) -> Result<Self, ConfigError> { ) -> Result<Self, ConfigError> {
Self::new_inner( Self::new_inner(
peri, peri,
new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(tx, config.tx_af()),
None, None,
None, None,
config, config,
@ -500,8 +550,8 @@ impl<'d> UartTx<'d, Blocking> {
) -> Result<Self, ConfigError> { ) -> Result<Self, ConfigError> {
Self::new_inner( Self::new_inner(
peri, peri,
new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(tx, config.tx_af()),
new_pin!(cts, AfType::input(config.rx_pull)), new_pin!(cts, AfType::input(config.cts_pull)),
None, None,
config, config,
) )
@ -658,7 +708,7 @@ impl<'d> UartRx<'d, Async> {
) -> Result<Self, ConfigError> { ) -> Result<Self, ConfigError> {
Self::new_inner( Self::new_inner(
peri, peri,
new_pin!(rx, AfType::input(config.rx_pull)), new_pin!(rx, config.rx_af()),
None, None,
new_dma!(rx_dma), new_dma!(rx_dma),
config, config,
@ -676,8 +726,8 @@ impl<'d> UartRx<'d, Async> {
) -> Result<Self, ConfigError> { ) -> Result<Self, ConfigError> {
Self::new_inner( Self::new_inner(
peri, peri,
new_pin!(rx, AfType::input(config.rx_pull)), new_pin!(rx, config.rx_af()),
new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(rts, config.rts_config.af_type()),
new_dma!(rx_dma), new_dma!(rx_dma),
config, config,
) )
@ -912,7 +962,7 @@ impl<'d> UartRx<'d, Blocking> {
rx: Peri<'d, impl RxPin<T>>, rx: Peri<'d, impl RxPin<T>>,
config: Config, config: Config,
) -> Result<Self, ConfigError> { ) -> Result<Self, ConfigError> {
Self::new_inner(peri, new_pin!(rx, AfType::input(config.rx_pull)), None, None, config) Self::new_inner(peri, new_pin!(rx, config.rx_af()), None, None, config)
} }
/// Create a new rx-only UART with a request-to-send pin /// Create a new rx-only UART with a request-to-send pin
@ -924,8 +974,8 @@ impl<'d> UartRx<'d, Blocking> {
) -> Result<Self, ConfigError> { ) -> Result<Self, ConfigError> {
Self::new_inner( Self::new_inner(
peri, peri,
new_pin!(rx, AfType::input(config.rx_pull)), new_pin!(rx, config.rx_af()),
new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(rts, config.rts_config.af_type()),
None, None,
config, config,
) )
@ -1141,8 +1191,8 @@ impl<'d> Uart<'d, Async> {
peri, peri,
new_pin!(rx, config.rx_af()), new_pin!(rx, config.rx_af()),
new_pin!(tx, config.tx_af()), new_pin!(tx, config.tx_af()),
new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(rts, config.rts_config.af_type()),
new_pin!(cts, AfType::input(Pull::None)), new_pin!(cts, AfType::input(config.cts_pull)),
None, None,
new_dma!(tx_dma), new_dma!(tx_dma),
new_dma!(rx_dma), new_dma!(rx_dma),
@ -1168,7 +1218,7 @@ impl<'d> Uart<'d, Async> {
new_pin!(tx, config.tx_af()), new_pin!(tx, config.tx_af()),
None, None,
None, None,
new_pin!(de, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(de, config.de_config.af_type()),
new_dma!(tx_dma), new_dma!(tx_dma),
new_dma!(rx_dma), new_dma!(rx_dma),
config, config,
@ -1308,8 +1358,8 @@ impl<'d> Uart<'d, Blocking> {
peri, peri,
new_pin!(rx, config.rx_af()), new_pin!(rx, config.rx_af()),
new_pin!(tx, config.tx_af()), new_pin!(tx, config.tx_af()),
new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(rts, config.rts_config.af_type()),
new_pin!(cts, AfType::input(Pull::None)), new_pin!(cts, AfType::input(config.cts_pull)),
None, None,
None, None,
None, None,
@ -1332,7 +1382,7 @@ impl<'d> Uart<'d, Blocking> {
new_pin!(tx, config.tx_af()), new_pin!(tx, config.tx_af()),
None, None,
None, None,
new_pin!(de, AfType::output(OutputType::PushPull, Speed::Medium)), new_pin!(de, config.de_config.af_type()),
None, None,
None, None,
config, config,