Skip to content

Commit

Permalink
tests: add gpio driver test case
Browse files Browse the repository at this point in the history
the commit include 5 ztest cases, cover the basic gpio APIs
including callback relevant and pin read/write functions.
It proves workable on intel quark c1000 and
arduino 101 platform

Change-Id: Iab30aa841cfa440c1f773b5a8c5ce0d68346c353
Signed-off-by: jing wang <[email protected]>
Signed-off-by: Anas Nashif <[email protected]>
  • Loading branch information
jwang11 authored and Anas Nashif committed Dec 24, 2016
1 parent 3d99a0c commit b008914
Show file tree
Hide file tree
Showing 9 changed files with 499 additions and 0 deletions.
4 changes: 4 additions & 0 deletions tests/drivers/gpio/gpio_basic_api/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
BOARD ?= quark_se_c1000_devboard
CONF_FILE = prj.conf

include ${ZEPHYR_BASE}/Makefile.inc
3 changes: 3 additions & 0 deletions tests/drivers/gpio/gpio_basic_api/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CONFIG_GPIO=y
CONFIG_ZTEST=y
CONFIG_NEWLIB_LIBC=y
2 changes: 2 additions & 0 deletions tests/drivers/gpio/gpio_basic_api/src/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
include $(ZEPHYR_BASE)/tests/Makefile.test
obj-y = main.o test_callback_trigger.o test_callback_manage.o test_pin_rw.o
57 changes: 57 additions & 0 deletions tests/drivers/gpio/gpio_basic_api/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @addtogroup t_driver_gpio
* @{
* @defgroup t_gpio_basic_api test_gpio_basic_api
* @}
*
* Setup: loop PIN_OUT with PIN_IN on the target board
*
* quark_se_c1000_devboard - x86
* --------------------
*
* 1. PIN_OUT is GPIO_15
* 2. PIN_IN is GPIO_16
*
* quark_se_c1000_ss_devboard - arc
* --------------------
*
* 1. PIN_OUT is GPIO_SS_12
* 2. PIN_IN is GPIO_SS_13
*
* arduino_101 - x86
* --------------------
*
* 1. PIN_OUT is GPIO_16
* 2. PIN_IN is GPIO_19
*/

#include "test_gpio.h"

void test_main(void)
{
ztest_test_suite(gpio_basic_test,
ztest_unit_test(test_gpio_pin_read_write),
ztest_unit_test(test_gpio_callback_edge_high),
ztest_unit_test(test_gpio_callback_edge_low),
ztest_unit_test(test_gpio_callback_level_high),
ztest_unit_test(test_gpio_callback_add_remove),
ztest_unit_test(test_gpio_callback_enable_disable),
ztest_unit_test(test_gpio_callback_level_high));
ztest_run_test_suite(gpio_basic_test);
}
172 changes: 172 additions & 0 deletions tests/drivers/gpio/gpio_basic_api/src/test_callback_manage.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @addtogroup t_gpio_basic_api
* @{
* @defgroup t_gpio_callback_manage test_gpio_callback_manage
* @brief TestPurpose: verify zephyr gpio callback add/remvoe and enable/disable
* @}
*/

#include "test_gpio.h"

static struct drv_data cb_data[2];
static int cb_cnt[2];

static void callback_1(struct device *dev,
struct gpio_callback *gpio_cb, uint32_t pins)
{
TC_PRINT("%s triggered: %d\n", __func__, ++cb_cnt[0]);

}

static void callback_2(struct device *dev,
struct gpio_callback *gpio_cb, uint32_t pins)
{
TC_PRINT("%s triggered: %d\n", __func__, ++cb_cnt[1]);
}

static void init_callback(struct device *dev)
{
gpio_pin_disable_callback(dev, PIN_IN);
gpio_pin_disable_callback(dev, PIN_OUT);

/* 1. set PIN_OUT */
gpio_pin_configure(dev, PIN_OUT, GPIO_DIR_OUT);
gpio_pin_write(dev, PIN_OUT, 0);

/* 2. configure PIN_IN callback and trigger condition */
gpio_pin_configure(dev, PIN_IN,
GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE | \
GPIO_INT_ACTIVE_HIGH | GPIO_INT_DEBOUNCE);

gpio_init_callback(&cb_data[0].gpio_cb, callback_1, BIT(PIN_IN));
gpio_add_callback(dev, &cb_data[0].gpio_cb);

gpio_init_callback(&cb_data[1].gpio_cb, callback_2, BIT(PIN_IN));
gpio_add_callback(dev, &cb_data[1].gpio_cb);
}

