aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Špaček <[email protected]>2024-05-26 16:37:26 +0200
committerJan Špaček <[email protected]>2024-06-01 19:46:39 +0200
commit44e4a2c9e9c1e5824acb68673c8f6b4b98d1ea07 (patch)
treecb690564bba8644b61d5a4868c998dcdf817d091
parentade27b7f212f9548816e5ae21826a230c2345574 (diff)
stm32/buffered-usart: use new_pin! and disconnect pins on drop
-rw-r--r--embassy-stm32/src/usart/buffered.rs102
-rw-r--r--embassy-stm32/src/usart/mod.rs5
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
7use embassy_embedded_hal::SetConfig; 7use embassy_embedded_hal::SetConfig;
8use embassy_hal_internal::atomic_ring_buffer::RingBuffer; 8use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
9use embassy_hal_internal::{into_ref, Peripheral}; 9use embassy_hal_internal::{Peripheral, PeripheralRef};
10use embassy_sync::waitqueue::AtomicWaker; 10use 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};
18use crate::gpio::AFType; 18use crate::gpio::{AFType, AnyPin, SealedPin as _};
19use crate::interrupt::typelevel::Interrupt as _; 19use crate::interrupt::typelevel::Interrupt as _;
20use crate::interrupt::{self, InterruptExt}; 20use crate::interrupt::{self, InterruptExt};
21use crate::rcc; 21use 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
172impl<'d> SetConfig for BufferedUart<'d> { 175impl<'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;
14use futures_util::future::{select, Either}; 14use futures_util::future::{select, Either};
15 15
16use crate::dma::ChannelAndRequest; 16use crate::dma::ChannelAndRequest;
17use crate::gpio::{AFType, AnyPin, SealedPin}; 17use crate::gpio::{AFType, AnyPin, SealedPin as _};
18use crate::interrupt::typelevel::Interrupt as _; 18use crate::interrupt::typelevel::Interrupt as _;
19use crate::interrupt::{self, Interrupt, InterruptExt}; 19use crate::interrupt::{self, Interrupt, InterruptExt};
20use crate::mode::{Async, Blocking, Mode}; 20use 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)))]