diff --git a/docs/docs/features/dongle.mdx b/docs/docs/features/dongle.mdx new file mode 100644 index 00000000..3c7bffcd --- /dev/null +++ b/docs/docs/features/dongle.mdx @@ -0,0 +1,209 @@ +--- +title: Keyboard Dongle +sidebar_label: Keyboard Dongle +--- + +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + +:::warning +This implementation is experimental and subject to change. + +The information below is for keyboards consisting of a [board and a shield](../faq.md#why-boards-and-shields-why-not-just-keyboard). The setup for keyboards consisting exclusively of a [board](../faq.md#what-is-a-board) is not yet documented. +::: + +A bluetooth dongle can be added to any keyboard running ZMK. The result is a [split keyboard](./split-keyboards.md) with the dongle as "central". There are a number of advantages to adding a dongle, but also some disadvantages: + +Benefits: + +- The "central" dongle results in increased battery life for the keyboard/former "central", as it is now a peripheral. +- It is easier to connect to the host device. + +Disadvantages: + +- An extra microcontroller is needed. +- The keyboard becomes unusable without the dongle. + +:::note +Depending on how the dongle is used, there are some additional [latency considerations](./split-keyboards.md#latency-considerations) to keep in mind. +On average, the latency increase is around 3.75ms, in worst case scenario, the latency increase can be up to 7.5ms compared to a unibody keyboard. +::: + +## Editing a Keyboard Definition to Support a Dongle + +You will modify the [files defining your keyboard](../config/index.md#shield-folder) to support a dongle. +The recommended approach to doing so (found below) allows you to easily enable a dongle, but it is disabled by default. +This is done to ensure that backwards compatibility is maintained for users who do not wish to use a dongle. + +### Shield Configuration Files + +Start by adding the dongle body to the shield configuration. + +```kconfig title="Kconfig.shield" +config SHIELD_MY_KEYBOARD_DONGLE + def_bool $(shields_list_contains,my_keyboard_dongle) +``` + +Next, add the dongle configuration to your keyboard's `Kconfig.defconfig`. + + + + +```kconfig title="Kconfig.defconfig" +if SHIELD_MY_KEYBOARD_DONGLE + +config ZMK_KEYBOARD_NAME + default "My Board" + +config ZMK_SPLIT_ROLE_CENTRAL + default y + +config ZMK_SPLIT + default y + + +# Increase the transmit power of the dongle +choice BT_CTLR_TX_PWR + default BT_CTLR_TX_PWR_PLUS_8 +endchoice + +endif + +if SHIELD_MY_KEYBOARD && !ZMK_SPLIT +config ZMK_KEYBOARD_NAME + default "My Board" +endif +``` + + + + +Modify the following `Kconfig.defconfig` file to include the dongle in the split keyboard configuration. + +```kconfig title="Kconfig.defconfig" +if SHIELD_MY_KEYBOARD_DONGLE || SHIELD_MY_KEYBOARD_LEFT || SHIELD_MY_KEYBOARD_RIGHT + +config ZMK_SPLIT + default y + +endif + +if SHIELD_MY_KEYBOARD_DONGLE + +config ZMK_KEYBOARD_NAME + default "My Keyboard" + +config ZMK_SPLIT_ROLE_CENTRAL + default y + +config ZMK_SPLIT_BLE_CENTRAL_PERIPHERALS + default 2 + +# Increase the transmit power of the dongle +choice BT_CTLR_TX_PWR + default BT_CTLR_TX_PWR_PLUS_8 +endchoice + +endif +``` + +Modify the `Kconfig.defconfig` file to include the following: + +```kconfig title="Kconfig.defconfig" + +if SHIELD_MY_KEYBOARD_LEFT + +# Setting this to y will make the left half the central +# We want it to be the central when dongle is not used +config ZMK_SPLIT_ROLE_CENTRAL + default y + +# Check if the left half is the central +if ZMK_SPLIT_ROLE_CENTRAL +config ZMK_KEYBOARD_NAME + default "My Keyboard" + +endif # ZMK_SPLIT_ROLE_CENTRAL + +endif # SHIELD_MY_KEYBOARD_LEFT +``` + + + + +### Dongle Overlay File + +Replace the `kscan` with `kscan-mock` in the dongle overlay. + +:::warning +Your keyboard's matrix transform must be both defined and selected under the `chosen` node either here or in a `my_keyboard.dtsi` file. +::: + +```dts title="my_keyboard_dongle.overlay" +// import the default shield configuration +#include "my_keyboard.dtsi" + +/ { + chosen { + zmk,kscan = &mock_kscan; + }; + + mock_kscan: kscan_1 { + compatible = "zmk,kscan-mock"; + + columns = <0>; + rows = <0>; + events = <0>; + }; +}; + +``` + +## Enabling the Dongle + +When the above has been implemented in the keyboard definition. + +The dongle can be enabled by implementing the following changes in the user config file. + +For a split keyboard, change this + +```kconfig title="config/my_keyboard_left.conf" +# Disable central role to use dongle +CONFIG_ZMK_SPLIT_ROLE_CENTRAL=n +``` + +For a unibody keyboard, change this + +```kconfig title="config/my_keyboard.conf" +# Enable split functionality, this will put the unibody keyboard in peripheral mode +CONFIG_ZMK_SPLIT=y +``` + +## Building the firmware + +Add the appropriate lines to your `build.yml` file to build the firmware for your dongle, in addition to the other parts of your keyboard. + +```yaml +include: +# ----------------------------------------- +# Your other keyboard parts here +# ----------------------------------------- + - board: nice_nano_v2 + shield: my_keyboard_dongle + - board: nice_nano_v2 + shield: settings_reset +``` + +:::warning +Before flashing your new firmware, flash the `settings_reset` [UF2 firmware](../troubleshooting/connection-issues.mdx#acquiring-a-reset-uf2) on all devices. +::: +:::note +Any microcontroller with BLE support can be used as a dongle. +::: + diff --git a/docs/sidebars.js b/docs/sidebars.js index d4c398b4..22de7c45 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -44,6 +44,7 @@ module.exports = { "features/backlight", "features/battery", "features/soft-off", + "features/dongle", ], }, {