From 7d67130622ac86f67874fed6519908ec0cc925f7 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 14 Sep 2022 11:29:46 +0200 Subject: [PATCH 1/4] drivers: gpio: pca953x: select I2C Select I2C instead of depending on it, following upstream policy. Signed-off-by: Pieter De Gendt --- drivers/gpio/Kconfig.pca953x | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/Kconfig.pca953x b/drivers/gpio/Kconfig.pca953x index 5ed94370824cb..0bcb54cb8e5ac 100644 --- a/drivers/gpio/Kconfig.pca953x +++ b/drivers/gpio/Kconfig.pca953x @@ -8,7 +8,7 @@ menuconfig GPIO_PCA953X bool "PCA953X I2C GPIO chip" default y depends on DT_HAS_TI_TCA9538_ENABLED - depends on I2C + select I2C help Enable driver for PCA953X I2C GPIO chip. From 57d261431dd7cb23726a4558a9fd77beb9c50d9f Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Fri, 9 Sep 2022 10:57:01 +0200 Subject: [PATCH 2/4] 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 --- drivers/gpio/CMakeLists.txt | 1 + drivers/gpio/Kconfig | 2 + drivers/gpio/Kconfig.emul_sdl | 13 +++ drivers/gpio/gpio_emul_sdl.c | 103 ++++++++++++++++++++ dts/bindings/gpio/zephyr,gpio-emul-sdl.yaml | 53 ++++++++++ 5 files changed, 172 insertions(+) create mode 100644 drivers/gpio/Kconfig.emul_sdl create mode 100644 drivers/gpio/gpio_emul_sdl.c create mode 100644 dts/bindings/gpio/zephyr,gpio-emul-sdl.yaml diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index eb228bb51b4b8..ba81f597d8911 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -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) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index d8b8404f57122..06a78c2b63131 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -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" diff --git a/drivers/gpio/Kconfig.emul_sdl b/drivers/gpio/Kconfig.emul_sdl new file mode 100644 index 0000000000000..fb57cb9f1c697 --- /dev/null +++ b/drivers/gpio/Kconfig.emul_sdl @@ -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. diff --git a/drivers/gpio/gpio_emul_sdl.c b/drivers/gpio/gpio_emul_sdl.c new file mode 100644 index 0000000000000..015d0f352c9f7 --- /dev/null +++ b/drivers/gpio/gpio_emul_sdl.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2022, Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT zephyr_gpio_emul_sdl + +#include +#include + +#include + +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) diff --git a/dts/bindings/gpio/zephyr,gpio-emul-sdl.yaml b/dts/bindings/gpio/zephyr,gpio-emul-sdl.yaml new file mode 100644 index 0000000000000..2893740319751 --- /dev/null +++ b/dts/bindings/gpio/zephyr,gpio-emul-sdl.yaml @@ -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 From 14d1753024507943ae1e004177a58148ba7a665b Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Tue, 13 Sep 2022 14:43:45 +0200 Subject: [PATCH 3/4] samples: subsys: display: lvgl: Add button to reset counter Connect the sw0 alias to reset the counter. Signed-off-by: Pieter De Gendt --- samples/subsys/display/lvgl/src/main.c | 51 +++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/samples/subsys/display/lvgl/src/main.c b/samples/subsys/display/lvgl/src/main.c index 1b8e944b45101..900961ff8eb5a 100644 --- a/samples/subsys/display/lvgl/src/main.c +++ b/samples/subsys/display/lvgl/src/main.c @@ -5,7 +5,9 @@ */ #include +#include #include +#include #include #include #include @@ -15,9 +17,28 @@ #include LOG_MODULE_REGISTER(app); +static uint32_t count; + +#ifdef CONFIG_GPIO +static struct gpio_dt_spec button_gpio = GPIO_DT_SPEC_GET_OR( + DT_ALIAS(sw0), gpios, {0}); +static struct gpio_callback button_callback; + +static void button_isr_callback(const struct device *port, + struct gpio_callback *cb, + uint32_t pins) +{ + ARG_UNUSED(port); + ARG_UNUSED(cb); + ARG_UNUSED(pins); + + count = 0; +} +#endif + void main(void) { - uint32_t count = 0U; + int err; char count_str[11] = {0}; const struct device *display_dev; lv_obj_t *hello_world_label; @@ -29,6 +50,32 @@ void main(void) return; } +#ifdef CONFIG_GPIO + if (device_is_ready(button_gpio.port)) { + err = gpio_pin_configure_dt(&button_gpio, GPIO_INPUT); + if (err) { + LOG_ERR("failed to configure button gpio: %d", err); + return; + } + + gpio_init_callback(&button_callback, button_isr_callback, + BIT(button_gpio.pin)); + + err = gpio_add_callback(button_gpio.port, &button_callback); + if (err) { + LOG_ERR("failed to add button callback: %d", err); + return; + } + + err = gpio_pin_interrupt_configure_dt(&button_gpio, + GPIO_INT_EDGE_TO_ACTIVE); + if (err) { + LOG_ERR("failed to enable button callback: %d", err); + return; + } + } +#endif + if (IS_ENABLED(CONFIG_LV_Z_POINTER_KSCAN)) { lv_obj_t *hello_world_button; @@ -54,7 +101,7 @@ void main(void) lv_label_set_text(count_label, count_str); } lv_task_handler(); - k_sleep(K_MSEC(10)); ++count; + k_sleep(K_MSEC(10)); } } From 380bfc07cc369490c195d331f329a539bdf42c6d Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Tue, 13 Sep 2022 14:45:30 +0200 Subject: [PATCH 4/4] samples: subsys: display: lvgl: Add native_posix overlay for SDL input Enable SDL keyboard events using the zephyr,gpio-emul-sdl driver and alias key to sw0. Pressing 'r' on the keyboard resets the counter. Signed-off-by: Pieter De Gendt --- .../display/lvgl/boards/native_posix.conf | 1 + .../display/lvgl/boards/native_posix.overlay | 31 +++++++++++++++++++ .../display/lvgl/boards/native_posix_64.conf | 1 + .../lvgl/boards/native_posix_64.overlay | 6 ++++ 4 files changed, 39 insertions(+) create mode 100644 samples/subsys/display/lvgl/boards/native_posix.overlay create mode 100644 samples/subsys/display/lvgl/boards/native_posix_64.overlay diff --git a/samples/subsys/display/lvgl/boards/native_posix.conf b/samples/subsys/display/lvgl/boards/native_posix.conf index 1f42f11f7ab0a..c14d92acb8f38 100644 --- a/samples/subsys/display/lvgl/boards/native_posix.conf +++ b/samples/subsys/display/lvgl/boards/native_posix.conf @@ -1 +1,2 @@ CONFIG_LV_COLOR_DEPTH_32=y +CONFIG_GPIO=y diff --git a/samples/subsys/display/lvgl/boards/native_posix.overlay b/samples/subsys/display/lvgl/boards/native_posix.overlay new file mode 100644 index 0000000000000..3813072d1092b --- /dev/null +++ b/samples/subsys/display/lvgl/boards/native_posix.overlay @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022, Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +/ { + aliases { + sw0 = &button0; + }; + + keys { + compatible = "gpio-keys"; + button0: button0 { + /* gpio0 pin 0 is already aliased to led0 */ + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&gpio0 { + ngpios = <2>; + + sdl_gpio { + status = "okay"; + compatible = "zephyr,gpio-emul-sdl"; + /* Skip pin 0 with the unknown code 0 */ + scancodes = <0 21>; + }; +}; diff --git a/samples/subsys/display/lvgl/boards/native_posix_64.conf b/samples/subsys/display/lvgl/boards/native_posix_64.conf index 1f42f11f7ab0a..c14d92acb8f38 100644 --- a/samples/subsys/display/lvgl/boards/native_posix_64.conf +++ b/samples/subsys/display/lvgl/boards/native_posix_64.conf @@ -1 +1,2 @@ CONFIG_LV_COLOR_DEPTH_32=y +CONFIG_GPIO=y diff --git a/samples/subsys/display/lvgl/boards/native_posix_64.overlay b/samples/subsys/display/lvgl/boards/native_posix_64.overlay new file mode 100644 index 0000000000000..060625d230cb9 --- /dev/null +++ b/samples/subsys/display/lvgl/boards/native_posix_64.overlay @@ -0,0 +1,6 @@ +/* + * Copyright (c) 2022, Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "native_posix.overlay"