diff options
| author | xoviat <[email protected]> | 2025-11-19 21:51:51 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-11-19 21:51:51 +0000 |
| commit | 117b875134f4edcb32ec327146c2c2af01a50672 (patch) | |
| tree | 82cf5e8a35a69e617e19b15b52c26eddffe310ef | |
| parent | 4d040403f56da169337b10008027df28ecb921e7 (diff) | |
| parent | e5a95221ba2ab05f3e7000c206049654fe28af92 (diff) | |
Merge pull request #4914 from xoviat/exti
stm32/exit: add poll_for methods
| -rw-r--r-- | embassy-stm32/CHANGELOG.md | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/exti.rs | 46 |
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 | ||
| 8 | use embassy_hal_internal::{PeripheralType, impl_peripheral}; | 8 | use embassy_hal_internal::{PeripheralType, impl_peripheral}; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 10 | use futures_util::FutureExt; | ||
| 10 | 11 | ||
| 11 | use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, PinNumber, Pull}; | 12 | use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, PinNumber, Pull}; |
| 12 | use crate::pac::EXTI; | 13 | use 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"] |
| 228 | struct ExtiInputFuture<'a> { | 250 | struct 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 | ||
| 233 | impl<'a> ExtiInputFuture<'a> { | 256 | 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 { |
| 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 | ||
| 260 | impl<'a> Drop for ExtiInputFuture<'a> { | 284 | impl<'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 | ||
