Skip to content

Commit 1b475b7

Browse files
committed
tests: drivers: gpio-async: Test the async gpio operations
This is a basic test to test for the waiting gpios. Currently, this test requires a specific hardware setup. To test on the rpi-pico, it is necessary to connect GPIO-0 to GPIO-6 with a button or switch. Running should then print Pressed/Released on a debounced version of that switch, with the code not polling the gpio while waiting. Signed-off-by: David Brown <[email protected]>
1 parent 0347eac commit 1b475b7

File tree

9 files changed

+199
-0
lines changed

9 files changed

+199
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
5+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
6+
7+
project(gpio_async)
8+
rust_cargo_application()

tests/drivers/gpio-async/Cargo.toml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Copyright (c) 2024 Linaro LTD
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
[package]
5+
# This must be rustapp for now.
6+
name = "rustapp"
7+
version = "0.1.0"
8+
edition = "2021"
9+
description = "Test async gpios"
10+
license = "Apache-2.0 or MIT"
11+
12+
[lib]
13+
crate-type = ["staticlib"]
14+
15+
[dependencies]
16+
zephyr = { version = "0.1.0", features = ["time-driver", "executor-zephyr", "async-drivers"] }
17+
log = "0.4.22"
18+
static_cell = "2.1"
19+
heapless = "0.8"
20+
21+
[dependencies.embassy-executor]
22+
version = "0.7.0"
23+
features = [
24+
"log",
25+
"task-arena-size-2048",
26+
]
27+
28+
[dependencies.embassy-futures]
29+
version = "0.1.1"
30+
31+
[dependencies.embassy-sync]
32+
version = "0.6.2"
33+
34+
[dependencies.embassy-time]
35+
version = "0.4.0"
36+
features = ["tick-hz-10_000"]
37+
38+
[dependencies.critical-section]
39+
version = "1.2"
40+
41+
[profile.dev]
42+
opt-level = 1
43+
44+
[profile.release]
45+
debug = true
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/ {
2+
gpio-leds {
3+
compatible = "gpio-leds";
4+
col0: col0 {
5+
gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
6+
label = "Column 0";
7+
};
8+
row0: row0 {
9+
gpios = <&gpio0 0 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>;
10+
label = "Row 0";
11+
};
12+
};
13+
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/ {
2+
gpio-leds {
3+
compatible = "gpio-leds";
4+
col0: col0 {
5+
gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
6+
label = "Column 0";
7+
};
8+
row0: row0 {
9+
gpios = <&gpio0 0 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>;
10+
label = "Row 0";
11+
};
12+
};
13+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Copyright (c) 2024 Linaro LTD
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
# This board doesn't have a serial console, so use RTT.
5+
CONFIG_UART_CONSOLE=n
6+
CONFIG_RTT_CONSOLE=y
7+
CONFIG_USE_SEGGER_RTT=y

tests/drivers/gpio-async/prj.conf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copyright (c) 2024 Linaro LTD
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
CONFIG_DEBUG=y
5+
6+
# The default 1k stack isn't large enough for rust string formatting with logging.
7+
CONFIG_MAIN_STACK_SIZE=4096
8+
9+
CONFIG_RUST=y
10+
11+
CONFIG_RUST_ALLOC=y
12+
# CONFIG_LOG=y
13+
CONFIG_GPIO=y
14+
CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT=y
15+
16+
CONFIG_LOG_BACKEND_RTT=n
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Copyright (c) 2024 Linaro LTD
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
# This board doesn't have a serial console, so use RTT.
5+
CONFIG_UART_CONSOLE=n
6+
CONFIG_RTT_CONSOLE=y
7+
CONFIG_USE_SEGGER_RTT=y

tests/drivers/gpio-async/src/lib.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) 2024 Linaro LTD
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#![no_std]
5+
6+
extern crate alloc;
7+
8+
use embassy_time::{Duration, Ticker};
9+
use zephyr::{
10+
device::gpio::{GpioPin, GpioToken},
11+
embassy::Executor,
12+
raw::{GPIO_INPUT, GPIO_OUTPUT_ACTIVE, GPIO_PULL_DOWN},
13+
};
14+
15+
use embassy_executor::Spawner;
16+
use log::info;
17+
use static_cell::StaticCell;
18+
19+
static EXECUTOR_MAIN: StaticCell<Executor> = StaticCell::new();
20+
21+
#[no_mangle]
22+
extern "C" fn rust_main() {
23+
unsafe {
24+
zephyr::set_logger().unwrap();
25+
}
26+
27+
let executor = EXECUTOR_MAIN.init(Executor::new());
28+
executor.run(|spawner| {
29+
spawner.spawn(main(spawner)).unwrap();
30+
})
31+
}
32+
33+
#[embassy_executor::task]
34+
async fn main(spawner: Spawner) {
35+
info!("Hello world");
36+
let _ = spawner;
37+
38+
let mut col0 = zephyr::devicetree::labels::col0::get_instance().unwrap();
39+
let mut row0 = zephyr::devicetree::labels::row0::get_instance().unwrap();
40+
let mut gpio_token = unsafe { zephyr::device::gpio::GpioToken::get_instance().unwrap() };
41+
42+
unsafe {
43+
col0.configure(&mut gpio_token, GPIO_OUTPUT_ACTIVE);
44+
col0.set(&mut gpio_token, true);
45+
row0.configure(&mut gpio_token, GPIO_INPUT | GPIO_PULL_DOWN);
46+
}
47+
48+
loop {
49+
unsafe { row0.wait_for_high(&mut gpio_token).await };
50+
// Simple debounce, Wait for 20 consecutive high samples.
51+
debounce(&mut row0, &mut gpio_token, true).await;
52+
info!("Pressed");
53+
unsafe { row0.wait_for_low(&mut gpio_token).await };
54+
debounce(&mut row0, &mut gpio_token, false).await;
55+
info!("Released");
56+
}
57+
}
58+
59+
/// Simple debounce. Scan the gpio periodically, and return when we have 20 consecutive samples of
60+
/// the intended value.
61+
async fn debounce(pin: &mut GpioPin, gpio_token: &mut GpioToken, level: bool) {
62+
let mut count = 0;
63+
let mut ticker = Ticker::every(Duration::from_millis(1));
64+
loop {
65+
ticker.next().await;
66+
67+
if unsafe { pin.get(gpio_token) } == level {
68+
count += 1;
69+
70+
if count >= 20 {
71+
return;
72+
}
73+
} else {
74+
count = 0;
75+
}
76+
}
77+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
common:
2+
filter: CONFIG_RUST_SUPPORTED
3+
platform_allow:
4+
- rpi_pico
5+
tests:
6+
test.gpio-async:
7+
harness: console
8+
harness_config:
9+
type: one_line
10+
regex:
11+
# This doesn't actually happen, as this test requires specific hardware and buttons to be
12+
# pressed.
13+
- "All tests passed"

0 commit comments

Comments
 (0)