blob: 48b48c4071346029bae1af395ff190ade4b5a8c8 [file] [log] [blame]
/*
* Copyright (c) 2019 Piotr Mienkowski
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <limits.h>
#include <zephyr/sys/util.h>
#include "test_gpio_api.h"
static void pin_get_raw_and_verify(const struct device *port,
unsigned int pin,
int val_expected, int idx)
{
int val_actual;
val_actual = gpio_pin_get_raw(port, pin);
zassert_true(val_actual >= 0,
"Test point %d: failed to get physical pin value", idx);
zassert_equal(val_expected, val_actual,
"Test point %d: invalid physical pin get value", idx);
}
static void pin_get_and_verify(const struct device *port, unsigned int pin,
int val_expected, int idx)
{
int val_actual;
val_actual = gpio_pin_get(port, pin);
zassert_true(val_actual >= 0,
"Test point %d: failed to get logical pin value", idx);
zassert_equal(val_expected, val_actual,
"Test point %d: invalid logical pin get value", idx);
}
static void pin_set_raw_and_verify(const struct device *port,
unsigned int pin,
int val, int idx)
{
zassert_equal(gpio_pin_set_raw(port, pin, val), 0,
"Test point %d: failed to set physical pin value", idx);
k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
}
static void pin_set_and_verify(const struct device *port, unsigned int pin,
int val,
int idx)
{
zassert_equal(gpio_pin_set(port, pin, val), 0,
"Test point %d: failed to set logical pin value", idx);
k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
}
/** @brief Verify gpio_pin_toggle function.
*
* - Verify that gpio_pin_toggle function changes pin state from active to
* inactive and vice versa.
*/
ZTEST(gpio_api_1pin_pin, test_gpio_pin_toggle)
{
const struct device *port;
int val_expected;
int ret;
port = DEVICE_DT_GET(TEST_NODE);
zassert_true(device_is_ready(port), "GPIO dev is not ready");
TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT);
if (ret == -ENOTSUP) {
TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
ztest_test_skip();
return;
}
zassert_equal(ret, 0, "Failed to configure the pin");
pin_set_raw_and_verify(port, TEST_PIN, 1, 0);
for (int i = 0; i < 5; i++) {
ret = gpio_pin_toggle(port, TEST_PIN);
zassert_equal(ret, 0, "Failed to toggle pin value");
k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
val_expected = i % 2;
pin_get_raw_and_verify(port, TEST_PIN, val_expected, i);
}
}
/** @brief Verify visually gpio_pin_toggle function.
*
* This test configures the pin using board DTS flags which should
* correctly set pin active state via GPIO_ACTIVE_LOW/_HIGH flags.
* It is possible to do a visual check to confirm that "LED ON", "LED OFF"
* messages correspond to the LED being turned ON or OFF.
*
* - Verify visually that gpio_pin_toggle function changes pin state from active
* to inactive and vice versa.
*/
ZTEST(gpio_api_1pin_pin, test_gpio_pin_toggle_visual)
{
const struct device *port;
int val_expected;
int ret;
port = DEVICE_DT_GET(TEST_NODE);
zassert_true(device_is_ready(port), "GPIO dev is not ready");
TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT |
TEST_PIN_DTS_FLAGS);
zassert_equal(ret, 0, "Failed to configure the pin");
pin_set_and_verify(port, TEST_PIN, 1, 0);
TC_PRINT("LED ON\n");
for (int i = 0; i < 3; i++) {
k_sleep(K_SECONDS(2));
ret = gpio_pin_toggle(port, TEST_PIN);
zassert_equal(ret, 0, "Failed to toggle pin value");
k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
val_expected = i % 2;
TC_PRINT("LED %s\n", val_expected == 1 ? "ON" : "OFF");
}
}
/** @brief Verify gpio_pin_set_raw, gpio_pin_get_raw functions.
*
* - Verify that gpio_pin_get_raw reads the same value as set by
* gpio_pin_set_raw function.
*/
ZTEST(gpio_api_1pin_pin, test_gpio_pin_set_get_raw)
{
const struct device *port;
int val_expected;
int ret;
const int test_vector[] = {
4, 1, 45, 0, 0, -7, 0, 0, 0, INT_MAX, INT_MIN, 0
};
port = DEVICE_DT_GET(TEST_NODE);
zassert_true(device_is_ready(port), "GPIO dev is not ready");
TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT);
if (ret == -ENOTSUP) {
TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
ztest_test_skip();
return;
}
zassert_equal(ret, 0, "Failed to configure the pin");
for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
pin_set_raw_and_verify(port, TEST_PIN, test_vector[i], i);
val_expected = test_vector[i] != 0 ? 1 : 0;
pin_get_raw_and_verify(port, TEST_PIN, val_expected, i);
}
}
/** @brief Verify gpio_pin_set, gpio_pin_get functions.
*
* - Verify that gpio_pin_get reads the same value as set by gpio_pin_set
* function.
*/
ZTEST(gpio_api_1pin_pin, test_gpio_pin_set_get)
{
const struct device *port;
int val_expected;
int ret;
const int test_vector[] = {
1, 2, 3, 0, 4, 0, 0, 0, 17, INT_MAX, INT_MIN, 0
};
port = DEVICE_DT_GET(TEST_NODE);
zassert_true(device_is_ready(port), "GPIO dev is not ready");
TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT);
if (ret == -ENOTSUP) {
TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
ztest_test_skip();
return;
}
zassert_equal(ret, 0, "Failed to configure the pin");
for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
pin_set_and_verify(port, TEST_PIN, test_vector[i], i);
val_expected = test_vector[i] != 0 ? 1 : 0;
pin_get_and_verify(port, TEST_PIN, val_expected, i);
}
}
/** @brief Verify GPIO_ACTIVE_HIGH flag.
*
* - Verify that there is no functional difference between gpio_pin_set_raw and
* gpio_pin_set functions if the pin is configured as Active High.
* - Verify that there is no functional difference between gpio_pin_get_raw and
* gpio_pin_get functions if the pin is configured as Active High.
*/
ZTEST(gpio_api_1pin_pin, test_gpio_pin_set_get_active_high)
{
const struct device *port;
int val_expected;
int ret;
const int test_vector[] = {0, 2, 0, 9, -1, 0, 0, 1, INT_MAX, INT_MIN};
port = DEVICE_DT_GET(TEST_NODE);
zassert_true(device_is_ready(port), "GPIO dev is not ready");
TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT |
GPIO_ACTIVE_HIGH);
if (ret == -ENOTSUP) {
TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
ztest_test_skip();
return;
}
zassert_equal(ret, 0, "Failed to configure the pin");
TC_PRINT("Step 1: Set logical, get logical and physical pin value\n");
for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
pin_set_and_verify(port, TEST_PIN, test_vector[i], i);
val_expected = test_vector[i] != 0 ? 1 : 0;
pin_get_and_verify(port, TEST_PIN, val_expected, i);
pin_get_raw_and_verify(port, TEST_PIN, val_expected, i);
}
TC_PRINT("Step 2: Set physical, get logical and physical pin value\n");
for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
pin_set_raw_and_verify(port, TEST_PIN, test_vector[i], i);
val_expected = test_vector[i] != 0 ? 1 : 0;
pin_get_and_verify(port, TEST_PIN, val_expected, i);
pin_get_raw_and_verify(port, TEST_PIN, val_expected, i);
}
}
/** @brief Verify GPIO_ACTIVE_LOW flag.
*
* - Verify that value set by gpio_pin_set function is inverted compared to
* gpio_pin_set_raw if the pin is configured as Active Low.
* - Verify that value read by gpio_pin_get function is inverted compared to
* gpio_pin_get_raw if the pin is configured as Active Low.
*/
ZTEST(gpio_api_1pin_pin, test_gpio_pin_set_get_active_low)
{
const struct device *port;
int val_expected, val_raw_expected;
int ret;
const int test_vector[] = {0, 4, 0, 0, 1, 8, -3, -12, 0};
port = DEVICE_DT_GET(TEST_NODE);
zassert_true(device_is_ready(port), "GPIO dev is not ready");
TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT |
GPIO_ACTIVE_LOW);
if (ret == -ENOTSUP) {
TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
ztest_test_skip();
return;
}
zassert_equal(ret, 0, "Failed to configure the pin");
TC_PRINT("Step 1: Set logical, get logical and physical pin value\n");
for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
pin_set_and_verify(port, TEST_PIN, test_vector[i], i);
val_expected = (test_vector[i] != 0) ? 1 : 0;
val_raw_expected = (val_expected != 0) ? 0 : 1;
pin_get_and_verify(port, TEST_PIN, val_expected, i);
pin_get_raw_and_verify(port, TEST_PIN, val_raw_expected, i);
}
TC_PRINT("Step 2: Set physical, get logical and physical pin value\n");
for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
pin_set_raw_and_verify(port, TEST_PIN, test_vector[i], i);
val_expected = (test_vector[i] != 0) ? 0 : 1;
val_raw_expected = (val_expected != 0) ? 0 : 1;
pin_get_and_verify(port, TEST_PIN, val_expected, i);
pin_get_raw_and_verify(port, TEST_PIN, val_raw_expected, i);
}
}
ZTEST_SUITE(gpio_api_1pin_pin, NULL, NULL, NULL, NULL, NULL);