From a074cd0625d68e72694c6575063ae53a840d12dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ardelean=20C=C4=83lin=20Petru?= Date: Tue, 22 Nov 2022 16:56:04 +0200 Subject: [PATCH 1/5] Update gpiote.rs Adding these changes enables us to define a channel using a mutable reference to `GPIOTE_CH(n)`, similar to how we can do with other drivers. So instead of using: ```rust let freq_in = InputChannel::new( p.GPIOTE_CH0, Input::new(&mut p.P0_19, embassy_nrf::gpio::Pull::Up), embassy_nrf::gpiote::InputChannelPolarity::HiToLo, ); ``` we can use: ```rust let freq_in = InputChannel::new( &mut p.GPIOTE_CH0, Input::new(&mut p.P0_19, embassy_nrf::gpio::Pull::Up), embassy_nrf::gpiote::InputChannelPolarity::HiToLo, ); ``` --- embassy-nrf/src/gpiote.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 25ad9049..4f11f33e 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -419,6 +419,12 @@ macro_rules! impl_channel { $number as usize } } + impl sealed::Channel for &mut peripherals::$type {} + impl Channel for &mut peripherals::$type { + fn number(&self) -> usize { + $number as usize + } + } }; } From 64c2e1b9b670fda7446a0df6eeb2db5dce2aa1c2 Mon Sep 17 00:00:00 2001 From: Ardelean Calin Date: Tue, 22 Nov 2022 17:35:38 +0200 Subject: [PATCH 2/5] Switched to PeripheralRef for channel. --- embassy-nrf/src/gpiote.rs | 43 ++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 4f11f33e..6fac2c37 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -2,7 +2,7 @@ use core::convert::Infallible; use core::future::{poll_fn, Future}; use core::task::{Context, Poll}; -use embassy_hal_common::{impl_peripheral, Peripheral, PeripheralRef}; +use embassy_hal_common::{impl_peripheral, Peripheral, PeripheralRef, into_ref}; use embassy_sync::waitqueue::AtomicWaker; use crate::gpio::sealed::Pin as _; @@ -148,21 +148,23 @@ impl Iterator for BitIter { /// GPIOTE channel driver in input mode pub struct InputChannel<'d, C: Channel, T: GpioPin> { - ch: C, + _ch: PeripheralRef<'d, C>, pin: Input<'d, T>, } impl<'d, C: Channel, T: GpioPin> Drop for InputChannel<'d, C, T> { fn drop(&mut self) { let g = regs(); - let num = self.ch.number(); + let num = self._ch.number(); g.config[num].write(|w| w.mode().disabled()); g.intenclr.write(|w| unsafe { w.bits(1 << num) }); } } impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { - pub fn new(ch: C, pin: Input<'d, T>, polarity: InputChannelPolarity) -> Self { + pub fn new(ch: impl Peripheral

+ 'd, pin: Input<'d, T>, polarity: InputChannelPolarity) -> Self { + into_ref!(ch); + let g = regs(); let num = ch.number(); @@ -183,12 +185,12 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { g.events_in[num].reset(); - InputChannel { ch, pin } + InputChannel { _ch: ch, pin } } pub async fn wait(&self) { let g = regs(); - let num = self.ch.number(); + let num = self._ch.number(); // Enable interrupt g.events_in[num].reset(); @@ -209,27 +211,28 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { /// Returns the IN event, for use with PPI. pub fn event_in(&self) -> Event { let g = regs(); - Event::from_reg(&g.events_in[self.ch.number()]) + Event::from_reg(&g.events_in[self._ch.number()]) } } /// GPIOTE channel driver in output mode pub struct OutputChannel<'d, C: Channel, T: GpioPin> { - ch: C, + _ch: PeripheralRef<'d, C>, _pin: Output<'d, T>, } impl<'d, C: Channel, T: GpioPin> Drop for OutputChannel<'d, C, T> { fn drop(&mut self) { let g = regs(); - let num = self.ch.number(); + let num = self._ch.number(); g.config[num].write(|w| w.mode().disabled()); g.intenclr.write(|w| unsafe { w.bits(1 << num) }); } } impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> { - pub fn new(ch: C, pin: Output<'d, T>, polarity: OutputChannelPolarity) -> Self { + pub fn new(ch: impl Peripheral

+ 'd, pin: Output<'d, T>, polarity: OutputChannelPolarity) -> Self { + into_ref!(ch); let g = regs(); let num = ch.number(); @@ -252,47 +255,47 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> { unsafe { w.psel().bits(pin.pin.pin.pin()) } }); - OutputChannel { ch, _pin: pin } + OutputChannel { _ch: ch, _pin: pin } } /// Triggers `task out` (as configured with task_out_polarity, defaults to Toggle). pub fn out(&self) { let g = regs(); - g.tasks_out[self.ch.number()].write(|w| unsafe { w.bits(1) }); + g.tasks_out[self._ch.number()].write(|w| unsafe { w.bits(1) }); } /// Triggers `task set` (set associated pin high). #[cfg(not(feature = "nrf51"))] pub fn set(&self) { let g = regs(); - g.tasks_set[self.ch.number()].write(|w| unsafe { w.bits(1) }); + g.tasks_set[self._ch.number()].write(|w| unsafe { w.bits(1) }); } /// Triggers `task clear` (set associated pin low). #[cfg(not(feature = "nrf51"))] pub fn clear(&self) { let g = regs(); - g.tasks_clr[self.ch.number()].write(|w| unsafe { w.bits(1) }); + g.tasks_clr[self._ch.number()].write(|w| unsafe { w.bits(1) }); } /// Returns the OUT task, for use with PPI. pub fn task_out(&self) -> Task { let g = regs(); - Task::from_reg(&g.tasks_out[self.ch.number()]) + Task::from_reg(&g.tasks_out[self._ch.number()]) } /// Returns the CLR task, for use with PPI. #[cfg(not(feature = "nrf51"))] pub fn task_clr(&self) -> Task { let g = regs(); - Task::from_reg(&g.tasks_clr[self.ch.number()]) + Task::from_reg(&g.tasks_clr[self._ch.number()]) } /// Returns the SET task, for use with PPI. #[cfg(not(feature = "nrf51"))] pub fn task_set(&self) -> Task { let g = regs(); - Task::from_reg(&g.tasks_set[self.ch.number()]) + Task::from_reg(&g.tasks_set[self._ch.number()]) } } @@ -419,12 +422,6 @@ macro_rules! impl_channel { $number as usize } } - impl sealed::Channel for &mut peripherals::$type {} - impl Channel for &mut peripherals::$type { - fn number(&self) -> usize { - $number as usize - } - } }; } From e7c876d7444fb24ad854bd7339c480874f72dbe2 Mon Sep 17 00:00:00 2001 From: Ardelean Calin Date: Tue, 22 Nov 2022 17:36:22 +0200 Subject: [PATCH 3/5] Changed pin to private as it is for OutputChannel --- embassy-nrf/src/gpiote.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 6fac2c37..e3be0240 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -149,7 +149,7 @@ impl Iterator for BitIter { /// GPIOTE channel driver in input mode pub struct InputChannel<'d, C: Channel, T: GpioPin> { _ch: PeripheralRef<'d, C>, - pin: Input<'d, T>, + _pin: Input<'d, T>, } impl<'d, C: Channel, T: GpioPin> Drop for InputChannel<'d, C, T> { @@ -185,7 +185,7 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { g.events_in[num].reset(); - InputChannel { _ch: ch, pin } + InputChannel { _ch: ch, _pin: pin } } pub async fn wait(&self) { @@ -443,11 +443,11 @@ mod eh02 { type Error = Infallible; fn is_high(&self) -> Result { - Ok(self.pin.is_high()) + Ok(self._pin.is_high()) } fn is_low(&self) -> Result { - Ok(self.pin.is_low()) + Ok(self._pin.is_low()) } } } @@ -462,11 +462,11 @@ mod eh1 { impl<'d, C: Channel, T: GpioPin> embedded_hal_1::digital::InputPin for InputChannel<'d, C, T> { fn is_high(&self) -> Result { - Ok(self.pin.is_high()) + Ok(self._pin.is_high()) } fn is_low(&self) -> Result { - Ok(self.pin.is_low()) + Ok(self._pin.is_low()) } } } From 4f2f3757773fb30700c3c6ee7ab98cd6e38406a3 Mon Sep 17 00:00:00 2001 From: Ardelean Calin Date: Tue, 22 Nov 2022 17:45:05 +0200 Subject: [PATCH 4/5] Corrected order of use statements. --- embassy-nrf/src/gpiote.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index e3be0240..4d5fa62b 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -2,7 +2,7 @@ use core::convert::Infallible; use core::future::{poll_fn, Future}; use core::task::{Context, Poll}; -use embassy_hal_common::{impl_peripheral, Peripheral, PeripheralRef, into_ref}; +use embassy_hal_common::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; use crate::gpio::sealed::Pin as _; From eae67d0be888d12e71bc3340279bab85666c05ae Mon Sep 17 00:00:00 2001 From: Ardelean Calin Date: Wed, 23 Nov 2022 14:16:18 +0200 Subject: [PATCH 5/5] Review comments. Corrected unused fields. --- embassy-nrf/src/gpiote.rs | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 4d5fa62b..7f7468a2 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -148,14 +148,14 @@ impl Iterator for BitIter { /// GPIOTE channel driver in input mode pub struct InputChannel<'d, C: Channel, T: GpioPin> { - _ch: PeripheralRef<'d, C>, - _pin: Input<'d, T>, + ch: PeripheralRef<'d, C>, + pin: Input<'d, T>, } impl<'d, C: Channel, T: GpioPin> Drop for InputChannel<'d, C, T> { fn drop(&mut self) { let g = regs(); - let num = self._ch.number(); + let num = self.ch.number(); g.config[num].write(|w| w.mode().disabled()); g.intenclr.write(|w| unsafe { w.bits(1 << num) }); } @@ -185,12 +185,12 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { g.events_in[num].reset(); - InputChannel { _ch: ch, _pin: pin } + InputChannel { ch, pin } } pub async fn wait(&self) { let g = regs(); - let num = self._ch.number(); + let num = self.ch.number(); // Enable interrupt g.events_in[num].reset(); @@ -211,20 +211,20 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { /// Returns the IN event, for use with PPI. pub fn event_in(&self) -> Event { let g = regs(); - Event::from_reg(&g.events_in[self._ch.number()]) + Event::from_reg(&g.events_in[self.ch.number()]) } } /// GPIOTE channel driver in output mode pub struct OutputChannel<'d, C: Channel, T: GpioPin> { - _ch: PeripheralRef<'d, C>, + ch: PeripheralRef<'d, C>, _pin: Output<'d, T>, } impl<'d, C: Channel, T: GpioPin> Drop for OutputChannel<'d, C, T> { fn drop(&mut self) { let g = regs(); - let num = self._ch.number(); + let num = self.ch.number(); g.config[num].write(|w| w.mode().disabled()); g.intenclr.write(|w| unsafe { w.bits(1 << num) }); } @@ -255,47 +255,47 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> { unsafe { w.psel().bits(pin.pin.pin.pin()) } }); - OutputChannel { _ch: ch, _pin: pin } + OutputChannel { ch, _pin: pin } } /// Triggers `task out` (as configured with task_out_polarity, defaults to Toggle). pub fn out(&self) { let g = regs(); - g.tasks_out[self._ch.number()].write(|w| unsafe { w.bits(1) }); + g.tasks_out[self.ch.number()].write(|w| unsafe { w.bits(1) }); } /// Triggers `task set` (set associated pin high). #[cfg(not(feature = "nrf51"))] pub fn set(&self) { let g = regs(); - g.tasks_set[self._ch.number()].write(|w| unsafe { w.bits(1) }); + g.tasks_set[self.ch.number()].write(|w| unsafe { w.bits(1) }); } /// Triggers `task clear` (set associated pin low). #[cfg(not(feature = "nrf51"))] pub fn clear(&self) { let g = regs(); - g.tasks_clr[self._ch.number()].write(|w| unsafe { w.bits(1) }); + g.tasks_clr[self.ch.number()].write(|w| unsafe { w.bits(1) }); } /// Returns the OUT task, for use with PPI. pub fn task_out(&self) -> Task { let g = regs(); - Task::from_reg(&g.tasks_out[self._ch.number()]) + Task::from_reg(&g.tasks_out[self.ch.number()]) } /// Returns the CLR task, for use with PPI. #[cfg(not(feature = "nrf51"))] pub fn task_clr(&self) -> Task { let g = regs(); - Task::from_reg(&g.tasks_clr[self._ch.number()]) + Task::from_reg(&g.tasks_clr[self.ch.number()]) } /// Returns the SET task, for use with PPI. #[cfg(not(feature = "nrf51"))] pub fn task_set(&self) -> Task { let g = regs(); - Task::from_reg(&g.tasks_set[self._ch.number()]) + Task::from_reg(&g.tasks_set[self.ch.number()]) } } @@ -443,11 +443,11 @@ mod eh02 { type Error = Infallible; fn is_high(&self) -> Result { - Ok(self._pin.is_high()) + Ok(self.pin.is_high()) } fn is_low(&self) -> Result { - Ok(self._pin.is_low()) + Ok(self.pin.is_low()) } } } @@ -462,11 +462,11 @@ mod eh1 { impl<'d, C: Channel, T: GpioPin> embedded_hal_1::digital::InputPin for InputChannel<'d, C, T> { fn is_high(&self) -> Result { - Ok(self._pin.is_high()) + Ok(self.pin.is_high()) } fn is_low(&self) -> Result { - Ok(self._pin.is_low()) + Ok(self.pin.is_low()) } } }