diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-07-02 00:58:54 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-07-02 00:58:54 +0000 |
| commit | d6e4086a15bbec4b448a56622b3cdb4c7ceea3f0 (patch) | |
| tree | e94d7dae04fe3c51d3a52f99702a9e2f404be6f4 /embassy-stm32 | |
| parent | c0cd851fb9bb33e774681a9d7d02b4cdb2c6bf7b (diff) | |
| parent | a862334daef1986d41d8873324821dfce37c70b6 (diff) | |
Merge pull request #3089 from qwerty19106/stm32_uart_half_fix_sequential_read_write
WIP: STM32 Half-Duplex: fix sequential reads and writes
Diffstat (limited to 'embassy-stm32')
| -rw-r--r-- | embassy-stm32/src/usart/mod.rs | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 5754f783e..7ed3793a1 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs | |||
| @@ -371,9 +371,12 @@ impl<'d> UartTx<'d, Async> { | |||
| 371 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { | 371 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 372 | let r = self.info.regs; | 372 | let r = self.info.regs; |
| 373 | 373 | ||
| 374 | // Disable Receiver for Half-Duplex mode | 374 | // Enable Transmitter and disable Receiver for Half-Duplex mode |
| 375 | if r.cr3().read().hdsel() { | 375 | let mut cr1 = r.cr1().read(); |
| 376 | r.cr1().modify(|reg| reg.set_re(false)); | 376 | if r.cr3().read().hdsel() && !cr1.te() { |
| 377 | cr1.set_te(true); | ||
| 378 | cr1.set_re(false); | ||
| 379 | r.cr1().write_value(cr1); | ||
| 377 | } | 380 | } |
| 378 | 381 | ||
| 379 | let ch = self.tx_dma.as_mut().unwrap(); | 382 | let ch = self.tx_dma.as_mut().unwrap(); |
| @@ -474,9 +477,12 @@ impl<'d, M: Mode> UartTx<'d, M> { | |||
| 474 | pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { | 477 | pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 475 | let r = self.info.regs; | 478 | let r = self.info.regs; |
| 476 | 479 | ||
| 477 | // Disable Receiver for Half-Duplex mode | 480 | // Enable Transmitter and disable Receiver for Half-Duplex mode |
| 478 | if r.cr3().read().hdsel() { | 481 | let mut cr1 = r.cr1().read(); |
| 479 | r.cr1().modify(|reg| reg.set_re(false)); | 482 | if r.cr3().read().hdsel() && !cr1.te() { |
| 483 | cr1.set_te(true); | ||
| 484 | cr1.set_re(false); | ||
| 485 | r.cr1().write_value(cr1); | ||
| 480 | } | 486 | } |
| 481 | 487 | ||
| 482 | for &b in buffer { | 488 | for &b in buffer { |
| @@ -561,8 +567,9 @@ impl<'d> UartRx<'d, Async> { | |||
| 561 | ) -> Result<ReadCompletionEvent, Error> { | 567 | ) -> Result<ReadCompletionEvent, Error> { |
| 562 | let r = self.info.regs; | 568 | let r = self.info.regs; |
| 563 | 569 | ||
| 564 | // Call flush for Half-Duplex mode. It prevents reading of bytes which have just been written. | 570 | // Call flush for Half-Duplex mode if some bytes were written and flush was not called. |
| 565 | if r.cr3().read().hdsel() { | 571 | // It prevents reading of bytes which have just been written. |
| 572 | if r.cr3().read().hdsel() && r.cr1().read().te() { | ||
| 566 | blocking_flush(self.info)?; | 573 | blocking_flush(self.info)?; |
| 567 | } | 574 | } |
| 568 | 575 | ||
| @@ -898,8 +905,9 @@ impl<'d, M: Mode> UartRx<'d, M> { | |||
| 898 | pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { | 905 | pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { |
| 899 | let r = self.info.regs; | 906 | let r = self.info.regs; |
| 900 | 907 | ||
| 901 | // Call flush for Half-Duplex mode. It prevents reading of bytes which have just been written. | 908 | // Call flush for Half-Duplex mode if some bytes were written and flush was not called. |
| 902 | if r.cr3().read().hdsel() { | 909 | // It prevents reading of bytes which have just been written. |
| 910 | if r.cr3().read().hdsel() && r.cr1().read().te() { | ||
| 903 | blocking_flush(self.info)?; | 911 | blocking_flush(self.info)?; |
| 904 | } | 912 | } |
| 905 | 913 | ||
| @@ -1481,10 +1489,19 @@ fn configure( | |||
| 1481 | r.cr1().write(|w| { | 1489 | r.cr1().write(|w| { |
| 1482 | // enable uart | 1490 | // enable uart |
| 1483 | w.set_ue(true); | 1491 | w.set_ue(true); |
| 1484 | // enable transceiver | 1492 | |
| 1485 | w.set_te(enable_tx); | 1493 | if config.half_duplex { |
| 1486 | // enable receiver | 1494 | // The te and re bits will be set by write, read and flush methods. |
| 1487 | w.set_re(enable_rx); | 1495 | // Receiver should be enabled by default for Half-Duplex. |
| 1496 | w.set_te(false); | ||
| 1497 | w.set_re(true); | ||
| 1498 | } else { | ||
| 1499 | // enable transceiver | ||
| 1500 | w.set_te(enable_tx); | ||
| 1501 | // enable receiver | ||
| 1502 | w.set_re(enable_rx); | ||
| 1503 | } | ||
| 1504 | |||
| 1488 | // configure word size | 1505 | // configure word size |
| 1489 | // if using odd or even parity it must be configured to 9bits | 1506 | // if using odd or even parity it must be configured to 9bits |
| 1490 | w.set_m0(if config.parity != Parity::ParityNone { | 1507 | w.set_m0(if config.parity != Parity::ParityNone { |
