From 591612db7e5f8f8dd5120b12a55c00da38a510a8 Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Mon, 23 Oct 2023 22:39:24 +0300 Subject: [PATCH 1/6] stm32 uart: return error if rx and tx not enabled --- embassy-stm32/src/usart/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 880ca4162..09d5a59d2 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -108,6 +108,7 @@ pub enum StopBits { pub enum ConfigError { BaudrateTooLow, BaudrateTooHigh, + RxOrTxNotEnabled, } #[non_exhaustive] @@ -866,7 +867,7 @@ fn configure( enable_tx: bool, ) -> Result<(), ConfigError> { if !enable_rx && !enable_tx { - panic!("USART: At least one of RX or TX should be enabled"); + return Err(ConfigError::RxOrTxNotEnabled); } #[cfg(not(usart_v4))] From 188ee59ba656d5fd47f5a13f978cd064752d3b75 Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Mon, 23 Oct 2023 22:40:24 +0300 Subject: [PATCH 2/6] stm32: fix setting uart databits --- embassy-stm32/src/usart/mod.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 09d5a59d2..8c4df375a 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -910,6 +910,11 @@ fn configure( brr + rounding } + // UART must be disabled during configuration. + r.cr1().modify(|w| { + w.set_ue(false); + }); + #[cfg(not(usart_v1))] let mut over8 = false; let mut found_brr = None; @@ -977,10 +982,9 @@ fn configure( // enable receiver w.set_re(enable_rx); // configure word size - w.set_m0(if config.parity != Parity::ParityNone { - vals::M0::BIT9 - } else { - vals::M0::BIT8 + w.set_m0(match config.data_bits { + DataBits::DataBits8 => vals::M0::BIT8, + DataBits::DataBits9 => vals::M0::BIT9, }); // configure parity w.set_pce(config.parity != Parity::ParityNone); From 7f72dbdaf2dc43872c647086d7199769a88b5289 Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Mon, 23 Oct 2023 22:43:15 +0300 Subject: [PATCH 3/6] stm32: fix set_config for buffered uart In reconfigure() cr1 register is initialised with write (not modify) which means rxneie and idleneie are disabled after reconfiguration. --- embassy-stm32/src/usart/buffered.rs | 38 ++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index cbc13a342..1c0a6d697 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -233,7 +233,7 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { configure(r, &config, T::frequency(), T::KIND, true, true)?; r.cr1().modify(|w| { - #[cfg(lpuart_v2)] + #[cfg(usart_v4)] w.set_fifoen(true); w.set_rxneie(true); @@ -254,7 +254,17 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { } pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - reconfigure::(config) + reconfigure::(config)?; + + T::regs().cr1().modify(|w| { + #[cfg(usart_v4)] + w.set_fifoen(true); + + w.set_rxneie(true); + w.set_idleie(true); + }); + + Ok(()) } } @@ -334,7 +344,17 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { } pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - reconfigure::(config) + reconfigure::(config)?; + + T::regs().cr1().modify(|w| { + #[cfg(usart_v4)] + w.set_fifoen(true); + + w.set_rxneie(true); + w.set_idleie(true); + }); + + Ok(()) } } @@ -408,7 +428,17 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { } pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - reconfigure::(config) + reconfigure::(config)?; + + T::regs().cr1().modify(|w| { + #[cfg(usart_v4)] + w.set_fifoen(true); + + w.set_rxneie(true); + w.set_idleie(true); + }); + + Ok(()) } } From 1e362c750baca264e1ab199adb0f18f2098fa236 Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Tue, 24 Oct 2023 09:54:17 +0300 Subject: [PATCH 4/6] stm32 uart: use ConfigError instead of () as error --- embassy-stm32/src/usart/buffered.rs | 18 +++++++++--------- embassy-stm32/src/usart/mod.rs | 20 ++++++++++---------- embassy-stm32/src/usart/ringbuffered.rs | 6 +++--- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 1c0a6d697..0e314c1d3 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -116,28 +116,28 @@ pub struct BufferedUartRx<'d, T: BasicInstance> { impl<'d, T: BasicInstance> SetConfig for BufferedUart<'d, T> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } impl<'d, T: BasicInstance> SetConfig for BufferedUartRx<'d, T> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } impl<'d, T: BasicInstance> SetConfig for BufferedUartTx<'d, T> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 8c4df375a..60b504da1 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -182,11 +182,11 @@ pub struct Uart<'d, T: BasicInstance, TxDma = NoDma, RxDma = NoDma> { impl<'d, T: BasicInstance, TxDma, RxDma> SetConfig for Uart<'d, T, TxDma, RxDma> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.tx.set_config(config).map_err(|_| ())?; - self.rx.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.tx.set_config(config)?; + self.rx.set_config(config) } } @@ -197,10 +197,10 @@ pub struct UartTx<'d, T: BasicInstance, TxDma = NoDma> { impl<'d, T: BasicInstance, TxDma> SetConfig for UartTx<'d, T, TxDma> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } @@ -214,10 +214,10 @@ pub struct UartRx<'d, T: BasicInstance, RxDma = NoDma> { impl<'d, T: BasicInstance, RxDma> SetConfig for UartRx<'d, T, RxDma> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index 55489f2e0..eceabbe9a 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs @@ -18,10 +18,10 @@ pub struct RingBufferedUartRx<'d, T: BasicInstance, RxDma: super::RxDma> { impl<'d, T: BasicInstance, RxDma: super::RxDma> SetConfig for RingBufferedUartRx<'d, T, RxDma> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } From 25c2a9baaa863a42780e70791d6ab9df89f2dd3b Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Tue, 24 Oct 2023 10:11:54 +0300 Subject: [PATCH 5/6] stm32 uart: remove redundant set_fifoen(true) --- embassy-stm32/src/usart/buffered.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 0e314c1d3..4daddfe91 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -233,9 +233,6 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { configure(r, &config, T::frequency(), T::KIND, true, true)?; r.cr1().modify(|w| { - #[cfg(usart_v4)] - w.set_fifoen(true); - w.set_rxneie(true); w.set_idleie(true); }); @@ -257,9 +254,6 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { reconfigure::(config)?; T::regs().cr1().modify(|w| { - #[cfg(usart_v4)] - w.set_fifoen(true); - w.set_rxneie(true); w.set_idleie(true); }); @@ -347,9 +341,6 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { reconfigure::(config)?; T::regs().cr1().modify(|w| { - #[cfg(usart_v4)] - w.set_fifoen(true); - w.set_rxneie(true); w.set_idleie(true); }); @@ -431,9 +422,6 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { reconfigure::(config)?; T::regs().cr1().modify(|w| { - #[cfg(usart_v4)] - w.set_fifoen(true); - w.set_rxneie(true); w.set_idleie(true); }); From bda99e59ec0f2d31e4f29b8d03fbd44d8e917fdd Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Tue, 24 Oct 2023 15:57:03 +0300 Subject: [PATCH 6/6] stm32: fix uart parity, add comment why it is so --- embassy-stm32/src/usart/mod.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 60b504da1..ea127e7f7 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -974,6 +974,12 @@ fn configure( #[cfg(any(usart_v3, usart_v4))] w.set_swap(config.swap_rx_tx); }); + + #[cfg(not(usart_v1))] + r.cr3().modify(|w| { + w.set_onebit(config.assume_noise_free); + }); + r.cr1().write(|w| { // enable uart w.set_ue(true); @@ -982,9 +988,11 @@ fn configure( // enable receiver w.set_re(enable_rx); // configure word size - w.set_m0(match config.data_bits { - DataBits::DataBits8 => vals::M0::BIT8, - DataBits::DataBits9 => vals::M0::BIT9, + // if using odd or even parity it must be configured to 9bits + w.set_m0(if config.parity != Parity::ParityNone { + vals::M0::BIT9 + } else { + vals::M0::BIT8 }); // configure parity w.set_pce(config.parity != Parity::ParityNone); @@ -999,11 +1007,6 @@ fn configure( w.set_fifoen(true); }); - #[cfg(not(usart_v1))] - r.cr3().modify(|w| { - w.set_onebit(config.assume_noise_free); - }); - Ok(()) }