@@ -616,7 +616,7 @@ mod asynch {
616
616
use procmacros:: handler;
617
617
618
618
use super :: * ;
619
- use crate :: { asynch:: AtomicWaker , peripherals :: SYSTIMER } ;
619
+ use crate :: asynch:: AtomicWaker ;
620
620
621
621
const NUM_ALARMS : usize = 3 ;
622
622
@@ -629,65 +629,65 @@ mod asynch {
629
629
630
630
impl < ' a > AlarmFuture < ' a > {
631
631
pub ( crate ) fn new ( alarm : & ' a Alarm ) -> Self {
632
+ // For some reason, on the S2 we need to enable the interrupt before we
633
+ // read its status. Doing so in the other order causes the interrupt
634
+ // request to never be fired.
632
635
alarm. enable_interrupt ( true ) ;
633
-
634
636
Self { alarm }
635
637
}
636
638
637
- fn event_bit_is_clear ( & self ) -> bool {
638
- SYSTIMER :: regs ( )
639
- . int_ena ( )
640
- . read ( )
641
- . target ( self . alarm . channel ( ) )
642
- . bit_is_clear ( )
639
+ fn is_done ( & self ) -> bool {
640
+ self . alarm . is_interrupt_set ( )
643
641
}
644
642
}
645
643
646
644
impl core:: future:: Future for AlarmFuture < ' _ > {
647
645
type Output = ( ) ;
648
646
649
647
fn poll ( self : Pin < & mut Self > , ctx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
648
+ // Interrupts are enabled, so we need to register the waker before we check for
649
+ // done. Otherwise we might miss the interrupt that would wake us.
650
650
WAKERS [ self . alarm . channel ( ) as usize ] . register ( ctx. waker ( ) ) ;
651
651
652
- if self . event_bit_is_clear ( ) {
652
+ if self . is_done ( ) {
653
653
Poll :: Ready ( ( ) )
654
654
} else {
655
655
Poll :: Pending
656
656
}
657
657
}
658
658
}
659
659
660
+ impl Drop for AlarmFuture < ' _ > {
661
+ fn drop ( & mut self ) {
662
+ self . alarm . enable_interrupt ( false ) ;
663
+ self . alarm . clear_interrupt ( ) ;
664
+ }
665
+ }
666
+
667
+ #[ inline]
668
+ fn handle_alarm ( alarm : u8 ) {
669
+ Alarm {
670
+ comp : alarm,
671
+ unit : Unit :: Unit0 ,
672
+ }
673
+ . enable_interrupt ( false ) ;
674
+
675
+ WAKERS [ alarm as usize ] . wake ( ) ;
676
+ }
677
+
660
678
#[ handler]
661
679
pub ( crate ) fn target0_handler ( ) {
662
- lock ( & INT_ENA_LOCK , || {
663
- SYSTIMER :: regs ( )
664
- . int_ena ( )
665
- . modify ( |_, w| w. target0 ( ) . clear_bit ( ) ) ;
666
- } ) ;
667
-
668
- WAKERS [ 0 ] . wake ( ) ;
680
+ handle_alarm ( 0 ) ;
669
681
}
670
682
671
683
#[ handler]
672
684
pub ( crate ) fn target1_handler ( ) {
673
- lock ( & INT_ENA_LOCK , || {
674
- SYSTIMER :: regs ( )
675
- . int_ena ( )
676
- . modify ( |_, w| w. target1 ( ) . clear_bit ( ) ) ;
677
- } ) ;
678
-
679
- WAKERS [ 1 ] . wake ( ) ;
685
+ handle_alarm ( 1 ) ;
680
686
}
681
687
682
688
#[ handler]
683
689
pub ( crate ) fn target2_handler ( ) {
684
- lock ( & INT_ENA_LOCK , || {
685
- SYSTIMER :: regs ( )
686
- . int_ena ( )
687
- . modify ( |_, w| w. target2 ( ) . clear_bit ( ) ) ;
688
- } ) ;
689
-
690
- WAKERS [ 2 ] . wake ( ) ;
690
+ handle_alarm ( 2 ) ;
691
691
}
692
692
}
693
693
0 commit comments