@@ -363,6 +363,16 @@ macro_rules! hal {
363
363
}
364
364
}
365
365
366
+ /// Check for, and return, any errors
367
+ ///
368
+ /// See [`Rx::check_for_error`].
369
+ pub fn check_for_error( ) -> Result <( ) , Error > {
370
+ let mut rx: Rx <pac:: $USARTX> = Rx {
371
+ _usart: PhantomData ,
372
+ } ;
373
+ rx. check_for_error( )
374
+ }
375
+
366
376
/// Stops listening for an interrupt event
367
377
pub fn unlisten( & mut self , event: Event ) {
368
378
match event {
@@ -417,32 +427,19 @@ macro_rules! hal {
417
427
type Error = Error ;
418
428
419
429
fn read( & mut self ) -> nb:: Result <u8 , Error > {
430
+ self . check_for_error( ) ?;
431
+
420
432
// NOTE(unsafe) atomic read with no side effects
421
433
let isr = unsafe { ( * pac:: $USARTX:: ptr( ) ) . isr. read( ) } ;
422
434
423
- // NOTE(unsafe): Only used for atomic writes, to clear error flags.
424
- let icr = unsafe { & ( * pac:: $USARTX:: ptr( ) ) . icr } ;
425
-
426
- Err ( if isr. pe( ) . bit_is_set( ) {
427
- icr. write( |w| w. pecf( ) . clear( ) ) ;
428
- nb:: Error :: Other ( Error :: Parity )
429
- } else if isr. fe( ) . bit_is_set( ) {
430
- icr. write( |w| w. fecf( ) . clear( ) ) ;
431
- nb:: Error :: Other ( Error :: Framing )
432
- } else if isr. nf( ) . bit_is_set( ) {
433
- icr. write( |w| w. ncf( ) . clear( ) ) ;
434
- nb:: Error :: Other ( Error :: Noise )
435
- } else if isr. ore( ) . bit_is_set( ) {
436
- icr. write( |w| w. orecf( ) . clear( ) ) ;
437
- nb:: Error :: Other ( Error :: Overrun )
438
- } else if isr. rxne( ) . bit_is_set( ) {
435
+ if isr. rxne( ) . bit_is_set( ) {
439
436
// NOTE(read_volatile) see `write_volatile` below
440
437
return Ok ( unsafe {
441
438
ptr:: read_volatile( & ( * pac:: $USARTX:: ptr( ) ) . rdr as * const _ as * const _)
442
439
} ) ;
443
- } else {
444
- nb :: Error :: WouldBlock
445
- } )
440
+ }
441
+
442
+ Err ( nb :: Error :: WouldBlock )
446
443
}
447
444
}
448
445
@@ -643,6 +640,38 @@ macro_rules! hal {
643
640
false
644
641
}
645
642
}
643
+
644
+ /// Check for, and return, any errors
645
+ ///
646
+ /// The `read` methods can only return one error at a time, but
647
+ /// there might actually be multiple errors. This method will
648
+ /// return and clear a currently active error. Once it returns
649
+ /// `Ok(())`, it should be possible to proceed with the next
650
+ /// `read` call unimpeded.
651
+ pub fn check_for_error( & mut self ) -> Result <( ) , Error > {
652
+ // NOTE(unsafe): Only used for atomic access.
653
+ let isr = unsafe { ( * pac:: $USARTX:: ptr( ) ) . isr. read( ) } ;
654
+ let icr = unsafe { & ( * pac:: $USARTX:: ptr( ) ) . icr } ;
655
+
656
+ if isr. pe( ) . bit_is_set( ) {
657
+ icr. write( |w| w. pecf( ) . clear( ) ) ;
658
+ return Err ( Error :: Parity ) ;
659
+ }
660
+ if isr. fe( ) . bit_is_set( ) {
661
+ icr. write( |w| w. fecf( ) . clear( ) ) ;
662
+ return Err ( Error :: Framing ) ;
663
+ }
664
+ if isr. nf( ) . bit_is_set( ) {
665
+ icr. write( |w| w. ncf( ) . clear( ) ) ;
666
+ return Err ( Error :: Noise ) ;
667
+ }
668
+ if isr. ore( ) . bit_is_set( ) {
669
+ icr. write( |w| w. orecf( ) . clear( ) ) ;
670
+ return Err ( Error :: Overrun ) ;
671
+ }
672
+
673
+ Ok ( ( ) )
674
+ }
646
675
}
647
676
648
677
impl Tx <pac:: $USARTX> {
0 commit comments