mirror of
https://github.com/zmkfirmware/zmk.git
synced 2026-03-24 15:05:17 -05:00
Compare commits
21 Commits
docs/prede
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
197f899777 | ||
|
|
a1aca03aa0 | ||
|
|
e4fb39d4a6 | ||
|
|
9278505975 | ||
|
|
ff9d326939 | ||
|
|
df2e979d7e | ||
|
|
8feeb52eaf | ||
|
|
714bbe30b0 | ||
|
|
a23aa009d7 | ||
|
|
2a9ac3ba7f | ||
|
|
27afcb11ef | ||
|
|
61f9ae4de2 | ||
|
|
f6c629e895 | ||
|
|
536375e45e | ||
|
|
e108e319c0 | ||
|
|
9490391e1e | ||
|
|
ed0fa157b1 | ||
|
|
39a14154a9 | ||
|
|
5cfc67a334 | ||
|
|
75c9d5f6fd | ||
|
|
e742da8e47 |
4
.github/workflows/ble-test.yml
vendored
4
.github/workflows/ble-test.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
- 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@v4
|
uses: actions/checkout@v5
|
||||||
- name: Cache west modules
|
- name: Cache west modules
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
env:
|
env:
|
||||||
|
|||||||
43
.github/workflows/build-user-config.yml
vendored
43
.github/workflows/build-user-config.yml
vendored
@@ -30,17 +30,28 @@ jobs:
|
|||||||
name: Fetch Build Keyboards
|
name: Fetch Build Keyboards
|
||||||
outputs:
|
outputs:
|
||||||
build_matrix: ${{ env.build_matrix }}
|
build_matrix: ${{ env.build_matrix }}
|
||||||
|
has_valid_build_matrix: ${{ steps.fetch.outputs.has_valid_build_matrix }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Fetch Build Matrix
|
- name: Fetch Build Matrix
|
||||||
|
id: fetch
|
||||||
run: |
|
run: |
|
||||||
echo "build_matrix=$(yq -oj -I0 '${{ inputs.build_matrix_path }}')" >> $GITHUB_ENV
|
matrix_content=$(yq -oj -I0 '${{ inputs.build_matrix_path }}')
|
||||||
yq -oj "${{ inputs.build_matrix_path }}"
|
|
||||||
|
if [ -z "$matrix_content" ] || [ "$matrix_content" = "null" ]; then
|
||||||
|
echo "::notice file=${{inputs.build_matrix_path}},title=Empty build matrix file::To add a keyboard to the build, see https://zmk.dev/docs/user-setup#add-a-keyboard."
|
||||||
|
echo "has_valid_build_matrix=false" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "build_matrix=$matrix_content" >> $GITHUB_ENV
|
||||||
|
echo "has_valid_build_matrix=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "$matrix_content"
|
||||||
|
fi
|
||||||
|
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: needs.matrix.outputs.has_valid_build_matrix == 'true'
|
||||||
container:
|
container:
|
||||||
image: zmkfirmware/zmk-build-arm:stable
|
image: zmkfirmware/zmk-build-arm:stable
|
||||||
needs: matrix
|
needs: matrix
|
||||||
@@ -56,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@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Create build directory
|
- name: Create build directory
|
||||||
run: |
|
run: |
|
||||||
@@ -147,6 +158,29 @@ jobs:
|
|||||||
echo "See also the [list of released versions](https://github.com/zmkfirmware/zmk/releases)." >> $GITHUB_STEP_SUMMARY
|
echo "See also the [list of released versions](https://github.com/zmkfirmware/zmk/releases)." >> $GITHUB_STEP_SUMMARY
|
||||||
echo "If you wish to stay on main, check the most recent pending release PR for breaking changes. [Our blog](https://zmk.dev/blog) may have upgrade information if breaking changes are significant." >> $GITHUB_STEP_SUMMARY
|
echo "If you wish to stay on main, check the most recent pending release PR for breaking changes. [Our blog](https://zmk.dev/blog) may have upgrade information if breaking changes are significant." >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
- name: Check if building a board without explicit ZMK compat
|
||||||
|
if: always()
|
||||||
|
working-directory: "${{ env.base_dir }}/${{ inputs.config_path }}"
|
||||||
|
run: |
|
||||||
|
if ! (grep "CONFIG_ZMK_BOARD_COMPAT=y" "${{ env.build_dir }}/zephyr/.config" > /dev/null)
|
||||||
|
then
|
||||||
|
original_board=$(echo "${{ matrix.board }}" | sed -e 's$/.*$$')
|
||||||
|
west_board=$(west boards --board-root ${{ env.base_dir }}/zmk/app/module --board-root ${{ env.base_dir }}/zmk/app --board "${original_board}")
|
||||||
|
if [ -z "$west_board" ]; then
|
||||||
|
echo "Not found the board listed with west boards. Skipping further checking."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
west boards --board-root ${{ env.base_dir }}/zmk/app/module --board-root ${{ env.base_dir }}/zmk/app --board "${original_board}" --format "{qualifiers}" | grep "zmk" > /dev/null
|
||||||
|
if [ $? -ne 0 ]
|
||||||
|
then
|
||||||
|
echo "::warning file=build/zephyr/.config,title=Missing ZMK Compat::The selected board does not report explicit ZMK compat. Please verify you've selected the correct board and ZMK variant if one exists"
|
||||||
|
else
|
||||||
|
echo "::error file=build/zephyr/.config,title=Missing ZMK Compat::The selected board is not set up for ZMK and there is a ZMK variant available. See https://zmk.dev/blog/2025/12/09/zephyr-4-1#zmk-board-variant."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
- name: ${{ env.display_name }} Kconfig file
|
- name: ${{ env.display_name }} Kconfig file
|
||||||
run: |
|
run: |
|
||||||
if [ -f "${{ env.build_dir }}/zephyr/.config" ]
|
if [ -f "${{ env.build_dir }}/zephyr/.config" ]
|
||||||
@@ -190,6 +224,7 @@ jobs:
|
|||||||
|
|
||||||
merge:
|
merge:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: needs.matrix.outputs.has_valid_build_matrix == 'true'
|
||||||
needs: build
|
needs: build
|
||||||
name: Merge Output Artifacts
|
name: Merge Output Artifacts
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
10
.github/workflows/build.yml
vendored
10
.github/workflows/build.yml
vendored
@@ -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@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Cache west modules
|
- name: Cache west modules
|
||||||
@@ -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@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Use Node.js
|
- name: Use Node.js
|
||||||
@@ -218,7 +218,7 @@ jobs:
|
|||||||
boards-include: ${{ steps.boards-list.outputs.result }}
|
boards-include: ${{ steps.boards-list.outputs.result }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
- name: Use Node.js
|
- name: Use Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
@@ -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@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Use Node.js
|
- name: Use Node.js
|
||||||
@@ -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@v4
|
uses: actions/checkout@v5
|
||||||
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
|
||||||
|
|||||||
4
.github/workflows/doc-checks.yml
vendored
4
.github/workflows/doc-checks.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
|||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- 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@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: bahmutov/npm-install@v1
|
- uses: bahmutov/npm-install@v1
|
||||||
with:
|
with:
|
||||||
working-directory: docs
|
working-directory: docs
|
||||||
|
|||||||
@@ -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@v4
|
- uses: actions/checkout@v5
|
||||||
- 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
|
||||||
|
|||||||
2
.github/workflows/pre-commit.yml
vendored
2
.github/workflows/pre-commit.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
|||||||
pre-commit:
|
pre-commit:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|||||||
2
.github/workflows/release-please.yml
vendored
2
.github/workflows/release-please.yml
vendored
@@ -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@v4
|
- uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Create major.minor branch
|
- name: Create major.minor branch
|
||||||
if: ${{ needs.handle-commit.outputs.patch == '0' }}
|
if: ${{ needs.handle-commit.outputs.patch == '0' }}
|
||||||
|
|||||||
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
- 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@v4
|
uses: actions/checkout@v5
|
||||||
- name: Cache west modules
|
- name: Cache west modules
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ target_sources_ifdef(CONFIG_ZMK_BATTERY_REPORTING app PRIVATE src/events/battery
|
|||||||
target_sources_ifdef(CONFIG_ZMK_BATTERY_REPORTING app PRIVATE src/battery.c)
|
target_sources_ifdef(CONFIG_ZMK_BATTERY_REPORTING app PRIVATE src/battery.c)
|
||||||
|
|
||||||
target_sources_ifdef(CONFIG_ZMK_HID_INDICATORS app PRIVATE src/events/hid_indicators_changed.c)
|
target_sources_ifdef(CONFIG_ZMK_HID_INDICATORS app PRIVATE src/events/hid_indicators_changed.c)
|
||||||
|
add_subdirectory_ifdef(CONFIG_ZMK_HID_INDICATORS src/indicators)
|
||||||
|
|
||||||
target_sources_ifdef(CONFIG_ZMK_SPLIT app PRIVATE src/events/split_peripheral_status_changed.c)
|
target_sources_ifdef(CONFIG_ZMK_SPLIT app PRIVATE src/events/split_peripheral_status_changed.c)
|
||||||
add_subdirectory_ifdef(CONFIG_ZMK_SPLIT src/split)
|
add_subdirectory_ifdef(CONFIG_ZMK_SPLIT src/split)
|
||||||
|
|||||||
13
app/Kconfig
13
app/Kconfig
@@ -5,6 +5,17 @@ mainmenu "ZMK Firmware"
|
|||||||
|
|
||||||
menu "ZMK"
|
menu "ZMK"
|
||||||
|
|
||||||
|
config ZMK_BOARD_COMPAT
|
||||||
|
bool
|
||||||
|
help
|
||||||
|
Hidden symbol used to hint that a board has been specifically
|
||||||
|
set up with various ZMK requirements in mind, e.g. settings
|
||||||
|
storage, bootloader integration, etc.
|
||||||
|
|
||||||
|
Failure to set this will warn users they may want to verify they
|
||||||
|
used a ZMK variant of an upstream board, or are using a board
|
||||||
|
properly migrated to a newer ZMK version.
|
||||||
|
|
||||||
menu "Basic Keyboard Setup"
|
menu "Basic Keyboard Setup"
|
||||||
|
|
||||||
config ZMK_KEYBOARD_NAME
|
config ZMK_KEYBOARD_NAME
|
||||||
@@ -110,6 +121,8 @@ config ZMK_HID_INDICATORS
|
|||||||
Enable HID indicators, used for detecting state of Caps/Scroll/Num Lock,
|
Enable HID indicators, used for detecting state of Caps/Scroll/Num Lock,
|
||||||
Kata, and Compose.
|
Kata, and Compose.
|
||||||
|
|
||||||
|
rsource "src/indicators/Kconfig"
|
||||||
|
|
||||||
config ZMK_HID_SEPARATE_MOD_RELEASE_REPORT
|
config ZMK_HID_SEPARATE_MOD_RELEASE_REPORT
|
||||||
bool "Release Modifiers Separately"
|
bool "Release Modifiers Separately"
|
||||||
help
|
help
|
||||||
|
|||||||
9
app/boards/adafruit/kb2040/Kconfig.adafruit_kb2040
Normal file
9
app/boards/adafruit/kb2040/Kconfig.adafruit_kb2040
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) 2026 The ZMK Contributors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
config BOARD_ADAFRUIT_KB2040
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_ADAFRUIT_KB2040_RP2040_ZMK
|
||||||
|
imply RETAINED_MEM if BOARD_ADAFRUIT_KB2040_RP2040_ZMK
|
||||||
|
imply RETENTION if BOARD_ADAFRUIT_KB2040_RP2040_ZMK
|
||||||
|
imply RETENTION_BOOT_MODE if BOARD_ADAFRUIT_KB2040_RP2040_ZMK
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) 2026 The ZMK Contributors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
config BOARD_ADAFRUIT_QT_PY_RP2040
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_ADAFRUIT_QT_PY_RP2040_RP2040_ZMK
|
||||||
|
imply RETAINED_MEM if BOARD_ADAFRUIT_QT_PY_RP2040_RP2040_ZMK
|
||||||
|
imply RETENTION if BOARD_ADAFRUIT_QT_PY_RP2040_RP2040_ZMK
|
||||||
|
imply RETENTION_BOOT_MODE if BOARD_ADAFRUIT_QT_PY_RP2040_RP2040_ZMK
|
||||||
|
|
||||||
9
app/boards/boardsource/blok/Kconfig.boardsource_blok
Normal file
9
app/boards/boardsource/blok/Kconfig.boardsource_blok
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) 2026 Pete Johanson
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
config BOARD_BOARDSOURCE_BLOK
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_BOARDSOURCE_BLOK_RP2040_ZMK
|
||||||
|
imply RETAINED_MEM if BOARD_BOARDSOURCE_BLOK_RP2040_ZMK
|
||||||
|
imply RETENTION if BOARD_BOARDSOURCE_BLOK_RP2040_ZMK
|
||||||
|
imply RETENTION_BOOT_MODE if BOARD_BOARDSOURCE_BLOK_RP2040_ZMK
|
||||||
|
|
||||||
@@ -7,6 +7,7 @@ config BOARD_NRFMICRO
|
|||||||
select SOC_NRF52840_QIAA if BOARD_NRFMICRO_NRF52840_ZMK
|
select SOC_NRF52840_QIAA if BOARD_NRFMICRO_NRF52840_ZMK
|
||||||
select SOC_NRF52840_QIAA if BOARD_NRFMICRO_NRF52840_FLIPPED_ZMK
|
select SOC_NRF52840_QIAA if BOARD_NRFMICRO_NRF52840_FLIPPED_ZMK
|
||||||
select SOC_NRF52833_QIAA if BOARD_NRFMICRO_NRF52833_ZMK
|
select SOC_NRF52833_QIAA if BOARD_NRFMICRO_NRF52833_ZMK
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_NRFMICRO_NRF52840_ZMK || BOARD_NRFMICRO_NRF52840_FLIPPED_ZMK || BOARD_NRFMICRO_NRF52833_ZMK
|
||||||
imply RETAINED_MEM if BOARD_NRFMICRO_NRF52840_ZMK || BOARD_NRFMICRO_NRF52840_FLIPPED_ZMK || BOARD_NRFMICRO_NRF52833_ZMK
|
imply RETAINED_MEM if BOARD_NRFMICRO_NRF52840_ZMK || BOARD_NRFMICRO_NRF52840_FLIPPED_ZMK || BOARD_NRFMICRO_NRF52833_ZMK
|
||||||
imply RETENTION if BOARD_NRFMICRO_NRF52840_ZMK || BOARD_NRFMICRO_NRF52840_FLIPPED_ZMK || BOARD_NRFMICRO_NRF52833_ZMK
|
imply RETENTION if BOARD_NRFMICRO_NRF52840_ZMK || BOARD_NRFMICRO_NRF52840_FLIPPED_ZMK || BOARD_NRFMICRO_NRF52833_ZMK
|
||||||
imply RETENTION_BOOT_MODE if BOARD_NRFMICRO_NRF52840_ZMK || BOARD_NRFMICRO_NRF52840_FLIPPED_ZMK || BOARD_NRFMICRO_NRF52833_ZMK
|
imply RETENTION_BOOT_MODE if BOARD_NRFMICRO_NRF52840_ZMK || BOARD_NRFMICRO_NRF52840_FLIPPED_ZMK || BOARD_NRFMICRO_NRF52833_ZMK
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
config BOARD_BLUEMICRO840
|
config BOARD_BLUEMICRO840
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_BLUEMICRO840_NRF52840_ZMK
|
||||||
imply RETAINED_MEM if BOARD_BLUEMICRO840_NRF52840_ZMK
|
imply RETAINED_MEM if BOARD_BLUEMICRO840_NRF52840_ZMK
|
||||||
imply RETENTION if BOARD_BLUEMICRO840_NRF52840_ZMK
|
imply RETENTION if BOARD_BLUEMICRO840_NRF52840_ZMK
|
||||||
imply RETENTION_BOOT_MODE if BOARD_BLUEMICRO840_NRF52840_ZMK
|
imply RETENTION_BOOT_MODE if BOARD_BLUEMICRO840_NRF52840_ZMK
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
config BOARD_TOFU65
|
config BOARD_TOFU65
|
||||||
select SOC_RP2040
|
select SOC_RP2040
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
imply RETAINED_MEM
|
imply RETAINED_MEM
|
||||||
imply RETENTION
|
imply RETENTION
|
||||||
imply RETENTION_BOOT_MODE
|
imply RETENTION_BOOT_MODE
|
||||||
|
|||||||
@@ -3,3 +3,4 @@
|
|||||||
|
|
||||||
config BOARD_BDN9
|
config BOARD_BDN9
|
||||||
select SOC_STM32F072XB
|
select SOC_STM32F072XB
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
config BOARD_PUCHI_BLE
|
config BOARD_PUCHI_BLE
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_PUCHI_BLE_NRF52840_ZMK
|
||||||
imply RETAINED_MEM if BOARD_PUCHI_BLE_NRF52840_ZMK
|
imply RETAINED_MEM if BOARD_PUCHI_BLE_NRF52840_ZMK
|
||||||
imply RETENTION if BOARD_PUCHI_BLE_NRF52840_ZMK
|
imply RETENTION if BOARD_PUCHI_BLE_NRF52840_ZMK
|
||||||
imply RETENTION_BOOT_MODE if BOARD_PUCHI_BLE_NRF52840_ZMK
|
imply RETENTION_BOOT_MODE if BOARD_PUCHI_BLE_NRF52840_ZMK
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
config BOARD_ADV360PRO_LEFT
|
config BOARD_ADV360PRO_LEFT
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
imply RETAINED_MEM
|
imply RETAINED_MEM
|
||||||
imply RETENTION
|
imply RETENTION
|
||||||
imply RETENTION_BOOT_MODE
|
imply RETENTION_BOOT_MODE
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
config BOARD_ADV360PRO_RIGHT
|
config BOARD_ADV360PRO_RIGHT
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
imply RETAINED_MEM
|
imply RETAINED_MEM
|
||||||
imply RETENTION
|
imply RETENTION
|
||||||
imply RETENTION_BOOT_MODE
|
imply RETENTION_BOOT_MODE
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
config BOARD_CORNEISH_ZEN_LEFT
|
config BOARD_CORNEISH_ZEN_LEFT
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
imply RETAINED_MEM
|
imply RETAINED_MEM
|
||||||
imply RETENTION
|
imply RETENTION
|
||||||
imply RETENTION_BOOT_MODE
|
imply RETENTION_BOOT_MODE
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
config BOARD_CORNEISH_ZEN_RIGHT
|
config BOARD_CORNEISH_ZEN_RIGHT
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
imply RETAINED_MEM
|
imply RETAINED_MEM
|
||||||
imply RETENTION
|
imply RETENTION
|
||||||
imply RETENTION_BOOT_MODE
|
imply RETENTION_BOOT_MODE
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
config BOARD_NRF52840_M2
|
config BOARD_NRF52840_M2
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_NRF52840_M2_NRF52840_ZMK
|
||||||
imply RETAINED_MEM if BOARD_NRF52840_M2_NRF52840_ZMK
|
imply RETAINED_MEM if BOARD_NRF52840_M2_NRF52840_ZMK
|
||||||
imply RETENTION if BOARD_NRF52840_M2_NRF52840_ZMK
|
imply RETENTION if BOARD_NRF52840_M2_NRF52840_ZMK
|
||||||
imply RETENTION_BOOT_MODE if BOARD_NRF52840_M2_NRF52840_ZMK
|
imply RETENTION_BOOT_MODE if BOARD_NRF52840_M2_NRF52840_ZMK
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
config BOARD_PILLBUG
|
config BOARD_PILLBUG
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_PILLBUG_NRF52840_ZMK
|
||||||
imply RETAINED_MEM if BOARD_PILLBUG_NRF52840_ZMK
|
imply RETAINED_MEM if BOARD_PILLBUG_NRF52840_ZMK
|
||||||
imply RETENTION if BOARD_PILLBUG_NRF52840_ZMK
|
imply RETENTION if BOARD_PILLBUG_NRF52840_ZMK
|
||||||
imply RETENTION_BOOT_MODE if BOARD_PILLBUG_NRF52840_ZMK
|
imply RETENTION_BOOT_MODE if BOARD_PILLBUG_NRF52840_ZMK
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
board:
|
board:
|
||||||
name: pillbug
|
extend: pillbug
|
||||||
variants:
|
variants:
|
||||||
- name: zmk
|
- name: zmk
|
||||||
qualifier: nrf52840
|
qualifier: nrf52840
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
config BOARD_GLOVE80_LH
|
config BOARD_GLOVE80_LH
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
imply RETAINED_MEM
|
imply RETAINED_MEM
|
||||||
imply RETENTION
|
imply RETENTION
|
||||||
imply RETENTION_BOOT_MODE
|
imply RETENTION_BOOT_MODE
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
config BOARD_GLOVE80_RH
|
config BOARD_GLOVE80_RH
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
imply RETAINED_MEM
|
imply RETAINED_MEM
|
||||||
imply RETENTION
|
imply RETENTION
|
||||||
imply RETENTION_BOOT_MODE
|
imply RETENTION_BOOT_MODE
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
config BOARD_NICE60
|
config BOARD_NICE60
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
imply RETAINED_MEM
|
select ZMK_BOARD_COMPAT if BOARD_NICE60_NRF52840_ZMK
|
||||||
imply RETENTION
|
imply RETAINED_MEM if BOARD_NICE60_NRF52840_ZMK
|
||||||
imply RETENTION_BOOT_MODE
|
imply RETENTION if BOARD_NICE60_NRF52840_ZMK
|
||||||
|
imply RETENTION_BOOT_MODE if BOARD_NICE60_NRF52840_ZMK
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
config BOARD_NICE_NANO
|
config BOARD_NICE_NANO
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_NICE_NANO_NRF52840_ZMK
|
||||||
imply RETAINED_MEM if BOARD_NICE_NANO_NRF52840_ZMK
|
imply RETAINED_MEM if BOARD_NICE_NANO_NRF52840_ZMK
|
||||||
imply RETENTION if BOARD_NICE_NANO_NRF52840_ZMK
|
imply RETENTION if BOARD_NICE_NANO_NRF52840_ZMK
|
||||||
imply RETENTION_BOOT_MODE if BOARD_NICE_NANO_NRF52840_ZMK
|
imply RETENTION_BOOT_MODE if BOARD_NICE_NANO_NRF52840_ZMK
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
config BOARD_NRF52840DK
|
config BOARD_NRF52840DK
|
||||||
select SOC_NRF52840_QIAA if BOARD_NRF52840DK_NRF52840_ZMK
|
select SOC_NRF52840_QIAA if BOARD_NRF52840DK_NRF52840_ZMK
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_NRF52840DK_NRF52840_ZMK
|
||||||
|
|||||||
5
app/boards/nordic/nrf52840dongle/Kconfig.nrf52840dongle
Normal file
5
app/boards/nordic/nrf52840dongle/Kconfig.nrf52840dongle
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Copyright (c) 2026 The ZMK Contributors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
config BOARD_NRF52840DONGLE
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_NRF52840DONGLE_NRF52840_ZMK
|
||||||
@@ -4,5 +4,5 @@
|
|||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
config BOARD_PLANCK
|
config BOARD_PLANCK
|
||||||
bool "Planck Keyboard"
|
|
||||||
select SOC_STM32F303XC
|
select SOC_STM32F303XC
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
|
|||||||
@@ -5,3 +5,4 @@
|
|||||||
|
|
||||||
config BOARD_PREONIC
|
config BOARD_PREONIC
|
||||||
select SOC_STM32F303XC
|
select SOC_STM32F303XC
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
config BOARD_FERRIS
|
config BOARD_FERRIS
|
||||||
select SOC_STM32F072XB
|
select SOC_STM32F072XB
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
imply RETAINED_MEM
|
imply RETAINED_MEM
|
||||||
imply RETENTION
|
imply RETENTION
|
||||||
imply RETENTION_BOOT_MODE
|
imply RETENTION_BOOT_MODE
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
config BOARD_BT60
|
config BOARD_BT60
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
imply RETAINED_MEM
|
imply RETAINED_MEM
|
||||||
imply RETENTION
|
imply RETENTION
|
||||||
imply RETENTION_BOOT_MODE
|
imply RETENTION_BOOT_MODE
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
config BOARD_BT60_HS
|
config BOARD_BT60_HS
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
imply RETAINED_MEM
|
imply RETAINED_MEM
|
||||||
imply RETENTION
|
imply RETENTION
|
||||||
imply RETENTION_BOOT_MODE
|
imply RETENTION_BOOT_MODE
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
config BOARD_BT65
|
config BOARD_BT65
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
imply RETAINED_MEM
|
imply RETAINED_MEM
|
||||||
imply RETENTION
|
imply RETENTION
|
||||||
imply RETENTION_BOOT_MODE
|
imply RETENTION_BOOT_MODE
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
config BOARD_BT75
|
config BOARD_BT75
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
imply RETAINED_MEM
|
imply RETAINED_MEM
|
||||||
imply RETENTION
|
imply RETENTION
|
||||||
imply RETENTION_BOOT_MODE
|
imply RETENTION_BOOT_MODE
|
||||||
|
|||||||
6
app/boards/qmk/proton_c/Kconfig.proton_c
Normal file
6
app/boards/qmk/proton_c/Kconfig.proton_c
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Copyright (c) 2026 The ZMK Contributors
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config BOARD_PROTON_C
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
|
|
||||||
10
app/boards/raspberrypi/rpi_pico/Kconfig.rpi_pico
Normal file
10
app/boards/raspberrypi/rpi_pico/Kconfig.rpi_pico
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Copyright (c) 2026 The ZMK Contributors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
config BOARD_RPI_PICO
|
||||||
|
select SOC_RP2040
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_RPI_PICO_RP2040_ZMK
|
||||||
|
imply RETAINED_MEM if BOARD_RPI_PICO_RP2040_ZMK
|
||||||
|
imply RETENTION if BOARD_RPI_PICO_RP2040_ZMK
|
||||||
|
imply RETENTION_BOOT_MODE if BOARD_RPI_PICO_RP2040_ZMK
|
||||||
|
|
||||||
9
app/boards/seeed/seeeduino_xiao/Kconfig.seeeduino_xiao
Normal file
9
app/boards/seeed/seeeduino_xiao/Kconfig.seeeduino_xiao
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) 2026 Pete Johanson
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
config BOARD_SEEEDUINO_XIAO
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_SEEEDUINO_XIAO_SAMD21G18A_ZMK
|
||||||
|
imply RETAINED_MEM if BOARD_SEEEDUINO_XIAO_SAMD21G18A_ZMK
|
||||||
|
imply RETENTION if BOARD_SEEEDUINO_XIAO_SAMD21G18A_ZMK
|
||||||
|
imply RETENTION_BOOT_MODE if BOARD_SEEEDUINO_XIAO_SAMD21G18A_ZMK
|
||||||
|
|
||||||
10
app/boards/seeed/xiao_ble/Kconfig.xiao_ble
Normal file
10
app/boards/seeed/xiao_ble/Kconfig.xiao_ble
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Copyright (c) 2026 Pete Johanson
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
config BOARD_XIAO_BLE
|
||||||
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_XIAO_BLE_NRF52840_ZMK
|
||||||
|
imply RETAINED_MEM if BOARD_XIAO_BLE_NRF52840_ZMK
|
||||||
|
imply RETENTION if BOARD_XIAO_BLE_NRF52840_ZMK
|
||||||
|
imply RETENTION_BOOT_MODE if BOARD_XIAO_BLE_NRF52840_ZMK
|
||||||
|
|
||||||
@@ -26,6 +26,7 @@ endchoice
|
|||||||
|
|
||||||
config LV_Z_MEM_POOL_SIZE
|
config LV_Z_MEM_POOL_SIZE
|
||||||
default 8192 if ZMK_DISPLAY_STATUS_SCREEN_CUSTOM
|
default 8192 if ZMK_DISPLAY_STATUS_SCREEN_CUSTOM
|
||||||
|
default 5120 if ZMK_DISPLAY_STATUS_SCREEN_BUILT_IN
|
||||||
|
|
||||||
config ZMK_DISPLAY_STATUS_SCREEN_CUSTOM
|
config ZMK_DISPLAY_STATUS_SCREEN_CUSTOM
|
||||||
imply NICE_VIEW_WIDGET_STATUS
|
imply NICE_VIEW_WIDGET_STATUS
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
// | | | | | | | | | | | |
|
// | | | | | | | | | | | |
|
||||||
bindings = <
|
bindings = <
|
||||||
&bt BT_CLR &bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &bt BT_SEL 3 &bt BT_SEL 4 &trans &trans &trans &trans &trans &trans
|
&bt BT_CLR &bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &bt BT_SEL 3 &bt BT_SEL 4 &trans &trans &trans &trans &trans &trans
|
||||||
&trans &kp INS &kp PSCRN &kp K_CMENU &trans &trans &kp PG_UP &trans &kp UP &trans &kp N0 &trans
|
&trans &kp INS &kp PSCRN &kp K_CMENU &trans &trans &kp PG_UP &trans &kp UP &trans &trans &trans
|
||||||
&trans &kp LALT &kp LCTRL &kp LSHFT &trans &kp CLCK &kp PG_DN &kp LEFT &kp DOWN &kp RIGHT &kp DEL &kp BSPC
|
&trans &kp LALT &kp LCTRL &kp LSHFT &trans &kp CLCK &kp PG_DN &kp LEFT &kp DOWN &kp RIGHT &kp DEL &kp BSPC
|
||||||
&trans &kp K_UNDO &kp K_CUT &kp K_COPY &kp K_PASTE &trans &trans &trans &trans &trans &trans &trans &trans &trans
|
&trans &kp K_UNDO &kp K_CUT &kp K_COPY &kp K_PASTE &trans &trans &trans &trans &trans &trans &trans &trans &trans
|
||||||
&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans
|
&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# Copyright (c) 2026 The ZMK Contributors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
config BOARD_SPARKFUN_PRO_MICRO_RP2040
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_SPARKFUN_PRO_MICRO_RP2040_RP2040_ZMK
|
||||||
|
imply RETAINED_MEM if BOARD_SPARKFUN_PRO_MICRO_RP2040_RP2040_ZMK
|
||||||
|
imply RETENTION if BOARD_SPARKFUN_PRO_MICRO_RP2040_RP2040_ZMK
|
||||||
|
imply RETENTION_BOOT_MODE if BOARD_SPARKFUN_PRO_MICRO_RP2040_RP2040_ZMK
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Copyright (c) 2026 The ZMK Contributors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
config BOARD_BLACKPILL_F401CC
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Copyright (c) 2026 The ZMK Contributors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
config BOARD_BLACKPILL_F401CE
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Copyright (c) 2026 The ZMK Contributors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
config BOARD_BLACKPILL_F411CE
|
||||||
|
select ZMK_BOARD_COMPAT
|
||||||
|
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
config BOARD_MIKOTO
|
config BOARD_MIKOTO
|
||||||
select SOC_NRF52840_QIAA
|
select SOC_NRF52840_QIAA
|
||||||
|
select ZMK_BOARD_COMPAT if BOARD_MIKOTO_NRF52840_ZMK
|
||||||
imply RETAINED_MEM if BOARD_MIKOTO_NRF52840_ZMK
|
imply RETAINED_MEM if BOARD_MIKOTO_NRF52840_ZMK
|
||||||
imply RETENTION if BOARD_MIKOTO_NRF52840_ZMK
|
imply RETENTION if BOARD_MIKOTO_NRF52840_ZMK
|
||||||
imply RETENTION_BOOT_MODE if BOARD_MIKOTO_NRF52840_ZMK
|
imply RETENTION_BOOT_MODE if BOARD_MIKOTO_NRF52840_ZMK
|
||||||
|
|||||||
37
app/dts/bindings/indicators/zmk,indicator-leds.yaml
Normal file
37
app/dts/bindings/indicators/zmk,indicator-leds.yaml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Copyright (c) 2025, The ZMK Contributors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
description: Display the states of HID indicators using LEDs
|
||||||
|
|
||||||
|
compatible: "zmk,indicator-leds"
|
||||||
|
|
||||||
|
child-binding:
|
||||||
|
properties:
|
||||||
|
leds:
|
||||||
|
type: phandles
|
||||||
|
required: true
|
||||||
|
description: One or more LED devices to control
|
||||||
|
|
||||||
|
indicator:
|
||||||
|
type: int
|
||||||
|
required: true
|
||||||
|
description: HID_INDICATOR_* value to indicate (see dt-bindings/zmk/hid_indicators.h)
|
||||||
|
|
||||||
|
active-brightness:
|
||||||
|
type: int
|
||||||
|
description: LED brightness in percent when the indicator is active
|
||||||
|
default: 100
|
||||||
|
|
||||||
|
inactive-brightness:
|
||||||
|
type: int
|
||||||
|
description: LED brightness in percent when the indicator is not active
|
||||||
|
default: 0
|
||||||
|
|
||||||
|
disconnected-brightness:
|
||||||
|
type: int
|
||||||
|
description: LED brightness in percent when the keyboard is not connected to any device
|
||||||
|
default: 0
|
||||||
|
|
||||||
|
on-while-idle:
|
||||||
|
type: boolean
|
||||||
|
description: Keep LEDs enabled even when the keyboard is idle and on battery power
|
||||||
18
app/include/dt-bindings/zmk/hid_indicators.h
Normal file
18
app/include/dt-bindings/zmk/hid_indicators.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2026 The ZMK Contributors
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <dt-bindings/zmk/hid_usage.h>
|
||||||
|
|
||||||
|
// hid.h defines HID_USAGE_LED_NUM_LOCK as the minimum value, so that is bit
|
||||||
|
// zero in the report, and all other indicators are relative to that.
|
||||||
|
|
||||||
|
#define HID_INDICATOR_NUM_LOCK (1 << (HID_USAGE_LED_NUM_LOCK - HID_USAGE_LED_NUM_LOCK))
|
||||||
|
#define HID_INDICATOR_CAPS_LOCK (1 << (HID_USAGE_LED_CAPS_LOCK - HID_USAGE_LED_NUM_LOCK))
|
||||||
|
#define HID_INDICATOR_SCROLL_LOCK (1 << (HID_USAGE_LED_SCROLL_LOCK - HID_USAGE_LED_NUM_LOCK))
|
||||||
|
#define HID_INDICATOR_COMPOSE (1 << (HID_USAGE_LED_COMPOSE - HID_USAGE_LED_NUM_LOCK))
|
||||||
|
#define HID_INDICATOR_KANA (1 << (HID_USAGE_LED_KANA - HID_USAGE_LED_NUM_LOCK))
|
||||||
@@ -61,7 +61,7 @@ config ZMK_KSCAN_MATRIX_WAIT_BEFORE_INPUTS
|
|||||||
|
|
||||||
config ZMK_KSCAN_MATRIX_WAIT_BETWEEN_OUTPUTS
|
config ZMK_KSCAN_MATRIX_WAIT_BETWEEN_OUTPUTS
|
||||||
int "Ticks to wait between each output when scanning"
|
int "Ticks to wait between each output when scanning"
|
||||||
default 1 if SOC_RP2040
|
default 1 if SOC_RP2040 || SOC_SERIES_RP2350
|
||||||
default 0
|
default 0
|
||||||
help
|
help
|
||||||
When iterating over each output to drive it active, read inputs, then set
|
When iterating over each output to drive it active, read inputs, then set
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ struct ec11_data {
|
|||||||
const struct sensor_trigger *trigger;
|
const struct sensor_trigger *trigger;
|
||||||
|
|
||||||
#if defined(CONFIG_EC11_TRIGGER_OWN_THREAD)
|
#if defined(CONFIG_EC11_TRIGGER_OWN_THREAD)
|
||||||
K_THREAD_STACK_MEMBER(thread_stack, CONFIG_EC11_THREAD_STACK_SIZE);
|
K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_EC11_THREAD_STACK_SIZE);
|
||||||
struct k_sem gpio_sem;
|
struct k_sem gpio_sem;
|
||||||
struct k_thread thread;
|
struct k_thread thread;
|
||||||
#elif defined(CONFIG_EC11_TRIGGER_GLOBAL_THREAD)
|
#elif defined(CONFIG_EC11_TRIGGER_GLOBAL_THREAD)
|
||||||
|
|||||||
4
app/src/indicators/CMakeLists.txt
Normal file
4
app/src/indicators/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Copyright (c) 2025 The ZMK Contributors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
target_sources_ifdef(CONFIG_ZMK_INDICATOR_LEDS app PRIVATE indicator_leds.c)
|
||||||
4
app/src/indicators/Kconfig
Normal file
4
app/src/indicators/Kconfig
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Copyright (c) 2026 The ZMK Contributors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
rsource "Kconfig.indicator_leds"
|
||||||
19
app/src/indicators/Kconfig.indicator_leds
Normal file
19
app/src/indicators/Kconfig.indicator_leds
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Copyright (c) 2025 The ZMK Contributors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
config ZMK_INDICATOR_LEDS
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
depends on DT_HAS_ZMK_INDICATOR_LEDS_ENABLED
|
||||||
|
select LED
|
||||||
|
select ZMK_HID_INDICATORS
|
||||||
|
|
||||||
|
if ZMK_INDICATOR_LEDS
|
||||||
|
|
||||||
|
config ZMK_INDICATOR_LEDS_INIT_PRIORITY
|
||||||
|
int "ZMK indicator LED initialization priority"
|
||||||
|
default 91
|
||||||
|
help
|
||||||
|
System initialization priority for ZMK indicator LEDs.
|
||||||
|
|
||||||
|
endif # ZMK_INDICATOR_LEDS
|
||||||
226
app/src/indicators/indicator_leds.c
Normal file
226
app/src/indicators/indicator_leds.c
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 The ZMK Contributors
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DT_DRV_COMPAT zmk_indicator_leds
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <zephyr/device.h>
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/drivers/led.h>
|
||||||
|
#include <zephyr/pm/device.h>
|
||||||
|
|
||||||
|
#include <zmk/endpoints.h>
|
||||||
|
#include <zmk/event_manager.h>
|
||||||
|
#include <zmk/hid_indicators.h>
|
||||||
|
#include <zmk/usb.h>
|
||||||
|
#include <zmk/events/activity_state_changed.h>
|
||||||
|
#include <zmk/events/endpoint_changed.h>
|
||||||
|
#include <zmk/events/hid_indicators_changed.h>
|
||||||
|
#include <zmk/events/usb_conn_state_changed.h>
|
||||||
|
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
|
struct indicator_led_child_config {
|
||||||
|
size_t leds_len;
|
||||||
|
const struct led_dt_spec *leds;
|
||||||
|
|
||||||
|
zmk_hid_indicators_t indicator;
|
||||||
|
uint8_t active_brightness;
|
||||||
|
uint8_t inactive_brightness;
|
||||||
|
uint8_t disconnected_brightness;
|
||||||
|
bool on_while_idle;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct indicator_led_config {
|
||||||
|
size_t indicators_len;
|
||||||
|
const struct indicator_led_child_config *indicators;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct indicator_led_data {
|
||||||
|
enum zmk_activity_state activity_state;
|
||||||
|
zmk_hid_indicators_t indicators;
|
||||||
|
bool usb_powered;
|
||||||
|
bool pm_suspended;
|
||||||
|
bool endpoint_connected;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool is_led_disabled(const struct indicator_led_child_config *config,
|
||||||
|
const struct indicator_led_data *data) {
|
||||||
|
// LEDs should always be off if the device is suspended.
|
||||||
|
if (data->pm_suspended) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the keyboard is powered, LEDs don't need to be disabled to save power.
|
||||||
|
if (data->usb_powered) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (data->activity_state) {
|
||||||
|
case ZMK_ACTIVITY_ACTIVE:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case ZMK_ACTIVITY_IDLE:
|
||||||
|
return !config->on_while_idle;
|
||||||
|
|
||||||
|
case ZMK_ACTIVITY_SLEEP:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_ERR("Unhandled activity state %d", data->activity_state);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t get_brightness(const struct indicator_led_child_config *config,
|
||||||
|
const struct indicator_led_data *data) {
|
||||||
|
if (is_led_disabled(config, data)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data->endpoint_connected) {
|
||||||
|
return config->disconnected_brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool active = data->indicators & config->indicator;
|
||||||
|
return active ? config->active_brightness : config->inactive_brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int update_indicator(const struct indicator_led_child_config *config,
|
||||||
|
const struct indicator_led_data *data) {
|
||||||
|
const uint8_t value = get_brightness(config, data);
|
||||||
|
|
||||||
|
for (int i = 0; i < config->leds_len; i++) {
|
||||||
|
const struct led_dt_spec *spec = &config->leds[i];
|
||||||
|
const int err = led_set_brightness_dt(spec, value);
|
||||||
|
if (err) {
|
||||||
|
LOG_ERR("Failed to set %s %u to %u%%: %d", spec->dev->name, spec->index, value, err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Set %s %u to %u%%", spec->dev->name, spec->index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int update_device(const struct device *dev) {
|
||||||
|
const struct indicator_led_config *config = dev->config;
|
||||||
|
struct indicator_led_data *data = dev->data;
|
||||||
|
|
||||||
|
data->activity_state = zmk_activity_get_state();
|
||||||
|
data->indicators = zmk_hid_indicators_get_current_profile();
|
||||||
|
data->usb_powered = zmk_usb_is_powered();
|
||||||
|
data->endpoint_connected = zmk_endpoint_is_connected();
|
||||||
|
|
||||||
|
for (int i = 0; i < config->indicators_len; i++) {
|
||||||
|
const int err = update_indicator(&config->indicators[i], data);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INST_DEV(n) DEVICE_DT_GET(DT_DRV_INST(n)),
|
||||||
|
static const struct device *all_instances[] = {DT_INST_FOREACH_STATUS_OKAY(INST_DEV)};
|
||||||
|
|
||||||
|
static void update_all_indicators(struct k_work *work) {
|
||||||
|
LOG_DBG("Updating indicator LEDs");
|
||||||
|
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(all_instances); i++) {
|
||||||
|
if (device_is_ready(all_instances[i])) {
|
||||||
|
update_device(all_instances[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We may get multiple events at the same time (e.g. endpoint changed will
|
||||||
|
// also trigger HID indicators changed), but we only need to update the LEDs
|
||||||
|
// once per batch of events, so defer the updates with a work item.
|
||||||
|
static K_WORK_DEFINE(update_all_indicators_work, update_all_indicators);
|
||||||
|
|
||||||
|
static int indicator_led_event_listener(const zmk_event_t *eh) {
|
||||||
|
k_work_submit(&update_all_indicators_work);
|
||||||
|
return ZMK_EV_EVENT_BUBBLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int indicator_led_init(const struct device *dev) { return update_device(dev); }
|
||||||
|
|
||||||
|
ZMK_LISTENER(indicator_led, indicator_led_event_listener);
|
||||||
|
ZMK_SUBSCRIPTION(indicator_led, zmk_activity_state_changed);
|
||||||
|
ZMK_SUBSCRIPTION(indicator_led, zmk_hid_indicators_changed);
|
||||||
|
ZMK_SUBSCRIPTION(indicator_led, zmk_usb_conn_state_changed);
|
||||||
|
ZMK_SUBSCRIPTION(indicator_led, zmk_endpoint_changed);
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_PM_DEVICE)
|
||||||
|
|
||||||
|
static int indicator_led_init_pm_action(const struct device *dev, enum pm_device_action action) {
|
||||||
|
struct indicator_led_data *data = dev->data;
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case PM_DEVICE_ACTION_SUSPEND:
|
||||||
|
data->pm_suspended = true;
|
||||||
|
return update_device(dev);
|
||||||
|
|
||||||
|
case PM_DEVICE_ACTION_RESUME:
|
||||||
|
data->pm_suspended = false;
|
||||||
|
return update_device(dev);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // IS_ENABLED(CONFIG_PM_DEVICE)
|
||||||
|
|
||||||
|
#define LED_DT_SPEC_GET_BY_IDX(node_id, prop, idx) \
|
||||||
|
LED_DT_SPEC_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx))
|
||||||
|
|
||||||
|
#define CHILD_LEDS_ARRAY(inst) DT_CAT(indicator_led_dt_spec_, inst)
|
||||||
|
|
||||||
|
#define DEFINE_CHILD_LEDS(inst) \
|
||||||
|
static const struct led_dt_spec CHILD_LEDS_ARRAY(inst)[] = { \
|
||||||
|
DT_FOREACH_PROP_ELEM_SEP(inst, leds, LED_DT_SPEC_GET_BY_IDX, (, )), \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CHILD_CONFIG(inst) \
|
||||||
|
{ \
|
||||||
|
.leds_len = ARRAY_SIZE(CHILD_LEDS_ARRAY(inst)), \
|
||||||
|
.leds = CHILD_LEDS_ARRAY(inst), \
|
||||||
|
.indicator = DT_PROP(inst, indicator), \
|
||||||
|
.active_brightness = DT_PROP_OR(inst, active_brightness, 100), \
|
||||||
|
.inactive_brightness = DT_PROP_OR(inst, inactive_brightness, 0), \
|
||||||
|
.disconnected_brightness = DT_PROP_OR(inst, disconnected_brightness, 0), \
|
||||||
|
.on_while_idle = DT_PROP_OR(inst, on_while_idle, false), \
|
||||||
|
},
|
||||||
|
|
||||||
|
#define INDICATOR_LED_DEVICE(n) \
|
||||||
|
DT_INST_FOREACH_CHILD(n, DEFINE_CHILD_LEDS) \
|
||||||
|
\
|
||||||
|
static const struct indicator_led_child_config indicator_led_children_##n[] = { \
|
||||||
|
DT_INST_FOREACH_CHILD(n, CHILD_CONFIG)}; \
|
||||||
|
\
|
||||||
|
static const struct indicator_led_config indicator_led_config_##n = { \
|
||||||
|
.indicators_len = ARRAY_SIZE(indicator_led_children_##n), \
|
||||||
|
.indicators = indicator_led_children_##n, \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
static struct indicator_led_data indicator_led_data_##n = { \
|
||||||
|
.activity_state = ZMK_ACTIVITY_ACTIVE, \
|
||||||
|
.indicators = 0, \
|
||||||
|
.usb_powered = true, \
|
||||||
|
.pm_suspended = false, \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
PM_DEVICE_DT_INST_DEFINE(n, indicator_led_init_pm_action); \
|
||||||
|
\
|
||||||
|
DEVICE_DT_INST_DEFINE(n, &indicator_led_init, PM_DEVICE_DT_INST_GET(n), \
|
||||||
|
&indicator_led_data_##n, &indicator_led_config_##n, POST_KERNEL, \
|
||||||
|
CONFIG_ZMK_INDICATOR_LEDS_INIT_PRIORITY, NULL);
|
||||||
|
|
||||||
|
DT_INST_FOREACH_STATUS_OKAY(INDICATOR_LED_DEVICE);
|
||||||
@@ -22,8 +22,8 @@ config ZMK_SPLIT_ROLE_CENTRAL
|
|||||||
select BT_SCAN_WITH_IDENTITY
|
select BT_SCAN_WITH_IDENTITY
|
||||||
|
|
||||||
# Bump this value needed for concurrent GATT discovery of splits
|
# Bump this value needed for concurrent GATT discovery of splits
|
||||||
config BT_L2CAP_TX_BUF_COUNT
|
config BT_ATT_TX_COUNT
|
||||||
default 5 if ZMK_SPLIT_ROLE_CENTRAL
|
default 10 if ZMK_SPLIT_ROLE_CENTRAL
|
||||||
|
|
||||||
if ZMK_SPLIT_ROLE_CENTRAL
|
if ZMK_SPLIT_ROLE_CENTRAL
|
||||||
|
|
||||||
|
|||||||
@@ -59,11 +59,20 @@ config ZMK_STUDIO_TRANSPORT_UART
|
|||||||
select RING_BUFFER
|
select RING_BUFFER
|
||||||
default y if $(dt_chosen_enabled,$(DT_CHOSEN_ZMK_STUDIO_RPC_UART))
|
default y if $(dt_chosen_enabled,$(DT_CHOSEN_ZMK_STUDIO_RPC_UART))
|
||||||
|
|
||||||
|
if ZMK_STUDIO_TRANSPORT_UART
|
||||||
|
|
||||||
config ZMK_STUDIO_TRANSPORT_UART_RX_STACK_SIZE
|
config ZMK_STUDIO_TRANSPORT_UART_RX_STACK_SIZE
|
||||||
int "RX Stack Size"
|
int "RX Stack Size"
|
||||||
depends on !UART_INTERRUPT_DRIVEN
|
depends on !UART_INTERRUPT_DRIVEN
|
||||||
default 512
|
default 512
|
||||||
|
|
||||||
|
config ZMK_STUDIO_TRANSPORT_UART_RX_PRIORITY
|
||||||
|
int "RX Thread Priority"
|
||||||
|
depends on !UART_INTERRUPT_DRIVEN
|
||||||
|
default 9
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
config ZMK_STUDIO_TRANSPORT_BLE
|
config ZMK_STUDIO_TRANSPORT_BLE
|
||||||
bool "BLE (GATT)"
|
bool "BLE (GATT)"
|
||||||
select RING_BUFFER
|
select RING_BUFFER
|
||||||
@@ -71,9 +80,12 @@ config ZMK_STUDIO_TRANSPORT_BLE
|
|||||||
depends on ZMK_BLE
|
depends on ZMK_BLE
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
|
||||||
config BT_CONN_TX_MAX
|
config BT_CONN_TX_MAX
|
||||||
default 64 if ZMK_STUDIO_TRANSPORT_BLE
|
default 64 if ZMK_STUDIO_TRANSPORT_BLE
|
||||||
|
|
||||||
|
if ZMK_STUDIO_TRANSPORT_BLE
|
||||||
|
|
||||||
config ZMK_STUDIO_TRANSPORT_BLE_PREF_LATENCY
|
config ZMK_STUDIO_TRANSPORT_BLE_PREF_LATENCY
|
||||||
int "BLE Transport preferred latency"
|
int "BLE Transport preferred latency"
|
||||||
default 10
|
default 10
|
||||||
@@ -81,6 +93,8 @@ config ZMK_STUDIO_TRANSPORT_BLE_PREF_LATENCY
|
|||||||
When the studio UI is connected, a lower latency can be requested in order
|
When the studio UI is connected, a lower latency can be requested in order
|
||||||
to make the interactions between keyboard and studio faster.
|
to make the interactions between keyboard and studio faster.
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
config ZMK_STUDIO_RPC_THREAD_STACK_SIZE
|
config ZMK_STUDIO_RPC_THREAD_STACK_SIZE
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ static void uart_rx_main(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
K_THREAD_DEFINE(uart_transport_read_thread, CONFIG_ZMK_STUDIO_TRANSPORT_UART_RX_STACK_SIZE,
|
K_THREAD_DEFINE(uart_transport_read_thread, CONFIG_ZMK_STUDIO_TRANSPORT_UART_RX_STACK_SIZE,
|
||||||
uart_rx_main, NULL, NULL, NULL, K_LOWEST_APPLICATION_THREAD_PRIO, 0, 0);
|
uart_rx_main, NULL, NULL, NULL, CONFIG_ZMK_STUDIO_TRANSPORT_UART_RX_PRIORITY, 0, 0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -80,36 +80,36 @@ As a result, all board definitions found in the ZMK tree now must be used with a
|
|||||||
As part of this change, ZMK is now using board/shield revisions, rather than duplicate board/shield definitions. This means that instead of having e.g. `nice_nano`, and `nice_nano_v2`, we only have `nice_nano`, which by default points to the `2.0.0` revision. To point to the original Nice!Nano V1, you would need to use `nice_nano@1.0.0` where you would have previously used `nice_nano`. Of course, you could also put `nice_nano@2.0.0` if you wished to make that explicit, instead of merely replacing `nice_nano_v2` with `nice_nano`. Some boards, such as the `nrfmicro`, also have additional _board qualifiers_ such as the choice between multiple SoCs. Board qualifiers must always be specified, and do not have defaults. See [Zephyr's overview](https://docs.zephyrproject.org/4.1.0/hardware/porting/board_porting.html#board-terminology) for more information on board qualifiers. The below table provides an overview of some of the differences in in-tree boards we have in ZMK, and how they are selected in the new build system. The shorthand shows the minimum needed to build with a specific board, taking into account defaults.
|
As part of this change, ZMK is now using board/shield revisions, rather than duplicate board/shield definitions. This means that instead of having e.g. `nice_nano`, and `nice_nano_v2`, we only have `nice_nano`, which by default points to the `2.0.0` revision. To point to the original Nice!Nano V1, you would need to use `nice_nano@1.0.0` where you would have previously used `nice_nano`. Of course, you could also put `nice_nano@2.0.0` if you wished to make that explicit, instead of merely replacing `nice_nano_v2` with `nice_nano`. Some boards, such as the `nrfmicro`, also have additional _board qualifiers_ such as the choice between multiple SoCs. Board qualifiers must always be specified, and do not have defaults. See [Zephyr's overview](https://docs.zephyrproject.org/4.1.0/hardware/porting/board_porting.html#board-terminology) for more information on board qualifiers. The below table provides an overview of some of the differences in in-tree boards we have in ZMK, and how they are selected in the new build system. The shorthand shows the minimum needed to build with a specific board, taking into account defaults.
|
||||||
|
|
||||||
- nice!nano (`nice_nano`)
|
- nice!nano (`nice_nano`)
|
||||||
- `nice_nano` -> `nice_nano@1.0.0` (short: `nice_nano@1`)
|
- `nice_nano` -> `nice_nano@1.0.0//zmk` (short: `nice_nano@1//zmk`)
|
||||||
- `nice_nano_v2` -> `nice_nano@2.0.0` (short: `nice_nano`)
|
- `nice_nano_v2` -> `nice_nano@2.0.0//zmk` (short: `nice_nano//zmk`)
|
||||||
- nRFMicro (`nrfmicro/nrf52840`)
|
- nRFMicro (`nrfmicro/nrf52840`)
|
||||||
- `nrfmicro_11` -> `nrfmicro@1.1.0/nrf52840` (short: `nrfmicro@1.1/nrf52840`)
|
- `nrfmicro_11` -> `nrfmicro@1.1.0/nrf52840/zmk` (short: `nrfmicro@1.1/nrf52840/zmk`)
|
||||||
- `nrfmicro_11_flipped` -> `nrfmicro@1.1.0/nrf52840/flipped` (short: `nrfmicro@1.1/nrf52840/flipped`)
|
- `nrfmicro_11_flipped` -> `nrfmicro@1.1.0/nrf52840/flipped_zmk` (short: `nrfmicro@1.1/nrf52840/flipped_zmk`)
|
||||||
- `nrfmicro_13` -> `nrfmicro@1.3.0/nrf52840` (short: `nrfmicro/nrf52840`)
|
- `nrfmicro_13` -> `nrfmicro@1.3.0/nrf52840/zmk` (short: `nrfmicro/nrf52840/zmk`)
|
||||||
- `nrfmicro_13_52833` -> `nrfmicro@1.3.0/nrf52833` (short: `nrfmicro/nrf52833`)
|
- `nrfmicro_13_52833` -> `nrfmicro@1.3.0/nrf52833/zmk` (short: `nrfmicro/nrf52833/zmk`)
|
||||||
- Mikoto (`mikoto`)
|
- Mikoto (`mikoto`)
|
||||||
- `mikoto` -> `mikoto@5.20.0` (short: `mikoto`)
|
- `mikoto` -> `mikoto@5.20.0//zmk` (short: `mikoto//zmk`)
|
||||||
- `mikoto@6.1` -> `mikoto@6.1.0` (short: `mikoto@6`)
|
- `mikoto@6.1` -> `mikoto@6.1.0//zmk` (short: `mikoto@6//zmk`)
|
||||||
- `mikoto@7.2` -> `mikoto@7.2.0` (short: `mikoto@7`)
|
- `mikoto@7.2` -> `mikoto@7.2.0//zmk` (short: `mikoto@7//zmk`)
|
||||||
- XIAO RP2040 (`xiao_rp2040`)
|
- XIAO RP2040 (`xiao_rp2040`)
|
||||||
- `seeeduino_xiao_rp2040` -> `xiao_rp2040`
|
- `seeeduino_xiao_rp2040` -> `xiao_rp2040//zmk`
|
||||||
- XIAO nRF52840/BLE (`xiao_ble`)
|
- XIAO nRF52840/BLE (`xiao_ble`)
|
||||||
- `seeeduino_xiao_ble` -> `xiao_ble`
|
- `seeeduino_xiao_ble` -> `xiao_ble//zmk`
|
||||||
- BT60 (`bt60`)
|
- BT60 (`bt60`)
|
||||||
- `bt60_v1` -> `bt60@1.0.0`
|
- `bt60_v1` -> `bt60@1.0.0//zmk`
|
||||||
- `bt60_v2` -> `bt60@2.0.0`
|
- `bt60_v2` -> `bt60@2.0.0//zmk`
|
||||||
- `bt60_hs` -> `bt60_hs`
|
- `bt60_hs` -> `bt60_hs//zmk`
|
||||||
- Planck (`planck`)
|
- Planck (`planck`)
|
||||||
- `planck_rev6` -> `planck`
|
- `planck_rev6` -> `planck//zmk`
|
||||||
- BDN9 (`bdn9`)
|
- BDN9 (`bdn9`)
|
||||||
- `bdn9_rev2` -> `bdn9`
|
- `bdn9_rev2` -> `bdn9//zmk`
|
||||||
- Ferris Rev2 (`ferris`)
|
- Ferris Rev2 (`ferris`)
|
||||||
- `ferris_rev02` -> `ferris@2.0.0` (short: `ferris`)
|
- `ferris_rev02` -> `ferris@2.0.0//zmk` (short: `ferris//zmk`)
|
||||||
- Corne-ish Zen (`corneish_zen`)
|
- Corne-ish Zen (`corneish_zen`)
|
||||||
- `corneish_zen_v2_left` -> `corneish_zen_left@2.0.0` (short: `corneish_zen_left`)
|
- `corneish_zen_v2_left` -> `corneish_zen_left@2.0.0//zmk` (short: `corneish_zen_left//zmk`)
|
||||||
- `corneish_zen_v2_right` -> `corneish_zen_right@2.0.0` (short: `corneish_zen_right`)
|
- `corneish_zen_v2_right` -> `corneish_zen_right@2.0.0//zmk` (short: `corneish_zen_right//zmk`)
|
||||||
- `corneish_zen_v1_left` -> `corneish_zen_left@1.0.0` (short: `corneish_zen_left@1`)
|
- `corneish_zen_v1_left` -> `corneish_zen_left@1.0.0//zmk` (short: `corneish_zen_left@1//zmk`)
|
||||||
- `corneish_zen_v1_right` -> `corneish_zen_right@1.0.0` (short: `corneish_zen_right@1`)
|
- `corneish_zen_v1_right` -> `corneish_zen_right@1.0.0//zmk` (short: `corneish_zen_right@1//zmk`)
|
||||||
|
|
||||||
The boards above are those which have changed in ZMK's tree, with the addition of the very popular XIAO series. For other boards in Zephyr's tree, please refer to the Zephyr documentation or source files directly.
|
The boards above are those which have changed in ZMK's tree, with the addition of the very popular XIAO series. For other boards in Zephyr's tree, please refer to the Zephyr documentation or source files directly.
|
||||||
|
|
||||||
|
|||||||
41
docs/docs/config/led-indicators.md
Normal file
41
docs/docs/config/led-indicators.md
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
title: LED Indicators Configuration
|
||||||
|
sidebar_label: LED Indicators
|
||||||
|
---
|
||||||
|
|
||||||
|
See the [LED indicators feature page](../features/led-indicators.md) for more details.
|
||||||
|
|
||||||
|
See [Configuration Overview](index.md) for instructions on how to change these settings.
|
||||||
|
|
||||||
|
## Kconfig
|
||||||
|
|
||||||
|
Definition files:
|
||||||
|
|
||||||
|
- [zmk/app/src/indicators/Kconfig](https://github.com/zmkfirmware/zmk/blob/main/app/src/indicators/Kconfig)
|
||||||
|
|
||||||
|
| Config | Type | Description | Default |
|
||||||
|
| ----------------------------------------- | ---- | --------------------------------------------------- | ------- |
|
||||||
|
| `CONFIG_ZMK_INDICATOR_LEDS_INIT_PRIORITY` | int | Indicator LED device driver initialization priority | 91 |
|
||||||
|
|
||||||
|
`CONFIG_ZMK_INDICATOR_LEDS_INIT_PRIORITY` must be set to a larger value than `CONFIG_LED_INIT_PRIORITY`.
|
||||||
|
|
||||||
|
## Indicator LED Driver
|
||||||
|
|
||||||
|
This driver maps HID indicator states to [LED API](https://docs.zephyrproject.org/4.1.0/hardware/peripherals/led.html) devices.
|
||||||
|
|
||||||
|
### Devicetree
|
||||||
|
|
||||||
|
Applies to: `compatible = "zmk,indicator-leds"`
|
||||||
|
|
||||||
|
Definition file: [zmk/app/dts/bindings/indicators/zmk,indicator-leds.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/indicators/zmk%2Cindicator-leds.yaml)
|
||||||
|
|
||||||
|
| Property | Type | Description | Default |
|
||||||
|
| ------------------------- | -------- | --------------------------------------------------------------------- | ------- |
|
||||||
|
| `indicator` | int | The `HID_INDICATOR_*` value to indicate | |
|
||||||
|
| `leds` | phandles | One or more LED devices to control | |
|
||||||
|
| `active-brightness` | int | LED brightness in percent when the indicator is active | 100 |
|
||||||
|
| `inactive-brightness` | int | LED brightness in percent when the indicator is not active | 0 |
|
||||||
|
| `disconnected-brightness` | int | LED brightness in percent when the keyboard is not connected | 0 |
|
||||||
|
| `on-while-idle` | bool | Keep LEDs enabled even when the keyboard is idle and on battery power | false |
|
||||||
|
|
||||||
|
The `indicator` property must be one of the `HID_INDICATOR_*` values defined in [zmk/app/include/dt-bindings/zmk/hid_indicators.h](https://github.com/zmkfirmware/zmk/blob/main/app/include/dt-bindings/zmk/hid_indicators.h). You may also combine values with `|` to make the LED be lit when any of the indicator states are active.
|
||||||
@@ -14,7 +14,8 @@ Definition file: [zmk/app/Kconfig](https://github.com/zmkfirmware/zmk/blob/main/
|
|||||||
### General
|
### General
|
||||||
|
|
||||||
| Config | Type | Description | Default |
|
| Config | Type | Description | Default |
|
||||||
| --------------------------- | ------ | -------------------------------------------- | ------- |
|
| --------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||||
|
| `CONFIG_ZMK_BOARD_COMPAT` | bool | A special config for boards to enable. This helps check if users have accidentally used an upstream Zephyr board without ZMK additions applied | n |
|
||||||
| `CONFIG_ZMK_KEYBOARD_NAME` | string | The name of the keyboard (max 16 characters) | |
|
| `CONFIG_ZMK_KEYBOARD_NAME` | string | The name of the keyboard (max 16 characters) | |
|
||||||
| `CONFIG_ZMK_WPM` | bool | Enable calculating words per minute | n |
|
| `CONFIG_ZMK_WPM` | bool | Enable calculating words per minute | n |
|
||||||
| `CONFIG_HEAP_MEM_POOL_SIZE` | int | Size of the heap memory pool | 8192 |
|
| `CONFIG_HEAP_MEM_POOL_SIZE` | int | Size of the heap memory pool | 8192 |
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ There are three commonly found possibilities:
|
|||||||
Copy the file into your dongle's folder. Then import the file, assign the matrix transform to it, and select it in the `chosen` node:
|
Copy the file into your dongle's folder. Then import the file, assign the matrix transform to it, and select it in the `chosen` node:
|
||||||
|
|
||||||
```dts
|
```dts
|
||||||
#import "my_keyboard-layouts.dtsi"
|
#include "my_keyboard-layouts.dtsi"
|
||||||
|
|
||||||
&physical_layout0 {
|
&physical_layout0 {
|
||||||
transform = <&default_transform>;
|
transform = <&default_transform>;
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ And other miscellaneous ones:
|
|||||||
- A `<keyboard_name>.zmk.yml` file containing [metadata](hardware-metadata-files.md) for the keyboard.
|
- A `<keyboard_name>.zmk.yml` file containing [metadata](hardware-metadata-files.md) for the keyboard.
|
||||||
|
|
||||||
See Zephyr's [board porting guide](https://docs.zephyrproject.org/4.1.0/hardware/porting/board_porting.html) for information on creating a new board.
|
See Zephyr's [board porting guide](https://docs.zephyrproject.org/4.1.0/hardware/porting/board_porting.html) for information on creating a new board.
|
||||||
Also see the [new keyboard shield guide](new-shield.mdx#shield-overlays) for information on parts of the devicetree specifically related to ZMK.
|
See also our [new board guide](new-board.md) for information on creating a ZMK-compatible board variant.
|
||||||
|
|
||||||
[^1]:
|
[^1]:
|
||||||
Parts of these files can live in separate `.dtsi` files (typically in the same directory) that are then `#include`d in the files, to reduce duplication or improve organization.
|
Parts of these files can live in separate `.dtsi` files (typically in the same directory) that are then `#include`d in the files, to reduce duplication or improve organization.
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
---
|
||||||
|
title: LED Indicators
|
||||||
|
sidebar_label: LED Indicators
|
||||||
|
description: Lighting system that indicates HID states such as caps lock.
|
||||||
|
---
|
||||||
|
|
||||||
|
ZMK supports the following five LED indicator states from the HID specification:
|
||||||
|
|
||||||
|
- Num Lock
|
||||||
|
- Caps Lock
|
||||||
|
- Scroll Lock
|
||||||
|
- Compose
|
||||||
|
- Kana
|
||||||
|
|
||||||
|
To connect these indicator states to LEDs on a keyboard, you must do two things in your board or shield files:
|
||||||
|
|
||||||
|
1. Define an LED driver and one or more LEDs to control.
|
||||||
|
2. Configure ZMK to control those LEDs.
|
||||||
|
|
||||||
|
## LED Definitions
|
||||||
|
|
||||||
|
The most common setup is for LEDs to be driven directly from a GPIO pin. The examples on this page show how to controls these using the `gpio-leds` or `pwm-leds` drivers, but you can also use any other [LED driver](https://docs.zephyrproject.org/4.1.0/hardware/peripherals/led.html) from Zephyr.
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
LED strip drivers (e.g. WS2812 LEDs) are not currently supported. More work is needed to support the separate API and avoid conflicts with the underglow system.
|
||||||
|
:::
|
||||||
|
|
||||||
|
In your shield's `.overlay` file or board's `.dts` file, create a `gpio-leds` node and define any LEDs that you want to be able to control. The following example defines two LEDs on `&gpio0 1` and `&gpio0 2` which are enabled by driving the pins high:
|
||||||
|
|
||||||
|
```dts
|
||||||
|
/ {
|
||||||
|
leds {
|
||||||
|
compatible = "gpio-leds";
|
||||||
|
|
||||||
|
num_lock_led: num_lock_led {
|
||||||
|
gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
|
||||||
|
};
|
||||||
|
|
||||||
|
caps_lock_led: caps_lock_led {
|
||||||
|
gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### PWM Brightness Control
|
||||||
|
|
||||||
|
The above example only supports LEDs being off or on at full brightness. If you want to be able to reduce the brightness or use multiple brightness levels, you must use `pwm-leds` instead of `gpio-leds`. Note that this will increase power usage slightly when LEDs are enabled compared to using `gpio-leds`.
|
||||||
|
|
||||||
|
See the [backlight hardware integration page](backlight.mdx) for an example of configuring PWM LEDs.
|
||||||
|
|
||||||
|
## Indicator Definitions
|
||||||
|
|
||||||
|
Now that you have some LEDs defined, you can configure ZMK to use them.
|
||||||
|
|
||||||
|
In your shield's `.overlay` file or board's `.dts` file, add the following include to the top of the file:
|
||||||
|
|
||||||
|
```dts
|
||||||
|
#include <dt-bindings/zmk/hid_indicators.h>
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, add a `zmk,indicator-leds` node. This node can have any number of child nodes. Each child maps an indicator state to one or more LEDs:
|
||||||
|
|
||||||
|
```dts
|
||||||
|
/ {
|
||||||
|
leds {
|
||||||
|
compatible = "gpio-leds";
|
||||||
|
|
||||||
|
// LEDs as defined in the previous step
|
||||||
|
num_lock_led: num_lock_led { ... };
|
||||||
|
caps_lock_led: caps_lock_led { ... };
|
||||||
|
};
|
||||||
|
|
||||||
|
indicators {
|
||||||
|
compatible = "zmk,indicator-leds";
|
||||||
|
|
||||||
|
num_lock_indicator: num_lock {
|
||||||
|
indicator = <HID_INDICATOR_NUM_LOCK>;
|
||||||
|
leds = <&num_lock_led>;
|
||||||
|
};
|
||||||
|
|
||||||
|
caps_lock_indicator: caps_lock {
|
||||||
|
indicator = <HID_INDICATOR_CAPS_LOCK>;
|
||||||
|
leds = <&caps_lock_led>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
The name of each child node is unimportant, but you should give each node a label so users can change their settings in `.keymap` files. Conventionally, you should use one of the following:
|
||||||
|
|
||||||
|
- `num_lock_indicator`
|
||||||
|
- `caps_lock_indicator`
|
||||||
|
- `scroll_lock_indicator`
|
||||||
|
- `compose_indicator`
|
||||||
|
- `kana_indicator`
|
||||||
|
|
||||||
|
(If you have a non-standard setup and need to use different labels, you should document this somewhere so users know how to configure them.)
|
||||||
|
|
||||||
|
Each child node must have an `indicator` property, which is set to one of the following:
|
||||||
|
|
||||||
|
- `HID_INDICATOR_NUM_LOCK`
|
||||||
|
- `HID_INDICATOR_CAPS_LOCK`
|
||||||
|
- `HID_INDICATOR_SCROLL_LOCK`
|
||||||
|
- `HID_INDICATOR_COMPOSE`
|
||||||
|
- `HID_INDICATOR_KANA`
|
||||||
|
|
||||||
|
Each child node must also have an `leds` property, which holds a list of LED nodes to control. In this example, the LEDs are labeled `num_lock_led` and `caps_lock_led`, so the `leds` properties refer to them with `&num_lock_led` and `&caps_lock_led`, respectively.
|
||||||
|
|
||||||
|
You can also control multiple LEDs from the same indicator:
|
||||||
|
|
||||||
|
```dts
|
||||||
|
leds = <&led_1 &led_2>;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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.
|
||||||
187
docs/docs/development/hardware-integration/new-board.md
Normal file
187
docs/docs/development/hardware-integration/new-board.md
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
---
|
||||||
|
title: New Board
|
||||||
|
---
|
||||||
|
|
||||||
|
This guide will walk through the necessary steps to write a [board](./index.mdx#boards--shields) suitable for use with ZMK. Boards used with ZMK fall into two categories:
|
||||||
|
|
||||||
|
- Boards with interconnects, such as `nice_nano` or `seeed_xiao`. Such boards will (active development of ZMK aside) always be used with a shield to create a keyboard.
|
||||||
|
- Boards that are themselves keyboards, such as `bt75` or `ferris`.
|
||||||
|
|
||||||
|
Some keyboards are boards but also have interconnects for modular add-ons. These are considered as keyboard-boards for the purpose of this guide. Details on adding an interconnect for modular add-ons are considered out of scope.
|
||||||
|
|
||||||
|
## 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 that are included with ZMK are generally:
|
||||||
|
|
||||||
|
- Reliably commercially available as individual units
|
||||||
|
- In regular use across multiple shields (i.e. not niche)
|
||||||
|
|
||||||
|
Popular open source designs which are not being sold can also be considered for inclusion.
|
||||||
|
|
||||||
|
There also exist many boards in the tree of upstream Zephyr. We generally accept ZMK-variants of these boards into our tree as well.
|
||||||
|
|
||||||
|
## New ZMK Module Repository
|
||||||
|
|
||||||
|
Regardless of whether you aim to include the board in ZMK or not, you should first write the definition for it in a module. A new ZMK module repository can be created from a template.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
This guide assumes you already have a configured GitHub account. If you don't yet have one, go ahead and [sign up](https://github.com/join) before continuing.
|
||||||
|
:::
|
||||||
|
|
||||||
|
Follow these steps to create your new repository:
|
||||||
|
|
||||||
|
- Visit https://github.com/zmkfirmware/unified-zmk-config-template
|
||||||
|
- Click the green "Use this template" button
|
||||||
|
- In the drop down that opens, click "Use this template".
|
||||||
|
- In the following screen, provide the following information:
|
||||||
|
- A repository name, e.g. `my-board-module`.
|
||||||
|
- A brief description, e.g. `ZMK Support For MyBoard`.
|
||||||
|
- Select Public or Private, depending on your preference.
|
||||||
|
- Click the green "Create repository" button
|
||||||
|
|
||||||
|
The repository is a combination of the directories and files required of a ZMK config, and those required of a shield module.
|
||||||
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
```yaml title="zephyr/module.yml"
|
||||||
|
name: zmk-keyboard-<keyboard_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
if it is a keyboard, or
|
||||||
|
|
||||||
|
```yaml title="zephyr/module.yml"
|
||||||
|
name: zmk-component-<board_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
if it is a board with an interconnect.
|
||||||
|
|
||||||
|
## Write a Zephyr Board Definition
|
||||||
|
|
||||||
|
Zephyr has a guide on writing a board [here](https://docs.zephyrproject.org/4.1.0/hardware/porting/board_porting.html). Follow this guide to create a Zephyr-compatible board. Use the `boards` folder of your ZMK module as a base.
|
||||||
|
|
||||||
|
Once your board definition has been written, we recommend flashing some [Zephyr samples](https://docs.zephyrproject.org/4.1.0/samples/basic/basic.html) to it, to verify that it is working.
|
||||||
|
|
||||||
|
Flashing Zephyr samples can also be very helpful when troubleshooting/testing the functionality of extra features such as LED ICs, Bluetooth, or various sensor ICs.
|
||||||
|
|
||||||
|
## Write a ZMK Variant of Zephyr Board
|
||||||
|
|
||||||
|
To make a board fully compatible with ZMK, you will be creating a ZMK variant of the Zephyr board you made in the previous step. Perform the below actions for each board you've defined, in the case of multi-board split keyboards.
|
||||||
|
|
||||||
|
### Add Variant to board.yml
|
||||||
|
|
||||||
|
Edit your existing `board.yml` file to add the variant:
|
||||||
|
|
||||||
|
```yaml title="board.yml"
|
||||||
|
board:
|
||||||
|
...
|
||||||
|
socs:
|
||||||
|
- name: <soc-1>
|
||||||
|
variants:
|
||||||
|
- name: zmk
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add Kconfig for ZMK Variant
|
||||||
|
|
||||||
|
Add a file to your board's folder called `<your-board>_zmk_defconfig`. This file will be used to set Kconfig flags specific to the ZMK variant.
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
Make sure you know what each Kconfig flag does before you enable it. Some flags may be incompatible with certain hardware, or have other adverse effects.
|
||||||
|
:::
|
||||||
|
|
||||||
|
These flags are typically a subset of the following:
|
||||||
|
|
||||||
|
```yaml title="<your-board>_zmk_defconfig"
|
||||||
|
# SPDX-License-Identifier: <your license>
|
||||||
|
|
||||||
|
# Enable MPU
|
||||||
|
CONFIG_ARM_MPU=y
|
||||||
|
|
||||||
|
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=125000000
|
||||||
|
|
||||||
|
# Enable reset by default
|
||||||
|
CONFIG_RESET=y
|
||||||
|
|
||||||
|
# Enable clock control by default
|
||||||
|
CONFIG_CLOCK_CONTROL=y
|
||||||
|
|
||||||
|
# Code partition needed to target the correct flash range
|
||||||
|
CONFIG_USE_DT_CODE_PARTITION=y
|
||||||
|
|
||||||
|
# Output UF2 by default, native bootloader supports it.
|
||||||
|
CONFIG_BUILD_OUTPUT_UF2=y
|
||||||
|
|
||||||
|
# USB HID
|
||||||
|
CONFIG_ZMK_USB=y
|
||||||
|
|
||||||
|
# BLE HID
|
||||||
|
CONFIG_ZMK_BLE=y
|
||||||
|
|
||||||
|
# Bootloader Support
|
||||||
|
CONFIG_RETAINED_MEM=y
|
||||||
|
CONFIG_RETENTION=y
|
||||||
|
CONFIG_RETENTION_BOOT_MODE=y
|
||||||
|
|
||||||
|
# Settings Support
|
||||||
|
CONFIG_MPU_ALLOW_FLASH_WRITE=y
|
||||||
|
CONFIG_NVS=y
|
||||||
|
CONFIG_SETTINGS_NVS=y
|
||||||
|
CONFIG_FLASH=y
|
||||||
|
CONFIG_FLASH_PAGE_LAYOUT=y
|
||||||
|
CONFIG_FLASH_MAP=y
|
||||||
|
|
||||||
|
|
||||||
|
# Enable HW stack protection
|
||||||
|
CONFIG_HW_STACK_PROTECTION=y
|
||||||
|
|
||||||
|
# Enable GPIO
|
||||||
|
CONFIG_GPIO=y
|
||||||
|
|
||||||
|
# Defaults for matrix scanning to avoid interrupt issues
|
||||||
|
CONFIG_ZMK_KSCAN_MATRIX_POLLING=y
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that none of our in-tree boards have all of the above flags set. We recommend referencing the Kconfig flags from an existing in-tree board with the same SoC as the one you are using for your initial definition, making sure you understand what each flag does.
|
||||||
|
|
||||||
|
### Add Devicetree for ZMK Variant
|
||||||
|
|
||||||
|
```dts title="<your-board>_zmk.dts
|
||||||
|
/*
|
||||||
|
* Copyright (c) <year> <you>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: <your license>
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Include the base board definition
|
||||||
|
#include <../boards/<vendor or you>/<board folder name>/<your board>.dts>
|
||||||
|
// Include predefined boot mode settings, e.g.
|
||||||
|
#include <arm/raspberrypi/rp2040-boot-mode-retention.dtsi>
|
||||||
|
|
||||||
|
// Disable UART nodes if they are not actively in use (wired split) as they increase power draw
|
||||||
|
&uart0 { status = "disabled"; };
|
||||||
|
|
||||||
|
// Reduce the code partition section of the memory and add a storage partition to store ZMK Studio changes
|
||||||
|
&code_partition {
|
||||||
|
reg = <0x100 (DT_SIZE_M(2) - 0x100 - DT_SIZE_K(512))>;
|
||||||
|
};
|
||||||
|
&flash0 {
|
||||||
|
reg = <0x10000000 DT_SIZE_M(2)>;
|
||||||
|
partitions {
|
||||||
|
storage_partition: partition@180000 {
|
||||||
|
reg = <0x180000 DT_SIZE_K(512)>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
See [here](./bootloader/index.mdx) for bootloader instructions for other SoCs. Depending on your SoC and design you may need to make further changes. Please refer to our in-tree boards with the same SoC as yours as examples.
|
||||||
|
|
||||||
|
## 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 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.
|
||||||
@@ -202,7 +202,7 @@ values={[
|
|||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DT_DRV_COMPAT zmk_<name_of_behavior>
|
#define DT_DRV_COMPAT zmk_behavior_<name_of_behavior>
|
||||||
|
|
||||||
// Dependencies
|
// Dependencies
|
||||||
#include <zephyr/device.h>
|
#include <zephyr/device.h>
|
||||||
@@ -247,7 +247,7 @@ static int on_<name_of_behavior>_binding_released(struct zmk_behavior_binding *b
|
|||||||
// API struct
|
// API struct
|
||||||
static const struct behavior_driver_api <name_of_behavior>_driver_api = {
|
static const struct behavior_driver_api <name_of_behavior>_driver_api = {
|
||||||
.binding_pressed = on_<name_of_behavior>_binding_pressed,
|
.binding_pressed = on_<name_of_behavior>_binding_pressed,
|
||||||
.binding_released = on_<name_of_behavior>_binding_pressed,
|
.binding_released = on_<name_of_behavior>_binding_released,
|
||||||
};
|
};
|
||||||
|
|
||||||
BEHAVIOR_DT_INST_DEFINE(0, // Instance Number (0)
|
BEHAVIOR_DT_INST_DEFINE(0, // Instance Number (0)
|
||||||
@@ -273,7 +273,7 @@ BEHAVIOR_DT_INST_DEFINE(0, // Ins
|
|||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DT_DRV_COMPAT zmk_<name_of_behavior>
|
#define DT_DRV_COMPAT zmk_behavior_<name_of_behavior>
|
||||||
|
|
||||||
// Dependencies
|
// Dependencies
|
||||||
#include <zephyr/device.h>
|
#include <zephyr/device.h>
|
||||||
@@ -318,29 +318,30 @@ static int on_<name_of_behavior>_binding_released(struct zmk_behavior_binding *b
|
|||||||
// API struct
|
// API struct
|
||||||
static const struct behavior_driver_api <name_of_behavior>_driver_api = {
|
static const struct behavior_driver_api <name_of_behavior>_driver_api = {
|
||||||
.binding_pressed = on_<name_of_behavior>_binding_pressed,
|
.binding_pressed = on_<name_of_behavior>_binding_pressed,
|
||||||
.binding_released = on_<name_of_behavior>_binding_pressed,
|
.binding_released = on_<name_of_behavior>_binding_released,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define <NAME_OF_BEHAVIOR>_INST(n) \
|
#define <NAME_OF_BEHAVIOR>_INST(n) \
|
||||||
static struct behavior_<name_of_behavior>_data_##n { \
|
static struct behavior_<name_of_behavior>_data_##n { \
|
||||||
.data_param1 = foo1; \
|
.data_param1 = foo1, \
|
||||||
.data_param2 = foo2; \
|
.data_param2 = foo2, \
|
||||||
.data_param3 = foo3; \
|
.data_param3 = foo3, \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
static struct behavior_<name_of_behavior>_config_##n { \
|
static struct behavior_<name_of_behavior>_config_##n { \
|
||||||
.config_param1 = bar1; \
|
.config_param1 = bar1, \
|
||||||
.config_param2 = bar2; \
|
.config_param2 = bar2, \
|
||||||
.config_param3 = bar3; \
|
.config_param3 = bar3, \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
BEHAVIOR_DT_INST_DEFINE(n, \ // Instance Number (Automatically populated by macro)
|
BEHAVIOR_DT_INST_DEFINE(n, /* Instance Number (Automatically populated by macro) */ \
|
||||||
<name_of_behavior>_init, \ // Initialization Function
|
<name_of_behavior>_init, /* Initialization Function */ \
|
||||||
NULL, \ // Power Management Device Pointer
|
NULL, /* Power Management Device Pointer */ \
|
||||||
&<name_of_behavior>_data_##n, \ // Behavior Data Pointer
|
&<name_of_behavior>_data_##n, /* Behavior Data Pointer */ \
|
||||||
&<name_of_behavior>_config_##n, \ // Behavior Configuration Pointer
|
&<name_of_behavior>_config_##n, /* Behavior Configuration Pointer */ \
|
||||||
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT \ // Initialization Level, Device Priority
|
POST_KERNEL, /* Initialization Level */ \
|
||||||
&<name_of_behavior>_driver_api); // API struct
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT /* Device Priority */ \
|
||||||
|
&<name_of_behavior>_driver_api); /* API struct */ \
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(<NAME_OF_BEHAVIOR>_INST)
|
DT_INST_FOREACH_STATUS_OKAY(<NAME_OF_BEHAVIOR>_INST)
|
||||||
|
|
||||||
|
|||||||
67
docs/docs/features/led-indicators.md
Normal file
67
docs/docs/features/led-indicators.md
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
title: LED Indicators
|
||||||
|
sidebar_label: LED Indicators
|
||||||
|
---
|
||||||
|
|
||||||
|
ZMK supports the following five LED indicator states from the HID specification:
|
||||||
|
|
||||||
|
- Num Lock
|
||||||
|
- Caps Lock
|
||||||
|
- Scroll Lock
|
||||||
|
- Compose
|
||||||
|
- Kana
|
||||||
|
|
||||||
|
If your keyboard supports this feature, ZMK will display some or all of these states on LEDs.
|
||||||
|
|
||||||
|
The default behavior for an indicator LED is as follows:
|
||||||
|
|
||||||
|
- If the keyboard is on battery power and idle, the LED is off.
|
||||||
|
- If the keyboard is not connected to any host, the LED is off.
|
||||||
|
- If the indicator state is active, the LED is on at full brightness.
|
||||||
|
- Otherwise, the LED is off.
|
||||||
|
|
||||||
|
If you want to change these behaviors, you can set properties on the devicetree nodes for each indicator in your `.keymap` file. The conventional node labels for indicators are as follows:
|
||||||
|
|
||||||
|
- `num_lock_indicator`
|
||||||
|
- `caps_lock_indicator`
|
||||||
|
- `scroll_lock_indicator`
|
||||||
|
- `compose_indicator`
|
||||||
|
- `kana_indicator`
|
||||||
|
|
||||||
|
The examples below all use `caps_lock_indicator`. To edit a different indicator, use the relevant label for that indicator instead.
|
||||||
|
|
||||||
|
## Idle Behavior
|
||||||
|
|
||||||
|
The `on-while-idle` property prevents the LED from turning off when the keyboard on battery power and idle:
|
||||||
|
|
||||||
|
```dts
|
||||||
|
&caps_lock_indicator {
|
||||||
|
on-while-idle;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## LED Brightness
|
||||||
|
|
||||||
|
The `active-brightness`, `inactive-brightness`, and `disconnected-brightness` properties control the brightness of the LED when the indicator is active, indicator is not active, and the keyboard is not connected to any host, respectively.
|
||||||
|
|
||||||
|
For example, if you want the LED to be off when the indicator is active, 100% brightness when inactive, and 50% brightness when not connected:
|
||||||
|
|
||||||
|
```dts
|
||||||
|
&caps_lock_indicator {
|
||||||
|
active-brightness = <0>;
|
||||||
|
inactive-brightness = <100>;
|
||||||
|
disconnected-brightness = <50>;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
:::note
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 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.
|
||||||
1
docs/docs/keymaps/_footnotes/macos-international.mdx
Normal file
1
docs/docs/keymaps/_footnotes/macos-international.mdx
Normal file
@@ -0,0 +1 @@
|
|||||||
|
On macOS in Japanese mode, `INTERNATIONAL1` is ろ (ro, bottom right on the Apple Japanese keyboard) and `INTERNATIONAL3` is ¥ (yen, top right).
|
||||||
1
docs/docs/keymaps/_footnotes/macos-language.mdx
Normal file
1
docs/docs/keymaps/_footnotes/macos-language.mdx
Normal file
@@ -0,0 +1 @@
|
|||||||
|
On macOS in Japanese mode, `LANG1` is かな (kana, to turn on Japanese IME) and `LANG2` is 英数 (eisuu, to turn off the IME).
|
||||||
@@ -208,8 +208,8 @@ A popular method of implementing Autoshift in ZMK involves a C-preprocessor macr
|
|||||||
as: auto_shift {
|
as: auto_shift {
|
||||||
compatible = "zmk,behavior-hold-tap";
|
compatible = "zmk,behavior-hold-tap";
|
||||||
#binding-cells = <2>;
|
#binding-cells = <2>;
|
||||||
tapping_term_ms = <135>;
|
tapping-term-ms = <135>;
|
||||||
quick_tap_ms = <0>;
|
quick-tap-ms = <0>;
|
||||||
flavor = "tap-preferred";
|
flavor = "tap-preferred";
|
||||||
bindings = <&kp>, <&kp>;
|
bindings = <&kp>, <&kp>;
|
||||||
};
|
};
|
||||||
@@ -299,7 +299,7 @@ One workaround is to create a [macro](macros.md) that invokes those behaviors an
|
|||||||
By default, when another key is pressed while a hold-tap is held, it will trigger the "hold" behavior even if `tapping-term-ms` has not been exceeded yet.
|
By default, when another key is pressed while a hold-tap is held, it will trigger the "hold" behavior even if `tapping-term-ms` has not been exceeded yet.
|
||||||
We refer to the interaction of pressing one key while another is held as the "interrupt", and the way the hold-tap resolves is referred to as its "interrupt flavor".
|
We refer to the interaction of pressing one key while another is held as the "interrupt", and the way the hold-tap resolves is referred to as its "interrupt flavor".
|
||||||
|
|
||||||
This default interrupt flavor is called "hold-preferred". While this flavor may work well for a ctrl/escape key, but it might not be well suited for home-row mods or layer-taps. For this reason, ZMK defines multiple interrupt flavors which hold-tap behaviors can be configured with, listed below:
|
This default interrupt flavor is called "hold-preferred". While this flavor may work well for a ctrl/escape key, it might not be well suited for home-row mods or layer-taps. For this reason, ZMK defines multiple interrupt flavors which hold-tap behaviors can be configured with, listed below:
|
||||||
|
|
||||||
- The "hold-preferred" flavor triggers the hold behavior when the `tapping-term-ms` has expired or another key is pressed.
|
- The "hold-preferred" flavor triggers the hold behavior when the `tapping-term-ms` has expired or another key is pressed.
|
||||||
- The "balanced" flavor will trigger the hold behavior when the `tapping-term-ms` has expired or another key is pressed _and_ released while the hold-tap is held.
|
- The "balanced" flavor will trigger the hold behavior when the `tapping-term-ms` has expired or another key is pressed _and_ released while the hold-tap is held.
|
||||||
@@ -312,7 +312,7 @@ When the hold-tap key is released and the hold behavior has not been triggered,
|
|||||||
|
|
||||||
#### Comparison to QMK
|
#### Comparison to QMK
|
||||||
|
|
||||||
The `hold-preferred` flavor works similar to the `HOLD_ON_OTHER_KEY_PRESS` setting in QMK.
|
The `hold-preferred` flavor works similarly to the `HOLD_ON_OTHER_KEY_PRESS` setting in QMK.
|
||||||
The `balanced` flavor is similar to the `PERMISSIVE_HOLD` setting, and the `tap-preferred` flavor is the QMK default.
|
The `balanced` flavor is similar to the `PERMISSIVE_HOLD` setting, and the `tap-preferred` flavor is the QMK default.
|
||||||
|
|
||||||
```dts
|
```dts
|
||||||
@@ -333,6 +333,10 @@ By default this behavior is disabled.
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Comparison to QMK
|
||||||
|
|
||||||
|
QMK has a parameter called `QUICK_TAP_TERM`, but its semantics are slightly different. In QMK, it is the time interval between releasing the first key and pressing the second key whereas in ZMK, it is the time interval between pressing the first and second keys. Therefore you might want to use a larger value for `quick-tap-ms` compared to the value used in QMK.
|
||||||
|
|
||||||
### `require-prior-idle-ms`
|
### `require-prior-idle-ms`
|
||||||
|
|
||||||
If a hold-tap is pressed within `require-prior-idle-ms` of another non-modifier _key_ (not behavior), then the hold-tap will always resolve in a tap.
|
If a hold-tap is pressed within `require-prior-idle-ms` of another non-modifier _key_ (not behavior), then the hold-tap will always resolve in a tap.
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ module.exports = {
|
|||||||
"features/split-keyboards",
|
"features/split-keyboards",
|
||||||
"features/debouncing",
|
"features/debouncing",
|
||||||
"features/battery",
|
"features/battery",
|
||||||
|
"features/led-indicators",
|
||||||
"features/low-power-states",
|
"features/low-power-states",
|
||||||
"features/encoders",
|
"features/encoders",
|
||||||
"features/pointing",
|
"features/pointing",
|
||||||
@@ -126,6 +127,7 @@ module.exports = {
|
|||||||
"config/combos",
|
"config/combos",
|
||||||
"config/displays",
|
"config/displays",
|
||||||
"config/encoders",
|
"config/encoders",
|
||||||
|
"config/led-indicators",
|
||||||
"config/lighting",
|
"config/lighting",
|
||||||
"config/pointing",
|
"config/pointing",
|
||||||
"config/keymap",
|
"config/keymap",
|
||||||
@@ -158,6 +160,7 @@ module.exports = {
|
|||||||
"development/hardware-integration/encoders",
|
"development/hardware-integration/encoders",
|
||||||
"development/hardware-integration/soft-off-setup",
|
"development/hardware-integration/soft-off-setup",
|
||||||
"development/hardware-integration/pointing",
|
"development/hardware-integration/pointing",
|
||||||
|
"development/hardware-integration/new-board",
|
||||||
"development/hardware-integration/battery",
|
"development/hardware-integration/battery",
|
||||||
{
|
{
|
||||||
type: "category",
|
type: "category",
|
||||||
@@ -186,6 +189,7 @@ module.exports = {
|
|||||||
items: [
|
items: [
|
||||||
"development/hardware-integration/lighting/underglow",
|
"development/hardware-integration/lighting/underglow",
|
||||||
"development/hardware-integration/lighting/backlight",
|
"development/hardware-integration/lighting/backlight",
|
||||||
|
"development/hardware-integration/lighting/led-indicators",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
* SPDX-License-Identifier: CC-BY-NC-SA-4.0
|
* SPDX-License-Identifier: CC-BY-NC-SA-4.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import macosLanguage from "@site/docs/keymaps/_footnotes/macos-language.mdx";
|
||||||
|
import macosInternational from "@site/docs/keymaps/_footnotes/macos-international.mdx";
|
||||||
import example from "@site/docs/keymaps/_footnotes/example.mdx";
|
import example from "@site/docs/keymaps/_footnotes/example.mdx";
|
||||||
import iosApplication from "@site/docs/keymaps/_footnotes/ios-application.mdx";
|
import iosApplication from "@site/docs/keymaps/_footnotes/ios-application.mdx";
|
||||||
import iosPower from "@site/docs/keymaps/_footnotes/ios-power.mdx";
|
import iosPower from "@site/docs/keymaps/_footnotes/ios-power.mdx";
|
||||||
@@ -13,6 +15,8 @@ import macosUndoRedo from "@site/docs/keymaps/_footnotes/macos-undo-redo.mdx";
|
|||||||
import globe from "@site/docs/keymaps/_footnotes/globe.mdx";
|
import globe from "@site/docs/keymaps/_footnotes/globe.mdx";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
macosLanguage,
|
||||||
|
macosInternational,
|
||||||
example,
|
example,
|
||||||
iosApplication,
|
iosApplication,
|
||||||
iosPower,
|
iosPower,
|
||||||
|
|||||||
@@ -3396,10 +3396,12 @@ export default [
|
|||||||
windows: false,
|
windows: false,
|
||||||
linux: true,
|
linux: true,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {
|
||||||
|
macos: ["macosInternational"],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
names: ["INTERNATIONAL_2", "INT2", "INT_KATAKANAHIRAGANA", "INT_KANA"],
|
names: ["INTERNATIONAL_2", "INT2", "INT_KATAKANAHIRAGANA", "INT_KANA"],
|
||||||
@@ -3417,7 +3419,7 @@ export default [
|
|||||||
windows: false,
|
windows: false,
|
||||||
linux: true,
|
linux: true,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {},
|
||||||
@@ -3438,10 +3440,12 @@ export default [
|
|||||||
windows: false,
|
windows: false,
|
||||||
linux: true,
|
linux: true,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {
|
||||||
|
macos: ["macosInternational"],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
names: ["INTERNATIONAL_4", "INT4", "INT_HENKAN"],
|
names: ["INTERNATIONAL_4", "INT4", "INT_HENKAN"],
|
||||||
@@ -3459,7 +3463,7 @@ export default [
|
|||||||
windows: false,
|
windows: false,
|
||||||
linux: true,
|
linux: true,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {},
|
||||||
@@ -3480,7 +3484,7 @@ export default [
|
|||||||
windows: false,
|
windows: false,
|
||||||
linux: true,
|
linux: true,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {},
|
||||||
@@ -3501,7 +3505,7 @@ export default [
|
|||||||
windows: false,
|
windows: false,
|
||||||
linux: true,
|
linux: true,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {},
|
||||||
@@ -3522,7 +3526,7 @@ export default [
|
|||||||
windows: null,
|
windows: null,
|
||||||
linux: false,
|
linux: false,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {},
|
||||||
@@ -3543,7 +3547,7 @@ export default [
|
|||||||
windows: null,
|
windows: null,
|
||||||
linux: false,
|
linux: false,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {},
|
||||||
@@ -3564,7 +3568,7 @@ export default [
|
|||||||
windows: null,
|
windows: null,
|
||||||
linux: false,
|
linux: false,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {},
|
||||||
@@ -3585,10 +3589,12 @@ export default [
|
|||||||
windows: true,
|
windows: true,
|
||||||
linux: true,
|
linux: true,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {
|
||||||
|
macos: ["macosLanguage"],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
names: ["LANGUAGE_2", "LANG2", "LANG_HANJA"],
|
names: ["LANGUAGE_2", "LANG2", "LANG_HANJA"],
|
||||||
@@ -3606,10 +3612,12 @@ export default [
|
|||||||
windows: true,
|
windows: true,
|
||||||
linux: true,
|
linux: true,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {
|
||||||
|
macos: ["macosLanguage"],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
names: ["LANGUAGE_3", "LANG3", "LANG_KATAKANA"],
|
names: ["LANGUAGE_3", "LANG3", "LANG_KATAKANA"],
|
||||||
@@ -3627,7 +3635,7 @@ export default [
|
|||||||
windows: false,
|
windows: false,
|
||||||
linux: true,
|
linux: true,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {},
|
||||||
@@ -3648,7 +3656,7 @@ export default [
|
|||||||
windows: false,
|
windows: false,
|
||||||
linux: true,
|
linux: true,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {},
|
||||||
@@ -3669,7 +3677,7 @@ export default [
|
|||||||
windows: false,
|
windows: false,
|
||||||
linux: true,
|
linux: true,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {},
|
||||||
@@ -3690,7 +3698,7 @@ export default [
|
|||||||
windows: null,
|
windows: null,
|
||||||
linux: false,
|
linux: false,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {},
|
||||||
@@ -3711,7 +3719,7 @@ export default [
|
|||||||
windows: null,
|
windows: null,
|
||||||
linux: false,
|
linux: false,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {},
|
||||||
@@ -3732,7 +3740,7 @@ export default [
|
|||||||
windows: null,
|
windows: null,
|
||||||
linux: false,
|
linux: false,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {},
|
||||||
@@ -3753,7 +3761,7 @@ export default [
|
|||||||
windows: null,
|
windows: null,
|
||||||
linux: false,
|
linux: false,
|
||||||
android: false,
|
android: false,
|
||||||
macos: null,
|
macos: true,
|
||||||
ios: null,
|
ios: null,
|
||||||
},
|
},
|
||||||
footnotes: {},
|
footnotes: {},
|
||||||
@@ -7889,7 +7897,7 @@ export default [
|
|||||||
documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=153",
|
documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=153",
|
||||||
os: {
|
os: {
|
||||||
windows: null,
|
windows: null,
|
||||||
linux: null,
|
linux: false,
|
||||||
android: null,
|
android: null,
|
||||||
macos: true,
|
macos: true,
|
||||||
ios: true,
|
ios: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user