Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | /*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @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) == GPIO_INT_EDGE) {
if (cb_cnt != 1) {
TC_ERROR("not trigger callback correctly\n");
goto err_exit;
}
goto pass_exit;
}
if ((mode & GPIO_INT_LEVEL) == GPIO_INT_LEVEL) {
if (cb_cnt != MAX_INT_CNT) {
TC_ERROR("not trigger callback correctly\n");
goto err_exit;
}
}
pass_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);
}
|