diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-11-06 17:08:16 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-11-06 17:08:16 +0000 |
| commit | dbba79179571251494ba1dab3640834dfbc93d5d (patch) | |
| tree | 0f96a220978e121311c06a7448e945b2cf10e674 | |
| parent | e1501a21a878a96ea5cc01f2ce5574a115a53193 (diff) | |
| parent | 72109a7bda5cf1568b1ff2b1b4b7de06f73d3342 (diff) | |
Merge pull request #3500 from KennethKnudsen97/main
Add split_ref for stm32 uart
| -rw-r--r-- | embassy-stm32/src/usart/buffered.rs | 79 | ||||
| -rw-r--r-- | embassy-stm32/src/usart/mod.rs | 7 |
2 files changed, 63 insertions, 23 deletions
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 7ba209063..f7b2bf4b4 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs | |||
| @@ -157,6 +157,7 @@ pub struct BufferedUartTx<'d> { | |||
| 157 | tx: Option<PeripheralRef<'d, AnyPin>>, | 157 | tx: Option<PeripheralRef<'d, AnyPin>>, |
| 158 | cts: Option<PeripheralRef<'d, AnyPin>>, | 158 | cts: Option<PeripheralRef<'d, AnyPin>>, |
| 159 | de: Option<PeripheralRef<'d, AnyPin>>, | 159 | de: Option<PeripheralRef<'d, AnyPin>>, |
| 160 | is_borrowed: bool, | ||
| 160 | } | 161 | } |
| 161 | 162 | ||
| 162 | /// Rx-only buffered UART | 163 | /// Rx-only buffered UART |
| @@ -168,6 +169,7 @@ pub struct BufferedUartRx<'d> { | |||
| 168 | kernel_clock: Hertz, | 169 | kernel_clock: Hertz, |
| 169 | rx: Option<PeripheralRef<'d, AnyPin>>, | 170 | rx: Option<PeripheralRef<'d, AnyPin>>, |
| 170 | rts: Option<PeripheralRef<'d, AnyPin>>, | 171 | rts: Option<PeripheralRef<'d, AnyPin>>, |
| 172 | is_borrowed: bool, | ||
| 171 | } | 173 | } |
| 172 | 174 | ||
| 173 | impl<'d> SetConfig for BufferedUart<'d> { | 175 | impl<'d> SetConfig for BufferedUart<'d> { |
| @@ -341,6 +343,7 @@ impl<'d> BufferedUart<'d> { | |||
| 341 | kernel_clock, | 343 | kernel_clock, |
| 342 | rx, | 344 | rx, |
| 343 | rts, | 345 | rts, |
| 346 | is_borrowed: false, | ||
| 344 | }, | 347 | }, |
| 345 | tx: BufferedUartTx { | 348 | tx: BufferedUartTx { |
| 346 | info, | 349 | info, |
| @@ -349,6 +352,7 @@ impl<'d> BufferedUart<'d> { | |||
| 349 | tx, | 352 | tx, |
| 350 | cts, | 353 | cts, |
| 351 | de, | 354 | de, |
| 355 | is_borrowed: false, | ||
| 352 | }, | 356 | }, |
| 353 | }; | 357 | }; |
| 354 | this.enable_and_configure(tx_buffer, rx_buffer, &config)?; | 358 | this.enable_and_configure(tx_buffer, rx_buffer, &config)?; |
| @@ -396,6 +400,31 @@ impl<'d> BufferedUart<'d> { | |||
| 396 | (self.tx, self.rx) | 400 | (self.tx, self.rx) |
| 397 | } | 401 | } |
| 398 | 402 | ||
| 403 | /// Split the Uart into a transmitter and receiver, | ||
| 404 | /// which is particularly useful when having two tasks correlating to | ||
| 405 | /// transmitting and receiving. | ||
| 406 | pub fn split_ref(&mut self) -> (BufferedUartTx<'_>, BufferedUartRx<'_>) { | ||
| 407 | ( | ||
| 408 | BufferedUartTx { | ||
| 409 | info: self.tx.info, | ||
| 410 | state: self.tx.state, | ||
| 411 | kernel_clock: self.tx.kernel_clock, | ||
| 412 | tx: self.tx.tx.as_mut().map(PeripheralRef::reborrow), | ||
| 413 | cts: self.tx.cts.as_mut().map(PeripheralRef::reborrow), | ||
| 414 | de: self.tx.de.as_mut().map(PeripheralRef::reborrow), | ||
| 415 | is_borrowed: true, | ||
| 416 | }, | ||
| 417 | BufferedUartRx { | ||
| 418 | info: self.rx.info, | ||
| 419 | state: self.rx.state, | ||
| 420 | kernel_clock: self.rx.kernel_clock, | ||
| 421 | rx: self.rx.rx.as_mut().map(PeripheralRef::reborrow), | ||
| 422 | rts: self.rx.rts.as_mut().map(PeripheralRef::reborrow), | ||
| 423 | is_borrowed: true, | ||
| 424 | }, | ||
| 425 | ) | ||
| 426 | } | ||
| 427 | |||
| 399 | /// Reconfigure the driver | 428 | /// Reconfigure the driver |
| 400 | pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { | 429 | pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { |
| 401 | reconfigure(self.rx.info, self.rx.kernel_clock, config)?; | 430 | reconfigure(self.rx.info, self.rx.kernel_clock, config)?; |
| @@ -600,40 +629,44 @@ impl<'d> BufferedUartTx<'d> { | |||
| 600 | 629 | ||
| 601 | impl<'d> Drop for BufferedUartRx<'d> { | 630 | impl<'d> Drop for BufferedUartRx<'d> { |
| 602 | fn drop(&mut self) { | 631 | fn drop(&mut self) { |
| 603 | let state = self.state; | 632 | if !self.is_borrowed { |
| 604 | unsafe { | 633 | let state = self.state; |
| 605 | state.rx_buf.deinit(); | 634 | unsafe { |
| 635 | state.rx_buf.deinit(); | ||
| 606 | 636 | ||
| 607 | // TX is inactive if the the buffer is not available. | 637 | // TX is inactive if the the buffer is not available. |
| 608 | // We can now unregister the interrupt handler | 638 | // We can now unregister the interrupt handler |
| 609 | if state.tx_buf.len() == 0 { | 639 | if state.tx_buf.len() == 0 { |
| 610 | self.info.interrupt.disable(); | 640 | self.info.interrupt.disable(); |
| 641 | } | ||
| 611 | } | 642 | } |
| 612 | } | ||
| 613 | 643 | ||
| 614 | self.rx.as_ref().map(|x| x.set_as_disconnected()); | 644 | self.rx.as_ref().map(|x| x.set_as_disconnected()); |
| 615 | self.rts.as_ref().map(|x| x.set_as_disconnected()); | 645 | self.rts.as_ref().map(|x| x.set_as_disconnected()); |
| 616 | drop_tx_rx(self.info, state); | 646 | drop_tx_rx(self.info, state); |
| 647 | } | ||
| 617 | } | 648 | } |
| 618 | } | 649 | } |
| 619 | 650 | ||
| 620 | impl<'d> Drop for BufferedUartTx<'d> { | 651 | impl<'d> Drop for BufferedUartTx<'d> { |
| 621 | fn drop(&mut self) { | 652 | fn drop(&mut self) { |
| 622 | let state = self.state; | 653 | if !self.is_borrowed { |
| 623 | unsafe { | 654 | let state = self.state; |
| 624 | state.tx_buf.deinit(); | 655 | unsafe { |
| 656 | state.tx_buf.deinit(); | ||
| 625 | 657 | ||
| 626 | // RX is inactive if the the buffer is not available. | 658 | // RX is inactive if the the buffer is not available. |
| 627 | // We can now unregister the interrupt handler | 659 | // We can now unregister the interrupt handler |
| 628 | if state.rx_buf.len() == 0 { | 660 | if state.rx_buf.len() == 0 { |
| 629 | self.info.interrupt.disable(); | 661 | self.info.interrupt.disable(); |
| 662 | } | ||
| 630 | } | 663 | } |
| 631 | } | ||
| 632 | 664 | ||
| 633 | self.tx.as_ref().map(|x| x.set_as_disconnected()); | 665 | self.tx.as_ref().map(|x| x.set_as_disconnected()); |
| 634 | self.cts.as_ref().map(|x| x.set_as_disconnected()); | 666 | self.cts.as_ref().map(|x| x.set_as_disconnected()); |
| 635 | self.de.as_ref().map(|x| x.set_as_disconnected()); | 667 | self.de.as_ref().map(|x| x.set_as_disconnected()); |
| 636 | drop_tx_rx(self.info, state); | 668 | drop_tx_rx(self.info, state); |
| 669 | } | ||
| 637 | } | 670 | } |
| 638 | } | 671 | } |
| 639 | 672 | ||
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 333e01e36..8152fc560 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs | |||
| @@ -1440,6 +1440,13 @@ impl<'d, M: Mode> Uart<'d, M> { | |||
| 1440 | (self.tx, self.rx) | 1440 | (self.tx, self.rx) |
| 1441 | } | 1441 | } |
| 1442 | 1442 | ||
| 1443 | /// Split the Uart into a transmitter and receiver by mutable reference, | ||
| 1444 | /// which is particularly useful when having two tasks correlating to | ||
| 1445 | /// transmitting and receiving. | ||
| 1446 | pub fn split_ref(&mut self) -> (&mut UartTx<'d, M>, &mut UartRx<'d, M>) { | ||
| 1447 | (&mut self.tx, &mut self.rx) | ||
| 1448 | } | ||
| 1449 | |||
| 1443 | /// Send break character | 1450 | /// Send break character |
| 1444 | pub fn send_break(&self) { | 1451 | pub fn send_break(&self) { |
| 1445 | self.tx.send_break(); | 1452 | self.tx.send_break(); |