static void trigger_callback(struct device *dev, int enable_cb)
{
gpio_pin_write(dev, PIN_OUT, 0);
k_sleep(100);

cb_cnt[0] = 0;
cb_cnt[1] = 0;
if (enable_cb == 1) {
gpio_pin_enable_callback(dev, PIN_IN);
} else {
gpio_pin_disable_callback(dev, PIN_IN);
}
k_sleep(100);
gpio_pin_write(dev, PIN_OUT, 1);
k_sleep(1000);
}

static int test_callback_add_remove(void)
{
struct device *dev = device_get_binding(DEV_NAME);

/* SetUp: initialize environment */
init_callback(dev);

/* 3. enable callback, trigger PIN_IN interrupt by operate PIN_OUT */
trigger_callback(dev, 1);
/*= checkpoint: check callback is triggered =*/
if (cb_cnt[0] != 1 || cb_cnt[1] != 1) {
TC_ERROR("not trigger callback correctly\n");
goto err_exit;
}

/* 4. remove callback_1 */
gpio_remove_callback(dev, &cb_data[0].gpio_cb);
trigger_callback(dev, 1);

/*= checkpoint: check callback is triggered =*/
if (cb_cnt[0] != 0 || cb_cnt[1] != 1) {
TC_ERROR("not trigger callback correctly\n");
goto err_exit;
}

/* 5. remove callback_2 */
gpio_remove_callback(dev, &cb_data[1].gpio_cb);
trigger_callback(dev, 1);
/*= checkpoint: check callback is triggered =*/
if (cb_cnt[0] != 0 || cb_cnt[1] != 0) {
TC_ERROR("not trigger callback correctly\n");
goto err_exit;
}
return TC_PASS;

err_exit:
gpio_remove_callback(dev, &cb_data[0].gpio_cb);
gpio_remove_callback(dev, &cb_data[1].gpio_cb);
return TC_FAIL;
}

static int test_callback_enable_disable(void)
{
struct device *dev = device_get_binding(DEV_NAME);

/* SetUp: initialize environment */
init_callback(dev);

/* 3. enable callback, trigger PIN_IN interrupt by operate PIN_OUT */
trigger_callback(dev, 1);
/*= checkpoint: check callback is triggered =*/
if (cb_cnt[0] != 1 || cb_cnt[1] != 1) {
TC_ERROR("not trigger callback correctly\n");
goto err_exit;
}

/* 4. disable callback */
trigger_callback(dev, 0);
/*= checkpoint: check callback is triggered =*/
if (cb_cnt[0] != 0 || cb_cnt[1] != 0) {
TC_ERROR("not trigger callback correctly\n");
goto err_exit;
}

/* 5. enable callback again */
trigger_callback(dev, 1);
/*= checkpoint: check callback is triggered =*/
if (cb_cnt[0] != 1 || cb_cnt[1] != 1) {
TC_ERROR("not trigger callback correctly\n");
goto err_exit;
}
gpio_remove_callback(dev, &cb_data[0].gpio_cb);
gpio_remove_callback(dev, &cb_data[1].gpio_cb);
return TC_PASS;

err_exit:
gpio_remove_callback(dev, &cb_data[0].gpio_cb);
gpio_remove_callback(dev, &cb_data[1].gpio_cb);
return TC_FAIL;
}

void test_gpio_callback_add_remove(void)
{
assert_true(
test_callback_add_remove() == TC_PASS, NULL);
}

void test_gpio_callback_enable_disable(void)
{
assert_true(
test_callback_enable_disable() == TC_PASS, NULL);
}
146 changes: 146 additions & 0 deletions tests/drivers/gpio/gpio_basic_api/src/test_callback_trigger.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @addtogroup t_gpio_basic_api
* @{
* @defgroup t_gpio_callback_trigger test_gpio_callback_trigger
* @brief TestPurpose: verify zephyr gpio callback triggered
* under different INT modes
* @}
*/

