From 7ea97161b24480ec2d3abd4529718dc38415fcac Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Thu, 25 Jul 2024 17:41:06 +0300 Subject: [PATCH 1/2] Serial flow control --- CHANGELOG.md | 1 + src/serial/uart_impls.rs | 64 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86e7f8e7..fbc1c5ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added + - Serial flow control enable - `i2c_scanner` example [#758] - Enable `sdio` for stm32f446 - port LTDC implementation and example from stm32f7xx-hal [#731] diff --git a/src/serial/uart_impls.rs b/src/serial/uart_impls.rs index 75f316c6..8d0ca7d2 100644 --- a/src/serial/uart_impls.rs +++ b/src/serial/uart_impls.rs @@ -10,7 +10,10 @@ use crate::dma::{ traits::{DMASet, PeriAddress}, MemoryToPeripheral, PeripheralToMemory, }; -use crate::gpio::{alt::SerialAsync as CommonPins, NoPin, PushPull}; +use crate::gpio::{ + alt::{SerialAsync as CommonPins, SerialFlowControl}, + NoPin, PushPull, +}; use crate::rcc::{self, Clocks}; #[cfg(feature = "uart4")] @@ -262,6 +265,20 @@ macro_rules! uartCommon { }; } +pub trait RBFlowControlImpl { + fn enable_rts(&self, state: bool); + fn enable_cts(&self, state: bool); +} + +impl RBFlowControlImpl for RegisterBlockUsart { + fn enable_rts(&self, state: bool) { + self.cr3().modify(|_, w| w.rtse().bit(state)); + } + fn enable_cts(&self, state: bool) { + self.cr3().modify(|_, w| w.ctse().bit(state)); + } +} + impl RegisterBlockImpl for RegisterBlockUsart { fn new, WORD>( uart: UART, @@ -402,6 +419,23 @@ where { uartCommon! {} } +#[cfg(feature = "uart4")] +#[cfg(not(any( + feature = "gpio-f413", + feature = "gpio-f417", + feature = "gpio-f427", + feature = "gpio-f446", + feature = "gpio-f469" +)))] +impl RBFlowControlImpl for RegisterBlockUart { + fn enable_rts(&self, state: bool) { + self.cr3().modify(|_, w| w.rtse().bit(state)); + } + fn enable_cts(&self, state: bool) { + self.cr3().modify(|_, w| w.ctse().bit(state)); + } +} + #[cfg(feature = "uart4")] impl RegisterBlockImpl for RegisterBlockUart { fn new, WORD>( @@ -509,6 +543,34 @@ where { uartCommon! {} } +impl Serial +where + UART::RegisterBlock: RBFlowControlImpl, +{ + pub fn with_rts(self, rts: impl Into) -> Self { + self.rx.usart.enable_rts(true); + let _rts = rts.into(); + self + } + pub fn with_cts(self, cts: impl Into) -> Self { + self.tx.usart.enable_cts(true); + let _cts = cts.into(); + self + } + pub fn enable_request_to_send(&mut self) { + self.rx.usart.enable_rts(true); + } + pub fn disable_request_to_send(&mut self) { + self.rx.usart.enable_rts(false); + } + pub fn enable_clear_to_send(&mut self) { + self.tx.usart.enable_cts(true); + } + pub fn disable_clear_to_send(&mut self) { + self.tx.usart.enable_cts(false); + } +} + impl RxISR for Serial where Rx: RxISR, From c05ca30894c7324f993d37cc527d1ec7ba5a1898 Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Thu, 25 Jul 2024 19:42:07 +0300 Subject: [PATCH 2/2] listen CTS --- CHANGELOG.md | 4 +++- src/serial.rs | 2 ++ src/serial/uart_impls.rs | 15 ++++++++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbc1c5ca..e8dd8a26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - - Serial flow control enable + - Serial flow control enable [#775] - `i2c_scanner` example [#758] - Enable `sdio` for stm32f446 - port LTDC implementation and example from stm32f7xx-hal [#731] @@ -36,6 +36,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). [#758]: https://github.com/stm32-rs/stm32f4xx-hal/pull/758 [#773]: https://github.com/stm32-rs/stm32f4xx-hal/pull/773 +[#775]: https://github.com/stm32-rs/stm32f4xx-hal/pull/775 + ## [v0.21.0] - 2024-05-30 ### Changed diff --git a/src/serial.rs b/src/serial.rs index d4192bb2..bf00718c 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -111,6 +111,8 @@ pub enum CFlag { TransmissionComplete = 1 << 6, /// LIN break detection flag LinBreak = 1 << 8, + /// Clear to send flag + Cts = 1 << 9, } pub mod config; diff --git a/src/serial/uart_impls.rs b/src/serial/uart_impls.rs index 8d0ca7d2..4ae91e1c 100644 --- a/src/serial/uart_impls.rs +++ b/src/serial/uart_impls.rs @@ -268,15 +268,22 @@ macro_rules! uartCommon { pub trait RBFlowControlImpl { fn enable_rts(&self, state: bool); fn enable_cts(&self, state: bool); + fn listen_cts(&self, state: bool); } impl RBFlowControlImpl for RegisterBlockUsart { + #[inline(always)] fn enable_rts(&self, state: bool) { self.cr3().modify(|_, w| w.rtse().bit(state)); } + #[inline(always)] fn enable_cts(&self, state: bool) { self.cr3().modify(|_, w| w.ctse().bit(state)); } + #[inline(always)] + fn listen_cts(&self, state: bool) { + self.cr3().modify(|_, w| w.ctsie().bit(state)) + } } impl RegisterBlockImpl for RegisterBlockUsart { @@ -545,7 +552,7 @@ where { impl Serial where - UART::RegisterBlock: RBFlowControlImpl, + UART::RB: RBFlowControlImpl, { pub fn with_rts(self, rts: impl Into) -> Self { self.rx.usart.enable_rts(true); @@ -569,6 +576,12 @@ where pub fn disable_clear_to_send(&mut self) { self.tx.usart.enable_cts(false); } + pub fn listen_clear_to_send(&mut self) { + self.tx.usart.listen_cts(true) + } + pub fn unlisten_clear_to_send(&mut self) { + self.tx.usart.listen_cts(false) + } } impl RxISR for Serial