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