diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-06-18 10:40:22 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-06-18 10:40:22 +0000 |
| commit | adaed307b4d81ed09611e496524b1d96ad04c60d (patch) | |
| tree | 0253e5113b90cd4ceaff3a0bb889d3e0839b68fa | |
| parent | ae83e6f5367197feb8361b9a28adbdedbe37e0c5 (diff) | |
| parent | b4f96e192cd8c86f437e1d155388a860dcd3e1fd (diff) | |
Merge pull request #1561 from petegibson/stm32-buffereduart-int-flags-fix
Ensure idle & ove flags are cleared in BufferedUart ISR on STM32
| -rw-r--r-- | embassy-stm32/src/usart/buffered.rs | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 613da5674..086196a2c 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs | |||
| @@ -21,27 +21,33 @@ impl<T: BasicInstance> interrupt::typelevel::Handler<T::Interrupt> for Interrupt | |||
| 21 | // RX | 21 | // RX |
| 22 | unsafe { | 22 | unsafe { |
| 23 | let sr = sr(r).read(); | 23 | let sr = sr(r).read(); |
| 24 | // On v1 & v2, reading DR clears the rxne, error and idle interrupt | ||
| 25 | // flags. Keep this close to the SR read to reduce the chance of a | ||
| 26 | // flag being set in-between. | ||
| 27 | let dr = if sr.rxne() || cfg!(any(usart_v1, usart_v2)) && (sr.ore() || sr.idle()) { | ||
| 28 | Some(rdr(r).read_volatile()) | ||
| 29 | } else { | ||
| 30 | None | ||
| 31 | }; | ||
| 24 | clear_interrupt_flags(r, sr); | 32 | clear_interrupt_flags(r, sr); |
| 25 | 33 | ||
| 34 | if sr.pe() { | ||
| 35 | warn!("Parity error"); | ||
| 36 | } | ||
| 37 | if sr.fe() { | ||
| 38 | warn!("Framing error"); | ||
| 39 | } | ||
| 40 | if sr.ne() { | ||
| 41 | warn!("Noise error"); | ||
| 42 | } | ||
| 43 | if sr.ore() { | ||
| 44 | warn!("Overrun error"); | ||
| 45 | } | ||
| 26 | if sr.rxne() { | 46 | if sr.rxne() { |
| 27 | if sr.pe() { | ||
| 28 | warn!("Parity error"); | ||
| 29 | } | ||
| 30 | if sr.fe() { | ||
| 31 | warn!("Framing error"); | ||
| 32 | } | ||
| 33 | if sr.ne() { | ||
| 34 | warn!("Noise error"); | ||
| 35 | } | ||
| 36 | if sr.ore() { | ||
| 37 | warn!("Overrun error"); | ||
| 38 | } | ||
| 39 | |||
| 40 | let mut rx_writer = state.rx_buf.writer(); | 47 | let mut rx_writer = state.rx_buf.writer(); |
| 41 | let buf = rx_writer.push_slice(); | 48 | let buf = rx_writer.push_slice(); |
| 42 | if !buf.is_empty() { | 49 | if !buf.is_empty() { |
| 43 | // This read also clears the error and idle interrupt flags on v1. | 50 | buf[0] = dr.unwrap(); |
| 44 | buf[0] = rdr(r).read_volatile(); | ||
| 45 | rx_writer.push_done(1); | 51 | rx_writer.push_done(1); |
| 46 | } else { | 52 | } else { |
| 47 | // FIXME: Should we disable any further RX interrupts when the buffer becomes full. | 53 | // FIXME: Should we disable any further RX interrupts when the buffer becomes full. |
| @@ -54,7 +60,7 @@ impl<T: BasicInstance> interrupt::typelevel::Handler<T::Interrupt> for Interrupt | |||
| 54 | 60 | ||
| 55 | if sr.idle() { | 61 | if sr.idle() { |
| 56 | state.rx_waker.wake(); | 62 | state.rx_waker.wake(); |
| 57 | }; | 63 | } |
| 58 | } | 64 | } |
| 59 | 65 | ||
| 60 | // TX | 66 | // TX |
