nrf/gpiote: update output channel to new API

This commit is contained in:
Dario Nieuwenhuis 2021-03-27 04:01:48 +01:00
parent 2bd9323f28
commit 90f599bc2f
2 changed files with 34 additions and 57 deletions

View File

@ -117,7 +117,7 @@ pub enum OutputDrive {
/// GPIO output driver. /// GPIO output driver.
pub struct Output<'d, T: Pin> { pub struct Output<'d, T: Pin> {
pin: T, pub(crate) pin: T,
phantom: PhantomData<&'d mut T>, phantom: PhantomData<&'d mut T>,
} }

View File

@ -15,7 +15,7 @@ use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
use futures::future::poll_fn; use futures::future::poll_fn;
use crate::gpio::sealed::Pin as _; use crate::gpio::sealed::Pin as _;
use crate::gpio::{AnyPin, Input, Pin as GpioPin, Port, Pull}; use crate::gpio::{AnyPin, Input, Output, Pin as GpioPin, Port, Pull};
use crate::pac; use crate::pac;
use crate::pac::generic::Reg; use crate::pac::generic::Reg;
use crate::pac::gpiote::_TASKS_OUT; use crate::pac::gpiote::_TASKS_OUT;
@ -204,37 +204,35 @@ impl<'d, C: Channel, T: GpioPin> InputPin for InputChannel<'d, C, T> {
} }
} }
/* pub struct OutputChannel<'d, C: Channel, T: GpioPin> {
pub struct OutputChannel<C: ChannelID, T> {
ch: C, ch: C,
pin: GpioPin<Output<T>>, pin: Output<'d, T>,
} }
impl<C: ChannelID, T> Drop for OutputChannel<C, T> { impl<'d, C: Channel, T: GpioPin> Drop for OutputChannel<'d, C, T> {
fn drop(&mut self) { fn drop(&mut self) {
let g = unsafe { &*GPIOTE::ptr() }; let g = unsafe { &*pac::GPIOTE::ptr() };
let index = self.ch.number(); let num = self.ch.number() as usize;
g.config[index].write(|w| w.mode().disabled()); g.config[num].write(|w| w.mode().disabled());
g.intenclr.write(|w| unsafe { w.bits(1 << index) }); g.intenclr.write(|w| unsafe { w.bits(1 << num) });
} }
} }
impl<C: ChannelID, T> OutputChannel<C, T> { impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
pub fn new( pub fn new(
_gpiote: Gpiote, _init: Initialized,
ch: C, ch: C,
pin: GpioPin<Output<T>>, pin: Output<'d, T>,
level: Level,
polarity: OutputChannelPolarity, polarity: OutputChannelPolarity,
) -> Self { ) -> Self {
let g = unsafe { &*GPIOTE::ptr() }; let g = unsafe { &*pac::GPIOTE::ptr() };
let index = ch.number(); let num = ch.number() as usize;
g.config[index].write(|w| { g.config[num].write(|w| {
w.mode().task(); w.mode().task();
match level { match pin.is_set_high().unwrap() {
Level::High => w.outinit().high(), true => w.outinit().high(),
Level::Low => w.outinit().low(), false => w.outinit().low(),
}; };
match polarity { match polarity {
OutputChannelPolarity::Set => w.polarity().lo_to_hi(), OutputChannelPolarity::Set => w.polarity().lo_to_hi(),
@ -242,77 +240,56 @@ impl<C: ChannelID, T> OutputChannel<C, T> {
OutputChannelPolarity::Toggle => w.polarity().toggle(), OutputChannelPolarity::Toggle => w.polarity().toggle(),
}; };
#[cfg(any(feature = "52833", feature = "52840"))] #[cfg(any(feature = "52833", feature = "52840"))]
w.port().bit(match pin.port() { w.port().bit(match pin.pin.port() {
Port::Port0 => false, Port::Port0 => false,
Port::Port1 => true, Port::Port1 => true,
}); });
unsafe { w.psel().bits(pin.pin()) } unsafe { w.psel().bits(pin.pin.pin()) }
}); });
// Enable interrupt
g.intenset.write(|w| unsafe { w.bits(1 << index) });
OutputChannel { ch, pin } OutputChannel { ch, pin }
} }
pub fn free(self) -> (C, GpioPin<Output<T>>) {
let m = ManuallyDrop::new(self);
let ch = unsafe { ptr::read(&m.ch) };
let pin = unsafe { ptr::read(&m.pin) };
(ch, pin)
}
/// Triggers `task out` (as configured with task_out_polarity, defaults to Toggle). /// Triggers `task out` (as configured with task_out_polarity, defaults to Toggle).
pub fn out(&self) { pub fn out(&self) {
let g = unsafe { &*GPIOTE::ptr() }; let g = unsafe { &*pac::GPIOTE::ptr() };
let index = self.ch.number(); g.tasks_out[self.ch.number() as usize].write(|w| unsafe { w.bits(1) });
g.tasks_out[index].write(|w| unsafe { w.bits(1) });
} }
/// Triggers `task set` (set associated pin high). /// Triggers `task set` (set associated pin high).
#[cfg(not(feature = "51"))] #[cfg(not(feature = "51"))]
pub fn set(&self) { pub fn set(&self) {
let g = unsafe { &*GPIOTE::ptr() }; let g = unsafe { &*pac::GPIOTE::ptr() };
let index = self.ch.number(); g.tasks_set[self.ch.number() as usize].write(|w| unsafe { w.bits(1) });
g.tasks_set[index].write(|w| unsafe { w.bits(1) });
} }
/// Triggers `task clear` (set associated pin low). /// Triggers `task clear` (set associated pin low).
#[cfg(not(feature = "51"))] #[cfg(not(feature = "51"))]
pub fn clear(&self) { pub fn clear(&self) {
let g = unsafe { &*GPIOTE::ptr() }; let g = unsafe { &*pac::GPIOTE::ptr() };
let index = self.ch.number(); g.tasks_clr[self.ch.number() as usize].write(|w| unsafe { w.bits(1) });
g.tasks_clr[index].write(|w| unsafe { w.bits(1) });
} }
/// Returns reference to task_out endpoint for PPI. /// Returns reference to task_out endpoint for PPI.
pub fn task_out(&self) -> &Reg<u32, _TASKS_OUT> { pub fn task_out(&self) -> &Reg<u32, _TASKS_OUT> {
let g = unsafe { &*GPIOTE::ptr() }; let g = unsafe { &*pac::GPIOTE::ptr() };
let index = self.ch.number(); &g.tasks_out[self.ch.number() as usize]
&g.tasks_out[index]
} }
/// Returns reference to task_clr endpoint for PPI. /// Returns reference to task_clr endpoint for PPI.
#[cfg(not(feature = "51"))] #[cfg(not(feature = "51"))]
pub fn task_clr(&self) -> &Reg<u32, _TASKS_CLR> { pub fn task_clr(&self) -> &Reg<u32, _TASKS_CLR> {
let g = unsafe { &*GPIOTE::ptr() }; let g = unsafe { &*pac::GPIOTE::ptr() };
let index = self.ch.number(); &g.tasks_clr[self.ch.number() as usize]
&g.tasks_clr[index]
} }
/// Returns reference to task_set endpoint for PPI. /// Returns reference to task_set endpoint for PPI.
#[cfg(not(feature = "51"))] #[cfg(not(feature = "51"))]
pub fn task_set(&self) -> &Reg<u32, _TASKS_SET> { pub fn task_set(&self) -> &Reg<u32, _TASKS_SET> {
let g = unsafe { &*GPIOTE::ptr() }; let g = unsafe { &*pac::GPIOTE::ptr() };
let index = self.ch.number(); &g.tasks_set[self.ch.number() as usize]
&g.tasks_set[index]
} }
} }
*/
/// GPIO input driver with support /// GPIO input driver with support
pub struct PortInput<'d, T: GpioPin> { pub struct PortInput<'d, T: GpioPin> {