drivers: gpio: Add SDL emulated GPIO support
This commit adds a driver to simulate GPIO state and interrupts using the keyboard when using SDL. Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
This commit is contained in:
parent
bd71698a66
commit
ff8a90b1de
|
@ -38,6 +38,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_LPC11U6X gpio_lpc11u6x.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_GPIO_XLNX_AXI gpio_xlnx_axi.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_NPCX gpio_npcx.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_EMUL gpio_emul.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_EMUL_SDL gpio_emul_sdl.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_PSOC6 gpio_psoc6.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_PCAL6408A gpio_pcal6408a.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_EOS_S3 gpio_eos_s3.c)
|
||||
|
|
|
@ -110,6 +110,8 @@ source "drivers/gpio/Kconfig.npcx"
|
|||
|
||||
source "drivers/gpio/Kconfig.emul"
|
||||
|
||||
source "drivers/gpio/Kconfig.emul_sdl"
|
||||
|
||||
source "drivers/gpio/Kconfig.psoc6"
|
||||
|
||||
source "drivers/gpio/Kconfig.pcal6408a"
|
||||
|
|
13
drivers/gpio/Kconfig.emul_sdl
Normal file
13
drivers/gpio/Kconfig.emul_sdl
Normal file
|
@ -0,0 +1,13 @@
|
|||
# GPIO emulation using SDL keyboard events
|
||||
#
|
||||
# Copyright (c) 2022, Basalte bv
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config GPIO_EMUL_SDL
|
||||
bool "SDL GPIO emulation"
|
||||
default y
|
||||
depends on DT_HAS_ZEPHYR_GPIO_EMUL_SDL_ENABLED
|
||||
depends on GPIO_EMUL
|
||||
depends on HAS_SDL
|
||||
help
|
||||
Enable GPIO emulation using SDL keyboard events.
|
103
drivers/gpio/gpio_emul_sdl.c
Normal file
103
drivers/gpio/gpio_emul_sdl.c
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Basalte bv
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT zephyr_gpio_emul_sdl
|
||||
|
||||
#include <zephyr/drivers/gpio/gpio_emul.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
LOG_MODULE_REGISTER(gpio_emul_sdl, CONFIG_GPIO_LOG_LEVEL);
|
||||
|
||||
struct gpio_sdl_config {
|
||||
const struct device *emul;
|
||||
|
||||
const SDL_Scancode *codes;
|
||||
uint8_t num_codes;
|
||||
};
|
||||
|
||||
static int sdl_filter(void *arg, SDL_Event *event)
|
||||
{
|
||||
const struct device *port = arg;
|
||||
const struct gpio_sdl_config *config = port->config;
|
||||
int ret;
|
||||
|
||||
gpio_pin_t pin = 0;
|
||||
|
||||
/* Only handle keyboard events */
|
||||
switch (event->type) {
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Search for the corresponding scancode */
|
||||
while (pin < config->num_codes) {
|
||||
if (config->codes[pin] == event->key.keysym.scancode) {
|
||||
break;
|
||||
}
|
||||
pin++;
|
||||
}
|
||||
|
||||
if (pin == config->num_codes) {
|
||||
/* Not tracked */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Lock the scheduler so we can't be preempted,
|
||||
* as the gpio_emul driver keeps a mutex locked
|
||||
* for as long as there are pending interrupts
|
||||
*/
|
||||
k_sched_lock();
|
||||
|
||||
/* Update the pin state */
|
||||
ret = gpio_emul_input_set(config->emul, pin, event->type == SDL_KEYDOWN ? 1 : 0);
|
||||
|
||||
k_sched_unlock();
|
||||
if (ret < 0) {
|
||||
LOG_WRN("Failed to emulate input (%d)", ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_sdl_init(const struct device *dev)
|
||||
{
|
||||
const struct gpio_sdl_config *config = dev->config;
|
||||
|
||||
for (uint8_t pin = 0; pin < config->num_codes; ++pin) {
|
||||
if (config->codes[pin] != SDL_SCANCODE_UNKNOWN) {
|
||||
LOG_INF("GPIO %s:%u = %u", dev->name, pin, config->codes[pin]);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_AddEventWatch(sdl_filter, (void *)dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define GPIO_SDL_DEFINE(inst) \
|
||||
BUILD_ASSERT(DT_NODE_HAS_COMPAT_STATUS(DT_INST_PARENT(inst), \
|
||||
zephyr_gpio_emul, okay), \
|
||||
"Enabled parent zephyr,gpio-emul node is required"); \
|
||||
\
|
||||
static const SDL_Scancode gpio_sdl_##inst##_codes[] \
|
||||
= DT_INST_PROP(inst, scancodes); \
|
||||
\
|
||||
static const struct gpio_sdl_config gpio_sdl_##inst##_config = { \
|
||||
.emul = DEVICE_DT_GET(DT_INST_PARENT(inst)), \
|
||||
.codes = gpio_sdl_##inst##_codes, \
|
||||
.num_codes = DT_INST_PROP_LEN(inst, scancodes), \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(inst, gpio_sdl_init, NULL, NULL, \
|
||||
&gpio_sdl_##inst##_config, POST_KERNEL, \
|
||||
CONFIG_GPIO_INIT_PRIORITY, NULL);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(GPIO_SDL_DEFINE)
|
53
dts/bindings/gpio/zephyr,gpio-emul-sdl.yaml
Normal file
53
dts/bindings/gpio/zephyr,gpio-emul-sdl.yaml
Normal file
|
@ -0,0 +1,53 @@
|
|||
# Copyright 2022, Basalte bv
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: |
|
||||
SDL keyboard GPIO input Emulator
|
||||
|
||||
Simulate GPIO state/interrupts using SDL keyboard events. This node has
|
||||
to be a child of a `zephyr,gpio-emul` compatible.
|
||||
Add a list of scancodes for the desired keys to be mapped.
|
||||
|
||||
Refer to https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf
|
||||
section Keyboard/Keypad (p53) for a list of scancode values.
|
||||
|
||||
The following example maps the first 3 numeric keys to GPIO pins:
|
||||
|
||||
/* gpio0 has to be a zephyr,gpio-emul device */
|
||||
&gpio0 {
|
||||
ngpios = <3>;
|
||||
|
||||
sdl_gpio {
|
||||
compatible = "zephyr,gpio-emul-sdl";
|
||||
scancodes = <30 31 32>;
|
||||
};
|
||||
};
|
||||
|
||||
keypad: keypad {
|
||||
compatible = "gpio-keys";
|
||||
key1: key1 {
|
||||
gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
key1: key2 {
|
||||
gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
key3: key3 {
|
||||
gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
The limitations of usage are:
|
||||
- Only active high as we don't get events for keys that aren't pressed
|
||||
- Pressing multiple keys is best effort, state will be kept but no events
|
||||
are generated once the last key is released
|
||||
|
||||
compatible: "zephyr,gpio-emul-sdl"
|
||||
|
||||
include: base.yaml
|
||||
|
||||
properties:
|
||||
scancodes:
|
||||
type: array
|
||||
required: true
|
||||
description: |
|
||||
An array of SDL scancodes mapped to its GPIO index
|
Loading…
Reference in a new issue