#include "test_gpio.h"

static struct drv_data data;
static int cb_cnt;

static int pin_num(uint32_t pins)
{
int ret = 0;

while (pins >>= 1) {
ret++;
}
return ret;
}

static void callback(struct device *dev,
struct gpio_callback *gpio_cb, uint32_t pins)
{
/*= checkpoint: pins should be marked with correct pin number bit =*/
assert_true(pin_num(pins) == PIN_IN, NULL);
TC_PRINT("callback triggered: %d\n", ++cb_cnt);
if (cb_cnt >= MAX_INT_CNT) {
struct drv_data *drv_data = CONTAINER_OF(gpio_cb,
struct drv_data, gpio_cb);
gpio_pin_write(dev, PIN_OUT,
(drv_data->mode & GPIO_INT_ACTIVE_HIGH) ? 0 : 1);
}
}

static int test_callback(int mode)
{
struct device *dev = device_get_binding(DEV_NAME);

gpio_pin_disable_callback(dev, PIN_IN);
gpio_pin_disable_callback(dev, PIN_OUT);

/* 1. set PIN_OUT to initial state */
if (gpio_pin_configure(dev, PIN_OUT, GPIO_DIR_OUT) != 0) {
TC_ERROR("PIN_OUT config fail\n");
return TC_FAIL;
}
if (gpio_pin_write(dev, PIN_OUT,
(mode & GPIO_INT_ACTIVE_HIGH) ? 0 : 1) != 0) {
TC_ERROR("set PIN_OUT init voltage fail\n");
return TC_FAIL;
}

/* 2. configure PIN_IN callback and trigger condition */
if (gpio_pin_configure(dev, PIN_IN,
GPIO_DIR_IN | GPIO_INT | mode | GPIO_INT_DEBOUNCE) != 0) {
TC_ERROR("config PIN_IN fail");
goto err_exit;
}

struct drv_data *drv_data = &data;

drv_data->mode = mode;
gpio_init_callback(&drv_data->gpio_cb, callback, BIT(PIN_IN));
if (gpio_add_callback(dev, &drv_data->gpio_cb) != 0) {
TC_ERROR("set PIN_IN callback fail\n");
return TC_FAIL;
}

/* 3. enable callback, trigger PIN_IN interrupt by operate PIN_OUT */
cb_cnt = 0;
gpio_pin_enable_callback(dev, PIN_IN);
k_sleep(100);
gpio_pin_write(dev, PIN_OUT, (mode & GPIO_INT_ACTIVE_HIGH) ? 1 : 0);
k_sleep(1000);

/*= checkpoint: check callback is triggered =*/
TC_PRINT("check enabled callback\n");
if (mode & GPIO_INT_EDGE) {
if (cb_cnt != 1) {
TC_ERROR("not trigger callback correctly\n");
goto err_exit;
}
}

if (mode & GPIO_INT_LEVEL) {
if (cb_cnt != MAX_INT_CNT) {
TC_ERROR("not trigger callback correctly\n");
goto err_exit;
}
}
gpio_remove_callback(dev, &drv_data->gpio_cb);
return TC_PASS;

err_exit:
gpio_remove_callback(dev, &drv_data->gpio_cb);
return TC_FAIL;
}

/* export test cases */
void test_gpio_callback_edge_high(void)
{
assert_true(
test_callback(GPIO_INT_EDGE | GPIO_INT_ACTIVE_HIGH) == TC_PASS,
NULL);
}

void test_gpio_callback_edge_low(void)
{
assert_true(
test_callback(GPIO_INT_EDGE | GPIO_INT_ACTIVE_LOW) == TC_PASS,
NULL);
}

void test_gpio_callback_level_high(void)
{
assert_true(
test_callback(GPIO_INT_LEVEL | GPIO_INT_ACTIVE_HIGH) == TC_PASS,
NULL);
}

void test_gpio_callback_level_low(void)
{
assert_true(
test_callback(GPIO_INT_LEVEL | GPIO_INT_ACTIVE_LOW) == TC_PASS,
NULL);
}
Loading

0 comments on commit b008914

Please sign in to comment.