From 664e4a5c032d2291beedf1ead706f5d17b8178da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C5=A0pa=C4=8Dek?= Date: Sun, 26 May 2024 16:55:07 +0200 Subject: [PATCH] stm32/usart: move init code to function that's not generic in T --- embassy-stm32/src/usart/buffered.rs | 68 +++++++++------ embassy-stm32/src/usart/mod.rs | 130 ++++++++++++++++------------ 2 files changed, 113 insertions(+), 85 deletions(-) diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 2c19e16db..09d020a7b 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -16,9 +16,7 @@ use super::{ Regs, RtsPin, RxPin, TxPin, }; use crate::gpio::{AFType, AnyPin, SealedPin as _}; -use crate::interrupt::typelevel::Interrupt as _; use crate::interrupt::{self, InterruptExt}; -use crate::rcc; use crate::time::Hertz; /// Interrupt handler. @@ -284,35 +282,11 @@ impl<'d> BufferedUart<'d> { rx_buffer: &'d mut [u8], config: Config, ) -> Result { - rcc::enable_and_reset::(); - let info = T::info(); let state = T::buffered_state(); let kernel_clock = T::frequency(); - let len = tx_buffer.len(); - unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; - let len = rx_buffer.len(); - unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; - info.regs.cr3().write(|w| { - w.set_rtse(rts.is_some()); - w.set_ctse(cts.is_some()); - #[cfg(not(any(usart_v1, usart_v2)))] - w.set_dem(de.is_some()); - }); - configure(info, kernel_clock, &config, true, true)?; - - info.regs.cr1().modify(|w| { - w.set_rxneie(true); - w.set_idleie(true); - }); - - T::Interrupt::unpend(); - unsafe { T::Interrupt::enable() }; - - state.tx_rx_refcount.store(2, Ordering::Relaxed); - - Ok(Self { + let mut this = Self { rx: BufferedUartRx { info, state, @@ -328,7 +302,45 @@ impl<'d> BufferedUart<'d> { cts, de, }, - }) + }; + this.enable_and_configure(tx_buffer, rx_buffer, &config)?; + Ok(this) + } + + fn enable_and_configure( + &mut self, + tx_buffer: &'d mut [u8], + rx_buffer: &'d mut [u8], + config: &Config, + ) -> Result<(), ConfigError> { + let info = self.rx.info; + let state = self.rx.state; + + info.rcc.enable_and_reset(); + + let len = tx_buffer.len(); + unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; + let len = rx_buffer.len(); + unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; + + info.regs.cr3().write(|w| { + w.set_rtse(self.rx.rts.is_some()); + w.set_ctse(self.tx.cts.is_some()); + #[cfg(not(any(usart_v1, usart_v2)))] + w.set_dem(self.tx.de.is_some()); + }); + configure(info, self.rx.kernel_clock, &config, true, true)?; + + info.regs.cr1().modify(|w| { + w.set_rxneie(true); + w.set_idleie(true); + }); + + info.interrupt.unpend(); + unsafe { info.interrupt.enable() }; + + state.tx_rx_refcount.store(2, Ordering::Relaxed); + Ok(()) } /// Split the driver into a Tx and Rx part (useful for sending to separate tasks) diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 6ef80c54f..df5121f67 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -28,7 +28,7 @@ use crate::pac::usart::Lpuart as Regs; #[cfg(any(usart_v1, usart_v2))] use crate::pac::usart::Usart as Regs; use crate::pac::usart::{regs, vals}; -use crate::rcc::{self, RccInfo, SealedRccPeripheral}; +use crate::rcc::{RccInfo, SealedRccPeripheral}; use crate::time::Hertz; use crate::Peripheral; @@ -429,29 +429,33 @@ impl<'d, M: Mode> UartTx<'d, M> { tx_dma: Option>, config: Config, ) -> Result { - rcc::enable_and_reset::(); - - let info = T::info(); - let state = T::state(); - let kernel_clock = T::frequency(); - let r = info.regs; - r.cr3().modify(|w| { - w.set_ctse(cts.is_some()); - }); - configure(info, kernel_clock, &config, false, true)?; - - state.tx_rx_refcount.store(1, Ordering::Relaxed); - - Ok(Self { - info, - state, - kernel_clock, + let mut this = Self { + info: T::info(), + state: T::state(), + kernel_clock: T::frequency(), tx, cts, de: None, tx_dma, _phantom: PhantomData, - }) + }; + this.enable_and_configure(&config)?; + Ok(this) + } + + fn enable_and_configure(&mut self, config: &Config) -> Result<(), ConfigError> { + let info = self.info; + let state = self.state; + + info.rcc.enable_and_reset(); + + info.regs.cr3().modify(|w| { + w.set_ctse(self.cts.is_some()); + }); + configure(info, self.kernel_clock, config, false, true)?; + + state.tx_rx_refcount.store(1, Ordering::Relaxed); + Ok(()) } /// Reconfigure the driver @@ -775,34 +779,38 @@ impl<'d, M: Mode> UartRx<'d, M> { rx_dma: Option>, config: Config, ) -> Result { - rcc::enable_and_reset::(); - - let info = T::info(); - let state = T::state(); - let kernel_clock = T::frequency(); - let r = info.regs; - r.cr3().write(|w| { - w.set_rtse(rts.is_some()); - }); - configure(info, kernel_clock, &config, true, false)?; - - T::Interrupt::unpend(); - unsafe { T::Interrupt::enable() }; - - state.tx_rx_refcount.store(1, Ordering::Relaxed); - - Ok(Self { + let mut this = Self { _phantom: PhantomData, - info, - state, - kernel_clock, + info: T::info(), + state: T::state(), + kernel_clock: T::frequency(), rx, rts, rx_dma, detect_previous_overrun: config.detect_previous_overrun, #[cfg(any(usart_v1, usart_v2))] buffered_sr: stm32_metapac::usart::regs::Sr(0), - }) + }; + this.enable_and_configure(&config)?; + Ok(this) + } + + fn enable_and_configure(&mut self, config: &Config) -> Result<(), ConfigError> { + let info = self.info; + let state = self.state; + + info.rcc.enable_and_reset(); + + info.regs.cr3().write(|w| { + w.set_rtse(self.rts.is_some()); + }); + configure(info, self.kernel_clock, &config, true, false)?; + + info.interrupt.unpend(); + unsafe { info.interrupt.enable() }; + + state.tx_rx_refcount.store(1, Ordering::Relaxed); + Ok(()) } /// Reconfigure the driver @@ -1228,26 +1236,11 @@ impl<'d, M: Mode> Uart<'d, M> { rx_dma: Option>, config: Config, ) -> Result { - rcc::enable_and_reset::(); - let info = T::info(); let state = T::state(); let kernel_clock = T::frequency(); - info.regs.cr3().write(|w| { - w.set_rtse(rts.is_some()); - w.set_ctse(cts.is_some()); - #[cfg(not(any(usart_v1, usart_v2)))] - w.set_dem(de.is_some()); - }); - configure(info, kernel_clock, &config, true, true)?; - - T::Interrupt::unpend(); - unsafe { T::Interrupt::enable() }; - - state.tx_rx_refcount.store(2, Ordering::Relaxed); - - Ok(Self { + let mut this = Self { tx: UartTx { _phantom: PhantomData, info, @@ -1270,7 +1263,30 @@ impl<'d, M: Mode> Uart<'d, M> { #[cfg(any(usart_v1, usart_v2))] buffered_sr: stm32_metapac::usart::regs::Sr(0), }, - }) + }; + this.enable_and_configure(&config)?; + Ok(this) + } + + fn enable_and_configure(&mut self, config: &Config) -> Result<(), ConfigError> { + let info = self.rx.info; + let state = self.rx.state; + + info.rcc.enable_and_reset(); + + info.regs.cr3().write(|w| { + w.set_rtse(self.rx.rts.is_some()); + w.set_ctse(self.tx.cts.is_some()); + #[cfg(not(any(usart_v1, usart_v2)))] + w.set_dem(self.tx.de.is_some()); + }); + configure(info, self.rx.kernel_clock, config, true, true)?; + + info.interrupt.unpend(); + unsafe { info.interrupt.enable() }; + + state.tx_rx_refcount.store(2, Ordering::Relaxed); + Ok(()) } /// Perform a blocking write