diff --git a/docs/docs/development/hardware-integration/new-shield.mdx b/docs/docs/development/hardware-integration/new-shield.mdx index 5f532ab8001..59a049ccc07 100644 --- a/docs/docs/development/hardware-integration/new-shield.mdx +++ b/docs/docs/development/hardware-integration/new-shield.mdx @@ -46,7 +46,7 @@ This guide will walk through the steps necessary to add ZMK support for a keyboa The high level steps are: -- Create a new [Zephyr module](https://docs.zephyrproject.org/3.5.0/develop/modules.html) to contain your shield. +- Create a new [ZMK module](../module-creation.md) to contain your shield. - Create a new shield directory. - Add the base Kconfig files. - Add the shield overlay file defining: @@ -61,9 +61,9 @@ Many of the above files will differ depending on whether your keyboard is a unib After adding ZMK support for a basic shield using this guide, check the sidebar for guides on adding any additional features (such as encoders) that your keyboard has. It may be helpful to review the upstream [shields documentation](https://docs.zephyrproject.org/3.5.0/hardware/porting/shields.html#shields) to get a proper understanding of the underlying system before continuing. -## New Zephyr Module Repository +## New ZMK Module Repository -The first step to creating the shield is to create a new Zephyr module repository from a template. +The first step to creating the shield is to create a new ZMK module repository from a template. :::note This guide assumes you already have a configured GitHub account. If you don't yet have one, go ahead and [sign up](https://github.com/join) before continuing. @@ -81,13 +81,14 @@ Follow these steps to create your new repository: - Click the green "Create repository" button The repository is a combination of the directories and files required of a ZMK config, and those required of a shield module. -To create a shield module, the following components are needed: +This enables the use of GitHub Actions to test that the shield is defined correctly. +See also the page on [module creation](../module-creation.md) for a reference on exactly which file structure and files are required for a ZMK keyboard module. -- The `boards/shields` directory, where the keyboard's files will go -- The `zephyr/module.yml` file, which identifies and describes the module. See the [Zephyr documentation](https://docs.zephyrproject.org/3.5.0/develop/modules.html#module-yaml-file-description) for details on customising this file. For the purposes of creating a shield module, the default found in the template can be left untouched. +We recommend that you take this moment to name your module according to our [convention](../module-creation.md), i.e. your `zephyr/module.yml` file should begin with -Neither of these should be moved out of their parent directory. -The other files and directories such as `config` are not necessary for the purposes of a shield module, but rather intended to be used for user configuration and testing. +```yaml title="zephyr/module.yml" +name: zmk-keyboard- +``` ## New Shield Directory @@ -447,13 +448,39 @@ Also see the [matrix transform section](../../config/layout.md#matrix-transform) ### Physical Layout Your keyboard will need to have a physical layout defined. -Read through our [dedicated page on physical layouts](./physical-layouts.md) for information on how to define a physical layout. -Once you have finished creating your physical layout, you should import the file in which it was created: +Physical layouts organize the matrix transform, kscan and optionally the physical description of key positions in a single entity. + + + + +If you are not planning to add support for [ZMK Studio](../../features/studio.md), you can add a `zmk,physical-layout`-compatible node for each physical layout your keyboard supports: + +```dts +/ { + physical_layout0: physical_layout_0 { // First physical layout, use different naming for other layouts + compatible = "zmk,physical-layout"; + display-name = "Default Layout"; + kscan = <&kscan0>; // Label of the kscan node, optional if all layouts use the same + transform = <&default_transform>; // Label of the matrix transform for this layout + }; +}; +``` + +These nodes should be placed in `my_keyboard.overlay` for unibody keyboards and the shared `my_keyboard.dtsi` for splits. + + + + +If you are planning to add support for [ZMK Studio](../../features/studio.md), you should follow the [physical layouts documentation](physical-layouts.md) to create a new file `my_keyboard-layouts.dtsi` which includes the physical layout definitions. +Once you have finished defining your physical layouts, import the `my_keyboard-layouts.dtsi` file at the top of your `my_keyboard.overlay` file (unibody) or `my_keyboard.dtsi` file (split). ```dts #include "my_keyboard-layouts.dtsi" ``` + + + ### Chosen Node Set the `chosen` node to a defined "default" physical layout. This should also be placed in the same file as the physical layout, i.e. `my_keyboard.overlay` for unibodies and `my_keyboard.dtsi` for split keyboards. @@ -488,11 +515,13 @@ If all of your physical layouts use the same `kscan` node under the hood, you ca Each keyboard should provide a default keymap to be used when building the firmware, which can be overridden and customized by user configs. For "shield keyboards", this should be placed in the `boards/shields/my_keyboard/my_keyboard.keymap` file. -The keymap is configured as an additional devicetree overlay that includes the following: Here is an example simple keymap for a 3x3 macropad, with only one layer: ```dts title="my_keyboard.keymap" +#include +#include + / { keymap { compatible = "zmk,keymap"; diff --git a/docs/docs/development/hardware-integration/physical-layouts.md b/docs/docs/development/hardware-integration/physical-layouts.md index 06acaf8422b..281b1c97ca3 100644 --- a/docs/docs/development/hardware-integration/physical-layouts.md +++ b/docs/docs/development/hardware-integration/physical-layouts.md @@ -30,8 +30,8 @@ Every physical layout needs a matrix transform, and optionally can also have a k ```dts title=".dts | .dtsi | .overlay" &physical_layout0 { - kscan = <&kscan0>; - transform = <&matrix_transform0>; + kscan = <&kscan0>; // Label of the kscan node this layout uses + transform = <&default_transform>; // Label of the matrix transform this layout uses }; ``` @@ -64,7 +64,7 @@ You can specify negative values in devicetree using parentheses around it, e.g. :::tip -We recommend the use of [this tool](https://zmk-physical-layout-converter.streamlit.app/) for writing a physical layout or converting one from a QMK JSON definition. If your keyboard already has a physical layout defined for the use with KLE, we recommend using [this other tool](https://nickcoutsos.github.io/keymap-layout-tools/) first to convert your existing layout into QMK JSON. +We recommend the use of [this tool](https://zmk-physical-layout-converter.streamlit.app/) for writing a physical layout or converting one from a QMK JSON definition. If your keyboard already has a physical layout defined for the use with KLE, we recommend using [this other tool](https://nickcoutsos.github.io/keymap-layout-tools/) first to convert your existing layout into QMK JSON. The second tool can also import the position data from KiCAD, if said program was used to design the keyboard. ::: @@ -146,7 +146,7 @@ Here is an example of using the predefined physical layouts for a 60% keyboard: If a keyboard has multiple possible layouts (e.g. you can snap off an outer column), then you should define multiple matrix transformations and multiple physical layouts, one for each possible layout. If necessary, you can also define multiple kscan instances. -```dts +```dts title="-layouts.dtsi" // Needed if and only if keys property is used #include @@ -181,7 +181,7 @@ Keys whose positions can neither be inferred from the default layout nor have bi A position map looks something like this: -```dts +```dts title="-layouts.dtsi" / { position_map { compatible = "zmk,physical-layout-position-map"; @@ -217,7 +217,7 @@ We recommend the use of [this tool](https://zmk-layout-helper.netlify.app/), dis Start by creating the parent node defining the position map: -```dts +```dts title="-layouts.dtsi" / { keypad_position_map { compatible = "zmk,physical-layout-position-map"; @@ -236,7 +236,7 @@ It is easiest to write the position map by considering one layout to be the "ref Create the child node for the reference layout, and fill the `positions` array by counting upwards, giving it the same order and number of keys as the `keys` property of its physical layout. For a 2x2 macropad the child node would be -```dts +```dts title="2x2macropad-layouts.dtsi" / { keypad_position_map { // Other properties @@ -261,7 +261,7 @@ Consider the following macropad/numpad with two physical layouts: Let us first consider each side individually. The "reference" position map of the left side would look like this: -```dts +```dts title="macropad-layouts.dtsi" / { keypad_position_map { // Other properties @@ -281,7 +281,7 @@ Let us first consider each side individually. The "reference" position map of th Meanwhile, the "reference" position map of the right side with fewer keys would look like this: -```dts +```dts title="macropad-layouts.dtsi" / { keypad_position_map { // Other properties @@ -303,7 +303,7 @@ As a reminder, the `positions` property is a one-dimensional array like the `key If the left side with more keys was used as the reference layout, then the overall position map of the keyboard would look like this: -```dts +```dts title="macropad-layouts.dtsi" / { keypad_position_map1 { compatible = "zmk,physical-layout-position-map"; @@ -336,7 +336,7 @@ The "missing" positions are filled with the "spare" numbers of the layout with m If the right side with fewer keys were used as a reference instead, then the overall position map would look like this: -```dts +```dts title="macropad-layouts.dtsi" / { keypad_position_map2 { compatible = "zmk,physical-layout-position-map"; @@ -373,7 +373,7 @@ Consider the above device again -- most of the positions have identical `keys` p A non-`complete` position map can be used to assign mappings to only these particular keys: -```dts +```dts title="macropad-layouts.dtsi" / { keypad_position_map3 { compatible = "zmk,physical-layout-position-map"; @@ -422,3 +422,5 @@ The following is an example of a position map which maps the 5-column and 6-colu }; }; ``` + +The above position map is in actuality spread over [multiple files](https://github.com/zmkfirmware/zmk/tree/main/app/dts/layouts/foostan/corne), as one of our predefined layouts. diff --git a/docs/docs/development/local-toolchain/build-flash.mdx b/docs/docs/development/local-toolchain/build-flash.mdx index 982d00f4bd4..c7a09d05079 100644 --- a/docs/docs/development/local-toolchain/build-flash.mdx +++ b/docs/docs/development/local-toolchain/build-flash.mdx @@ -143,7 +143,7 @@ Build times can be significantly reduced after the initial build by omitting all ### Building With External Modules -ZMK supports loading additional boards, shields, code, etc. from [external Zephyr modules](https://docs.zephyrproject.org/3.5.0/develop/modules.html), facilitating out-of-tree management and versioning independent of the ZMK repository. To build with any additional modules, use the `ZMK_EXTRA_MODULES` define added to your `west build` command. +ZMK supports loading additional boards, shields, code, etc. from [external ZMK modules](../../features/modules.mdx), facilitating out-of-tree management and versioning independent of the ZMK repository. To build with any additional modules, use the `ZMK_EXTRA_MODULES` define added to your `west build` command. For instance, building with the `my-vendor-keebs-module` checked out to your documents directory, you would build like: diff --git a/docs/docs/development/module-creation.md b/docs/docs/development/module-creation.md index 29cc6c443fb..17eb157dbf2 100644 --- a/docs/docs/development/module-creation.md +++ b/docs/docs/development/module-creation.md @@ -65,7 +65,7 @@ name: Next, you need to define the options to build your module. These also go into `zephyr/module.yml`, as children of the `build` property. Commonly used options are: -- The `depends` child property is used to specify a list of modules which the module depends on. The dependencies are referred to by their [module name](#module-name). +- The `depends` child property is used to specify a list of modules which the module depends on. The dependencies are referred to by their [module name](#name). - The `cmake` child property is used to identify a folder containing a `CMakeLists.txt` file that lists the CMake commands used to build source files. - The `kconfig` child property is used to identify the `Kconfig` file that defines configuration settings used by the module. - `settings` is a child property containing additional child properties, two of which are particularly relevant: diff --git a/docs/docs/features/modules.mdx b/docs/docs/features/modules.mdx index 5cc6e3d1c97..83fbd9bfe0c 100644 --- a/docs/docs/features/modules.mdx +++ b/docs/docs/features/modules.mdx @@ -192,3 +192,7 @@ manifest: ### Building Locally When building from a pull request locally, you'll need to [perform the local user setup](../development/local-toolchain/setup/index.md), but using the repository of the pull request rather than the official ZMK repository. You can then [build and flash](../development/local-toolchain/build-flash.mdx) as usual. + +## Creating a ZMK Module + +Please see the dedicated page [here](../development/module-creation.md) for information on creating modules. diff --git a/docs/docs/features/studio.md b/docs/docs/features/studio.md index 8e368fcc7ac..3ef8d0d35b1 100644 --- a/docs/docs/features/studio.md +++ b/docs/docs/features/studio.md @@ -36,6 +36,7 @@ ZMK Studio currently has the following capabilities: | ✅ | Renaming layers & enabling [extra layers](#including-extra-layers) | | ❌ | Adding more layers than specified by devicetree | | 💡 | Host locale selection | +| 💡 | Importing and exporting keymaps | Items listed as "planned", "under development", "low priority", or "not planned" can be configured using [devicetree](../config/index.md#devicetree-files) instead.