1 /*
2 * Copyright (c) 2022 Google LLC
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/sys/util.h>
8 #include <zephyr/device.h>
9 #include <zephyr/drivers/gpio.h>
10 #include <zephyr/drivers/gpio/gpio_emul.h>
11 #include <zephyr/kernel.h>
12 #include <zephyr/ztest.h>
13 #include <zephyr/input/input.h>
14
15 static const struct device *const test_gpio_keys_dev = DEVICE_DT_GET(DT_NODELABEL(buttons));
16 #define BUTTON_0_IDX DT_NODE_CHILD_IDX(DT_NODELABEL(voldown_button))
17
18 struct gpio_keys_pin_config {
19 /** GPIO specification from devicetree */
20 struct gpio_dt_spec spec;
21 /** Zephyr code from devicetree */
22 uint32_t zephyr_code;
23 };
24 struct gpio_keys_config {
25 /** Debounce interval in milliseconds from devicetree */
26 uint32_t debounce_interval_ms;
27 const int num_keys;
28 const struct gpio_keys_pin_config *pin_cfg;
29 };
30
31 /**
32 * @brief Test Suite: Verifies gpio_keys_config functionality.
33 */
34 ZTEST_SUITE(gpio_keys, NULL, NULL, NULL, NULL, NULL);
35
36 static int event_count;
37 static uint16_t last_code;
38 static bool last_val;
test_gpio_keys_cb_handler(struct input_event * evt,void * user_data)39 static void test_gpio_keys_cb_handler(struct input_event *evt, void *user_data)
40 {
41 TC_PRINT("GPIO_KEY %s pressed, zephyr_code=%u, value=%d\n",
42 evt->dev->name, evt->code, evt->value);
43 event_count++;
44 last_code = evt->code;
45 last_val = evt->value;
46 }
47 INPUT_CALLBACK_DEFINE(test_gpio_keys_dev, test_gpio_keys_cb_handler, NULL);
48
49 /**
50 * @brief TestPurpose: Verify gpio_keys_config pressed raw.
51 *
52 */
ZTEST(gpio_keys,test_gpio_keys_pressed)53 ZTEST(gpio_keys, test_gpio_keys_pressed)
54 {
55 const struct gpio_keys_config *config = test_gpio_keys_dev->config;
56 const struct gpio_keys_pin_config *pin_cfg = &config->pin_cfg[BUTTON_0_IDX];
57 const struct gpio_dt_spec *spec = &pin_cfg->spec;
58
59 last_code = 0;
60 last_val = false;
61
62 zassert_ok(gpio_emul_input_set(spec->port, spec->pin, 0));
63
64 /* Check interrupt doesn't prematurely fires */
65 k_sleep(K_MSEC(config->debounce_interval_ms / 2));
66 zassert_equal(event_count, 0);
67
68 /* Check interrupt fires after debounce interval */
69 k_sleep(K_MSEC(config->debounce_interval_ms));
70 zassert_equal(event_count, 1);
71 zassert_equal(last_code, pin_cfg->zephyr_code);
72 zassert_equal(last_val, true);
73
74 zassert_ok(gpio_emul_input_set(spec->port, spec->pin, 1));
75
76 /* Check interrupt doesn't prematurely fires */
77 k_sleep(K_MSEC(config->debounce_interval_ms / 2));
78 zassert_equal(event_count, 1);
79
80 /* Check interrupt fires after debounce interval */
81 k_sleep(K_MSEC(config->debounce_interval_ms));
82 zassert_equal(event_count, 2);
83 zassert_equal(last_code, pin_cfg->zephyr_code);
84 zassert_equal(last_val, false);
85 }
86