nrf/gpio: add infallible inherent methods, remove some duplication.
This implements Input and Output using FlexPin, to avoid some code duplication.
This commit is contained in:
parent
fcb43caa36
commit
22bc1e4ae1
6 changed files with 221 additions and 262 deletions
|
@ -14,14 +14,13 @@ use embassy_nrf::{
|
|||
peripherals::P0_13,
|
||||
Peripherals,
|
||||
};
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
|
||||
#[embassy::task]
|
||||
async fn blinker(mut led: Output<'static, P0_13>, interval: Duration) {
|
||||
loop {
|
||||
unwrap!(led.set_high());
|
||||
led.set_high();
|
||||
Timer::after(interval).await;
|
||||
unwrap!(led.set_low());
|
||||
led.set_low();
|
||||
Timer::after(interval).await;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#![macro_use]
|
||||
|
||||
use core::convert::Infallible;
|
||||
use core::future::Future;
|
||||
use core::hint::unreachable_unchecked;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
|
@ -38,26 +37,23 @@ pub enum Pull {
|
|||
|
||||
/// GPIO input driver.
|
||||
pub struct Input<'d, T: Pin> {
|
||||
pub(crate) pin: T,
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
pub(crate) pin: FlexPin<'d, T>,
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> Input<'d, T> {
|
||||
pub fn new(pin: impl Unborrow<Target = T> + 'd, pull: Pull) -> Self {
|
||||
unborrow!(pin);
|
||||
let mut pin = FlexPin::new(pin);
|
||||
pin.set_as_input(pull);
|
||||
|
||||
init_input(&pin, pull);
|
||||
|
||||
Self {
|
||||
pin,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Self { pin }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> Drop for Input<'d, T> {
|
||||
fn drop(&mut self) {
|
||||
self.pin.conf().reset();
|
||||
fn is_high(&self) -> bool {
|
||||
self.pin.is_high()
|
||||
}
|
||||
|
||||
fn is_low(&self) -> bool {
|
||||
self.pin.is_low()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,65 +61,11 @@ impl<'d, T: Pin> InputPin for Input<'d, T> {
|
|||
type Error = Infallible;
|
||||
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
self.is_low().map(|v| !v)
|
||||
Ok(self.is_high())
|
||||
}
|
||||
|
||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.pin.block().in_.read().bits() & (1 << self.pin.pin()) == 0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gpiote")]
|
||||
impl<'d, T: Pin> embassy::traits::gpio::WaitForHigh for Input<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + Unpin + 'a;
|
||||
|
||||
fn wait_for_high<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
self.pin.conf().modify(|_, w| w.sense().high());
|
||||
|
||||
crate::gpiote::PortInputFuture {
|
||||
pin_port: self.pin.pin_port(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gpiote")]
|
||||
impl<'d, T: Pin> embassy::traits::gpio::WaitForLow for Input<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + Unpin + 'a;
|
||||
|
||||
fn wait_for_low<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
self.pin.conf().modify(|_, w| w.sense().low());
|
||||
|
||||
crate::gpiote::PortInputFuture {
|
||||
pin_port: self.pin.pin_port(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gpiote")]
|
||||
impl<'d, T: Pin> embassy::traits::gpio::WaitForAnyEdge for Input<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + Unpin + 'a;
|
||||
|
||||
fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
if self.is_high().ok().unwrap() {
|
||||
self.pin.conf().modify(|_, w| w.sense().low());
|
||||
} else {
|
||||
self.pin.conf().modify(|_, w| w.sense().high());
|
||||
}
|
||||
crate::gpiote::PortInputFuture {
|
||||
pin_port: self.pin.pin_port(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Ok(self.is_low())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,8 +102,7 @@ pub enum OutputDrive {
|
|||
|
||||
/// GPIO output driver.
|
||||
pub struct Output<'d, T: Pin> {
|
||||
pub(crate) pin: T,
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
pub(crate) pin: FlexPin<'d, T>,
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> Output<'d, T> {
|
||||
|
@ -170,63 +111,56 @@ impl<'d, T: Pin> Output<'d, T> {
|
|||
initial_output: Level,
|
||||
drive: OutputDrive,
|
||||
) -> Self {
|
||||
unborrow!(pin);
|
||||
|
||||
let mut pin = FlexPin::new(pin);
|
||||
match initial_output {
|
||||
Level::High => pin.set_high(),
|
||||
Level::Low => pin.set_low(),
|
||||
}
|
||||
pin.set_as_output(drive);
|
||||
|
||||
init_output(&pin, drive);
|
||||
|
||||
Self {
|
||||
pin,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Self { pin }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> Drop for Output<'d, T> {
|
||||
fn drop(&mut self) {
|
||||
self.pin.conf().reset();
|
||||
/// Set the output as high.
|
||||
pub fn set_high(&mut self) {
|
||||
self.pin.set_high()
|
||||
}
|
||||
|
||||
/// Set the output as low.
|
||||
pub fn set_low(&mut self) {
|
||||
self.pin.set_low()
|
||||
}
|
||||
|
||||
/// Is the output pin set as high?
|
||||
pub fn is_set_high(&self) -> bool {
|
||||
self.pin.is_set_high()
|
||||
}
|
||||
|
||||
/// Is the output pin set as low?
|
||||
pub fn is_set_low(&self) -> bool {
|
||||
self.pin.is_set_low()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> OutputPin for Output<'d, T> {
|
||||
type Error = Infallible;
|
||||
|
||||
/// Set the output as high.
|
||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||
unsafe {
|
||||
self.pin
|
||||
.block()
|
||||
.outset
|
||||
.write(|w| w.bits(1u32 << self.pin.pin()));
|
||||
}
|
||||
Ok(())
|
||||
Ok(self.set_high())
|
||||
}
|
||||
|
||||
/// Set the output as low.
|
||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||
unsafe {
|
||||
self.pin
|
||||
.block()
|
||||
.outclr
|
||||
.write(|w| w.bits(1u32 << self.pin.pin()));
|
||||
}
|
||||
Ok(())
|
||||
Ok(self.set_low())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> {
|
||||
/// Is the output pin set as high?
|
||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||
self.is_set_low().map(|v| !v)
|
||||
Ok(self.is_set_high())
|
||||
}
|
||||
|
||||
/// Is the output pin set as low?
|
||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.pin.block().out.read().bits() & (1 << self.pin.pin()) == 0)
|
||||
Ok(self.is_set_low())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,7 +190,24 @@ impl<'d, T: Pin> FlexPin<'d, T> {
|
|||
|
||||
/// Put the pin into input mode.
|
||||
pub fn set_as_input(&mut self, pull: Pull) {
|
||||
init_input(&self.pin, pull);
|
||||
self.pin.conf().write(|w| {
|
||||
w.dir().input();
|
||||
w.input().connect();
|
||||
match pull {
|
||||
Pull::None => {
|
||||
w.pull().disabled();
|
||||
}
|
||||
Pull::Up => {
|
||||
w.pull().pullup();
|
||||
}
|
||||
Pull::Down => {
|
||||
w.pull().pulldown();
|
||||
}
|
||||
}
|
||||
w.drive().s0s1();
|
||||
w.sense().disabled();
|
||||
w
|
||||
});
|
||||
}
|
||||
|
||||
/// Put the pin into output mode.
|
||||
|
@ -264,13 +215,59 @@ impl<'d, T: Pin> FlexPin<'d, T> {
|
|||
/// The pin level will be whatever was set before (or low by default). If you want it to begin
|
||||
/// at a specific level, call `set_high`/`set_low` on the pin first.
|
||||
pub fn set_as_output(&mut self, drive: OutputDrive) {
|
||||
init_output(&self.pin, drive);
|
||||
let drive = match drive {
|
||||
OutputDrive::Standard => DRIVE_A::S0S1,
|
||||
OutputDrive::HighDrive0Standard1 => DRIVE_A::H0S1,
|
||||
OutputDrive::Standard0HighDrive1 => DRIVE_A::S0H1,
|
||||
OutputDrive::HighDrive => DRIVE_A::H0H1,
|
||||
OutputDrive::Disconnect0Standard1 => DRIVE_A::D0S1,
|
||||
OutputDrive::Disconnect0HighDrive1 => DRIVE_A::D0H1,
|
||||
OutputDrive::Standard0Disconnect1 => DRIVE_A::S0D1,
|
||||
OutputDrive::HighDrive0Disconnect1 => DRIVE_A::H0D1,
|
||||
};
|
||||
|
||||
self.pin.conf().write(|w| {
|
||||
w.dir().output();
|
||||
w.input().disconnect();
|
||||
w.pull().disabled();
|
||||
w.drive().variant(drive);
|
||||
w.sense().disabled();
|
||||
w
|
||||
});
|
||||
}
|
||||
|
||||
/// Put the pin into disconnected mode.
|
||||
pub fn set_as_disconnected(&mut self) {
|
||||
self.pin.conf().reset();
|
||||
}
|
||||
|
||||
pub fn is_high(&self) -> bool {
|
||||
!self.is_low()
|
||||
}
|
||||
|
||||
pub fn is_low(&self) -> bool {
|
||||
self.pin.block().in_.read().bits() & (1 << self.pin.pin()) == 0
|
||||
}
|
||||
|
||||
/// Set the output as high.
|
||||
pub fn set_high(&mut self) {
|
||||
self.pin.set_high()
|
||||
}
|
||||
|
||||
/// Set the output as low.
|
||||
pub fn set_low(&mut self) {
|
||||
self.pin.set_low()
|
||||
}
|
||||
|
||||
/// Is the output pin set as high?
|
||||
pub fn is_set_high(&self) -> bool {
|
||||
!self.is_set_low()
|
||||
}
|
||||
|
||||
/// Is the output pin set as low?
|
||||
pub fn is_set_low(&self) -> bool {
|
||||
self.pin.block().out.read().bits() & (1 << self.pin.pin()) == 0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> Drop for FlexPin<'d, T> {
|
||||
|
@ -286,103 +283,33 @@ impl<'d, T: Pin> InputPin for FlexPin<'d, T> {
|
|||
type Error = Infallible;
|
||||
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
self.is_low().map(|v| !v)
|
||||
Ok(self.is_high())
|
||||
}
|
||||
|
||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.pin.block().in_.read().bits() & (1 << self.pin.pin()) == 0)
|
||||
Ok(self.is_low())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> OutputPin for FlexPin<'d, T> {
|
||||
type Error = Infallible;
|
||||
|
||||
/// Set the output as high.
|
||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||
unsafe {
|
||||
self.pin
|
||||
.block()
|
||||
.outset
|
||||
.write(|w| w.bits(1u32 << self.pin.pin()));
|
||||
}
|
||||
Ok(())
|
||||
Ok(self.set_high())
|
||||
}
|
||||
|
||||
/// Set the output as low.
|
||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||
unsafe {
|
||||
self.pin
|
||||
.block()
|
||||
.outclr
|
||||
.write(|w| w.bits(1u32 << self.pin.pin()));
|
||||
}
|
||||
Ok(())
|
||||
Ok(self.set_low())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> StatefulOutputPin for FlexPin<'d, T> {
|
||||
/// Is the output pin set as high?
|
||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||
self.is_set_low().map(|v| !v)
|
||||
Ok(self.is_set_high())
|
||||
}
|
||||
|
||||
/// Is the output pin set as low?
|
||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.pin.block().out.read().bits() & (1 << self.pin.pin()) == 0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gpiote")]
|
||||
impl<'d, T: Pin> embassy::traits::gpio::WaitForHigh for FlexPin<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + Unpin + 'a;
|
||||
|
||||
fn wait_for_high<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
self.pin.conf().modify(|_, w| w.sense().high());
|
||||
|
||||
crate::gpiote::PortInputFuture {
|
||||
pin_port: self.pin.pin_port(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gpiote")]
|
||||
impl<'d, T: Pin> embassy::traits::gpio::WaitForLow for FlexPin<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + Unpin + 'a;
|
||||
|
||||
fn wait_for_low<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
self.pin.conf().modify(|_, w| w.sense().low());
|
||||
|
||||
crate::gpiote::PortInputFuture {
|
||||
pin_port: self.pin.pin_port(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gpiote")]
|
||||
impl<'d, T: Pin> embassy::traits::gpio::WaitForAnyEdge for FlexPin<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + Unpin + 'a;
|
||||
|
||||
fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
if self.is_high().ok().unwrap() {
|
||||
self.pin.conf().modify(|_, w| w.sense().low());
|
||||
} else {
|
||||
self.pin.conf().modify(|_, w| w.sense().high());
|
||||
}
|
||||
crate::gpiote::PortInputFuture {
|
||||
pin_port: self.pin.pin_port(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Ok(self.is_set_low())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -493,55 +420,6 @@ impl sealed::Pin for AnyPin {
|
|||
}
|
||||
}
|
||||
|
||||
// =====================
|
||||
|
||||
/// Set up a pin for input
|
||||
#[inline]
|
||||
fn init_input<T: Pin>(pin: &T, pull: Pull) {
|
||||
pin.conf().write(|w| {
|
||||
w.dir().input();
|
||||
w.input().connect();
|
||||
match pull {
|
||||
Pull::None => {
|
||||
w.pull().disabled();
|
||||
}
|
||||
Pull::Up => {
|
||||
w.pull().pullup();
|
||||
}
|
||||
Pull::Down => {
|
||||
w.pull().pulldown();
|
||||
}
|
||||
}
|
||||
w.drive().s0s1();
|
||||
w.sense().disabled();
|
||||
w
|
||||
});
|
||||
}
|
||||
|
||||
/// Set up a pin for output
|
||||
#[inline]
|
||||
fn init_output<T: Pin>(pin: &T, drive: OutputDrive) {
|
||||
let drive = match drive {
|
||||
OutputDrive::Standard => DRIVE_A::S0S1,
|
||||
OutputDrive::HighDrive0Standard1 => DRIVE_A::H0S1,
|
||||
OutputDrive::Standard0HighDrive1 => DRIVE_A::S0H1,
|
||||
OutputDrive::HighDrive => DRIVE_A::H0H1,
|
||||
OutputDrive::Disconnect0Standard1 => DRIVE_A::D0S1,
|
||||
OutputDrive::Disconnect0HighDrive1 => DRIVE_A::D0H1,
|
||||
OutputDrive::Standard0Disconnect1 => DRIVE_A::S0D1,
|
||||
OutputDrive::HighDrive0Disconnect1 => DRIVE_A::H0D1,
|
||||
};
|
||||
|
||||
pin.conf().write(|w| {
|
||||
w.dir().output();
|
||||
w.input().disconnect();
|
||||
w.pull().disabled();
|
||||
w.drive().variant(drive);
|
||||
w.sense().disabled();
|
||||
w
|
||||
});
|
||||
}
|
||||
|
||||
// ====================
|
||||
|
||||
pub trait OptionalPin: Unborrow<Target = Self> + sealed::OptionalPin + Sized {
|
||||
|
@ -601,9 +479,7 @@ pub(crate) fn deconfigure_pin(psel_bits: u32) {
|
|||
if psel_bits & 0x8000_0000 != 0 {
|
||||
return;
|
||||
}
|
||||
unsafe {
|
||||
AnyPin::steal(psel_bits as _).conf().reset();
|
||||
}
|
||||
unsafe { AnyPin::steal(psel_bits as _).conf().reset() }
|
||||
}
|
||||
|
||||
// ====================
|
||||
|
|
|
@ -5,11 +5,11 @@ use core::task::{Context, Poll};
|
|||
use embassy::interrupt::{Interrupt, InterruptExt};
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_hal_common::unsafe_impl_unborrow;
|
||||
use embedded_hal::digital::v2::{InputPin, StatefulOutputPin};
|
||||
use embedded_hal::digital::v2::InputPin;
|
||||
use futures::future::poll_fn;
|
||||
|
||||
use crate::gpio::sealed::Pin as _;
|
||||
use crate::gpio::{AnyPin, Input, Output, Pin as GpioPin};
|
||||
use crate::gpio::{AnyPin, FlexPin, Input, Output, Pin as GpioPin};
|
||||
use crate::pac;
|
||||
use crate::ppi::{Event, Task};
|
||||
use crate::{interrupt, peripherals};
|
||||
|
@ -177,11 +177,11 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> {
|
|||
InputChannelPolarity::Toggle => w.mode().event().polarity().toggle(),
|
||||
};
|
||||
#[cfg(any(feature = "nrf52833", feature = "nrf52840"))]
|
||||
w.port().bit(match pin.pin.port() {
|
||||
w.port().bit(match pin.pin.pin.port() {
|
||||
crate::gpio::Port::Port0 => false,
|
||||
crate::gpio::Port::Port1 => true,
|
||||
});
|
||||
unsafe { w.psel().bits(pin.pin.pin()) }
|
||||
unsafe { w.psel().bits(pin.pin.pin.pin()) }
|
||||
});
|
||||
|
||||
g.events_in[num].reset();
|
||||
|
@ -250,7 +250,7 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
|
|||
|
||||
g.config[num].write(|w| {
|
||||
w.mode().task();
|
||||
match pin.is_set_high().unwrap() {
|
||||
match pin.is_set_high() {
|
||||
true => w.outinit().high(),
|
||||
false => w.outinit().low(),
|
||||
};
|
||||
|
@ -260,11 +260,11 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
|
|||
OutputChannelPolarity::Toggle => w.polarity().toggle(),
|
||||
};
|
||||
#[cfg(any(feature = "nrf52833", feature = "nrf52840"))]
|
||||
w.port().bit(match pin.pin.port() {
|
||||
w.port().bit(match pin.pin.pin.port() {
|
||||
crate::gpio::Port::Port0 => false,
|
||||
crate::gpio::Port::Port1 => true,
|
||||
});
|
||||
unsafe { w.psel().bits(pin.pin.pin()) }
|
||||
unsafe { w.psel().bits(pin.pin.pin.pin()) }
|
||||
});
|
||||
|
||||
OutputChannel { ch, _pin: pin }
|
||||
|
@ -311,9 +311,11 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
|
|||
}
|
||||
}
|
||||
|
||||
// =======================
|
||||
|
||||
pub(crate) struct PortInputFuture<'a> {
|
||||
pub(crate) pin_port: u8,
|
||||
pub(crate) phantom: PhantomData<&'a mut AnyPin>,
|
||||
pin_port: u8,
|
||||
phantom: PhantomData<&'a mut AnyPin>,
|
||||
}
|
||||
|
||||
impl<'a> Unpin for PortInputFuture<'a> {}
|
||||
|
@ -340,6 +342,92 @@ impl<'a> Future for PortInputFuture<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'d, T: GpioPin> embassy::traits::gpio::WaitForHigh for Input<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + Unpin + 'a;
|
||||
|
||||
fn wait_for_high<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
self.pin.wait_for_high()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: GpioPin> embassy::traits::gpio::WaitForLow for Input<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + Unpin + 'a;
|
||||
|
||||
fn wait_for_low<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
self.pin.wait_for_low()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: GpioPin> embassy::traits::gpio::WaitForAnyEdge for Input<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + Unpin + 'a;
|
||||
|
||||
fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
self.pin.wait_for_any_edge()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: GpioPin> embassy::traits::gpio::WaitForHigh for FlexPin<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + Unpin + 'a;
|
||||
|
||||
fn wait_for_high<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
self.pin.conf().modify(|_, w| w.sense().high());
|
||||
|
||||
PortInputFuture {
|
||||
pin_port: self.pin.pin_port(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: GpioPin> embassy::traits::gpio::WaitForLow for FlexPin<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + Unpin + 'a;
|
||||
|
||||
fn wait_for_low<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
self.pin.conf().modify(|_, w| w.sense().low());
|
||||
|
||||
PortInputFuture {
|
||||
pin_port: self.pin.pin_port(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: GpioPin> embassy::traits::gpio::WaitForAnyEdge for FlexPin<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + Unpin + 'a;
|
||||
|
||||
fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
if self.is_high() {
|
||||
self.pin.conf().modify(|_, w| w.sense().low());
|
||||
} else {
|
||||
self.pin.conf().modify(|_, w| w.sense().high());
|
||||
}
|
||||
PortInputFuture {
|
||||
pin_port: self.pin.pin_port(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =======================
|
||||
|
||||
mod sealed {
|
||||
pub trait Channel {}
|
||||
}
|
||||
|
|
|
@ -5,21 +5,19 @@
|
|||
#[path = "../example_common.rs"]
|
||||
mod example_common;
|
||||
|
||||
use defmt::unwrap;
|
||||
use embassy::executor::Spawner;
|
||||
use embassy::time::{Duration, Timer};
|
||||
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
||||
use embassy_nrf::Peripherals;
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
|
||||
#[embassy::main]
|
||||
async fn main(_spawner: Spawner, p: Peripherals) {
|
||||
let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
|
||||
|
||||
loop {
|
||||
unwrap!(led.set_high());
|
||||
led.set_high();
|
||||
Timer::after(Duration::from_millis(300)).await;
|
||||
unwrap!(led.set_low());
|
||||
led.set_low();
|
||||
Timer::after(Duration::from_millis(300)).await;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ use embassy::time::{Duration, Timer};
|
|||
use embassy::util::Forever;
|
||||
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
||||
use embassy_nrf::Peripherals;
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
|
||||
enum LedState {
|
||||
On,
|
||||
|
@ -53,8 +52,8 @@ async fn main(spawner: Spawner, p: Peripherals) {
|
|||
Err(TryRecvError::Closed) => break,
|
||||
};
|
||||
match maybe_message {
|
||||
Some(LedState::On) => unwrap!(led.set_high()),
|
||||
Some(LedState::Off) => unwrap!(led.set_low()),
|
||||
Some(LedState::On) => led.set_high(),
|
||||
Some(LedState::Off) => led.set_low(),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
|||
use embassy_nrf::Peripherals;
|
||||
use embassy_nrf::{interrupt, spim};
|
||||
use embassy_traits::spi::FullDuplex;
|
||||
use embedded_hal::digital::v2::*;
|
||||
use example_common::*;
|
||||
|
||||
#[embassy::main]
|
||||
|
@ -29,12 +28,12 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
|||
|
||||
// softreset
|
||||
cortex_m::asm::delay(10);
|
||||
unwrap!(ncs.set_low());
|
||||
ncs.set_low();
|
||||
cortex_m::asm::delay(5);
|
||||
let tx = [0xFF];
|
||||
unwrap!(spim.read_write(&mut [], &tx).await);
|
||||
cortex_m::asm::delay(10);
|
||||
unwrap!(ncs.set_high());
|
||||
ncs.set_high();
|
||||
|
||||
cortex_m::asm::delay(100000);
|
||||
|
||||
|
@ -42,31 +41,31 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
|||
|
||||
// read ESTAT
|
||||
cortex_m::asm::delay(5000);
|
||||
unwrap!(ncs.set_low());
|
||||
ncs.set_low();
|
||||
cortex_m::asm::delay(5000);
|
||||
let tx = [0b000_11101, 0];
|
||||
unwrap!(spim.read_write(&mut rx, &tx).await);
|
||||
cortex_m::asm::delay(5000);
|
||||
unwrap!(ncs.set_high());
|
||||
ncs.set_high();
|
||||
info!("estat: {=[?]}", rx);
|
||||
|
||||
// Switch to bank 3
|
||||
cortex_m::asm::delay(10);
|
||||
unwrap!(ncs.set_low());
|
||||
ncs.set_low();
|
||||
cortex_m::asm::delay(5);
|
||||
let tx = [0b100_11111, 0b11];
|
||||
unwrap!(spim.read_write(&mut rx, &tx).await);
|
||||
cortex_m::asm::delay(10);
|
||||
unwrap!(ncs.set_high());
|
||||
ncs.set_high();
|
||||
|
||||
// read EREVID
|
||||
cortex_m::asm::delay(10);
|
||||
unwrap!(ncs.set_low());
|
||||
ncs.set_low();
|
||||
cortex_m::asm::delay(5);
|
||||
let tx = [0b000_10010, 0];
|
||||
unwrap!(spim.read_write(&mut rx, &tx).await);
|
||||
cortex_m::asm::delay(10);
|
||||
unwrap!(ncs.set_high());
|
||||
ncs.set_high();
|
||||
|
||||
info!("erevid: {=[?]}", rx);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue