@@ -20,11 +20,13 @@ mod async_io {
20
20
//! the largest number currently used, although this might change with 64-bit targest in the
21
21
//! future.
22
22
23
- use core:: { cell:: UnsafeCell , future:: Future , mem, sync:: atomic:: Ordering , task:: { Poll , Waker } } ;
23
+ use core:: { cell:: UnsafeCell , ffi :: c_int , future:: Future , mem, sync:: atomic:: Ordering , task:: { Poll , Waker } } ;
24
24
25
25
use embassy_sync:: waitqueue:: AtomicWaker ;
26
26
use portable_atomic:: AtomicBool ;
27
- use zephyr_sys:: { device, gpio_add_callback, gpio_callback, gpio_init_callback, gpio_pin_get, gpio_pin_interrupt_configure, gpio_pin_interrupt_configure_dt, gpio_port_pins_t, GPIO_INT_LEVEL_HIGH , ZR_GPIO_INT_MODE_DISABLE_ONLY } ;
27
+ use zephyr_sys:: { device, gpio_add_callback, gpio_callback, gpio_init_callback, gpio_pin_get, gpio_pin_interrupt_configure, gpio_pin_interrupt_configure_dt, gpio_port_pins_t, GPIO_INT_LEVEL_HIGH , GPIO_INT_LEVEL_LOW , ZR_GPIO_INT_MODE_DISABLE_ONLY } ;
28
+
29
+ use crate :: printkln;
28
30
29
31
use super :: { GpioPin , GpioToken } ;
30
32
@@ -135,19 +137,31 @@ mod async_io {
135
137
/// more than one GPIO.
136
138
///
137
139
pub unsafe fn wait_for_high ( & mut self , _token : & mut GpioToken ) -> impl Future < Output = ( ) > + use < ' _ > {
138
- GpioWait :: new ( self )
140
+ GpioWait :: new ( self , 1 )
141
+ }
142
+
143
+ /// Asynchronously wait for a gpio pin to become low.
144
+ ///
145
+ /// # Safety
146
+ ///
147
+ /// The `_token` enforces single use of gpios. Note that this makes it impossible to wait
148
+ /// for more than one GPIO.
149
+ pub unsafe fn wait_for_low ( & mut self , _token : & mut GpioToken ) -> impl Future < Output = ( ) > + use < ' _ > {
150
+ GpioWait :: new ( self , 0 )
139
151
}
140
152
}
141
153
142
154
/// A future that waits for a gpio to become high.
143
155
pub struct GpioWait < ' a > {
144
156
pin : & ' a mut GpioPin ,
157
+ level : u8 ,
145
158
}
146
159
147
160
impl < ' a > GpioWait < ' a > {
148
- fn new ( pin : & ' a mut GpioPin ) -> Self {
161
+ fn new ( pin : & ' a mut GpioPin , level : u8 ) -> Self {
149
162
Self {
150
163
pin,
164
+ level,
151
165
}
152
166
}
153
167
}
@@ -160,10 +174,16 @@ mod async_io {
160
174
161
175
self . pin . data . register ( self . pin . pin . pin , cx. waker ( ) ) ;
162
176
177
+ let mode = match self . level {
178
+ 0 => GPIO_INT_LEVEL_LOW ,
179
+ 1 => GPIO_INT_LEVEL_HIGH ,
180
+ _ => unreachable ! ( ) ,
181
+ } ;
182
+
163
183
unsafe {
164
- gpio_pin_interrupt_configure_dt ( & self . pin . pin , GPIO_INT_LEVEL_HIGH ) ;
184
+ gpio_pin_interrupt_configure_dt ( & self . pin . pin , mode ) ;
165
185
166
- if gpio_pin_get ( self . pin . pin . port , self . pin . pin . pin ) == 1 {
186
+ if gpio_pin_get ( self . pin . pin . port , self . pin . pin . pin ) == self . level as c_int {
167
187
// TODO: Need to match with level.
168
188
// Zephyr doesn't have a way to determine if a given interrupt is pending, so the
169
189
// best we can do is just read the pin. This doesn't work for edges though.
0 commit comments