From 6e1d6be315957e587051df7bf96f4a87fc748117 Mon Sep 17 00:00:00 2001 From: Matthew Tran <0e4ef622@gmail.com> Date: Sat, 20 Sep 2025 11:55:59 -0500 Subject: [PATCH] nrf: add persist() method for gpio and ppi --- embassy-nrf/CHANGELOG.md | 1 + embassy-nrf/src/gpio.rs | 27 +++++++++++++++++++++++++++ embassy-nrf/src/ppi/dppi.rs | 9 +++++++++ embassy-nrf/src/ppi/mod.rs | 8 ++++++++ embassy-nrf/src/ppi/ppi.rs | 9 +++++++++ embassy-nrf/src/timer.rs | 4 ++-- 6 files changed, 56 insertions(+), 2 deletions(-) diff --git a/embassy-nrf/CHANGELOG.md b/embassy-nrf/CHANGELOG.md index befa34ecf..de8dfd391 100644 --- a/embassy-nrf/CHANGELOG.md +++ b/embassy-nrf/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - changed: nrf54l: Disable glitch detection and enable DC/DC in init. - changed: Add embassy-net-driver-channel implementation for IEEE 802.15.4 +- changed: add persist() method for gpio and ppi ## 0.7.0 - 2025-08-26 diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs index 65f2d99f7..0cea38777 100644 --- a/embassy-nrf/src/gpio.rs +++ b/embassy-nrf/src/gpio.rs @@ -75,6 +75,15 @@ impl<'d> Input<'d> { } } +impl Input<'static> { + /// Persist the pin's configuration for the rest of the program's lifetime. This method should + /// be preferred over [`core::mem::forget()`] because the `'static` bound prevents accidental + /// reuse of the underlying peripheral. + pub fn persist(self) { + self.pin.persist() + } +} + /// Digital input or output level. #[derive(Clone, Copy, Debug, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -264,6 +273,15 @@ impl<'d> Output<'d> { } } +impl Output<'static> { + /// Persist the pin's configuration for the rest of the program's lifetime. This method should + /// be preferred over [`core::mem::forget()`] because the `'static` bound prevents accidental + /// reuse of the underlying peripheral. + pub fn persist(self) { + self.pin.persist() + } +} + pub(crate) fn convert_drive(w: &mut pac::gpio::regs::PinCnf, drive: OutputDrive) { #[cfg(not(feature = "_nrf54l"))] { @@ -447,6 +465,15 @@ impl<'d> Flex<'d> { } } +impl Flex<'static> { + /// Persist the pin's configuration for the rest of the program's lifetime. This method should + /// be preferred over [`core::mem::forget()`] because the `'static` bound prevents accidental + /// reuse of the underlying peripheral. + pub fn persist(self) { + core::mem::forget(self); + } +} + impl<'d> Drop for Flex<'d> { fn drop(&mut self) { self.set_as_disconnected(); diff --git a/embassy-nrf/src/ppi/dppi.rs b/embassy-nrf/src/ppi/dppi.rs index 686f66987..078d2fd1c 100644 --- a/embassy-nrf/src/ppi/dppi.rs +++ b/embassy-nrf/src/ppi/dppi.rs @@ -59,6 +59,15 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Ppi<'d, } } +impl Ppi<'static, C, EVENT_COUNT, TASK_COUNT> { + /// Persist the channel's configuration for the rest of the program's lifetime. This method + /// should be preferred over [`core::mem::forget()`] because the `'static` bound prevents + /// accidental reuse of the underlying peripheral. + pub fn persist(self) { + core::mem::forget(self); + } +} + impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop for Ppi<'d, C, EVENT_COUNT, TASK_COUNT> { fn drop(&mut self) { self.disable(); diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs index 531777205..2bcf72e9c 100644 --- a/embassy-nrf/src/ppi/mod.rs +++ b/embassy-nrf/src/ppi/mod.rs @@ -108,6 +108,14 @@ impl<'d, G: Group> PpiGroup<'d, G> { Task::from_reg(regs().tasks_chg(n).dis()) } } +impl PpiGroup<'static, G> { + /// Persist this group's configuration for the rest of the program's lifetime. This method + /// should be preferred over [`core::mem::forget()`] because the `'static` bound prevents + /// accidental reuse of the underlying peripheral. + pub fn persist(self) { + core::mem::forget(self); + } +} impl<'d, G: Group> Drop for PpiGroup<'d, G> { fn drop(&mut self) { diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs index e04dacbc0..531c25444 100644 --- a/embassy-nrf/src/ppi/ppi.rs +++ b/embassy-nrf/src/ppi/ppi.rs @@ -68,6 +68,15 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Ppi<'d, } } +impl Ppi<'static, C, EVENT_COUNT, TASK_COUNT> { + /// Persist the channel's configuration for the rest of the program's lifetime. This method + /// should be preferred over [`core::mem::forget()`] because the `'static` bound prevents + /// accidental reuse of the underlying peripheral. + pub fn persist(self) { + core::mem::forget(self); + } +} + impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop for Ppi<'d, C, EVENT_COUNT, TASK_COUNT> { fn drop(&mut self) { self.disable(); diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index 5b58b0a50..de2875765 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs @@ -90,7 +90,7 @@ pub struct Timer<'d, T: Instance> { impl<'d, T: Instance> Timer<'d, T> { /// Create a new `Timer` driver. /// - /// This can be useful for triggering tasks via PPI + /// This can be useful for triggering tasks via PPI. /// `Uarte` uses this internally. pub fn new(timer: Peri<'d, T>) -> Self { Self::new_inner(timer, false) @@ -98,7 +98,7 @@ impl<'d, T: Instance> Timer<'d, T> { /// Create a new `Timer` driver in counter mode. /// - /// This can be useful for triggering tasks via PPI + /// This can be useful for triggering tasks via PPI. /// `Uarte` uses this internally. pub fn new_counter(timer: Peri<'d, T>) -> Self { Self::new_inner(timer, true)