diff options
| -rw-r--r-- | embassy-stm32/src/usart/buffered.rs | 68 | ||||
| -rw-r--r-- | 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::{ | |||
| 16 | Regs, RtsPin, RxPin, TxPin, | 16 | Regs, RtsPin, RxPin, TxPin, |
| 17 | }; | 17 | }; |
| 18 | use crate::gpio::{AFType, AnyPin, SealedPin as _}; | 18 | use crate::gpio::{AFType, AnyPin, SealedPin as _}; |
| 19 | use crate::interrupt::typelevel::Interrupt as _; | ||
| 20 | use crate::interrupt::{self, InterruptExt}; | 19 | use crate::interrupt::{self, InterruptExt}; |
| 21 | use crate::rcc; | ||
| 22 | use crate::time::Hertz; | 20 | use crate::time::Hertz; |
| 23 | 21 | ||
| 24 | /// Interrupt handler. | 22 | /// Interrupt handler. |
| @@ -284,35 +282,11 @@ impl<'d> BufferedUart<'d> { | |||
| 284 | rx_buffer: &'d mut [u8], | 282 | rx_buffer: &'d mut [u8], |
| 285 | config: Config, | 283 | config: Config, |
| 286 | ) -> Result<Self, ConfigError> { | 284 | ) -> Result<Self, ConfigError> { |
| 287 | rcc::enable_and_reset::<T>(); | ||
| 288 | |||
| 289 | let info = T::info(); | 285 | let info = T::info(); |
| 290 | let state = T::buffered_state(); | 286 | let state = T::buffered_state(); |
| 291 | let kernel_clock = T::frequency(); | 287 | let kernel_clock = T::frequency(); |
| 292 | let len = tx_buffer.len(); | ||
| 293 | unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; | ||
| 294 | let len = rx_buffer.len(); | ||
| 295 | unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; | ||
| 296 | 288 | ||
| 297 | info.regs.cr3().write(|w| { | 289 | let mut this = Self { |
| 298 | w.set_rtse(rts.is_some()); | ||
| 299 | w.set_ctse(cts.is_some()); | ||
| 300 | #[cfg(not(any(usart_v1, usart_v2)))] | ||
| 301 | w.set_dem(de.is_some()); | ||
| 302 | }); | ||
| 303 | configure(info, kernel_clock, &config, true, true)?; | ||
| 304 | |||
| 305 | info.regs.cr1().modify(|w| { | ||
| 306 | w.set_rxneie(true); | ||
| 307 | w.set_idleie(true); | ||
| 308 | }); | ||
| 309 | |||
| 310 | T::Interrupt::unpend(); | ||
| 311 | unsafe { T::Interrupt::enable() }; | ||
| 312 | |||
| 313 | state.tx_rx_refcount.store(2, Ordering::Relaxed); | ||
| 314 | |||
| 315 | Ok(Self { | ||
| 316 | rx: BufferedUartRx { | 290 | rx: BufferedUartRx { |
| 317 | info, | 291 | info, |
| 318 | state, | 292 | state, |
| @@ -328,7 +302,45 @@ impl<'d> BufferedUart<'d> { | |||
| 328 | cts, | 302 | cts, |
| 329 | de, | 303 | de, |
| 330 | }, | 304 | }, |
| 331 | }) | 305 | }; |
| 306 | this.enable_and_configure(tx_buffer, rx_buffer, &config)?; | ||
| 307 | Ok(this) | ||
| 308 | } | ||
| 309 | |||
| 310 | fn enable_and_configure( | ||
| 311 | &mut self, | ||
| 312 | tx_buffer: &'d mut [u8], | ||
| 313 | rx_buffer: &'d mut [u8], | ||
| 314 | config: &Config, | ||
| 315 | ) -> Result<(), ConfigError> { | ||
| 316 | let info = self.rx.info; | ||
| 317 | let state = self.rx.state; | ||
| 318 | |||
| 319 | info.rcc.enable_and_reset(); | ||
| 320 | |||
| 321 | let len = tx_buffer.len(); | ||
| 322 | unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; | ||
| 323 | let len = rx_buffer.len(); | ||
| 324 | unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; | ||
| 325 | |||
| 326 | info.regs.cr3().write(|w| { | ||
| 327 | w.set_rtse(self.rx.rts.is_some()); | ||
| 328 | w.set_ctse(self.tx.cts.is_some()); | ||
| 329 | #[cfg(not(any(usart_v1, usart_v2)))] | ||
| 330 | w.set_dem(self.tx.de.is_some()); | ||
| 331 | }); | ||
| 332 | configure(info, self.rx.kernel_clock, &config, true, true)?; | ||
| 333 | |||
| 334 | info.regs.cr1().modify(|w| { | ||
| 335 | w.set_rxneie(true); | ||
| 336 | w.set_idleie(true); | ||
| 337 | }); | ||
| 338 | |||
| 339 | info.interrupt.unpend(); | ||
| 340 | unsafe { info.interrupt.enable() }; | ||
| 341 | |||
| 342 | state.tx_rx_refcount.store(2, Ordering::Relaxed); | ||
| 343 | Ok(()) | ||
| 332 | } | 344 | } |
| 333 | 345 | ||
| 334 | /// Split the driver into a Tx and Rx part (useful for sending to separate tasks) | 346 | /// 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; | |||
| 28 | #[cfg(any(usart_v1, usart_v2))] | 28 | #[cfg(any(usart_v1, usart_v2))] |
| 29 | use crate::pac::usart::Usart as Regs; | 29 | use crate::pac::usart::Usart as Regs; |
| 30 | use crate::pac::usart::{regs, vals}; | 30 | use crate::pac::usart::{regs, vals}; |
| 31 | use crate::rcc::{self, RccInfo, SealedRccPeripheral}; | 31 | use crate::rcc::{RccInfo, SealedRccPeripheral}; |
| 32 | use crate::time::Hertz; | 32 | use crate::time::Hertz; |
| 33 | use crate::Peripheral; | 33 | use crate::Peripheral; |
| 34 | 34 | ||
| @@ -429,29 +429,33 @@ impl<'d, M: Mode> UartTx<'d, M> { | |||
| 429 | tx_dma: Option<ChannelAndRequest<'d>>, | 429 | tx_dma: Option<ChannelAndRequest<'d>>, |
| 430 | config: Config, | 430 | config: Config, |
| 431 | ) -> Result<Self, ConfigError> { | 431 | ) -> Result<Self, ConfigError> { |
| 432 | rcc::enable_and_reset::<T>(); | 432 | let mut this = Self { |
| 433 | 433 | info: T::info(), | |
| 434 | let info = T::info(); | 434 | state: T::state(), |
| 435 | let state = T::state(); | 435 | kernel_clock: T::frequency(), |
| 436 | let kernel_clock = T::frequency(); | ||
| 437 | let r = info.regs; | ||
| 438 | r.cr3().modify(|w| { | ||
| 439 | w.set_ctse(cts.is_some()); | ||
| 440 | }); | ||
| 441 | configure(info, kernel_clock, &config, false, true)?; | ||
| 442 | |||
| 443 | state.tx_rx_refcount.store(1, Ordering::Relaxed); | ||
| 444 | |||
| 445 | Ok(Self { | ||
| 446 | info, | ||
| 447 | state, | ||
| 448 | kernel_clock, | ||
| 449 | tx, | 436 | tx, |
| 450 | cts, | 437 | cts, |
| 451 | de: None, | 438 | de: None, |
| 452 | tx_dma, | 439 | tx_dma, |
| 453 | _phantom: PhantomData, | 440 | _phantom: PhantomData, |
| 454 | }) | 441 | }; |
| 442 | this.enable_and_configure(&config)?; | ||
| 443 | Ok(this) | ||
| 444 | } | ||
| 445 | |||
| 446 | fn enable_and_configure(&mut self, config: &Config) -> Result<(), ConfigError> { | ||
| 447 | let info = self.info; | ||
| 448 | let state = self.state; | ||
| 449 | |||
| 450 | info.rcc.enable_and_reset(); | ||
| 451 | |||
| 452 | info.regs.cr3().modify(|w| { | ||
| 453 | w.set_ctse(self.cts.is_some()); | ||
| 454 | }); | ||
| 455 | configure(info, self.kernel_clock, config, false, true)?; | ||
| 456 | |||
| 457 | state.tx_rx_refcount.store(1, Ordering::Relaxed); | ||
| 458 | Ok(()) | ||
| 455 | } | 459 | } |
| 456 | 460 | ||
| 457 | /// Reconfigure the driver | 461 | /// Reconfigure the driver |
| @@ -775,34 +779,38 @@ impl<'d, M: Mode> UartRx<'d, M> { | |||
| 775 | rx_dma: Option<ChannelAndRequest<'d>>, | 779 | rx_dma: Option<ChannelAndRequest<'d>>, |
| 776 | config: Config, | 780 | config: Config, |
| 777 | ) -> Result<Self, ConfigError> { | 781 | ) -> Result<Self, ConfigError> { |
| 778 | rcc::enable_and_reset::<T>(); | 782 | let mut this = Self { |
| 779 | |||
| 780 | let info = T::info(); | ||
| 781 | let state = T::state(); | ||
| 782 | let kernel_clock = T::frequency(); | ||
| 783 | let r = info.regs; | ||
| 784 | r.cr3().write(|w| { | ||
| 785 | w.set_rtse(rts.is_some()); | ||
| 786 | }); | ||
| 787 | configure(info, kernel_clock, &config, true, false)?; | ||
| 788 | |||
| 789 | T::Interrupt::unpend(); | ||
| 790 | unsafe { T::Interrupt::enable() }; | ||
| 791 | |||
| 792 | state.tx_rx_refcount.store(1, Ordering::Relaxed); | ||
| 793 | |||
| 794 | Ok(Self { | ||
| 795 | _phantom: PhantomData, | 783 | _phantom: PhantomData, |
| 796 | info, | 784 | info: T::info(), |
| 797 | state, | 785 | state: T::state(), |
| 798 | kernel_clock, | 786 | kernel_clock: T::frequency(), |
| 799 | rx, | 787 | rx, |
| 800 | rts, | 788 | rts, |
| 801 | rx_dma, | 789 | rx_dma, |
| 802 | detect_previous_overrun: config.detect_previous_overrun, | 790 | detect_previous_overrun: config.detect_previous_overrun, |
| 803 | #[cfg(any(usart_v1, usart_v2))] | 791 | #[cfg(any(usart_v1, usart_v2))] |
| 804 | buffered_sr: stm32_metapac::usart::regs::Sr(0), | 792 | buffered_sr: stm32_metapac::usart::regs::Sr(0), |
| 805 | }) | 793 | }; |
| 794 | this.enable_and_configure(&config)?; | ||
| 795 | Ok(this) | ||
| 796 | } | ||
| 797 | |||
| 798 | fn enable_and_configure(&mut self, config: &Config) -> Result<(), ConfigError> { | ||
| 799 | let info = self.info; | ||
| 800 | let state = self.state; | ||
| 801 | |||
| 802 | info.rcc.enable_and_reset(); | ||
| 803 | |||
| 804 | info.regs.cr3().write(|w| { | ||
| 805 | w.set_rtse(self.rts.is_some()); | ||
| 806 | }); | ||
| 807 | configure(info, self.kernel_clock, &config, true, false)?; | ||
| 808 | |||
| 809 | info.interrupt.unpend(); | ||
| 810 | unsafe { info.interrupt.enable() }; | ||
| 811 | |||
| 812 | state.tx_rx_refcount.store(1, Ordering::Relaxed); | ||
| 813 | Ok(()) | ||
| 806 | } | 814 | } |
| 807 | 815 | ||
| 808 | /// Reconfigure the driver | 816 | /// Reconfigure the driver |
| @@ -1228,26 +1236,11 @@ impl<'d, M: Mode> Uart<'d, M> { | |||
| 1228 | rx_dma: Option<ChannelAndRequest<'d>>, | 1236 | rx_dma: Option<ChannelAndRequest<'d>>, |
| 1229 | config: Config, | 1237 | config: Config, |
| 1230 | ) -> Result<Self, ConfigError> { | 1238 | ) -> Result<Self, ConfigError> { |
| 1231 | rcc::enable_and_reset::<T>(); | ||
| 1232 | |||
| 1233 | let info = T::info(); | 1239 | let info = T::info(); |
| 1234 | let state = T::state(); | 1240 | let state = T::state(); |
| 1235 | let kernel_clock = T::frequency(); | 1241 | let kernel_clock = T::frequency(); |
| 1236 | 1242 | ||
| 1237 | info.regs.cr3().write(|w| { | 1243 | let mut this = Self { |
| 1238 | w.set_rtse(rts.is_some()); | ||
| 1239 | w.set_ctse(cts.is_some()); | ||
| 1240 | #[cfg(not(any(usart_v1, usart_v2)))] | ||
| 1241 | w.set_dem(de.is_some()); | ||
| 1242 | }); | ||
| 1243 | configure(info, kernel_clock, &config, true, true)?; | ||
| 1244 | |||
| 1245 | T::Interrupt::unpend(); | ||
| 1246 | unsafe { T::Interrupt::enable() }; | ||
| 1247 | |||
| 1248 | state.tx_rx_refcount.store(2, Ordering::Relaxed); | ||
| 1249 | |||
| 1250 | Ok(Self { | ||
| 1251 | tx: UartTx { | 1244 | tx: UartTx { |
| 1252 | _phantom: PhantomData, | 1245 | _phantom: PhantomData, |
| 1253 | info, | 1246 | info, |
| @@ -1270,7 +1263,30 @@ impl<'d, M: Mode> Uart<'d, M> { | |||
| 1270 | #[cfg(any(usart_v1, usart_v2))] | 1263 | #[cfg(any(usart_v1, usart_v2))] |
| 1271 | buffered_sr: stm32_metapac::usart::regs::Sr(0), | 1264 | buffered_sr: stm32_metapac::usart::regs::Sr(0), |
| 1272 | }, | 1265 | }, |
| 1273 | }) | 1266 | }; |
| 1267 | this.enable_and_configure(&config)?; | ||
| 1268 | Ok(this) | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | fn enable_and_configure(&mut self, config: &Config) -> Result<(), ConfigError> { | ||
| 1272 | let info = self.rx.info; | ||
| 1273 | let state = self.rx.state; | ||
| 1274 | |||
| 1275 | info.rcc.enable_and_reset(); | ||
| 1276 | |||
| 1277 | info.regs.cr3().write(|w| { | ||
| 1278 | w.set_rtse(self.rx.rts.is_some()); | ||
| 1279 | w.set_ctse(self.tx.cts.is_some()); | ||
| 1280 | #[cfg(not(any(usart_v1, usart_v2)))] | ||
| 1281 | w.set_dem(self.tx.de.is_some()); | ||
| 1282 | }); | ||
| 1283 | configure(info, self.rx.kernel_clock, config, true, true)?; | ||
| 1284 | |||
| 1285 | info.interrupt.unpend(); | ||
| 1286 | unsafe { info.interrupt.enable() }; | ||
| 1287 | |||
| 1288 | state.tx_rx_refcount.store(2, Ordering::Relaxed); | ||
| 1289 | Ok(()) | ||
| 1274 | } | 1290 | } |
| 1275 | 1291 | ||
| 1276 | /// Perform a blocking write | 1292 | /// Perform a blocking write |
