nrf/gpio: allow borrowed pins.
This commit is contained in:
parent
806ee120ba
commit
a08d781442
@ -19,7 +19,7 @@ use embassy_nrf::interrupt;
|
|||||||
use embassy_nrf::Peripherals;
|
use embassy_nrf::Peripherals;
|
||||||
use example_common::*;
|
use example_common::*;
|
||||||
|
|
||||||
async fn button(n: usize, mut pin: PortInput<AnyPin>) {
|
async fn button(n: usize, mut pin: PortInput<'static, AnyPin>) {
|
||||||
loop {
|
loop {
|
||||||
Pin::new(&mut pin).wait_for_low().await;
|
Pin::new(&mut pin).wait_for_low().await;
|
||||||
info!("Button {:?} pressed!", n);
|
info!("Button {:?} pressed!", n);
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use core::convert::Infallible;
|
use core::convert::Infallible;
|
||||||
use core::hint::unreachable_unchecked;
|
use core::hint::unreachable_unchecked;
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use embassy::util::PeripheralBorrow;
|
use embassy::util::PeripheralBorrow;
|
||||||
|
use embassy_extras::unborrow;
|
||||||
use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
|
use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
|
||||||
use gpio::pin_cnf::DRIVE_A;
|
use gpio::pin_cnf::DRIVE_A;
|
||||||
|
|
||||||
@ -30,12 +32,15 @@ pub enum Pull {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// GPIO input driver.
|
/// GPIO input driver.
|
||||||
pub struct Input<T: Pin> {
|
pub struct Input<'d, T: Pin> {
|
||||||
pub(crate) pin: T,
|
pub(crate) pin: T,
|
||||||
|
phantom: PhantomData<&'d mut T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Pin> Input<T> {
|
impl<'d, T: Pin> Input<'d, T> {
|
||||||
pub fn new(pin: T, pull: Pull) -> Self {
|
pub fn new(pin: impl PeripheralBorrow<Target = T> + 'd, pull: Pull) -> Self {
|
||||||
|
unborrow!(pin);
|
||||||
|
|
||||||
pin.conf().write(|w| {
|
pin.conf().write(|w| {
|
||||||
w.dir().input();
|
w.dir().input();
|
||||||
w.input().connect();
|
w.input().connect();
|
||||||
@ -55,17 +60,20 @@ impl<T: Pin> Input<T> {
|
|||||||
w
|
w
|
||||||
});
|
});
|
||||||
|
|
||||||
Self { pin }
|
Self {
|
||||||
|
pin,
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Pin> Drop for Input<T> {
|
impl<'d, T: Pin> Drop for Input<'d, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.pin.conf().reset();
|
self.pin.conf().reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Pin> InputPin for Input<T> {
|
impl<'d, T: Pin> InputPin for Input<'d, T> {
|
||||||
type Error = Infallible;
|
type Error = Infallible;
|
||||||
|
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
@ -108,12 +116,19 @@ pub enum OutputDrive {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// GPIO output driver.
|
/// GPIO output driver.
|
||||||
pub struct Output<T: Pin> {
|
pub struct Output<'d, T: Pin> {
|
||||||
pin: T,
|
pin: T,
|
||||||
|
phantom: PhantomData<&'d mut T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Pin> Output<T> {
|
impl<'d, T: Pin> Output<'d, T> {
|
||||||
pub fn new(pin: T, initial_output: Level, drive: OutputDrive) -> Self {
|
pub fn new(
|
||||||
|
pin: impl PeripheralBorrow<Target = T> + 'd,
|
||||||
|
initial_output: Level,
|
||||||
|
drive: OutputDrive,
|
||||||
|
) -> Self {
|
||||||
|
unborrow!(pin);
|
||||||
|
|
||||||
match initial_output {
|
match initial_output {
|
||||||
Level::High => pin.set_high(),
|
Level::High => pin.set_high(),
|
||||||
Level::Low => pin.set_low(),
|
Level::Low => pin.set_low(),
|
||||||
@ -139,17 +154,20 @@ impl<T: Pin> Output<T> {
|
|||||||
w
|
w
|
||||||
});
|
});
|
||||||
|
|
||||||
Self { pin }
|
Self {
|
||||||
|
pin,
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Pin> Drop for Output<T> {
|
impl<'d, T: Pin> Drop for Output<'d, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.pin.conf().reset();
|
self.pin.conf().reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Pin> OutputPin for Output<T> {
|
impl<'d, T: Pin> OutputPin for Output<'d, T> {
|
||||||
type Error = Infallible;
|
type Error = Infallible;
|
||||||
|
|
||||||
/// Set the output as high.
|
/// Set the output as high.
|
||||||
@ -175,7 +193,7 @@ impl<T: Pin> OutputPin for Output<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Pin> StatefulOutputPin for Output<T> {
|
impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> {
|
||||||
/// Is the output pin set as high?
|
/// Is the output pin set as high?
|
||||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||||
self.is_set_low().map(|v| !v)
|
self.is_set_low().map(|v| !v)
|
||||||
|
@ -9,7 +9,7 @@ use core::ptr;
|
|||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
use embassy::interrupt::InterruptExt;
|
use embassy::interrupt::InterruptExt;
|
||||||
use embassy::traits::gpio::{WaitForHigh, WaitForLow};
|
use embassy::traits::gpio::{WaitForHigh, WaitForLow};
|
||||||
use embassy::util::{AtomicWakerRegistration, Signal};
|
use embassy::util::{AtomicWakerRegistration, PeripheralBorrow, Signal};
|
||||||
use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
|
use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
|
||||||
|
|
||||||
use crate::gpio::sealed::Pin as _;
|
use crate::gpio::sealed::Pin as _;
|
||||||
@ -338,18 +338,19 @@ impl<C: ChannelID, T> OutputChannel<C, T> {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// GPIO input driver with support
|
/// GPIO input driver with support
|
||||||
pub struct PortInput<T: GpioPin> {
|
pub struct PortInput<'d, T: GpioPin> {
|
||||||
pin: Input<T>,
|
pin: Input<'d, T>,
|
||||||
}
|
}
|
||||||
impl<T: GpioPin> Unpin for PortInput<T> {}
|
|
||||||
|
|
||||||
impl<T: GpioPin> PortInput<T> {
|
impl<'d, T: GpioPin> Unpin for PortInput<'d, T> {}
|
||||||
pub fn new(_init: Initialized, pin: Input<T>) -> Self {
|
|
||||||
|
impl<'d, T: GpioPin> PortInput<'d, T> {
|
||||||
|
pub fn new(_init: Initialized, pin: Input<'d, T>) -> Self {
|
||||||
Self { pin }
|
Self { pin }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: GpioPin> InputPin for PortInput<T> {
|
impl<'d, T: GpioPin> InputPin for PortInput<'d, T> {
|
||||||
type Error = Infallible;
|
type Error = Infallible;
|
||||||
|
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
@ -361,7 +362,7 @@ impl<T: GpioPin> InputPin for PortInput<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: GpioPin> WaitForHigh for PortInput<T> {
|
impl<'d, T: GpioPin> WaitForHigh for PortInput<'d, T> {
|
||||||
type Future<'a> = PortInputFuture<'a>;
|
type Future<'a> = PortInputFuture<'a>;
|
||||||
|
|
||||||
fn wait_for_high<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
|
fn wait_for_high<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
|
||||||
@ -374,7 +375,7 @@ impl<T: GpioPin> WaitForHigh for PortInput<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: GpioPin> WaitForLow for PortInput<T> {
|
impl<'d, T: GpioPin> WaitForLow for PortInput<'d, T> {
|
||||||
type Future<'a> = PortInputFuture<'a>;
|
type Future<'a> = PortInputFuture<'a>;
|
||||||
|
|
||||||
fn wait_for_low<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
|
fn wait_for_low<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
|
||||||
|
Loading…
Reference in New Issue
Block a user