From 7a1c1be933b0b2b82940b3e0ad17d17d1de5db9d Mon Sep 17 00:00:00 2001 From: genteure Date: Mon, 29 Jun 2026 19:05:41 +0800 Subject: [PATCH 1/4] docs: revise keyboard dongle guide For the keyboard dongle page, the main change is now it instructs the user to use the same physical layout(s) instead of making new ones for the dongle. The rest are mostly formatting and wording changes, and some clarifications. Also adjusted the new shield guide to include some information about multi-peripheral split setup. Added a new "ReadMore" component as an alternative to admonitions with less visual importance, for linking to other pages. --- docs/docs/hardware-integration/dongle.mdx | 255 ++++++++++-------- docs/docs/hardware-integration/new-shield.mdx | 74 ++++- docs/src/components/ReadMore.jsx | 32 +++ docs/src/components/ReadMore.module.css | 45 ++++ 4 files changed, 286 insertions(+), 120 deletions(-) create mode 100644 docs/src/components/ReadMore.jsx create mode 100644 docs/src/components/ReadMore.module.css diff --git a/docs/docs/hardware-integration/dongle.mdx b/docs/docs/hardware-integration/dongle.mdx index 822b6248ab8..62fd301de05 100644 --- a/docs/docs/hardware-integration/dongle.mdx +++ b/docs/docs/hardware-integration/dongle.mdx @@ -5,8 +5,9 @@ sidebar_label: Keyboard Dongle import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; +import ReadMore from "../../src/components/ReadMore"; -A bluetooth dongle can be added to any wireless keyboard running ZMK. The result is a [split keyboard](../features/split-keyboards.md) with the dongle as ["central"](../features/split-keyboards.md#central-and-peripheral-roles). There are a number of advantages to adding a dongle, but also some disadvantages: +A bluetooth dongle can be added to any wireless keyboard running ZMK. The result is a split keyboard with the dongle as "central". There are a number of advantages to adding a dongle, but also some disadvantages: Benefits: @@ -15,36 +16,49 @@ Benefits: Disadvantages: -- An extra [board](index.mdx#what-is-a-board) is needed (any BLE-capable board that ZMK supports will work). -- The keyboard becomes unusable without the dongle. +- An extra board is needed. +- The keyboard becomes unusable without the dongle, since the peripherals cannot connect to hosts without a central. + +For the setup described on this page, the dongle is simply a central split keyboard part with no keys. Any BLE-capable board that ZMK supports can be used as a dongle. + + + +See [Split Keyboards](../features/split-keyboards.md) for more information on the central and peripheral roles. + + + + + +See [Hardware Integration](../hardware-integration/index.mdx) for more information about "boards" and "shields". + + Depending on how the dongle is used, there are some additional [latency considerations](../features/split-keyboards.md#latency-considerations) to keep in mind. The addition of the dongle adds an extra "hop" for the former central, increasing its latency to that of a peripheral. The other parts are unchanged latency-wise. There is also a commonly occurring case where the peripherals benefit. Assuming the dongle is connected to USB and the former central would have been connected via bluetooth to the host if the dongle wasn't present: - The former central will have its latency increased by about 1ms from the extra USB "hop" -- The other parts will have their average latency _decreased_ by 6.5ms from the replacement of a BLE "hop" with a "USB" hop. +- The other parts will have their average latency _decreased_ by 6.5ms from the replacement of a BLE "hop" with a USB "hop". As a result, for this common use case the average latency of the keyboard decreases. ## Adding a Dongle -The approach taken to adding a dongle is _generally_ the same[^1]. -Whether your keyboard consists of a [board and a shield](index.mdx#boards--shields) or is just a board is irrelevant. +We'll add a new part with no keys as the central part, then switch the role of existing keyboard parts to peripheral. -To add a dongle, you will create a simplified form of a [new shield](new-shield.mdx). -The approach described below assumes the dongle will not have any keys assigned to itself, so it will not work for that scenario. -If you want to understand the details of how it all works better, please read through the [new shield guide](new-shield.mdx). +This guide assumes that you are adding a dongle to an existing keyboard definition, with the keyboard boards and/or shields defined in the main ZMK repository or external modules. +The dongle shield is defined in your personal ZMK config, no change is needed to the existing keyboard boards and/or shields. -As there are a very large number of possible devices that could be used as a dongle, you will be defining your dongle as a personal shield intended for your exclusive use. +If you are creating a new keyboard, the dongle shield can be defined together with other parts of the keyboard. +Follow the [new keyboard shield guide](../hardware-integration/new-shield.mdx) and repeat the steps for "right" for each peripheral part of the keyboard. -Prior to adding a dongle to your keyboard, please test its functionality without a dongle. The below guide will assume that your keyboard is named `my_keyboard`, replace accordingly. +Prior to adding a dongle to your keyboard, please test its functionality without a dongle. ### Dongle Folder -First, make sure that your `zmk-config` matches the folder structure found in the [unified ZMK config template](https://github.com/zmkfirmware/unified-zmk-config-template) (extra files and folders are fine, but none should be missing). +First, make sure that your `zmk-config` matches the folder structure found in the [unified ZMK config template](https://github.com/zmkfirmware/unified-zmk-config-template), especially `zephyr/module.yml` to ensure it is recognized as a module. -Next, navigate to the `zmk-config/boards/shields` directory. Create a subdirectory called `my_keyboard`, if one doesn't already exist. Unless otherwise specified, the below files should all be placed in said folder. +Next, create a folder with the shield name of your keyboard under `zmk-config/boards/shields`, for example `zmk-config/boards/shields/my_keyboard`. This folder will contain the devicetree overlay and Kconfig files for your dongle. ### Kconfig Files @@ -52,22 +66,24 @@ Next, navigate to the `zmk-config/boards/shields` directory. Create a subdirecto Make a file called `Kconfig.shield`, if one does not exist already. Add the following lines to it, replacing `SHIELD_MY_KEYBOARD_DONGLE` and `my_keyboard_dongle` according to your keyboard: -```kconfig title="Kconfig.shield" +```kconfig title="zmk-config/boards/shields/my_keyboard/Kconfig.shield" # No whitespace after the comma or in the keyboard name! config SHIELD_MY_KEYBOARD_DONGLE def_bool $(shields_list_contains,my_keyboard_dongle) ``` +To use the same keymap file, the dongle shield name should match other parts of the keyboard, e.g. `my_keyboard_dongle` if other parts are named `my_keyboard` (for unibody) or `my_keyboard_left` (for split). + #### Kconfig.defconfig Make a file called `Kconfig.defconfig`, if one does not exist already. Add the following lines to it where `SHIELD_MY_KEYBOARD_DONGLE` should match the previous section: -```kconfig title="Kconfig.defconfig" +```kconfig title="zmk-config/boards/shields/my_keyboard/Kconfig.defconfig" if SHIELD_MY_KEYBOARD_DONGLE # Max 16 characters in keyboard name config ZMK_KEYBOARD_NAME - default "My Board" + default "My Keyboard" config ZMK_SPLIT_ROLE_CENTRAL default y @@ -93,12 +109,16 @@ endif ### Dongle Overlay File -Create a file called `my_keyboard_dongle.overlay` (renamed as appropriate). +Create a file called `my_keyboard_dongle.overlay` matching the shield name in `Kconfig.shield`. This file will include your keyboard's matrix transform and physical layout, allowing it to map key press events from the peripherals to behaviors. -Add the following lines to the file you created, introducing a mock kscan for the dongle since it has no keys itself: +All keyboard parts need to have the exact same sets of matrix transforms and physical layouts. Each keyboard part has its own kscan and matrix transform offsets. + +#### Kscan -```dts title="my_keyboard_dongle.overlay" +Add the following lines to the overlay file, introducing a mock kscan for the dongle since it has no keys itself: + +```dts title="zmk-config/boards/shields/my_keyboard/my_keyboard_dongle.overlay" #include / { @@ -115,53 +135,37 @@ Add the following lines to the file you created, introducing a mock kscan for th }; ``` -You will now need to find and copy your keyboard's matrix transform into the `my_keyboard_dongle.overlay` file. +#### Matrix Transform -#### Matrix transform +Next, find all matrix transforms for your keyboard and copy them to the dongle shield. Look for a devicetree node with `compatible = "zmk,matrix-transform";` in the devicetree files for your keyboard. -Navigate to the directory defining your keyboard (in-tree keyboards found [here](https://github.com/zmkfirmware/zmk/tree/main/app/boards), if your keyboard is a shield look under the `shields` subdirectory) and look through the [devicetree files](../config/index.md) for nodes with `compatible = "zmk,matrix-transform";`. -This should look something like this: + + [Devicetree Overview](../development/devicetree.md) explains the devicetree + format. + -```dts - default_transform: keymap_transform_0 { - compatible = "zmk,matrix-transform"; - columns = <14>; - rows = <5>; - - map = < - // Lots of RC(r,c) macros - >; - }; -``` +#### Physical Layout -Copy this node into your `my_keyboard_dongle.overlay` file. It should be a child node of the root node (put it inside the `/ { ... };`). -If there are multiple matrix transformations, copy the one that matches your keyboard's layout. +Finally, find all physical layouts for your keyboard and copy them to the dongle shield. Depending on the keyboard, physical layouts may be found in a variety of locations. -Make a note of the label that the transform has, it will be used later. In the example the label is `default_transform`. +For physical layouts, look for `#include .dtsi>` or a devicetree node with `compatible = "zmk,physical-layout";`. -#### Physical layout +Some older shields may not have a physical layout defined and use a matrix transform directly in the `chosen` node. The dongle shield should match the same approach as the other parts of the keyboard. -A full physical layout is necessary to allow your dongle to be used with [ZMK Studio](../features/studio.md). -If your keyboard is not Studio-ready or you have no interest in using ZMK Studio with your dongle, then this section is simplified significantly. +:::warning - - +It is very important that all keyboard parts have the exact same physical layouts and matrix transforms with the same devicetree node names. +For keyboards with multiple physical layouts, make sure to include all of them in the dongle shield, even if you only use one of them. + +::: -You will need to find your keyboard's physical layout, much like finding the matrix transform. -Depending on your keyboard, the physical layout could be found in a variety of locations. Look for a node with `compatible = "zmk,physical-layout";`. -There are three commonly found possibilities: +There are three commonly found possibilities for physical layouts: -- The physical layout is found in a file called `my_keyboard-layouts.dtsi` -- The physical layout is found in the same file as the matrix transform and chosen node -- The physical layout is imported from ZMK's shared layouts - `#include .dtsi>` can be found at the top of one of the devicetree files. +- Dedicated physical layout file: `my_keyboard-layouts.dtsi` +- Physical layout in the same file as the matrix transform and chosen node +- Physical layout imported from ZMK's shared layouts: `#include .dtsi>`. + +Use the following tabs to see how to copy the physical layout and matrix transform for each of these cases. -Copy the file into your dongle's folder. Then import the file, assign the matrix transform to it, and select it in the `chosen` node: -```dts -#include "my_keyboard-layouts.dtsi" +If your keyboard has a dedicated physical layout file, usually named `-layouts.dtsi`, copy the file into your dongle shield's folder. +Import the `dtsi` file in your dongle shield's overlay, assign the matrix transform to it, and select it in the `chosen` node just like the other parts of the keyboard. -&physical_layout0 { - transform = <&default_transform>; -}; +As an example of dedicated physical layout file, [`boards/shields/reviung34/reviung34-layouts.dtsi`](https://github.com/zmkfirmware/zmk/blob/64daf698e073e37b6748ac54f4eb48d8666af0b9/app/boards/shields/reviung34/reviung34-layouts.dtsi) is included by [`boards/shields/reviung34/reviung34.overlay`](https://github.com/zmkfirmware/zmk/blob/64daf698e073e37b6748ac54f4eb48d8666af0b9/app/boards/shields/reviung34/reviung34.overlay#L9-L17). + +```dts title="zmk-config/boards/shields/my_keyboard/my_keyboard_dongle.overlay" +#include "my_keyboard-layouts.dtsi" / { chosen { @@ -191,17 +196,34 @@ Copy the file into your dongle's folder. Then import the file, assign the matrix }; ``` -Make sure that the labels `physical_layout0` and `default_transform` match those of the physical layout node defined in the file and the matrix transform respectively. +If the `kscan` property is set on the physical layout node, remove it so the dongle uses the mock kscan instead. + +```diff + / { + physical_layout0: physical_layout_0 { + compatible = "zmk,physical-layout"; +- kscan = &kscan0; + display-name = "Default Layout"; + transform = <&default_transform>; + keys = <...>; // Long list of key positions, optional + }; +}; +``` -:::note -If there are multiple physical layouts in the file, you will need to copy over all of the remaining matrix transformations and assign them to their corresponding physical layout. -::: +```diff + &physical_layout0 { +- kscan = &kscan0; + transform = <&default_transform>; + }; +``` -Copy the physical layout node into your `my_keyboard_dongle.overlay` file. Make sure the matrix transform is assigned to it, and select it in the `chosen` node. +If your keyboard has a physical layout defined in the same file as the matrix transform and chosen node, copy the physical layout node into your dongle shield's overlay. -```dts +Silimar to the previous case with a dedicated physical layout file, make sure the matrix transform is assigned to it, and select it in the `chosen` node just like the other parts of the keyboard. + +```dts title="zmk-config/boards/shields/my_keyboard/my_keyboard_dongle.overlay" / { chosen { zmk,kscan = &mock_kscan; @@ -212,103 +234,104 @@ Copy the physical layout node into your `my_keyboard_dongle.overlay` file. Make compatible = "zmk,physical-layout"; display-name = "Default Layout"; transform = <&default_transform>; - keys = <...>; // Long list of key positions + keys = <...>; // Long list of key positions, optional }; }; ``` -Make sure that the labels `physical_layout0` and `default_transform` match those of the physical layout node and the matrix transform respectively. +If the `kscan` property is set on the physical layout node, remove it so the dongle uses the mock kscan instead. + +```diff + / { + physical_layout0: physical_layout_0 { + compatible = "zmk,physical-layout"; +- kscan = &kscan0; + display-name = "Default Layout"; + transform = <&default_transform>; + keys = <...>; // Long list of key positions, optional + }; +}; +``` -:::note -If there are multiple physical layouts, you need only copy the one that applies to your keyboard. -::: +```diff + &physical_layout0 { +- kscan = &kscan0; + transform = <&default_transform>; + }; +``` -Include your desired layout at the top of the file. Then assign your matrix transform to it, taking care to match up the node labels correctly. -```dts -#include .dtsi> +If the keyboard's physical layout is imported from ZMK's shared layouts, include the layout at the top of your dongle shield's overlay file, then assign the matrix transform to it and select it in the `chosen` node just like the other parts of the keyboard. -&physical_layout0 { - transform = <&default_transform>; -}; -``` +As an example of importing shared layouts, [`boards/shields/corne/corne.dtsi`](https://github.com/zmkfirmware/zmk/blob/64daf698e073e37b6748ac54f4eb48d8666af0b9/app/boards/shields/corne/corne.dtsi#L9-L18) imports `layouts/foostan/corne/5column.dtsi` and `layouts/foostan/corne/6column.dtsi` at the top of the file. -In this case your node label will _not_ be `physical_layout0`, make sure to adjust it accordingly. +```dts title="zmk-config/boards/shields/my_keyboard/my_keyboard_dongle.overlay" +#include -Finally, select your physical layout in the chosen node. +&layout_name { + transform = <&default_transform>; +}; -```dts / { chosen { zmk,kscan = &mock_kscan; - zmk,physical-layout = &physical_layout0; + zmk,physical-layout = &layout_name; }; }; ``` - - - - -Add a barebones [physical layout](physical-layouts.md) without the `keys` property to your `my_keyboard_dongle.overlay` file. - -```dts -/ { - physical_layout0: physical_layout_0 { - compatible = "zmk,physical-layout"; - display-name = "Default Layout"; - transform = <&default_transform>; - }; -}; -``` + -Make sure that the `transform` property uses the same label as your matrix transform. Then select the physical layout in the same `chosen` node that was previously created: +If you see `chosen` `zmk,matrix-transform` like the following, then your keyboard does not have a physical layout defined. ```dts / { chosen { - zmk,kscan = &mock_kscan; - zmk,physical-layout = &physical_layout0; // New item added + zmk,matrix-transform = &default_transform; }; }; ``` +In this case, you can simply set `zmk,matrix-transform` in the dongle shield's `chosen` node to the same matrix transform as the other parts of the keyboard. + +Your dongle shield is now complete and ready to be built. + ## Building the Firmware -Add the appropriate lines to your `build.yaml` file to build the firmware for your dongle. Also add some CMake arguments using `cmake-args` to the existing parts of your keyboard, turning them into peripherals for your dongle.[^2] +The dongle shield we just created is compatible with any BLE-capable board that ZMK supports, since it uses the mock kscan driver and does not use any physical GPIO pins. + +Add a new build for the dongle to your `build.yaml` file. +For existing parts of your keyboard, add the following CMake arguments to convert them into split peripherals. ```yaml +--- include: - # ----------------------------------------- - # Your other keyboard parts here - # ----------------------------------------- # Change the board appropriately, you can use any board - board: nice_nano shield: my_keyboard_dongle - - board: nice_nano - shield: settings_reset - # Add these cmake-args to the peripherals you wish to use with the dongle + - board: nice_nano shield: my_keyboard + # Add these cmake-args to the peripherals you wish to use with the dongle cmake-args: -DCONFIG_ZMK_SPLIT=y -DCONFIG_ZMK_SPLIT_ROLE_CENTRAL=n + + - board: nice_nano + shield: settings_reset ``` You can then flash the firmware to your device as detailed in our [user setup](../user-setup.mdx#install-the-firmware) and [split keyboard](../features/split-keyboards.md#building-and-flashing-firmware) pages. :::warning -Before flashing your new firmware, you need to flash `settings_reset` [firmware](../troubleshooting/connection-issues.mdx#building-a-reset-firmware) on all devices to ensure they can pair to each other. +Before flashing your new firmware, you need to flash [`settings_reset` firmware](../troubleshooting/connection-issues.mdx#building-a-reset-firmware) on all devices to clear any previous bonding information. +Flashing standard ZMK firmware on a device will not clear any previous settings. ::: To use your dongled keyboard with [ZMK Studio](../features/studio.md), apply the instructions for [building with Studio](../features/studio.md#building) to the dongle. -If you ever want to "undongle" your keyboard, simply remove these CMake arguments and flash the resulting firmware (after a `settings_reset`). - -[^1]: If you have a custom dongle that uses an onboard MCU, then you will need to take a slightly different approach that isn't currently documented. - -[^2]: If you are building locally, you can append these flags to the end of the [build command](../development/local-toolchain/build-flash.mdx#cmake-arguments). +If you ever want to "undongle" your keyboard, simply remove these CMake arguments, do the settings reset procedure, and flash the newly built firmware to your devices. diff --git a/docs/docs/hardware-integration/new-shield.mdx b/docs/docs/hardware-integration/new-shield.mdx index de9eca55bf0..9220021d5af 100644 --- a/docs/docs/hardware-integration/new-shield.mdx +++ b/docs/docs/hardware-integration/new-shield.mdx @@ -113,6 +113,8 @@ You can check out the [`shields` folder](https://github.com/zmkfirmware/zmk/tree There are two required [Kconfig](https://docs.zephyrproject.org/4.1.0/build/kconfig/index.html) files that need to be created for your new keyboard shield to get it picked up for ZMK, `Kconfig.shield` and `Kconfig.defconfig`. +All file names are case sensitive. + ### Kconfig.shield @@ -122,7 +124,7 @@ The `Kconfig.shield` file defines the shield name used to build your keyboard. -```kconfig title="Kconfig.shield" +```kconfig title="boards/shields//Kconfig.shield" # No whitespace after the comma or in your keyboard name! config SHIELD_MY_KEYBOARD def_bool $(shields_list_contains,my_keyboard) @@ -137,7 +139,7 @@ The `SHIELD_MY_KEYBOARD` flag will be used in `Kconfig.defconfig` to set other p Split keyboards have multiple shield names defined, one for each part. For example, if your keyboard consists of two halves named `my_keyboard_left` and `my_keyboard_right`, it would look like this: -```kconfig title="Kconfig.shield" +```kconfig title="boards/shields//Kconfig.shield" # No whitespace after the comma or in your part name! config SHIELD_MY_KEYBOARD_LEFT def_bool $(shields_list_contains,my_keyboard_left) @@ -151,6 +153,29 @@ This will set the `SHIELD_MY_KEYBOARD_LEFT` flag to `y` whenever `my_keyboard_le Likewise, when `my_keyboard_right` is used as the shield name the `SHIELD_MY_KEYBOARD_RIGHT` flag is set to `y`. The `SHIELD_MY_KEYBOARD_LEFT` and `SHIELD_MY_KEYBOARD_RIGHT` flags will be used in `Kconfig.defconfig` to set other properties about your shields, so make sure that they match. +ZMK supports split keyboards with more than two parts, repeat the above for each part of your keyboard. + +
+Split keyboards with more than two parts + +For split keyboards with more than two parts, you can define additional flags for each part of your keyboard. Each keyboard part should have a unique shield name. For example: + +```kconfig title="boards/shields//Kconfig.shield" +# No whitespace after the comma or in your part name! +config SHIELD_MY_KEYBOARD_LEFT + def_bool $(shields_list_contains,my_keyboard_left) + +# No whitespace after the comma or in your part name! +config SHIELD_MY_KEYBOARD_RIGHT + def_bool $(shields_list_contains,my_keyboard_right) + +# No whitespace after the comma or in your part name! +config SHIELD_MY_KEYBOARD_NUMPAD + def_bool $(shields_list_contains,my_keyboard_numpad) +``` + +
+
@@ -164,7 +189,7 @@ The updated new default values should always be wrapped inside a conditional on -```kconfig title="Kconfig.defconfig" +```kconfig title="boards/shields//Kconfig.defconfig" if SHIELD_MY_KEYBOARD # Name must be less than 16 characters long! @@ -182,7 +207,7 @@ For that side, the keyboard name is assigned and the central config is set. The peripheral side is not assigned a name. Finally, the split config needs to be set for both sides: -```kconfig title="Kconfig.defconfig" +```kconfig title="boards/shields//Kconfig.defconfig" if SHIELD_MY_KEYBOARD_LEFT # Name must be less than 16 characters long! @@ -202,6 +227,47 @@ config ZMK_SPLIT endif ``` +
+Split keyboards with more than two parts + +For split keyboards with more than two parts, adjust the number of peripheral parts and BLE connection settings: + +```kconfig title="boards/shields//Kconfig.defconfig" +if SHIELD_MY_KEYBOARD_LEFT + +# Name must be less than 16 characters long! +config ZMK_KEYBOARD_NAME + default "My Keyboard" + +config ZMK_SPLIT_ROLE_CENTRAL + default y + +# If not set, the default is 1 peripheral part +# Set to the number of peripheral parts in your split keyboard +config ZMK_SPLIT_BLE_CENTRAL_PERIPHERALS + default 2 + +# Set this to ZMK_SPLIT_BLE_CENTRAL_PERIPHERALS + your desired number of BT profiles (default is 5) +config BT_MAX_CONN + default 7 + +# Set this to the same number as BT_MAX_CONN +config BT_MAX_PAIRED + default 7 + +endif + +# List all Kconfig flags for each part of your split keyboard here, e.g.: +if SHIELD_MY_KEYBOARD_LEFT || SHIELD_MY_KEYBOARD_RIGHT || SHIELD_MY_KEYBOARD_NUMPAD + +config ZMK_SPLIT + default y + +endif +``` + +
+
diff --git a/docs/src/components/ReadMore.jsx b/docs/src/components/ReadMore.jsx new file mode 100644 index 00000000000..a100e1eccd4 --- /dev/null +++ b/docs/src/components/ReadMore.jsx @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2026 The ZMK Contributors + * + * SPDX-License-Identifier: CC-BY-NC-SA-4.0 + */ + +import { faBook } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import classNames from "classnames"; +import PropTypes from "prop-types"; + +import styles from "./ReadMore.module.css"; + +export default function ReadMore({ children, className }) { + return ( + + ); +} + +ReadMore.propTypes = { + children: PropTypes.node.isRequired, + className: PropTypes.string, +}; + +ReadMore.defaultProps = { + className: undefined, +}; diff --git a/docs/src/components/ReadMore.module.css b/docs/src/components/ReadMore.module.css new file mode 100644 index 00000000000..defc4e6d445 --- /dev/null +++ b/docs/src/components/ReadMore.module.css @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2026 The ZMK Contributors + * + * SPDX-License-Identifier: CC-BY-NC-SA-4.0 + */ + +.readMore { + display: flex; + gap: 0.6rem; + align-items: flex-start; + margin-top: 0.5rem; + margin-bottom: 0.8rem; + padding: 0.4rem 0.7rem; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 0.75rem; +} + +.icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 1.5rem; + height: 1.5rem; + flex: 0 0 1.5rem; + margin-top: 0.1rem; + color: var(--ifm-color-emphasis-600); +} + +.icon :global(svg) { + width: 1.25rem; + height: 1.25rem; +} + +.content { + min-width: 0; + flex: 1 1 auto; +} + +.content > :first-child { + margin-top: 0; +} + +.content > :last-child { + margin-bottom: 0; +} From 4f19a8846ac43f26b2f47162cbe804cb1f4cc37d Mon Sep 17 00:00:00 2001 From: Genteure Date: Thu, 9 Jul 2026 14:12:29 +0800 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Cem Aksoylar --- docs/docs/hardware-integration/dongle.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/docs/hardware-integration/dongle.mdx b/docs/docs/hardware-integration/dongle.mdx index 62fd301de05..6776be66951 100644 --- a/docs/docs/hardware-integration/dongle.mdx +++ b/docs/docs/hardware-integration/dongle.mdx @@ -58,7 +58,7 @@ Prior to adding a dongle to your keyboard, please test its functionality without First, make sure that your `zmk-config` matches the folder structure found in the [unified ZMK config template](https://github.com/zmkfirmware/unified-zmk-config-template), especially `zephyr/module.yml` to ensure it is recognized as a module. -Next, create a folder with the shield name of your keyboard under `zmk-config/boards/shields`, for example `zmk-config/boards/shields/my_keyboard`. This folder will contain the devicetree overlay and Kconfig files for your dongle. +Next, create a folder with the name of your keyboard under `zmk-config/boards/shields`, for example `zmk-config/boards/shields/my_keyboard`. This folder will contain the devicetree overlay and Kconfig files for your dongle. ### Kconfig Files @@ -221,7 +221,7 @@ If the `kscan` property is set on the physical layout node, remove it so the don If your keyboard has a physical layout defined in the same file as the matrix transform and chosen node, copy the physical layout node into your dongle shield's overlay. -Silimar to the previous case with a dedicated physical layout file, make sure the matrix transform is assigned to it, and select it in the `chosen` node just like the other parts of the keyboard. +Similar to the previous case with a dedicated physical layout file, make sure the matrix transform is assigned to it, and select it in the `chosen` node just like the other parts of the keyboard. ```dts title="zmk-config/boards/shields/my_keyboard/my_keyboard_dongle.overlay" / { @@ -250,7 +250,7 @@ If the `kscan` property is set on the physical layout node, remove it so the don transform = <&default_transform>; keys = <...>; // Long list of key positions, optional }; -}; + }; ``` ```diff @@ -334,4 +334,4 @@ Flashing standard ZMK firmware on a device will not clear any previous settings. To use your dongled keyboard with [ZMK Studio](../features/studio.md), apply the instructions for [building with Studio](../features/studio.md#building) to the dongle. -If you ever want to "undongle" your keyboard, simply remove these CMake arguments, do the settings reset procedure, and flash the newly built firmware to your devices. +If you ever want to "undongle" your keyboard, simply remove these CMake arguments, perform the settings reset procedure, and flash the newly built firmware to your devices. From e0d5ac927d4be7eb5cca13fbf7b0f33fe2b63807 Mon Sep 17 00:00:00 2001 From: Genteure Date: Thu, 9 Jul 2026 14:15:15 +0800 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Cem Aksoylar --- docs/docs/hardware-integration/dongle.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/hardware-integration/dongle.mdx b/docs/docs/hardware-integration/dongle.mdx index 6776be66951..818877349a9 100644 --- a/docs/docs/hardware-integration/dongle.mdx +++ b/docs/docs/hardware-integration/dongle.mdx @@ -140,7 +140,7 @@ Add the following lines to the overlay file, introducing a mock kscan for the do Next, find all matrix transforms for your keyboard and copy them to the dongle shield. Look for a devicetree node with `compatible = "zmk,matrix-transform";` in the devicetree files for your keyboard. - [Devicetree Overview](../development/devicetree.md) explains the devicetree + See [Devicetree Overview](../development/devicetree.md) for details on the devicetree format. format. From 6c9261b107008138ee9641e8db27497495839bb8 Mon Sep 17 00:00:00 2001 From: genteure Date: Thu, 16 Jul 2026 01:27:49 +0800 Subject: [PATCH 4/4] address review comments --- docs/docs/hardware-integration/dongle.mdx | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/docs/hardware-integration/dongle.mdx b/docs/docs/hardware-integration/dongle.mdx index 818877349a9..32ce6833074 100644 --- a/docs/docs/hardware-integration/dongle.mdx +++ b/docs/docs/hardware-integration/dongle.mdx @@ -46,25 +46,28 @@ As a result, for this common use case the average latency of the keyboard decrea We'll add a new part with no keys as the central part, then switch the role of existing keyboard parts to peripheral. -This guide assumes that you are adding a dongle to an existing keyboard definition, with the keyboard boards and/or shields defined in the main ZMK repository or external modules. +This guide describes a dongle setup where we add the dongle as a new part with no keys with the central role, then switch the role of existing keyboard parts to peripheral. +It assumes that you are adding a dongle to an existing keyboard definition, with the keyboard boards and/or shields defined in the main ZMK repository or external modules. The dongle shield is defined in your personal ZMK config, no change is needed to the existing keyboard boards and/or shields. If you are creating a new keyboard, the dongle shield can be defined together with other parts of the keyboard. -Follow the [new keyboard shield guide](../hardware-integration/new-shield.mdx) and repeat the steps for "right" for each peripheral part of the keyboard. +Follow the [new keyboard shield guide](../hardware-integration/new-shield.mdx) and use the mock kscan driver for the shield with central role. Prior to adding a dongle to your keyboard, please test its functionality without a dongle. ### Dongle Folder -First, make sure that your `zmk-config` matches the folder structure found in the [unified ZMK config template](https://github.com/zmkfirmware/unified-zmk-config-template), especially `zephyr/module.yml` to ensure it is recognized as a module. +First, make sure that your `zmk-config` repository matches the folder structure found in the [unified ZMK config template](https://github.com/zmkfirmware/unified-zmk-config-template), especially `zephyr/module.yml` to ensure it is recognized as a module. Next, create a folder with the name of your keyboard under `zmk-config/boards/shields`, for example `zmk-config/boards/shields/my_keyboard`. This folder will contain the devicetree overlay and Kconfig files for your dongle. +This guide will use `my_keyboard` as the keyboard name, but you should replace it with your keyboard's name in all files and paths so the keymap and other files are correctly associated with all parts of the keyboard. + ### Kconfig Files #### Kconfig.shield -Make a file called `Kconfig.shield`, if one does not exist already. Add the following lines to it, replacing `SHIELD_MY_KEYBOARD_DONGLE` and `my_keyboard_dongle` according to your keyboard: +Make a file called `Kconfig.shield`, if one does not exist already. Add the following lines to it, replacing `SHIELD_MY_KEYBOARD_DONGLE` and `my_keyboard_dongle` with your keyboard's name. ```kconfig title="zmk-config/boards/shields/my_keyboard/Kconfig.shield" # No whitespace after the comma or in the keyboard name! @@ -72,8 +75,6 @@ config SHIELD_MY_KEYBOARD_DONGLE def_bool $(shields_list_contains,my_keyboard_dongle) ``` -To use the same keymap file, the dongle shield name should match other parts of the keyboard, e.g. `my_keyboard_dongle` if other parts are named `my_keyboard` (for unibody) or `my_keyboard_left` (for split). - #### Kconfig.defconfig Make a file called `Kconfig.defconfig`, if one does not exist already. Add the following lines to it where `SHIELD_MY_KEYBOARD_DONGLE` should match the previous section: @@ -140,8 +141,8 @@ Add the following lines to the overlay file, introducing a mock kscan for the do Next, find all matrix transforms for your keyboard and copy them to the dongle shield. Look for a devicetree node with `compatible = "zmk,matrix-transform";` in the devicetree files for your keyboard. - See [Devicetree Overview](../development/devicetree.md) for details on the devicetree format. - format. + See [Devicetree Overview](../development/devicetree.md) for details on the + devicetree format. #### Physical Layout @@ -325,6 +326,8 @@ include: shield: settings_reset ``` +If you are building locally, you can append these flags to the end of the [build command](../development/local-toolchain/build-flash.mdx#cmake-arguments). + You can then flash the firmware to your device as detailed in our [user setup](../user-setup.mdx#install-the-firmware) and [split keyboard](../features/split-keyboards.md#building-and-flashing-firmware) pages. :::warning