Add GPIO as wake-up source (#1724)
* Add GPIO as wake-up source * CHANGELOG.md * Clippy * Doc fix
This commit is contained in:
parent
347ef5188b
commit
8cb921f73b
@ -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
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user