Compare commits

...
Sign in to create a new pull request.

12 commits

Author SHA1 Message Date
dependabot[bot]
64daf698e0
chore(deps): bump ws in /docs (#3398)
Bumps  and [ws](https://github.com/websockets/ws). These dependencies needed to be updated together.

Updates `ws` from 7.5.10 to 7.5.11
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/7.5.10...7.5.11)

Updates `ws` from 8.20.0 to 8.21.0
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/7.5.10...7.5.11)

---
updated-dependencies:
- dependency-name: ws
  dependency-version: 7.5.11
  dependency-type: indirect
- dependency-name: ws
  dependency-version: 8.21.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-20 09:13:12 +02:00
dependabot[bot]
e695d94fda
chore(deps): bump webpack-dev-server from 5.2.4 to 5.2.5 in /docs (#3396)
Bumps [webpack-dev-server](https://github.com/webpack/webpack-dev-server) from 5.2.4 to 5.2.5.
- [Release notes](https://github.com/webpack/webpack-dev-server/releases)
- [Changelog](https://github.com/webpack/webpack-dev-server/blob/main/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-dev-server/compare/v5.2.4...v5.2.5)

---
updated-dependencies:
- dependency-name: webpack-dev-server
  dependency-version: 5.2.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-20 09:12:26 +02:00
dependabot[bot]
f57e255657
chore(deps): bump actions/checkout from 6 to 7 (#3393)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-20 06:58:21 +02:00
dependabot[bot]
fb1fad07a1
chore(deps): bump actions/github-script from 7 to 9 (#3324)
Bumps [actions/github-script](https://github.com/actions/github-script) from 7 to 9.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v7...v9)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-version: '9'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-20 06:56:25 +02:00
dependabot[bot]
45d6d67a04
chore(deps): bump googleapis/release-please-action from 4 to 5 (#3333)
Bumps [googleapis/release-please-action](https://github.com/googleapis/release-please-action) from 4 to 5.
- [Release notes](https://github.com/googleapis/release-please-action/releases)
- [Changelog](https://github.com/googleapis/release-please-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/googleapis/release-please-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: googleapis/release-please-action
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-20 06:54:09 +02:00
dependabot[bot]
7fdae56f02
chore(deps): bump launch-editor from 2.13.2 to 2.14.1 in /docs (#3394)
Bumps [launch-editor](https://github.com/vitejs/launch-editor) from 2.13.2 to 2.14.1.
- [Commits](https://github.com/vitejs/launch-editor/compare/v2.13.2...v2.14.1)

---
updated-dependencies:
- dependency-name: launch-editor
  dependency-version: 2.14.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-20 06:47:57 +02:00
Genteure
68212cfb1d
docs: reduce the use of admonitions (#3371)
* docs: reduce use of admonitions

- Removed some admonitions
- Some are merged with surrounding paragraphs
- Also slipped in a bit of other formatting changes

* address review comments

* address review comments
2026-06-20 06:28:27 +02:00
yekingyan
0a6c6a1856
feat(boards): add physical layout for reviung34 (#3351)
* feat(boards): add physical layout for reviung34

Add physical layout support for the REVIUNG34 keyboard:
- Dual 1U (34-key) layout
- Single 2U (33-key) layout
- Position map for layout switching

Coordinates extracted from the original KiCad PCB (gtips/reviung).
Closes #2536

* Update app/boards/shields/reviung34/reviung34-layouts.dtsi

Co-authored-by: Nicolas Munnich <98408764+nmunnich@users.noreply.github.com>

* Update app/boards/shields/reviung34/reviung34-layouts.dtsi

Co-authored-by: Nicolas Munnich <98408764+nmunnich@users.noreply.github.com>

* Update app/boards/shields/reviung34/reviung34-layouts.dtsi

Co-authored-by: Nicolas Munnich <98408764+nmunnich@users.noreply.github.com>

* Update app/boards/shields/reviung34/reviung34-layouts.dtsi

Co-authored-by: Nicolas Munnich <98408764+nmunnich@users.noreply.github.com>

* Update app/boards/shields/reviung34/reviung34-layouts.dtsi

Co-authored-by: Nicolas Munnich <98408764+nmunnich@users.noreply.github.com>

* fix: wrap negative numbers in parentheses for DTS syntax

---------

Co-authored-by: Nicolas Munnich <98408764+nmunnich@users.noreply.github.com>
2026-06-20 06:25:02 +02:00
Genteure
ff09f2d0c9
docs: reorganise supported hardware page (#3363)
* docs: supported hardware structure changes

Added a few links to hardware intergration pages to provide clearly signal to reader "you can make your own".
Removed "Contributing" section since it's not really relavent anymore.

* docs: move unsupported boards section out of metadata

* address review comments

* fix broken link

* board variants, interconnect, fix link, move unsupported section

* Apply suggested change

Co-authored-by: Nicolas Munnich <98408764+nmunnich@users.noreply.github.com>

---------

Co-authored-by: Nicolas Munnich <98408764+nmunnich@users.noreply.github.com>
2026-06-07 18:45:31 +02:00
Cem Aksoylar
773dec58ea
docs: Add missing input processor to sidebar (#3372) 2026-06-03 23:26:39 +02:00
dependabot[bot]
26246da1b6
chore(deps): bump actions/stale from 10.2.0 to 10.3.0 (#3358)
Bumps [actions/stale](https://github.com/actions/stale) from 10.2.0 to 10.3.0.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v10.2.0...v10.3.0)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-version: 10.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-30 19:58:53 +02:00
Nicolas Munnich
ed56d81db7
docs: Move the hardware integration section out of development (#3360) 2026-05-26 22:33:57 +02:00
88 changed files with 429 additions and 355 deletions

View file

@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7
- name: Find test directories - name: Find test directories
id: test-dirs id: test-dirs
run: | run: |
@ -38,7 +38,7 @@ jobs:
image: docker.io/zmkfirmware/zmk-build-arm:4.1 image: docker.io/zmkfirmware/zmk-build-arm:4.1
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7
- name: Cache west modules - name: Cache west modules
uses: actions/cache@v5 uses: actions/cache@v5
env: env:

View file

@ -33,7 +33,7 @@ jobs:
has_valid_build_matrix: ${{ steps.fetch.outputs.has_valid_build_matrix }} has_valid_build_matrix: ${{ steps.fetch.outputs.has_valid_build_matrix }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7
- name: Fetch Build Matrix - name: Fetch Build Matrix
id: fetch id: fetch
@ -67,7 +67,7 @@ jobs:
curl -fsSL https://deb.nodesource.com/setup_22.x | bash && apt install -y nodejs curl -fsSL https://deb.nodesource.com/setup_22.x | bash && apt install -y nodejs
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7
- name: Create build directory - name: Create build directory
run: | run: |

View file

@ -30,7 +30,7 @@ jobs:
include: ${{ fromJSON(needs.compile-matrix.outputs.include-list) }} include: ${{ fromJSON(needs.compile-matrix.outputs.include-list) }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7
with: with:
persist-credentials: false persist-credentials: false
- name: Cache west modules - name: Cache west modules
@ -63,7 +63,7 @@ jobs:
- name: Install @actions/artifact - name: Install @actions/artifact
run: npm install @actions/artifact@5.0.3 run: npm install @actions/artifact@5.0.3
- name: Build - name: Build
uses: actions/github-script@v7 uses: actions/github-script@v9
id: boards-list id: boards-list
with: with:
script: | script: |
@ -95,7 +95,7 @@ jobs:
throw new Error('Failed to build one or more configurations'); throw new Error('Failed to build one or more configurations');
} }
- name: Upload artifacts - name: Upload artifacts
uses: actions/github-script@v7 uses: actions/github-script@v9
continue-on-error: ${{ github.event_name == 'pull_request' }} continue-on-error: ${{ github.event_name == 'pull_request' }}
id: boards-upload id: boards-upload
with: with:
@ -146,7 +146,7 @@ jobs:
include-list: ${{ steps.compile-list.outputs.result }} include-list: ${{ steps.compile-list.outputs.result }}
steps: steps:
- name: Join build lists - name: Join build lists
uses: actions/github-script@v7 uses: actions/github-script@v9
id: compile-list id: compile-list
with: with:
script: | script: |
@ -187,7 +187,7 @@ jobs:
core-include: ${{ steps.core-list.outputs.result }} core-include: ${{ steps.core-list.outputs.result }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7
with: with:
persist-credentials: false persist-credentials: false
- name: Use Node.js - name: Use Node.js
@ -196,7 +196,7 @@ jobs:
node-version: "14.x" node-version: "14.x"
- name: Install js-yaml - name: Install js-yaml
run: npm install js-yaml run: npm install js-yaml
- uses: actions/github-script@v7 - uses: actions/github-script@v9
id: core-list id: core-list
with: with:
script: | script: |
@ -218,14 +218,14 @@ jobs:
boards-include: ${{ steps.boards-list.outputs.result }} boards-include: ${{ steps.boards-list.outputs.result }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7
- name: Use Node.js - name: Use Node.js
uses: actions/setup-node@v6 uses: actions/setup-node@v6
with: with:
node-version: "14.x" node-version: "14.x"
- name: Install js-yaml - name: Install js-yaml
run: npm install js-yaml run: npm install js-yaml
- uses: actions/github-script@v7 - uses: actions/github-script@v9
id: boards-list id: boards-list
with: with:
script: | script: |
@ -303,7 +303,7 @@ jobs:
nightly-include: ${{ steps.nightly-list.outputs.result }} nightly-include: ${{ steps.nightly-list.outputs.result }}
steps: steps:
- name: Create nightly list - name: Create nightly list
uses: actions/github-script@v7 uses: actions/github-script@v9
id: nightly-list id: nightly-list
with: with:
script: | script: |
@ -346,7 +346,7 @@ jobs:
organized-metadata: ${{ steps.organize-metadata.outputs.result }} organized-metadata: ${{ steps.organize-metadata.outputs.result }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7
with: with:
persist-credentials: false persist-credentials: false
- name: Use Node.js - name: Use Node.js
@ -356,7 +356,7 @@ jobs:
- name: Install js-yaml - name: Install js-yaml
run: npm install js-yaml run: npm install js-yaml
- name: Aggregate Metadata - name: Aggregate Metadata
uses: actions/github-script@v7 uses: actions/github-script@v9
id: aggregate-metadata id: aggregate-metadata
with: with:
script: | script: |
@ -374,7 +374,7 @@ jobs:
result-encoding: string result-encoding: string
- name: Organize Metadata - name: Organize Metadata
uses: actions/github-script@v7 uses: actions/github-script@v9
id: organize-metadata id: organize-metadata
with: with:
script: | script: |
@ -428,7 +428,7 @@ jobs:
core-changes: ${{ steps.core-changes.outputs.result }} core-changes: ${{ steps.core-changes.outputs.result }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7
with: with:
persist-credentials: false persist-credentials: false
- uses: tj-actions/changed-files@9200e69727eb73eb060652b19946b8a2fdfb654b # pin to v45.0.8 due to https://github.com/tj-actions/changed-files/issues/2463 https://www.stepsecurity.io/blog/harden-runner-detection-tj-actions-changed-files-action-is-compromised - uses: tj-actions/changed-files@9200e69727eb73eb060652b19946b8a2fdfb654b # pin to v45.0.8 due to https://github.com/tj-actions/changed-files/issues/2463 https://www.stepsecurity.io/blog/harden-runner-detection-tj-actions-changed-files-action-is-compromised
@ -436,7 +436,7 @@ jobs:
with: with:
json: true json: true
escape_json: false escape_json: false
- uses: actions/github-script@v7 - uses: actions/github-script@v9
id: board-changes id: board-changes
with: with:
script: | script: |
@ -444,7 +444,7 @@ jobs:
const boardChanges = changedFiles.filter(f => f.startsWith('app/boards')); const boardChanges = changedFiles.filter(f => f.startsWith('app/boards'));
return boardChanges.length ? 'true' : 'false'; return boardChanges.length ? 'true' : 'false';
result-encoding: string result-encoding: string
- uses: actions/github-script@v7 - uses: actions/github-script@v9
id: core-changes id: core-changes
with: with:
script: | script: |

View file

@ -14,7 +14,7 @@ jobs:
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
- uses: bahmutov/npm-install@v1 - uses: bahmutov/npm-install@v1
with: with:
working-directory: docs working-directory: docs
@ -24,7 +24,7 @@ jobs:
typecheck: typecheck:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
- uses: bahmutov/npm-install@v1 - uses: bahmutov/npm-install@v1
with: with:
working-directory: docs working-directory: docs

View file

@ -20,7 +20,7 @@ jobs:
container: container:
image: docker.io/zmkfirmware/zmk-dev-arm:4.1 image: docker.io/zmkfirmware/zmk-dev-arm:4.1
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
- name: Install dependencies - name: Install dependencies
run: pip install --break-system-packages -r app/scripts/requirements.txt run: pip install --break-system-packages -r app/scripts/requirements.txt
- name: West init - name: West init

View file

@ -8,7 +8,7 @@ jobs:
pre-commit: pre-commit:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
- uses: actions/setup-python@v6 - uses: actions/setup-python@v6
with: with:
python-version: 3.x python-version: 3.x

View file

@ -20,7 +20,7 @@ jobs:
minor: ${{ steps.release.outputs.minor }} minor: ${{ steps.release.outputs.minor }}
patch: ${{ steps.release.outputs.patch }} patch: ${{ steps.release.outputs.patch }}
steps: steps:
- uses: googleapis/release-please-action@v4 - uses: googleapis/release-please-action@v5
id: release id: release
with: with:
token: ${{ secrets.ZMK_RELEASE_PLEASE_TOKEN }} token: ${{ secrets.ZMK_RELEASE_PLEASE_TOKEN }}
@ -35,7 +35,7 @@ jobs:
ZMK_RELEASE_PLEASE_TOKEN: ${{ secrets.ZMK_RELEASE_PLEASE_TOKEN }} ZMK_RELEASE_PLEASE_TOKEN: ${{ secrets.ZMK_RELEASE_PLEASE_TOKEN }}
VERSION: v${{ needs.handle-commit.outputs.major }}.${{ needs.handle-commit.outputs.minor }} VERSION: v${{ needs.handle-commit.outputs.major }}.${{ needs.handle-commit.outputs.minor }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
- name: Create major.minor branch - name: Create major.minor branch
if: ${{ needs.handle-commit.outputs.patch == '0' }} if: ${{ needs.handle-commit.outputs.patch == '0' }}

View file

@ -7,7 +7,7 @@ jobs:
stale: stale:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/stale@v10.2.0 - uses: actions/stale@v10.3.0
with: with:
days-before-pr-stale: 300 # ~10 months days-before-pr-stale: 300 # ~10 months
stale-pr-label: "stale" stale-pr-label: "stale"

View file

@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7
- name: Find test directories - name: Find test directories
id: test-dirs id: test-dirs
run: | run: |
@ -40,7 +40,7 @@ jobs:
image: docker.io/zmkfirmware/zmk-build-arm:4.1 image: docker.io/zmkfirmware/zmk-build-arm:4.1
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7
- name: Cache west modules - name: Cache west modules
uses: actions/cache@v5 uses: actions/cache@v5
env: env:

View file

@ -9,10 +9,6 @@ description: |
natural extension, once there were many shields designed for it, many other *boards* began to be developed natural extension, once there were many shields designed for it, many other *boards* began to be developed
that were compatible to leverage the extensive available shields. Today, many dev kits come with Uno that were compatible to leverage the extensive available shields. Today, many dev kits come with Uno
headers to make it easy to work with them. headers to make it easy to work with them.
Note: ZMK doesn't support boards with AVR 8-bit processors, such as the ATmega32U4, because Zephyr™ only
supports 32-bit and 64-bit platforms. As a result, boards like the original Arduino Uno Rev3 itself are
*not* supported by ZMK.
node_labels: node_labels:
gpio: arduino_header gpio: arduino_header
i2c: arduino_i2c i2c: arduino_i2c

View file

@ -6,12 +6,8 @@ url: https://www.sparkfun.com/products/12640
manufacturer: SparkFun manufacturer: SparkFun
description: | description: |
The SparkFun Pro Micro grew popular as a low cost ATmega32U4 board with sufficient GPIO and peripherals The SparkFun Pro Micro grew popular as a low cost ATmega32U4 board with sufficient GPIO and peripherals
to work for many keyboard needs. Since the original Pro Micro, many pin compatible boards have appeared, to work for many keyboard needs. Since the original Pro Micro, many pin compatible boards have appeared
with various changes or improvements, such as the Elite-C w/ USB-C, nice!nano with nRF52840 wireless. with various changes or improvements.
Note: ZMK doesn't support boards with AVR 8-bit processors, such as the ATmega32U4, because Zephyr™ only
supports 32-bit and 64-bit platforms. As a result, controllers like the SparkFun Pro Micro and the Elite-C
are *not* supported by ZMK.
node_labels: node_labels:
gpio: pro_micro gpio: pro_micro
i2c: pro_micro_i2c i2c: pro_micro_i2c

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2026 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/
#include <physical_layouts.dtsi>
/ {
reviung34_dual_1u_layout: reviung34_dual_1u_layout {
compatible = "zmk,physical-layout";
display-name = "Dual 1U (34 keys)";
keys // w h x y rot rx ry
= <&key_physical_attrs 100 100 35 2 1000 85 52>
, <&key_physical_attrs 100 100 136 1 1000 186 51>
, <&key_physical_attrs 100 100 238 0 1000 288 50>
, <&key_physical_attrs 100 100 333 35 1000 383 85>
, <&key_physical_attrs 100 100 429 71 1000 479 121>
, <&key_physical_attrs 100 100 555 71 (-1000) 605 121>
, <&key_physical_attrs 100 100 650 35 (-1000) 700 85>
, <&key_physical_attrs 100 100 746 0 (-1000) 796 50>
, <&key_physical_attrs 100 100 847 1 (-1000) 897 51>
, <&key_physical_attrs 100 100 949 1 (-1000) 999 51>
, <&key_physical_attrs 100 100 17 100 1000 67 150>
, <&key_physical_attrs 100 100 119 99 1000 169 149>
, <&key_physical_attrs 100 100 221 98 1000 271 148>
, <&key_physical_attrs 100 100 316 134 1000 366 184>
, <&key_physical_attrs 100 100 411 169 1000 461 219>
, <&key_physical_attrs 100 100 572 169 (-1000) 622 219>
, <&key_physical_attrs 100 100 668 134 (-1000) 718 184>
, <&key_physical_attrs 100 100 763 98 (-1000) 813 148>
, <&key_physical_attrs 100 100 865 99 (-1000) 915 149>
, <&key_physical_attrs 100 100 966 100 (-1000) 1016 150>
, <&key_physical_attrs 100 100 0 198 1000 50 248>
, <&key_physical_attrs 100 100 102 198 1000 152 248>
, <&key_physical_attrs 100 100 203 197 1000 253 247>
, <&key_physical_attrs 100 100 298 232 1000 348 282>
, <&key_physical_attrs 100 100 394 268 1000 444 318>
, <&key_physical_attrs 100 100 590 268 (-1000) 640 318>
, <&key_physical_attrs 100 100 685 232 (-1000) 735 282>
, <&key_physical_attrs 100 100 780 197 (-1000) 830 247>
, <&key_physical_attrs 100 100 882 198 (-1000) 932 248>
, <&key_physical_attrs 100 100 984 198 (-1000) 1034 248>
, <&key_physical_attrs 100 100 328 370 1500 378 420>
, <&key_physical_attrs 100 100 442 385 0 0 0>
, <&key_physical_attrs 100 100 542 385 0 0 0>
, <&key_physical_attrs 100 100 655 370 (-1500) 705 420>
;
};
reviung34_single_2u_layout: reviung34_single_2u_layout {
compatible = "zmk,physical-layout";
display-name = "Single 2U (33 keys)";
keys // w h x y rot rx ry
= <&key_physical_attrs 100 100 35 2 1000 85 52>
, <&key_physical_attrs 100 100 136 1 1000 186 51>
, <&key_physical_attrs 100 100 238 0 1000 288 50>
, <&key_physical_attrs 100 100 333 35 1000 383 85>
, <&key_physical_attrs 100 100 429 71 1000 479 121>
, <&key_physical_attrs 100 100 555 71 (-1000) 605 121>
, <&key_physical_attrs 100 100 650 35 (-1000) 700 85>
, <&key_physical_attrs 100 100 746 0 (-1000) 796 50>
, <&key_physical_attrs 100 100 847 1 (-1000) 897 51>
, <&key_physical_attrs 100 100 949 1 (-1000) 999 51>
, <&key_physical_attrs 100 100 17 100 1000 67 150>
, <&key_physical_attrs 100 100 119 99 1000 169 149>
, <&key_physical_attrs 100 100 221 98 1000 271 148>
, <&key_physical_attrs 100 100 316 134 1000 366 184>
, <&key_physical_attrs 100 100 411 169 1000 461 219>
, <&key_physical_attrs 100 100 572 169 (-1000) 622 219>
, <&key_physical_attrs 100 100 668 134 (-1000) 718 184>
, <&key_physical_attrs 100 100 763 98 (-1000) 813 148>
, <&key_physical_attrs 100 100 865 99 (-1000) 915 149>
, <&key_physical_attrs 100 100 966 100 (-1000) 1016 150>
, <&key_physical_attrs 100 100 0 198 1000 50 248>
, <&key_physical_attrs 100 100 102 198 1000 152 248>
, <&key_physical_attrs 100 100 203 197 1000 253 247>
, <&key_physical_attrs 100 100 298 232 1000 348 282>
, <&key_physical_attrs 100 100 394 268 1000 444 318>
, <&key_physical_attrs 100 100 590 268 (-1000) 640 318>
, <&key_physical_attrs 100 100 685 232 (-1000) 735 282>
, <&key_physical_attrs 100 100 780 197 (-1000) 830 247>
, <&key_physical_attrs 100 100 882 198 (-1000) 932 248>
, <&key_physical_attrs 100 100 984 198 (-1000) 1034 248>
, <&key_physical_attrs 100 100 328 370 1500 378 420>
, <&key_physical_attrs 200 100 442 385 0 0 0>
, <&key_physical_attrs 100 100 655 370 (-1500) 705 420>
;
};
reviung34_position_map {
compatible = "zmk,physical-layout-position-map";
reviung34_dual_1u_posmap {
physical-layout = <&reviung34_dual_1u_layout>;
positions
= < 0 1 2 3 4 5 6 7 8 9>
, <10 11 12 13 14 15 16 17 18 19>
, <20 21 22 23 24 25 26 27 28 29>
, <30 31 33 32>;
};
reviung34_single_2u_posmap {
physical-layout = <&reviung34_single_2u_layout>;
positions
= < 0 1 2 3 4 5 6 7 8 9>
, <10 11 12 13 14 15 16 17 18 19>
, <20 21 22 23 24 25 26 27 28 29>
, <30 31 32>;
};
};
};

View file

@ -6,10 +6,20 @@
#include <dt-bindings/zmk/matrix_transform.h> #include <dt-bindings/zmk/matrix_transform.h>
#include "reviung34-layouts.dtsi"
&reviung34_dual_1u_layout {
transform = <&dual_1u_transform>;
};
&reviung34_single_2u_layout {
transform = <&single_2u_transform>;
};
/ { / {
chosen { chosen {
zmk,kscan = &kscan0; zmk,kscan = &kscan0;
zmk,matrix-transform = &dual_1u_transform; zmk,physical-layout = &reviung34_dual_1u_layout;
}; };
dual_1u_transform: keymap_transform_0 { dual_1u_transform: keymap_transform_0 {

View file

@ -50,12 +50,12 @@ if (ZMK_CONFIG)
set(ENV{ZMK_CONFIG} "${ZMK_CONFIG}") set(ENV{ZMK_CONFIG} "${ZMK_CONFIG}")
if(EXISTS ${ZMK_CONFIG}/boards) if(EXISTS ${ZMK_CONFIG}/boards)
message(STATUS "Adding ZMK config directory as board root: ${ZMK_CONFIG}") message(STATUS "Adding ZMK config directory as board root: ${ZMK_CONFIG}")
message(DEPRECATION "The `config/boards` folder is deprecated. Please use a module instead. See https://zmk.dev/docs/development/hardware-integration/new-shield and https://zmk.dev/docs/development/module-creation for more information.") message(DEPRECATION "The `config/boards` folder is deprecated. Please use a module instead. See https://zmk.dev/docs/hardware-integration/new-shield and https://zmk.dev/docs/development/module-creation for more information.")
list(APPEND BOARD_ROOT ${ZMK_CONFIG}) list(APPEND BOARD_ROOT ${ZMK_CONFIG})
endif() endif()
if(EXISTS ${ZMK_CONFIG}/dts) if(EXISTS ${ZMK_CONFIG}/dts)
message(STATUS "Adding ZMK config directory as DTS root: ${ZMK_CONFIG}") message(STATUS "Adding ZMK config directory as DTS root: ${ZMK_CONFIG}")
message(DEPRECATION "The `config/dts` folder is deprecated. Please use a module instead. See https://zmk.dev/docs/development/hardware-integration/new-shield and https://zmk.dev/docs/development/module-creation for more information.") message(DEPRECATION "The `config/dts` folder is deprecated. Please use a module instead. See https://zmk.dev/docs/hardware-integration/new-shield and https://zmk.dev/docs/development/module-creation for more information.")
list(APPEND DTS_ROOT ${ZMK_CONFIG}) list(APPEND DTS_ROOT ${ZMK_CONFIG})
endif() endif()
endif() endif()

View file

@ -71,7 +71,7 @@ BUILD_ASSERT(
#define ZMK_LAYOUT_INST(n) \ #define ZMK_LAYOUT_INST(n) \
BUILD_ASSERT(!IS_ENABLED(CONFIG_ZMK_STUDIO) || DT_INST_NODE_HAS_PROP(n, keys), \ BUILD_ASSERT(!IS_ENABLED(CONFIG_ZMK_STUDIO) || DT_INST_NODE_HAS_PROP(n, keys), \
"ZMK Studio requires physical layouts with key positions. See " \ "ZMK Studio requires physical layouts with key positions. See " \
"https://zmk.dev/docs/development/hardware-integration/studio-setup"); \ "https://zmk.dev/docs/hardware-integration/studio-setup"); \
static const struct zmk_key_physical_attrs _CONCAT(_zmk_physical_layout_keys_, \ static const struct zmk_key_physical_attrs _CONCAT(_zmk_physical_layout_keys_, \
n)[DT_INST_PROP_LEN_OR(n, keys, 0)] = { \ n)[DT_INST_PROP_LEN_OR(n, keys, 0)] = { \
LISTIFY(DT_INST_PROP_LEN_OR(n, keys, 0), ZKPA_INIT, (, ), n)}; \ LISTIFY(DT_INST_PROP_LEN_OR(n, keys, 0), ZKPA_INIT, (, ), n)}; \

View file

@ -77,7 +77,7 @@ static const struct gpio_dt_spec detect_gpio = GPIO_DT_SPEC_INST_GET(0, detect_g
#else #else
#error \ #error \
"Need to create a node with compatible of 'zmk,wired-split` with a `device` property set to an enabled UART. See http://zmk.dev/docs/development/hardware-integration/new-shield#wired-split" "Need to create a node with compatible of 'zmk,wired-split` with a `device` property set to an enabled UART. See http://zmk.dev/docs/hardware-integration/new-shield#wired-split"
#endif #endif

View file

@ -76,7 +76,7 @@ static const struct gpio_dt_spec detect_gpio = GPIO_DT_SPEC_INST_GET(0, detect_g
#else #else
#error \ #error \
"Need to create a node with compatible of 'zmk,wired-split` with a `device` property set to an enabled UART. See http://zmk.dev/docs/development/hardware-integration/new-shield#wired-split" "Need to create a node with compatible of 'zmk,wired-split` with a `device` property set to an enabled UART. See http://zmk.dev/docs/hardware-integration/new-shield#wired-split"
#endif #endif

View file

@ -18,7 +18,7 @@ There's been lots of various activity in ZMK land!
- Tons of [documentation](/docs) work. - Tons of [documentation](/docs) work.
- Refactoring ([#73](https://github.com/zmkfirmware/zmk/pull/73), [#74](https://github.com/zmkfirmware/zmk/pull/74)) of [keymaps](/docs/keymaps) to make them simpler for users. - Refactoring ([#73](https://github.com/zmkfirmware/zmk/pull/73), [#74](https://github.com/zmkfirmware/zmk/pull/74)) of [keymaps](/docs/keymaps) to make them simpler for users.
- Mod-Tap Behavior (docs coming!) is much improved ([#69](https://github.com/zmkfirmware/zmk/pull/69)) and usable now. - Mod-Tap Behavior (docs coming!) is much improved ([#69](https://github.com/zmkfirmware/zmk/pull/69)) and usable now.
- An initial [`setup.sh`](/docs/user-setup#user-config-setup-script) script was created, allowing users to quickly bootstrap a "user config" setup and push it to GitHub, where GitHub Actions will build the firmware for you. - An initial `setup.sh` script was created, allowing users to quickly bootstrap a "user config" setup and push it to GitHub, where GitHub Actions will build the firmware for you.
- Corne shield ([#80](https://github.com/zmkfirmware/zmk/pull/80)) shield definition was added. - Corne shield ([#80](https://github.com/zmkfirmware/zmk/pull/80)) shield definition was added.
- Initial [encoder](/docs/features/encoders) support ([#61](https://github.com/zmkfirmware/zmk/pull/61)) was added. - Initial [encoder](/docs/features/encoders) support ([#61](https://github.com/zmkfirmware/zmk/pull/61)) was added.

View file

@ -219,7 +219,7 @@ This can be useful to be sure that lowering brightness doesn't set the brightnes
## Board/Shield Metadata ## Board/Shield Metadata
[nicell] and [petejohanson] worked together in [#883](https://github.com/zmkfirmware/zmk/pull/883) to settle on a [metadata format](/docs/development/hardware-integration/hardware-metadata-files) that is used to document every board and shield. This now drives automatic generation of our [supported hardware](/docs/hardware) page and our [nicell] and [petejohanson] worked together in [#883](https://github.com/zmkfirmware/zmk/pull/883) to settle on a [metadata format](/docs/hardware-integration/hardware-metadata-files) that is used to document every board and shield. This now drives automatic generation of our [supported hardware](/docs/hardware) page and our
more nuanced GH Actions automation for testing changes to ZMK. more nuanced GH Actions automation for testing changes to ZMK.
## Coming Soon! ## Coming Soon!

View file

@ -173,7 +173,7 @@ For users or future contributors that might want to dive into writing their own
#### Shield interconnects #### Shield interconnects
[petejohanson] updated the [new shield guide](/docs/development/hardware-integration/new-shield) for non-Pro Micro interconnects including Xiao, Arduino Uno and Blackpill in [#1607](https://github.com/zmkfirmware/zmk/pull/1607). [petejohanson] updated the [new shield guide](/docs/hardware-integration/new-shield) for non-Pro Micro interconnects including Xiao, Arduino Uno and Blackpill in [#1607](https://github.com/zmkfirmware/zmk/pull/1607).
#### Bluetooth feature page #### Bluetooth feature page

View file

@ -19,7 +19,7 @@ Stay tuned for future installments in the series!
## ZMK Tools ## ZMK Tools
[ZMK Tools](https://github.com/joelspadin/zmk-tools) is an extension for [Visual Studio Code](https://code.visualstudio.com) that helps with editing a ZMK user config repo or a fork of ZMK. I originally created it to add some code completion in `.keymap` files, but then I realized that with the web version of VS Code, I could also let you set up a user config repo and build firmware, much like the [user setup script](/docs/user-setup#user-config-setup-script), except without downloading a single thing. [ZMK Tools](https://github.com/joelspadin/zmk-tools) is an extension for [Visual Studio Code](https://code.visualstudio.com) that helps with editing a ZMK user config repo or a fork of ZMK. I originally created it to add some code completion in `.keymap` files, but then I realized that with the web version of VS Code, I could also let you set up a user config repo and build firmware, much like the user setup script, except without downloading a single thing.
### User Config Setup in Browser ### User Config Setup in Browser

View file

@ -225,7 +225,7 @@ return (
:::note :::note
For keyboard maintainers, additional changes are needed to add metadata about the keyboard's physical layouts in order to use ZMK Studio. See the documentation on [physical layouts](/docs/development/hardware-integration/physical-layouts#optional-keys-property) for more information. For keyboard maintainers, additional changes are needed to add metadata about the keyboard's physical layouts in order to use ZMK Studio. See the documentation on [physical layouts](/docs/hardware-integration/physical-layouts#optional-keys-property) for more information.
::: :::
To use ZMK Studio, you need to have a firmware for your keyboard with the feature enabled, as well as a small keymap change to add an unlock key. See [Building with ZMK Studio](/docs/features/studio#building) and [ZMK Studio keymap changes](/docs/features/studio#keymap-changes) for more details. To use ZMK Studio, you need to have a firmware for your keyboard with the feature enabled, as well as a small keymap change to add an unlock key. See [Building with ZMK Studio](/docs/features/studio#building) and [ZMK Studio keymap changes](/docs/features/studio#keymap-changes) for more details.

View file

@ -257,7 +257,7 @@ A few other changes, unrelated to the HWMv2 move, may impact out-of-tree boards/
### Bootloader Setup ### Bootloader Setup
With the version bump, the previous method to enable `&bootloader` has been disabled. Instead, ZMK is introducing _boot retention_, which as a side effect also enables `&bootloader` for SoCs which previously didn't work with said behavior, such as the STM32F072. To set up boot retention for your board, please read through [the dedicated page](/docs/development/hardware-integration/bootloader). With the version bump, the previous method to enable `&bootloader` has been disabled. Instead, ZMK is introducing _boot retention_, which as a side effect also enables `&bootloader` for SoCs which previously didn't work with said behavior, such as the STM32F072. To set up boot retention for your board, please read through [the dedicated page](/docs/hardware-integration/bootloader).
### nRF52840 NFC Pins as GPIO ### nRF52840 NFC Pins as GPIO

View file

@ -32,7 +32,7 @@ To ensure the BOOT button on keyboard and controllers using these SoCs works as
### Bootmode Magic Value Mapper ### Bootmode Magic Value Mapper
Some target SoCs may use the bootmode magic value mapper for [bootloader integration](docs/development/hardware-integration/bootloader/index.mdx). When doing so, the following configurations are used: Some target SoCs may use the bootmode magic value mapper for [bootloader integration](docs/hardware-integration/bootloader/index.mdx). When doing so, the following configurations are used:
| Config | Type | Description | Default | | Config | Type | Description | Default |
| ---------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------- | ------- | | ---------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------- | ------- |

View file

@ -55,12 +55,8 @@ Per sensor overrides can be added with ordered nested nodes with the correct ove
}; };
``` ```
:::note
The names of the child nodes are not important, and are applied in order to the sensors listed in the `sensors` property of the sensors node. The names of the child nodes are not important, and are applied in order to the sensors listed in the `sensors` property of the sensors node.
:::
Applies to the node and child nodes of: `compatible = "zmk,keymap-sensors"` Applies to the node and child nodes of: `compatible = "zmk,keymap-sensors"`
Definition file: [zmk/app/drivers/zephyr/dts/bindings/zmk,keymap-sensors.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/drivers/zephyr/dts/bindings/zmk%2Ckeymap-sensors.yaml) Definition file: [zmk/app/drivers/zephyr/dts/bindings/zmk,keymap-sensors.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/drivers/zephyr/dts/bindings/zmk%2Ckeymap-sensors.yaml)

View file

@ -64,7 +64,7 @@ ZMK will search the shield folder for the following config files _in addition_ t
Shared config files (excluding any `_left` or `_right` suffix) are not currently supported in shield folders. Shared config files (excluding any `_left` or `_right` suffix) are not currently supported in shield folders.
For more documentation on creating and configuring a new shield, see [Zephyr's shield documentation](https://docs.zephyrproject.org/4.1.0/hardware/porting/shields.html) and [ZMK's new keyboard shield](../development/hardware-integration/new-shield.mdx) guide. For more documentation on creating and configuring a new shield, see [Zephyr's shield documentation](https://docs.zephyrproject.org/4.1.0/hardware/porting/shields.html) and [ZMK's new keyboard shield](../hardware-integration/new-shield.mdx) guide.
## Kconfig Files ## Kconfig Files

View file

@ -11,7 +11,7 @@ Defines a mapping from keymap logical positions to physical [kscan](./kscan.md)
You can define multiple matrix transform nodes, one for each layout, and users can select which one they want from the `/chosen` node in their keymaps. You can define multiple matrix transform nodes, one for each layout, and users can select which one they want from the `/chosen` node in their keymaps.
See the [new shield guide](../development/hardware-integration/new-shield.mdx#matrix-transform) for more documentation on how to define a matrix transform. See the [new shield guide](../hardware-integration/new-shield.mdx#matrix-transform) for more documentation on how to define a matrix transform.
### Devicetree ### Devicetree
@ -174,7 +174,7 @@ Note that the entire addressable space does not need to be mapped.
Defines a keyboard layout by joining together a [matrix transform](#matrix-transform), a [keyboard scan](./kscan.md), and a list of physical key properties. Defines a keyboard layout by joining together a [matrix transform](#matrix-transform), a [keyboard scan](./kscan.md), and a list of physical key properties.
Multiple physical layouts can be defined for keyboards with multiple physical key layouts. Multiple physical layouts can be defined for keyboards with multiple physical key layouts.
Read through the [page on physical layouts](../development/hardware-integration/physical-layouts.md) for more information. Read through the [page on physical layouts](../hardware-integration/physical-layouts.md) for more information.
### Devicetree ### Devicetree
@ -211,7 +211,7 @@ The `key_physical_attrs` node is defined in [`dts/physical_layouts.dtsi`](https:
## Physical Layout Position Map ## Physical Layout Position Map
Defines a mapping between [physical layouts](#physical-layout), allowing key mappings to be preserved in the same locations as previously when using [ZMK Studio](../features/studio.md). Read through the [page on physical layouts](../development/hardware-integration/physical-layouts.md) for more information. Defines a mapping between [physical layouts](#physical-layout), allowing key mappings to be preserved in the same locations as previously when using [ZMK Studio](../features/studio.md). Read through the [page on physical layouts](../hardware-integration/physical-layouts.md) for more information.
### Devicetree ### Devicetree

View file

@ -7,7 +7,7 @@ See the [Lighting feature page](../features/lighting.md) for an overview of the
## RGB Underglow ## RGB Underglow
See the [RGB underglow section](../features/lighting.md#rgb-underglow) in the Lighting feature page for more details, and [hardware integration page](../development/hardware-integration/lighting/underglow.md) for adding underglow support to a board. See the [RGB underglow section](../features/lighting.md#rgb-underglow) in the Lighting feature page for more details, and [hardware integration page](../hardware-integration/lighting/underglow.md) for adding underglow support to a board.
See [Configuration Overview](index.md) for instructions on how to change these settings. See [Configuration Overview](index.md) for instructions on how to change these settings.
@ -52,11 +52,11 @@ The `*_START` settings only determine the initial underglow state. Any changes y
ZMK does not have any Devicetree properties of its own. See the Devicetree bindings for [Zephyr's LED strip drivers](https://github.com/zephyrproject-rtos/zephyr/tree/main/dts/bindings/led_strip). ZMK does not have any Devicetree properties of its own. See the Devicetree bindings for [Zephyr's LED strip drivers](https://github.com/zephyrproject-rtos/zephyr/tree/main/dts/bindings/led_strip).
See the [RGB underglow hardware integration page](../development/hardware-integration/lighting/underglow.md) for examples of the properties that must be set to enable underglow. See the [RGB underglow hardware integration page](../hardware-integration/lighting/underglow.md) for examples of the properties that must be set to enable underglow.
## Backlight ## Backlight
See the [backlight section](../features/lighting.md#backlight) in Lighting feature page for more details, and [hardware integration page](../development/hardware-integration/lighting/backlight.mdx) for adding backlight support to a board. See the [backlight section](../features/lighting.md#backlight) in Lighting feature page for more details, and [hardware integration page](../hardware-integration/lighting/backlight.mdx) for adding backlight support to a board.
See [Configuration Overview](index.md) for instructions on how to change these settings. See [Configuration Overview](index.md) for instructions on how to change these settings.
@ -90,4 +90,4 @@ See the Zephyr devicetree bindings for LED drivers:
- [gpio-leds](https://docs.zephyrproject.org/4.1.0/build/dts/api/bindings/led/gpio-leds.html) - [gpio-leds](https://docs.zephyrproject.org/4.1.0/build/dts/api/bindings/led/gpio-leds.html)
- [pwm-leds](https://docs.zephyrproject.org/4.1.0/build/dts/api/bindings/led/pwm-leds.html) - [pwm-leds](https://docs.zephyrproject.org/4.1.0/build/dts/api/bindings/led/pwm-leds.html)
See the [backlight hardware integration page](../development/hardware-integration/lighting/backlight.mdx) for examples of the properties that must be set to enable backlighting. See the [backlight hardware integration page](../hardware-integration/lighting/backlight.mdx) for examples of the properties that must be set to enable backlighting.

View file

@ -53,7 +53,7 @@ Additional properties can be set on child nodes, which allows changing the setti
## Input Split ## Input Split
Input splits are used for [pointing devices on split peripherals](../development/hardware-integration/pointing.mdx#listener-and-input-split-device). Input splits are used for [pointing devices on split peripherals](../hardware-integration/pointing.mdx#listener-and-input-split-device).
### Devicetree ### Devicetree

View file

@ -36,7 +36,7 @@ Definition file: [zmk/app/Kconfig](https://github.com/zmkfirmware/zmk/blob/main/
While regular ZMK builds will not cause any settings to be cleared upon flashing, flashing a build with `CONFIG_ZMK_SETTINGS_RESET_ON_START` enabled as documented above will cause the firmware to run a special procedure when the controller starts that clears the settings partition. While regular ZMK builds will not cause any settings to be cleared upon flashing, flashing a build with `CONFIG_ZMK_SETTINGS_RESET_ON_START` enabled as documented above will cause the firmware to run a special procedure when the controller starts that clears the settings partition.
For end users, it is recommended to use a special [shield](../development/hardware-integration/index.mdx#boards--shields) named `settings_reset` to build a new firmware file, then flash that firmware. For end users, it is recommended to use a special [shield](../hardware-integration/index.mdx#boards--shields) named `settings_reset` to build a new firmware file, then flash that firmware.
See example for building firmware using this shield in the [troubleshooting docs](../troubleshooting/connection-issues.mdx#building-a-reset-firmware). See example for building firmware using this shield in the [troubleshooting docs](../troubleshooting/connection-issues.mdx#building-a-reset-firmware).
In both cases, regular, non-reset firmware will need to be flashed afterwards for normal operation. In both cases, regular, non-reset firmware will need to be flashed afterwards for normal operation.

View file

@ -76,7 +76,7 @@ The following settings only apply when using wired split in polling mode:
### Wired Split ### 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](../development/hardware-integration/pinctrl.mdx#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](../development/hardware-integration/pinctrl.mdx#additional-examples) to configure the pins for your UART. 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](../hardware-integration/pinctrl.mdx#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](../hardware-integration/pinctrl.mdx#additional-examples) 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: 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:

View file

@ -11,6 +11,8 @@ This document outlines how to test your documentation changes locally and prepar
The documentation is written with [Docusaurus](https://docusaurus.io/). The ZMK source code has all of the necessary Docusaurus dependencies included, but referencing their documentation can be helpful at times. The documentation is written with [Docusaurus](https://docusaurus.io/). The ZMK source code has all of the necessary Docusaurus dependencies included, but referencing their documentation can be helpful at times.
The website is built using the latest LTS version of node, which is available at <https://nodejs.org/en/download/>.
The general process for updating the ZMK documentation is: The general process for updating the ZMK documentation is:
1. Update the documentation 1. Update the documentation
@ -18,14 +20,6 @@ The general process for updating the ZMK documentation is:
3. Ensure the sources are formatted properly and linted 3. Ensure the sources are formatted properly and linted
4. Create a Pull Request for review and inclusion into the ZMK sources 4. Create a Pull Request for review and inclusion into the ZMK sources
:::note
If you are working with the documentation from within VS Code+Docker please be aware the documentation will not be auto-generated when making changes while the server is running. You'll need to restart the server when saving changes to the documentation.
:::
:::note
You will need `Node.js` and `npm` installed to update the documentation. If you're using the ZMK dev container (Docker) the necessary dependencies are already installed. Otherwise, you must install these dependencies yourself. Since `Node.js` packages in Linux distributions tend to be outdated, it's recommended to install the current version from a repository like [NodeSource](https://github.com/nodesource/distributions) to avoid build errors.
:::
## Testing Documentation Updates Locally ## Testing Documentation Updates Locally
To verify documentation updates locally, follow the following procedure. The `npm` commands and first step will need to be run from a terminal. To verify documentation updates locally, follow the following procedure. The `npm` commands and first step will need to be run from a terminal.
@ -52,15 +46,9 @@ The check commands can be run with the following procedure in a terminal that's
3. Run `npm run lint` 3. Run `npm run lint`
4. Run `npm run build` 4. Run `npm run build`
:::danger
If any of the above steps throw an error, they need to be addressed and all of the checks re-run prior to submitting a pull request. If any of the above steps throw an error, they need to be addressed and all of the checks re-run prior to submitting a pull request.
:::
:::note The documentation uses American English spelling and grammar conventions. Title case is used for the first three heading levels, with sentence case used beyond that. Please make sure your changes conform to these conventions.
The documentation uses American English spelling and grammar conventions. Title case is used for the first three heading levels, with sentence case used beyond that.
Please make sure your changes conform to these conventions - prettier and lint are unfortunately unable to do this automatically.
:::
## Submitting a Pull Request ## Submitting a Pull Request

View file

@ -160,7 +160,7 @@ west build -b nice_nano -- -DSHIELD=vendor_shield -DZMK_EXTRA_MODULES="C:/Users/
### Building from `zmk-config` Folder ### Building from `zmk-config` Folder
Instead of building .uf2 files using the default keymap and config files, you Instead of building .uf2 files using the default keymap and config files, you
can build using files from your [`zmk-config` folder](../../user-setup.mdx#github-repo) can build using files from your [`zmk-config` folder](../../user-setup.mdx#config-repo-setup)
by adding `-DZMK_CONFIG="C:/the/absolute/path/config"` to your `west build` by adding `-DZMK_CONFIG="C:/the/absolute/path/config"` to your `west build`
command. **Notice that this path should point to the folder labeled `config` command. **Notice that this path should point to the folder labeled `config`
within your `zmk-config` folder.** within your `zmk-config` folder.**

View file

@ -12,9 +12,7 @@ sidebar_label: ZMK Module Creation
See also Zephyr's [page on modules](https://docs.zephyrproject.org/4.1.0/develop/modules.html). See also Zephyr's [page on modules](https://docs.zephyrproject.org/4.1.0/develop/modules.html).
:::tip For open source hardware designs, it's recommended to **not** include the hardware design files in the ZMK module itself, since the module will be fetched by users during build and having design files in the module would likely make the module unnecessarily large and slow to fetch.
For open source hardware designs, it can be convenient to use [Git submodules](https://github.blog/open-source/git/working-with-submodules/) to have the ZMK module also be a Git submodule of the repository hosting the hardware design.
:::
## Module Setup ## Module Setup
@ -133,15 +131,15 @@ Note that the `include` and `src` folders are not mandated by the module system,
Modules should expose all provided header files with an include path name beginning with the module-name, for example at `include/zmk_<type>_<description>/<header>.h`. Modules should expose all provided header files with an include path name beginning with the module-name, for example at `include/zmk_<type>_<description>/<header>.h`.
:::info :::info
If your module requires adding drivers to existing subsystems in modules, you will need to use the `zephyr_library_amend()` CMake command, which requires you to have a specific directory structure. See [here](https://github.com/zephyrproject-rtos/zephyr/blob/main/cmake/modules/extensions.cmake#L454) for the definition and some documentation in the comments, with an example [here](https://github.com/petejohanson/ec-support-zmk-module/tree/main/drivers/kscan). If your module requires adding drivers to existing subsystems in modules, you will need to use the `zephyr_library_amend()` CMake command, which requires you to have a specific directory structure. See [`zephyr/cmake/modules/extensions.cmake`](https://github.com/zephyrproject-rtos/zephyr/blob/main@%7B2025-Feb-15%7D/cmake/modules/extensions.cmake#L492) for the definition and some documentation in the comments, with an example in [`petejohanson/ec-support-zmk-module`](https://github.com/petejohanson/ec-support-zmk-module/tree/main/drivers/kscan).
::: :::
## Examples ## Examples
Below are some examples of modules for different types. Unless under the `zmkfirmware` project, these are not endorsed officially and may not follow our conventions perfectly. For such reason, the modules chosen to be presented here may change with time. Below are some examples of modules for different types. Unless under the `zmkfirmware` project, these are not endorsed officially and may not follow our conventions perfectly. For such reason, the modules chosen to be presented here may change with time.
- Keyboard: https://github.com/petejohanson/zmk-keyboards-katori - Keyboard: <https://github.com/petejohanson/zmk-keyboards-katori>
- Behavior: https://github.com/urob/zmk-leader-key - Behavior: <https://github.com/urob/zmk-leader-key>
- Driver: https://github.com/petejohanson/cirque-input-module - Driver: <https://github.com/petejohanson/cirque-input-module>
- Feature: https://github.com/joelspadin/zmk-locales - Feature: <https://github.com/joelspadin/zmk-locales>
- VFX: https://github.com/caksoylar/zmk-rgbled-widget - VFX: <https://github.com/caksoylar/zmk-rgbled-widget>

View file

@ -51,7 +51,7 @@ ZMK is still in its infancy, so theres a learning curve involved. But if you
ZMK uses the Zephyr concepts of "boards" and "shields" to refer to different parts of a keyboard build, that in turn get combined during a firmware build. ZMK uses the Zephyr concepts of "boards" and "shields" to refer to different parts of a keyboard build, that in turn get combined during a firmware build.
This provides the modularity to be able to use composite keyboards with different compatible controllers. This provides the modularity to be able to use composite keyboards with different compatible controllers.
Please see the [explainer on boards & shields](development/hardware-integration/index.mdx#boards--shields) for more details. Please see the [explainer on boards & shields](hardware-integration/index.mdx#boards--shields) for more details.
### Does ZMK support wired split? ### Does ZMK support wired split?
@ -63,7 +63,7 @@ The latency of ZMK is comparable to other firmware offerings. ZMK is equipped wi
### Any chance for 2.4GHz dongle implementation? ### Any chance for 2.4GHz dongle implementation?
At this time, there are no current plans to implement 2.4GHz dongle mode. This is because utilizing Nordic's proprietary 2.4GHz low level protocols requires use of the Nordic Connect SDK, which is licensed with a more restrictive license than ZMK's MIT license. However, it is possible to [create a dongle](development/hardware-integration/dongle.mdx) for your keyboard that runs ZMK and communicates between parts using BLE (with encryption). This results in a 3.75ms average theoretical latency from the protocol itself. At this time, there are no current plans to implement 2.4GHz dongle mode. This is because utilizing Nordic's proprietary 2.4GHz low level protocols requires use of the Nordic Connect SDK, which is licensed with a more restrictive license than ZMK's MIT license. However, it is possible to [create a dongle](hardware-integration/dongle.mdx) for your keyboard that runs ZMK and communicates between parts using BLE (with encryption). This results in a 3.75ms average theoretical latency from the protocol itself.
### What bootloader does ZMK use? ### What bootloader does ZMK use?

View file

@ -16,4 +16,4 @@ Windows may not properly ask the keyboard to notify it of changes in battery lev
## Adding a Battery Sensor to a Board ## Adding a Battery Sensor to a Board
If your keyboard is using one of the [boards supported in ZMK](../hardware.mdx) it will already be configured to sense and report battery levels. If your keyboard is using one of the [boards supported in ZMK](../hardware.mdx) it will already be configured to sense and report battery levels.
If you are using a custom board, see [battery sensing hardware integration page](../development/hardware-integration/battery.md) to add support. If you are using a custom board, see [battery sensing hardware integration page](../hardware-integration/battery.md) to add support.

View file

@ -41,4 +41,4 @@ Here, the left encoder is configured to control volume up and down while the rig
## Adding Encoder Support ## Adding Encoder Support
See the [Hardware Integration page for encoders](../development/hardware-integration/encoders.md) for instructions on adding them to your keyboard. See the [Hardware Integration page for encoders](../hardware-integration/encoders.md) for instructions on adding them to your keyboard.

View file

@ -54,14 +54,10 @@ For example, if you want the LED to be off when the indicator is active, 100% br
}; };
``` ```
:::note
If the LED is not configured to support brightness control, any value greater than 0 will result in maximum brightness. If the LED is not configured to support brightness control, any value greater than 0 will result in maximum brightness.
For most LEDs, you can enable PWM brightness control, though this will increase power usage slightly. See the [LED indicators hardware integration page](../development/hardware-integration/lighting/led-indicators.md) for details on configuring the LEDs. For most LEDs, you can enable PWM brightness control, though this will increase power usage slightly. See the [LED indicators hardware integration page](../hardware-integration/lighting/led-indicators.md) for details on configuring the LEDs.
:::
## Adding LED Indicator Support to a Keyboard ## Adding LED Indicator Support to a Keyboard
See the [LED indicators hardware integration page](../development/hardware-integration/lighting/led-indicators.md) for instructions to enable this feature on a keyboard. See the [LED indicators hardware integration page](../hardware-integration/lighting/led-indicators.md) for instructions to enable this feature on a keyboard.

View file

@ -11,7 +11,7 @@ Your keyboard likely uses only one type, depending on the type of LED hardware i
- [Backlight](#backlight) system controls parallel-connected, non-addressable, single color LEDs. - [Backlight](#backlight) system controls parallel-connected, non-addressable, single color LEDs.
These are found on keyboards that have a single color backlight that only allows for brightness control. These are found on keyboards that have a single color backlight that only allows for brightness control.
:::warning :::info
Although the naming of the systems might imply it, which system you use typically does _not_ depend on the physical location of the LEDs. Although the naming of the systems might imply it, which system you use typically does _not_ depend on the physical location of the LEDs.
Instead, you should use the one that supports the LED hardware type that your keyboard has, as described above. Instead, you should use the one that supports the LED hardware type that your keyboard has, as described above.
@ -73,7 +73,7 @@ See [RGB underglow configuration](../config/lighting.md#rgb-underglow).
### Adding RGB Underglow Support to a Keyboard ### Adding RGB Underglow Support to a Keyboard
See [RGB underglow hardware integration page](../development/hardware-integration/lighting/underglow.md) on adding underglow support to a ZMK keyboard. See [RGB underglow hardware integration page](../hardware-integration/lighting/underglow.md) on adding underglow support to a ZMK keyboard.
## Backlight ## Backlight
@ -100,4 +100,4 @@ See [backlight configuration](../config/lighting.md#backlight) for details.
### Adding Backlight to a Board or a Shield ### Adding Backlight to a Board or a Shield
See [backlight hardware integration page](../development/hardware-integration/lighting/backlight.mdx) for information on adding backlight support to a ZMK keyboard. See [backlight hardware integration page](../hardware-integration/lighting/backlight.mdx) for information on adding backlight support to a ZMK keyboard.

View file

@ -44,13 +44,9 @@ It is recommended to add the `wakeup-source` property to `kscan` devices even if
The soft off feature is used to turn the keyboard on and off explicitly, rather than through a timeout like the deep sleep feature. Depending on the keyboard, this may be through a dedicated on/off push button defined in hardware, or merely through an additional binding in the keymap to turn the device off and an existing reset button to turn the device back on. The soft off feature is used to turn the keyboard on and off explicitly, rather than through a timeout like the deep sleep feature. Depending on the keyboard, this may be through a dedicated on/off push button defined in hardware, or merely through an additional binding in the keymap to turn the device off and an existing reset button to turn the device back on.
The feature is intended as an alternative to using a hardware switch to physically cut power from the battery to the keyboard. This can be useful for existing PCBs not designed for wireless that don't have a power switch, or for new designs that favor a push button on/off like found on other devices. It yields power savings comparable to the deep sleep state.
:::note
The device enters the same software power-off state as in deep sleep, but is significantly more restrictive in the sources which can wake it. Power is _not_ technically removed from the entire system, unlike a hardware switch. The device enters the same software power-off state as in deep sleep, but is significantly more restrictive in the sources which can wake it. Power is _not_ technically removed from the entire system, unlike a hardware switch.
::: The feature is intended as an alternative to using a hardware switch to physically cut power from the battery to the keyboard. This can be useful for existing PCBs not designed for wireless that don't have a power switch, or for new designs that favor a push button on/off like found on other devices. It yields power savings comparable to the deep sleep state.
A device can be put in the soft off state by: A device can be put in the soft off state by:
@ -78,4 +74,4 @@ You can then wake up the keyboard by pressing the reset button once, and repeati
### Adding Soft Off to a Keyboard ### Adding Soft Off to a Keyboard
Please refer to the [corresponding page under hardware integration](../development/hardware-integration/soft-off-setup.mdx) for details. Please refer to the [corresponding page under hardware integration](../hardware-integration/soft-off-setup.mdx) for details.

View file

@ -24,7 +24,7 @@ See the [mouse emulation behaviors](../keymaps/behaviors/mouse-emulation.md) for
There are a few drivers available for supporting physical pointing devices integrated into a ZMK powered device. When doing so, you can use your device as both a keyboard and a pointing device with any connected hosts. The functionality can be extended further, e.g. slow mode, scroll mode, temporary mouse layers, etc. by configuring [input processors](#input-processors) linked to the physical pointing device. There are a few drivers available for supporting physical pointing devices integrated into a ZMK powered device. When doing so, you can use your device as both a keyboard and a pointing device with any connected hosts. The functionality can be extended further, e.g. slow mode, scroll mode, temporary mouse layers, etc. by configuring [input processors](#input-processors) linked to the physical pointing device.
For more information, refer to the [pointer hardware integration](../development/hardware-integration/pointing.mdx) documentation. For more information, refer to the [pointer hardware integration](../hardware-integration/pointing.mdx) documentation.
## Input Processors ## Input Processors

View file

@ -8,7 +8,7 @@ ZMK supports setups where a keyboard is split into two or more physical parts (a
## Central and Peripheral Roles ## Central and Peripheral Roles
In split keyboards running ZMK, one part is assigned the "central" role which receives key position and sensor events from the other parts that are called "peripherals." In split keyboards running ZMK, one part is assigned the "central" role which receives key position and sensor events from the other parts that are called "peripherals."
The central runs the necessary keymap logic to convert received events into HID events such as keycodes and then communicates with the connected host devices, e.g. over USB or bluetooth. If the keyboard makes use of a [dongle](../development/hardware-integration/dongle.mdx), then the dongle takes on the role of central. The central runs the necessary keymap logic to convert received events into HID events such as keycodes and then communicates with the connected host devices, e.g. over USB or bluetooth. If the keyboard makes use of a [dongle](../hardware-integration/dongle.mdx), then the dongle takes on the role of central.
The internal keyboard state (like active layers) is handled exclusively by the central. The internal keyboard state (like active layers) is handled exclusively by the central.
Peripherals _cannot_ communicate with host devices on their own, since they can only communicate with the central. Peripherals _cannot_ communicate with host devices on their own, since they can only communicate with the central.
@ -23,7 +23,7 @@ You can refer to the [power profiler](/power-profiler) to see battery life estim
### Configuration ### Configuration
The [new shield guide](../development/hardware-integration/new-shield.mdx) details how to define a split keyboard shield with two parts, enabling the split feature and setting up the necessary roles for each part. The [new shield guide](../hardware-integration/new-shield.mdx) details how to define a split keyboard shield with two parts, enabling the split feature and setting up the necessary roles for each part.
Also see the reference section on [split keyboards configuration](../config/split.md) where the relevant symbols include `CONFIG_ZMK_SPLIT` that enables the feature, `CONFIG_ZMK_SPLIT_ROLE_CENTRAL` which sets the central role and `CONFIG_ZMK_SPLIT_BLE_CENTRAL_PERIPHERALS` that sets the number of peripherals. Also see the reference section on [split keyboards configuration](../config/split.md) where the relevant symbols include `CONFIG_ZMK_SPLIT` that enables the feature, `CONFIG_ZMK_SPLIT_ROLE_CENTRAL` which sets the central role and `CONFIG_ZMK_SPLIT_BLE_CENTRAL_PERIPHERALS` that sets the number of peripherals.
@ -44,7 +44,7 @@ Many popular cables, in particular, TRRS/TRS cables, can cause irreparable damag
### Bluetooth ### Bluetooth
[Bluetooth](./bluetooth.md) is the most well tested and flexible transport available in ZMK. Using Bluetooth, a central can connect to multiple peripherals, enabling the use of a [dongle](../development/hardware-integration/dongle.mdx) to improve battery life, or allowing for multi-part split keyboards. [Bluetooth](./bluetooth.md) is the most well tested and flexible transport available in ZMK. Using Bluetooth, a central can connect to multiple peripherals, enabling the use of a [dongle](../hardware-integration/dongle.mdx) to improve battery life, or allowing for multi-part split keyboards.
This transport will be enabled for designs that set `CONFIG_ZMK_SPLIT=y` and have `CONFIG_ZMK_BLE=y` set by a supported MCU/controller. This transport will be enabled for designs that set `CONFIG_ZMK_SPLIT=y` and have `CONFIG_ZMK_BLE=y` set by a supported MCU/controller.

View file

@ -6,7 +6,7 @@ ZMK Studio provides runtime update functionality to ZMK powered devices, allowin
:::info :::info
To use ZMK Studio, a keyboard needs to be [configured appropriately](#adding-zmk-studio-support-to-a-keyboard). ZMK has updated some, but not all, of its in-tree keyboards for use with ZMK Studio, the list of which can be found [here](/blog/2024/11/11/zmk-studio-mvp-ga). If your keyboard is supported by an external module/config, check with the maintainer to see if support has been added. To use ZMK Studio, a keyboard needs to be [configured appropriately](#adding-zmk-studio-support-to-a-keyboard). ZMK has updated some, but not all, of its in-tree keyboards for use with ZMK Studio, the list of which can be found in the [ZMK Studio blog post](/blog/2024/11/11/zmk-studio-mvp-ga). If your keyboard is supported by an external module/config, check with the maintainer to see if support has been added.
::: :::
@ -54,7 +54,7 @@ Generally, if you intend to use ZMK Studio, then you should not make any further
## Accessing ZMK Studio ## Accessing ZMK Studio
You can use ZMK Studio with Chrome/Edge at https://zmk.studio/. You can use ZMK Studio with Chrome/Edge at <https://zmk.studio/>.
To use the native app for Linux, macOS, or Windows, visit the [download page](https://zmk.studio/download). To use the native app for Linux, macOS, or Windows, visit the [download page](https://zmk.studio/download).
@ -172,12 +172,12 @@ The reserved layers will be ignored during regular ZMK builds but will become av
To allow ZMK Studio to be used with a keyboard, the keyboard will need to have a physical layout with the `keys` property defined. The keyboard should also **not** have a `chosen` `zmk,matrix-transform`. Relevant information can be found in: To allow ZMK Studio to be used with a keyboard, the keyboard will need to have a physical layout with the `keys` property defined. The keyboard should also **not** have a `chosen` `zmk,matrix-transform`. Relevant information can be found in:
- The [dedicated page on physical layouts](../development/hardware-integration/physical-layouts.md), informing you how to define one - The [dedicated page on physical layouts](../hardware-integration/physical-layouts.md), informing you how to define one
- The [new shield guide](../development/hardware-integration/new-shield.mdx), informing you how to select a physical layout once defined - The [new shield guide](../hardware-integration/new-shield.mdx), informing you how to select a physical layout once defined
- The corresponding [configuration page](../config/layout.md#physical-layout), for reference - The corresponding [configuration page](../config/layout.md#physical-layout), for reference
To use the `studio-rpc-usb-uart` snippet, the keyboard also needs to be configured to allow CDC-ACM console snippets (this is also used for [USB logging](../development/usb-logging.mdx)). If your keyboard is a composite keyboard, consisting of an in-tree board and a shield, then you can skip this step as the board will already be configured properly. Relevant information on that can be found [in the Zephyr documentation](https://docs.zephyrproject.org/4.1.0/snippets/cdc-acm-console/README.html). To use the `studio-rpc-usb-uart` snippet, the keyboard also needs to be configured to allow CDC-ACM console snippets (this is also used for [USB logging](../development/usb-logging.mdx)). If your keyboard is a composite keyboard, consisting of an in-tree board and a shield, then you can skip this step as the board will already be configured properly. Relevant information on that can be found [in the Zephyr documentation](https://docs.zephyrproject.org/4.1.0/snippets/cdc-acm-console/README.html).
Firmware with ZMK Studio enabled require significantly more RAM. Some MCUs, such as the STM32F072 series, will require fine tuning of various settings in order to reduce the RAM consumption enough for a Studio enabled build to fit. Firmware with ZMK Studio enabled require significantly more RAM. Some MCUs, such as the STM32F072 series, will require fine tuning of various settings in order to reduce the RAM consumption enough for a Studio enabled build to fit.
Finally, once you have successfully built and tested firmware with ZMK Studio enabled, add the `studio` flag to your keyboard's [metadata](../development/hardware-integration/hardware-metadata-files#features). Finally, once you have successfully built and tested firmware with ZMK Studio enabled, add the `studio` flag to your keyboard's [metadata](../hardware-integration/hardware-metadata-files#features).

View file

@ -3,7 +3,7 @@ title: Battery Sensing
sidebar_label: Battery Sensing sidebar_label: Battery Sensing
--- ---
If your keyboard is using one of the [boards supported in ZMK](../../hardware.mdx) it will already be configured to [sense and report battery levels](../../features/battery.md). If your keyboard is using one of the [boards supported in ZMK](../hardware.mdx) it will already be configured to [sense and report battery levels](../features/battery.md).
Below instructions are only intended for users defining and using a custom board. Below instructions are only intended for users defining and using a custom board.
To enable a battery sensor on a new board, add the driver for the sensor to your board's `.dts` file. ZMK provides two drivers for estimating the battery level using its voltage: To enable a battery sensor on a new board, add the driver for the sensor to your board's `.dts` file. ZMK provides two drivers for estimating the battery level using its voltage:
@ -11,7 +11,7 @@ To enable a battery sensor on a new board, add the driver for the sensor to your
- `zmk,battery-voltage-divider`: Reads the voltage on an analog input pin. - `zmk,battery-voltage-divider`: Reads the voltage on an analog input pin.
- `zmk,battery-nrf-vddh`: Reads the power supply voltage on a Nordic nRF52's VDDH pin. - `zmk,battery-nrf-vddh`: Reads the power supply voltage on a Nordic nRF52's VDDH pin.
See the [battery level configuration page](../../config/battery.md) for the configuration supported by each driver provided by ZMK. See the [battery level configuration page](../config/battery.md) for the configuration supported by each driver provided by ZMK.
Zephyr also provides some drivers for fuel gauge ICs such as the TI bq274xx series and Maxim MAX17xxx series. If you use a battery sensor that does not have an existing driver, you will need to write a new driver that supports the `SENSOR_CHAN_GAUGE_STATE_OF_CHARGE` sensor channel and contribute it to Zephyr or ZMK. Zephyr also provides some drivers for fuel gauge ICs such as the TI bq274xx series and Maxim MAX17xxx series. If you use a battery sensor that does not have an existing driver, you will need to write a new driver that supports the `SENSOR_CHAN_GAUGE_STATE_OF_CHARGE` sensor channel and contribute it to Zephyr or ZMK.

View file

@ -7,7 +7,7 @@ import BaseConfig from "./_base-config.md";
The RP2040/RP2350 Bootloader is a [jump-to type bootloader](./index.mdx#jump-to-bootloaders), with some extra setup used to integrate with it. The RP2040/RP2350 Bootloader is a [jump-to type bootloader](./index.mdx#jump-to-bootloaders), with some extra setup used to integrate with it.
By default, when integrating this bootloader, a ["double tap reset to enter the bootloader"](../../../config/system.md#double-tap-to-bootloader) feature will be enabled, to help with designs that do not easily expose a BOOTSEL pin. By default, when integrating this bootloader, a ["double tap reset to enter the bootloader"](../../config/bootloader.md#double-tap-to-bootloader) feature will be enabled, to help with designs that do not easily expose a BOOTSEL pin.
<BaseConfig /> <BaseConfig />

View file

@ -8,7 +8,7 @@ import BaseConfig from "./_base-config.md";
The [STM32 ROM Bootloader](https://www.st.com/resource/en/application_note/an2606-stm32-microcontroller-system-memory-boot-mode-stmicroelectronics.pdf) is a [jump-to type bootloader](./index.mdx#jump-to-bootloaders), with some extra setup used to integrate with it. The [STM32 ROM Bootloader](https://www.st.com/resource/en/application_note/an2606-stm32-microcontroller-system-memory-boot-mode-stmicroelectronics.pdf) is a [jump-to type bootloader](./index.mdx#jump-to-bootloaders), with some extra setup used to integrate with it.
By default, when integrating this bootloader, a ["double tap reset to enter the bootloader"](../../../config/system.md#double-tap-to-bootloader) feature will be enabled, to help with designs that do not easily expose a BOOT pin. By default, when integrating this bootloader, a ["double tap reset to enter the bootloader"](../../config/bootloader.md#double-tap-to-bootloader) feature will be enabled, to help with designs that do not easily expose a BOOT pin.
<BaseConfig /> <BaseConfig />

View file

@ -6,7 +6,7 @@ sidebar_label: Keyboard Dongle
import Tabs from "@theme/Tabs"; import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem"; import TabItem from "@theme/TabItem";
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](../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:
Benefits: Benefits:
@ -18,7 +18,7 @@ Disadvantages:
- An extra [board](index.mdx#what-is-a-board) is needed (any BLE-capable board that ZMK supports will work). - 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. - The keyboard becomes unusable without the dongle.
Depending on how the dongle is used, there are some additional [latency considerations](../../features/split-keyboards.md#latency-considerations) to keep in mind. 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. 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: 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:
@ -119,7 +119,7 @@ You will now need to find and copy your keyboard's matrix transform into the `my
#### Matrix transform #### Matrix transform
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";`. 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: This should look something like this:
```dts ```dts
@ -141,7 +141,7 @@ Make a note of the label that the transform has, it will be used later. In the e
#### Physical layout #### Physical layout
A full physical layout is necessary to allow your dongle to be used with [ZMK Studio](../../features/studio.md). 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. 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.
<Tabs <Tabs
@ -299,16 +299,16 @@ include:
cmake-args: -DCONFIG_ZMK_SPLIT=y -DCONFIG_ZMK_SPLIT_ROLE_CENTRAL=n cmake-args: -DCONFIG_ZMK_SPLIT=y -DCONFIG_ZMK_SPLIT_ROLE_CENTRAL=n
``` ```
You can then flash the firmware to your device as detailed in our [user setup](../../user-setup.mdx#installing-the-firmware) and [split keyboard](../../features/split-keyboards.md#building-and-flashing-firmware) pages. 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 :::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 ensure they can pair to each other.
::: :::
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. 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`). 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. [^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](../local-toolchain/build-flash.mdx#cmake-arguments). [^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).

View file

@ -18,12 +18,12 @@ In your configuration file you will need to add the following lines so that the
These should be commented by default for encoders that are optional/can be swapped with switches, but can be uncommented if encoders are part of the default design. These should be commented by default for encoders that are optional/can be swapped with switches, but can be uncommented if encoders are part of the default design.
:::note :::note
If building locally for split boards, you may need to add these lines to the specific half's configuration file as well as the combined configuration file, see the [configuration overview](../../config/index.md) for details. If building locally for split boards, you may need to add these lines to the specific half's configuration file as well as the combined configuration file, see the [configuration overview](../config/index.md) for details.
::: :::
## Devicetree File ## Devicetree File
In your devicetree file you will need to define each sensor with their properties. For split keyboards, do this in the .dtsi file that is shared by all parts; otherwise do it in the .dts (for boards) or .overlay (shields) file, see [configuration overview](../../config/index.md#devicetree-files) for details. Add the following lines: In your devicetree file you will need to define each sensor with their properties. For split keyboards, do this in the .dtsi file that is shared by all parts; otherwise do it in the .dts (for boards) or .overlay (shields) file, see [configuration overview](../config/index.md#devicetree-files) for details. Add the following lines:
```dts ```dts
left_encoder: encoder_left { left_encoder: encoder_left {
@ -53,7 +53,7 @@ Once you have defined the encoder sensors, you will have to add them to the list
In this example, a `left_encoder` and `right_encoder` are both added. Additional encoders can be added with spaces separating each, and the order they are added here determines the order in which you define their behavior in your keymap. In this example, a `left_encoder` and `right_encoder` are both added. Additional encoders can be added with spaces separating each, and the order they are added here determines the order in which you define their behavior in your keymap.
In addition, a default value for the number of times the sensors trigger the bound behavior per full rotation is set via the `triggers-per-rotation` property. See [Encoders Config](../../config/encoders.md#devicetree) for more details. In addition, a default value for the number of times the sensors trigger the bound behavior per full rotation is set via the `triggers-per-rotation` property. See [Encoders Config](../config/encoders.md#devicetree) for more details.
Add the following lines to the .dts/.overlay file that contains the encoder to enable it: Add the following lines to the .dts/.overlay file that contains the encoder to enable it:
@ -73,4 +73,4 @@ Add the following line to your keymap file to add default encoder behavior bindi
sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>;
``` ```
Add additional bindings as necessary to match the default number of encoders on your board. See the [Encoders](../../features/encoders.md) and [Keymaps](../../keymaps/index.mdx) documentation pages for more details. Add additional bindings as necessary to match the default number of encoders on your board. See the [Encoders](../features/encoders.md) and [Keymaps](../keymaps/index.mdx) documentation pages for more details.

View file

@ -95,7 +95,7 @@ Boards and shields should document the sets of hardware features found on them u
- `encoder` - Indicates the hardware contains one or more rotary encoders. - `encoder` - Indicates the hardware contains one or more rotary encoders.
- `underglow` - Indicates the hardware includes underglow LEDs. - `underglow` - Indicates the hardware includes underglow LEDs.
- `backlight` - Indicates the hardware includes backlight LEDs. - `backlight` - Indicates the hardware includes backlight LEDs.
- `studio` - Indicates the keyboard is ready to use with [ZMK Studio](../../features/studio.md). - `studio` - Indicates the keyboard is ready to use with [ZMK Studio](../features/studio.md).
- `pointer` (future) - Used to indicate the hardware includes one or more pointer inputs, e.g. joystick, touchpad, or trackpoint. - `pointer` (future) - Used to indicate the hardware includes one or more pointer inputs, e.g. joystick, touchpad, or trackpoint.
### Siblings ### Siblings

View file

@ -1,8 +1,8 @@
### KScan sideband behavior ### KScan sideband behavior
The kscan sideband behavior driver will be used to trigger the [soft off behavior](../../../keymaps/behaviors/soft-off.md) "out of band" from the normal keymap processing. To do so, it will decorate/wrap an underlying kscan driver. The kscan sideband behavior driver will be used to trigger the [soft off behavior](../../keymaps/behaviors/soft-off.md) "out of band" from the normal keymap processing. To do so, it will decorate/wrap an underlying kscan driver.
With a simple direct pin setup, the [direct kscan](../../../config/kscan.md) driver can be used with a [GPIO key](#gpio-key), to make a small "side matrix": With a simple direct pin setup, the [direct kscan](../../config/kscan.md) driver can be used with a [GPIO key](#gpio-key), to make a small "side matrix":
```dts ```dts
/ { / {
@ -34,4 +34,4 @@ With that in place, the kscan sideband behavior will wrap the new driver:
}; };
``` ```
As the kscan used only has a single key, both column and row are set to 0. The properties of the `kscan-sideband-behaviors` node can be found in the [appropriate configuration section](../../../config/kscan.md#kscan-sideband-behavior-driver). As the kscan used only has a single key, both column and row are set to 0. The properties of the `kscan-sideband-behaviors` node can be found in the [appropriate configuration section](../../config/kscan.md#kscan-sideband-behavior-driver).

View file

@ -1,6 +1,6 @@
### KScan sideband behavior ### KScan sideband behavior
The kscan sideband behavior driver will be used to trigger the [soft off behavior](../../../keymaps/behaviors/soft-off.md) "out of band" from the normal keymap processing. To do so, it will decorate/wrap an underlying kscan driver. The kscan sideband behavior driver will be used to trigger the [soft off behavior](../../keymaps/behaviors/soft-off.md) "out of band" from the normal keymap processing. To do so, it will decorate/wrap an underlying kscan driver.
For the matrix-integrated approach you will supplement the existing kscan matrix by adding the additional pin as another entry in For the matrix-integrated approach you will supplement the existing kscan matrix by adding the additional pin as another entry in
the `row-gpios`/`col-gpios` for whichever pins are used to read the matrix state. This approach requires a matrix transform to be present. As an example, consider the following existing kscan matrix: the `row-gpios`/`col-gpios` for whichever pins are used to read the matrix state. This approach requires a matrix transform to be present. As an example, consider the following existing kscan matrix:
@ -63,4 +63,4 @@ With that in place, you would decorate the kscan driver:
}; };
``` ```
Critically, the `column` and `row` values would correspond to the location of the added entry. The properties of the `kscan-sideband-behaviors` node can be found in the [appropriate configuration section](../../../config/kscan.md#kscan-sideband-behavior-driver). Critically, the `column` and `row` values would correspond to the location of the added entry. The properties of the `kscan-sideband-behaviors` node can be found in the [appropriate configuration section](../../config/kscan.md#kscan-sideband-behavior-driver).

View file

@ -1,6 +1,6 @@
### KScan sideband behavior ### KScan sideband behavior
With a simple direct pin setup, the [direct kscan](../../../config/kscan.md) driver can be used with a [GPIO key](#gpio-key), to make a small "side matrix": With a simple direct pin setup, the [direct kscan](../../config/kscan.md) driver can be used with a [GPIO key](#gpio-key), to make a small "side matrix":
```dts ```dts
/ { / {
@ -25,4 +25,4 @@ The kscan sideband behavior needs to wrap the new driver to enable it:
}; };
``` ```
The properties of the `kscan-sideband-behaviors` node can be found in the [appropriate configuration section](../../../config/kscan.md#kscan-sideband-behavior-driver). The properties of the `kscan-sideband-behaviors` node can be found in the [appropriate configuration section](../../config/kscan.md#kscan-sideband-behavior-driver).

View file

@ -1,6 +1,6 @@
### Soft off behavior instance ### Soft off behavior instance
Behind the scenes, a hardware dedicated GPIO pin utilizes the [soft off behavior](../../../keymaps/behaviors/soft-off.md) to trigger entering the soft-off state. To use said behavior outside of a keymap, add an instance of the behavior to your `.overlay`/`.dts` file: Behind the scenes, a hardware dedicated GPIO pin utilizes the [soft off behavior](../../keymaps/behaviors/soft-off.md) to trigger entering the soft-off state. To use said behavior outside of a keymap, add an instance of the behavior to your `.overlay`/`.dts` file:
```dts ```dts
/ { / {

View file

@ -13,5 +13,5 @@ We need to add another device which will be enabled only when the keyboard is go
}; };
``` ```
The properties for the `gpio-key-wakeup-trigger` node can be found in the [appropriate configuration section](../../../config/power.md#gpio-key-wakeup-trigger). The properties for the `gpio-key-wakeup-trigger` node can be found in the [appropriate configuration section](../../config/power.md#gpio-key-wakeup-trigger).
In particular, note the `extra-gpios` property containing the MCU output pins of any keys used to wake the keyboard (for a `col2row` matrix, these are your columns). In particular, note the `extra-gpios` property containing the MCU output pins of any keys used to wake the keyboard (for a `col2row` matrix, these are your columns).

View file

@ -12,10 +12,10 @@ Please see pages in the sidebar for guides and reference that describe different
The foundational elements needed to get a specific keyboard working with ZMK can be broken down into: The foundational elements needed to get a specific keyboard working with ZMK can be broken down into:
- A [physical layout](physical-layouts.md) that describes the electrical and physical structure of the keyboard, referring to: - A [physical layout](physical-layouts.md) that describes the electrical and physical structure of the keyboard, referring to:
- A [kscan driver](../../config/kscan.md), which most frequently uses `compatible = "zmk,kscan-gpio-matrix"` for GPIO matrix based keyboards, or `compatible = "zmk,kscan-gpio-direct"` for direct wires. - A [kscan driver](../config/kscan.md), which most frequently uses `compatible = "zmk,kscan-gpio-matrix"` for GPIO matrix based keyboards, or `compatible = "zmk,kscan-gpio-direct"` for direct wires.
- A [matrix transform](../../config/layout.md), which defines how the kscan row/column events are translated into logical "key positions". - A [matrix transform](../config/layout.md), which defines how the kscan row/column events are translated into logical "key positions".
- An [optional description](physical-layouts.md#optional-keys-property) of physical key positions and sizes, in order to visualize the keyboard accurately in [ZMK Studio](../../features/studio.md). - An [optional description](physical-layouts.md#optional-keys-property) of physical key positions and sizes, in order to visualize the keyboard accurately in [ZMK Studio](../features/studio.md).
- A [keymap](../../keymaps/index.mdx), which binds each key position to a behavior, e.g. key press, mod-tap, momentary layer, in a set of layers. - A [keymap](../keymaps/index.mdx), which binds each key position to a behavior, e.g. key press, mod-tap, momentary layer, in a set of layers.
- Other, optional configuration items to support features such as encoders or lighting systems. - Other, optional configuration items to support features such as encoders or lighting systems.
These core architectural elements are defined per-keyboard, and _where_ they are defined depends on the specifics of how that keyboard is structured. These core architectural elements are defined per-keyboard, and _where_ they are defined depends on the specifics of how that keyboard is structured.
@ -41,7 +41,7 @@ The shield is usually the big PCB containing all the keys.
### Why not just "keyboard"? ### Why not just "keyboard"?
["Composite" keyboards](../../hardware.mdx#composite) are keyboards which use a separate small PCB MCU module for its "brains". ["Composite" keyboards](../hardware.mdx#composite) are keyboards which use a separate small PCB MCU module for its "brains".
In such keyboards, the [shield](#what-is-a-shield) is a brainless shell containing all the keys, RGB LEDs, encoders etc. In such keyboards, the [shield](#what-is-a-shield) is a brainless shell containing all the keys, RGB LEDs, encoders etc.
It typically maps all of these features to a standard pin footprint, such as the Pro Micro pinout. It typically maps all of these features to a standard pin footprint, such as the Pro Micro pinout.
@ -52,7 +52,7 @@ But each board comes with its own features (MCU, flash, BLE, etc.) which must al
Therefore in ZMK, board and shield are considered two different (but related) entities so that it is easier to mix and match them, and they are combined during a ZMK build. Therefore in ZMK, board and shield are considered two different (but related) entities so that it is easier to mix and match them, and they are combined during a ZMK build.
This provides the modularity to be able to use composite keyboards with different compatible controllers. This provides the modularity to be able to use composite keyboards with different compatible controllers.
Note that ["self-contained" keyboards](../../hardware.mdx#onboard) only have a single PCB which includes the "brains" (MCU) onboard. Note that ["self-contained" keyboards](../hardware.mdx#onboard) only have a single PCB which includes the "brains" (MCU) onboard.
In ZMK, these have no shield, only a board. In ZMK, these have no shield, only a board.
## Organization Overview ## Organization Overview
@ -67,11 +67,11 @@ values={[
<TabItem value="self-contained"> <TabItem value="self-contained">
For a [self-contained keyboard](../../hardware.mdx#onboard) that includes the microprocessor, all of the above architecture components are included in the Zephyr _board_ definition and no shield is defined. For a [self-contained keyboard](../hardware.mdx#onboard) that includes the microprocessor, all of the above architecture components are included in the Zephyr _board_ definition and no shield is defined.
You can see an example for the [Planck V6](https://github.com/zmkfirmware/zmk/tree/main/app/boards/olkb/planck) board directory. You can see an example for the [Planck V6](https://github.com/zmkfirmware/zmk/tree/main/app/boards/olkb/planck) board directory.
With this type of keyboard, the full ZMK definition for the keyboard exists in the `<board_root>/boards/<vendor or designer>/<keyboard_name>` directory where `<board_root>` is `zmk/app` or a [module](../../features/modules.mdx) root, e.g. `zmk/app/boards/olkb/planck/`. With this type of keyboard, the full ZMK definition for the keyboard exists in the `<board_root>/boards/<vendor or designer>/<keyboard_name>` directory where `<board_root>` is `zmk/app` or a [module](../features/modules.mdx) root, e.g. `zmk/app/boards/olkb/planck/`.
In that directory you'll have the following files, where there can be multiples of files with `<board_name>`s, corresponding to each keyboard part for [split keyboards](../../features/split-keyboards.md): In that directory you'll have the following files, where there can be multiples of files with `<board_name>`s, corresponding to each keyboard part for [split keyboards](../features/split-keyboards.md):
``` ```
<keyboard_name> <keyboard_name>
@ -89,14 +89,14 @@ These files include [base Kconfig files](https://docs.zephyrproject.org/4.1.0/bu
- A `Kconfig.<board_name>` file that defines the toplevel [Kconfig](https://docs.zephyrproject.org/4.1.0/build/kconfig/index.html) items for the board, including selecting the corresponding SoC Kconfig setting. - A `Kconfig.<board_name>` file that defines the toplevel [Kconfig](https://docs.zephyrproject.org/4.1.0/build/kconfig/index.html) items for the board, including selecting the corresponding SoC Kconfig setting.
- A `Kconfig.defconfig` file that sets some initial defaults when building this keyboard. This usually includes: - A `Kconfig.defconfig` file that sets some initial defaults when building this keyboard. This usually includes:
- Setting [`ZMK_KEYBOARD_NAME`](../../config/system.md#general) to a value, for the product name to be used for USB/BLE info - Setting [`ZMK_KEYBOARD_NAME`](../config/system.md#general) to a value, for the product name to be used for USB/BLE info
[Configuration files](../../config/index.md#kconfig-files) that set the visible Kconfig symbols: [Configuration files](../config/index.md#kconfig-files) that set the visible Kconfig symbols:
- A `<board_name>_defconfig` file that forces specific Kconfig settings that are specific to this hardware configuration. - A `<board_name>_defconfig` file that forces specific Kconfig settings that are specific to this hardware configuration.
These tend to be settings enabling various drivers or features, e.g. GPIO, USB support, or memory settings for ZMK Studio. These tend to be settings enabling various drivers or features, e.g. GPIO, USB support, or memory settings for ZMK Studio.
[Devicetree files](../../config/index.md#devicetree-files): [Devicetree files](../config/index.md#devicetree-files):
- `<board_name>.dts` which contains all the devicetree definitions[^1], including but not limited to: - `<board_name>.dts` which contains all the devicetree definitions[^1], including but not limited to:
- An `#include` line that pulls in the specific microprocessor that is used, e.g. `#include <st/f3/stm32f303Xc.dtsi>`, - An `#include` line that pulls in the specific microprocessor that is used, e.g. `#include <st/f3/stm32f303Xc.dtsi>`,
@ -120,11 +120,11 @@ See also our [new board guide](new-board.md) for information on creating a ZMK-c
</TabItem> </TabItem>
<TabItem value="composite"> <TabItem value="composite">
Keyboards that require an add-on board to operate are [composite keyboards](../../hardware.mdx#composite), where the ZMK integration pieces are placed in the _shield_ definition for that keyboard. Keyboards that require an add-on board to operate are [composite keyboards](../hardware.mdx#composite), where the ZMK integration pieces are placed in the _shield_ definition for that keyboard.
This allows users to swap in different boards that use the same interconnect (e.g. Pro Micro RP2040, or nice!nano) and build a firmware the matches their actual combination of physical components. This allows users to swap in different boards that use the same interconnect (e.g. Pro Micro RP2040, or nice!nano) and build a firmware the matches their actual combination of physical components.
With this type of keyboard, the partial definition for the keyboard exists in the `<board_root>/boards/shields/<keyboard_name>` directory where `<board_root>` is `zmk/app` or a [module](../../features/modules.mdx) root, e.g. `zmk/app/boards/shields/clueboard_california/`. With this type of keyboard, the partial definition for the keyboard exists in the `<board_root>/boards/shields/<keyboard_name>` directory where `<board_root>` is `zmk/app` or a [module](../features/modules.mdx) root, e.g. `zmk/app/boards/shields/clueboard_california/`.
In that directory, you'll have the following files, where there can be multiple `<shield_name>`s, corresponding to each keyboard part for [split keyboards](../../features/split-keyboards.md): In that directory, you'll have the following files, where there can be multiple `<shield_name>`s, corresponding to each keyboard part for [split keyboards](../features/split-keyboards.md):
``` ```
<keyboard_name> <keyboard_name>
@ -140,7 +140,7 @@ These files include [base Kconfig files](new-shield.mdx#base-kconfig-files):
- A `Kconfig.shield` that defines the toplevel Kconfig value for the shield, which uses a supplied utility to function to default the value based on the shield list, e.g. `def_bool $(shields_list_contains,clueboard_california)`. - A `Kconfig.shield` that defines the toplevel Kconfig value for the shield, which uses a supplied utility to function to default the value based on the shield list, e.g. `def_bool $(shields_list_contains,clueboard_california)`.
- A `Kconfig.defconfig` file to set default values for settings like `ZMK_KEYBOARD_NAME` - A `Kconfig.defconfig` file to set default values for settings like `ZMK_KEYBOARD_NAME`
[Devicetree files](../../config/index.md#devicetree-files): [Devicetree files](../config/index.md#devicetree-files):
- A `<shield_name>.overlay` file which is a devicetree overlay file[^1], containing definitions including but not limited to: - A `<shield_name>.overlay` file which is a devicetree overlay file[^1], containing definitions including but not limited to:
- Kscan, matrix transform and physical layout devicetree nodes as described above, where the kscan node uses the interconnect [nexus node](https://docs.zephyrproject.org/4.1.0/hardware/porting/shields.html#gpio-nexus-nodes) aliases such as `&pro_micro` for GPIO pins. - Kscan, matrix transform and physical layout devicetree nodes as described above, where the kscan node uses the interconnect [nexus node](https://docs.zephyrproject.org/4.1.0/hardware/porting/shields.html#gpio-nexus-nodes) aliases such as `&pro_micro` for GPIO pins.

View file

@ -7,7 +7,7 @@ description: Lighting system that controls an array of single-color LEDs.
import Tabs from "@theme/Tabs"; import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem"; import TabItem from "@theme/TabItem";
Please see [lighting feature page](../../../features/lighting.md#backlight) for an introduction on the feature. Please see [lighting feature page](../../features/lighting.md#backlight) for an introduction on the feature.
<Tabs <Tabs
defaultValue="shieldpin" defaultValue="shieldpin"

View file

@ -115,4 +115,4 @@ You can also control multiple LEDs from the same indicator:
## LED Behavior ## LED Behavior
See the [feature page](../../../features/led-indicators.md) and [configuration page](../../../config/led-indicators.md) for details on configuring LED brightness according to the indicator state. See the [feature page](../../features/led-indicators.md) and [configuration page](../../config/led-indicators.md) for details on configuring LED brightness according to the indicator state.

View file

@ -4,7 +4,7 @@ sidebar_label: RGB Underglow
description: Lighting system that controls strips of RGB LEDs. description: Lighting system that controls strips of RGB LEDs.
--- ---
Please see [lighting feature page](../../../features/lighting.md#rgb-underglow) for an introduction on the feature. Please see [lighting feature page](../../features/lighting.md#rgb-underglow) for an introduction on the feature.
Support for RGB underglow is always added to a board, not a shield. This is because the LED strip drivers rely on hardware-specific interfaces (e.g. SPI, I2S) and configurations, which shields do not control. Support for RGB underglow is always added to a board, not a shield. This is because the LED strip drivers rely on hardware-specific interfaces (e.g. SPI, I2S) and configurations, which shields do not control.
See the documentation page on [pin control](../pinctrl.mdx) for detailed information on setting up pins for hardware protocols such as SPI or PIO that are used for LED strips. See the documentation page on [pin control](../pinctrl.mdx) for detailed information on setting up pins for hardware protocols such as SPI or PIO that are used for LED strips.
@ -15,12 +15,10 @@ For example: the `kyria` shield has a [`boards/nice_nano_nrf52840_zmk.overlay`](
### nRF52-Based Boards ### nRF52-Based Boards
Using an SPI-based LED strip driver on the `&spi3` interface is the simplest option for nRF52-based boards. If possible, avoid using pins which are limited to low-frequency I/O for this purpose. The resulting interference may result in poor wireless performance. Using an SPI-based LED strip driver on the `&spi3` interface is the simplest option for nRF52-based boards.
:::info :::info
If possible, avoid using pins which are limited to low-frequency I/O for this purpose. The resulting interference may result in poor wireless performance. The list of low frequency I/O pins for the nRF52840 can be found at <https://docs.nordicsemi.com/bundle/ps_nrf52840/page/pin.html>.
The list of low frequency I/O pins for the nRF52840 can be found [here](https://docs.nordicsemi.com/bundle/ps_nrf52840/page/pin.html).
::: :::
The following example uses `P0.06` as the "Data In" pin of a WS2812-compatible LED strip: The following example uses `P0.06` as the "Data In" pin of a WS2812-compatible LED strip:
@ -69,13 +67,9 @@ The following example uses `P0.06` as the "Data In" pin of a WS2812-compatible L
}; };
``` ```
:::note
Standard WS2812 LEDs use a wire protocol where the bits for the colors green, red, and blue values are sent in that order. Standard WS2812 LEDs use a wire protocol where the bits for the colors green, red, and blue values are sent in that order.
If your board/shield uses LEDs that require the data sent in a different order, the `color-mapping` property ordering should be changed to match. If your board/shield uses LEDs that require the data sent in a different order, the `color-mapping` property ordering should be changed to match.
:::
### Other Boards ### Other Boards
Be sure to check the Zephyr documentation for the LED strip and necessary hardware bindings. Not every board has an `spi3` node, or configures `pinctrl` the same way. Reconcile this with any hardware restrictions found in the manufacturer's datasheet. Additional hardware interfaces may need to be enabled via Kconfig. Be sure to check the Zephyr documentation for the LED strip and necessary hardware bindings. Not every board has an `spi3` node, or configures `pinctrl` the same way. Reconcile this with any hardware restrictions found in the manufacturer's datasheet. Additional hardware interfaces may need to be enabled via Kconfig.

View file

@ -11,7 +11,7 @@ Some keyboards are boards but also have interconnects for modular add-ons. These
## Boards Included in ZMK ## Boards Included in ZMK
Boards with interconnects can be considered for inclusion to the tree of ZMK. If this is your aim, it is vital that you read through our [clean room policy](../contributing/clean-room.md). Boards with interconnects can be considered for inclusion to the tree of ZMK. If this is your aim, it is vital that you read through our [clean room policy](../development/contributing/clean-room.md).
Boards with interconnects that are included with ZMK are generally: Boards with interconnects that are included with ZMK are generally:
@ -32,7 +32,7 @@ This guide assumes you already have a configured GitHub account. If you don't ye
Follow these steps to create your new repository: Follow these steps to create your new repository:
- Visit https://github.com/zmkfirmware/unified-zmk-config-template - Visit <https://github.com/zmkfirmware/unified-zmk-config-template>
- Click the green "Use this template" button - Click the green "Use this template" button
- In the drop down that opens, click "Use this template". - In the drop down that opens, click "Use this template".
- In the following screen, provide the following information: - In the following screen, provide the following information:
@ -43,9 +43,9 @@ Follow these steps to create your new repository:
The repository is a combination of the directories and files required of a ZMK config, and those required of a shield module. The repository is a combination of the directories and files required of a ZMK config, and those required of a shield module.
This enables the use of GitHub Actions to test that the shield is defined correctly. 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. See also the page on [module creation](../development/module-creation.md) for a reference on exactly which file structure and files are required for a ZMK keyboard module.
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 We recommend that you take this moment to name your module according to our [convention](../development/module-creation.md), i.e. your `zephyr/module.yml` file should begin with
```yaml title="zephyr/module.yml" ```yaml title="zephyr/module.yml"
name: zmk-keyboard-<keyboard_name> name: zmk-keyboard-<keyboard_name>
@ -182,6 +182,6 @@ See [here](./bootloader/index.mdx) for bootloader instructions for other SoCs. D
## Next Steps ## Next Steps
If your board is a keyboard, continue from [the `Kconfig.defconfig` step](https://zmk.dev/docs/development/hardware-integration/new-shield?keyboard-type=unibody#kconfigdefconfig) of the new shield guide. Use your ZMK variant's devicetree instead of the overlay file which would be used for a shield. If your board is a keyboard, continue from [the `Kconfig.defconfig` step](https://zmk.dev/docs/hardware-integration/new-shield?keyboard-type=unibody#kconfigdefconfig) of the new shield guide. Use your ZMK variant's devicetree instead of the overlay file which would be used for a shield.
If your board is a board with an interconnect, your next step should be to write a [tester shield](../../troubleshooting/hardware-issues.mdx#identifying-issues). Such a shield should be the bare minimum shield to verify that your board works with ZMK. If your board is a board with an interconnect, your next step should be to write a [tester shield](../troubleshooting/hardware-issues.mdx#identifying-issues). Such a shield should be the bare minimum shield to verify that your board works with ZMK.

View file

@ -44,7 +44,7 @@ This guide will walk through the steps necessary to add ZMK support for a keyboa
The high level steps are: The high level steps are:
- Create a new [ZMK module](../module-creation.md) to contain your shield. - Create a new [ZMK module](../development/module-creation.md) to contain your shield.
- Create a new shield directory. - Create a new shield directory.
- Add the base Kconfig files. - Add the base Kconfig files.
- Add the shield overlay file defining: - Add the shield overlay file defining:
@ -54,7 +54,7 @@ The high level steps are:
- Add a default keymap, which users can override in their own configs as needed. - Add a default keymap, which users can override in their own configs as needed.
- Add a `<my_shield>.zmk.yml` metadata file to document the high level details of your shield, and the features it supports. - Add a `<my_shield>.zmk.yml` metadata file to document the high level details of your shield, and the features it supports.
Many of the above files will differ depending on whether your keyboard is a unibody or is [split into multiple parts](../../features/split-keyboards.md). Many of the above files will differ depending on whether your keyboard is a unibody or is [split into multiple parts](../features/split-keyboards.md).
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. 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/4.1.0/hardware/porting/shields.html#shields) to get a proper understanding of the underlying system before continuing. It may be helpful to review the upstream [shields documentation](https://docs.zephyrproject.org/4.1.0/hardware/porting/shields.html#shields) to get a proper understanding of the underlying system before continuing.
@ -63,7 +63,7 @@ It may be helpful to review the upstream [shields documentation](https://docs.ze
When writing your shield, please be aware of [licensing](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/licensing-a-repository): When writing your shield, please be aware of [licensing](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/licensing-a-repository):
- If you reference code or other items that are under a copyleft license (e.g. GNU GPLv2, used by QMK) as a reference, you must license your shield under a compatible copyleft license. - If you reference code or other items that are under a copyleft license (e.g. GNU GPLv2, used by QMK) as a reference, you must license your shield under a compatible copyleft license.
- If you license anything under a copyleft license, it cannot be referenced by anyone working on ZMK (see our [clean room policy](../contributing/clean-room.md)). - If you license anything under a copyleft license, it cannot be referenced by anyone working on ZMK (see our [clean room policy](../development/contributing/clean-room.md)).
We generally recommend licensing your shield under MIT, if you don't have a particular incentive to do otherwise. We generally recommend licensing your shield under MIT, if you don't have a particular incentive to do otherwise.
::: :::
@ -89,9 +89,9 @@ Follow these steps to create your new repository:
The repository is a combination of the directories and files required of a ZMK config, and those required of a shield module. The repository is a combination of the directories and files required of a ZMK config, and those required of a shield module.
This enables the use of GitHub Actions to test that the shield is defined correctly. 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. See also the page on [module creation](../development/module-creation.md) for a reference on exactly which file structure and files are required for a ZMK keyboard module.
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 We recommend that you take this moment to name your module according to our [convention](../development/module-creation.md), i.e. your `zephyr/module.yml` file should begin with
```yaml title="zephyr/module.yml" ```yaml title="zephyr/module.yml"
name: zmk-keyboard-<keyboard_name> name: zmk-keyboard-<keyboard_name>
@ -108,7 +108,7 @@ mkdir boards/shields/<keyboard_name>
## Base Kconfig Files ## Base Kconfig Files
:::tip[Example shields] :::tip[Example shields]
You can check out the [`shields` folder](https://github.com/zmkfirmware/zmk/tree/main/app/boards/shields) in the ZMK repo that houses [the in-tree supported shields](../../hardware.mdx) in order to copy and modify as a starting point. You can check out the [`shields` folder](https://github.com/zmkfirmware/zmk/tree/main/app/boards/shields) in the ZMK repo that houses [the in-tree supported shields](../hardware.mdx) in order to copy and modify as a starting point.
::: :::
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`. 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`.
@ -208,7 +208,7 @@ endif
### User Configuration Files ### User Configuration Files
In addition to the `Kconfig.shield` and `Kconfig.defconfig` files, many shields will also define a user configuration file called `my_keyboard.conf`. In addition to the `Kconfig.shield` and `Kconfig.defconfig` files, many shields will also define a user configuration file called `my_keyboard.conf`.
This file exists to provide "suggestions" of [configuration settings](../../config/index.md) for a user to select, such as enabling deep sleep. This file exists to provide "suggestions" of [configuration settings](../config/index.md) for a user to select, such as enabling deep sleep.
Note that the name should match the shield/part name defined in the [Kconfig.shield file](#kconfigshield). Note that the name should match the shield/part name defined in the [Kconfig.shield file](#kconfigshield).
:::warning :::warning
@ -231,7 +231,7 @@ Split keyboards can have multiple `.conf` files, one for each part. For example:
In most case you'll only need to use the .conf file that affects both halves of a split board. In most case you'll only need to use the .conf file that affects both halves of a split board.
:::note :::note
The shared configuration in `my_keyboard.conf` is only applied when you are building with a [`zmk-config` folder](../local-toolchain/build-flash.mdx#building-from-zmk-config-folder) and it is present at `config/my_keyboard.conf`. The shared configuration in `my_keyboard.conf` is only applied when you are building with a [`zmk-config` folder](../development/local-toolchain/build-flash.mdx#building-from-zmk-config-folder) and it is present at `config/my_keyboard.conf`.
::: :::
</TabItem> </TabItem>
@ -246,7 +246,7 @@ There are three main things that need to be defined in this file:
- Your keyboard scan (kscan) driver, which determines which GPIO pins to scan for key press events - Your keyboard scan (kscan) driver, which determines which GPIO pins to scan for key press events
- Your matrix transform, which acts as a "bridge" between the kscan and the keymap - Your matrix transform, which acts as a "bridge" between the kscan and the keymap
- Your physical layout, which aggregates the above and (optionally) defines physical key positions so that the keyboard can be used with [ZMK Studio](../../features/studio.md). - Your physical layout, which aggregates the above and (optionally) defines physical key positions so that the keyboard can be used with [ZMK Studio](../features/studio.md).
<SplitInvisTabs> <SplitInvisTabs>
<TabItem value="unibody"> <TabItem value="unibody">
@ -280,7 +280,7 @@ To use GPIO pins that are not part of the interconnects as described above, you
For instance, pins numbered `PX.Y` in nRF52840-based boards can be referred to via `&gpioX Y` labels. For instance, pins numbered `PX.Y` in nRF52840-based boards can be referred to via `&gpioX Y` labels.
An example is `&gpio1 7` for the `P1.07` pin that the nice!nano exposes in the middle of the board. An example is `&gpio1 7` for the `P1.07` pin that the nice!nano exposes in the middle of the board.
The [Keyboard Scan configuration documentation](../../config/kscan.md) has the full details on configuring the kscan driver. The [Keyboard Scan configuration documentation](../config/kscan.md) has the full details on configuring the kscan driver.
<SplitTabs> <SplitTabs>
<TabItem value="unibody"> <TabItem value="unibody">
@ -450,7 +450,7 @@ The matrix transform is also used to "correct" pin orderings into something that
See the [in-tree keyboards](https://github.com/zmkfirmware/zmk/tree/main/app/boards/shields) that ZMK defines for examples of more complex matrix transformations. See the [in-tree keyboards](https://github.com/zmkfirmware/zmk/tree/main/app/boards/shields) that ZMK defines for examples of more complex matrix transformations.
Also see the [matrix transform section](../../config/layout.md#matrix-transform) in the Keyboard Scan configuration documentation for further details and examples of matrix transforms. Also see the [matrix transform section](../config/layout.md#matrix-transform) in the Keyboard Scan configuration documentation for further details and examples of matrix transforms.
### Physical Layout ### Physical Layout
@ -460,7 +460,7 @@ Physical layouts organize the matrix transform, kscan and optionally the physica
<Tabs groupId="physical-layouts" queryString defaultValue="basic"> <Tabs groupId="physical-layouts" queryString defaultValue="basic">
<TabItem value="basic" label="Basic"> <TabItem value="basic" label="Basic">
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: 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 ```dts
/ { / {
@ -478,7 +478,7 @@ These nodes should be placed in `my_keyboard.overlay` for unibody keyboards and
</TabItem> </TabItem>
<TabItem value="studio" label="With ZMK Studio Support"> <TabItem value="studio" label="With ZMK Studio Support">
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. 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). 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 ```dts
@ -501,7 +501,7 @@ Set the `chosen` node to a defined "default" physical layout. This should also b
}; };
``` ```
If you define multiple physical layouts, users can select a different layout by overriding the `zmk,physical-layout` chosen node in their keymap file or by using [ZMK Studio](../../features/studio.md) if your board is compatible with it. If you define multiple physical layouts, users can select a different layout by overriding the `zmk,physical-layout` chosen node in their keymap file or by using [ZMK Studio](../features/studio.md) if your board is compatible with it.
:::note :::note
If all of your physical layouts use the same `kscan` node under the hood, you can skip setting the `kscan` property on each layout and instead assign the `zmk,kscan` chosen node to your single kscan instance: If all of your physical layouts use the same `kscan` node under the hood, you can skip setting the `kscan` property on each layout and instead assign the `zmk,kscan` chosen node to your single kscan instance:
@ -524,7 +524,7 @@ If all of your physical layouts use the same `kscan` node under the hood, you ca
<TabItem value="unibody">This is only required for wired split keyboards.</TabItem> <TabItem value="unibody">This is only required for wired split keyboards.</TabItem>
<TabItem value="split"> <TabItem value="split">
If testing the experimental [wired split](../../features/split-keyboards.md) support, you should assign a [predefined](./pinctrl.mdx#predefined-nodes) or [pinctrl configured](./pinctrl.mdx) UART to the `device` property of a new node with `compatible` value of `"zmk,wired-split"`: If testing the experimental [wired split](../features/split-keyboards.md) support, you should assign a [predefined](./pinctrl.mdx#predefined-nodes) or [pinctrl configured](./pinctrl.mdx) UART to the `device` property of a new node with `compatible` value of `"zmk,wired-split"`:
```dts ```dts
/ { / {
@ -535,7 +535,7 @@ If testing the experimental [wired split](../../features/split-keyboards.md) sup
}; };
``` ```
See the [wired split](../../config/split.md#wired-split) configuration for more details. See the [wired split](../config/split.md#wired-split) configuration for more details.
For wireless split keyboards, this step should be skipped, especially since the UART pins on your controller might already be in use for other functionality. For wireless split keyboards, this step should be skipped, especially since the UART pins on your controller might already be in use for other functionality.
@ -573,8 +573,8 @@ Here is an example simple keymap for a 3x3 macropad, with only one layer:
``` ```
The keymap should match the order of the keys in the [matrix transform](#matrix-transform) exactly, left to right, top to bottom (they are both 1 dimensional arrays rearranged with newline characters for better legibility). The keymap should match the order of the keys in the [matrix transform](#matrix-transform) exactly, left to right, top to bottom (they are both 1 dimensional arrays rearranged with newline characters for better legibility).
See [Keymaps](../../keymaps/index.mdx) for information on defining keymaps in ZMK. See [Keymaps](../keymaps/index.mdx) for information on defining keymaps in ZMK.
If you wish to use [ZMK Studio](../../features/studio.md) with your keyboard, make sure to assign the [ZMK Studio unlocking behavior](../../keymaps/behaviors/studio-unlock.md) to a key in your keymap. If you wish to use [ZMK Studio](../features/studio.md) with your keyboard, make sure to assign the [ZMK Studio unlocking behavior](../keymaps/behaviors/studio-unlock.md) to a key in your keymap.
## Metadata ## Metadata
@ -604,12 +604,12 @@ See [Hardware Metadata Files](hardware-metadata-files.md) for the full details.
## Testing ## Testing
Once you've defined everything as described above, you can build your firmware to make sure everything is working. Once you've defined everything as described above, you can build your firmware to make sure everything is working.
If you wish to test that your keyboard works with [ZMK Studio](../../features/studio.md), you'll also need to follow the [instructions for enabling Studio](../../features/studio.md#building). If you wish to test that your keyboard works with [ZMK Studio](../features/studio.md), you'll also need to follow the [instructions for enabling Studio](../features/studio.md#building).
### GitHub Actions ### GitHub Actions
To use GitHub Actions to test, push the files defining the keyboard to GitHub. To use GitHub Actions to test, push the files defining the keyboard to GitHub.
Next, [update the `build.yaml`](../../customization.md#building-additional-keyboards) of your `zmk-config` to build your keyboard. Next, [update the `build.yaml`](../customization.md#building-additional-keyboards) of your `zmk-config` to build your keyboard.
- If your shield is defined in your `zmk-config`, then the shield should start building. - If your shield is defined in your `zmk-config`, then the shield should start building.
- If the shield is defined in a separate module, you will need to [adjust your `west.yml` to reference the module](https://zmk.dev/docs/features/modules#building-with-modules). - If the shield is defined in a separate module, you will need to [adjust your `west.yml` to reference the module](https://zmk.dev/docs/features/modules#building-with-modules).
@ -617,5 +617,5 @@ Next, [update the `build.yaml`](../../customization.md#building-additional-keybo
### Local Toolchain ### Local Toolchain
You can also use a local toolchain setup to test your keyboard. You can also use a local toolchain setup to test your keyboard.
Follow [our guide for getting set up](../local-toolchain/setup/index.md), then follow the [instructions for building and flashing locally](../local-toolchain/build-flash.mdx). Follow [our guide for getting set up](../development/local-toolchain/setup/index.md), then follow the [instructions for building and flashing locally](../development/local-toolchain/build-flash.mdx).
You will need to specify the module of your keyboard when building. You will need to specify the module of your keyboard when building.

View file

@ -6,8 +6,8 @@ toc_max_heading_level: 4
A physical layout is a devicetree entity that aggregates all details about a certain possible keyboard layout. A physical layout is a devicetree entity that aggregates all details about a certain possible keyboard layout.
It contains: It contains:
- A [keyboard scan (kscan) driver](../../config/kscan.md) - A [keyboard scan (kscan) driver](../config/kscan.md)
- A [matrix transform](../../config/layout.md#matrix-transform) - A [matrix transform](../config/layout.md#matrix-transform)
- (Optional) [Physical key positions](#optional-keys-property) - (Optional) [Physical key positions](#optional-keys-property)
By convention, physical layouts and any [position maps](#position-map) are defined in a separate file called `<your keyboard>-layouts.dtsi`. By convention, physical layouts and any [position maps](#position-map) are defined in a separate file called `<your keyboard>-layouts.dtsi`.
@ -35,11 +35,11 @@ Every physical layout needs a matrix transform, and optionally can also have a k
}; };
``` ```
The `kscan` property only needs to be assigned if some of your physical layouts use different kscans. Otherwise, it can be omitted and the `kscan` can be assigned in the [`chosen` node](./new-shield.mdx#chosen-node) instead. See the [configuration section on physical layouts](../../config/layout.md#physical-layout) for reference. The `kscan` property only needs to be assigned if some of your physical layouts use different kscans. Otherwise, it can be omitted and the `kscan` can be assigned in the [`chosen` node](./new-shield.mdx#chosen-node) instead. See the [configuration section on physical layouts](../config/layout.md#physical-layout) for reference.
## (Optional) Keys Property ## (Optional) Keys Property
The `keys` property is required for [ZMK Studio](../../features/studio.md) support. It is used to describe the physical attributes of each key position present in that layout. The `keys` property is required for [ZMK Studio](../features/studio.md) support. It is used to describe the physical attributes of each key position present in that layout.
To pull in the necessary definition for creating physical layouts with the `keys` property, a new include should be added to the top of the devicetree file: To pull in the necessary definition for creating physical layouts with the `keys` property, a new include should be added to the top of the devicetree file:
@ -62,11 +62,7 @@ A key description has the shape `<&key_physical_attrs w h x y r rx ry>` with the
You can specify negative values in devicetree using parentheses around it, e.g. `(-3000)` for a 30 degree counterclockwise rotation. You can specify negative values in devicetree using parentheses around it, e.g. `(-3000)` for a 30 degree counterclockwise rotation.
:::tip We recommend the use of <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 <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.
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.
:::
### Physical Layout with Keys Example ### Physical Layout with Keys Example
@ -171,7 +167,7 @@ If necessary, you can also define multiple kscan instances.
### Position Map ### Position Map
When switching between layouts using [ZMK Studio](../../features/studio.md), an attempt is made to automatically infer bindings for the keys in the new layout from the old layout. Keys with the same physical key properties are given the same binding. This approach has some limitations, so for more accurate transference of bindings a position map is used. When switching between layouts using [ZMK Studio](../features/studio.md), an attempt is made to automatically infer bindings for the keys in the new layout from the old layout. Keys with the same physical key properties are given the same binding. This approach has some limitations, so for more accurate transference of bindings a position map is used.
:::warning :::warning
@ -203,15 +199,11 @@ A child node is defined for every layout the keyboard can have. The `positions`
When switching from one layout to another, say from layout 1 to layout 2, the _orderings_ found in the `positions` arrays are used. The first key in the `positions` array of layout 2 is given the binding assigned to the first key in the `positions` array of layout 1, the second key in the `positions` array of layout 2 is given the binding assigned to the second key in the `positions` array of layout 1, and so on. When switching from one layout to another, say from layout 1 to layout 2, the _orderings_ found in the `positions` arrays are used. The first key in the `positions` array of layout 2 is given the binding assigned to the first key in the `positions` array of layout 1, the second key in the `positions` array of layout 2 is given the binding assigned to the second key in the `positions` array of layout 1, and so on.
The position map should be marked as `complete` if all desired binding transfers are defined within it. Otherwise, [ZMK Studio](../../features/studio.md) will continue to automatically determine assignments for keys not listed in the position map. See [this example non-complete position map](#example-non-complete-position-map) for why this could be useful. The position map should be marked as `complete` if all desired binding transfers are defined within it. Otherwise, [ZMK Studio](../features/studio.md) will continue to automatically determine assignments for keys not listed in the position map. See [this example non-complete position map](#example-non-complete-position-map) for why this could be useful.
See also the [configuration section on position maps](../../config/layout.md#physical-layout-position-map). See also the [configuration section on position maps](../config/layout.md#physical-layout-position-map).
:::tip We recommend the use of <https://zmk-layout-helper.netlify.app>, distinct from the previous two mentioned, for the purposes of writing a position map.
We recommend the use of [this tool](https://zmk-layout-helper.netlify.app/), distinct from the previous two mentioned, for the purposes of writing a position map.
:::
#### Writing a position map #### Writing a position map
@ -257,7 +249,7 @@ Next write the child nodes for every other layout with respect to the reference.
Consider the following macropad/numpad with two physical layouts: Consider the following macropad/numpad with two physical layouts:
![A 4x5 numpad/macropad](../../assets/hardware-integration/numpad.svg) ![A 4x5 numpad/macropad](../assets/hardware-integration/numpad.svg)
Let us first consider each side individually. The "reference" position map of the left side would look like this: Let us first consider each side individually. The "reference" position map of the left side would look like this:

View file

@ -8,15 +8,11 @@ import TabItem from "@theme/TabItem";
import InterconnectTabs from "@site/src/components/interconnect-tabs"; import InterconnectTabs from "@site/src/components/interconnect-tabs";
import Metadata from "@site/src/data/hardware-metadata.json"; import Metadata from "@site/src/data/hardware-metadata.json";
:::info
This page exists to provide a guide to [Pin Control](https://docs.zephyrproject.org/4.1.0/hardware/pinctrl/index.html#pin-control) for ZMK users and designers. Refer to [Zephyr's page on Pin Control](https://docs.zephyrproject.org/4.1.0/hardware/pinctrl/index.html#pin-control) for elaboration and more details on any of the points raised here. This page exists to provide a guide to [Pin Control](https://docs.zephyrproject.org/4.1.0/hardware/pinctrl/index.html#pin-control) for ZMK users and designers. Refer to [Zephyr's page on Pin Control](https://docs.zephyrproject.org/4.1.0/hardware/pinctrl/index.html#pin-control) for elaboration and more details on any of the points raised here.
:::
A basic keyboard design as introduced in the [new shield guide](./new-shield.mdx) only uses its pins for the keyboard matrix. Many keyboard designs make use of advanced components or functionality, such as displays or shift registers. This results in the keyboard making use of communication protocols such as (but not limited to) SPI, I2C, or UART. Configuring pins for the usage of advanced functionality such as drivers for the previously named protocols is referred to as "Pin Control". A basic keyboard design as introduced in the [new shield guide](./new-shield.mdx) only uses its pins for the keyboard matrix. Many keyboard designs make use of advanced components or functionality, such as displays or shift registers. This results in the keyboard making use of communication protocols such as (but not limited to) SPI, I2C, or UART. Configuring pins for the usage of advanced functionality such as drivers for the previously named protocols is referred to as "Pin Control".
:::warning
The details of pin control can vary from vendor to vendor. An attempt was made to be as general as possible, but it isn't possible to cover all possible cases. The approaches for the nRF52840 and RP2040 MCUs/SoCs are documented in their entirety below. For other MCUs/SoCs, please refer to the [Zephyr documentation](https://docs.zephyrproject.org/4.1.0/index.html) and the examples and other files found in-tree of [ZMK](https://github.com/zmkfirmware/zmk/tree/main/app/boards) and [ZMK's fork of Zephyr](https://github.com/zmkfirmware/zephyr). The details of pin control can vary from vendor to vendor. An attempt was made to be as general as possible, but it isn't possible to cover all possible cases. The approaches for the nRF52840 and RP2040 MCUs/SoCs are documented in their entirety below. For other MCUs/SoCs, please refer to the [Zephyr documentation](https://docs.zephyrproject.org/4.1.0/index.html) and the examples and other files found in-tree of [ZMK](https://github.com/zmkfirmware/zmk/tree/main/app/boards) and [ZMK's fork of Zephyr](https://github.com/zmkfirmware/zephyr).
:::
## Boards, Shields, and Modules ## Boards, Shields, and Modules
@ -33,10 +29,8 @@ Pin control is always defined for a _board_, never for a shield:
``` ```
Note that you will need to define a separate overlay _for each_ of the boards to be used with the shield. Note that you will need to define a separate overlay _for each_ of the boards to be used with the shield.
:::info
Assume that the shield that you are using is found in-tree of ZMK or within an external module, and _does not_ contain the overlay for the board that you wish to use. Assume that the shield that you are using is found in-tree of ZMK or within an external module, and _does not_ contain the overlay for the board that you wish to use.
If this is the case, then you should fork the source repository and add the overlay to the fork. Use said fork to build your firmware, and potentially submit a PR to upstream. If this is the case, then you should fork the source repository and add the overlay to the fork. Use said fork to build your firmware, and potentially submit a PR to upstream.
:::
## Predefined Nodes ## Predefined Nodes

View file

@ -7,10 +7,10 @@ import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem"; import TabItem from "@theme/TabItem";
ZMK's pointing device support builds upon the Zephyr [input API](https://docs.zephyrproject.org/4.1.0/services/input/index.html) to offer pointing/mouse functionality with various hardware. ZMK's pointing device support builds upon the Zephyr [input API](https://docs.zephyrproject.org/4.1.0/services/input/index.html) to offer pointing/mouse functionality with various hardware.
A limited number of input drivers are available in the Zephyr version currently used by ZMK, but additional drivers can be found in [external modules](../../features/modules.mdx) for a variety of hardware. A limited number of input drivers are available in the Zephyr version currently used by ZMK, but additional drivers can be found in [external modules](../features/modules.mdx) for a variety of hardware.
Pointing devices are also supported on split peripherals, with some additional configuration using the [input split device](../../config/pointing.md#input-split). Pointing devices are also supported on split peripherals, with some additional configuration using the [input split device](../config/pointing.md#input-split).
The configuration details will thus vary depending on if you are adding a pointing device to a [split peripheral](../../features/split-keyboards.md#central-and-peripheral-roles) as opposed to a unibody keyboard or split central part. The configuration details will thus vary depending on if you are adding a pointing device to a [split peripheral](../features/split-keyboards.md#central-and-peripheral-roles) as opposed to a unibody keyboard or split central part.
export const SplitTabs = (props) => ( export const SplitTabs = (props) => (
<Tabs <Tabs
@ -81,7 +81,7 @@ The specifics of the properties required to set for a given driver will vary; al
## Listener and Input Split Device ## Listener and Input Split Device
Every input device needs an associated listener added that listens for events from the device and processes them before sending the events to the host using a HID mouse report. Every input device needs an associated listener added that listens for events from the device and processes them before sending the events to the host using a HID mouse report.
See [input listener configuration](../../config/pointing.md#input-listener) for the full details. See [input listener configuration](../config/pointing.md#input-listener) for the full details.
If your pointing device is on a split peripheral part, you also need to define and use an input split device on all keyboard parts. If your pointing device is on a split peripheral part, you also need to define and use an input split device on all keyboard parts.
@ -246,7 +246,7 @@ Here we first include the shared file, and then enable the input listener that i
Some physical pointing devices may be generating input events that need adjustment before being sent to hosts. Some physical pointing devices may be generating input events that need adjustment before being sent to hosts.
For example a trackpad might be integrated into a keyboard rotated 90° and need the X/Y data adjusted appropriately. For example a trackpad might be integrated into a keyboard rotated 90° and need the X/Y data adjusted appropriately.
This can be accomplished with [input processors](../../keymaps/input-processors/index.md). This can be accomplished with [input processors](../keymaps/input-processors/index.md).
As an example, you could enhance the listener defined in the previous section with an input processor that inverts and swaps the X/Y axes: As an example, you could enhance the listener defined in the previous section with an input processor that inverts and swaps the X/Y axes:
```dts ```dts
@ -263,7 +263,7 @@ As an example, you could enhance the listener defined in the previous section wi
## Configuration Setting ## Configuration Setting
If your keyboard hardware includes a pointing device by default, you can enable the [`ZMK_POINTING` config](../../config/pointing.md#general) in your keyboard definition. If your keyboard hardware includes a pointing device by default, you can enable the [`ZMK_POINTING` config](../config/pointing.md#general) in your keyboard definition.
You can do that in your [`Kconfig.defconfig` file](new-shield.mdx#kconfigdefconfig), where you can also enable the config for the communication protocol (e.g. [SPI](https://docs.zephyrproject.org/4.1.0/kconfig.html#CONFIG_SPI), [I2C](https://docs.zephyrproject.org/4.1.0/hardware/peripherals/i2c.html#configuration-options)) used by the pointing device: You can do that in your [`Kconfig.defconfig` file](new-shield.mdx#kconfigdefconfig), where you can also enable the config for the communication protocol (e.g. [SPI](https://docs.zephyrproject.org/4.1.0/kconfig.html#CONFIG_SPI), [I2C](https://docs.zephyrproject.org/4.1.0/hardware/peripherals/i2c.html#configuration-options)) used by the pointing device:
<SplitTabs> <SplitTabs>

View file

@ -9,13 +9,11 @@ Shift registers are the recommended method of adding additional GPIO pins to MCU
This page assumes that you are using a SIPO shift register with the part number 74HC595. Other shift registers can work as well but this is the most commonly used one. This page assumes that you are using a SIPO shift register with the part number 74HC595. Other shift registers can work as well but this is the most commonly used one.
::: :::
:::tip
To understand how shift registers work, we recommend reading through ["How does the 74HC595 Shift Register work?"](https://lastminuteengineers.com/74hc595-shift-register-arduino-tutorial/#how-does-the-74hc595-shift-register-work). To understand how shift registers work, we recommend reading through ["How does the 74HC595 Shift Register work?"](https://lastminuteengineers.com/74hc595-shift-register-arduino-tutorial/#how-does-the-74hc595-shift-register-work).
:::
## Design Guidelines ## Design Guidelines
The shift register output pins should act as MCU outputs in your design. All MCU inputs should remain connected directly to MCU/board pins. This is to allow the inputs to trigger "interrupts" on the MCU/board, upon which it will begin scanning the keys. Using a shift register for MCU inputs is also possible, but requires you to use a PISO shift register and will harm your battery life. Note that a [direct kscan](../../config/kscan.md#direct-gpio-driver) keyboard does not have any MCU output pins, but a diodeless keyboard is still possible by making use of a single row pin and using the [matrix kscan](../../config/kscan.md#matrix-driver) driver. The shift register output pins should act as MCU outputs in your design. All MCU inputs should remain connected directly to MCU/board pins. This is to allow the inputs to trigger "interrupts" on the MCU/board, upon which it will begin scanning the keys. Using a shift register for MCU inputs is also possible, but requires you to use a PISO shift register and will harm your battery life. Note that a [direct kscan](../config/kscan.md#direct-gpio-driver) keyboard does not have any MCU output pins, but a diodeless keyboard is still possible by making use of a single row pin and using the [matrix kscan](../config/kscan.md#matrix-driver) driver.
:::info :::info
In a diode matrix, MCU output pins are those connected to the [anodes of your diodes](https://learn.sparkfun.com/tutorials/diodes/all#ideal-diodes). You most likely will need to rearrange your matrix to maximize the use of shift register output pins, in order to reduce the total number of GPIO pins connected to your MCU. For example, a 9 column 5 row `col2row` matrix could be rearranged to use 16 columns and 3 rows. In a diode matrix, MCU output pins are those connected to the [anodes of your diodes](https://learn.sparkfun.com/tutorials/diodes/all#ideal-diodes). You most likely will need to rearrange your matrix to maximize the use of shift register output pins, in order to reduce the total number of GPIO pins connected to your MCU. For example, a 9 column 5 row `col2row` matrix could be rearranged to use 16 columns and 3 rows.
@ -25,7 +23,7 @@ You will want to make sure that the data and clock pins of the shift register ar
ZMK allows you to daisy-chain up to four shift registers. Below is a fragment of a schematic showing two shift registers that are daisy-chained. ZMK allows you to daisy-chain up to four shift registers. Below is a fragment of a schematic showing two shift registers that are daisy-chained.
![A fragment of a schematic featuring two shift registers daisy chained together.](../../assets/hardware-integration/shift-register-daisy.png) ![A fragment of a schematic featuring two shift registers daisy chained together.](../assets/hardware-integration/shift-register-daisy.png)
## Configuration ## Configuration

View file

@ -16,7 +16,7 @@ import SidebandDirect from "./includes/_sideband-direct.md";
import SidebandMatrix from "./includes/_sideband-matrix.md"; import SidebandMatrix from "./includes/_sideband-matrix.md";
import SidebandWakeupDirect from "./includes/_sideband-wakeup-direct.md"; import SidebandWakeupDirect from "./includes/_sideband-wakeup-direct.md";
Advanced methods of adding [soft off](../../features/low-power-states.md#soft-off) to a keyboard are detailed below. The first two tabs describe methods involving hardware changes, while the last describes the firmware changes necessary to define a single specific key switch for waking up. Advanced methods of adding [soft off](../features/low-power-states.md#soft-off) to a keyboard are detailed below. The first two tabs describe methods involving hardware changes, while the last describes the firmware changes necessary to define a single specific key switch for waking up.
<Tabs groupId="advanced-methods" queryString defaultValue="direct"> <Tabs groupId="advanced-methods" queryString defaultValue="direct">
<TabItem value="direct" label="Direct Pin"></TabItem> <TabItem value="direct" label="Direct Pin"></TabItem>
@ -68,7 +68,7 @@ Several items work together to make both triggering soft off properly, and setti
### Soft off behavior ### Soft off behavior
For this approach, you will need to make sure that the [soft off behavior](../../keymaps/behaviors/soft-off.md) is present in your keymap, to trigger soft off. For this approach, you will need to make sure that the [soft off behavior](../keymaps/behaviors/soft-off.md) is present in your keymap, to trigger soft off.
</TabItem> </TabItem>
</Tabs> </Tabs>
@ -166,7 +166,7 @@ Finally, we will list the `wakeup_scan` device in an additional configuration se
Here are the properties for the node: Here are the properties for the node:
- The `compatible` property for the node must be `zmk,soft-off-wakeup-sources`. - The `compatible` property for the node must be `zmk,soft-off-wakeup-sources`.
- The `wakeup-sources` property is a [phandle array](../devicetree.md#property-types) pointing to all the devices that should be enabled during the shutdown process to be sure they can later wake the keyboard. - The `wakeup-sources` property is a [phandle array](../development/devicetree.md#property-types) pointing to all the devices that should be enabled during the shutdown process to be sure they can later wake the keyboard.
:::tip :::tip
If you add your kscan to the `wakeup-sources` array, then your keyboard will wake upon pressing any key in your kscan. Essentially, this causes `&soft_off` to behave like a behavior that puts the keyboard in deep sleep. If you choose to do so, then you can omit everything aside from the `soft_off_wakers` node. If you add your kscan to the `wakeup-sources` array, then your keyboard will wake upon pressing any key in your kscan. Essentially, this causes `&soft_off` to behave like a behavior that puts the keyboard in deep sleep. If you choose to do so, then you can omit everything aside from the `soft_off_wakers` node.

View file

@ -11,11 +11,6 @@ import Heading from "@theme/Heading";
import { groupedMetadata } from "@site/src/components/hardware-utils"; import { groupedMetadata } from "@site/src/components/hardware-utils";
export const toc = [ export const toc = [
{
value: "Onboard Controller Keyboards",
id: "onboard",
level: 2,
},
{ {
value: "Composite Keyboards", value: "Composite Keyboards",
id: "composite", id: "composite",
@ -28,25 +23,33 @@ export const toc = [
id: interconnect.id, id: interconnect.id,
level: 3, level: 3,
})), })),
{
value: "Onboard Controller Keyboards",
id: "onboard",
level: 2,
},
{ {
value: "Other Hardware", value: "Other Hardware",
id: "other-hardware", id: "other-hardware",
level: 2, level: 2,
}, },
{
value: "Contributing",
id: "contributing",
level: 2,
},
]; ];
With the solid technical foundation of Zephyr™ RTOS, ZMK can support a wide diversity of hardware targets, With the solid technical foundation of Zephyr™ RTOS, ZMK can support a wide variety of hardware targets,
including but not limited to Nordic nRF52, Raspberry Pi RP2040/RP2350, most ST STM32 MCUs, and Microchip SAMD21. including but not limited to Nordic nRF52, Raspberry Pi RP2040/RP2350, most ST STM32 MCUs, and Microchip SAMD21.
That being said, there are specific [boards / shields](development/hardware-integration/index.mdx#boards--shields) that have been implemented and tested by the ZMK contributors, listed below. ZMK has the potential to run on any hardware supported by Zephyr™, such as those on
the [Zephyr™ supported boards](https://docs.zephyrproject.org/4.1.0/boards/index.html) page, though you may need to do some additional work to configure them for ZMK.
That being said, there are specific boards that have been tested and pre-configured by the ZMK contributors, denoted by the `zmk` board variants below.
:::note Designing a new keyboard? Check out the [Hardware Integration](hardware-integration/index.mdx) section
for more information on how to configure ZMK to run on your custom hardware.
With the [upgrade to Zephyr 4.1](/blog/2025/12/09/zephyr-4-1#zmk-board-variant), the ZMK project has moved all in-tree boards to use a `zmk` [board variant](https://docs.zephyrproject.org/4.1.0/glossary.html#term-variant), for consistency when distinguishing from stock boards that are actually in upstream Zephyr. :::info[Boards, Board Variants, and Shields]
ZMK uses the Zephyr concepts of "boards" and "shields" to refer to different parts of a keyboard build that are then combined during a firmware build.
Please see the [explainer on boards & shields](hardware-integration/index.mdx#boards--shields) for more details.
Zephyr boards come with minimal configuration. ZMK board variants add the necessary configuration to make the board usable out of the box with ZMK.
::: :::
@ -58,7 +61,6 @@ With the [upgrade to Zephyr 4.1](/blog/2025/12/09/zephyr-4-1#zmk-board-variant),
In addition to the basic keyboard functionality, there is also support for additional keyboard hardware such as encoders, RGB underglow, backlight and displays. In addition to the basic keyboard functionality, there is also support for additional keyboard hardware such as encoders, RGB underglow, backlight and displays.
Please see pages under the "Features" header in the sidebar for details. Please see pages under the "Features" header in the sidebar for details.
{/* prettier-ignore */} ZMK doesn't support boards with AVR 8-bit processors, such as the ATmega32U4, because Zephyr™ only
<Heading as="h2" id="contributing">Contributing</Heading> supports 32-bit and 64-bit platforms. As a result, controllers like the SparkFun Pro Micro, Elite-C,
and Arduino Uno Rev3 are **NOT** supported by ZMK.
If you'd like to add support for a new keyboard shield, head over to the [New Keyboard Shield](development/hardware-integration/new-shield.mdx) documentation and note the [clean room design requirements](development/contributing/clean-room.md).

View file

@ -372,11 +372,9 @@ Including `hold-trigger-key-positions` in your hold-tap definition turns on the
In all other situations, positional hold-tap will not modify the behavior of your hold-tap. Positional hold-tap is useful when used with home-row modifiers: for example, if you have a home-row modifier key in the left hand, by including only key positions from the right hand in `hold-trigger-key-positions`, you will only get hold behaviors during cross-hand key combinations unless you exceed `tapping-term-ms` when using "balanced" or "hold-preferred" flavors. In all other situations, positional hold-tap will not modify the behavior of your hold-tap. Positional hold-tap is useful when used with home-row modifiers: for example, if you have a home-row modifier key in the left hand, by including only key positions from the right hand in `hold-trigger-key-positions`, you will only get hold behaviors during cross-hand key combinations unless you exceed `tapping-term-ms` when using "balanced" or "hold-preferred" flavors.
For home-row mods, it is recommended to use this property with `hold-trigger-on-release` so that modifiers on the same hand can be combined.
:::info
`hold-trigger-key-positions` is an array of key position indexes. Key positions are numbered sequentially according to your keymap, starting with 0. So if the first key in your keymap is Q, this key is in position 0. The next key (probably W) will be in position 1, et cetera. `hold-trigger-key-positions` is an array of key position indexes. Key positions are numbered sequentially according to your keymap, starting with 0. So if the first key in your keymap is Q, this key is in position 0. The next key (probably W) will be in position 1, et cetera.
:::
For home-row mods, it is recommended to use this property with `hold-trigger-on-release` so that modifiers on the same hand can be combined.
<details> <details>
<summary>The following example uses a hold-tap behavior definition configured with the `hold-preferred` flavor, and with positional hold-tap enabled:</summary> <summary>The following example uses a hold-tap behavior definition configured with the `hold-preferred` flavor, and with positional hold-tap enabled:</summary>

View file

@ -312,10 +312,6 @@ To avoid repetition or possible typos when declaring a **zero parameter macro**,
) )
``` ```
:::note
`ZMK_MACRO()` **only supports declaring non-parameterized (zero parameter) macros**; parameterized declarations are not currently supported.
:::
This can be used instead of a complete macro definition. During the firmware build process, the example above would produce the complete macro definition below: This can be used instead of a complete macro definition. During the firmware build process, the example above would produce the complete macro definition below:
```dts ```dts

View file

@ -48,7 +48,7 @@ The on/off state that is set by the `&ext_power` behavior will be [saved to flas
However it will only be saved after [`CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE`](../../config/system.md#general) milliseconds in order to reduce potential wear on the flash memory. However it will only be saved after [`CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE`](../../config/system.md#general) milliseconds in order to reduce potential wear on the flash memory.
::: :::
### Example: ### Examples
1. Behavior binding to enable the external power 1. Behavior binding to enable the external power

View file

@ -7,12 +7,8 @@ sidebar_label: Behaviors
The behaviors input processor is used invoke standard behaviors when certain input events occur; most frequently this is used to trigger behaviors when certain mouse buttons are triggered by physical pointing devices. The behaviors input processor is used invoke standard behaviors when certain input events occur; most frequently this is used to trigger behaviors when certain mouse buttons are triggered by physical pointing devices.
:::note
This input processor is primarily intended for `INPUT_EV_KEY` type of events that have a binary on/off state, not vector types for relative or absolute movements. This input processor is primarily intended for `INPUT_EV_KEY` type of events that have a binary on/off state, not vector types for relative or absolute movements.
:::
:::note[Source-specific behaviors on split keyboards] :::note[Source-specific behaviors on split keyboards]
Invoking a [source-specific behavior](../../features/split-keyboards.md#source-locality-behaviors) such as one of the [reset behaviors](../behaviors/reset.md) using this input processor will always trigger it on the central side of the keyboard, regardless of the side includes the input device that originally generated the input event. Invoking a [source-specific behavior](../../features/split-keyboards.md#source-locality-behaviors) such as one of the [reset behaviors](../behaviors/reset.md) using this input processor will always trigger it on the central side of the keyboard, regardless of the side includes the input device that originally generated the input event.
::: :::

View file

@ -9,11 +9,6 @@ import Table from "@site/src/components/codes/Table";
This is the reference page for keycodes used by behaviors. Use the table of contents (on the right or the top) for easy navigation. This is the reference page for keycodes used by behaviors. Use the table of contents (on the right or the top) for easy navigation.
:::warning
Take extra notice of the spelling of the keycodes, especially the shorthand spelling.
Otherwise, it will result in an elusive parsing error!
:::
:::info[Keyboard vs. Consumer keycodes] :::info[Keyboard vs. Consumer keycodes]
In the below tables, there are keycode pairs with similar names where one variant has a `K_` prefix and another `C_`. In the below tables, there are keycode pairs with similar names where one variant has a `K_` prefix and another `C_`.
These variants correspond to similarly named usages from different [HID usage pages](https://usb.org/sites/default/files/hut1_2.pdf#page=16), These variants correspond to similarly named usages from different [HID usage pages](https://usb.org/sites/default/files/hut1_2.pdf#page=16),

View file

@ -53,12 +53,10 @@ A `devicetree_generated.h` error that follows with an "undeclared here" string i
In this example, the error string `DT_N_S_keymap_S_symbol_layer_P_bindings_IDX_12_PH_P_label` indicates a problem with the key binding in position `12` in the `symbol_layer` of the keymap. In this example, the error string `DT_N_S_keymap_S_symbol_layer_P_bindings_IDX_12_PH_P_label` indicates a problem with the key binding in position `12` in the `symbol_layer` of the keymap.
:::info
Key positions are numbered starting from `0` at the top left key on the keymap, incrementing horizontally, row by row. Key positions are numbered starting from `0` at the top left key on the keymap, incrementing horizontally, row by row.
:::
:::tip :::tip
A common mistake that leads to this error is to use [key press keycodes](keymaps/behaviors/key-press.md) without the leading `&kp` binding. That is, having entries such as `SPACE` that should have been `&kp SPACE`. A common mistake that leads to this error is to use [key press keycodes](keymaps/behaviors/key-press.md) without the leading `&kp` binding. That is, having entries such as `&kp A SPACE &kp B` that should have been `&kp A &kp SPACE &kp B`.
::: :::
## Diagnosing Unexpected Build Results ## Diagnosing Unexpected Build Results

View file

@ -175,7 +175,7 @@ Once you have done so, you will need to adjust the `kscan` of your keyboard slig
}; };
``` ```
could have the pin `&pro_micro 6` (D6 in the [Pro Micro pinout](../development/hardware-integration/new-shield.mdx#shield-overlays)) replaced with `&gpio0 8` (P0.08 for nRF MCUs). could have the pin `&pro_micro 6` (D6 in the [Pro Micro pinout](../hardware-integration/new-shield.mdx#shield-overlays)) replaced with `&gpio0 8` (P0.08 for nRF MCUs).
```dts title="<my_keyboard>.keymap" ```dts title="<my_keyboard>.keymap"
&kscan0 { &kscan0 {

View file

@ -280,7 +280,7 @@ Run `zmk keyboard add` again, and the new keyboards should appear in the list.
**Create It Yourself** **Create It Yourself**
If nobody has created a module for your keyboard yet, or if it is your own custom design, you will need to set it up yourself. Your config repo is already set up as a module, so you can define new keyboards there. See ZMK's [new keyboard shield guide](development/hardware-integration/new-shield.mdx) for more information. If nobody has created a module for your keyboard yet, or if it is your own custom design, you will need to set it up yourself. Your config repo is already set up as a module, so you can define new keyboards there. See ZMK's [new keyboard shield guide](hardware-integration/new-shield.mdx) for more information.
ZMK CLI can also help generate some of the boilerplate for defining a new keyboard: ZMK CLI can also help generate some of the boilerplate for defining a new keyboard:

View file

@ -51,7 +51,7 @@ Run `zmk keyboard list` to print a list of supported keyboard hardware.
If ZMK doesn't support your keyboard yet, you can run `zmk keyboard new` to create a new keyboard from a template. If ZMK doesn't support your keyboard yet, you can run `zmk keyboard new` to create a new keyboard from a template.
This won't walk you through all of the details of adding support for a new keyboard, but it will generate most of the boilerplate for you. See the [New Keyboard Shield](development/hardware-integration/new-shield.mdx) guide for how to finish writing the keyboard files. This won't walk you through all of the details of adding support for a new keyboard, but it will generate most of the boilerplate for you. See the [New Keyboard Shield](hardware-integration/new-shield.mdx) guide for how to finish writing the keyboard files.
### Module Management ### Module Management

32
docs/package-lock.json generated
View file

@ -13847,13 +13847,13 @@
} }
}, },
"node_modules/launch-editor": { "node_modules/launch-editor": {
"version": "2.13.2", "version": "2.14.1",
"resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.13.2.tgz", "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.14.1.tgz",
"integrity": "sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==", "integrity": "sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"picocolors": "^1.1.1", "picocolors": "^1.1.1",
"shell-quote": "^1.8.3" "shell-quote": "^1.8.4"
} }
}, },
"node_modules/layout-base": { "node_modules/layout-base": {
@ -20819,9 +20819,9 @@
} }
}, },
"node_modules/shell-quote": { "node_modules/shell-quote": {
"version": "1.8.3", "version": "1.8.4",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.4.tgz",
"integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", "integrity": "sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@ -23154,9 +23154,9 @@
} }
}, },
"node_modules/webpack-dev-server": { "node_modules/webpack-dev-server": {
"version": "5.2.4", "version": "5.2.5",
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.4.tgz", "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.5.tgz",
"integrity": "sha512-GqDPGZN9bRqKBTkp4aWkobDDHMsrXKoGSdOH56smIri8qR0JG8gfL8/v/f/OZR3/OKXjG8uwJbFVhKm/FNU/UA==", "integrity": "sha512-4wZtCquSuv9CKX8oybo+mqxtxZqWz47uM1Ch94lxowBztOhWCbhqvRbfC/mODOwxgV2brY+JGZpHq58/SuVFYg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@types/bonjour": "^3.5.13", "@types/bonjour": "^3.5.13",
@ -23241,9 +23241,9 @@
} }
}, },
"node_modules/webpack-dev-server/node_modules/ws": { "node_modules/webpack-dev-server/node_modules/ws": {
"version": "8.20.0", "version": "8.21.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
"integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"
@ -23636,9 +23636,9 @@
} }
}, },
"node_modules/ws": { "node_modules/ws": {
"version": "7.5.10", "version": "7.5.11",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz",
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "integrity": "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=8.3.0" "node": ">=8.3.0"

View file

@ -107,6 +107,7 @@ module.exports = {
"keymaps/input-processors/transformer", "keymaps/input-processors/transformer",
"keymaps/input-processors/code-mapper", "keymaps/input-processors/code-mapper",
"keymaps/input-processors/temp-layer", "keymaps/input-processors/temp-layer",
"keymaps/input-processors/behaviors",
], ],
}, },
], ],
@ -140,42 +141,40 @@ module.exports = {
"config/studio", "config/studio",
], ],
}, },
{
Development: [
{ {
type: "category", type: "category",
label: "Hardware Integration", label: "Hardware Integration",
link: { link: {
type: "doc", type: "doc",
id: "development/hardware-integration/index", id: "hardware-integration/index",
}, },
collapsed: true, collapsed: true,
items: [ items: [
"development/hardware-integration/new-shield", "hardware-integration/new-board",
"development/hardware-integration/physical-layouts", "hardware-integration/new-shield",
"development/hardware-integration/hardware-metadata-files", "hardware-integration/physical-layouts",
"development/hardware-integration/pinctrl", "hardware-integration/hardware-metadata-files",
"development/hardware-integration/dongle", "hardware-integration/pinctrl",
"development/hardware-integration/shift-registers", "hardware-integration/dongle",
"development/hardware-integration/encoders", "hardware-integration/shift-registers",
"development/hardware-integration/soft-off-setup", "hardware-integration/encoders",
"development/hardware-integration/pointing", "hardware-integration/soft-off-setup",
"development/hardware-integration/new-board", "hardware-integration/pointing",
"development/hardware-integration/battery", "hardware-integration/battery",
{ {
type: "category", type: "category",
label: "Bootloader", label: "Bootloader",
link: { link: {
type: "doc", type: "doc",
id: "development/hardware-integration/bootloader/index", id: "hardware-integration/bootloader/index",
}, },
collapsed: true, collapsed: true,
items: [ items: [
"development/hardware-integration/bootloader/adafruit-nrf52", "hardware-integration/bootloader/adafruit-nrf52",
"development/hardware-integration/bootloader/tinyuf2", "hardware-integration/bootloader/tinyuf2",
"development/hardware-integration/bootloader/samd21-uf2", "hardware-integration/bootloader/samd21-uf2",
"development/hardware-integration/bootloader/rp2", "hardware-integration/bootloader/rp2",
"development/hardware-integration/bootloader/stm32", "hardware-integration/bootloader/stm32",
], ],
}, },
{ {
@ -183,17 +182,19 @@ module.exports = {
label: "Lighting", label: "Lighting",
link: { link: {
type: "doc", type: "doc",
id: "development/hardware-integration/lighting/index", id: "hardware-integration/lighting/index",
}, },
collapsed: true, collapsed: true,
items: [ items: [
"development/hardware-integration/lighting/underglow", "hardware-integration/lighting/underglow",
"development/hardware-integration/lighting/backlight", "hardware-integration/lighting/backlight",
"development/hardware-integration/lighting/led-indicators", "hardware-integration/lighting/led-indicators",
], ],
}, },
], ],
}, },
{
Development: [
{ {
type: "category", type: "category",
label: "Contributing", label: "Contributing",

View file

@ -84,6 +84,34 @@ function HardwareList({ items }: HardwareListProps) {
return ( return (
<> <>
<section>
<Heading as="h2" id="composite">
Composite Keyboards
</Heading>
<p>
Composite keyboards are composed of two main PCBs: a small controller{" "}
<strong>board</strong> with exposed pads, and a larger keyboard PCB (a{" "}
<strong>shield</strong>, in ZMK lingo) with switch footprints. The
board and shield share the same <strong>interconnect</strong>{" "}
standard, which defines the physical and electrical specifications for
the PCB-to-PCB connection.
</p>
<p>
Boards and shields that share the same interconnect are usually
compatible with each other but not always. Check hardware
compatibility before connecting them.
</p>
<p>
Designing a custom composite keyboard with an off-the-shelf controller
board? Check out the{" "}
<a href="/docs/hardware-integration/new-shield">
New Keyboard Shield
</a>{" "}
guide.
</p>
{Object.values(grouped.interconnects).map(mapInterconnect)}
</section>
<section> <section>
<Heading as="h2" id="onboard"> <Heading as="h2" id="onboard">
Onboard Controller Keyboards Onboard Controller Keyboards
@ -93,6 +121,10 @@ function HardwareList({ items }: HardwareListProps) {
the components of a keyboard, including the controller chip, switch the components of a keyboard, including the controller chip, switch
footprints, etc. footprints, etc.
</p> </p>
<p>
Designing a custom keyboard with an onboard controller? Check out the{" "}
<a href="/docs/hardware-integration/new-board">New Board</a> guide.
</p>
<ul> <ul>
{grouped["onboard"] {grouped["onboard"]
.sort((a, b) => a.name.localeCompare(b.name)) .sort((a, b) => a.name.localeCompare(b.name))
@ -101,19 +133,6 @@ function HardwareList({ items }: HardwareListProps) {
))} ))}
</ul> </ul>
</section> </section>
<section>
<Heading as="h2" id="composite">
Composite Keyboards
</Heading>
<p>
Composite keyboards are composed of two main PCBs: a small controller
board with exposed pads, and a larger keyboard PCB (a shield, in ZMK
lingo) with switch footprints and a location where the controller is
added. This location is called an interconnect. Multiple interconnects
can be found below.
</p>
{Object.values(grouped.interconnects).map(mapInterconnect)}
</section>
</> </>
); );
} }

View file

@ -10,17 +10,18 @@
/docs/config/underglow /docs/config/lighting#rgb-underglow 301 /docs/config/underglow /docs/config/lighting#rgb-underglow 301
/docs/features/beta-testing /docs/features/modules#beta-testing 301 /docs/features/beta-testing /docs/features/modules#beta-testing 301
/docs/development/setup /docs/development/local-toolchain/setup 301 /docs/development/setup /docs/development/local-toolchain/setup 301
/docs/development/boards-shields-keymaps /docs/development/hardware-integration/boards-shields-keymaps 301 /docs/development/boards-shields-keymaps /docs/hardware-integration 301
/docs/development/hardware-metadata-files /docs/development/hardware-integration/hardware-metadata-files 301 /docs/development/hardware-metadata-files /docs/hardware-integration/hardware-metadata-files 301
/docs/development/clean-room /docs/development/contributing/clean-room 301 /docs/development/clean-room /docs/development/contributing/clean-room 301
/docs/development/documentation /docs/development/contributing/documentation 301 /docs/development/documentation /docs/development/contributing/documentation 301
/docs/development/new-shield /docs/development/hardware-integration/new-shield 301 /docs/development/new-shield /docs/hardware-integration/new-shield 301
/docs/development/build-flash /docs/development/local-toolchain/build-flash 301 /docs/development/build-flash /docs/development/local-toolchain/build-flash 301
/docs/development/ide-integration /docs/development/local-toolchain/ide-integration 301 /docs/development/ide-integration /docs/development/local-toolchain/ide-integration 301
/docs/development/posix-board /docs/development/local-toolchain/posix-board 301 /docs/development/posix-board /docs/development/local-toolchain/posix-board 301
/docs/development/pre-commit /docs/development/local-toolchain/pre-commit 301 /docs/development/pre-commit /docs/development/local-toolchain/pre-commit 301
/docs/development/tests /docs/development/local-toolchain/tests 301 /docs/development/tests /docs/development/local-toolchain/tests 301
/docs/development/guides/new-behavior /docs/development/new-behavior 301 /docs/development/guides/new-behavior /docs/development/new-behavior 301
/docs/development/hardware-integration/studio-setup /docs/development/hardware-integration/physical-layouts 301 /docs/development/hardware-integration/studio-setup /docs/hardware-integration/physical-layouts 301
/docs/keymaps/behaviors/mod-tap /docs/keymaps/behaviors/hold-tap#mod-tap /docs/keymaps/behaviors/mod-tap /docs/keymaps/behaviors/hold-tap#mod-tap
/docs/user-setup-cli /docs/user-setup 301 /docs/user-setup-cli /docs/user-setup 301
/docs/development/hardware-integration/* /docs/hardware-integration/:splat 301