1 /*
2 * Copyright (c) 2019 Piotr Mienkowski
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7
8 #include <limits.h>
9 #include <zephyr/sys/util.h>
10 #include "test_gpio_api.h"
11
pin_get_raw_and_verify(const struct device * port,unsigned int pin,int val_expected,int idx)12 static void pin_get_raw_and_verify(const struct device *port,
13 unsigned int pin,
14 int val_expected, int idx)
15 {
16 int val_actual;
17
18 val_actual = gpio_pin_get_raw(port, pin);
19 zassert_true(val_actual >= 0,
20 "Test point %d: failed to get physical pin value", idx);
21 zassert_equal(val_expected, val_actual,
22 "Test point %d: invalid physical pin get value", idx);
23 }
24
pin_get_and_verify(const struct device * port,unsigned int pin,int val_expected,int idx)25 static void pin_get_and_verify(const struct device *port, unsigned int pin,
26 int val_expected, int idx)
27 {
28 int val_actual;
29
30 val_actual = gpio_pin_get(port, pin);
31 zassert_true(val_actual >= 0,
32 "Test point %d: failed to get logical pin value", idx);
33 zassert_equal(val_expected, val_actual,
34 "Test point %d: invalid logical pin get value", idx);
35 }
36
pin_set_raw_and_verify(const struct device * port,unsigned int pin,int val,int idx)37 static void pin_set_raw_and_verify(const struct device *port,
38 unsigned int pin,
39 int val, int idx)
40 {
41 zassert_equal(gpio_pin_set_raw(port, pin, val), 0,
42 "Test point %d: failed to set physical pin value", idx);
43 k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
44 }
45
pin_set_and_verify(const struct device * port,unsigned int pin,int val,int idx)46 static void pin_set_and_verify(const struct device *port, unsigned int pin,
47 int val,
48 int idx)
49 {
50 zassert_equal(gpio_pin_set(port, pin, val), 0,
51 "Test point %d: failed to set logical pin value", idx);
52 k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
53 }
54
55 /** @brief Verify gpio_pin_toggle function.
56 *
57 * - Verify that gpio_pin_toggle function changes pin state from active to
58 * inactive and vice versa.
59 */
ZTEST(gpio_api_1pin_pin,test_gpio_pin_toggle)60 ZTEST(gpio_api_1pin_pin, test_gpio_pin_toggle)
61 {
62 const struct device *port;
63 int val_expected;
64 int ret;
65
66 port = DEVICE_DT_GET(TEST_NODE);
67 zassert_true(device_is_ready(port), "GPIO dev is not ready");
68
69 TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
70
71 ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT);
72 if (ret == -ENOTSUP) {
73 TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
74 ztest_test_skip();
75 return;
76 }
77 zassert_equal(ret, 0, "Failed to configure the pin");
78
79 pin_set_raw_and_verify(port, TEST_PIN, 1, 0);
80
81 for (int i = 0; i < 5; i++) {
82 ret = gpio_pin_toggle(port, TEST_PIN);
83 zassert_equal(ret, 0, "Failed to toggle pin value");
84 k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
85
86 val_expected = i % 2;
87
88 pin_get_raw_and_verify(port, TEST_PIN, val_expected, i);
89 }
90 }
91
92 /** @brief Verify visually gpio_pin_toggle function.
93 *
94 * This test configures the pin using board DTS flags which should
95 * correctly set pin active state via GPIO_ACTIVE_LOW/_HIGH flags.
96 * It is possible to do a visual check to confirm that "LED ON", "LED OFF"
97 * messages correspond to the LED being turned ON or OFF.
98 *
99 * - Verify visually that gpio_pin_toggle function changes pin state from active
100 * to inactive and vice versa.
101 */
ZTEST(gpio_api_1pin_pin,test_gpio_pin_toggle_visual)102 ZTEST(gpio_api_1pin_pin, test_gpio_pin_toggle_visual)
103 {
104 const struct device *port;
105 int val_expected;
106 int ret;
107
108 port = DEVICE_DT_GET(TEST_NODE);
109 zassert_true(device_is_ready(port), "GPIO dev is not ready");
110
111 TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
112
113 ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT |
114 TEST_PIN_DTS_FLAGS);
115 zassert_equal(ret, 0, "Failed to configure the pin");
116
117 pin_set_and_verify(port, TEST_PIN, 1, 0);
118 TC_PRINT("LED ON\n");
119
120 for (int i = 0; i < 3; i++) {
121 k_sleep(K_SECONDS(2));
122
123 ret = gpio_pin_toggle(port, TEST_PIN);
124 zassert_equal(ret, 0, "Failed to toggle pin value");
125 k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
126
127 val_expected = i % 2;
128 TC_PRINT("LED %s\n", val_expected == 1 ? "ON" : "OFF");
129 }
130 }
131
132 /** @brief Verify gpio_pin_set_raw, gpio_pin_get_raw functions.
133 *
134 * - Verify that gpio_pin_get_raw reads the same value as set by
135 * gpio_pin_set_raw function.
136 */
ZTEST(gpio_api_1pin_pin,test_gpio_pin_set_get_raw)137 ZTEST(gpio_api_1pin_pin, test_gpio_pin_set_get_raw)
138 {
139 const struct device *port;
140 int val_expected;
141 int ret;
142
143 const int test_vector[] = {
144 4, 1, 45, 0, 0, -7, 0, 0, 0, INT_MAX, INT_MIN, 0
145 };
146
147 port = DEVICE_DT_GET(TEST_NODE);
148 zassert_true(device_is_ready(port), "GPIO dev is not ready");
149
150 TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
151
152 ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT);
153 if (ret == -ENOTSUP) {
154 TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
155 ztest_test_skip();
156 return;
157 }
158 zassert_equal(ret, 0, "Failed to configure the pin");
159
160 for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
161 pin_set_raw_and_verify(port, TEST_PIN, test_vector[i], i);
162
163 val_expected = test_vector[i] != 0 ? 1 : 0;
164
165 pin_get_raw_and_verify(port, TEST_PIN, val_expected, i);
166 }
167 }
168
169 /** @brief Verify gpio_pin_set, gpio_pin_get functions.
170 *
171 * - Verify that gpio_pin_get reads the same value as set by gpio_pin_set
172 * function.
173 */
ZTEST(gpio_api_1pin_pin,test_gpio_pin_set_get)174 ZTEST(gpio_api_1pin_pin, test_gpio_pin_set_get)
175 {
176 const struct device *port;
177 int val_expected;
178 int ret;
179
180 const int test_vector[] = {
181 1, 2, 3, 0, 4, 0, 0, 0, 17, INT_MAX, INT_MIN, 0
182 };
183
184 port = DEVICE_DT_GET(TEST_NODE);
185 zassert_true(device_is_ready(port), "GPIO dev is not ready");
186
187 TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
188
189 ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT);
190 if (ret == -ENOTSUP) {
191 TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
192 ztest_test_skip();
193 return;
194 }
195 zassert_equal(ret, 0, "Failed to configure the pin");
196
197 for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
198 pin_set_and_verify(port, TEST_PIN, test_vector[i], i);
199
200 val_expected = test_vector[i] != 0 ? 1 : 0;
201
202 pin_get_and_verify(port, TEST_PIN, val_expected, i);
203 }
204 }
205
206 /** @brief Verify GPIO_ACTIVE_HIGH flag.
207 *
208 * - Verify that there is no functional difference between gpio_pin_set_raw and
209 * gpio_pin_set functions if the pin is configured as Active High.
210 * - Verify that there is no functional difference between gpio_pin_get_raw and
211 * gpio_pin_get functions if the pin is configured as Active High.
212 */
ZTEST(gpio_api_1pin_pin,test_gpio_pin_set_get_active_high)213 ZTEST(gpio_api_1pin_pin, test_gpio_pin_set_get_active_high)
214 {
215 const struct device *port;
216 int val_expected;
217 int ret;
218
219 const int test_vector[] = {0, 2, 0, 9, -1, 0, 0, 1, INT_MAX, INT_MIN};
220
221 port = DEVICE_DT_GET(TEST_NODE);
222 zassert_true(device_is_ready(port), "GPIO dev is not ready");
223
224 TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
225
226 ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT |
227 GPIO_ACTIVE_HIGH);
228 if (ret == -ENOTSUP) {
229 TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
230 ztest_test_skip();
231 return;
232 }
233 zassert_equal(ret, 0, "Failed to configure the pin");
234
235 TC_PRINT("Step 1: Set logical, get logical and physical pin value\n");
236 for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
237 pin_set_and_verify(port, TEST_PIN, test_vector[i], i);
238
239 val_expected = test_vector[i] != 0 ? 1 : 0;
240
241 pin_get_and_verify(port, TEST_PIN, val_expected, i);
242 pin_get_raw_and_verify(port, TEST_PIN, val_expected, i);
243 }
244
245 TC_PRINT("Step 2: Set physical, get logical and physical pin value\n");
246 for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
247 pin_set_raw_and_verify(port, TEST_PIN, test_vector[i], i);
248
249 val_expected = test_vector[i] != 0 ? 1 : 0;
250
251 pin_get_and_verify(port, TEST_PIN, val_expected, i);
252 pin_get_raw_and_verify(port, TEST_PIN, val_expected, i);
253 }
254 }
255
256 /** @brief Verify GPIO_ACTIVE_LOW flag.
257 *
258 * - Verify that value set by gpio_pin_set function is inverted compared to
259 * gpio_pin_set_raw if the pin is configured as Active Low.
260 * - Verify that value read by gpio_pin_get function is inverted compared to
261 * gpio_pin_get_raw if the pin is configured as Active Low.
262 */
ZTEST(gpio_api_1pin_pin,test_gpio_pin_set_get_active_low)263 ZTEST(gpio_api_1pin_pin, test_gpio_pin_set_get_active_low)
264 {
265 const struct device *port;
266 int val_expected, val_raw_expected;
267 int ret;
268
269 const int test_vector[] = {0, 4, 0, 0, 1, 8, -3, -12, 0};
270
271 port = DEVICE_DT_GET(TEST_NODE);
272 zassert_true(device_is_ready(port), "GPIO dev is not ready");
273
274 TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
275
276 ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT |
277 GPIO_ACTIVE_LOW);
278 if (ret == -ENOTSUP) {
279 TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
280 ztest_test_skip();
281 return;
282 }
283 zassert_equal(ret, 0, "Failed to configure the pin");
284
285 TC_PRINT("Step 1: Set logical, get logical and physical pin value\n");
286 for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
287 pin_set_and_verify(port, TEST_PIN, test_vector[i], i);
288
289 val_expected = (test_vector[i] != 0) ? 1 : 0;
290 val_raw_expected = (val_expected != 0) ? 0 : 1;
291
292 pin_get_and_verify(port, TEST_PIN, val_expected, i);
293 pin_get_raw_and_verify(port, TEST_PIN, val_raw_expected, i);
294 }
295
296 TC_PRINT("Step 2: Set physical, get logical and physical pin value\n");
297 for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
298 pin_set_raw_and_verify(port, TEST_PIN, test_vector[i], i);
299
300 val_expected = (test_vector[i] != 0) ? 0 : 1;
301 val_raw_expected = (val_expected != 0) ? 0 : 1;
302
303 pin_get_and_verify(port, TEST_PIN, val_expected, i);
304 pin_get_raw_and_verify(port, TEST_PIN, val_raw_expected, i);
305 }
306 }
307
308 ZTEST_SUITE(gpio_api_1pin_pin, NULL, NULL, NULL, NULL, NULL);
309