1 /*
2 * Copyright (c) 2020 Friedt Professional Engineering Services, Inc
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/device.h>
8 #include <zephyr/drivers/gpio.h>
9 #include <zephyr/drivers/gpio/gpio_emul.h>
10 #include <zephyr/sys/util.h>
11 #include <zephyr/kernel.h>
12
13 #include "test_gpio.h"
14
15 /*
16 * When GPIO are emulated, this callback can be used to implement the
17 * "wiring". E.g. in this test application, PIN_OUT is connected to
18 * PIN_IN. When PIN_OUT is set high or low, PIN_IN must be set
19 * correspondingly, as if a wire were connecting the two.
20 */
21 static void gpio_emul_callback_handler(const struct device *port,
22 struct gpio_callback *cb,
23 gpio_port_pins_t pins);
24
25 struct gpio_callback gpio_emul_callback = {
26 .handler = gpio_emul_callback_handler,
27 .pin_mask = BIT(PIN_IN) | BIT(PIN_OUT),
28 };
29
gpio_emul_callback_handler(const struct device * port,struct gpio_callback * cb,gpio_port_pins_t pins)30 static void gpio_emul_callback_handler(const struct device *port,
31 struct gpio_callback *cb,
32 gpio_port_pins_t pins)
33 {
34 int r;
35 int val;
36 uint32_t output_flags;
37 uint32_t input_flags;
38
39 __ASSERT(pins & gpio_emul_callback.pin_mask, "invalid mask: %x", pins);
40
41 r = gpio_emul_flags_get(port, PIN_OUT, &output_flags);
42 __ASSERT(r == 0, "gpio_emul_flags_get() failed: %d", r);
43 r = gpio_emul_flags_get(port, PIN_IN, &input_flags);
44 __ASSERT(r == 0, "gpio_emul_flags_get() failed: %d", r);
45
46 if ((output_flags & GPIO_OUTPUT) && (input_flags & GPIO_INPUT)) {
47 r = gpio_emul_output_get(port, PIN_OUT);
48 __ASSERT(r == 0 || r == 1, "gpio_emul_output_get() failed: %d", r);
49 val = r;
50 r = gpio_emul_input_set(port, PIN_IN, val);
51 __ASSERT(r == 0, "gpio_emul_input_set() failed: %d", r);
52
53 return;
54 }
55
56 if ((output_flags == GPIO_DISCONNECTED) && (input_flags & GPIO_INPUT)) {
57 if (input_flags & GPIO_PULL_UP) {
58 val = 1;
59 } else {
60 /* either GPIO_PULL_DOWN or no input */
61 val = 0;
62 }
63
64 r = gpio_emul_input_set(port, PIN_IN, val);
65 __ASSERT(r == 0, "gpio_emul_input_set() failed: %d", r);
66
67 return;
68 }
69 }
70