From 644a05a2744d739f29a39c3de70ed1cdb930eedf Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Sat, 16 May 2020 17:30:30 -0400 Subject: [PATCH] Keymap directory support. --- CMakeLists.txt | 2 + README.md | 3 +- .../keymaps/petejohanson/keymap.overlay | 35 +++++++ .../petejohanson_handwire.overlay | 32 ------- cmake/keymap.cmake | 91 +++++++++++++++++++ 5 files changed, 130 insertions(+), 33 deletions(-) create mode 100644 boards/shields/petejohanson_handwire/keymaps/petejohanson/keymap.overlay create mode 100644 cmake/keymap.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 385000cf..dc8ccdae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,8 @@ cmake_minimum_required(VERSION 3.13.1) list(APPEND BOARD_ROOT ${CMAKE_SOURCE_DIR}) list(APPEND DTS_ROOT ${CMAKE_SOURCE_DIR}) +include(cmake/keymap.cmake) + find_package(Zephyr) project(zmk) diff --git a/README.md b/README.md index b7145b3c..311e782b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ with a less restritive license and better BLE support, built on top of the [Zeph ## TODO - Debouncing in the kscan driver itself? Only some GPIO drivers in Zephyr support it "natively" -- Better DTS overlay setup for _keymaps_. Current use of SHIELDs works, but perhaps would be better with something more integrated. +- Document boards/shields/keymaps usage. +- Custom keymap code via `zephyr_library()`> - Move most Kconfig setings to the board/keymap defconfigs and out of the toplevel `prj.conf` file. - Merge the Kscan GPIO driver upstream, or integrate it locally, to avoid use of Zephyr branch. - BLE SC by typing in the # prompted on the host. diff --git a/boards/shields/petejohanson_handwire/keymaps/petejohanson/keymap.overlay b/boards/shields/petejohanson_handwire/keymaps/petejohanson/keymap.overlay new file mode 100644 index 00000000..9e7d3d80 --- /dev/null +++ b/boards/shields/petejohanson_handwire/keymaps/petejohanson/keymap.overlay @@ -0,0 +1,35 @@ +#include + +/ { + chosen { + zmk,keymap = &keymap0; + }; + keymap0: keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + layers = <&default &lower &raise>; + }; + + layers { + compatible = "zmk,layers"; + + default: layer_0 { + label = "Default"; + keys = + < + KC_A KC_B + KC_C ZC_CSTM(1) + >; + }; + + lower: layer_1 { + label = "Lower"; + keys = ; + }; + + raise: layer_2 { + label = "Raise"; + keys = ; + }; + }; +}; diff --git a/boards/shields/petejohanson_handwire/petejohanson_handwire.overlay b/boards/shields/petejohanson_handwire/petejohanson_handwire.overlay index fd55b28d..72e24a0b 100644 --- a/boards/shields/petejohanson_handwire/petejohanson_handwire.overlay +++ b/boards/shields/petejohanson_handwire/petejohanson_handwire.overlay @@ -1,41 +1,9 @@ -#include / { chosen { - zmk,keymap = &keymap0; zmk,kscan = &kscan0; }; - layers { - compatible = "zmk,layers"; - - default: layer_0 { - label = "Default"; - keys = - < - KC_A KC_B - KC_C ZC_CSTM(1) - >; - }; - - lower: layer_1 { - label = "Lower"; - keys = ; - }; - - raise: layer_2 { - label = "Raise"; - keys = ; - }; - }; - - keymap0: keymap { - compatible = "zmk,keymap"; - - label ="Default keymap"; - layers = <&default &lower &raise>; - }; - kscan0: kscan { compatible = "gpio-kscan"; label = "KSCAN"; diff --git a/cmake/keymap.cmake b/cmake/keymap.cmake new file mode 100644 index 00000000..b7039f38 --- /dev/null +++ b/cmake/keymap.cmake @@ -0,0 +1,91 @@ + +get_property(cached_keymap_value CACHE KEYMAP PROPERTY VALUE) + +# There are actually 4 sources, the three user input sources, and the +# previously used value (CACHED_KEYMAP). The previously used value has +# precedence, and if we detect that the user is trying to change the +# value we give him a warning about needing to clean the build +# directory to be able to change keymaps. + +set(keymap_cli_argument ${cached_keymap_value}) # Either new or old +if(keymap_cli_argument STREQUAL CACHED_KEYMAP) + # We already have a CACHED_KEYMAP so there is no new input on the CLI + unset(keymap_cli_argument) +endif() + +set(keymap_app_cmake_lists ${KEYMAP}) +if(cached_keymap_value STREQUAL KEYMAP) + # The app build scripts did not set a default, The KEYMAP we are + # reading is the cached value from the CLI + unset(keymap_app_cmake_lists) +endif() + +if(CACHED_KEYMAP) + # Warn the user if it looks like he is trying to change the keymap + # without cleaning first + if(keymap_cli_argument) + if(NOT (CACHED_KEYMAP STREQUAL keymap_cli_argument)) + message(WARNING "The build directory must be cleaned pristinely when changing keymaps") + # TODO: Support changing keymaps without requiring a clean build + endif() + endif() + + set(KEYMAP ${CACHED_KEYMAP}) +elseif(keymap_cli_argument) + set(KEYMAP ${keymap_cli_argument}) + +elseif(DEFINED ENV{KEYMAP}) + set(KEYMAP $ENV{KEYMAP}) + +elseif(keymap_app_cmake_lists) + set(KEYMAP ${keymap_app_cmake_lists}) + +else() + set(KEYMAP default) + message(STATUS "KEYMAP defaulted to 'default'") +endif() + +message(STATUS "Keymap: ${KEYMAP}") + +# Store the selected keymap in the cache +set(CACHED_KEYMAP ${KEYMAP} CACHE STRING "Selected keymap") + +set(ZMK_APP_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + +list(APPEND KEYMAP_DIRS ${ZMK_APP_DIR}/keymaps) + +foreach(root ${BOARD_ROOT}) + find_path(BOARD_DIR + NAMES ${BOARD}_defconfig + PATHS ${root}/boards/*/* + NO_DEFAULT_PATH + ) + if(BOARD_DIR) + list(APPEND KEYMAP_DIRS ${BOARD_DIR}/keymaps) + endif() + + if(DEFINED SHIELD) + find_path(shields_refs_list + NAMES ${SHIELD}.overlay + PATHS ${root}/boards/shields/* + NO_DEFAULT_PATH + ) + foreach(shield_path ${shields_refs_list}) + list(APPEND KEYMAP_DIRS ${shield_path}/keymaps) + endforeach() + endif() +endforeach() + +foreach(keymap_root ${KEYMAP_DIRS}) + find_path(KEYMAP_DIR + NAMES ${KEYMAP} + PATHS ${keymap_root}/*/* + NO_DEFAULT_PATH + ) + + if (KEYMAP_DIR) + message(STATUS "Using keymap directory: ${KEYMAP_DIR}/${KEYMAP}/") + set(DTC_OVERLAY_FILE ${KEYMAP_DIR}/${KEYMAP}/keymap.overlay) + break() + endif() +endforeach()