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:
Dario Nieuwenhuis 2021-12-19 23:25:02 +01:00
parent fcb43caa36
commit 22bc1e4ae1
6 changed files with 221 additions and 262 deletions

View File

@ -14,14 +14,13 @@ use embassy_nrf::{
peripherals::P0_13, peripherals::P0_13,
Peripherals, Peripherals,
}; };
use embedded_hal::digital::v2::OutputPin;
#[embassy::task] #[embassy::task]
async fn blinker(mut led: Output<'static, P0_13>, interval: Duration) { async fn blinker(mut led: Output<'static, P0_13>, interval: Duration) {
loop { loop {
unwrap!(led.set_high()); led.set_high();
Timer::after(interval).await; Timer::after(interval).await;
unwrap!(led.set_low()); led.set_low();
Timer::after(interval).await; Timer::after(interval).await;
} }
} }

View File

@ -1,7 +1,6 @@
#![macro_use] #![macro_use]
use core::convert::Infallible; use core::convert::Infallible;
use core::future::Future;
use core::hint::unreachable_unchecked; use core::hint::unreachable_unchecked;
use core::marker::PhantomData; use core::marker::PhantomData;
@ -38,26 +37,23 @@ pub enum Pull {
/// GPIO input driver. /// GPIO input driver.
pub struct Input<'d, T: Pin> { pub struct Input<'d, T: Pin> {
pub(crate) pin: T, pub(crate) pin: FlexPin<'d, T>,
phantom: PhantomData<&'d mut T>,
} }
impl<'d, T: Pin> Input<'d, T> { impl<'d, T: Pin> Input<'d, T> {
pub fn new(pin: impl Unborrow<Target = T> + 'd, pull: Pull) -> Self { 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 }
Self {
pin,
phantom: PhantomData,
}
} }
}
impl<'d, T: Pin> Drop for Input<'d, T> { fn is_high(&self) -> bool {
fn drop(&mut self) { self.pin.is_high()
self.pin.conf().reset(); }
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; type Error = Infallible;
fn is_high(&self) -> Result<bool, Self::Error> { 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> { fn is_low(&self) -> Result<bool, Self::Error> {
Ok(self.pin.block().in_.read().bits() & (1 << self.pin.pin()) == 0) Ok(self.is_low())
}
}
#[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,
}
} }
} }
@ -160,8 +102,7 @@ pub enum OutputDrive {
/// GPIO output driver. /// GPIO output driver.
pub struct Output<'d, T: Pin> { pub struct Output<'d, T: Pin> {
pub(crate) pin: T, pub(crate) pin: FlexPin<'d, T>,
phantom: PhantomData<&'d mut T>,
} }
impl<'d, T: Pin> Output<'d, T> { impl<'d, T: Pin> Output<'d, T> {
@ -170,63 +111,56 @@ impl<'d, T: Pin> Output<'d, T> {
initial_output: Level, initial_output: Level,
drive: OutputDrive, drive: OutputDrive,
) -> Self { ) -> Self {
unborrow!(pin); let mut pin = FlexPin::new(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(),
} }
pin.set_as_output(drive);
init_output(&pin, drive); Self { pin }
Self {
pin,
phantom: PhantomData,
}
} }
}
impl<'d, T: Pin> Drop for Output<'d, T> { /// Set the output as high.
fn drop(&mut self) { pub fn set_high(&mut self) {
self.pin.conf().reset(); 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> { impl<'d, T: Pin> OutputPin for Output<'d, T> {
type Error = Infallible; type Error = Infallible;
/// Set the output as high.
fn set_high(&mut self) -> Result<(), Self::Error> { fn set_high(&mut self) -> Result<(), Self::Error> {
unsafe { Ok(self.set_high())
self.pin
.block()
.outset
.write(|w| w.bits(1u32 << self.pin.pin()));
}
Ok(())
} }
/// Set the output as low.
fn set_low(&mut self) -> Result<(), Self::Error> { fn set_low(&mut self) -> Result<(), Self::Error> {
unsafe { Ok(self.set_low())
self.pin
.block()
.outclr
.write(|w| w.bits(1u32 << self.pin.pin()));
}
Ok(())
} }
} }
impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> { 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> { 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> { 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. /// Put the pin into input mode.
pub fn set_as_input(&mut self, pull: Pull) { 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. /// 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 /// 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. /// at a specific level, call `set_high`/`set_low` on the pin first.
pub fn set_as_output(&mut self, drive: OutputDrive) { 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. /// Put the pin into disconnected mode.
pub fn set_as_disconnected(&mut self) { pub fn set_as_disconnected(&mut self) {
self.pin.conf().reset(); 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> { 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; type Error = Infallible;
fn is_high(&self) -> Result<bool, Self::Error> { 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> { 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> { impl<'d, T: Pin> OutputPin for FlexPin<'d, T> {
type Error = Infallible; type Error = Infallible;
/// Set the output as high.
fn set_high(&mut self) -> Result<(), Self::Error> { fn set_high(&mut self) -> Result<(), Self::Error> {
unsafe { Ok(self.set_high())
self.pin
.block()
.outset
.write(|w| w.bits(1u32 << self.pin.pin()));
}
Ok(())
} }
/// Set the output as low.
fn set_low(&mut self) -> Result<(), Self::Error> { fn set_low(&mut self) -> Result<(), Self::Error> {
unsafe { Ok(self.set_low())
self.pin
.block()
.outclr
.write(|w| w.bits(1u32 << self.pin.pin()));
}
Ok(())
} }
} }
impl<'d, T: Pin> StatefulOutputPin for FlexPin<'d, T> { 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> { 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> { 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())
}
}
#[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,
}
} }
} }
@ -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 { 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 { if psel_bits & 0x8000_0000 != 0 {
return; return;
} }
unsafe { unsafe { AnyPin::steal(psel_bits as _).conf().reset() }
AnyPin::steal(psel_bits as _).conf().reset();
}
} }
// ==================== // ====================

View File

@ -5,11 +5,11 @@ use core::task::{Context, Poll};
use embassy::interrupt::{Interrupt, InterruptExt}; use embassy::interrupt::{Interrupt, InterruptExt};
use embassy::waitqueue::AtomicWaker; use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::unsafe_impl_unborrow; 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 futures::future::poll_fn;
use crate::gpio::sealed::Pin as _; 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::pac;
use crate::ppi::{Event, Task}; use crate::ppi::{Event, Task};
use crate::{interrupt, peripherals}; 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(), InputChannelPolarity::Toggle => w.mode().event().polarity().toggle(),
}; };
#[cfg(any(feature = "nrf52833", feature = "nrf52840"))] #[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::Port0 => false,
crate::gpio::Port::Port1 => true, 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(); g.events_in[num].reset();
@ -250,7 +250,7 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
g.config[num].write(|w| { g.config[num].write(|w| {
w.mode().task(); w.mode().task();
match pin.is_set_high().unwrap() { match pin.is_set_high() {
true => w.outinit().high(), true => w.outinit().high(),
false => w.outinit().low(), false => w.outinit().low(),
}; };
@ -260,11 +260,11 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
OutputChannelPolarity::Toggle => w.polarity().toggle(), OutputChannelPolarity::Toggle => w.polarity().toggle(),
}; };
#[cfg(any(feature = "nrf52833", feature = "nrf52840"))] #[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::Port0 => false,
crate::gpio::Port::Port1 => true, crate::gpio::Port::Port1 => true,
}); });
unsafe { w.psel().bits(pin.pin.pin()) } unsafe { w.psel().bits(pin.pin.pin.pin()) }
}); });
OutputChannel { ch, _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) struct PortInputFuture<'a> {
pub(crate) pin_port: u8, pin_port: u8,
pub(crate) phantom: PhantomData<&'a mut AnyPin>, phantom: PhantomData<&'a mut AnyPin>,
} }
impl<'a> Unpin for PortInputFuture<'a> {} 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 { mod sealed {
pub trait Channel {} pub trait Channel {}
} }

