From 44e4a2c9e9c1e5824acb68673c8f6b4b98d1ea07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C5=A0pa=C4=8Dek?= Date: Sun, 26 May 2024 16:37:26 +0200 Subject: [PATCH] stm32/buffered-usart: use new_pin! and disconnect pins on drop --- embassy-stm32/src/usart/buffered.rs | 102 +++++++++++++++++----------- embassy-stm32/src/usart/mod.rs | 5 +- 2 files changed, 65 insertions(+), 42 deletions(-) diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index eacf95002..2c19e16db 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -6,7 +6,7 @@ use core::task::Poll; use embassy_embedded_hal::SetConfig; use embassy_hal_internal::atomic_ring_buffer::RingBuffer; -use embassy_hal_internal::{into_ref, Peripheral}; +use embassy_hal_internal::{Peripheral, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; #[cfg(not(any(usart_v1, usart_v2)))] @@ -15,7 +15,7 @@ use super::{ clear_interrupt_flags, configure, rdr, reconfigure, sr, tdr, Config, ConfigError, CtsPin, Error, Info, Instance, Regs, RtsPin, RxPin, TxPin, }; -use crate::gpio::AFType; +use crate::gpio::{AFType, AnyPin, SealedPin as _}; use crate::interrupt::typelevel::Interrupt as _; use crate::interrupt::{self, InterruptExt}; use crate::rcc; @@ -156,7 +156,9 @@ pub struct BufferedUartTx<'d> { info: &'static Info, state: &'static State, kernel_clock: Hertz, - _phantom: PhantomData<&'d mut ()>, + tx: Option>, + cts: Option>, + de: Option>, } /// Rx-only buffered UART @@ -166,7 +168,8 @@ pub struct BufferedUartRx<'d> { info: &'static Info, state: &'static State, kernel_clock: Hertz, - _phantom: PhantomData<&'d mut ()>, + rx: Option>, + rts: Option>, } impl<'d> SetConfig for BufferedUart<'d> { @@ -207,9 +210,17 @@ impl<'d> BufferedUart<'d> { rx_buffer: &'d mut [u8], config: Config, ) -> Result { - rcc::enable_and_reset::(); - - Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) + Self::new_inner( + peri, + new_pin!(rx, AFType::Input), + new_pin!(tx, AFType::OutputPushPull), + None, + None, + None, + tx_buffer, + rx_buffer, + config, + ) } /// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins @@ -224,18 +235,17 @@ impl<'d> BufferedUart<'d> { rx_buffer: &'d mut [u8], config: Config, ) -> Result { - into_ref!(cts, rts); - - rcc::enable_and_reset::(); - - rts.set_as_af(rts.af_num(), AFType::OutputPushPull); - cts.set_as_af(cts.af_num(), AFType::Input); - T::info().regs.cr3().write(|w| { - w.set_rtse(true); - w.set_ctse(true); - }); - - Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) + Self::new_inner( + peri, + new_pin!(rx, AFType::Input), + new_pin!(tx, AFType::OutputPushPull), + new_pin!(rts, AFType::OutputPushPull), + new_pin!(cts, AFType::Input), + None, + tx_buffer, + rx_buffer, + config, + ) } /// Create a new bidirectional buffered UART driver with a driver-enable pin @@ -250,27 +260,31 @@ impl<'d> BufferedUart<'d> { rx_buffer: &'d mut [u8], config: Config, ) -> Result { - into_ref!(de); - - rcc::enable_and_reset::(); - - de.set_as_af(de.af_num(), AFType::OutputPushPull); - T::info().regs.cr3().write(|w| { - w.set_dem(true); - }); - - Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) + Self::new_inner( + peri, + new_pin!(rx, AFType::Input), + new_pin!(tx, AFType::OutputPushPull), + None, + None, + new_pin!(de, AFType::OutputPushPull), + tx_buffer, + rx_buffer, + config, + ) } fn new_inner( _peri: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, - tx: impl Peripheral

> + 'd, + rx: Option>, + tx: Option>, + rts: Option>, + cts: Option>, + de: Option>, tx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8], config: Config, ) -> Result { - into_ref!(_peri, rx, tx); + rcc::enable_and_reset::(); let info = T::info(); let state = T::buffered_state(); @@ -280,13 +294,15 @@ impl<'d> BufferedUart<'d> { let len = rx_buffer.len(); unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; - let r = info.regs; - rx.set_as_af(rx.af_num(), AFType::Input); - tx.set_as_af(tx.af_num(), AFType::OutputPushPull); - + 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)?; - r.cr1().modify(|w| { + info.regs.cr1().modify(|w| { w.set_rxneie(true); w.set_idleie(true); }); @@ -301,13 +317,16 @@ impl<'d> BufferedUart<'d> { info, state, kernel_clock, - _phantom: PhantomData, + rx, + rts, }, tx: BufferedUartTx { info, state, kernel_clock, - _phantom: PhantomData, + tx, + cts, + de, }, }) } @@ -516,6 +535,8 @@ impl<'d> Drop for BufferedUartRx<'d> { } } + self.rx.as_ref().map(|x| x.set_as_disconnected()); + self.rts.as_ref().map(|x| x.set_as_disconnected()); drop_tx_rx(self.info, state); } } @@ -533,6 +554,9 @@ impl<'d> Drop for BufferedUartTx<'d> { } } + self.tx.as_ref().map(|x| x.set_as_disconnected()); + self.cts.as_ref().map(|x| x.set_as_disconnected()); + self.de.as_ref().map(|x| x.set_as_disconnected()); drop_tx_rx(self.info, state); } } diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 2a39c6301..6ef80c54f 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -14,7 +14,7 @@ use embassy_sync::waitqueue::AtomicWaker; use futures_util::future::{select, Either}; use crate::dma::ChannelAndRequest; -use crate::gpio::{AFType, AnyPin, SealedPin}; +use crate::gpio::{AFType, AnyPin, SealedPin as _}; use crate::interrupt::typelevel::Interrupt as _; use crate::interrupt::{self, Interrupt, InterruptExt}; use crate::mode::{Async, Blocking, Mode}; @@ -1233,9 +1233,8 @@ impl<'d, M: Mode> Uart<'d, M> { let info = T::info(); let state = T::state(); let kernel_clock = T::frequency(); - let r = info.regs; - r.cr3().write(|w| { + info.regs.cr3().write(|w| { w.set_rtse(rts.is_some()); w.set_ctse(cts.is_some()); #[cfg(not(any(usart_v1, usart_v2)))]