Skip to content

Commit

Permalink
drivers gpio SDL emul: Split in top and bottom
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
aescolar committed Jul 5, 2023
1 parent 09b876c commit 8b14161
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 21 deletions.
9 changes: 8 additions & 1 deletion drivers/gpio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
36 changes: 16 additions & 20 deletions drivers/gpio/gpio_emul_sdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_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++;
Expand All @@ -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) {
Expand All @@ -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;
}

Expand All @@ -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);
Expand Down
33 changes: 33 additions & 0 deletions drivers/gpio/gpio_emul_sdl_bottom.c
Original file line number Diff line number Diff line change
@@ -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_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);
}
39 changes: 39 additions & 0 deletions drivers/gpio/gpio_emul_sdl_bottom.h
Original file line number Diff line number Diff line change
@@ -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_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 */

0 comments on commit 8b14161

Please sign in to comment.