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 
12 #define TEST_GPIO_PORT_VALUE_MAX         ((1LLU << GPIO_MAX_PINS_PER_PORT) - 1)
13 
port_get_raw_and_verify(const struct device * port,gpio_port_pins_t mask,gpio_port_value_t val_expected,int idx)14 static void port_get_raw_and_verify(const struct device *port,
15 				    gpio_port_pins_t mask,
16 				    gpio_port_value_t val_expected, int idx)
17 {
18 	gpio_port_value_t val_actual;
19 
20 	zassert_equal(gpio_port_get_raw(port, &val_actual), 0,
21 		     "Test point %d: failed to get physical port value", idx);
22 	zassert_equal(val_expected & mask, val_actual & mask,
23 		      "Test point %d: invalid physical port get value", idx);
24 }
25 
port_get_and_verify(const struct device * port,gpio_port_pins_t mask,gpio_port_value_t val_expected,int idx)26 static void port_get_and_verify(const struct device *port,
27 				gpio_port_pins_t mask,
28 				gpio_port_value_t val_expected, int idx)
29 {
30 	gpio_port_value_t val_actual;
31 
32 	zassert_equal(gpio_port_get(port, &val_actual), 0,
33 		     "Test point %d: failed to get logical port value", idx);
34 	zassert_equal(val_expected & mask, val_actual & mask,
35 		      "Test point %d: invalid logical port get value", idx);
36 }
37 
port_set_masked_raw_and_verify(const struct device * port,gpio_port_pins_t mask,gpio_port_value_t value,int idx)38 static void port_set_masked_raw_and_verify(const struct device *port,
39 					   gpio_port_pins_t mask,
40 					   gpio_port_value_t value, int idx)
41 {
42 	zassert_equal(gpio_port_set_masked_raw(port, mask, value), 0,
43 		      "Test point %d: failed to set physical port value", idx);
44 	k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
45 }
46 
port_set_masked_and_verify(const struct device * port,gpio_port_pins_t mask,gpio_port_value_t value,int idx)47 static void port_set_masked_and_verify(const struct device *port,
48 				       gpio_port_pins_t mask,
49 				       gpio_port_value_t value, int idx)
50 {
51 	zassert_equal(gpio_port_set_masked(port, mask, value), 0,
52 		      "Test point %d: failed to set logical port value", idx);
53 	k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
54 }
55 
port_set_bits_raw_and_verify(const struct device * port,gpio_port_pins_t pins,int idx)56 static void port_set_bits_raw_and_verify(const struct device *port,
57 					 gpio_port_pins_t pins, int idx)
58 {
59 	zassert_equal(gpio_port_set_bits_raw(port, pins), 0,
60 		      "Test point %d: failed to set physical port value", idx);
61 	k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
62 }
63 
port_set_bits_and_verify(const struct device * port,gpio_port_pins_t pins,int idx)64 static void port_set_bits_and_verify(const struct device *port,
65 				     gpio_port_pins_t pins, int idx)
66 {
67 	zassert_equal(gpio_port_set_bits(port, pins), 0,
68 		      "Test point %d: failed to set logical port value", idx);
69 	k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
70 }
71 
port_clear_bits_raw_and_verify(const struct device * port,gpio_port_pins_t pins,int idx)72 static void port_clear_bits_raw_and_verify(const struct device *port,
73 					   gpio_port_pins_t pins, int idx)
74 {
75 	zassert_equal(gpio_port_clear_bits_raw(port, pins), 0,
76 		      "Test point %d: failed to set physical port value", idx);
77 	k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
78 }
79 
port_clear_bits_and_verify(const struct device * port,gpio_port_pins_t pins,int idx)80 static void port_clear_bits_and_verify(const struct device *port,
81 				       gpio_port_pins_t pins, int idx)
82 {
83 	zassert_equal(gpio_port_clear_bits(port, pins), 0,
84 		      "Test point %d: failed to set logical port value", idx);
85 	k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
86 }
87 
port_set_clr_bits_raw(const struct device * port,gpio_port_pins_t set_pins,gpio_port_pins_t clear_pins,int idx)88 static void port_set_clr_bits_raw(const struct device *port,
89 				  gpio_port_pins_t set_pins,
90 				  gpio_port_pins_t clear_pins, int idx)
91 {
92 	zassert_equal(gpio_port_set_clr_bits_raw(port, set_pins, clear_pins), 0,
93 		      "Test point %d: failed to set physical port value", idx);
94 	k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
95 }
96 
port_set_clr_bits(const struct device * port,gpio_port_pins_t set_pins,gpio_port_pins_t clear_pins,int idx)97 static void port_set_clr_bits(const struct device *port,
98 			      gpio_port_pins_t set_pins,
99 			      gpio_port_pins_t clear_pins, int idx)
100 {
101 	zassert_equal(gpio_port_set_clr_bits(port, set_pins, clear_pins), 0,
102 		      "Test point %d: failed to set logical port value", idx);
103 	k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
104 }
105 
106 /** @brief Verify gpio_port_toggle_bits function.
107  *
108  * - Verify that gpio_port_toggle_bits function changes pin state from active to
109  *   inactive and vice versa.
110  */
ZTEST(gpio_api_1pin_port,test_gpio_port_toggle)111 ZTEST(gpio_api_1pin_port, test_gpio_port_toggle)
112 {
113 	const struct device *port;
114 	gpio_port_value_t val_expected;
115 	int ret;
116 
117 	port = DEVICE_DT_GET(TEST_NODE);
118 	zassert_true(device_is_ready(port), "GPIO dev is not ready");
119 
120 	TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
121 
122 	ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT);
123 	if (ret == -ENOTSUP) {
124 		TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
125 		ztest_test_skip();
126 		return;
127 	}
128 	zassert_equal(ret, 0, "Failed to configure the pin");
129 
130 	port_set_bits_raw_and_verify(port, BIT(TEST_PIN), 0);
131 
132 	val_expected = BIT(TEST_PIN);
133 
134 	for (int i = 0; i < 5; i++) {
135 		ret = gpio_port_toggle_bits(port, BIT(TEST_PIN));
136 		zassert_equal(ret, 0, "Failed to toggle pin value");
137 		k_busy_wait(TEST_GPIO_MAX_RISE_FALL_TIME_US);
138 
139 		val_expected ^= BIT(TEST_PIN);
140 
141 		port_get_raw_and_verify(port, BIT(TEST_PIN), val_expected, i);
142 	}
143 }
144 
ZTEST(gpio_api_1pin_port,test_gpio_port_set_masked_get_raw)145 ZTEST(gpio_api_1pin_port, test_gpio_port_set_masked_get_raw)
146 {
147 	const struct device *port;
148 	int ret;
149 
150 	const gpio_port_value_t test_vector[] = {
151 		0xEE11EE11,
152 		0x11EE11EE,
153 		TEST_GPIO_PORT_VALUE_MAX,
154 		TEST_GPIO_PORT_VALUE_MAX,
155 		0x00000000,
156 		0x00000000,
157 		0x55555555,
158 		0xAAAAAAAA,
159 		0x00000000,
160 		0x00000000,
161 		TEST_GPIO_PORT_VALUE_MAX,
162 		TEST_GPIO_PORT_VALUE_MAX,
163 		0x00000000,
164 	};
165 
166 	port = DEVICE_DT_GET(TEST_NODE);
167 	zassert_true(device_is_ready(port), "GPIO dev is not ready");
168 
169 	TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
170 
171 	ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT);
172 	if (ret == -ENOTSUP) {
173 		TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
174 		ztest_test_skip();
175 		return;
176 	}
177 	zassert_equal(ret, 0, "Failed to configure the pin");
178 
179 	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
180 		port_set_masked_raw_and_verify(port, BIT(TEST_PIN), test_vector[i], i);
181 		port_get_raw_and_verify(port, BIT(TEST_PIN), test_vector[i], i);
182 	}
183 }
184 
ZTEST(gpio_api_1pin_port,test_gpio_port_set_masked_get)185 ZTEST(gpio_api_1pin_port, test_gpio_port_set_masked_get)
186 {
187 	const struct device *port;
188 	int ret;
189 
190 	const gpio_port_value_t test_vector[] = {
191 		0xEE11EE11,
192 		0x11EE11EE,
193 		TEST_GPIO_PORT_VALUE_MAX,
194 		TEST_GPIO_PORT_VALUE_MAX,
195 		0x00000000,
196 		0x00000000,
197 		0x55555555,
198 		0xAAAAAAAA,
199 		0x00000000,
200 		0x00000000,
201 		TEST_GPIO_PORT_VALUE_MAX,
202 		TEST_GPIO_PORT_VALUE_MAX,
203 		0x00000000,
204 	};
205 
206 	port = DEVICE_DT_GET(TEST_NODE);
207 	zassert_true(device_is_ready(port), "GPIO dev is not ready");
208 
209 	TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
210 
211 	ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT);
212 	if (ret == -ENOTSUP) {
213 		TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
214 		ztest_test_skip();
215 		return;
216 	}
217 	zassert_equal(ret, 0, "Failed to configure the pin");
218 
219 	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
220 		port_set_masked_and_verify(port, BIT(TEST_PIN), test_vector[i], i);
221 		port_get_and_verify(port, BIT(TEST_PIN), test_vector[i], i);
222 	}
223 }
224 
ZTEST(gpio_api_1pin_port,test_gpio_port_set_masked_get_active_high)225 ZTEST(gpio_api_1pin_port, test_gpio_port_set_masked_get_active_high)
226 {
227 	const struct device *port;
228 	int ret;
229 
230 	const gpio_port_value_t test_vector[] = {
231 		0xCC33CC33,
232 		0x33CC33CC,
233 		TEST_GPIO_PORT_VALUE_MAX,
234 		TEST_GPIO_PORT_VALUE_MAX,
235 		TEST_GPIO_PORT_VALUE_MAX,
236 		0x00000000,
237 		0x00000000,
238 		0x00000000,
239 		0x55555555,
240 		0x00000000,
241 		0xAAAAAAAA,
242 		0x00000000,
243 		TEST_GPIO_PORT_VALUE_MAX,
244 		0x00000000,
245 	};
246 
247 	port = DEVICE_DT_GET(TEST_NODE);
248 	zassert_true(device_is_ready(port), "GPIO dev is not ready");
249 
250 	TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
251 
252 	ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT |
253 				 GPIO_ACTIVE_HIGH);
254 	if (ret == -ENOTSUP) {
255 		TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
256 		ztest_test_skip();
257 		return;
258 	}
259 	zassert_equal(ret, 0, "Failed to configure the pin");
260 
261 	TC_PRINT("Step 1: Set logical, get logical and physical port value\n");
262 	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
263 		port_set_masked_and_verify(port, BIT(TEST_PIN), test_vector[i], i);
264 		port_get_and_verify(port, BIT(TEST_PIN), test_vector[i], i);
265 		port_get_raw_and_verify(port, BIT(TEST_PIN), test_vector[i], i);
266 	}
267 
268 	TC_PRINT("Step 2: Set physical, get logical and physical port value\n");
269 	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
270 		port_set_masked_raw_and_verify(port, BIT(TEST_PIN), test_vector[i], i);
271 		port_get_and_verify(port, BIT(TEST_PIN), test_vector[i], i);
272 		port_get_raw_and_verify(port, BIT(TEST_PIN), test_vector[i], i);
273 	}
274 }
275 
ZTEST(gpio_api_1pin_port,test_gpio_port_set_masked_get_active_low)276 ZTEST(gpio_api_1pin_port, test_gpio_port_set_masked_get_active_low)
277 {
278 	const struct device *port;
279 	int ret;
280 
281 	const gpio_port_value_t test_vector[] = {
282 		0xCC33CC33,
283 		0x33CC33CC,
284 		TEST_GPIO_PORT_VALUE_MAX,
285 		TEST_GPIO_PORT_VALUE_MAX,
286 		TEST_GPIO_PORT_VALUE_MAX,
287 		0x00000000,
288 		0x00000000,
289 		0x00000000,
290 		0x55555555,
291 		0x00000000,
292 		0xAAAAAAAA,
293 		0x00000000,
294 		TEST_GPIO_PORT_VALUE_MAX,
295 		0x00000000,
296 	};
297 
298 	port = DEVICE_DT_GET(TEST_NODE);
299 	zassert_true(device_is_ready(port), "GPIO dev is not ready");
300 
301 	TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
302 
303 	ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT |
304 				 GPIO_ACTIVE_LOW);
305 	if (ret == -ENOTSUP) {
306 		TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
307 		ztest_test_skip();
308 		return;
309 	}
310 	zassert_equal(ret, 0, "Failed to configure the pin");
311 
312 	TC_PRINT("Step 1: Set logical, get logical and physical port value\n");
313 	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
314 		port_set_masked_and_verify(port, BIT(TEST_PIN), test_vector[i], i);
315 		port_get_and_verify(port, BIT(TEST_PIN), test_vector[i], i);
316 		port_get_raw_and_verify(port, BIT(TEST_PIN), ~test_vector[i], i);
317 	}
318 
319 	TC_PRINT("Step 2: Set physical, get logical and physical port value\n");
320 	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
321 		port_set_masked_raw_and_verify(port, BIT(TEST_PIN), test_vector[i], i);
322 		port_get_and_verify(port, BIT(TEST_PIN), ~test_vector[i], i);
323 		port_get_raw_and_verify(port, BIT(TEST_PIN), test_vector[i], i);
324 	}
325 }
326 
ZTEST(gpio_api_1pin_port,test_gpio_port_set_bits_clear_bits_raw)327 ZTEST(gpio_api_1pin_port, test_gpio_port_set_bits_clear_bits_raw)
328 {
329 	const struct device *port;
330 	gpio_port_value_t val_expected = 0;
331 	int ret;
332 
333 	const gpio_port_value_t test_vector[][2] = {
334 		/* set value, clear value */
335 		{0xEE11EE11, 0xEE11EE11},
336 		{0x11EE11EE, TEST_GPIO_PORT_VALUE_MAX},
337 		{0x00000000, 0x55555555},
338 		{TEST_GPIO_PORT_VALUE_MAX, 0xAAAAAAAA},
339 		{TEST_GPIO_PORT_VALUE_MAX, TEST_GPIO_PORT_VALUE_MAX},
340 	};
341 
342 	port = DEVICE_DT_GET(TEST_NODE);
343 	zassert_true(device_is_ready(port), "GPIO dev is not ready");
344 
345 	TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
346 
347 	ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT);
348 	if (ret == -ENOTSUP) {
349 		TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
350 		ztest_test_skip();
351 		return;
352 	}
353 	zassert_equal(ret, 0, "Failed to configure the pin");
354 
355 	port_clear_bits_raw_and_verify(port, 0xFFFFFFFF, 0);
356 
357 	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
358 		port_set_bits_raw_and_verify(port, test_vector[i][0], i);
359 		val_expected |= test_vector[i][0] & (BIT(TEST_PIN));
360 		port_get_raw_and_verify(port, BIT(TEST_PIN), val_expected, i);
361 
362 		port_clear_bits_raw_and_verify(port, test_vector[i][1], i);
363 		val_expected &= ~(test_vector[i][1] & (BIT(TEST_PIN)));
364 		port_get_raw_and_verify(port, BIT(TEST_PIN), val_expected, i);
365 	}
366 }
367 
ZTEST(gpio_api_1pin_port,test_gpio_port_set_bits_clear_bits)368 ZTEST(gpio_api_1pin_port, test_gpio_port_set_bits_clear_bits)
369 {
370 	const struct device *port;
371 	gpio_port_value_t val_expected = 0;
372 	int ret;
373 
374 	const gpio_port_value_t test_vector[][2] = {
375 		/* set value, clear value */
376 		{TEST_GPIO_PORT_VALUE_MAX, 0xAAAAAAAA},
377 		{0x00000000, TEST_GPIO_PORT_VALUE_MAX},
378 		{0xCC33CC33, 0x33CC33CC},
379 		{0x33CC33CC, 0x33CC33CC},
380 		{0x00000000, 0x55555555},
381 	};
382 
383 	port = DEVICE_DT_GET(TEST_NODE);
384 	zassert_true(device_is_ready(port), "GPIO dev is not ready");
385 
386 	TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
387 
388 	ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT);
389 	if (ret == -ENOTSUP) {
390 		TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
391 		ztest_test_skip();
392 		return;
393 	}
394 	zassert_equal(ret, 0, "Failed to configure the pin");
395 
396 	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
397 		port_set_bits_and_verify(port, test_vector[i][0], i);
398 		val_expected |= test_vector[i][0] & (BIT(TEST_PIN));
399 		port_get_and_verify(port, BIT(TEST_PIN), val_expected, i);
400 
401 		port_clear_bits_and_verify(port, test_vector[i][1], i);
402 		val_expected &= ~(test_vector[i][1] & (BIT(TEST_PIN)));
403 		port_get_and_verify(port, BIT(TEST_PIN), val_expected, i);
404 	}
405 }
406 
ZTEST(gpio_api_1pin_port,test_gpio_port_set_clr_bits_raw)407 ZTEST(gpio_api_1pin_port, test_gpio_port_set_clr_bits_raw)
408 {
409 	const struct device *port;
410 	gpio_port_value_t val_expected = 0;
411 	int ret;
412 
413 	const gpio_port_value_t test_vector[][2] = {
414 		/* set value, clear value */
415 		{0xEE11EE11, 0x11EE11EE},
416 		{0x00000000, TEST_GPIO_PORT_VALUE_MAX},
417 		{0x55555555, 0x00000000},
418 		{TEST_GPIO_PORT_VALUE_MAX, 0x00000000},
419 		{0x00000000, 0x00000000},
420 		{0xAAAAAAAA, 0x00000000},
421 		{0x00000000, TEST_GPIO_PORT_VALUE_MAX},
422 	};
423 
424 	port = DEVICE_DT_GET(TEST_NODE);
425 	zassert_true(device_is_ready(port), "GPIO dev is not ready");
426 
427 	TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
428 
429 	ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT);
430 	if (ret == -ENOTSUP) {
431 		TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
432 		ztest_test_skip();
433 		return;
434 	}
435 	zassert_equal(ret, 0, "Failed to configure the pin");
436 
437 	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
438 		port_set_clr_bits_raw(port, test_vector[i][0], test_vector[i][1], i);
439 		val_expected |= test_vector[i][0] & (BIT(TEST_PIN));
440 		val_expected &= ~(test_vector[i][1] & (BIT(TEST_PIN)));
441 		port_get_raw_and_verify(port, BIT(TEST_PIN), val_expected, i);
442 	}
443 }
444 
ZTEST(gpio_api_1pin_port,test_gpio_port_set_clr_bits)445 ZTEST(gpio_api_1pin_port, test_gpio_port_set_clr_bits)
446 {
447 	const struct device *port;
448 	gpio_port_value_t val_expected = 0;
449 	int ret;
450 
451 	const gpio_port_value_t test_vector[][2] = {
452 		/* set value, clear value */
453 		{0xEE11EE11, 0x11EE11EE},
454 		{0x00000000, TEST_GPIO_PORT_VALUE_MAX},
455 		{0x55555555, 0x00000000},
456 		{TEST_GPIO_PORT_VALUE_MAX, 0x00000000},
457 		{0xAAAAAAAA, 0x00000000},
458 		{0x00000000, TEST_GPIO_PORT_VALUE_MAX},
459 	};
460 
461 	port = DEVICE_DT_GET(TEST_NODE);
462 	zassert_true(device_is_ready(port), "GPIO dev is not ready");
463 
464 	TC_PRINT("Running test on port=%s, pin=%d\n", port->name, TEST_PIN);
465 
466 	ret = gpio_pin_configure(port, TEST_PIN, GPIO_OUTPUT | GPIO_INPUT);
467 	if (ret == -ENOTSUP) {
468 		TC_PRINT("Simultaneous pin in/out mode is not supported.\n");
469 		ztest_test_skip();
470 		return;
471 	}
472 	zassert_equal(ret, 0, "Failed to configure the pin");
473 
474 	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
475 		port_set_clr_bits(port, test_vector[i][0], test_vector[i][1], i);
476 		val_expected |= test_vector[i][0] & (BIT(TEST_PIN));
477 		val_expected &= ~(test_vector[i][1] & (BIT(TEST_PIN)));
478 		port_get_and_verify(port, BIT(TEST_PIN), val_expected, i);
479 	}
480 }
481 
482 ZTEST_SUITE(gpio_api_1pin_port, NULL, NULL, NULL, NULL, NULL);
483