1 /*
2 * Copyright (c) 2023 Intel Corporation
3 * Copyright 2024 NXP
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include "test_gpio.h"
9
10 static struct drv_data data;
11 static int cb_cnt;
12
callback(const struct device * dev,struct gpio_callback * gpio_cb,uint32_t pins)13 static void callback(const struct device *dev,
14 struct gpio_callback *gpio_cb, uint32_t pins)
15 {
16 /*= checkpoint: pins should be marked with correct pin number bit =*/
17 zassert_equal(pins, BIT(PIN_IN),
18 "unexpected pins %x", pins);
19
20 ++cb_cnt;
21 }
22
ZTEST(after_flash_gpio_config_trigger,test_gpio_config_twice_trigger)23 ZTEST(after_flash_gpio_config_trigger, test_gpio_config_twice_trigger)
24 {
25 const struct device *const dev_in = DEVICE_DT_GET(DEV_IN);
26 const struct device *const dev_out = DEVICE_DT_GET(DEV_OUT);
27 struct drv_data *drv_data = &data;
28 int ret;
29
30 cb_cnt = 0;
31
32 ret = gpio_pin_configure(dev_out, PIN_OUT, GPIO_DISCONNECTED);
33
34 /* 1. Configure PIN_IN callback */
35 ret = gpio_pin_configure(dev_in, PIN_IN, GPIO_INPUT);
36 zassert_ok(ret, "config PIN_IN failed");
37
38 gpio_init_callback(&drv_data->gpio_cb, callback, BIT(PIN_IN));
39 ret = gpio_add_callback(dev_in, &drv_data->gpio_cb);
40 zassert_ok(ret, "add callback failed");
41
42 /* 2. Enable PIN callback as both edges */
43 ret = gpio_pin_interrupt_configure(dev_in, PIN_IN, GPIO_INT_EDGE_BOTH);
44 if (ret == -ENOTSUP) {
45 TC_PRINT("Both edge GPIO interrupt not supported.\n");
46 gpio_remove_callback(dev_in, &drv_data->gpio_cb);
47 } else {
48 zassert_ok(ret, "enable callback failed");
49 }
50
51 /* 3. Configure PIN_OUT as open drain, internal pull-up (may trigger
52 * callback)
53 */
54 ret = gpio_pin_configure(dev_out, PIN_OUT, GPIO_OUTPUT | GPIO_OPEN_DRAIN | GPIO_PULL_UP);
55 if (ret == -ENOTSUP) {
56 TC_PRINT("Open drain not supported.\n");
57 gpio_remove_callback(dev_in, &drv_data->gpio_cb);
58 ztest_test_skip();
59 return;
60 }
61 zassert_ok(ret, "config PIN_OUT failed");
62
63 /* 4. Configure PIN_OUT again (should not trigger callback) */
64 ret = gpio_pin_configure(dev_out, PIN_OUT, GPIO_OUTPUT | GPIO_OPEN_DRAIN | GPIO_PULL_UP);
65 zassert_ok(ret, "config PIN_OUT twice failed");
66
67 /* 5. Wait a bit and ensure that interrupt happened at most once */
68 k_sleep(K_MSEC(10));
69 zassert_between_inclusive(cb_cnt, 0, 1, "Got %d interrupts", cb_cnt);
70
71 gpio_remove_callback(dev_in, &drv_data->gpio_cb);
72 }
73
ZTEST(after_flash_gpio_config_trigger,test_gpio_config_trigger)74 ZTEST(after_flash_gpio_config_trigger, test_gpio_config_trigger)
75 {
76 const struct device *const dev_in = DEVICE_DT_GET(DEV_IN);
77 const struct device *const dev_out = DEVICE_DT_GET(DEV_OUT);
78 struct drv_data *drv_data = &data;
79 int ret;
80
81 cb_cnt = 0;
82
83 ret = gpio_pin_configure(dev_out, PIN_OUT, GPIO_DISCONNECTED);
84
85 /* 1. Configure PIN_IN callback */
86 ret = gpio_pin_configure(dev_in, PIN_IN, GPIO_INPUT);
87 zassert_ok(ret, "config PIN_IN failed");
88
89 gpio_init_callback(&drv_data->gpio_cb, callback, BIT(PIN_IN));
90 ret = gpio_add_callback(dev_in, &drv_data->gpio_cb);
91 zassert_ok(ret, "add callback failed");
92
93 /* 2. Enable PIN callback as both edges */
94 ret = gpio_pin_interrupt_configure(dev_in, PIN_IN, GPIO_INT_EDGE_BOTH);
95 if (ret == -ENOTSUP) {
96 TC_PRINT("Both edge GPIO interrupt not supported.\n");
97 gpio_remove_callback(dev_in, &drv_data->gpio_cb);
98 } else {
99 zassert_ok(ret, "enable callback failed");
100 }
101
102 /* 3. Configure PIN_OUT as open drain, internal pull-up (may trigger
103 * callback)
104 */
105 ret = gpio_pin_configure(dev_out, PIN_OUT, GPIO_OUTPUT | GPIO_OPEN_DRAIN | GPIO_PULL_UP);
106 if (ret == -ENOTSUP) {
107 TC_PRINT("Open drain not supported.\n");
108 gpio_remove_callback(dev_in, &drv_data->gpio_cb);
109 ztest_test_skip();
110 return;
111 }
112 zassert_ok(ret, "config PIN_OUT failed");
113
114 /* 4. Wait a bit and ensure that interrupt happened at most once */
115 k_sleep(K_MSEC(10));
116 zassert_between_inclusive(cb_cnt, 0, 1, "Got %d interrupts", cb_cnt);
117
118 gpio_remove_callback(dev_in, &drv_data->gpio_cb);
119 }
120