@@ -578,7 +578,7 @@ impl<'a> UartTx<'a, Async> {
578578 let res = select (
579579 transfer,
580580 poll_fn ( |cx| {
581- self . info . waker . register ( cx. waker ( ) ) ;
581+ self . info . tx_waker . register ( cx. waker ( ) ) ;
582582
583583 self . info . regs . fifointenset ( ) . write ( |w| w. txerr ( ) . set_bit ( ) ) ;
584584
@@ -606,38 +606,23 @@ impl<'a> UartTx<'a, Async> {
606606
607607 /// Flush UART TX asynchronously.
608608 pub fn flush ( & mut self ) -> impl Future < Output = Result < ( ) > > + use < ' _ , ' a > {
609- self . wait_on (
610- |me| {
611- if me. info . regs . stat ( ) . read ( ) . txidle ( ) . bit_is_set ( ) {
612- Poll :: Ready ( Ok ( ( ) ) )
613- } else {
614- Poll :: Pending
615- }
616- } ,
617- |me| {
618- me. info . regs . intenset ( ) . write ( |w| w. txidleen ( ) . set_bit ( ) ) ;
619- } ,
620- )
621- }
622-
623- /// Calls `f` to check if we are ready or not.
624- /// If not, `g` is called once the waker is set (to eg enable the required interrupts).
625- fn wait_on < F , U , G > ( & mut self , mut f : F , mut g : G ) -> impl Future < Output = U > + use < ' _ , ' a , F , U , G >
626- where
627- F : FnMut ( & mut Self ) -> Poll < U > ,
628- G : FnMut ( & mut Self ) ,
629- {
630- poll_fn ( move |cx| {
631- // Register waker before checking condition, to ensure that wakes/interrupts
632- // aren't lost between f() and g()
633- self . info . waker . register ( cx. waker ( ) ) ;
634- let r = f ( self ) ;
635-
636- if r. is_pending ( ) {
637- g ( self ) ;
638- }
609+ poll_fn ( |cx| {
610+ self . info . tx_waker . register ( cx. waker ( ) ) ;
611+
612+ self . info . regs . intenset ( ) . write ( |w| w. txidleen ( ) . set_bit ( ) ) ;
613+ self . info . regs . fifointenset ( ) . write ( |w| w. txerr ( ) . set_bit ( ) ) ;
614+
615+ let fifointstat = self . info . regs . fifointstat ( ) . read ( ) ;
639616
640- r
617+ self . info . regs . fifostat ( ) . write ( |w| w. txerr ( ) . set_bit ( ) ) ;
618+
619+ if self . info . regs . stat ( ) . read ( ) . txidle ( ) . bit_is_set ( ) {
620+ Poll :: Ready ( Ok ( ( ) ) )
621+ } else if fifointstat. txerr ( ) . bit_is_set ( ) {
622+ Poll :: Ready ( Err ( Error :: Overrun ) )
623+ } else {
624+ Poll :: Pending
625+ }
641626 } )
642627 }
643628}
@@ -685,7 +670,7 @@ impl<'a> UartRx<'a, Async> {
685670 let res = select (
686671 transfer,
687672 poll_fn ( |cx| {
688- self . info . waker . register ( cx. waker ( ) ) ;
673+ self . info . rx_waker . register ( cx. waker ( ) ) ;
689674
690675 self . info
691676 . regs
@@ -1065,7 +1050,8 @@ impl embedded_io_async::Write for Uart<'_, Async> {
10651050
10661051struct Info {
10671052 regs : & ' static crate :: pac:: usart0:: RegisterBlock ,
1068- waker : & ' static AtomicWaker ,
1053+ tx_waker : & ' static AtomicWaker ,
1054+ rx_waker : & ' static AtomicWaker ,
10691055}
10701056
10711057// SAFETY: safety for Send here is the same as the other accessors to unsafe blocks: it must be done from a single executor context.
@@ -1075,7 +1061,8 @@ unsafe impl Send for Info {}
10751061
10761062trait SealedInstance {
10771063 fn info ( ) -> Info ;
1078- fn waker ( ) -> & ' static AtomicWaker ;
1064+ fn tx_waker ( ) -> & ' static AtomicWaker ;
1065+ fn rx_waker ( ) -> & ' static AtomicWaker ;
10791066}
10801067
10811068/// UART interrupt handler.
@@ -1088,29 +1075,29 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
10881075 let regs = T :: info ( ) . regs ;
10891076 let stat = regs. intstat ( ) . read ( ) ;
10901077
1091- if stat. txidle ( ) . bit_is_set ( )
1092- || stat. framerrint ( ) . bit_is_set ( )
1093- || stat. parityerrint ( ) . bit_is_set ( )
1094- || stat. rxnoiseint ( ) . bit_is_set ( )
1095- {
1096- regs. intenclr ( ) . write ( |w| {
1097- w. txidleclr ( )
1098- . set_bit ( )
1099- . framerrclr ( )
1100- . set_bit ( )
1101- . parityerrclr ( )
1102- . set_bit ( )
1103- . rxnoiseclr ( )
1104- . set_bit ( )
1105- } ) ;
1078+ if stat. txidle ( ) . bit_is_set ( ) {
1079+ regs. intenclr ( ) . write ( |w| w. txidleclr ( ) . set_bit ( ) ) ;
1080+ T :: tx_waker ( ) . wake ( ) ;
1081+ }
1082+
1083+ if stat. framerrint ( ) . bit_is_set ( ) || stat. parityerrint ( ) . bit_is_set ( ) || stat. rxnoiseint ( ) . bit_is_set ( ) {
1084+ regs. intenclr ( )
1085+ . write ( |w| w. framerrclr ( ) . set_bit ( ) . parityerrclr ( ) . set_bit ( ) . rxnoiseclr ( ) . set_bit ( ) ) ;
1086+
1087+ T :: rx_waker ( ) . wake ( ) ;
11061088 }
11071089
11081090 let fifointstat = regs. fifointstat ( ) . read ( ) ;
1109- if fifointstat. txerr ( ) . bit_is_set ( ) || fifointstat. rxerr ( ) . bit_is_set ( ) {
1110- regs. fifointenclr ( ) . write ( |w| w. txerr ( ) . set_bit ( ) . rxerr ( ) . set_bit ( ) ) ;
1091+ if fifointstat. txerr ( ) . bit_is_set ( ) {
1092+ regs. fifointenclr ( ) . write ( |w| w. txerr ( ) . set_bit ( ) ) ;
1093+
1094+ T :: tx_waker ( ) . wake ( ) ;
11111095 }
11121096
1113- T :: waker ( ) . wake ( ) ;
1097+ if fifointstat. rxerr ( ) . bit_is_set ( ) {
1098+ regs. fifointenclr ( ) . write ( |w| w. txerr ( ) . set_bit ( ) . rxerr ( ) . set_bit ( ) ) ;
1099+ T :: rx_waker ( ) . wake ( ) ;
1100+ }
11141101 }
11151102}
11161103
@@ -1129,13 +1116,19 @@ macro_rules! impl_instance {
11291116 fn info( ) -> Info {
11301117 Info {
11311118 regs: unsafe { & * crate :: pac:: [ <Usart $n>] :: ptr( ) } ,
1132- waker: Self :: waker( ) ,
1119+ tx_waker: Self :: tx_waker( ) ,
1120+ rx_waker: Self :: rx_waker( ) ,
11331121 }
11341122 }
11351123
1136- fn waker( ) -> & ' static AtomicWaker {
1137- static WAKER : AtomicWaker = AtomicWaker :: new( ) ;
1138- & WAKER
1124+ fn tx_waker( ) -> & ' static AtomicWaker {
1125+ static TX_WAKER : AtomicWaker = AtomicWaker :: new( ) ;
1126+ & TX_WAKER
1127+ }
1128+
1129+ fn rx_waker( ) -> & ' static AtomicWaker {
1130+ static RX_WAKER : AtomicWaker = AtomicWaker :: new( ) ;
1131+ & RX_WAKER
11391132 }
11401133 }
11411134
0 commit comments