View File

@ -5,21 +5,19 @@
#[path = "../example_common.rs"] #[path = "../example_common.rs"]
mod example_common; mod example_common;
use defmt::unwrap;
use embassy::executor::Spawner; use embassy::executor::Spawner;
use embassy::time::{Duration, Timer}; use embassy::time::{Duration, Timer};
use embassy_nrf::gpio::{Level, Output, OutputDrive}; use embassy_nrf::gpio::{Level, Output, OutputDrive};
use embassy_nrf::Peripherals; use embassy_nrf::Peripherals;
use embedded_hal::digital::v2::OutputPin;
#[embassy::main] #[embassy::main]
async fn main(_spawner: Spawner, p: Peripherals) { async fn main(_spawner: Spawner, p: Peripherals) {
let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard); let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
loop { loop {
unwrap!(led.set_high()); led.set_high();
Timer::after(Duration::from_millis(300)).await; Timer::after(Duration::from_millis(300)).await;
unwrap!(led.set_low()); led.set_low();
Timer::after(Duration::from_millis(300)).await; Timer::after(Duration::from_millis(300)).await;
} }
} }

View File

@ -13,7 +13,6 @@ use embassy::time::{Duration, Timer};
use embassy::util::Forever; use embassy::util::Forever;
use embassy_nrf::gpio::{Level, Output, OutputDrive}; use embassy_nrf::gpio::{Level, Output, OutputDrive};
use embassy_nrf::Peripherals; use embassy_nrf::Peripherals;
use embedded_hal::digital::v2::OutputPin;
enum LedState { enum LedState {
On, On,
@ -53,8 +52,8 @@ async fn main(spawner: Spawner, p: Peripherals) {
Err(TryRecvError::Closed) => break, Err(TryRecvError::Closed) => break,
}; };
match maybe_message { match maybe_message {
Some(LedState::On) => unwrap!(led.set_high()), Some(LedState::On) => led.set_high(),
Some(LedState::Off) => unwrap!(led.set_low()), Some(LedState::Off) => led.set_low(),
_ => (), _ => (),
} }
} }

