Skip to content

Commit

Permalink
async gpio fixes (esp-rs#537)
Browse files Browse the repository at this point in the history
* async gpio fixes

- Fix pin number calculation for bank1
- Clear interrupt status after disabling interrupt to avoid hardware
  pending another interrupt
- Clear interrupt status per pin when we create the input future

* add changelog item
  • Loading branch information
MabezDev authored and SergioGasquez committed Jun 9, 2023
1 parent b1bddb1 commit fd334e1
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- DMA is supported for SPI3 on ESP32-S3 (#507)
- `change_bus_frequency` is now available on `SpiDma` (#529)
- Fixed a bug where a GPIO interrupt could erroneously fire again causing the next `await` on that pin to instantly return `Poll::Ok` (#537)

### Changed
- Improve examples documentation (#533)
Expand Down
15 changes: 8 additions & 7 deletions esp-hal-common/src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1881,6 +1881,8 @@ mod asynch {
P: crate::gpio::Pin + embedded_hal_1::digital::ErrorType,
{
pub fn new(pin: &'a mut P, event: Event) -> Self {
pin.clear_interrupt(); // clear stale interrupt flags, when we await we want to know when an event
// occurs from the await call, not if the pin event has happened recently.
pin.listen(event);
Self { pin }
}
Expand Down Expand Up @@ -1913,27 +1915,21 @@ mod asynch {
type Bank0 = SingleCoreInteruptStatusRegisterAccessBank0;
#[cfg(any(esp32, esp32s2, esp32s3))]
type Bank1 = SingleCoreInteruptStatusRegisterAccessBank1;

let mut intrs = Bank0::pro_cpu_interrupt_status_read() as u64;

#[cfg(any(esp32, esp32s2, esp32s3))]
{
intrs |= (Bank1::pro_cpu_interrupt_status_read() as u64) << 32;
}

// clear interrupts
Bank0GpioRegisterAccess::write_interrupt_status_clear(!0);
#[cfg(any(esp32, esp32s2, esp32s3))]
Bank1GpioRegisterAccess::write_interrupt_status_clear(!0);

while intrs != 0 {
let pin_nr = intrs.trailing_zeros();
cfg_if::cfg_if! {
if #[cfg(any(esp32, esp32s2, esp32s3))] {
if pin_nr < 32 {
Bank0GpioRegisterAccess::set_int_enable(pin_nr as u8, 0, 0, false);
} else {
Bank1GpioRegisterAccess::set_int_enable(pin_nr as u8, 0, 0, false);
Bank1GpioRegisterAccess::set_int_enable((pin_nr - 32) as u8, 0, 0, false);
}
} else {
Bank0GpioRegisterAccess::set_int_enable(pin_nr as u8, 0, 0, false);
Expand All @@ -1942,5 +1938,10 @@ mod asynch {
PIN_WAKERS[pin_nr as usize].wake(); // wake task
intrs &= !(1 << pin_nr);
}

// clear interrupt bits
Bank0GpioRegisterAccess::write_interrupt_status_clear(intrs as u32);
#[cfg(any(esp32, esp32s2, esp32s3))]
Bank1GpioRegisterAccess::write_interrupt_status_clear((intrs >> 32) as u32);
}
}

0 comments on commit fd334e1

Please sign in to comment.