blob: 0752795c648805f62912d5d0d865c39b1f73ef62 [file] [log] [blame]
/*
* Copyright (c) 2020 Friedt Professional Engineering Services, Inc
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <drivers/gpio.h>
#include <drivers/gpio/gpio_emul.h>
#include <sys/util.h>
#include <zephyr.h>
#include "test_gpio.h"
/*
* When GPIO are emulated, this callback can be used to implement the
* "wiring". E.g. in this test application, PIN_OUT is connected to
* PIN_IN. When PIN_OUT is set high or low, PIN_IN must be set
* correspondingly, as if a wire were connecting the two.
*/
static void gpio_emul_callback_handler(const struct device *port,
struct gpio_callback *cb,
gpio_port_pins_t pins);
struct gpio_callback gpio_emul_callback = {
.handler = gpio_emul_callback_handler,
.pin_mask = BIT(PIN_IN) | BIT(PIN_OUT),
};
static void gpio_emul_callback_handler(const struct device *port,
struct gpio_callback *cb,
gpio_port_pins_t pins)
{
int r;
int val;
uint32_t output_flags;
uint32_t input_flags;
__ASSERT(pins & gpio_emul_callback.pin_mask, "invalid mask: %x", pins);
r = gpio_emul_flags_get(port, PIN_OUT, &output_flags);
__ASSERT(r == 0, "gpio_emul_flags_get() failed: %d", r);
r = gpio_emul_flags_get(port, PIN_IN, &input_flags);
__ASSERT(r == 0, "gpio_emul_flags_get() failed: %d", r);
if ((output_flags & GPIO_OUTPUT) && (input_flags & GPIO_INPUT)) {
r = gpio_emul_output_get(port, PIN_OUT);
__ASSERT(r == 0 || r == 1, "gpio_emul_output_get() failed: %d", r);
val = r;
r = gpio_emul_input_set(port, PIN_IN, val);
__ASSERT(r == 0, "gpio_emul_input_set() failed: %d", r);
return;
}
if ((output_flags == GPIO_DISCONNECTED) && (input_flags & GPIO_INPUT)) {
if (input_flags & GPIO_PULL_UP) {
val = 1;
} else {
/* either GPIO_PULL_DOWN or no input */
val = 0;
}
r = gpio_emul_input_set(port, PIN_IN, val);
__ASSERT(r == 0, "gpio_emul_input_set() failed: %d", r);
return;
}
}