From b0c724a34be079017fb4146422381df33aa95976 Mon Sep 17 00:00:00 2001 From: ReFil <31960031+ReFil@users.noreply.github.com> Date: Fri, 8 Sep 2023 11:53:44 +0100 Subject: [PATCH] Initial profile switch work --- app/CMakeLists.txt | 1 + app/Kconfig | 4 ++ app/dts/bindings/zmk,profile-switch.yaml | 14 +++++ app/src/profile_switch.c | 65 ++++++++++++++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 app/dts/bindings/zmk,profile-switch.yaml create mode 100644 app/src/profile_switch.c diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 6ef00311027..096e701618a 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -96,6 +96,7 @@ target_sources_ifdef(CONFIG_ZMK_USB app PRIVATE src/usb_hid.c) target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/rgb_underglow.c) target_sources_ifdef(CONFIG_ZMK_BACKLIGHT app PRIVATE src/backlight.c) target_sources_ifdef(CONFIG_ZMK_LOW_PRIORITY_WORK_QUEUE app PRIVATE src/workqueue.c) +target_sources_ifdef(CONFIG_ZMK_PROFILESWITCH app PRIVATE src/profile_switch.c) target_sources(app PRIVATE src/main.c) add_subdirectory(src/display/) diff --git a/app/Kconfig b/app/Kconfig index bb6997a43ae..153782aa06b 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -238,6 +238,10 @@ config BT_PERIPHERAL_PREF_LATENCY config BT_PERIPHERAL_PREF_TIMEOUT default 400 +config ZMK_PROFILESWITCH + bool "Enable two state profile switch" + default n + #ZMK_BLE endif diff --git a/app/dts/bindings/zmk,profile-switch.yaml b/app/dts/bindings/zmk,profile-switch.yaml new file mode 100644 index 00000000000..2c093abe6e3 --- /dev/null +++ b/app/dts/bindings/zmk,profile-switch.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2020 The ZMK Contributors +# SPDX-License-Identifier: MIT + +description: | + Generic driver for controlling the bluetooth profile on the + switch-gpio pin status + (Only in supported hardware) + +compatible: "zmk,profile-switch" + +properties: + switch-gpios: + type: phandle-array + required: true diff --git a/app/src/profile_switch.c b/app/src/profile_switch.c new file mode 100644 index 00000000000..d6a820b7916 --- /dev/null +++ b/app/src/profile_switch.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include + +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +BUILD_ASSERT(DT_HAS_CHOSEN(zmk_profileswitch), + "CONFIG_ZMK_PROFILESWITCH is enabled but no zmk,profileswitch chosen node found"); + +struct gpio_callback a_gpio_cb; +const struct gpio_dt_spec switchgpio = GPIO_DT_SPEC_GET(DT_CHOSEN(zmk_profileswitch), switch_gpios); + +static void zmk_profile_switch_read() { + uint8_t val = gpio_pin_get_dt(&switchgpio); + LOG_DBG("Setting BLE profile to %d", val); + zmk_ble_prof_select(val); + if (gpio_pin_interrupt_configure_dt(&switchgpio, GPIO_INT_EDGE_BOTH)) { + LOG_WRN("Unable to set A pin GPIO interrupt"); + } +} + +static void zmk_profile_switch_work_cb(struct k_work *work) { zmk_profile_switch_read(); } + +K_WORK_DEFINE(profileswitch_work, zmk_profile_switch_work_cb); + +static void zmk_profile_switch_callback(const struct device *dev, struct gpio_callback *cb, + uint32_t pins) { + + if (gpio_pin_interrupt_configure_dt(&switchgpio, GPIO_INT_DISABLE)) { + LOG_WRN("Unable to set A pin GPIO interrupt"); + } + LOG_DBG("interrupt triggered"); + k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &profileswitch_work); +} + +static int zmk_profile_switch_init(const struct device *_arg) { + + if (!device_is_ready(switchgpio.port)) { + LOG_ERR("A GPIO device is not ready"); + return -EINVAL; + } + if (gpio_pin_configure_dt(&switchgpio, GPIO_INPUT)) { + LOG_DBG("Failed to configure A pin"); + return -EIO; + } + gpio_init_callback(&a_gpio_cb, zmk_profile_switch_callback, BIT(switchgpio.pin)); + + if (gpio_add_callback(switchgpio.port, &a_gpio_cb) < 0) { + LOG_DBG("Failed to set A callback!"); + return -EIO; + } + if (gpio_pin_interrupt_configure_dt(&switchgpio, GPIO_INT_EDGE_BOTH)) { + LOG_WRN("Unable to set A pin GPIO interrupt"); + } + LOG_DBG("Setting profile now"); + zmk_profile_switch_read(); + return 0; +} + +SYS_INIT(zmk_profile_switch_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); \ No newline at end of file