diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2023-04-30 14:58:36 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-04-30 14:58:36 +0000 |
| commit | 41fe718ea83748c23884aede3d78a60bea8fd731 (patch) | |
| tree | 3d3974e0fd391ac35a2c358138fc6a8985b17540 | |
| parent | 94c6727b3fccd39093eb6eb61d8505f63b082d2c (diff) | |
| parent | b77794c9a70d35ea027454a678ac24e215a62c13 (diff) | |
Merge #1412
1412: stm32/uart: abort on error r=Dirbaio a=xoviat
This PR aborts the DMA transfer in the event of a UART error. Otherwise, the transfer will never complete, and an error will not be returned.
Co-authored-by: xoviat <[email protected]>
| -rw-r--r-- | embassy-stm32/src/usart/mod.rs | 32 |
1 files changed, 14 insertions, 18 deletions
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index b8656b586..266561659 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs | |||
| @@ -497,28 +497,24 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { | |||
| 497 | unreachable!(); | 497 | unreachable!(); |
| 498 | } | 498 | } |
| 499 | 499 | ||
| 500 | if !enable_idle_line_detection { | 500 | if enable_idle_line_detection { |
| 501 | transfer.await; | 501 | // clear idle flag |
| 502 | let sr = sr(r).read(); | ||
| 503 | // This read also clears the error and idle interrupt flags on v1. | ||
| 504 | rdr(r).read_volatile(); | ||
| 505 | clear_interrupt_flags(r, sr); | ||
| 502 | 506 | ||
| 503 | return Ok(ReadCompletionEvent::DmaCompleted); | 507 | // enable idle interrupt |
| 508 | r.cr1().modify(|w| { | ||
| 509 | w.set_idleie(true); | ||
| 510 | }); | ||
| 504 | } | 511 | } |
| 505 | |||
| 506 | // clear idle flag | ||
| 507 | let sr = sr(r).read(); | ||
| 508 | // This read also clears the error and idle interrupt flags on v1. | ||
| 509 | rdr(r).read_volatile(); | ||
| 510 | clear_interrupt_flags(r, sr); | ||
| 511 | |||
| 512 | // enable idle interrupt | ||
| 513 | r.cr1().modify(|w| { | ||
| 514 | w.set_idleie(true); | ||
| 515 | }); | ||
| 516 | } | 512 | } |
| 517 | 513 | ||
| 518 | compiler_fence(Ordering::SeqCst); | 514 | compiler_fence(Ordering::SeqCst); |
| 519 | 515 | ||
| 520 | // future which completes when idle line is detected | 516 | // future which completes when idle line or error is detected |
| 521 | let idle = poll_fn(move |cx| { | 517 | let abort = poll_fn(move |cx| { |
| 522 | let s = T::state(); | 518 | let s = T::state(); |
| 523 | 519 | ||
| 524 | s.rx_waker.register(cx.waker()); | 520 | s.rx_waker.register(cx.waker()); |
| @@ -554,7 +550,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { | |||
| 554 | } | 550 | } |
| 555 | } | 551 | } |
| 556 | 552 | ||
| 557 | if sr.idle() { | 553 | if enable_idle_line_detection && sr.idle() { |
| 558 | // Idle line detected | 554 | // Idle line detected |
| 559 | return Poll::Ready(Ok(())); | 555 | return Poll::Ready(Ok(())); |
| 560 | } | 556 | } |
| @@ -565,7 +561,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { | |||
| 565 | // wait for the first of DMA request or idle line detected to completes | 561 | // wait for the first of DMA request or idle line detected to completes |
| 566 | // select consumes its arguments | 562 | // select consumes its arguments |
| 567 | // when transfer is dropped, it will stop the DMA request | 563 | // when transfer is dropped, it will stop the DMA request |
| 568 | let r = match select(transfer, idle).await { | 564 | let r = match select(transfer, abort).await { |
| 569 | // DMA transfer completed first | 565 | // DMA transfer completed first |
| 570 | Either::Left(((), _)) => Ok(ReadCompletionEvent::DmaCompleted), | 566 | Either::Left(((), _)) => Ok(ReadCompletionEvent::DmaCompleted), |
| 571 | 567 | ||
