aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2023-04-30 14:58:36 +0000
committerGitHub <[email protected]>2023-04-30 14:58:36 +0000
commit41fe718ea83748c23884aede3d78a60bea8fd731 (patch)
tree3d3974e0fd391ac35a2c358138fc6a8985b17540
parent94c6727b3fccd39093eb6eb61d8505f63b082d2c (diff)
parentb77794c9a70d35ea027454a678ac24e215a62c13 (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.rs32
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