diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 6ef00311..4222c584 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -99,5 +99,6 @@ target_sources_ifdef(CONFIG_ZMK_LOW_PRIORITY_WORK_QUEUE app PRIVATE src/workqueu target_sources(app PRIVATE src/main.c) add_subdirectory(src/display/) +add_subdirectory(src/shell/) zephyr_cc_option(-Wfatal-errors) diff --git a/app/Kconfig b/app/Kconfig index bb6997a4..1c2556cb 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -449,6 +449,8 @@ endmenu menu "Advanced" +rsource "src/shell/Kconfig" + menu "Initialization Priorities" if USB_DEVICE_STACK diff --git a/app/boards/native_posix_64.overlay b/app/boards/native_posix_64.overlay index d0526ca3..5881ca34 100644 --- a/app/boards/native_posix_64.overlay +++ b/app/boards/native_posix_64.overlay @@ -14,6 +14,7 @@ rows = <2>; columns = <2>; exit-after; + events = <>; }; uart0: uart { diff --git a/app/src/shell/CMakeLists.txt b/app/src/shell/CMakeLists.txt new file mode 100644 index 00000000..76ead89b --- /dev/null +++ b/app/src/shell/CMakeLists.txt @@ -0,0 +1 @@ +target_sources_ifdef(CONFIG_ZMK_SHELL_KEY_POSITIONS app PRIVATE key_positions.c) \ No newline at end of file diff --git a/app/src/shell/Kconfig b/app/src/shell/Kconfig new file mode 100644 index 00000000..6d242235 --- /dev/null +++ b/app/src/shell/Kconfig @@ -0,0 +1,8 @@ +menu "Shell" + +config ZMK_SHELL_KEY_POSITIONS + bool "Key Position commands" + default y if !ZMK_SPLIT || ZMK_SPLIT_ROLE_CENTRAL + depends on SHELL + +endmenu diff --git a/app/src/shell/key_positions.c b/app/src/shell/key_positions.c new file mode 100644 index 00000000..12277fa4 --- /dev/null +++ b/app/src/shell/key_positions.c @@ -0,0 +1,80 @@ + +#include +#include +#include +#include +#include + +#define HELP_NONE "[key_position]" + +static int parse_key_position(const struct shell *shell, char *pos_str) { + int position; + char *endptr; + + position = strtoul(pos_str, &endptr, 10); + + if (endptr == pos_str) { + shell_error(shell, "Enter an integer key position"); + return -EINVAL; + } + + return position; +} + +static int parse_and_raise(const struct shell *shell, char *pos_str, bool pressed) { + int position = parse_key_position(shell, pos_str); + + if (position < 0) { + return position; + } + + ZMK_EVENT_RAISE(new_zmk_position_state_changed( + (struct zmk_position_state_changed){.source = ZMK_POSITION_STATE_CHANGE_SOURCE_LOCAL, + .state = pressed, + .position = position, + .timestamp = k_uptime_get()})); + + return position; +} + +static int cmd_key_tap(const struct shell *shell, size_t argc, char **argv) { + if (argc != 2) { + return -EINVAL; + } + + parse_and_raise(shell, argv[1], true); + + k_sleep(K_MSEC(50)); + + parse_and_raise(shell, argv[1], false); + + return 0; +}; + +static int cmd_key_press(const struct shell *shell, size_t argc, char **argv) { + if (argc != 2) { + return -EINVAL; + } + + parse_and_raise(shell, argv[1], true); + + return 0; +}; + +static int cmd_key_release(const struct shell *shell, size_t argc, char **argv) { + if (argc != 2) { + return -EINVAL; + } + + parse_and_raise(shell, argv[1], false); + + return 0; +}; + +SHELL_STATIC_SUBCMD_SET_CREATE(sub_key, SHELL_CMD(tap, NULL, HELP_NONE, cmd_key_tap), + SHELL_CMD(press, NULL, HELP_NONE, cmd_key_press), + SHELL_CMD(release, NULL, HELP_NONE, cmd_key_release), + SHELL_SUBCMD_SET_END /* Array terminated. */ +); + +SHELL_CMD_REGISTER(key, &sub_key, "Key commands", NULL); \ No newline at end of file