drivers gpio SDL emul: Split in top and bottom

Split the SDL GPIO emulator driver in a top and bottom
to enable using it with embedded libCs.

Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
This commit is contained in:
Alberto Escolar Piedras 2023-07-05 11:25:25 +02:00 committed by Alberto Escolar
parent 78ff21e1e1
commit 1457b361b6
4 changed files with 97 additions and 21 deletions

View file

@ -45,7 +45,6 @@ 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_PCAL64XXA gpio_pcal64xxa.c)
zephyr_library_sources_ifdef(CONFIG_GPIO_EOS_S3 gpio_eos_s3.c)
@ -82,6 +81,15 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_HOGS gpio_hogs.c)
zephyr_library_sources_ifdef(CONFIG_GPIO_NUMAKER gpio_numaker.c)
zephyr_library_sources_ifdef(CONFIG_GPIO_EFINIX_SAPPHIRE gpio_efinix_sapphire.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()
if(CONFIG_GPIO_SC18IM704)
zephyr_library_include_directories(${ZEPHYR_BASE}/drivers)
zephyr_library_sources(gpio_sc18im704.c)

View file

@ -10,37 +10,29 @@
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <SDL.h>
#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 *data;
};
static int sdl_filter(void *arg, SDL_Event *event)
static int sdl_filter_top(struct gpio_sdl_data *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->data->dev = (void *)dev;
config->data->callback = sdl_filter_top;
gpio_sdl_init_bottom(config->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 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), \
.data = &data_##inst, \
}; \
\
\
DEVICE_DT_INST_DEFINE(inst, gpio_sdl_init, NULL, NULL, \
&gpio_sdl_##inst##_config, POST_KERNEL, \
CONFIG_GPIO_INIT_PRIORITY, NULL);

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2022, Basalte bv
* Copyright (c) 2023 Nordic Semiconductor
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <SDL.h>
#include "gpio_emul_sdl_bottom.h"
static int sdl_filter_bottom(void *arg, SDL_Event *event)
{
struct gpio_sdl_data *data = arg;
/* Only handle keyboard events */
switch (event->type) {
case SDL_KEYDOWN:
case SDL_KEYUP:
break;
default:
return 1;
}
data->event_scan_code = event->key.keysym.scancode;
data->key_down = event->type == SDL_KEYDOWN;
return data->callback(arg);
}
void gpio_sdl_init_bottom(struct gpio_sdl_data *data)
{
SDL_AddEventWatch(sdl_filter_bottom, (void *)data);
}

View file

@ -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 <stdbool.h>
#include <stdint.h>
#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 {
void *dev;
int (*callback)(struct gpio_sdl_data *data);
int event_scan_code;
bool key_down;
};
void gpio_sdl_init_bottom(struct gpio_sdl_data *data);
#ifdef __cplusplus
}
#endif
#endif /* DRIVERS_GPIO_GPIO_EMUL_SDL_BOTTOM_H */