View File

@ -10,7 +10,6 @@ use embassy_nrf::gpio::{Level, Output, OutputDrive};
use embassy_nrf::Peripherals; use embassy_nrf::Peripherals;
use embassy_nrf::{interrupt, spim}; use embassy_nrf::{interrupt, spim};
use embassy_traits::spi::FullDuplex; use embassy_traits::spi::FullDuplex;
use embedded_hal::digital::v2::*;
use example_common::*; use example_common::*;
#[embassy::main] #[embassy::main]
@ -29,12 +28,12 @@ async fn main(_spawner: Spawner, p: Peripherals) {
// softreset // softreset
cortex_m::asm::delay(10); cortex_m::asm::delay(10);
unwrap!(ncs.set_low()); ncs.set_low();
cortex_m::asm::delay(5); cortex_m::asm::delay(5);
let tx = [0xFF]; let tx = [0xFF];
unwrap!(spim.read_write(&mut [], &tx).await); unwrap!(spim.read_write(&mut [], &tx).await);
cortex_m::asm::delay(10); cortex_m::asm::delay(10);
unwrap!(ncs.set_high()); ncs.set_high();
cortex_m::asm::delay(100000); cortex_m::asm::delay(100000);
@ -42,31 +41,31 @@ async fn main(_spawner: Spawner, p: Peripherals) {
// read ESTAT // read ESTAT
cortex_m::asm::delay(5000); cortex_m::asm::delay(5000);
unwrap!(ncs.set_low()); ncs.set_low();
cortex_m::asm::delay(5000); cortex_m::asm::delay(5000);
let tx = [0b000_11101, 0]; let tx = [0b000_11101, 0];
unwrap!(spim.read_write(&mut rx, &tx).await); unwrap!(spim.read_write(&mut rx, &tx).await);
cortex_m::asm::delay(5000); cortex_m::asm::delay(5000);
unwrap!(ncs.set_high()); ncs.set_high();
info!("estat: {=[?]}", rx); info!("estat: {=[?]}", rx);
// Switch to bank 3 // Switch to bank 3
cortex_m::asm::delay(10); cortex_m::asm::delay(10);
unwrap!(ncs.set_low()); ncs.set_low();
cortex_m::asm::delay(5); cortex_m::asm::delay(5);
let tx = [0b100_11111, 0b11]; let tx = [0b100_11111, 0b11];
unwrap!(spim.read_write(&mut rx, &tx).await); unwrap!(spim.read_write(&mut rx, &tx).await);
cortex_m::asm::delay(10); cortex_m::asm::delay(10);
unwrap!(ncs.set_high()); ncs.set_high();
// read EREVID // read EREVID
cortex_m::asm::delay(10); cortex_m::asm::delay(10);
unwrap!(ncs.set_low()); ncs.set_low();
cortex_m::asm::delay(5); cortex_m::asm::delay(5);
let tx = [0b000_10010, 0]; let tx = [0b000_10010, 0];
unwrap!(spim.read_write(&mut rx, &tx).await); unwrap!(spim.read_write(&mut rx, &tx).await);
cortex_m::asm::delay(10); cortex_m::asm::delay(10);
unwrap!(ncs.set_high()); ncs.set_high();
info!("erevid: {=[?]}", rx); info!("erevid: {=[?]}", rx);
} }