Add GPIO as wake-up source (#1724)

* Add GPIO as wake-up source

* CHANGELOG.md

* Clippy

* Doc fix
This commit is contained in:
Björn Quentin 2024-06-28 13:14:29 +02:00 committed by GitHub
parent 347ef5188b
commit 8cb921f73b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 71 additions and 0 deletions

View File

@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add DmaTransactionTxOwned, DmaTransactionRxOwned, DmaTransactionTxRxOwned, functions to do owning transfers added to SPI half-duplex (#1672)
- uart: Implement `embedded_io::ReadReady` for `Uart` and `UartRx` (#1702)
- ESP32-C6: Support lp-core as wake-up source (#1723)
- Add support for GPIO wake-up source (#1724)
### Fixed

View File

@ -93,6 +93,7 @@ impl<'d> Pin for AnyPin<'d> {
fn unlisten(&mut self, _internal: private::Internal);
fn is_interrupt_set(&self, _internal: private::Internal) -> bool;
fn clear_interrupt(&mut self, _internal: private::Internal);
fn wakeup_enable(&mut self, enable: bool, event: WakeEvent, _internal: private::Internal);
}
}
}
@ -260,6 +261,7 @@ impl<'d> Pin for AnyInputOnlyPin<'d> {
fn unlisten(&mut self, _internal: private::Internal);
fn is_interrupt_set(&self, _internal: private::Internal) -> bool;
fn clear_interrupt(&mut self, _internal: private::Internal);
fn wakeup_enable(&mut self, enable: bool, event: WakeEvent, _internal: private::Internal);
}
}
}

View File

@ -77,6 +77,25 @@ pub enum Event {
HighLevel = 5,
}
impl From<WakeEvent> for Event {
fn from(value: WakeEvent) -> Self {
match value {
WakeEvent::LowLevel => Event::LowLevel,
WakeEvent::HighLevel => Event::HighLevel,
}
}
}
/// Event used to wake up from light sleep.
#[derive(Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum WakeEvent {
/// Wake on low level
LowLevel = 4,
/// Wake on high level
HighLevel = 5,
}
/// Digital input or output level.
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@ -227,6 +246,9 @@ pub trait Pin: private::Sealed {
/// Clear the interrupt status bit for this Pin
fn clear_interrupt(&mut self, _: private::Internal);
/// Enable this pin as a wake up source
fn wakeup_enable(&mut self, enable: bool, event: WakeEvent, _: private::Internal);
}
/// Trait implemented by pins which can be used as inputs
@ -862,6 +884,10 @@ where
fn clear_interrupt(&mut self, _: private::Internal) {
<Self as GpioProperties>::Bank::write_interrupt_status_clear(1 << (GPIONUM % 32));
}
fn wakeup_enable(&mut self, enable: bool, event: WakeEvent, _: private::Internal) {
self.listen_with_options(event.into(), false, false, enable, private::Internal);
}
}
impl<const GPIONUM: u8> GpioPin<GPIONUM>
@ -1672,6 +1698,14 @@ where
pub fn clear_interrupt(&mut self) {
self.pin.clear_interrupt(private::Internal);
}
/// Enable as a wake-up source.
///
/// This will unlisten for interrupts
#[inline]
pub fn wakeup_enable(&mut self, enable: bool, event: WakeEvent) {
self.pin.wakeup_enable(enable, event, private::Internal);
}
}
/// GPIO open-drain output driver.
@ -2302,6 +2336,12 @@ pub(crate) mod internal {
Pin::clear_interrupt(target, private::Internal)
})
}
fn wakeup_enable(&mut self, enable: bool, event: WakeEvent, _: private::Internal) {
handle_gpio_input!(self, target, {
Pin::wakeup_enable(target, enable, event, private::Internal)
})
}
}
impl InputPin for ErasedPin {

View File

@ -153,6 +153,34 @@ impl Default for WakeFromLpCoreWakeupSource {
}
}
/// GPIO wakeup source
///
/// Wake up from GPIO high or low level. Any pin can be used with this wake up
/// source. Configure the pin for wake up via
/// [crate::gpio::Input::wakeup_enable].
///
/// This wakeup source can be used to wake up from light sleep only.
pub struct GpioWakeupSource {}
impl GpioWakeupSource {
/// Create a new instance of [GpioWakeupSource]
pub fn new() -> Self {
Self {}
}
}
impl Default for GpioWakeupSource {
fn default() -> Self {
Self::new()
}
}
impl WakeSource for GpioWakeupSource {
fn apply(&self, _rtc: &Rtc, triggers: &mut WakeTriggers, _sleep_config: &mut RtcSleepConfig) {
triggers.set_gpio(true);
}
}
#[cfg(not(pmu))]
bitfield::bitfield! {
#[derive(Default, Clone, Copy)]