Skip to content

Commit ff8a90b

Browse files
pdgendtcarlescufi
authored andcommitted
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 <[email protected]>
1 parent bd71698 commit ff8a90b

File tree

5 files changed

+172
-0
lines changed

5 files changed

+172
-0
lines changed

drivers/gpio/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_LPC11U6X gpio_lpc11u6x.c)
3838
zephyr_library_sources_ifdef(CONFIG_GPIO_XLNX_AXI gpio_xlnx_axi.c)
3939
zephyr_library_sources_ifdef(CONFIG_GPIO_NPCX gpio_npcx.c)
4040
zephyr_library_sources_ifdef(CONFIG_GPIO_EMUL gpio_emul.c)
41+
zephyr_library_sources_ifdef(CONFIG_GPIO_EMUL_SDL gpio_emul_sdl.c)
4142
zephyr_library_sources_ifdef(CONFIG_GPIO_PSOC6 gpio_psoc6.c)
4243
zephyr_library_sources_ifdef(CONFIG_GPIO_PCAL6408A gpio_pcal6408a.c)
4344
zephyr_library_sources_ifdef(CONFIG_GPIO_EOS_S3 gpio_eos_s3.c)

drivers/gpio/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ source "drivers/gpio/Kconfig.npcx"
110110

111111
source "drivers/gpio/Kconfig.emul"
112112

113+
source "drivers/gpio/Kconfig.emul_sdl"
114+
113115
source "drivers/gpio/Kconfig.psoc6"
114116

115117
source "drivers/gpio/Kconfig.pcal6408a"

drivers/gpio/Kconfig.emul_sdl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# GPIO emulation using SDL keyboard events
2+
#
3+
# Copyright (c) 2022, Basalte bv
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
config GPIO_EMUL_SDL
7+
bool "SDL GPIO emulation"
8+
default y
9+
depends on DT_HAS_ZEPHYR_GPIO_EMUL_SDL_ENABLED
10+
depends on GPIO_EMUL
11+
depends on HAS_SDL
12+
help
13+
Enable GPIO emulation using SDL keyboard events.

drivers/gpio/gpio_emul_sdl.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright (c) 2022, Basalte bv
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT zephyr_gpio_emul_sdl
8+
9+
#include <zephyr/drivers/gpio/gpio_emul.h>
10+
#include <zephyr/logging/log.h>
11+
12+
#include <SDL.h>
13+
14+
LOG_MODULE_REGISTER(gpio_emul_sdl, CONFIG_GPIO_LOG_LEVEL);
15+
16+
struct gpio_sdl_config {
17+
const struct device *emul;
18+
19+
const SDL_Scancode *codes;
20+
uint8_t num_codes;
21+
};
22+
23+
static int sdl_filter(void *arg, SDL_Event *event)
24+
{
25+
const struct device *port = arg;
26+
const struct gpio_sdl_config *config = port->config;
27+
int ret;
28+
29+
gpio_pin_t pin = 0;
30+
31+
/* Only handle keyboard events */
32+
switch (event->type) {
33+
case SDL_KEYDOWN:
34+
case SDL_KEYUP:
35+
break;
36+
default:
37+
return 1;
38+
}
39+
40+
/* Search for the corresponding scancode */
41+
while (pin < config->num_codes) {
42+
if (config->codes[pin] == event->key.keysym.scancode) {
43+
break;
44+
}
45+
pin++;
46+
}
47+
48+
if (pin == config->num_codes) {
49+
/* Not tracked */
50+
return 1;
51+
}
52+
53+
/* Lock the scheduler so we can't be preempted,
54+
* as the gpio_emul driver keeps a mutex locked
55+
* for as long as there are pending interrupts
56+
*/
57+
k_sched_lock();
58+
59+
/* Update the pin state */
60+
ret = gpio_emul_input_set(config->emul, pin, event->type == SDL_KEYDOWN ? 1 : 0);
61+
62+
k_sched_unlock();
63+
if (ret < 0) {
64+
LOG_WRN("Failed to emulate input (%d)", ret);
65+
}
66+
67+
return 0;
68+
}
69+
70+
static int gpio_sdl_init(const struct device *dev)
71+
{
72+
const struct gpio_sdl_config *config = dev->config;
73+
74+
for (uint8_t pin = 0; pin < config->num_codes; ++pin) {
75+
if (config->codes[pin] != SDL_SCANCODE_UNKNOWN) {
76+
LOG_INF("GPIO %s:%u = %u", dev->name, pin, config->codes[pin]);
77+
}
78+
}
79+
80+
SDL_AddEventWatch(sdl_filter, (void *)dev);
81+
82+
return 0;
83+
}
84+
85+
#define GPIO_SDL_DEFINE(inst) \
86+
BUILD_ASSERT(DT_NODE_HAS_COMPAT_STATUS(DT_INST_PARENT(inst), \
87+
zephyr_gpio_emul, okay), \
88+
"Enabled parent zephyr,gpio-emul node is required"); \
89+
\
90+
static const SDL_Scancode gpio_sdl_##inst##_codes[] \
91+
= DT_INST_PROP(inst, scancodes); \
92+
\
93+
static const struct gpio_sdl_config gpio_sdl_##inst##_config = { \
94+
.emul = DEVICE_DT_GET(DT_INST_PARENT(inst)), \
95+
.codes = gpio_sdl_##inst##_codes, \
96+
.num_codes = DT_INST_PROP_LEN(inst, scancodes), \
97+
}; \
98+
\
99+
DEVICE_DT_INST_DEFINE(inst, gpio_sdl_init, NULL, NULL, \
100+
&gpio_sdl_##inst##_config, POST_KERNEL, \
101+
CONFIG_GPIO_INIT_PRIORITY, NULL);
102+
103+
DT_INST_FOREACH_STATUS_OKAY(GPIO_SDL_DEFINE)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Copyright 2022, Basalte bv
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: |
5+
SDL keyboard GPIO input Emulator
6+
7+
Simulate GPIO state/interrupts using SDL keyboard events. This node has
8+
to be a child of a `zephyr,gpio-emul` compatible.
9+
Add a list of scancodes for the desired keys to be mapped.
10+
11+
Refer to https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf
12+
section Keyboard/Keypad (p53) for a list of scancode values.
13+
14+
The following example maps the first 3 numeric keys to GPIO pins:
15+
16+
/* gpio0 has to be a zephyr,gpio-emul device */
17+
&gpio0 {
18+
ngpios = <3>;
19+
20+
sdl_gpio {
21+
compatible = "zephyr,gpio-emul-sdl";
22+
scancodes = <30 31 32>;
23+
};
24+
};
25+
26+
keypad: keypad {
27+
compatible = "gpio-keys";
28+
key1: key1 {
29+
gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
30+
};
31+
key1: key2 {
32+
gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
33+
};
34+
key3: key3 {
35+
gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
36+
};
37+
};
38+
39+
The limitations of usage are:
40+
- Only active high as we don't get events for keys that aren't pressed
41+
- Pressing multiple keys is best effort, state will be kept but no events
42+
are generated once the last key is released
43+
44+
compatible: "zephyr,gpio-emul-sdl"
45+
46+
include: base.yaml
47+
48+
properties:
49+
scancodes:
50+
type: array
51+
required: true
52+
description: |
53+
An array of SDL scancodes mapped to its GPIO index

0 commit comments

Comments
 (0)