aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2025-11-19 21:51:51 +0000
committerGitHub <[email protected]>2025-11-19 21:51:51 +0000
commit117b875134f4edcb32ec327146c2c2af01a50672 (patch)
tree82cf5e8a35a69e617e19b15b52c26eddffe310ef
parent4d040403f56da169337b10008027df28ecb921e7 (diff)
parente5a95221ba2ab05f3e7000c206049654fe28af92 (diff)
Merge pull request #4914 from xoviat/exti
stm32/exit: add poll_for methods
-rw-r--r--embassy-stm32/CHANGELOG.md1
-rw-r--r--embassy-stm32/src/exti.rs46
2 files changed, 37 insertions, 10 deletions
diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md
index 1ecb99be7..d2f675dbc 100644
--- a/embassy-stm32/CHANGELOG.md
+++ b/embassy-stm32/CHANGELOG.md
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7 7
8## Unreleased - ReleaseDate 8## Unreleased - ReleaseDate
9 9
10- feat: add poll_for methods to exti
10- feat: implement stop for stm32wb. 11- feat: implement stop for stm32wb.
11- change: rework hsem and add HIL test for some chips. 12- change: rework hsem and add HIL test for some chips.
12- 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)) 13- 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))
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs
index cb46d362c..899d5e677 100644
--- a/embassy-stm32/src/exti.rs
+++ b/embassy-stm32/src/exti.rs
@@ -7,6 +7,7 @@ use core::task::{Context, Poll};
7 7
8use embassy_hal_internal::{PeripheralType, impl_peripheral}; 8use embassy_hal_internal::{PeripheralType, impl_peripheral};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use futures_util::FutureExt;
10 11
11use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, PinNumber, Pull}; 12use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, PinNumber, Pull};
12use crate::pac::EXTI; 13use crate::pac::EXTI;
@@ -133,7 +134,7 @@ impl<'d> ExtiInput<'d> {
133 /// 134 ///
134 /// This returns immediately if the pin is already high. 135 /// This returns immediately if the pin is already high.
135 pub async fn wait_for_high(&mut self) { 136 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);
137 if self.is_high() { 138 if self.is_high() {
138 return; 139 return;
139 } 140 }
@@ -144,7 +145,7 @@ impl<'d> ExtiInput<'d> {
144 /// 145 ///
145 /// This returns immediately if the pin is already low. 146 /// This returns immediately if the pin is already low.
146 pub async fn wait_for_low(&mut self) { 147 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);
148 if self.is_low() { 149 if self.is_low() {
149 return; 150 return;
150 } 151 }
@@ -155,19 +156,40 @@ impl<'d> ExtiInput<'d> {
155 /// 156 ///
156 /// If the pin is already high, it will wait for it to go low then back high. 157 /// If the pin is already high, it will wait for it to go low then back high.
157 pub async fn wait_for_rising_edge(&mut self) { 158 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);
159 } 168 }
160 169
161 /// Asynchronously wait until the pin sees a falling edge. 170 /// Asynchronously wait until the pin sees a falling edge.
162 /// 171 ///
163 /// If the pin is already low, it will wait for it to go high then back low. 172 /// If the pin is already low, it will wait for it to go high then back low.
164 pub async fn wait_for_falling_edge(&mut self) { 173 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);
166 } 183 }
167 184
168 /// Asynchronously wait until the pin sees any edge (either rising or falling). 185 /// Asynchronously wait until the pin sees any edge (either rising or falling).
169 pub async fn wait_for_any_edge(&mut self) { 186 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);
171 } 193 }
172} 194}
173 195
@@ -227,11 +249,12 @@ impl<'d> embedded_hal_async::digital::Wait for ExtiInput<'d> {
227#[must_use = "futures do nothing unless you `.await` or poll them"] 249#[must_use = "futures do nothing unless you `.await` or poll them"]
228struct ExtiInputFuture<'a> { 250struct ExtiInputFuture<'a> {
229 pin: PinNumber, 251 pin: PinNumber,
252 drop: bool,
230 phantom: PhantomData<&'a mut AnyPin>, 253 phantom: PhantomData<&'a mut AnyPin>,
231} 254}
232 255
233impl<'a> ExtiInputFuture<'a> { 256impl<'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 {
235 critical_section::with(|_| { 258 critical_section::with(|_| {
236 let pin = pin as usize; 259 let pin = pin as usize;
237 exticr_regs().exticr(pin / 4).modify(|w| w.set_exti(pin % 4, port)); 260 exticr_regs().exticr(pin / 4).modify(|w| w.set_exti(pin % 4, port));
@@ -252,6 +275,7 @@ impl<'a> ExtiInputFuture<'a> {
252 275
253 Self { 276 Self {
254 pin, 277 pin,
278 drop,
255 phantom: PhantomData, 279 phantom: PhantomData,
256 } 280 }
257 } 281 }
@@ -259,10 +283,12 @@ impl<'a> ExtiInputFuture<'a> {
259 283
260impl<'a> Drop for ExtiInputFuture<'a> { 284impl<'a> Drop for ExtiInputFuture<'a> {
261 fn drop(&mut self) { 285 fn drop(&mut self) {
262 critical_section::with(|_| { 286 if self.drop {
263 let pin = self.pin as _; 287 critical_section::with(|_| {
264 cpu_regs().imr(0).modify(|w| w.set_line(pin, false)); 288 let pin = self.pin as _;
265 }); 289 cpu_regs().imr(0).modify(|w| w.set_line(pin, false));
290 });
291 }
266 } 292 }
267} 293}
268 294