aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Pöhl <[email protected]>2025-03-13 10:52:41 +0100
committerAnton Pöhl <[email protected]>2025-04-11 20:58:03 +0200
commite3cec4a246a0e3cbaae60c91f946f608f6637f63 (patch)
tree6d156a712cd7fb800dfa055d043d65d7defd1c63
parentcae954a87ec3c5ece520b6a44168b36e79f3f86a (diff)
Stm32 usart: make pin modes of cts, tx, rts and de configurable
-rw-r--r--embassy-stm32/src/usart/buffered.rs28
-rw-r--r--embassy-stm32/src/usart/mod.rs90
2 files changed, 84 insertions, 34 deletions
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs
index b1640b6dc..2dfb99dbc 100644
--- a/embassy-stm32/src/usart/buffered.rs
+++ b/embassy-stm32/src/usart/buffered.rs
@@ -16,7 +16,7 @@ use super::{
16 sr, tdr, Config, ConfigError, CtsPin, Duplex, Error, HalfDuplexConfig, HalfDuplexReadback, Info, Instance, Regs, 16 sr, tdr, Config, ConfigError, CtsPin, Duplex, Error, HalfDuplexConfig, HalfDuplexReadback, Info, Instance, Regs,
17 RtsPin, RxPin, TxPin, 17 RtsPin, RxPin, TxPin,
18}; 18};
19use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; 19use crate::gpio::{AfType, AnyPin, Pull, SealedPin as _};
20use crate::interrupt::{self, InterruptExt}; 20use crate::interrupt::{self, InterruptExt};
21use crate::time::Hertz; 21use crate::time::Hertz;
22 22
@@ -217,8 +217,8 @@ impl<'d> BufferedUart<'d> {
217 ) -> Result<Self, ConfigError> { 217 ) -> Result<Self, ConfigError> {
218 Self::new_inner( 218 Self::new_inner(
219 peri, 219 peri,
220 new_pin!(rx, AfType::input(config.rx_pull)), 220 new_pin!(rx, config.rx_af()),
221 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), 221 new_pin!(tx, config.tx_af()),
222 None, 222 None,
223 None, 223 None,
224 None, 224 None,
@@ -242,10 +242,10 @@ impl<'d> BufferedUart<'d> {
242 ) -> Result<Self, ConfigError> { 242 ) -> Result<Self, ConfigError> {
243 Self::new_inner( 243 Self::new_inner(
244 peri, 244 peri,
245 new_pin!(rx, AfType::input(Pull::None)), 245 new_pin!(rx, config.rx_af()),
246 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), 246 new_pin!(tx, config.tx_af()),
247 new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)), 247 new_pin!(rts, config.rts_config.af_type()),
248 new_pin!(cts, AfType::input(Pull::None)), 248 new_pin!(cts, AfType::input(config.cts_pull)),
249 None, 249 None,
250 tx_buffer, 250 tx_buffer,
251 rx_buffer, 251 rx_buffer,
@@ -266,8 +266,8 @@ impl<'d> BufferedUart<'d> {
266 ) -> Result<Self, ConfigError> { 266 ) -> Result<Self, ConfigError> {
267 Self::new_inner( 267 Self::new_inner(
268 peri, 268 peri,
269 new_pin!(rx, AfType::input(Pull::None)), 269 new_pin!(rx, config.rx_af()),
270 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), 270 new_pin!(tx, config.tx_af()),
271 None, 271 None,
272 None, 272 None,
273 new_pin!(rts, AfType::input(Pull::None)), // RTS mapped used as DE 273 new_pin!(rts, AfType::input(Pull::None)), // RTS mapped used as DE
@@ -290,8 +290,8 @@ impl<'d> BufferedUart<'d> {
290 ) -> Result<Self, ConfigError> { 290 ) -> Result<Self, ConfigError> {
291 Self::new_inner( 291 Self::new_inner(
292 peri, 292 peri,
293 new_pin!(rx, AfType::input(Pull::None)), 293 new_pin!(rx, config.rx_af()),
294 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), 294 new_pin!(tx, config.tx_af()),
295 new_pin!(rts, AfType::input(Pull::None)), 295 new_pin!(rts, AfType::input(Pull::None)),
296 None, // no CTS 296 None, // no CTS
297 None, // no DE 297 None, // no DE
@@ -315,11 +315,11 @@ impl<'d> BufferedUart<'d> {
315 ) -> Result<Self, ConfigError> { 315 ) -> Result<Self, ConfigError> {
316 Self::new_inner( 316 Self::new_inner(
317 peri, 317 peri,
318 new_pin!(rx, AfType::input(config.rx_pull)), 318 new_pin!(rx, config.rx_af()),
319 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), 319 new_pin!(tx, config.tx_af()),
320 None, 320 None,
321 None, 321 None,
322 new_pin!(de, AfType::output(OutputType::PushPull, Speed::Medium)), 322 new_pin!(de, config.de_config.af_type()),
323 tx_buffer, 323 tx_buffer,
324 rx_buffer, 324 rx_buffer,
325 config, 325 config,
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index 675e90c7f..80a391d41 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -138,6 +138,40 @@ pub enum HalfDuplexReadback {
138 138
139#[derive(Clone, Copy, PartialEq, Eq, Debug)] 139#[derive(Clone, Copy, PartialEq, Eq, Debug)]
140#[cfg_attr(feature = "defmt", derive(defmt::Format))] 140#[cfg_attr(feature = "defmt", derive(defmt::Format))]
141/// Half duplex IO mode
142pub enum OutputConfig {
143 /// Push pull allows for faster baudrates, no internal pullup
144 PushPull,
145 #[cfg(not(gpio_v1))]
146 /// Push pull with internal pull up resistor
147 PushPullPullUp,
148 #[cfg(not(gpio_v1))]
149 /// Push pull with internal pull down resistor
150 PushPullPullDown,
151 /// Open drain output using external pull down resistor
152 OpenDrainExternal,
153 #[cfg(not(gpio_v1))]
154 /// Open drain output using internal pull up resistor
155 OpenDrainInternal,
156}
157
158impl OutputConfig {
159 const fn af_type(self) -> AfType {
160 match self {
161 OutputConfig::PushPull => AfType::output(OutputType::PushPull, Speed::Medium),
162 #[cfg(not(gpio_v1))]
163 OutputConfig::PushPullPullUp => AfType::output_pull(OutputType::OpenDrain, Speed::Medium, Pull::Up),
164 #[cfg(not(gpio_v1))]
165 OutputConfig::PushPullPullDown => AfType::output_pull(OutputType::OpenDrain, Speed::Medium, Pull::Down),
166 OutputConfig::OpenDrainExternal => AfType::output(OutputType::OpenDrain, Speed::Medium),
167 #[cfg(not(gpio_v1))]
168 OutputConfig::OpenDrainInternal => AfType::output_pull(OutputType::OpenDrain, Speed::Medium, Pull::Up),
169 }
170 }
171}
172
173#[derive(Clone, Copy, PartialEq, Eq, Debug)]
174#[cfg_attr(feature = "defmt", derive(defmt::Format))]
141/// Duplex mode 175/// Duplex mode
142pub enum Duplex { 176pub enum Duplex {
143 /// Full duplex 177 /// Full duplex
@@ -208,6 +242,18 @@ pub struct Config {
208 /// Set the pull configuration for the RX pin. 242 /// Set the pull configuration for the RX pin.
209 pub rx_pull: Pull, 243 pub rx_pull: Pull,
210 244
245 /// Set the pull configuration for the CTS pin.
246 pub cts_pull: Pull,
247
248 /// Set the pin configuration for the TX pin.
249 pub tx_config: OutputConfig,
250
251 /// Set the pin configuration for the RTS pin.
252 pub rts_config: OutputConfig,
253
254 /// Set the pin configuration for the DE pin.
255 pub de_config: OutputConfig,
256
211 // private: set by new_half_duplex, not by the user. 257 // private: set by new_half_duplex, not by the user.
212 duplex: Duplex, 258 duplex: Duplex,
213} 259}
@@ -218,13 +264,13 @@ impl Config {
218 if self.swap_rx_tx { 264 if self.swap_rx_tx {
219 return AfType::input(self.rx_pull); 265 return AfType::input(self.rx_pull);
220 }; 266 };
221 AfType::output(OutputType::PushPull, Speed::Medium) 267 self.tx_config.af_type()
222 } 268 }
223 269
224 fn rx_af(&self) -> AfType { 270 fn rx_af(&self) -> AfType {
225 #[cfg(any(usart_v3, usart_v4))] 271 #[cfg(any(usart_v3, usart_v4))]
226 if self.swap_rx_tx { 272 if self.swap_rx_tx {
227 return AfType::output(OutputType::PushPull, Speed::Medium); 273 return self.tx_config.af_type();
228 }; 274 };
229 AfType::input(self.rx_pull) 275 AfType::input(self.rx_pull)
230 } 276 }
@@ -248,6 +294,10 @@ impl Default for Config {
248 #[cfg(any(usart_v3, usart_v4))] 294 #[cfg(any(usart_v3, usart_v4))]
249 invert_rx: false, 295 invert_rx: false,
250 rx_pull: Pull::None, 296 rx_pull: Pull::None,
297 cts_pull: Pull::None,
298 tx_config: OutputConfig::PushPull,
299 rts_config: OutputConfig::PushPull,
300 de_config: OutputConfig::PushPull,
251 duplex: Duplex::Full, 301 duplex: Duplex::Full,
252 } 302 }
253 } 303 }
@@ -426,7 +476,7 @@ impl<'d> UartTx<'d, Async> {
426 ) -> Result<Self, ConfigError> { 476 ) -> Result<Self, ConfigError> {
427 Self::new_inner( 477 Self::new_inner(
428 peri, 478 peri,
429 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), 479 new_pin!(tx, config.tx_af()),
430 None, 480 None,
431 new_dma!(tx_dma), 481 new_dma!(tx_dma),
432 config, 482 config,
@@ -443,8 +493,8 @@ impl<'d> UartTx<'d, Async> {
443 ) -> Result<Self, ConfigError> { 493 ) -> Result<Self, ConfigError> {
444 Self::new_inner( 494 Self::new_inner(
445 peri, 495 peri,
446 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), 496 new_pin!(tx, config.tx_af()),
447 new_pin!(cts, AfType::input(Pull::None)), 497 new_pin!(cts, AfType::input(config.cts_pull)),
448 new_dma!(tx_dma), 498 new_dma!(tx_dma),
449 config, 499 config,
450 ) 500 )
@@ -484,7 +534,7 @@ impl<'d> UartTx<'d, Blocking> {
484 ) -> Result<Self, ConfigError> { 534 ) -> Result<Self, ConfigError> {
485 Self::new_inner( 535 Self::new_inner(
486 peri, 536 peri,
487 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), 537 new_pin!(tx, config.tx_af()),
488 None, 538 None,
489 None, 539 None,
490 config, 540 config,
@@ -500,8 +550,8 @@ impl<'d> UartTx<'d, Blocking> {
500 ) -> Result<Self, ConfigError> { 550 ) -> Result<Self, ConfigError> {
501 Self::new_inner( 551 Self::new_inner(
502 peri, 552 peri,
503 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), 553 new_pin!(tx, config.tx_af()),
504 new_pin!(cts, AfType::input(config.rx_pull)), 554 new_pin!(cts, AfType::input(config.cts_pull)),
505 None, 555 None,
506 config, 556 config,
507 ) 557 )
@@ -658,7 +708,7 @@ impl<'d> UartRx<'d, Async> {
658 ) -> Result<Self, ConfigError> { 708 ) -> Result<Self, ConfigError> {
659 Self::new_inner( 709 Self::new_inner(
660 peri, 710 peri,
661 new_pin!(rx, AfType::input(config.rx_pull)), 711 new_pin!(rx, config.rx_af()),
662 None, 712 None,
663 new_dma!(rx_dma), 713 new_dma!(rx_dma),
664 config, 714 config,
@@ -676,8 +726,8 @@ impl<'d> UartRx<'d, Async> {
676 ) -> Result<Self, ConfigError> { 726 ) -> Result<Self, ConfigError> {
677 Self::new_inner( 727 Self::new_inner(
678 peri, 728 peri,
679 new_pin!(rx, AfType::input(config.rx_pull)), 729 new_pin!(rx, config.rx_af()),
680 new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)), 730 new_pin!(rts, config.rts_config.af_type()),
681 new_dma!(rx_dma), 731 new_dma!(rx_dma),
682 config, 732 config,
683 ) 733 )
@@ -912,7 +962,7 @@ impl<'d> UartRx<'d, Blocking> {
912 rx: Peri<'d, impl RxPin<T>>, 962 rx: Peri<'d, impl RxPin<T>>,
913 config: Config, 963 config: Config,
914 ) -> Result<Self, ConfigError> { 964 ) -> Result<Self, ConfigError> {
915 Self::new_inner(peri, new_pin!(rx, AfType::input(config.rx_pull)), None, None, config) 965 Self::new_inner(peri, new_pin!(rx, config.rx_af()), None, None, config)
916 } 966 }
917 967
918 /// Create a new rx-only UART with a request-to-send pin 968 /// Create a new rx-only UART with a request-to-send pin
@@ -924,8 +974,8 @@ impl<'d> UartRx<'d, Blocking> {
924 ) -> Result<Self, ConfigError> { 974 ) -> Result<Self, ConfigError> {
925 Self::new_inner( 975 Self::new_inner(
926 peri, 976 peri,
927 new_pin!(rx, AfType::input(config.rx_pull)), 977 new_pin!(rx, config.rx_af()),
928 new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)), 978 new_pin!(rts, config.rts_config.af_type()),
929 None, 979 None,
930 config, 980 config,
931 ) 981 )
@@ -1141,8 +1191,8 @@ impl<'d> Uart<'d, Async> {
1141 peri, 1191 peri,
1142 new_pin!(rx, config.rx_af()), 1192 new_pin!(rx, config.rx_af()),
1143 new_pin!(tx, config.tx_af()), 1193 new_pin!(tx, config.tx_af()),
1144 new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)), 1194 new_pin!(rts, config.rts_config.af_type()),
1145 new_pin!(cts, AfType::input(Pull::None)), 1195 new_pin!(cts, AfType::input(config.cts_pull)),
1146 None, 1196 None,
1147 new_dma!(tx_dma), 1197 new_dma!(tx_dma),
1148 new_dma!(rx_dma), 1198 new_dma!(rx_dma),
@@ -1168,7 +1218,7 @@ impl<'d> Uart<'d, Async> {
1168 new_pin!(tx, config.tx_af()), 1218 new_pin!(tx, config.tx_af()),
1169 None, 1219 None,
1170 None, 1220 None,
1171 new_pin!(de, AfType::output(OutputType::PushPull, Speed::Medium)), 1221 new_pin!(de, config.de_config.af_type()),
1172 new_dma!(tx_dma), 1222 new_dma!(tx_dma),
1173 new_dma!(rx_dma), 1223 new_dma!(rx_dma),
1174 config, 1224 config,
@@ -1308,8 +1358,8 @@ impl<'d> Uart<'d, Blocking> {
1308 peri, 1358 peri,
1309 new_pin!(rx, config.rx_af()), 1359 new_pin!(rx, config.rx_af()),
1310 new_pin!(tx, config.tx_af()), 1360 new_pin!(tx, config.tx_af()),
1311 new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)), 1361 new_pin!(rts, config.rts_config.af_type()),
1312 new_pin!(cts, AfType::input(Pull::None)), 1362 new_pin!(cts, AfType::input(config.cts_pull)),
1313 None, 1363 None,
1314 None, 1364 None,
1315 None, 1365 None,
@@ -1332,7 +1382,7 @@ impl<'d> Uart<'d, Blocking> {
1332 new_pin!(tx, config.tx_af()), 1382 new_pin!(tx, config.tx_af()),
1333 None, 1383 None,
1334 None, 1384 None,
1335 new_pin!(de, AfType::output(OutputType::PushPull, Speed::Medium)), 1385 new_pin!(de, config.de_config.af_type()),
1336 None, 1386 None,
1337 None, 1387 None,
1338 config, 1388 config,