diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 13b4c6eba83a931..12c1281d6d383d1 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -45,7 +45,14 @@ 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) +if (CONFIG_GPIO_EMUL_SDL) + zephyr_library_sources(gpio_emul_sdl.c) + if (CONFIG_NATIVE_APPLICATION) + zephyr_library_sources(gpio_emul_sdl_bottom.c) + else() + target_sources(native_simulator INTERFACE gpio_emul_sdl_bottom.c) + endif() +endif() zephyr_library_sources_ifdef(CONFIG_GPIO_PSOC6 gpio_psoc6.c) zephyr_library_sources_ifdef(CONFIG_GPIO_PCAL64XXA gpio_pcal64xxa.c) zephyr_library_sources_ifdef(CONFIG_GPIO_EOS_S3 gpio_eos_s3.c) diff --git a/drivers/gpio/gpio_emul_sdl.c b/drivers/gpio/gpio_emul_sdl.c index aa121322b91969d..ab23e6e6a2a1249 100644 --- a/drivers/gpio/gpio_emul_sdl.c +++ b/drivers/gpio/gpio_emul_sdl.c @@ -10,37 +10,29 @@ #include #include -#include +#include "gpio_emul_sdl_bottom.h" LOG_MODULE_REGISTER(gpio_emul_sdl, CONFIG_GPIO_LOG_LEVEL); struct gpio_sdl_config { const struct device *emul; - const SDL_Scancode *codes; + const int *codes; uint8_t num_codes; + struct gpio_sdl_data_bottom *bottom_data; }; -static int sdl_filter(void *arg, SDL_Event *event) +static int sdl_filter_top(struct gpio_sdl_data_bottom *bottom_data) { - const struct device *port = arg; + const struct device *port = bottom_data->dev; 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) { + if (config->codes[pin] == bottom_data->event_scan_code) { break; } pin++; @@ -58,7 +50,7 @@ static int sdl_filter(void *arg, SDL_Event *event) k_sched_lock(); /* Update the pin state */ - ret = gpio_emul_input_set(config->emul, pin, event->type == SDL_KEYDOWN ? 1 : 0); + ret = gpio_emul_input_set(config->emul, pin, bottom_data->key_down); k_sched_unlock(); if (ret < 0) { @@ -73,13 +65,14 @@ 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) { + if (config->codes[pin] != GPIOEMULSDL_SCANCODE_UNKNOWN) { LOG_INF("GPIO %s:%u = %u", dev->name, pin, config->codes[pin]); } } - SDL_AddEventWatch(sdl_filter, (void *)dev); - + config->bottom_data->dev = (void *)dev; + config->bottom_data->callback = sdl_filter_top; + gpio_sdl_init_bottom(config->bottom_data); return 0; } @@ -88,15 +81,18 @@ static int gpio_sdl_init(const struct device *dev) zephyr_gpio_emul, okay), \ "Enabled parent zephyr,gpio-emul node is required"); \ \ - static const SDL_Scancode gpio_sdl_##inst##_codes[] \ + static const int gpio_sdl_##inst##_codes[] \ = DT_INST_PROP(inst, scancodes); \ \ + static struct gpio_sdl_data_bottom bottom_data_##inst; \ + \ 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), \ + .bottom_data = &bottom_data_##inst, \ }; \ - \ + \ DEVICE_DT_INST_DEFINE(inst, gpio_sdl_init, NULL, NULL, \ &gpio_sdl_##inst##_config, POST_KERNEL, \ CONFIG_GPIO_INIT_PRIORITY, NULL); diff --git a/drivers/gpio/gpio_emul_sdl_bottom.c b/drivers/gpio/gpio_emul_sdl_bottom.c new file mode 100644 index 000000000000000..45bc21e8310e9c8 --- /dev/null +++ b/drivers/gpio/gpio_emul_sdl_bottom.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022, Basalte bv + * Copyright (c) 2023 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "gpio_emul_sdl_bottom.h" + +static int sdl_filter_bottom(void *arg, SDL_Event *event) +{ + struct gpio_sdl_data_bottom *bottom_data = arg; + + /* Only handle keyboard events */ + switch (event->type) { + case SDL_KEYDOWN: + case SDL_KEYUP: + break; + default: + return 1; + } + + bottom_data->event_scan_code = event->key.keysym.scancode; + bottom_data->key_down = event->type == SDL_KEYDOWN; + + return bottom_data->callback(arg); +} + +void gpio_sdl_init_bottom(struct gpio_sdl_data_bottom *data) +{ + SDL_AddEventWatch(sdl_filter_bottom, (void *)data); +} diff --git a/drivers/gpio/gpio_emul_sdl_bottom.h b/drivers/gpio/gpio_emul_sdl_bottom.h new file mode 100644 index 000000000000000..6d93e4d9eb70475 --- /dev/null +++ b/drivers/gpio/gpio_emul_sdl_bottom.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022, Basalte bv + * Copyright (c) 2023 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + * + * "Bottom" of the SDL GPIO emulator. + * When built with the native_simulator this will be built in the runner context, + * that is, with the host C library, and with the host include paths. + */ + +#ifndef DRIVERS_GPIO_GPIO_EMUL_SDL_BOTTOM_H +#define DRIVERS_GPIO_GPIO_EMUL_SDL_BOTTOM_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Note: None of these are public interfaces. But internal to the SDL GPIO emulator */ + +#define GPIOEMULSDL_SCANCODE_UNKNOWN 0 + +struct gpio_sdl_data_bottom { + void *dev; + int (*callback)(struct gpio_sdl_data_bottom *data); + int event_scan_code; + bool key_down; +}; + +void gpio_sdl_init_bottom(struct gpio_sdl_data_bottom *data); + +#ifdef __cplusplus +} +#endif + +#endif /* DRIVERS_GPIO_GPIO_EMUL_SDL_BOTTOM_H */