Skip to content

Commit 9af1dad

Browse files
committed
Add missing OpenDrain[IO] tests
1 parent 1f8fccf commit 9af1dad

File tree

3 files changed

+113
-9
lines changed

3 files changed

+113
-9
lines changed

nrf52840-hal-tests/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ harness = false
2020
name = "gpio-output-open-drain"
2121
harness = false
2222

23+
[[test]]
24+
name = "gpio-output-open-drain-io"
25+
harness = false
26+
2327
[[test]]
2428
name = "nvmc"
2529
harness = false
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Required connections:
2+
//
3+
// - P0.28 <-> P0.29
4+
5+
#![deny(warnings)]
6+
#![no_std]
7+
#![no_main]
8+
9+
use defmt_rtt as _;
10+
use nrf52840_hal as _;
11+
use panic_probe as _;
12+
13+
use nrf52840_hal::gpio::{Input, OpenDrainIO, Output, Pin, PullUp};
14+
15+
struct State {
16+
input_pin: Option<Pin<Input<PullUp>>>,
17+
output_pin: Pin<Output<OpenDrainIO>>,
18+
}
19+
20+
#[defmt_test::tests]
21+
mod tests {
22+
use cortex_m::asm;
23+
use defmt::{assert, unwrap};
24+
use nrf52840_hal::{
25+
gpio::{p0, Level, OpenDrainConfig},
26+
pac,
27+
prelude::*,
28+
};
29+
30+
use super::State;
31+
32+
#[init]
33+
fn init() -> State {
34+
let p = unwrap!(pac::Peripherals::take());
35+
let port0 = p0::Parts::new(p.P0);
36+
37+
let input_pin = Some(port0.p0_28.into_pullup_input().degrade());
38+
let output_pin = port0
39+
.p0_29
40+
.into_open_drain_input_output(OpenDrainConfig::Standard0Disconnect1, Level::High)
41+
.degrade();
42+
43+
State {
44+
input_pin,
45+
output_pin,
46+
}
47+
}
48+
49+
#[test]
50+
fn set_low_is_low(state: &mut State) {
51+
state.output_pin.set_low().unwrap();
52+
// GPIO operations are not instantaneous so a delay is needed
53+
asm::delay(100);
54+
assert!(state.input_pin.as_ref().unwrap().is_low().unwrap());
55+
}
56+
57+
#[test]
58+
fn set_high_is_open(state: &mut State) {
59+
state.output_pin.set_high().unwrap();
60+
// GPIO operations are not instantaneous so a delay is needed
61+
asm::delay(100);
62+
assert!(state.input_pin.as_ref().unwrap().is_high().unwrap());
63+
64+
let pulled_down_input_pin = state.input_pin.take().unwrap().into_pulldown_input();
65+
// GPIO operations are not instantaneous so a delay is needed
66+
asm::delay(100);
67+
assert!(pulled_down_input_pin.is_low().unwrap());
68+
69+
// Restore original input pin state
70+
state.input_pin = Some(pulled_down_input_pin.into_pullup_input());
71+
}
72+
73+
#[test]
74+
fn open_pullup_reads_high(state: &mut State) {
75+
// GPIO operations are not instantaneous so a delay is needed
76+
asm::delay(100);
77+
assert!(state.output_pin.is_high().unwrap());
78+
}
79+
80+
#[test]
81+
fn open_pulldown_reads_low(state: &mut State) {
82+
let pulled_down_input_pin = state.input_pin.take().unwrap().into_pulldown_input();
83+
// GPIO operations are not instantaneous so a delay is needed
84+
asm::delay(100);
85+
assert!(pulled_down_input_pin.is_low().unwrap());
86+
87+
// Restore original input pin state
88+
state.input_pin = Some(pulled_down_input_pin.into_pullup_input());
89+
}
90+
}

nrf52840-hal-tests/tests/gpio-output-open-drain.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@ use defmt_rtt as _;
1010
use nrf52840_hal as _;
1111
use panic_probe as _;
1212

13-
use nrf52840_hal::gpio::{Floating, Input, OpenDrain, Output, Pin};
13+
use nrf52840_hal::gpio::{Input, OpenDrain, Output, Pin, PullUp};
1414

1515
struct State {
16-
input_pin: Pin<Input<Floating>>,
16+
input_pin: Option<Pin<Input<PullUp>>>,
1717
output_pin: Pin<Output<OpenDrain>>,
1818
}
1919

2020
#[defmt_test::tests]
2121
mod tests {
22+
use cortex_m::asm;
2223
use defmt::{assert, unwrap};
2324
use nrf52840_hal::{
2425
gpio::{p0, Level, OpenDrainConfig},
@@ -33,7 +34,7 @@ mod tests {
3334
let p = unwrap!(pac::Peripherals::take());
3435
let port0 = p0::Parts::new(p.P0);
3536

36-
let input_pin = port0.p0_28.into_floating_input().degrade();
37+
let input_pin = Some(port0.p0_28.into_pullup_input().degrade());
3738
let output_pin = port0
3839
.p0_29
3940
.into_open_drain_output(OpenDrainConfig::Standard0Disconnect1, Level::High)
@@ -48,15 +49,24 @@ mod tests {
4849
#[test]
4950
fn set_low_is_low(state: &mut State) {
5051
state.output_pin.set_low().unwrap();
51-
assert!(state.input_pin.is_low().unwrap());
52+
// GPIO operations are not instantaneous so a delay is needed
53+
asm::delay(100);
54+
assert!(state.input_pin.as_ref().unwrap().is_low().unwrap());
5255
}
5356

54-
// with the current API we cannot test this w/o an _external_ pull-up
55-
/*
5657
#[test]
57-
fn set_high_is_high(state: &mut State) {
58+
fn set_high_is_open(state: &mut State) {
5859
state.output_pin.set_high().unwrap();
59-
assert!(state.input_pin.is_high().unwrap());
60+
// GPIO operations are not instantaneous so a delay is needed
61+
asm::delay(100);
62+
assert!(state.input_pin.as_ref().unwrap().is_high().unwrap());
63+
64+
let pulled_down_input_pin = state.input_pin.take().unwrap().into_pulldown_input();
65+
// GPIO operations are not instantaneous so a delay is needed
66+
asm::delay(100);
67+
assert!(pulled_down_input_pin.is_low().unwrap());
68+
69+
// Restore original input pin state
70+
state.input_pin = Some(pulled_down_input_pin.into_pullup_input());
6071
}
61-
*/
6272
}

0 commit comments

Comments
 (0)