zmk/docs/docs/config/split.md
Pete Johanson 1530ae36c2
fix(split): Enable wired split by default if DTS is set (#3010)
Remove the previous condition on ZMK_SPLIT_WIRED that only enabled it if
!ZMK_BLE. We'll defer to the `depends on` to ensure the DTS exists to
use wired split to make that decision on enabling the feature.
2025-07-30 13:43:46 -04:00

8.2 KiB

title sidebar_label
Split Configuration Split

These are settings that control how split keyboards behave.

See Configuration Overview for instructions on how to change these settings.

Kconfig

Following split keyboard settings are defined in zmk/app/src/split/Kconfig.

Config Type Description Default
CONFIG_ZMK_SPLIT bool Enable split keyboard support n
CONFIG_ZMK_SPLIT_ROLE_CENTRAL bool y for central device, n for peripheral n
CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS bool Enable split keyboard support for passing indicator state to peripherals n

Bluetooth Splits

Following bluetooth split keyboard settings are defined in zmk/app/src/split/bluetooth/Kconfig.

Config Type Description Default
CONFIG_ZMK_SPLIT_BLE bool Use BLE to communicate between split keyboard halves y
CONFIG_ZMK_SPLIT_BLE_CENTRAL_PERIPHERALS int Number of peripherals that will connect to the central 1
CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING bool Enable fetching split peripheral battery levels to the central side n
CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_PROXY bool Enable central reporting of split battery levels to hosts n
CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_QUEUE_SIZE int Max number of battery level events to queue when received from peripherals CONFIG_ZMK_SPLIT_BLE_CENTRAL_PERIPHERALS
CONFIG_ZMK_SPLIT_BLE_CENTRAL_POSITION_QUEUE_SIZE int Max number of key state events to queue when received from peripherals 5
CONFIG_ZMK_SPLIT_BLE_CENTRAL_SPLIT_RUN_STACK_SIZE int Stack size of the BLE split central write thread 512
CONFIG_ZMK_SPLIT_BLE_CENTRAL_SPLIT_RUN_QUEUE_SIZE int Max number of behavior run events to queue to send to the peripheral(s) 5
CONFIG_ZMK_SPLIT_BLE_PERIPHERAL_STACK_SIZE int Stack size of the BLE split peripheral notify thread 756
CONFIG_ZMK_SPLIT_BLE_PERIPHERAL_PRIORITY int Priority of the BLE split peripheral notify thread 5
CONFIG_ZMK_SPLIT_BLE_PERIPHERAL_POSITION_QUEUE_SIZE int Max number of key state events to queue to send to the central 10

Wired Splits

Hardware UARTs have a few different modes/approaches to sending and receiving data, with different levels of complexity and performance. Not all hardware nor drivers support all modes, so ZMK has code to support different interaction modes with the UART as needed. The default mode should be properly selected based on the platform's report support, but you can choose to override the mode if needed.

  • Polling Mode - The least efficient mode, this requires the MCU to constantly poll the UART to see if more data has been received, taking time away from other processing. This is basic mode supported by all UART drivers.
  • Interrupt Mode - This mode allows the MCU to do other processing until the UART raises an interrupt to signal new data has been received. On platforms where this is combined with a FIFO, there is even less superfluous processing, and high speeds can be achieved while allowing other processing to continue. Examples:
    • RP2040
    • nRF52
  • Async (DMA) Mode - Similar to interrupt mode, data reception can occur without involving the MCU. Additionally, larger volumes can be copied directly into accessible memory without the use of the MCU, allowing even further efficiency/rates without tying up the MCU. Only some drivers support this mode (and the current Zephyr 3.5 version of the nRF52 UART has some bugs that prevent its use). Examples:
    • SAM0 (e.g. SAMD21)
    • STM32 (e.g. stm32f072)

Following wired split keyboard settings are defined in zmk/app/src/split/wired/Kconfig.

Config Type Description Default
CONFIG_ZMK_SPLIT_WIRED bool Use wired connection to communicate between split keyboard halves y (if devicetree is set appropriately)
CONFIG_ZMK_SPLIT_WIRED_UART_MODE_ASYNC bool Async (DMA) mode y if the driver supports it (excluding nRF52 with known bugs)
CONFIG_ZMK_SPLIT_WIRED_UART_MODE_INTERRUPT bool Interrupt mode y if the hardware supports it
CONFIG_ZMK_SPLIT_WIRED_UART_MODE_POLLING bool Polling mode y if neither other mode is supported

Async (DMA) Mode

The following settings only apply when using wired split in async (DMA) mode:

Config Type Description Default
CONFIG_ZMK_SPLIT_WIRED_ASYNC_RX_TIMEOUT int RX Timeout (in microseconds) before reporting received data 20

Polling Mode

The following settings only apply when using wired split in polling mode:

Config Type Description Default
CONFIG_ZMK_SPLIT_WIRED_POLLING_RX_PERIOD int Number of ticks between calls to poll for split data 10

Devicetree

Wired Split

Wired splits require a properly configured UART to function. If writing a shield, you may be able to use the standard UART already provided by the board, e.g. &pro_micro_serial. See predefined nodes for details on the UART node labels provided by various interconnects. If you are creating your own board, or using custom pins for the UART, see the documentation on pin control to configure the pins for your UART.

Once you have a properly configured UART device, it needs to be assigned in a new node with a compatible value of "zmk,wired-split". For example:

/ {
    wired_split {
        compatible = "zmk,wired-split";
        device = <&pro_micro_serial>;
    };
};