Skip to content

Commit

Permalink
Add missing OpenDrain[IO] tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Finomnis committed Sep 28, 2022
1 parent 1f8fccf commit 314d980
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 9 deletions.
4 changes: 4 additions & 0 deletions nrf52840-hal-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ harness = false
name = "gpio-output-open-drain"
harness = false

[[test]]
name = "gpio-output-open-drain-io"
harness = false

[[test]]
name = "nvmc"
harness = false
Expand Down
93 changes: 93 additions & 0 deletions nrf52840-hal-tests/tests/gpio-output-open-drain-io.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Required connections:
//
// - P0.28 <-> P0.29

#![deny(warnings)]
#![no_std]
#![no_main]

use defmt_rtt as _;
use nrf52840_hal as _;
use panic_probe as _;

use nrf52840_hal::gpio::{Input, OpenDrainIO, Output, Pin, PullUp};

struct State {
input_pin: Option<Pin<Input<PullUp>>>,
output_pin: Pin<Output<OpenDrainIO>>,
}

#[defmt_test::tests]
mod tests {
use cortex_m::asm;
use defmt::{assert, unwrap};
use nrf52840_hal::{
gpio::{p0, Level, OpenDrainConfig},
pac,
prelude::*,
};

use super::State;

#[init]
fn init() -> State {
let p = unwrap!(pac::Peripherals::take());
let port0 = p0::Parts::new(p.P0);

let input_pin = Some(port0.p0_28.into_pullup_input().degrade());
let output_pin = port0
.p0_29
.into_open_drain_input_output(OpenDrainConfig::Standard0Disconnect1, Level::High)
.degrade();

State {
input_pin,
output_pin,
}
}

#[test]
fn set_low_is_low(state: &mut State) {
state.output_pin.set_low().unwrap();
// GPIO operations are not instantaneous so a delay is needed
asm::delay(100);
assert!(state.input_pin.as_ref().unwrap().is_low().unwrap());
}

#[test]
fn set_high_is_open(state: &mut State) {
state.output_pin.set_high().unwrap();
// GPIO operations are not instantaneous so a delay is needed
asm::delay(100);
assert!(state.input_pin.as_ref().unwrap().is_high().unwrap());

let pulled_down_input_pin = state.input_pin.take().unwrap().into_pulldown_input();
// GPIO operations are not instantaneous so a delay is needed
asm::delay(100);
assert!(pulled_down_input_pin.is_low().unwrap());

// Restore original input pin state
state.input_pin = Some(pulled_down_input_pin.into_pullup_input());
}

#[test]
fn open_pullup_reads_high(state: &mut State) {
state.output_pin.set_high().unwrap();
// GPIO operations are not instantaneous so a delay is needed
asm::delay(100);
assert!(state.output_pin.is_high().unwrap());
}

#[test]
fn open_pulldown_reads_low(state: &mut State) {
state.output_pin.set_high().unwrap();

let pulled_down_input_pin = state.input_pin.take().unwrap().into_pulldown_input();
// GPIO operations are not instantaneous so a delay is needed
asm::delay(100);
assert!(pulled_down_input_pin.is_low().unwrap());

// Restore original input pin state
state.input_pin = Some(pulled_down_input_pin.into_pullup_input());
}
}
28 changes: 19 additions & 9 deletions nrf52840-hal-tests/tests/gpio-output-open-drain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ use defmt_rtt as _;
use nrf52840_hal as _;
use panic_probe as _;

use nrf52840_hal::gpio::{Floating, Input, OpenDrain, Output, Pin};
use nrf52840_hal::gpio::{Input, OpenDrain, Output, Pin, PullUp};

struct State {
input_pin: Pin<Input<Floating>>,
input_pin: Option<Pin<Input<PullUp>>>,
output_pin: Pin<Output<OpenDrain>>,
}

#[defmt_test::tests]
mod tests {
use cortex_m::asm;
use defmt::{assert, unwrap};
use nrf52840_hal::{
gpio::{p0, Level, OpenDrainConfig},
Expand All @@ -33,7 +34,7 @@ mod tests {
let p = unwrap!(pac::Peripherals::take());
let port0 = p0::Parts::new(p.P0);

let input_pin = port0.p0_28.into_floating_input().degrade();
let input_pin = Some(port0.p0_28.into_pullup_input().degrade());
let output_pin = port0
.p0_29
.into_open_drain_output(OpenDrainConfig::Standard0Disconnect1, Level::High)
Expand All @@ -48,15 +49,24 @@ mod tests {
#[test]
fn set_low_is_low(state: &mut State) {
state.output_pin.set_low().unwrap();
assert!(state.input_pin.is_low().unwrap());
// GPIO operations are not instantaneous so a delay is needed
asm::delay(100);
assert!(state.input_pin.as_ref().unwrap().is_low().unwrap());
}

// with the current API we cannot test this w/o an _external_ pull-up
/*
#[test]
fn set_high_is_high(state: &mut State) {
fn set_high_is_open(state: &mut State) {
state.output_pin.set_high().unwrap();
assert!(state.input_pin.is_high().unwrap());
// GPIO operations are not instantaneous so a delay is needed
asm::delay(100);
assert!(state.input_pin.as_ref().unwrap().is_high().unwrap());

let pulled_down_input_pin = state.input_pin.take().unwrap().into_pulldown_input();
// GPIO operations are not instantaneous so a delay is needed
asm::delay(100);
assert!(pulled_down_input_pin.is_low().unwrap());

// Restore original input pin state
state.input_pin = Some(pulled_down_input_pin.into_pullup_input());
}
*/
}

0 comments on commit 314d980

Please sign in to comment.