diff options
| author | Jan Špaček <[email protected]> | 2024-05-26 16:37:26 +0200 |
|---|---|---|
| committer | Jan Špaček <[email protected]> | 2024-06-01 19:46:39 +0200 |
| commit | 44e4a2c9e9c1e5824acb68673c8f6b4b98d1ea07 (patch) | |
| tree | cb690564bba8644b61d5a4868c998dcdf817d091 | |
| parent | ade27b7f212f9548816e5ae21826a230c2345574 (diff) | |
stm32/buffered-usart: use new_pin! and disconnect pins on drop
| -rw-r--r-- | embassy-stm32/src/usart/buffered.rs | 102 | ||||
| -rw-r--r-- | 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; | |||
| 6 | 6 | ||
| 7 | use embassy_embedded_hal::SetConfig; | 7 | use embassy_embedded_hal::SetConfig; |
| 8 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; | 8 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; |
| 9 | use embassy_hal_internal::{into_ref, Peripheral}; | 9 | use embassy_hal_internal::{Peripheral, PeripheralRef}; |
| 10 | use embassy_sync::waitqueue::AtomicWaker; | 10 | use embassy_sync::waitqueue::AtomicWaker; |
| 11 | 11 | ||
| 12 | #[cfg(not(any(usart_v1, usart_v2)))] | 12 | #[cfg(not(any(usart_v1, usart_v2)))] |
| @@ -15,7 +15,7 @@ use super::{ | |||
| 15 | clear_interrupt_flags, configure, rdr, reconfigure, sr, tdr, Config, ConfigError, CtsPin, Error, Info, Instance, | 15 | clear_interrupt_flags, configure, rdr, reconfigure, sr, tdr, Config, ConfigError, CtsPin, Error, Info, Instance, |
| 16 | Regs, RtsPin, RxPin, TxPin, | 16 | Regs, RtsPin, RxPin, TxPin, |
| 17 | }; | 17 | }; |
| 18 | use crate::gpio::AFType; | 18 | use crate::gpio::{AFType, AnyPin, SealedPin as _}; |
| 19 | use crate::interrupt::typelevel::Interrupt as _; | 19 | use crate::interrupt::typelevel::Interrupt as _; |
| 20 | use crate::interrupt::{self, InterruptExt}; | 20 | use crate::interrupt::{self, InterruptExt}; |
| 21 | use crate::rcc; | 21 | use crate::rcc; |
| @@ -156,7 +156,9 @@ pub struct BufferedUartTx<'d> { | |||
| 156 | info: &'static Info, | 156 | info: &'static Info, |
| 157 | state: &'static State, | 157 | state: &'static State, |
| 158 | kernel_clock: Hertz, | 158 | kernel_clock: Hertz, |
| 159 | _phantom: PhantomData<&'d mut ()>, | 159 | tx: Option<PeripheralRef<'d, AnyPin>>, |
| 160 | cts: Option<PeripheralRef<'d, AnyPin>>, | ||
| 161 | de: Option<PeripheralRef<'d, AnyPin>>, | ||
| 160 | } | 162 | } |
| 161 | 163 | ||
| 162 | /// Rx-only buffered UART | 164 | /// Rx-only buffered UART |
| @@ -166,7 +168,8 @@ pub struct BufferedUartRx<'d> { | |||
| 166 | info: &'static Info, | 168 | info: &'static Info, |
| 167 | state: &'static State, | 169 | state: &'static State, |
| 168 | kernel_clock: Hertz, | 170 | kernel_clock: Hertz, |
| 169 | _phantom: PhantomData<&'d mut ()>, | 171 | rx: Option<PeripheralRef<'d, AnyPin>>, |
| 172 | rts: Option<PeripheralRef<'d, AnyPin>>, | ||
| 170 | } | 173 | } |
| 171 | 174 | ||
| 172 | impl<'d> SetConfig for BufferedUart<'d> { | 175 | impl<'d> SetConfig for BufferedUart<'d> { |
| @@ -207,9 +210,17 @@ impl<'d> BufferedUart<'d> { | |||
| 207 | rx_buffer: &'d mut [u8], | 210 | rx_buffer: &'d mut [u8], |
| 208 | config: Config, | 211 | config: Config, |
| 209 | ) -> Result<Self, ConfigError> { | 212 | ) -> Result<Self, ConfigError> { |
| 210 | rcc::enable_and_reset::<T>(); | 213 | Self::new_inner( |
| 211 | 214 | peri, | |
| 212 | Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) | 215 | new_pin!(rx, AFType::Input), |
| 216 | new_pin!(tx, AFType::OutputPushPull), | ||
| 217 | None, | ||
| 218 | None, | ||
| 219 | None, | ||
| 220 | tx_buffer, | ||
| 221 | rx_buffer, | ||
| 222 | config, | ||
| 223 | ) | ||
| 213 | } | 224 | } |
| 214 | 225 | ||
| 215 | /// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins | 226 | /// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins |
| @@ -224,18 +235,17 @@ impl<'d> BufferedUart<'d> { | |||
| 224 | rx_buffer: &'d mut [u8], | 235 | rx_buffer: &'d mut [u8], |
| 225 | config: Config, | 236 | config: Config, |
| 226 | ) -> Result<Self, ConfigError> { | 237 | ) -> Result<Self, ConfigError> { |
| 227 | into_ref!(cts, rts); | 238 | Self::new_inner( |
| 228 | 239 | peri, | |
| 229 | rcc::enable_and_reset::<T>(); | 240 | new_pin!(rx, AFType::Input), |
| 230 | 241 | new_pin!(tx, AFType::OutputPushPull), | |
| 231 | rts.set_as_af(rts.af_num(), AFType::OutputPushPull); | 242 | new_pin!(rts, AFType::OutputPushPull), |
| 232 | cts.set_as_af(cts.af_num(), AFType::Input); | 243 | new_pin!(cts, AFType::Input), |
| 233 | T::info().regs.cr3().write(|w| { | 244 | None, |
| 234 | w.set_rtse(true); | 245 | tx_buffer, |
| 235 | w.set_ctse(true); | 246 | rx_buffer, |
| 236 | }); | 247 | config, |
| 237 | 248 | ) | |
| 238 | Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) | ||
| 239 | } | 249 | } |
| 240 | 250 | ||
| 241 | /// Create a new bidirectional buffered UART driver with a driver-enable pin | 251 | /// Create a new bidirectional buffered UART driver with a driver-enable pin |
| @@ -250,27 +260,31 @@ impl<'d> BufferedUart<'d> { | |||
| 250 | rx_buffer: &'d mut [u8], | 260 | rx_buffer: &'d mut [u8], |
| 251 | config: Config, | 261 | config: Config, |
| 252 | ) -> Result<Self, ConfigError> { | 262 | ) -> Result<Self, ConfigError> { |
| 253 | into_ref!(de); | 263 | Self::new_inner( |
| 254 | 264 | peri, | |
| 255 | rcc::enable_and_reset::<T>(); | 265 | new_pin!(rx, AFType::Input), |
| 256 | 266 | new_pin!(tx, AFType::OutputPushPull), | |
| 257 | de.set_as_af(de.af_num(), AFType::OutputPushPull); | 267 | None, |
| 258 | T::info().regs.cr3().write(|w| { | 268 | None, |
| 259 | w.set_dem(true); | 269 | new_pin!(de, AFType::OutputPushPull), |
| 260 | }); | 270 | tx_buffer, |
| 261 | 271 | rx_buffer, | |
| 262 | Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) | 272 | config, |
| 273 | ) | ||
| 263 | } | 274 | } |
| 264 | 275 | ||
| 265 | fn new_inner<T: Instance>( | 276 | fn new_inner<T: Instance>( |
| 266 | _peri: impl Peripheral<P = T> + 'd, | 277 | _peri: impl Peripheral<P = T> + 'd, |
| 267 | rx: impl Peripheral<P = impl RxPin<T>> + 'd, | 278 | rx: Option<PeripheralRef<'d, AnyPin>>, |
| 268 | tx: impl Peripheral<P = impl TxPin<T>> + 'd, | 279 | tx: Option<PeripheralRef<'d, AnyPin>>, |
| 280 | rts: Option<PeripheralRef<'d, AnyPin>>, | ||
| 281 | cts: Option<PeripheralRef<'d, AnyPin>>, | ||
| 282 | de: Option<PeripheralRef<'d, AnyPin>>, | ||
| 269 | tx_buffer: &'d mut [u8], | 283 | tx_buffer: &'d mut [u8], |
| 270 | rx_buffer: &'d mut [u8], | 284 | rx_buffer: &'d mut [u8], |
| 271 | config: Config, | 285 | config: Config, |
| 272 | ) -> Result<Self, ConfigError> { | 286 | ) -> Result<Self, ConfigError> { |
| 273 | into_ref!(_peri, rx, tx); | 287 | rcc::enable_and_reset::<T>(); |
| 274 | 288 | ||
| 275 | let info = T::info(); | 289 | let info = T::info(); |
| 276 | let state = T::buffered_state(); | 290 | let state = T::buffered_state(); |
| @@ -280,13 +294,15 @@ impl<'d> BufferedUart<'d> { | |||
| 280 | let len = rx_buffer.len(); | 294 | let len = rx_buffer.len(); |
| 281 | unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; | 295 | unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; |
| 282 | 296 | ||
| 283 | let r = info.regs; | 297 | info.regs.cr3().write(|w| { |
| 284 | rx.set_as_af(rx.af_num(), AFType::Input); | 298 | w.set_rtse(rts.is_some()); |
| 285 | tx.set_as_af(tx.af_num(), AFType::OutputPushPull); | 299 | w.set_ctse(cts.is_some()); |
| 286 | 300 | #[cfg(not(any(usart_v1, usart_v2)))] | |
| 301 | w.set_dem(de.is_some()); | ||
| 302 | }); | ||
| 287 | configure(info, kernel_clock, &config, true, true)?; | 303 | configure(info, kernel_clock, &config, true, true)?; |
| 288 | 304 | ||
| 289 | r.cr1().modify(|w| { | 305 | info.regs.cr1().modify(|w| { |
| 290 | w.set_rxneie(true); | 306 | w.set_rxneie(true); |
| 291 | w.set_idleie(true); | 307 | w.set_idleie(true); |
| 292 | }); | 308 | }); |
| @@ -301,13 +317,16 @@ impl<'d> BufferedUart<'d> { | |||
| 301 | info, | 317 | info, |
| 302 | state, | 318 | state, |
| 303 | kernel_clock, | 319 | kernel_clock, |
| 304 | _phantom: PhantomData, | 320 | rx, |
| 321 | rts, | ||
| 305 | }, | 322 | }, |
| 306 | tx: BufferedUartTx { | 323 | tx: BufferedUartTx { |
| 307 | info, | 324 | info, |
| 308 | state, | 325 | state, |
| 309 | kernel_clock, | 326 | kernel_clock, |
| 310 | _phantom: PhantomData, | 327 | tx, |
| 328 | cts, | ||
| 329 | de, | ||
| 311 | }, | 330 | }, |
| 312 | }) | 331 | }) |
| 313 | } | 332 | } |
| @@ -516,6 +535,8 @@ impl<'d> Drop for BufferedUartRx<'d> { | |||
| 516 | } | 535 | } |
| 517 | } | 536 | } |
| 518 | 537 | ||
| 538 | self.rx.as_ref().map(|x| x.set_as_disconnected()); | ||
| 539 | self.rts.as_ref().map(|x| x.set_as_disconnected()); | ||
| 519 | drop_tx_rx(self.info, state); | 540 | drop_tx_rx(self.info, state); |
| 520 | } | 541 | } |
| 521 | } | 542 | } |
| @@ -533,6 +554,9 @@ impl<'d> Drop for BufferedUartTx<'d> { | |||
| 533 | } | 554 | } |
| 534 | } | 555 | } |
| 535 | 556 | ||
| 557 | self.tx.as_ref().map(|x| x.set_as_disconnected()); | ||
| 558 | self.cts.as_ref().map(|x| x.set_as_disconnected()); | ||
| 559 | self.de.as_ref().map(|x| x.set_as_disconnected()); | ||
| 536 | drop_tx_rx(self.info, state); | 560 | drop_tx_rx(self.info, state); |
| 537 | } | 561 | } |
| 538 | } | 562 | } |
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; | |||
| 14 | use futures_util::future::{select, Either}; | 14 | use futures_util::future::{select, Either}; |
| 15 | 15 | ||
| 16 | use crate::dma::ChannelAndRequest; | 16 | use crate::dma::ChannelAndRequest; |
| 17 | use crate::gpio::{AFType, AnyPin, SealedPin}; | 17 | use crate::gpio::{AFType, AnyPin, SealedPin as _}; |
| 18 | use crate::interrupt::typelevel::Interrupt as _; | 18 | use crate::interrupt::typelevel::Interrupt as _; |
| 19 | use crate::interrupt::{self, Interrupt, InterruptExt}; | 19 | use crate::interrupt::{self, Interrupt, InterruptExt}; |
| 20 | use crate::mode::{Async, Blocking, Mode}; | 20 | use crate::mode::{Async, Blocking, Mode}; |
| @@ -1233,9 +1233,8 @@ impl<'d, M: Mode> Uart<'d, M> { | |||
| 1233 | let info = T::info(); | 1233 | let info = T::info(); |
| 1234 | let state = T::state(); | 1234 | let state = T::state(); |
| 1235 | let kernel_clock = T::frequency(); | 1235 | let kernel_clock = T::frequency(); |
| 1236 | let r = info.regs; | ||
| 1237 | 1236 | ||
| 1238 | r.cr3().write(|w| { | 1237 | info.regs.cr3().write(|w| { |
| 1239 | w.set_rtse(rts.is_some()); | 1238 | w.set_rtse(rts.is_some()); |
| 1240 | w.set_ctse(cts.is_some()); | 1239 | w.set_ctse(cts.is_some()); |
| 1241 | #[cfg(not(any(usart_v1, usart_v2)))] | 1240 | #[cfg(not(any(usart_v1, usart_v2)))] |
