@@ -3,7 +3,7 @@ use crate::{
33 sealed:: { IrqWaker , Wakeable } ,
44 AsyncPeripheral , CancellablePollFn as CPFn ,
55 } ,
6- atomic_register_access:: write_bitmask_clear,
6+ atomic_register_access:: { write_bitmask_clear, write_bitmask_set } ,
77 gpio:: {
88 func:: { FunctionSio , SioConfig } ,
99 pin:: pin_sealed:: { PinIdOps , TypeLevelPinId } ,
@@ -14,6 +14,8 @@ use crate::{
1414use core:: task:: Poll ;
1515use embedded_hal_async:: digital:: Wait ;
1616
17+ const EDGE_INTERRUPTS_MASK : u32 = Interrupt :: EdgeLow . mask ( ) | Interrupt :: EdgeHigh . mask ( ) ;
18+
1719impl < I , P , S > AsyncPeripheral for Pin < I , FunctionSio < S > , P >
1820where
1921 I : PinId + TypeLevelPinId ,
2729 | Interrupt :: EdgeLow . mask ( )
2830 | Interrupt :: EdgeHigh . mask ( ) ;
2931
30- // Level interrupts are not latched and can't be cleared
31- const CLEAR_INTERRUPTS_MASK : u32 = Interrupt :: EdgeLow . mask ( ) | Interrupt :: EdgeHigh . mask ( ) ;
32-
3332 let pin_id = I :: ID ;
3433
3534 let ( ints_reg, ints_offset) = pin_id. proc_ints ( Sio :: core ( ) ) ;
4342 write_bitmask_clear ( inte_reg. as_ptr ( ) , INTERRUPTS_MASK << inte_offset) ;
4443 }
4544
46- // Clear interrupts for Pin
47- let ( intr_reg, intr_offset) = pin_id. intr ( ) ;
48- intr_reg. write ( |w| unsafe { w. bits ( CLEAR_INTERRUPTS_MASK << intr_offset) } ) ;
45+ // Don't need to clear any interrupts here. Level interrupts are not latched,
46+ // Edge interrupts are cleared in the relevant poll functions
4947
5048 Self :: waker ( ) . wake ( ) ;
5149 }
8583 }
8684 }
8785
86+ fn poll_rising_edge ( & mut self ) -> Poll < Result < ( ) , Error > > {
87+ // read raw interrupt status, because interrupt is disabled in on_interrupt(), but is not cleared
88+ if self . raw_interrupt_status ( Interrupt :: EdgeHigh ) {
89+ self . clear_interrupt ( Interrupt :: EdgeHigh ) ;
90+
91+ Poll :: Ready ( Ok ( ( ) ) )
92+ } else {
93+ Poll :: Pending
94+ }
95+ }
96+
97+ fn poll_falling_edge ( & mut self ) -> Poll < Result < ( ) , Error > > {
98+ // read raw interrupt status, because interrupt is disabled in on_interrupt(), but is not cleared
99+ if self . raw_interrupt_status ( Interrupt :: EdgeLow ) {
100+ self . clear_interrupt ( Interrupt :: EdgeLow ) ;
101+
102+ Poll :: Ready ( Ok ( ( ) ) )
103+ } else {
104+ Poll :: Pending
105+ }
106+ }
107+
108+ fn poll_any_edge ( & mut self ) -> Poll < Result < ( ) , Error > > {
109+ // read raw interrupt status, because interrupt is disabled in on_interrupt(), but is not cleared
110+ let ( reg, offset) = self . id . intr ( ) ;
111+ let bits = reg. read ( ) . bits ( ) >> offset;
112+
113+ if bits & EDGE_INTERRUPTS_MASK != 0 {
114+ reg. write ( |w| unsafe { w. bits ( EDGE_INTERRUPTS_MASK << offset) } ) ;
115+
116+ Poll :: Ready ( Ok ( ( ) ) )
117+ } else {
118+ Poll :: Pending
119+ }
120+ }
121+
88122 fn disable_level_high_irq ( & mut self ) {
89123 self . set_interrupt_enabled ( Interrupt :: LevelHigh , false ) ;
90124 }
@@ -117,6 +151,26 @@ where
117151 self . set_interrupt_enabled ( Interrupt :: EdgeLow , true )
118152 }
119153
154+ fn disable_any_edge_irq ( & mut self ) {
155+ let ( reg, offset) = self . id . proc_inte ( Sio :: core ( ) ) ;
156+ unsafe {
157+ write_bitmask_clear ( reg. as_ptr ( ) , EDGE_INTERRUPTS_MASK << offset) ;
158+ }
159+ }
160+
161+ fn enable_any_edge_irq ( & mut self ) {
162+ let ( reg, offset) = self . id . proc_inte ( Sio :: core ( ) ) ;
163+ unsafe {
164+ write_bitmask_set ( reg. as_ptr ( ) , EDGE_INTERRUPTS_MASK << offset) ;
165+ }
166+ }
167+
168+ fn raw_interrupt_status ( & self , interrupt : Interrupt ) -> bool {
169+ let ( reg, offset) = self . id . intr ( ) ;
170+ let mask = interrupt. mask ( ) ;
171+ ( reg. read ( ) . bits ( ) >> offset) & mask == mask
172+ }
173+
120174 async fn _wait_for_high ( & mut self ) {
121175 let _ = CPFn :: new (
122176 self ,
@@ -138,39 +192,33 @@ where
138192 }
139193
140194 async fn _wait_for_rising_edge ( & mut self ) {
141- if self . _is_high ( ) {
142- self . _wait_for_low ( ) . await ;
143- }
144-
145195 let _ = CPFn :: new (
146196 self ,
147- Self :: poll_is_high ,
197+ Self :: poll_rising_edge ,
148198 Self :: enable_rising_edge_irq,
149199 Self :: disable_rising_edge_irq,
150200 )
151201 . await ;
152202 }
153203
154204 async fn _wait_for_falling_edge ( & mut self ) {
155- if self . _is_low ( ) {
156- self . _wait_for_high ( ) . await ;
157- }
158-
159205 let _ = CPFn :: new (
160206 self ,
161- Self :: poll_is_high ,
207+ Self :: poll_falling_edge ,
162208 Self :: enable_falling_edge_irq,
163209 Self :: disable_falling_edge_irq,
164210 )
165211 . await ;
166212 }
167213
168214 async fn _wait_for_any_edge ( & mut self ) {
169- if self . _is_high ( ) {
170- self . _wait_for_falling_edge ( ) . await ;
171- } else {
172- self . _wait_for_rising_edge ( ) . await ;
173- }
215+ let _ = CPFn :: new (
216+ self ,
217+ Self :: poll_any_edge,
218+ Self :: enable_any_edge_irq,
219+ Self :: disable_any_edge_irq,
220+ )
221+ . await ;
174222 }
175223}
176224
0 commit comments