Skip to content

Commit 117b875

Browse files
authored
Merge pull request #4914 from xoviat/exti
stm32/exit: add poll_for methods
2 parents 4d04040 + e5a9522 commit 117b875

File tree

2 files changed

+37
-10
lines changed

2 files changed

+37
-10
lines changed

embassy-stm32/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased - ReleaseDate
99

10+
- feat: add poll_for methods to exti
1011
- feat: implement stop for stm32wb.
1112
- change: rework hsem and add HIL test for some chips.
1213
- change: stm32/eth: ethernet no longer has a hard dependency on station management, and station management can be used independently ([#4871](https://github.com/embassy-rs/embassy/pull/4871))

embassy-stm32/src/exti.rs

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use core::task::{Context, Poll};
77

88
use embassy_hal_internal::{PeripheralType, impl_peripheral};
99
use embassy_sync::waitqueue::AtomicWaker;
10+
use futures_util::FutureExt;
1011

1112
use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, PinNumber, Pull};
1213
use crate::pac::EXTI;
@@ -133,7 +134,7 @@ impl<'d> ExtiInput<'d> {
133134
///
134135
/// This returns immediately if the pin is already high.
135136
pub async fn wait_for_high(&mut self) {
136-
let fut = ExtiInputFuture::new(self.pin.pin.pin.pin(), self.pin.pin.pin.port(), true, false);
137+
let fut = ExtiInputFuture::new(self.pin.pin.pin.pin(), self.pin.pin.pin.port(), true, false, true);
137138
if self.is_high() {
138139
return;
139140
}
@@ -144,7 +145,7 @@ impl<'d> ExtiInput<'d> {
144145
///
145146
/// This returns immediately if the pin is already low.
146147
pub async fn wait_for_low(&mut self) {
147-
let fut = ExtiInputFuture::new(self.pin.pin.pin.pin(), self.pin.pin.pin.port(), false, true);
148+
let fut = ExtiInputFuture::new(self.pin.pin.pin.pin(), self.pin.pin.pin.port(), false, true, true);
148149
if self.is_low() {
149150
return;
150151
}
@@ -155,19 +156,40 @@ impl<'d> ExtiInput<'d> {
155156
///
156157
/// If the pin is already high, it will wait for it to go low then back high.
157158
pub async fn wait_for_rising_edge(&mut self) {
158-
ExtiInputFuture::new(self.pin.pin.pin.pin(), self.pin.pin.pin.port(), true, false).await
159+
ExtiInputFuture::new(self.pin.pin.pin.pin(), self.pin.pin.pin.port(), true, false, true).await
160+
}
161+
162+
/// Asynchronously wait until the pin sees a rising edge.
163+
///
164+
/// If the pin is already high, it will wait for it to go low then back high.
165+
pub fn poll_for_rising_edge<'a>(&mut self, cx: &mut Context<'a>) {
166+
let _ =
167+
ExtiInputFuture::new(self.pin.pin.pin.pin(), self.pin.pin.pin.port(), true, false, false).poll_unpin(cx);
159168
}
160169

161170
/// Asynchronously wait until the pin sees a falling edge.
162171
///
163172
/// If the pin is already low, it will wait for it to go high then back low.
164173
pub async fn wait_for_falling_edge(&mut self) {
165-
ExtiInputFuture::new(self.pin.pin.pin.pin(), self.pin.pin.pin.port(), false, true).await
174+
ExtiInputFuture::new(self.pin.pin.pin.pin(), self.pin.pin.pin.port(), false, true, true).await
175+
}
176+
177+
/// Asynchronously wait until the pin sees a falling edge.
178+
///
179+
/// If the pin is already low, it will wait for it to go high then back low.
180+
pub fn poll_for_falling_edge<'a>(&mut self, cx: &mut Context<'a>) {
181+
let _ =
182+
ExtiInputFuture::new(self.pin.pin.pin.pin(), self.pin.pin.pin.port(), false, true, false).poll_unpin(cx);
166183
}
167184

168185
/// Asynchronously wait until the pin sees any edge (either rising or falling).
169186
pub async fn wait_for_any_edge(&mut self) {
170-
ExtiInputFuture::new(self.pin.pin.pin.pin(), self.pin.pin.pin.port(), true, true).await
187+
ExtiInputFuture::new(self.pin.pin.pin.pin(), self.pin.pin.pin.port(), true, true, true).await
188+
}
189+
190+
/// Asynchronously wait until the pin sees any edge (either rising or falling).
191+
pub fn poll_for_any_edge<'a>(&mut self, cx: &mut Context<'a>) {
192+
let _ = ExtiInputFuture::new(self.pin.pin.pin.pin(), self.pin.pin.pin.port(), true, true, false).poll_unpin(cx);
171193
}
172194
}
173195

@@ -227,11 +249,12 @@ impl<'d> embedded_hal_async::digital::Wait for ExtiInput<'d> {
227249
#[must_use = "futures do nothing unless you `.await` or poll them"]
228250
struct ExtiInputFuture<'a> {
229251
pin: PinNumber,
252+
drop: bool,
230253
phantom: PhantomData<&'a mut AnyPin>,
231254
}
232255

233256
impl<'a> ExtiInputFuture<'a> {
234-
fn new(pin: PinNumber, port: PinNumber, rising: bool, falling: bool) -> Self {
257+
fn new(pin: PinNumber, port: PinNumber, rising: bool, falling: bool, drop: bool) -> Self {
235258
critical_section::with(|_| {
236259
let pin = pin as usize;
237260
exticr_regs().exticr(pin / 4).modify(|w| w.set_exti(pin % 4, port));
@@ -252,17 +275,20 @@ impl<'a> ExtiInputFuture<'a> {
252275

253276
Self {
254277
pin,
278+
drop,
255279
phantom: PhantomData,
256280
}
257281
}
258282
}
259283

260284
impl<'a> Drop for ExtiInputFuture<'a> {
261285
fn drop(&mut self) {
262-
critical_section::with(|_| {
263-
let pin = self.pin as _;
264-
cpu_regs().imr(0).modify(|w| w.set_line(pin, false));
265-
});
286+
if self.drop {
287+
critical_section::with(|_| {
288+
let pin = self.pin as _;
289+
cpu_regs().imr(0).modify(|w| w.set_line(pin, false));
290+
});
291+
}
266292
}
267293
}
268294

0 commit comments

Comments
 (0)