@@ -41,7 +41,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
4141unsafe fn on_interrupt ( r : Regs , s : & ' static State ) {
4242 let ( sr, cr1, cr3) = ( sr ( r) . read ( ) , r. cr1 ( ) . read ( ) , r. cr3 ( ) . read ( ) ) ;
4343
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 ( ) ) ;
4545 if has_errors {
4646 // clear all interrupts and DMA Rx Request
4747 r. cr1 ( ) . modify ( |w| {
@@ -74,6 +74,13 @@ unsafe fn on_interrupt(r: Regs, s: &'static State) {
7474 // We cannot check the RXNE flag as it is auto-cleared by the DMA controller
7575
7676 // 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+ }
7784 } else {
7885 return ;
7986 }
@@ -692,20 +699,27 @@ impl<'d> UartRx<'d, Async> {
692699
693700 /// Initiate an asynchronous UART read
694701 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 ?;
696703
697704 Ok ( ( ) )
698705 }
699706
700707 /// Initiate an asynchronous read with idle line detection enabled
701708 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
703716 }
704717
705718 async fn inner_read_run (
706719 & mut self ,
707720 buffer : & mut [ u8 ] ,
708721 enable_idle_line_detection : bool ,
722+ wait_for_break : bool ,
709723 ) -> Result < ReadCompletionEvent , Error > {
710724 let r = self . info . regs ;
711725
@@ -767,8 +781,8 @@ impl<'d> UartRx<'d, Async> {
767781 r. cr3 ( ) . modify ( |w| {
768782 // enable Error Interrupt: (Frame error, Noise error, Overrun error)
769783 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 ) ; }
772786 } ) ;
773787
774788 compiler_fence ( Ordering :: SeqCst ) ;
@@ -779,7 +793,7 @@ impl<'d> UartRx<'d, Async> {
779793
780794 let cr3 = r. cr3 ( ) . read ( ) ;
781795
782- if !cr3. dmar ( ) {
796+ if !wait_for_break && ! cr3. dmar ( ) {
783797 // something went wrong
784798 // because the only way to get this flag cleared is to have an interrupt
785799
@@ -841,7 +855,7 @@ impl<'d> UartRx<'d, Async> {
841855
842856 compiler_fence ( Ordering :: SeqCst ) ;
843857
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 ) ;
845859
846860 if has_errors {
847861 // all Rx interrupts and Rx DMA Request have already been cleared in interrupt handler
@@ -889,7 +903,7 @@ impl<'d> UartRx<'d, Async> {
889903 r
890904 }
891905
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 > {
893907 if buffer. is_empty ( ) {
894908 return Ok ( 0 ) ;
895909 } else if buffer. len ( ) > 0xFFFF {
@@ -899,7 +913,7 @@ impl<'d> UartRx<'d, Async> {
899913 let buffer_len = buffer. len ( ) ;
900914
901915 // 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 ;
903917
904918 match res {
905919 Ok ( ReadCompletionEvent :: DmaCompleted ) => Ok ( buffer_len) ,
0 commit comments