@@ -41,7 +41,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
41
41
unsafe fn on_interrupt ( r : Regs , s : & ' static State ) {
42
42
let ( sr, cr1, cr3) = ( sr ( r) . read ( ) , r. cr1 ( ) . read ( ) , r. cr3 ( ) . read ( ) ) ;
43
43
44
- let has_errors = ( sr. pe ( ) && cr1. peie ( ) ) || ( ( sr. fe ( ) || sr. ne ( ) || sr. ore ( ) ) && cr3. eie ( ) ) ;
44
+ let has_errors = ( sr. pe ( ) && cr1. peie ( ) ) || ( ( sr. ne ( ) || sr. ore ( ) ) && cr3 . eie ( ) ) || ( sr. fe ( ) && cr3. eie ( ) && cr3 . dmar ( ) ) ;
45
45
if has_errors {
46
46
// clear all interrupts and DMA Rx Request
47
47
r. cr1 ( ) . modify ( |w| {
@@ -74,6 +74,13 @@ unsafe fn on_interrupt(r: Regs, s: &'static State) {
74
74
// We cannot check the RXNE flag as it is auto-cleared by the DMA controller
75
75
76
76
// It is up to the listener to determine if this in fact was a RX event and disable the RXNE detection
77
+ } else if sr. fe ( ) && cr3. eie ( ) {
78
+ // Break detected (frame error)
79
+ if sr. fe ( ) {
80
+ r. icr ( ) . write ( |w| w. set_fe ( true ) ) ; // clear framing error
81
+ unsafe { rdr ( r) . read_volatile ( ) } ; // clear byte so DMA doesn't pick it up
82
+ r. cr3 ( ) . modify ( |w| w. set_dmar ( true ) ) ; // start DMA
83
+ }
77
84
} else {
78
85
return ;
79
86
}
@@ -692,20 +699,27 @@ impl<'d> UartRx<'d, Async> {
692
699
693
700
/// Initiate an asynchronous UART read
694
701
pub async fn read ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
695
- self . inner_read ( buffer, false ) . await ?;
702
+ self . inner_read ( buffer, false , false ) . await ?;
696
703
697
704
Ok ( ( ) )
698
705
}
699
706
700
707
/// Initiate an asynchronous read with idle line detection enabled
701
708
pub async fn read_until_idle ( & mut self , buffer : & mut [ u8 ] ) -> Result < usize , Error > {
702
- self . inner_read ( buffer, true ) . await
709
+ self . inner_read ( buffer, true , false ) . await
710
+ }
711
+
712
+ /// Initiate an asynchronous read, waiting for a break character (frame error) before starting the read
713
+ /// Returns Err(Framing) if a second break occurs before buffer.len() characters have been received.
714
+ pub async fn read_from_break ( & mut self , buffer : & mut [ u8 ] ) -> Result < usize , Error > {
715
+ self . inner_read ( buffer, false , true ) . await
703
716
}
704
717
705
718
async fn inner_read_run (
706
719
& mut self ,
707
720
buffer : & mut [ u8 ] ,
708
721
enable_idle_line_detection : bool ,
722
+ wait_for_break : bool ,
709
723
) -> Result < ReadCompletionEvent , Error > {
710
724
let r = self . info . regs ;
711
725
@@ -767,8 +781,8 @@ impl<'d> UartRx<'d, Async> {
767
781
r. cr3 ( ) . modify ( |w| {
768
782
// enable Error Interrupt: (Frame error, Noise error, Overrun error)
769
783
w. set_eie ( true ) ;
770
- // enable DMA Rx Request
771
- w. set_dmar ( true ) ;
784
+ // enable DMA Rx Request unless waiting for break first
785
+ if !wait_for_break { w. set_dmar ( true ) ; }
772
786
} ) ;
773
787
774
788
compiler_fence ( Ordering :: SeqCst ) ;
@@ -779,7 +793,7 @@ impl<'d> UartRx<'d, Async> {
779
793
780
794
let cr3 = r. cr3 ( ) . read ( ) ;
781
795
782
- if !cr3. dmar ( ) {
796
+ if !wait_for_break && ! cr3. dmar ( ) {
783
797
// something went wrong
784
798
// because the only way to get this flag cleared is to have an interrupt
785
799
@@ -841,7 +855,7 @@ impl<'d> UartRx<'d, Async> {
841
855
842
856
compiler_fence ( Ordering :: SeqCst ) ;
843
857
844
- let has_errors = sr. pe ( ) || sr. fe ( ) || sr. ne ( ) || sr. ore ( ) ;
858
+ let has_errors = sr. pe ( ) || sr. ne ( ) || sr. fe ( ) || ( sr. ore ( ) && !wait_for_break ) ;
845
859
846
860
if has_errors {
847
861
// all Rx interrupts and Rx DMA Request have already been cleared in interrupt handler
@@ -889,7 +903,7 @@ impl<'d> UartRx<'d, Async> {
889
903
r
890
904
}
891
905
892
- async fn inner_read ( & mut self , buffer : & mut [ u8 ] , enable_idle_line_detection : bool ) -> Result < usize , Error > {
906
+ async fn inner_read ( & mut self , buffer : & mut [ u8 ] , enable_idle_line_detection : bool , wait_for_break : bool ) -> Result < usize , Error > {
893
907
if buffer. is_empty ( ) {
894
908
return Ok ( 0 ) ;
895
909
} else if buffer. len ( ) > 0xFFFF {
@@ -899,7 +913,7 @@ impl<'d> UartRx<'d, Async> {
899
913
let buffer_len = buffer. len ( ) ;
900
914
901
915
// wait for DMA to complete or IDLE line detection if requested
902
- let res = self . inner_read_run ( buffer, enable_idle_line_detection) . await ;
916
+ let res = self . inner_read_run ( buffer, enable_idle_line_detection, wait_for_break ) . await ;
903
917
904
918
match res {
905
919
Ok ( ReadCompletionEvent :: DmaCompleted ) => Ok ( buffer_len) ,
0 commit comments