mirror of
https://github.com/qmk/qmk_firmware.git
synced 2026-06-30 19:24:03 -04:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 92005dee35 | |||
| 5dd8efc7c0 | |||
| cc22d67b32 | |||
| a1cb005981 | |||
| cfde338998 | |||
| 4d1ad14596 | |||
| c34f0e4998 | |||
| 94d76a4f9e | |||
| fe59b4e5d6 | |||
| 7093a41c6c | |||
| c9ca9b9875 | |||
| 060c15f32b | |||
| 6a960cbf05 | |||
| 531c37b256 | |||
| 6468360ff1 | |||
| 40a3a431ef | |||
| 4d999378d0 | |||
| 2ebad0d33f | |||
| d5760d02a6 | |||
| 9ae271c844 | |||
| 4aea69ba21 | |||
| 2031d063b5 | |||
| d32724c08f | |||
| 26756d05a2 | |||
| b45dbcd4c1 | |||
| 6fe0cd47ca | |||
| ca8596e4a8 |
@@ -1,4 +1,3 @@
|
||||
CompileFlags:
|
||||
Add: [-Wno-unknown-attributes, -Wno-maybe-uninitialized, -Wno-unknown-warning-option]
|
||||
Remove: [-W*, -mcall-prologues]
|
||||
Compiler: clang
|
||||
Remove: -mcall-prologues
|
||||
Add: -nostdinc
|
||||
@@ -19,7 +19,7 @@ on:
|
||||
jobs:
|
||||
api_data:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/qmk/qmk_cli
|
||||
container: qmkfm/qmk_cli
|
||||
|
||||
# protect against those who work in their fork on 'important' branches
|
||||
if: github.repository == 'qmk/qmk_firmware'
|
||||
|
||||
@@ -4,7 +4,6 @@ permissions:
|
||||
contents: write
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
@@ -32,7 +31,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Bump version and push tag
|
||||
uses: anothrNick/github-tag-action@1.62.0
|
||||
uses: anothrNick/github-tag-action@1.61.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
DEFAULT_BUMP: 'patch'
|
||||
|
||||
@@ -4,30 +4,25 @@ permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, develop]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
branch:
|
||||
type: choice
|
||||
description: 'Branch to build'
|
||||
options: [master, develop]
|
||||
|
||||
concurrency: ci_build-${{ github.event.inputs.branch || github.ref_name }}
|
||||
schedule:
|
||||
- cron: '0 0,12 * * *'
|
||||
|
||||
jobs:
|
||||
ci_builds:
|
||||
if: github.repository == 'qmk/qmk_firmware'
|
||||
name: "CI Build"
|
||||
runs-on: self-hosted
|
||||
timeout-minutes: 1380
|
||||
|
||||
if: github.repository == 'qmk/qmk_firmware'
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
branch: [master, develop]
|
||||
keymap: [default, via]
|
||||
|
||||
container: ghcr.io/qmk/qmk_cli
|
||||
container: qmkfm/qmk_cli
|
||||
|
||||
steps:
|
||||
- name: Disable safe.directory check
|
||||
@@ -36,7 +31,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{ github.event.inputs.branch || github.ref }}
|
||||
ref: ${{ matrix.branch }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip3 install -r requirements.txt
|
||||
@@ -56,19 +51,10 @@ jobs:
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: artifacts-${{ github.event.inputs.branch || github.ref_name }}-${{ matrix.keymap }}
|
||||
name: artifacts-${{ matrix.branch }}-${{ matrix.keymap }}
|
||||
if-no-files-found: ignore
|
||||
path: |
|
||||
*.bin
|
||||
*.hex
|
||||
*.uf2
|
||||
.build/failed.*
|
||||
|
||||
- name: 'CI Discord Notification'
|
||||
if: always()
|
||||
working-directory: util/ci/
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.CI_DISCORD_WEBHOOK }}
|
||||
run: |
|
||||
python3 -m pip install -r requirements.txt
|
||||
python3 ./discord-results.py --branch ${{ github.event.inputs.branch || github.ref_name }} --keymap ${{ matrix.keymap }} --url ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container: ghcr.io/qmk/qmk_cli
|
||||
container: qmkfm/qmk_cli
|
||||
|
||||
steps:
|
||||
- name: Disable safe.directory check
|
||||
|
||||
@@ -17,7 +17,7 @@ on:
|
||||
jobs:
|
||||
generate:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/qmk/qmk_cli
|
||||
container: qmkfm/qmk_cli
|
||||
|
||||
# protect against those who develop with their fork on master
|
||||
if: github.repository == 'qmk/qmk_firmware'
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
qmk --verbose generate-docs
|
||||
|
||||
- name: Deploy
|
||||
uses: JamesIves/github-pages-deploy-action@v4.4.2
|
||||
uses: JamesIves/github-pages-deploy-action@v4.4.1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BASE_BRANCH: master
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container: ghcr.io/qmk/qmk_cli
|
||||
container: qmkfm/qmk_cli
|
||||
|
||||
steps:
|
||||
- name: Disable safe.directory check
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container: ghcr.io/qmk/qmk_cli
|
||||
container: qmkfm/qmk_cli
|
||||
|
||||
steps:
|
||||
- name: Disable safe.directory check
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
git config user.email 'hello@qmk.fm'
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
if: ${{ github.repository == 'qmk/qmk_firmware'}}
|
||||
with:
|
||||
token: ${{ secrets.QMK_BOT_TOKEN }}
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container: ghcr.io/qmk/qmk_cli
|
||||
container: qmkfm/qmk_cli
|
||||
|
||||
steps:
|
||||
- name: Disable safe.directory check
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
regen:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container: ghcr.io/qmk/qmk_cli
|
||||
container: qmkfm/qmk_cli
|
||||
|
||||
steps:
|
||||
- name: Disable safe.directory check
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
regen:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container: ghcr.io/qmk/qmk_cli
|
||||
container: qmkfm/qmk_cli
|
||||
|
||||
steps:
|
||||
- name: Disable safe.directory check
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
git config user.email 'hello@qmk.fm'
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
if: ${{ github.repository == 'qmk/qmk_firmware'}}
|
||||
with:
|
||||
token: ${{ secrets.QMK_BOT_TOKEN }}
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container: ghcr.io/qmk/qmk_cli
|
||||
container: qmkfm/qmk_cli
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
+5
-4
@@ -30,9 +30,6 @@ quantum/version.h
|
||||
*.qmk
|
||||
*.uf2
|
||||
|
||||
# DD config at wrong location
|
||||
/keyboards/**/keymaps/*/info.json
|
||||
|
||||
# Old-style QMK Makefiles
|
||||
/keyboards/**/Makefile
|
||||
|
||||
@@ -48,15 +45,19 @@ quantum/version.h
|
||||
.idea/
|
||||
.project
|
||||
.settings/
|
||||
.vagrant/
|
||||
|
||||
# ?
|
||||
.dep
|
||||
.history/
|
||||
build/
|
||||
cmake-build-debug
|
||||
CMakeLists.txt
|
||||
# CMakeLists.txt
|
||||
*.pdf
|
||||
|
||||
# cmake toolchain downloads
|
||||
/toolchains
|
||||
|
||||
# Let these ones be user specific, since we have so many different configurations
|
||||
*.code-workspace
|
||||
.stfolder
|
||||
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
[
|
||||
{
|
||||
"name": "AVR GCC",
|
||||
"compilers": {
|
||||
"CC": "C:\\QMK_MSYS\\mingw64\\bin\\avr-gcc.exe",
|
||||
"CXX": "C:\\QMK_MSYS\\mingw64\\bin\\avr-g++.exe"
|
||||
}
|
||||
}
|
||||
]
|
||||
Vendored
+1
-1
@@ -3,7 +3,7 @@
|
||||
"recommendations": [
|
||||
"EditorConfig.EditorConfig",
|
||||
"xaver.clang-format",
|
||||
"llvm-vs-code-extensions.vscode-clangd",
|
||||
"ms-vscode.cpptools",
|
||||
"bierner.github-markdown-preview",
|
||||
"donjayamanne.git-extension-pack"
|
||||
]
|
||||
|
||||
Vendored
+4
-7
@@ -5,8 +5,8 @@
|
||||
// Configure glob patterns for excluding files and folders.
|
||||
"files.exclude": {
|
||||
"**/.build": true,
|
||||
"**/*.hex": true,
|
||||
"**/*.bin": true,
|
||||
// "**/*.hex": true,
|
||||
// "**/*.bin": true,
|
||||
"**/*.uf2": true
|
||||
},
|
||||
"files.associations": {
|
||||
@@ -26,9 +26,6 @@
|
||||
},
|
||||
"python.formatting.provider": "yapf",
|
||||
"[json]": {
|
||||
"editor.formatOnSave": false
|
||||
},
|
||||
"clangd.arguments": [
|
||||
"--header-insertion=never"
|
||||
]
|
||||
"editor.formatOnSave": false
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+114
@@ -0,0 +1,114 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Load Keyboard",
|
||||
"dependsOrder": "sequence",
|
||||
"dependsOn":[
|
||||
"Only Load Keyboard",
|
||||
"Configure CMake"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Only Load Keyboard",
|
||||
"type": "shell",
|
||||
"command": "cmake -D QMK_KEYBOARD_FOLDER=\"${input:all_keyboards}\" -D QMK_KEYMAP_FOLDER=\"${input:keyboard_keymap}\" -P ${workspaceFolder}/cmake/ConfigureKeyboard.cmake",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Configure CMake",
|
||||
"type": "cmake",
|
||||
"command": "configure"
|
||||
},
|
||||
{
|
||||
"label": "Build",
|
||||
"problemMatcher": [
|
||||
{
|
||||
"base": "$gcc",
|
||||
"fileLocation": ["relative", "${workspaceFolder}/build"]
|
||||
},
|
||||
],
|
||||
"options": {
|
||||
"environment": {
|
||||
"CLICOLOR_FORCE": "1"
|
||||
}
|
||||
},
|
||||
"type": "cmake",
|
||||
"command": "build",
|
||||
"targets":[
|
||||
"${input:keyboard_target}"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
},
|
||||
// {
|
||||
// "label": "Rebuild",
|
||||
// "problemMatcher": [
|
||||
// {
|
||||
// "base": "$gcc",
|
||||
// "fileLocation": ["relative", "${workspaceFolder}/build"]
|
||||
// },
|
||||
// ],
|
||||
// "options": {
|
||||
// "environment": {
|
||||
// "CLICOLOR_FORCE": "1"
|
||||
// }
|
||||
// },
|
||||
// "type": "cmake",
|
||||
// "command": "cleanRebuild",
|
||||
// "targets":[
|
||||
// "${input:keyboard_target}"
|
||||
// ],
|
||||
// "group": {
|
||||
// "kind": "build",
|
||||
// "isDefault": true
|
||||
// },
|
||||
// }
|
||||
],
|
||||
"inputs": [
|
||||
{
|
||||
"id": "keyboard_target",
|
||||
"type": "command",
|
||||
"command": "shellCommand.execute",
|
||||
"args": {
|
||||
"command": "type build\\targets",
|
||||
"description": "Target:",
|
||||
"fieldSeparator": "|"
|
||||
},
|
||||
},
|
||||
{
|
||||
"id": "all_keyboards",
|
||||
"type": "command",
|
||||
"command": "shellCommand.execute",
|
||||
"args": {
|
||||
"command": "type build\\all_keyboards",
|
||||
"description": "Keyboard:",
|
||||
"default": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"id": "keymap",
|
||||
"description": "Keymap:",
|
||||
"type": "pickString",
|
||||
"options":[
|
||||
"default"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "keyboard_keymap",
|
||||
"type": "command",
|
||||
"command": "shellCommand.execute",
|
||||
"args": {
|
||||
"command": "cmake -D QMK_KEYBOARD_FOLDER=\"${input:all_keyboards}\" -P ${workspaceFolder}/cmake/GetKeymaps.cmake && type build\\keyboard_keymaps",
|
||||
"description": "Keymap:",
|
||||
"default": ""
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "")
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
include(UpdateSubmodule)
|
||||
include(ResolveKeyboard)
|
||||
include(ValidateJson)
|
||||
include(ProcessKeyboard)
|
||||
|
||||
set(QMK_KEYBOARDS_FOLDER "${CMAKE_SOURCE_DIR}/keyboards")
|
||||
|
||||
function(_get_all_cmake_targets out_var current_dir)
|
||||
get_property(targets DIRECTORY ${current_dir} PROPERTY BUILDSYSTEM_TARGETS)
|
||||
get_property(subdirs DIRECTORY ${current_dir} PROPERTY SUBDIRECTORIES)
|
||||
|
||||
foreach(subdir ${subdirs})
|
||||
_get_all_cmake_targets(subdir_targets ${subdir})
|
||||
list(APPEND targets ${subdir_targets})
|
||||
endforeach()
|
||||
|
||||
set(${out_var} ${targets} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if(NOT DEFINED QMK_KEYBOARD)
|
||||
# configure step - populate targets
|
||||
project(qmk_firmware)
|
||||
|
||||
add_subdirectory(keyboards)
|
||||
|
||||
else()
|
||||
# build step
|
||||
if(NOT DEFINED QMK_KEYMAP_FOLDER)
|
||||
set(QMK_KEYMAP_FOLDER "default")
|
||||
endif()
|
||||
|
||||
resolve_keyboard(${QMK_KEYBOARD_FOLDER} QMK_KEYBOARD_FOLDER_ABS)
|
||||
cmake_path(IS_PREFIX QMK_KEYBOARDS_FOLDER "${QMK_KEYBOARD_FOLDER_ABS}" IS_KEYBOARDS_FOLDER)
|
||||
resolve_config_h(${QMK_KEYBOARD_FOLDER_ABS} QMK_KEYBOARD_CONFIG_H)
|
||||
process_keyboard()
|
||||
resolve_keyboard_h(${QMK_KEYBOARD_FOLDER_ABS} QMK_KEYBOARD_H)
|
||||
resolve_keymap_c(${QMK_KEYBOARD_FOLDER_ABS} ${QMK_KEYMAP_FOLDER} QMK_KEYMAP_C)
|
||||
|
||||
message(STATUS "config.h: ${QMK_KEYBOARD_CONFIG_H}")
|
||||
message(STATUS "keyboard.h: ${QMK_KEYBOARD_H}")
|
||||
message(STATUS "keymap.c: ${QMK_KEYMAP_C}")
|
||||
|
||||
|
||||
project(${QMK_KEYBOARD}
|
||||
LANGUAGES C CXX ASM
|
||||
HOMEPAGE_URL ${URL}
|
||||
VERSION ${DEVICE_VER})
|
||||
|
||||
# add_compile_options(
|
||||
# -include ${QMK_KEYBOARD_CONFIG_H}
|
||||
# )
|
||||
add_compile_definitions(
|
||||
QMK_KEYBOARD_H="${QMK_KEYBOARD_H}"
|
||||
KEYBOARD_${QMK_KEYBOARD}
|
||||
KEYMAP_C="${QMK_KEYMAP_C}"
|
||||
MATRIX_ROWS=8
|
||||
MATRIX_COLS=6
|
||||
)
|
||||
|
||||
if(DEFINED DIODE_DIRECTION)
|
||||
add_compile_definitions(DIODE_DIRECTION=${DIODE_DIRECTION})
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR})
|
||||
|
||||
# if(EXISTS ${QMK_KEYBOARD_FOLDER_ABS}/CMakeLists.txt)
|
||||
# add_subdirectory(${QMK_KEYBOARD_FOLDER_ABS})
|
||||
# else()
|
||||
file(GLOB KEYBOARD_SRC "${QMK_KEYBOARD_FOLDER_ABS}/*.c")
|
||||
list(REMOVE_ITEM KEYBOARD_SRC "${QMK_KEYMAP_C}")
|
||||
add_qmk_executable(${TARGET_NAME} ${KEYBOARD_SRC})
|
||||
|
||||
# endif()
|
||||
# add_library(qmk)
|
||||
|
||||
target_precompile_headers(qmk PUBLIC
|
||||
${QMK_KEYBOARD_CONFIG_H}
|
||||
)
|
||||
|
||||
resolve_keyboard_includes(${QMK_KEYBOARD_FOLDER_ABS})
|
||||
|
||||
add_subdirectory(quantum)
|
||||
add_subdirectory(platforms)
|
||||
add_subdirectory(tmk_core/protocol)
|
||||
|
||||
include(features/oled)
|
||||
include(features/backlight)
|
||||
include(features/eeprom)
|
||||
include(features/matrix)
|
||||
include(features/fnv)
|
||||
endif()
|
||||
@@ -0,0 +1,6 @@
|
||||
FROM qmkfm/qmk_cli
|
||||
|
||||
VOLUME /qmk_firmware
|
||||
WORKDIR /qmk_firmware
|
||||
|
||||
CMD qmk compile -kb all -km default
|
||||
Vendored
+95
@@ -0,0 +1,95 @@
|
||||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
Vagrant.configure(2) do |config|
|
||||
# define a name instead of just 'default'
|
||||
config.vm.define "qmk_firmware"
|
||||
|
||||
# VMware/Virtualbox ( and also Hyperv/Parallels) 64 bit
|
||||
config.vm.box = "generic/debian10"
|
||||
|
||||
config.vm.synced_folder '.', '/vagrant'
|
||||
|
||||
# This section allows you to customize the Virtualbox VM
|
||||
# settings, ie showing the GUI or upping the memory
|
||||
# or cores if desired
|
||||
config.vm.provider "virtualbox" do |vb|
|
||||
# Hide the VirtualBox GUI when booting the machine
|
||||
vb.gui = false
|
||||
# Uncomment the below lines if you want to program
|
||||
# your Teensy via the VM rather than your host OS
|
||||
#vb.customize ['modifyvm', :id, '--usb', 'on']
|
||||
#vb.customize ['usbfilter', 'add', '0',
|
||||
# '--target', :id,
|
||||
# '--name', 'teensy',
|
||||
# '--vendorid', '0x16c0',
|
||||
# '--productid','0x0478'
|
||||
# ]
|
||||
# Customize the amount of memory on the VM:
|
||||
vb.memory = "512"
|
||||
# Uncomment the below lines if you have time sync
|
||||
# issues with make and incremental builds
|
||||
#vb.customize [ "guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-set-threshold", 1000 ]
|
||||
end
|
||||
|
||||
# This section allows you to customize the VMware VM
|
||||
# settings, ie showing the GUI or upping the memory
|
||||
# or cores if desired
|
||||
config.vm.provider "vmware_workstation" do |vmw|
|
||||
# Hide the VMware GUI when booting the machine
|
||||
vmw.gui = false
|
||||
|
||||
# Customize the amount of memory on the VM:
|
||||
vmw.memory = "512"
|
||||
end
|
||||
|
||||
config.vm.provider "vmware_fusion" do |vmf|
|
||||
# Hide the vmfare GUI when booting the machine
|
||||
vmf.gui = false
|
||||
|
||||
# Customize the amount of memory on the VM:
|
||||
vmf.memory = "512"
|
||||
end
|
||||
|
||||
# Docker provider pulls from hub.docker.com respecting docker.image if
|
||||
# config.vm.box is nil. In this case, we adhoc build util/vagrant/Dockerfile.
|
||||
# Note that this bind-mounts from the current dir to
|
||||
# /vagrant in the guest, so unless your UID is 1000 to match vagrant in the
|
||||
# image, you'll need to: chmod -R a+rw .
|
||||
config.vm.provider "docker" do |docker, override|
|
||||
override.vm.box = nil
|
||||
docker.build_dir = "util/vagrant"
|
||||
docker.has_ssh = true
|
||||
end
|
||||
|
||||
# Unless we are running the docker container directly
|
||||
# 1. run container detached on vm
|
||||
# 2. attach on 'vagrant ssh'
|
||||
["virtualbox", "vmware_workstation", "vmware_fusion"].each do |type|
|
||||
config.vm.provider type do |virt, override|
|
||||
override.vm.provision "docker" do |d|
|
||||
d.run "qmkfm/qmk_cli",
|
||||
cmd: "tail -f /dev/null",
|
||||
args: "--privileged -v /dev:/dev -v '/vagrant:/vagrant'"
|
||||
end
|
||||
|
||||
override.vm.provision "shell", inline: <<-SHELL
|
||||
echo 'docker restart qmkfm-qmk_cli && exec docker exec -it qmkfm-qmk_cli /bin/bash -l' >> ~vagrant/.bashrc
|
||||
SHELL
|
||||
end
|
||||
end
|
||||
|
||||
config.vm.post_up_message = <<-EOT
|
||||
|
||||
Log into the environment using 'vagrant ssh'. QMK directory synchronized with
|
||||
host is located at /vagrant
|
||||
To compile the .hex files use make command inside this directory, e.g.
|
||||
cd /vagrant
|
||||
make <keyboard>:default
|
||||
|
||||
Examples:
|
||||
make planck/rev4:default:dfu
|
||||
make planck/rev4:default
|
||||
|
||||
EOT
|
||||
end
|
||||
@@ -343,15 +343,6 @@ $(KEYBOARD_OUTPUT)/src/default_keyboard.h: $(INFO_JSON_FILES)
|
||||
|
||||
generated-files: $(KEYBOARD_OUTPUT)/src/info_config.h $(KEYBOARD_OUTPUT)/src/default_keyboard.c $(KEYBOARD_OUTPUT)/src/default_keyboard.h
|
||||
|
||||
generated-files: $(KEYMAP_OUTPUT)/src/info_deps.d
|
||||
|
||||
$(KEYMAP_OUTPUT)/src/info_deps.d:
|
||||
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
|
||||
$(eval CMD=$(QMK_BIN) generate-make-dependencies -kb $(KEYBOARD) -km $(KEYMAP) -o $(KEYMAP_OUTPUT)/src/info_deps.d)
|
||||
@$(BUILD_CMD)
|
||||
|
||||
-include $(KEYMAP_OUTPUT)/src/info_deps.d
|
||||
|
||||
.INTERMEDIATE : generated-files
|
||||
|
||||
# Userspace setup and definitions
|
||||
@@ -455,14 +446,6 @@ $(eval $(call add_qmk_prefix_defs,MCU_FAMILY,MCU_FAMILY))
|
||||
$(eval $(call add_qmk_prefix_defs,MCU_SERIES,MCU_SERIES))
|
||||
$(eval $(call add_qmk_prefix_defs,BOARD,BOARD))
|
||||
|
||||
# Control whether intermediate file listings are generated
|
||||
# e.g.:
|
||||
# make handwired/onekey/blackpill_f411:default KEEP_INTERMEDIATES=yes
|
||||
# cat .build/obj_handwired_onekey_blackpill_f411_default/quantum/quantum.i | sed -e 's@^#.*@@g' -e 's@^\s*//.*@@g' -e '/^\s*$/d' | clang-format
|
||||
ifeq ($(strip $(KEEP_INTERMEDIATES)), yes)
|
||||
OPT_DEFS += -save-temps=obj
|
||||
endif
|
||||
|
||||
# TODO: remove this bodge?
|
||||
PROJECT_DEFS := $(OPT_DEFS)
|
||||
PROJECT_INC := $(VPATH) $(EXTRAINCDIRS) $(KEYBOARD_PATHS)
|
||||
|
||||
@@ -75,10 +75,6 @@ $(TEST)_SRC += \
|
||||
tests/test_common/main.cpp \
|
||||
$(QUANTUM_PATH)/logging/print.c
|
||||
|
||||
ifneq ($(strip $(INTROSPECTION_KEYMAP_C)),)
|
||||
$(TEST)_DEFS += -DINTROSPECTION_KEYMAP_C=\"$(strip $(INTROSPECTION_KEYMAP_C))\"
|
||||
endif
|
||||
|
||||
$(TEST_OBJ)/$(TEST)_SRC := $($(TEST)_SRC)
|
||||
$(TEST_OBJ)/$(TEST)_INC := $($(TEST)_INC) $(VPATH) $(GTEST_INC)
|
||||
$(TEST_OBJ)/$(TEST)_DEFS := $($(TEST)_DEFS)
|
||||
|
||||
@@ -134,7 +134,7 @@ ifeq ($(strip $(MOUSEKEY_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/mousekey.c
|
||||
endif
|
||||
|
||||
VALID_POINTING_DEVICE_DRIVER_TYPES := adns5050 adns9800 analog_joystick cirque_pinnacle_i2c cirque_pinnacle_spi paw3204 pmw3320 pmw3360 pmw3389 pimoroni_trackball custom
|
||||
VALID_POINTING_DEVICE_DRIVER_TYPES := adns5050 adns9800 analog_joystick cirque_pinnacle_i2c cirque_pinnacle_spi paw3204 pmw3360 pmw3389 pimoroni_trackball custom
|
||||
ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
|
||||
ifeq ($(filter $(POINTING_DEVICE_DRIVER),$(VALID_POINTING_DEVICE_DRIVER_TYPES)),)
|
||||
$(call CATASTROPHIC_ERROR,Invalid POINTING_DEVICE_DRIVER,POINTING_DEVICE_DRIVER="$(POINTING_DEVICE_DRIVER)" is not a valid pointing device type)
|
||||
@@ -213,10 +213,10 @@ else
|
||||
SRC += eeprom_driver.c eeprom_spi.c
|
||||
else ifeq ($(strip $(EEPROM_DRIVER)), legacy_stm32_flash)
|
||||
# STM32 Emulated EEPROM, backed by MCU flash (soon to be deprecated)
|
||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_LEGACY_EMULATED_FLASH
|
||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_FLASH_EMULATED
|
||||
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash
|
||||
COMMON_VPATH += $(DRIVER_PATH)/flash
|
||||
SRC += eeprom_driver.c eeprom_legacy_emulated_flash.c legacy_flash_ops.c
|
||||
SRC += eeprom_driver.c eeprom_stm32.c flash_stm32.c
|
||||
else ifeq ($(strip $(EEPROM_DRIVER)), transient)
|
||||
# Transient EEPROM implementation -- no data storage but provides runtime area for it
|
||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
|
||||
@@ -419,7 +419,7 @@ endif
|
||||
|
||||
RGB_MATRIX_ENABLE ?= no
|
||||
|
||||
VALID_RGB_MATRIX_TYPES := AW20216 IS31FL3731 IS31FL3733 IS31FL3736 IS31FL3737 IS31FL3741 IS31FL3742A IS31FL3743A IS31FL3745 IS31FL3746A CKLED2001 WS2812 custom
|
||||
VALID_RGB_MATRIX_TYPES := AW20216 IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 IS31FL3742A IS31FL3743A IS31FL3745 IS31FL3746A CKLED2001 WS2812 custom
|
||||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
|
||||
ifeq ($(filter $(RGB_MATRIX_DRIVER),$(VALID_RGB_MATRIX_TYPES)),)
|
||||
$(call CATASTROPHIC_ERROR,Invalid RGB_MATRIX_DRIVER,RGB_MATRIX_DRIVER="$(RGB_MATRIX_DRIVER)" is not a valid matrix type)
|
||||
@@ -460,13 +460,6 @@ endif
|
||||
QUANTUM_LIB_SRC += i2c_master.c
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), IS31FL3736)
|
||||
OPT_DEFS += -DIS31FL3736 -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
||||
SRC += is31fl3736.c
|
||||
QUANTUM_LIB_SRC += i2c_master.c
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), IS31FL3737)
|
||||
OPT_DEFS += -DIS31FL3737 -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
||||
@@ -581,7 +574,7 @@ ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
|
||||
endif
|
||||
endif
|
||||
|
||||
VALID_WS2812_DRIVER_TYPES := bitbang custom i2c pwm spi vendor
|
||||
VALID_WS2812_DRIVER_TYPES := bitbang pwm spi i2c vendor
|
||||
|
||||
WS2812_DRIVER ?= bitbang
|
||||
ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes)
|
||||
@@ -591,11 +584,15 @@ ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes)
|
||||
|
||||
OPT_DEFS += -DWS2812_DRIVER_$(strip $(shell echo $(WS2812_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
||||
|
||||
SRC += ws2812_$(strip $(WS2812_DRIVER)).c
|
||||
ifeq ($(strip $(WS2812_DRIVER)), bitbang)
|
||||
SRC += ws2812.c
|
||||
else
|
||||
SRC += ws2812_$(strip $(WS2812_DRIVER)).c
|
||||
|
||||
ifeq ($(strip $(PLATFORM)), CHIBIOS)
|
||||
ifeq ($(strip $(WS2812_DRIVER)), pwm)
|
||||
OPT_DEFS += -DSTM32_DMA_REQUIRED=TRUE
|
||||
ifeq ($(strip $(PLATFORM)), CHIBIOS)
|
||||
ifeq ($(strip $(WS2812_DRIVER)), pwm)
|
||||
OPT_DEFS += -DSTM32_DMA_REQUIRED=TRUE
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -744,28 +741,17 @@ endif
|
||||
|
||||
VALID_OLED_DRIVER_TYPES := SSD1306 custom
|
||||
OLED_DRIVER ?= SSD1306
|
||||
VALID_OLED_TRANSPORT_TYPES := i2c spi custom
|
||||
OLED_TRANSPORT ?= i2c
|
||||
ifeq ($(strip $(OLED_ENABLE)), yes)
|
||||
ifeq ($(filter $(OLED_DRIVER),$(VALID_OLED_DRIVER_TYPES)),)
|
||||
$(call CATASTROPHIC_ERROR,Invalid OLED_DRIVER,OLED_DRIVER="$(OLED_DRIVER)" is not a valid OLED driver)
|
||||
else
|
||||
ifeq ($(filter $(OLED_TRANSPORT),$(VALID_OLED_TRANSPORT_TYPES)),)
|
||||
$(call CATASTROPHIC_ERROR,Invalid OLED_TRANSPORT,OLED_TRANSPORT="$(OLED_TRANSPORT)" is not a valid OLED transport)
|
||||
else
|
||||
OPT_DEFS += -DOLED_ENABLE
|
||||
COMMON_VPATH += $(DRIVER_PATH)/oled
|
||||
ifneq ($(strip $(OLED_DRIVER)), custom)
|
||||
SRC += oled_driver.c
|
||||
endif
|
||||
OPT_DEFS += -DOLED_ENABLE
|
||||
COMMON_VPATH += $(DRIVER_PATH)/oled
|
||||
|
||||
OPT_DEFS += -DOLED_TRANSPORT_$(strip $(shell echo $(OLED_TRANSPORT) | tr '[:lower:]' '[:upper:]'))
|
||||
ifeq ($(strip $(OLED_TRANSPORT)), i2c)
|
||||
QUANTUM_LIB_SRC += i2c_master.c
|
||||
endif
|
||||
ifeq ($(strip $(OLED_TRANSPORT)), spi)
|
||||
QUANTUM_LIB_SRC += spi_master.c
|
||||
endif
|
||||
OPT_DEFS += -DOLED_DRIVER_$(strip $(shell echo $(OLED_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
||||
ifeq ($(strip $(OLED_DRIVER)), SSD1306)
|
||||
SRC += ssd1306_sh1106.c
|
||||
QUANTUM_LIB_SRC += i2c_master.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@@ -827,9 +813,9 @@ endif
|
||||
|
||||
ifeq ($(strip $(PS2_MOUSE_ENABLE)), yes)
|
||||
PS2_ENABLE := yes
|
||||
MOUSE_ENABLE := yes
|
||||
SRC += ps2_mouse.c
|
||||
OPT_DEFS += -DPS2_MOUSE_ENABLE
|
||||
OPT_DEFS += -DMOUSE_ENABLE
|
||||
endif
|
||||
|
||||
VALID_PS2_DRIVER_TYPES := busywait interrupt usart vendor
|
||||
@@ -906,11 +892,10 @@ ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
|
||||
OPT_DEFS += -DBLUETOOTH_ENABLE
|
||||
NO_USB_STARTUP_CHECK := yes
|
||||
COMMON_VPATH += $(DRIVER_PATH)/bluetooth
|
||||
SRC += outputselect.c
|
||||
SRC += outputselect.c bluetooth.c
|
||||
|
||||
ifeq ($(strip $(BLUETOOTH_DRIVER)), BluefruitLE)
|
||||
OPT_DEFS += -DBLUETOOTH_BLUEFRUIT_LE -DHAL_USE_SPI=TRUE
|
||||
SRC += $(DRIVER_PATH)/bluetooth/bluetooth.c
|
||||
SRC += $(DRIVER_PATH)/bluetooth/bluefruit_le.cpp
|
||||
QUANTUM_LIB_SRC += analog.c
|
||||
QUANTUM_LIB_SRC += spi_master.c
|
||||
@@ -918,7 +903,6 @@ ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
|
||||
|
||||
ifeq ($(strip $(BLUETOOTH_DRIVER)), RN42)
|
||||
OPT_DEFS += -DBLUETOOTH_RN42 -DHAL_USE_SERIAL=TRUE
|
||||
SRC += $(DRIVER_PATH)/bluetooth/bluetooth.c
|
||||
SRC += $(DRIVER_PATH)/bluetooth/rn42.c
|
||||
QUANTUM_LIB_SRC += uart.c
|
||||
endif
|
||||
|
||||
@@ -152,7 +152,6 @@ endif
|
||||
# To produce a UF2 file in your build, add to your keyboard's rules.mk:
|
||||
# FIRMWARE_FORMAT = uf2
|
||||
UF2CONV = $(TOP_DIR)/util/uf2conv.py
|
||||
UF2CONV_ARGS ?=
|
||||
UF2_FAMILY ?= 0x0
|
||||
|
||||
# Compiler flags to generate dependency files.
|
||||
@@ -220,7 +219,7 @@ gccversion :
|
||||
@$(BUILD_CMD)
|
||||
|
||||
%.uf2: %.elf
|
||||
$(eval CMD=$(HEX) $< $(BUILD_DIR)/$(TARGET).tmp && $(UF2CONV) $(UF2CONV_ARGS) $(BUILD_DIR)/$(TARGET).tmp --output $@ --convert --family $(UF2_FAMILY) >/dev/null 2>&1)
|
||||
$(eval CMD=$(HEX) $< $(BUILD_DIR)/$(TARGET).tmp && $(UF2CONV) $(BUILD_DIR)/$(TARGET).tmp --output $@ --convert --family $(UF2_FAMILY) >/dev/null 2>&1)
|
||||
#@$(SILENT) || printf "$(MSG_EXECUTING) '$(CMD)':\n"
|
||||
@$(SILENT) || printf "$(MSG_UF2) $@" | $(AWK_CMD)
|
||||
@$(BUILD_CMD)
|
||||
|
||||
@@ -7,12 +7,7 @@ endif
|
||||
|
||||
# TODO: opt in rather than assume everything uses a pro micro
|
||||
PIN_COMPATIBLE ?= promicro
|
||||
|
||||
# Remove whitespace from any rule.mk provided vars
|
||||
# - env cannot be overwritten but cannot have whitespace anyway
|
||||
CONVERT_TO:=$(strip $(CONVERT_TO))
|
||||
ifneq ($(CONVERT_TO),)
|
||||
|
||||
# stash so we can overwrite env provided vars if needed
|
||||
ACTIVE_CONVERTER=$(CONVERT_TO)
|
||||
|
||||
@@ -28,13 +23,13 @@ ifneq ($(CONVERT_TO),)
|
||||
TARGET := $(TARGET)_$(CONVERT_TO)
|
||||
|
||||
# Configure any defaults
|
||||
OPT_DEFS += -DCONVERT_TO_$(shell echo $(CONVERT_TO) | tr '[:lower:]' '[:upper:]')
|
||||
OPT_DEFS += -DCONVERTER_TARGET=\"$(CONVERT_TO)\"
|
||||
OPT_DEFS += -DCONVERT_TO_$(strip $(shell echo $(CONVERT_TO) | tr '[:lower:]' '[:upper:]'))
|
||||
OPT_DEFS += -DCONVERTER_TARGET=\"$(strip $(CONVERT_TO))\"
|
||||
OPT_DEFS += -DCONVERTER_ENABLED
|
||||
VPATH += $(CONVERTER)
|
||||
|
||||
# Configure for "alias" - worst case it produces an idential define
|
||||
OPT_DEFS += -DCONVERT_TO_$(shell echo $(ACTIVE_CONVERTER) | tr '[:lower:]' '[:upper:]')
|
||||
OPT_DEFS += -DCONVERT_TO_$(strip $(shell echo $(ACTIVE_CONVERTER) | tr '[:lower:]' '[:upper:]'))
|
||||
|
||||
# Finally run any converter specific logic
|
||||
include $(CONVERTER)/converter.mk
|
||||
|
||||
@@ -32,7 +32,6 @@ GENERIC_FEATURES = \
|
||||
KEY_OVERRIDE \
|
||||
LEADER \
|
||||
PROGRAMMABLE_BUTTON \
|
||||
REPEAT_KEY \
|
||||
SECURE \
|
||||
SPACE_CADET \
|
||||
SWAP_HANDS \
|
||||
|
||||
@@ -85,8 +85,7 @@ OTHER_OPTION_NAMES = \
|
||||
SECURE_ENABLE \
|
||||
CAPS_WORD_ENABLE \
|
||||
AUTOCORRECT_ENABLE \
|
||||
TRI_LAYER_ENABLE \
|
||||
REPEAT_KEY_ENABLE
|
||||
TRI_LAYER_ENABLE
|
||||
|
||||
define NAME_ECHO
|
||||
@printf " %-30s = %-16s # %s\\n" "$1" "$($1)" "$(origin $1)"
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"MKL26Z64" : {
|
||||
"MCU" : "cortex-m0plus",
|
||||
"ARMV": 6,
|
||||
"MCU_FAMILY": "KINETIS",
|
||||
"MCU_SERIES": "KL2x",
|
||||
"MCU_LDSCRIPT": "MKL26Z64",
|
||||
"MCU_STARTUP": "kl2x",
|
||||
"BOARD": "PJRC_TEENSY_LC"
|
||||
},
|
||||
"MK20DX128" : {
|
||||
"MCU" : "cortex-m4",
|
||||
"ARMV": 7,
|
||||
"MCU_FAMILY": "KINETIS",
|
||||
"MCU_SERIES": "K20x",
|
||||
"MCU_LDSCRIPT": "MK20DX128",
|
||||
"MCU_STARTUP": "k20x5",
|
||||
"BOARD": "PJRC_TEENSY_3"
|
||||
},
|
||||
"MK20DX256" : {
|
||||
"MCU" : "cortex-m4",
|
||||
"ARMV": 7,
|
||||
"MCU_FAMILY": "KINETIS",
|
||||
"MCU_SERIES": "K20x",
|
||||
"MCU_LDSCRIPT": "MK20DX256",
|
||||
"MCU_STARTUP": "k20x7",
|
||||
"BOARD": "PJRC_TEENSY_3_1"
|
||||
},
|
||||
"STM32F303" : {
|
||||
"MCU" : "cortex-m4",
|
||||
"ARMV": 7,
|
||||
"MCU_FAMILY": "STM32",
|
||||
"MCU_SERIES": "STM32F3xx",
|
||||
"MCU_LDSCRIPT": "STM32F303xC",
|
||||
"MCU_STARTUP": "stm32f3xx",
|
||||
"BOARD": "GENERIC_STM32_F303XC",
|
||||
"USE_FPU": true,
|
||||
"UF2_FAMILY": "STM32F3",
|
||||
"STM32_BOOTLOADER_ADDRESS": "0x1FFFD800"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
include(ResolveKeyboard)
|
||||
include(ValidateJson)
|
||||
include(ResolveToolchain)
|
||||
|
||||
macro(add_keyboard KEYBOARD_FOLDER KEYMAP_FOLDER)
|
||||
# not entirely sure why this is necessary
|
||||
# set(TEMP_PATH ${KEYBOARD_FOLDER})
|
||||
# cmake_path(IS_RELATIVE TEMP_PATH IS_KEYBOARD_FOLDER_RELATIVE)
|
||||
# if(${IS_KEYBOARD_FOLDER_RELATIVE})
|
||||
# set(KEYBOARD_FOLDER_ABS ${CMAKE_SOURCE_DIR}/keyboards/${KEYBOARD_FOLDER})
|
||||
# if(NOT EXISTS ${KEYBOARD_FOLDER_ABS})
|
||||
# # message(FATAL_ERROR "Keyboard does not exist in QMK - try using an absolute path to the keyboard folder")
|
||||
# resolve_keyboard(${KEYBOARD_FOLDER} KEYBOARD_FOLDER_ABS)
|
||||
# endif()
|
||||
# else()
|
||||
# set(KEYBOARD_FOLDER_ABS ${KEYBOARD_FOLDER})
|
||||
# if(NOT EXISTS ${KEYBOARD_FOLDER_ABS})
|
||||
# message(FATAL_ERROR "Absolute path to keyboard does not exist")
|
||||
# endif()
|
||||
# endif()
|
||||
|
||||
resolve_keyboard(${KEYBOARD_FOLDER} KEYBOARD_FOLDER_ABS)
|
||||
|
||||
set(TEMP_PATH ${KEYBOARD_FOLDER})
|
||||
cmake_path(IS_RELATIVE TEMP_PATH IS_KEYBOARD_FOLDER_RELATIVE)
|
||||
|
||||
set(TEMP_PATH ${KEYMAP_FOLDER})
|
||||
cmake_path(IS_RELATIVE TEMP_PATH IS_KEYMAP_FOLDER_RELATIVE)
|
||||
if(${IS_KEYMAP_FOLDER_RELATIVE})
|
||||
set(KEYMAP_NAME ${KEYMAP_FOLDER})
|
||||
else()
|
||||
if(WIN32)
|
||||
set(KEYMAP_NAME $ENV{USERNAME})
|
||||
else()
|
||||
set(KEYMAP_NAME $ENV{USE})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# find the right toolchain
|
||||
|
||||
# not sure we need to validate here
|
||||
validate_json(${KEYBOARD_FOLDER_ABS}/info.json keyboard JSON_STRING)
|
||||
|
||||
string(JSON PROCESSOR GET ${JSON_STRING} processor)
|
||||
resolve_toolchain(${PROCESSOR} TOOLCHAIN)
|
||||
|
||||
string(JSON KEYBOARD_NAME GET ${JSON_STRING} keyboard_name)
|
||||
if(${IS_KEYBOARD_FOLDER_RELATIVE})
|
||||
string(MAKE_C_IDENTIFIER ${KEYBOARD_FOLDER} KEYBOARD_SLUG)
|
||||
else()
|
||||
string(MAKE_C_IDENTIFIER ${KEYBOARD_NAME} KEYBOARD_SLUG)
|
||||
endif()
|
||||
string(JSON MANUFACTURER GET ${JSON_STRING} manufacturer)
|
||||
set(TARGET_NAME "${KEYBOARD_SLUG}_${KEYMAP_NAME}")
|
||||
ExternalProject_Add(${TARGET_NAME}
|
||||
SOURCE_DIR ${CMAKE_SOURCE_DIR}
|
||||
# PREFIX ${CMAKE_SOURCE_DIR}/build/keyboards/${KEYBOARD_FOLDER}
|
||||
TMP_DIR ${CMAKE_SOURCE_DIR}/build/tmp
|
||||
DOWNLOAD_DIR ${CMAKE_SOURCE_DIR}/build/download
|
||||
BINARY_DIR ${CMAKE_SOURCE_DIR}/build/keyboards/${TARGET_NAME}
|
||||
STAMP_DIR ${CMAKE_SOURCE_DIR}/build/stamp
|
||||
LOG_DIR ${CMAKE_SOURCE_DIR}/build/log
|
||||
INSTALL_DIR ${CMAKE_SOURCE_DIR}/build/install
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/build/${TARGET_NAME}${QMK_EXTENSION} ${CMAKE_SOURCE_DIR}/${TARGET_NAME}${QMK_EXTENSION}
|
||||
# this seems to work well for all systems so far - not sure if it'd be useful to customize
|
||||
CMAKE_GENERATOR "Unix Makefiles"
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_SOURCE_DIR}/cmake/toolchains/${TOOLCHAIN}.cmake
|
||||
-DQMK_KEYBOARD=${KEYBOARD_SLUG}
|
||||
-DQMK_KEYBOARD_FOLDER=${KEYBOARD_FOLDER}
|
||||
-DQMK_KEYMAP_FOLDER=${KEYMAP_FOLDER}
|
||||
-DTARGET_NAME=${TARGET_NAME}
|
||||
)
|
||||
ExternalProject_Add_Step(${TARGET_NAME} copy_compile_commands
|
||||
DEPENDEES configure
|
||||
DEPENDERS build
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/build/keyboards/${TARGET_NAME}/compile_commands.json ${CMAKE_SOURCE_DIR}/compile_commands.json
|
||||
# BYPRODUCTS ${CMAKE_SOURCE_DIR}/compile_commands.json
|
||||
ALWAYS TRUE
|
||||
)
|
||||
|
||||
# file(APPEND "${CMAKE_SOURCE_DIR}/build/targets" "${TARGET_NAME}|${KEYBOARD_NAME} with ${KEYMAP_FOLDER}|${KEYBOARD_FOLDER}|Made by: ${MANUFACTURER}\n")
|
||||
endmacro(add_keyboard)
|
||||
@@ -0,0 +1,44 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
include(ResolveKeyboard)
|
||||
include(ValidateJSON)
|
||||
|
||||
resolve_keyboard(${QMK_KEYBOARD_FOLDER} KEYBOARD_FOLDER_ABS)
|
||||
validate_json(${KEYBOARD_FOLDER_ABS}/info.json keyboard JSON_STRING)
|
||||
|
||||
if(NOT DEFINED QMK_KEYMAP_FOLDER)
|
||||
set(QMK_KEYMAP_FOLDER default)
|
||||
endif()
|
||||
|
||||
set(TEMP_PATH ${QMK_KEYBOARD_FOLDER})
|
||||
cmake_path(IS_RELATIVE TEMP_PATH IS_KEYBOARD_FOLDER_RELATIVE)
|
||||
|
||||
set(TEMP_PATH ${QMK_KEYMAP_FOLDER})
|
||||
cmake_path(IS_RELATIVE TEMP_PATH IS_KEYMAP_FOLDER_RELATIVE)
|
||||
|
||||
if(${IS_KEYMAP_FOLDER_RELATIVE})
|
||||
set(KEYMAP_NAME ${QMK_KEYMAP_FOLDER})
|
||||
else()
|
||||
if(WIN32)
|
||||
set(KEYMAP_NAME $ENV{USERNAME})
|
||||
else()
|
||||
set(KEYMAP_NAME $ENV{USE})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
string(JSON KEYBOARD_NAME GET ${JSON_STRING} keyboard_name)
|
||||
|
||||
if(${IS_KEYBOARD_FOLDER_RELATIVE})
|
||||
string(MAKE_C_IDENTIFIER ${QMK_KEYBOARD_FOLDER} KEYBOARD_SLUG)
|
||||
else()
|
||||
string(MAKE_C_IDENTIFIER ${KEYBOARD_NAME} KEYBOARD_SLUG)
|
||||
endif()
|
||||
|
||||
string(JSON MANUFACTURER GET ${JSON_STRING} manufacturer)
|
||||
|
||||
set(TARGET_NAME "${KEYBOARD_SLUG}_${KEYMAP_NAME}")
|
||||
file(APPEND "${CMAKE_SOURCE_DIR}/build/targets" "${TARGET_NAME}|${KEYBOARD_NAME} with ${QMK_KEYMAP_FOLDER}|${QMK_KEYBOARD_FOLDER}:${QMK_KEYMAP_FOLDER}|Made by: ${MANUFACTURER}\n")
|
||||
|
||||
message(STATUS "Added keyboard '${QMK_KEYBOARD_FOLDER}' with keymap '${QMK_KEYMAP_FOLDER}'")
|
||||
@@ -0,0 +1,14 @@
|
||||
macro(find_arm_toolchain)
|
||||
find_toolchain(arm-none-eabi TOOLCHAIN_ROOT)
|
||||
|
||||
if(NOT TOOLCHAIN_ROOT)
|
||||
include(GetARMToolchain)
|
||||
find_toolchain(arm-none-eabi TOOLCHAIN_ROOT)
|
||||
endif()
|
||||
|
||||
if(NOT TOOLCHAIN_ROOT)
|
||||
message(FATAL_ERROR "ARM Toolchain could not be found")
|
||||
endif()
|
||||
|
||||
message(STATUS "ARM toolchain found: ${TOOLCHAIN_ROOT}")
|
||||
endmacro()
|
||||
@@ -0,0 +1,20 @@
|
||||
macro(find_avr_toolchain)
|
||||
find_toolchain(avr TOOLCHAIN_ROOT)
|
||||
|
||||
if(NOT TOOLCHAIN_ROOT)
|
||||
include(GetAVRToolchain)
|
||||
find_toolchain(avr TOOLCHAIN_ROOT)
|
||||
endif()
|
||||
|
||||
find_program(DFU_PROGRAMMER NAMES dfu-programmer PATHS ${CMAKE_SOURCE_DIR}/toolchains/dfu-programmer/)
|
||||
if(${DFU_PROGRAMMER} STREQUAL "DFU_PROGRAMMER-NOTFOUND")
|
||||
include(GetDfuProgrammer)
|
||||
find_program(DFU_PROGRAMMER NAMES dfu-programmer PATHS ${CMAKE_SOURCE_DIR}/toolchains/dfu-programmer/)
|
||||
endif()
|
||||
|
||||
if(NOT TOOLCHAIN_ROOT)
|
||||
message(FATAL_ERROR "AVR Toolchain could not be found")
|
||||
endif()
|
||||
|
||||
message(STATUS "AVR toolchain found: ${TOOLCHAIN_ROOT}")
|
||||
endmacro()
|
||||
@@ -0,0 +1,282 @@
|
||||
include(ParseMakefile)
|
||||
|
||||
# STM32F303
|
||||
|
||||
set(MCU "cortex-m4")
|
||||
set(ARMV 7)
|
||||
set(MCU_FAMILY "STM32")
|
||||
set(MCU_SERIES "STM32F3xx")
|
||||
string(TOUPPER ${MCU_SERIES} MCU_SERIES_UPPER)
|
||||
set(MCU_LDSCRIPT "STM32F303xC")
|
||||
set(MCU_STARTUP "stm32f3xx")
|
||||
set(BOARD "GENERIC_STM32_F303XC")
|
||||
set(USE_FPU TRUE)
|
||||
set(UF2_FAMILY "STM32F3")
|
||||
set(STM32_BOOTLOADER_ADDRESS 0x1FFFD800)
|
||||
set(EEPROM_DRIVER "wear_leveling" FORCE)
|
||||
set(WEAR_LEVELING_DRIVER "embedded_flash" FORCE)
|
||||
|
||||
target_compile_definitions(qmk PUBLIC
|
||||
QMK_MCU_FAMILY_${MCU_FAMILY}
|
||||
QMK_MCU_SERIES_${MCU_SERIES_UPPER}
|
||||
)
|
||||
|
||||
target_compile_options(qmk PUBLIC
|
||||
-march=armv7-m
|
||||
)
|
||||
|
||||
target_compile_definitions(qmk PUBLIC
|
||||
MCU_${MCU_FAMILY}
|
||||
__ARM_ARCH_7M__
|
||||
)
|
||||
|
||||
# platforms/chibios/platform.mk
|
||||
|
||||
if(NOT DEFINED USE_PROCESS_STACKSIZE)
|
||||
set(USE_PROCESS_STACKSIZE 0x800)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED USE_EXCEPTIONS_STACKSIZE)
|
||||
set(USE_EXCEPTIONS_STACKSIZE 0x400)
|
||||
endif()
|
||||
|
||||
target_link_options(qmk PUBLIC
|
||||
-Wl,--defsym=__process_stack_size__=${USE_PROCESS_STACKSIZE},--defsym=__main_stack_size__=${USE_EXCEPTIONS_STACKSIZE}
|
||||
)
|
||||
|
||||
if(NOT DEFINED MCU_PORT_NAME)
|
||||
set(MCU_PORT_NAME ${MCU_FAMILY})
|
||||
endif()
|
||||
set(MCU_ARCH ${MCU})
|
||||
if(NOT DEFINED CHIBIOS_PORT)
|
||||
set(CHIBIOS_PORT "ARMv${ARMV}-M")
|
||||
endif()
|
||||
if(NOT DEFINED PLATFORM_NAME)
|
||||
set(PLATFORM_NAME platform)
|
||||
endif()
|
||||
|
||||
set(CHIBIOS ${CMAKE_SOURCE_DIR}/lib/chibios)
|
||||
set(CHIBIOS_CONTRIB ${CMAKE_SOURCE_DIR}/lib/chibios-contrib)
|
||||
|
||||
# port*.mk
|
||||
include(chibios/ports/${CHIBIOS_PORT})
|
||||
|
||||
# platform.mk
|
||||
include(chibios/ports/${MCU_SERIES})
|
||||
|
||||
# startup_*.mk - might need to convert these
|
||||
find_file(STARTUP_MK startup_${MCU_STARTUP}.mk
|
||||
${CHIBIOS}/os/common/ports/ARMCMx/compilers/GCC/mk
|
||||
${CHIBIOS}/os/common/startup/ARMCMx/compilers/GCC/mk
|
||||
${CHIBIOS_CONTRIB}/os/common/startup/ARMCMx/compilers/GCC/mk
|
||||
)
|
||||
get_filename_component(STARTUP_DIR ${STARTUP_MK} DIRECTORY)
|
||||
ParseMakefile(${STARTUP_MK})
|
||||
target_sources(qmk PUBLIC ${STARTUPSRC})
|
||||
target_sources(qmk PUBLIC ${STARTUPASM})
|
||||
target_include_directories(qmk PUBLIC ${STARTUPINC})
|
||||
|
||||
# board paths - we should just standardize these
|
||||
find_path(BOARD_PATH
|
||||
NAMES
|
||||
boards/${BOARD}/board.mk
|
||||
board/board.mk
|
||||
PATHS
|
||||
${QMK_KEYBOARD_FOLDER}/boards/${BOARD}
|
||||
${CMAKE_SOURCE_DIR}/platforms/chibios/boards/${BOARD}
|
||||
${CHIBIOS}/os/hal/
|
||||
${CHIBIOS_CONTRIB}/os/hal/
|
||||
)
|
||||
# if(EXISTS ${BOARD_PATH}/rules.mk)
|
||||
# ParseMakefile(${BOARD_PATH}/rules.mk)
|
||||
# endif()
|
||||
|
||||
if(EXISTS ${BOARD_PATH}/configs/config.h)
|
||||
target_precompile_headers(qmk PUBLIC
|
||||
${BOARD_PATH}/configs/config.h
|
||||
)
|
||||
endif()
|
||||
|
||||
if(EXISTS ${BOARD_PATH}/configs/post_config.h)
|
||||
target_precompile_headers(qmk PUBLIC
|
||||
${BOARD_PATH}/configs/post_config.h
|
||||
)
|
||||
endif()
|
||||
|
||||
find_file(BOARD_MK board.mk
|
||||
${BOARD_PATH}/boards/${BOARD}
|
||||
${BOARD_PATH}/board
|
||||
)
|
||||
ParseMakefile(${BOARD_MK})
|
||||
|
||||
target_sources(qmk PUBLIC ${BOARDSRC})
|
||||
target_include_directories(qmk PUBLIC ${BOARDINC})
|
||||
|
||||
# allow board.c to be overriden
|
||||
file(RELATIVE_PATH INIT_HOOK_RELATIVE ${CMAKE_BINARY_DIR}
|
||||
"${CMAKE_SOURCE_DIR}/tmk_core/protocol/chibios/init_hooks.h")
|
||||
set_source_files_properties(${BOARDSRC} TARGET_DIRECTORY qmk PROPERTIES
|
||||
# COMPILE_OPTIONS "-include ../../../tmk_core/protocol/chibios/init_hooks.h"
|
||||
COMPILE_OPTIONS "-include ${INIT_HOOK_RELATIVE}"
|
||||
)
|
||||
|
||||
# bootloader
|
||||
if(DEFINED STM32_BOOTLOADER_ADDRESS)
|
||||
target_compile_definitions(qmk PUBLIC STM32_BOOTLOADER_ADDRESS=${STM32_BOOTLOADER_ADDRESS})
|
||||
endif()
|
||||
if(DEFINED WB32_BOOTLOADER_ADDRESS)
|
||||
target_compile_definitions(qmk PUBLIC WB32_BOOTLOADER_ADDRESS=${WB32_BOOTLOADER_ADDRESS})
|
||||
endif()
|
||||
|
||||
find_file(BOOTLOADER_DEFS_H bootloader_defs.h
|
||||
${QMK_KEYBOARD_FOLDER}
|
||||
${QMK_KEYBOARD_FOLDER}/boards/${BOARD}
|
||||
${BOARD_PATH}/configs
|
||||
)
|
||||
if(EXISTS ${BOOTLOADER_DEFS_H})
|
||||
target_compile_options(qmk PUBLIC -include ${BOOTLOADER_DEFS_H})
|
||||
endif()
|
||||
|
||||
# chconf directories
|
||||
find_path(CHCONFDIR chconf.h
|
||||
${QMK_KEYBOARD_FOLDER}
|
||||
${CMAKE_SOURCE_DIR}/platforms/chibios/boards/${BOARD}/configs
|
||||
${CMAKE_SOURCE_DIR}/platforms/chibios/boards/common/configs
|
||||
)
|
||||
target_include_directories(qmk PUBLIC ${CHCONFDIR})
|
||||
|
||||
# halconf directories
|
||||
find_path(HALCONFDIR halconf.h
|
||||
${QMK_KEYBOARD_FOLDER}
|
||||
${CMAKE_SOURCE_DIR}/platforms/chibios/boards/${BOARD}/configs
|
||||
${CMAKE_SOURCE_DIR}/platforms/chibios/boards/common/configs
|
||||
)
|
||||
target_include_directories(qmk PUBLIC ${HALCONFDIR})
|
||||
|
||||
# linker script
|
||||
find_file(LDSCRIPT ${MCU_LDSCRIPT}.ld
|
||||
${QMK_KEYBOARD_FOLDER}/ld
|
||||
${CMAKE_SOURCE_DIR}/platforms/chibios/boards/${BOARD}/ld
|
||||
${CMAKE_SOURCE_DIR}/platforms/chibios/boards/common/ld
|
||||
${STARTUPLD}
|
||||
${STARTUPLD_CONTRIB}
|
||||
)
|
||||
get_filename_component(LDSCRIPT_PATH ${LDSCRIPT} DIRECTORY)
|
||||
target_link_options(qmk PUBLIC
|
||||
-T ${LDSCRIPT}
|
||||
-L ${LDSCRIPT_PATH}
|
||||
)
|
||||
|
||||
# os/hal/hal.mk
|
||||
target_sources(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/src/hal.c
|
||||
${CHIBIOS}/os/hal/src/hal_st.c
|
||||
${CHIBIOS}/os/hal/src/hal_buffers.c
|
||||
${CHIBIOS}/os/hal/src/hal_queues.c
|
||||
${CHIBIOS}/os/hal/src/hal_flash.c
|
||||
${CHIBIOS}/os/hal/src/hal_mmcsd.c
|
||||
${CHIBIOS}/os/hal/src/hal_adc.c
|
||||
${CHIBIOS}/os/hal/src/hal_can.c
|
||||
${CHIBIOS}/os/hal/src/hal_crypto.c
|
||||
${CHIBIOS}/os/hal/src/hal_dac.c
|
||||
${CHIBIOS}/os/hal/src/hal_efl.c
|
||||
${CHIBIOS}/os/hal/src/hal_gpt.c
|
||||
${CHIBIOS}/os/hal/src/hal_i2c.c
|
||||
${CHIBIOS}/os/hal/src/hal_i2s.c
|
||||
${CHIBIOS}/os/hal/src/hal_icu.c
|
||||
${CHIBIOS}/os/hal/src/hal_mac.c
|
||||
${CHIBIOS}/os/hal/src/hal_mmc_spi.c
|
||||
${CHIBIOS}/os/hal/src/hal_pal.c
|
||||
${CHIBIOS}/os/hal/src/hal_pwm.c
|
||||
${CHIBIOS}/os/hal/src/hal_rtc.c
|
||||
${CHIBIOS}/os/hal/src/hal_sdc.c
|
||||
${CHIBIOS}/os/hal/src/hal_serial.c
|
||||
${CHIBIOS}/os/hal/src/hal_serial_usb.c
|
||||
${CHIBIOS}/os/hal/src/hal_sio.c
|
||||
${CHIBIOS}/os/hal/src/hal_spi.c
|
||||
${CHIBIOS}/os/hal/src/hal_trng.c
|
||||
${CHIBIOS}/os/hal/src/hal_uart.c
|
||||
${CHIBIOS}/os/hal/src/hal_usb.c
|
||||
${CHIBIOS}/os/hal/src/hal_wdg.c
|
||||
${CHIBIOS}/os/hal/src/hal_wspi.c
|
||||
)
|
||||
target_include_directories(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/include
|
||||
)
|
||||
|
||||
# os/hal/osal/rt-nil/osal.mk
|
||||
target_sources(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/osal/rt-nil/osal.c
|
||||
)
|
||||
target_include_directories(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/osal/rt-nil
|
||||
)
|
||||
|
||||
# os/rt/rt.mk
|
||||
target_sources(qmk PUBLIC
|
||||
${CHIBIOS}/os/rt/src/chsys.c
|
||||
${CHIBIOS}/os/rt/src/chrfcu.c
|
||||
${CHIBIOS}/os/rt/src/chdebug.c
|
||||
${CHIBIOS}/os/rt/src/chtrace.c
|
||||
${CHIBIOS}/os/rt/src/chvt.c
|
||||
${CHIBIOS}/os/rt/src/chschd.c
|
||||
${CHIBIOS}/os/rt/src/chinstances.c
|
||||
${CHIBIOS}/os/rt/src/chthreads.c
|
||||
${CHIBIOS}/os/rt/src/chsys.c
|
||||
${CHIBIOS}/os/rt/src/chrfcu.c
|
||||
${CHIBIOS}/os/rt/src/chdebug.c
|
||||
${CHIBIOS}/os/rt/src/chtrace.c
|
||||
${CHIBIOS}/os/rt/src/chvt.c
|
||||
${CHIBIOS}/os/rt/src/chschd.c
|
||||
${CHIBIOS}/os/rt/src/chinstances.c
|
||||
${CHIBIOS}/os/rt/src/chthreads.c
|
||||
${CHIBIOS}/os/rt/src/chtm.c
|
||||
${CHIBIOS}/os/rt/src/chstats.c
|
||||
${CHIBIOS}/os/rt/src/chregistry.c
|
||||
${CHIBIOS}/os/rt/src/chsem.c
|
||||
${CHIBIOS}/os/rt/src/chmtx.c
|
||||
${CHIBIOS}/os/rt/src/chcond.c
|
||||
${CHIBIOS}/os/rt/src/chevents.c
|
||||
${CHIBIOS}/os/rt/src/chmsg.c
|
||||
${CHIBIOS}/os/rt/src/chdynamic.c
|
||||
)
|
||||
target_include_directories(qmk PUBLIC
|
||||
${CHIBIOS}/os/rt/include
|
||||
)
|
||||
|
||||
# os/oslib/oslib.mk
|
||||
target_sources(qmk PUBLIC
|
||||
${CHIBIOS}/os/oslib/src/chmboxes.c
|
||||
${CHIBIOS}/os/oslib/src/chmemcore.c
|
||||
${CHIBIOS}/os/oslib/src/chmemheaps.c
|
||||
${CHIBIOS}/os/oslib/src/chmempools.c
|
||||
${CHIBIOS}/os/oslib/src/chpipes.c
|
||||
${CHIBIOS}/os/oslib/src/chobjcaches.c
|
||||
${CHIBIOS}/os/oslib/src/chdelegates.c
|
||||
${CHIBIOS}/os/oslib/src/chfactory.c
|
||||
)
|
||||
target_include_directories(qmk PUBLIC
|
||||
${CHIBIOS}/os/oslib/include
|
||||
)
|
||||
|
||||
# os/hal/lib/streams/streams.mk
|
||||
target_sources(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/lib/streams/chprintf.c
|
||||
${CHIBIOS}/os/hal/lib/streams/chscanf.c
|
||||
${CHIBIOS}/os/hal/lib/streams/memstreams.c
|
||||
${CHIBIOS}/os/hal/lib/streams/nullstreams.c
|
||||
${CHIBIOS}/os/hal/lib/streams/bufstreams.c
|
||||
)
|
||||
target_include_directories(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/lib/streams
|
||||
)
|
||||
|
||||
# resume platform.mk
|
||||
target_sources(qmk PUBLIC
|
||||
${CHIBIOS}/os/various/syscalls.c
|
||||
)
|
||||
target_include_directories(qmk PUBLIC
|
||||
${CHIBIOS}/os/license
|
||||
${CHIBIOS}/os/oslib/include
|
||||
${CHIBIOS}/os/various
|
||||
)
|
||||
@@ -0,0 +1,27 @@
|
||||
include(UpdateSubmodule)
|
||||
update_submodule(lib/lufa)
|
||||
set(LUFA_PATH ${CMAKE_SOURCE_DIR}/lib/lufa)
|
||||
set(LUFA_ROOT_PATH ${LUFA_PATH}/LUFA)
|
||||
target_sources(qmk PUBLIC
|
||||
${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/USBController_${ARCH}.c
|
||||
${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/USBInterrupt_${ARCH}.c
|
||||
${LUFA_ROOT_PATH}/Drivers/USB/Core/ConfigDescriptors.c
|
||||
${LUFA_ROOT_PATH}/Drivers/USB/Core/Events.c
|
||||
${LUFA_ROOT_PATH}/Drivers/USB/Core/USBTask.c
|
||||
${LUFA_ROOT_PATH}/Drivers/USB/Class/Common/HIDParser.c
|
||||
|
||||
${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/Host_${ARCH}.c
|
||||
${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/Pipe_${ARCH}.c
|
||||
${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/PipeStream_${ARCH}.c
|
||||
${LUFA_ROOT_PATH}/Drivers/USB/Core/HostStandardReq.c
|
||||
|
||||
${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/Device_${ARCH}.c
|
||||
${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/Endpoint_${ARCH}.c
|
||||
${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/EndpointStream_${ARCH}.c
|
||||
${LUFA_ROOT_PATH}/Drivers/USB/Core/DeviceStandardReq.c
|
||||
${LUFA_PATH}/LUFA/Drivers/USB/USB.h
|
||||
)
|
||||
target_include_directories(qmk PUBLIC ${LUFA_PATH})
|
||||
# target_link_libraries(lufa ${QMK_TARGET})
|
||||
# target_link_libraries(lufa tmk_core_protocol)
|
||||
# target_link_libraries(lufa tmk_core_protocol_lufa)
|
||||
@@ -0,0 +1,24 @@
|
||||
message("Downloading gcc-arm-none-eabi")
|
||||
if(WIN32)
|
||||
file(DOWNLOAD
|
||||
https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10-win32.zip?rev=8f4a92e2ec2040f89912f372a55d8cf3&hash=8A9EAF77EF1957B779C59EADDBF2DAC118170BBF
|
||||
${CMAKE_SOURCE_DIR}/toolchains/downloads/gcc-arm-none-eabi-win32.zip
|
||||
EXPECTED_HASH MD5=2bc8f0c4c4659f8259c8176223eeafc1
|
||||
SHOW_PROGRESS
|
||||
)
|
||||
file(ARCHIVE_EXTRACT
|
||||
INPUT ${CMAKE_SOURCE_DIR}/toolchains/downloads/gcc-arm-none-eabi-win32.zip
|
||||
DESTINATION ${CMAKE_SOURCE_DIR}/toolchains/
|
||||
)
|
||||
elseif(UNIX)
|
||||
file(DOWNLOAD
|
||||
https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2?rev=78196d3461ba4c9089a67b5f33edf82a&hash=D484B37FF37D6FC3597EBE2877FB666A41D5253B
|
||||
${CMAKE_SOURCE_DIR}/toolchains/downloads/gcc-arm-none-eabi-x86_64-linux.tar.bz2
|
||||
EXPECTED_HASH MD5=3fe3d8bb693bd0a6e4615b6569443d0d
|
||||
SHOW_PROGRESS
|
||||
)
|
||||
file(ARCHIVE_EXTRACT
|
||||
INPUT ${CMAKE_SOURCE_DIR}/toolchains/downloads/gcc-arm-none-eabi-x86_64-linux.tar.bz2
|
||||
DESTINATION ${CMAKE_SOURCE_DIR}/toolchains/
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,24 @@
|
||||
message("Downloading avr-gcc")
|
||||
if(WIN32)
|
||||
file(DOWNLOAD
|
||||
https://github.com/ZakKemble/avr-gcc-build/releases/download/v12.1.0-1/avr-gcc-12.1.0-x64-windows.zip
|
||||
${CMAKE_SOURCE_DIR}/toolchains/downloads/avr-gcc-x64-windows.zip
|
||||
EXPECTED_HASH SHA256=e921a964fdeaedbe963352d0f26c6520a0a3eb8effc6ff232f3824b06c4ea0e2
|
||||
SHOW_PROGRESS
|
||||
)
|
||||
file(ARCHIVE_EXTRACT
|
||||
INPUT ${CMAKE_SOURCE_DIR}/toolchains/downloads/avr-gcc-x64-windows.zip
|
||||
DESTINATION ${CMAKE_SOURCE_DIR}/toolchains/
|
||||
)
|
||||
elseif(UNIX)
|
||||
file(DOWNLOAD
|
||||
https://github.com/ZakKemble/avr-gcc-build/releases/download/v12.1.0-1/avr-gcc-12.1.0-x64-linux.tar.bz2
|
||||
${CMAKE_SOURCE_DIR}/toolchains/downloads/avr-gcc-x64-linux.tar.bz2
|
||||
EXPECTED_HASH SHA256=feb034f4b85237032da8bac1f03765af5ebc4a8939b69bed57ff31bc482ca1a6
|
||||
SHOW_PROGRESS
|
||||
)
|
||||
file(ARCHIVE_EXTRACT
|
||||
INPUT ${CMAKE_SOURCE_DIR}/toolchains/downloads/avr-gcc-x64-linux.tar.bz2
|
||||
DESTINATION ${CMAKE_SOURCE_DIR}/toolchains/
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,22 @@
|
||||
message("Downloading dfu-programmer")
|
||||
if(WIN32)
|
||||
file(DOWNLOAD
|
||||
https://github.com/dfu-programmer/dfu-programmer/releases/download/v1.0.0/dfu-programmer-x64-1.0.0.7z
|
||||
${CMAKE_SOURCE_DIR}/toolchains/downloads/dfu-programmer-x64-1.0.0.7z
|
||||
SHOW_PROGRESS
|
||||
)
|
||||
file(ARCHIVE_EXTRACT
|
||||
INPUT ${CMAKE_SOURCE_DIR}/toolchains/downloads/dfu-programmer-x64-1.0.0.7z
|
||||
DESTINATION ${CMAKE_SOURCE_DIR}/toolchains/dfu-programmer/
|
||||
)
|
||||
elseif(UNIX)
|
||||
file(DOWNLOAD
|
||||
https://github.com/dfu-programmer/dfu-programmer/releases/download/v1.0.0/dfu-programmer-linux-1.0.0.7z
|
||||
${CMAKE_SOURCE_DIR}/toolchains/downloads/dfu-programmer-linux-1.0.0.7z
|
||||
SHOW_PROGRESS
|
||||
)
|
||||
file(ARCHIVE_EXTRACT
|
||||
INPUT ${CMAKE_SOURCE_DIR}/toolchains/downloads/dfu-programmer-linux-1.0.0.7z
|
||||
DESTINATION ${CMAKE_SOURCE_DIR}/toolchains/dfu-programmer/
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,51 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
include(ResolveKeyboard)
|
||||
include(ValidateJson)
|
||||
|
||||
set(QMK_KEYBOARDS_FOLDER "${CMAKE_SOURCE_DIR}/keyboards")
|
||||
set(CMAKE_MESSAGE_INDENT "")
|
||||
|
||||
resolve_keyboard(${QMK_KEYBOARD_FOLDER} KEYBOARD_FOLDER_ABS)
|
||||
validate_json(${KEYBOARD_FOLDER_ABS}/info.json keyboard JSON_STR)
|
||||
cmake_path(IS_PREFIX QMK_KEYBOARDS_FOLDER "${KEYBOARD_FOLDER_ABS}" IS_KEYBOARDS_FOLDER)
|
||||
|
||||
file(WRITE "${CMAKE_SOURCE_DIR}/build/keyboard_keymaps" "")
|
||||
if(${IS_KEYBOARDS_FOLDER})
|
||||
file(RELATIVE_PATH RELATIVE_KEYBOARD_FOLDER ${QMK_KEYBOARDS_FOLDER} ${KEYBOARD_FOLDER_ABS})
|
||||
while(NOT ${RELATIVE_KEYBOARD_FOLDER} STREQUAL "")
|
||||
file(GLOB KEYMAPS "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/keymaps/*/keymap.c")
|
||||
foreach(KEYMAP ${KEYMAPS})
|
||||
file(RELATIVE_PATH KEYMAP_C "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/keymaps" "${KEYMAP}")
|
||||
get_filename_component(KEYMAP_FOLDER ${KEYMAP_C} DIRECTORY)
|
||||
# message(STATUS "${KEYMAP_FOLDER}")
|
||||
file(APPEND "${CMAKE_SOURCE_DIR}/build/keyboard_keymaps" "${KEYMAP_FOLDER}\n")
|
||||
endforeach()
|
||||
get_filename_component(RELATIVE_KEYBOARD_FOLDER ${RELATIVE_KEYBOARD_FOLDER} DIRECTORY)
|
||||
endwhile()
|
||||
else()
|
||||
if(EXISTS "${KEYBOARD_FOLDER_ABS}/keymap.c")
|
||||
set(${KEYMAP_C_STR} "${KEYBOARD_FOLDER_ABS}/keymap.c" PARENT_SCOPE)
|
||||
elseif(EXISTS "${KEYBOARD_FOLDER_ABS}/keymaps/${KEYMAP_FOLDER}/keymap.c")
|
||||
set(${KEYMAP_C_STR} "${KEYBOARD_FOLDER_ABS}/keymaps/${KEYMAP_FOLDER}/keymap.c" PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
string(JSON COMMUNITY_LAYOUTS ERROR_VARIABLE NO_COMMUNITY_LAYOUTS GET ${JSON_STR} community_layouts)
|
||||
|
||||
if(${NO_COMMUNITY_LAYOUTS} STREQUAL "NOTFOUND")
|
||||
string(JSON NUM_LAYOUTS LENGTH ${COMMUNITY_LAYOUTS})
|
||||
math(EXPR MAX "${NUM_LAYOUTS} - 1")
|
||||
foreach(IDX RANGE ${MAX})
|
||||
string(JSON LAYOUT GET ${COMMUNITY_LAYOUTS} ${IDX})
|
||||
file(GLOB KEYMAPS "${CMAKE_SOURCE_DIR}/layouts/community/${LAYOUT}/*/keymap.c")
|
||||
foreach(KEYMAP ${KEYMAPS})
|
||||
file(RELATIVE_PATH KEYMAP_C "${CMAKE_SOURCE_DIR}/layouts/community/${LAYOUT}" "${KEYMAP}")
|
||||
get_filename_component(KEYMAP_FOLDER ${KEYMAP_C} DIRECTORY)
|
||||
# message(STATUS "${KEYMAP_FOLDER}")
|
||||
file(APPEND "${CMAKE_SOURCE_DIR}/build/keyboard_keymaps" "${KEYMAP_FOLDER}\n")
|
||||
endforeach()
|
||||
endforeach()
|
||||
endif()
|
||||
@@ -0,0 +1,64 @@
|
||||
# Simple CMake utility to read variables from MK files
|
||||
# - Gets contents from given file (name or path)
|
||||
# - Parses the assignment statements
|
||||
# - Makes the same assignments in the PARENT_SCOPE
|
||||
|
||||
if(POLICY CMP0007)
|
||||
cmake_policy(SET CMP0007 NEW)
|
||||
endif()
|
||||
|
||||
function(ParseHeader HeaderFile Prefix)
|
||||
_ParseHeader(${HeaderFile} ${Prefix})
|
||||
endfunction()
|
||||
|
||||
macro(_ParseHeader HeaderFile Prefix)
|
||||
message(CHECK_START "Parsing Header")
|
||||
list(APPEND CMAKE_MESSAGE_INDENT " ")
|
||||
message(STATUS "Reading \"${HeaderFile}\"")
|
||||
|
||||
file(READ "${HeaderFile}" FileContents)
|
||||
string(REGEX REPLACE "/\\*.*\\*/" "" FileContents ${FileContents})
|
||||
# replace the \ newlines with spaces
|
||||
string(REGEX REPLACE "\\\\\r?\n *" " " FileContents ${FileContents})
|
||||
# turn each line into an item in a list
|
||||
string(REGEX REPLACE "\r?\n" ";" FileLines ${FileContents})
|
||||
list(REMOVE_ITEM FileLines "")
|
||||
|
||||
foreach(line ${FileLines})
|
||||
# remove comments from the ends of each line
|
||||
string(REGEX REPLACE "//.*" "" line ${line})
|
||||
|
||||
# remove now-empty lines
|
||||
if("${line}" STREQUAL "")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# try to process includes, if the file exists
|
||||
if(line MATCHES "^#include \"(.+)\"")
|
||||
set(INCLUDED_HEADER ${CMAKE_MATCH_1})
|
||||
if(EXISTS ${INCLUDED_HEADER})
|
||||
_ParseHeader("${INCLUDED_HEADER}" ${Prefix})
|
||||
else()
|
||||
message(STATUS "Could not read ${INCLUDED_HEADER}")
|
||||
endif()
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# array
|
||||
if(line MATCHES "#define ([A-Za-z0-9_]+) {(.*)}")
|
||||
set(VARIABLE_NAME ${CMAKE_MATCH_1})
|
||||
set(VARIABLE_VALUE ${CMAKE_MATCH_2})
|
||||
set(${Prefix}${VARIABLE_NAME} ${VARIABLE_VALUE})
|
||||
endif()
|
||||
|
||||
# regular variable
|
||||
if(line MATCHES "#define ([A-Za-z0-9_]+) (.*)")
|
||||
set(VARIABLE_NAME ${CMAKE_MATCH_1})
|
||||
set(VARIABLE_VALUE ${CMAKE_MATCH_2})
|
||||
set(${Prefix}${VARIABLE_NAME} ${VARIABLE_VALUE})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
list(POP_BACK CMAKE_MESSAGE_INDENT)
|
||||
message(CHECK_PASS "Complete")
|
||||
endmacro()
|
||||
@@ -0,0 +1,98 @@
|
||||
# Simple CMake utility to read variables from MK files
|
||||
# - Gets contents from given file (name or path)
|
||||
# - Parses the assignment statements
|
||||
# - Makes the same assignments in the PARENT_SCOPE
|
||||
|
||||
if(POLICY CMP0007)
|
||||
cmake_policy(SET CMP0007 NEW)
|
||||
endif()
|
||||
|
||||
function(ParseMakefile MKFile)
|
||||
_ParseMakefile(${MKFile} ${ARGN})
|
||||
endfunction()
|
||||
|
||||
macro(_ParseMakefile MKFile)
|
||||
message(CHECK_START "Parsing Makefile")
|
||||
list(APPEND CMAKE_MESSAGE_INDENT " ")
|
||||
message(STATUS "Reading \"${MKFile}\"")
|
||||
|
||||
file(READ "${MKFile}" FileContents)
|
||||
# replace the \ newlines with spaces
|
||||
string(REGEX REPLACE "\\\\\r?\n *" " " FileContents ${FileContents})
|
||||
# turn each line into an item in a list
|
||||
string(REGEX REPLACE "\r?\n" ";" FileLines ${FileContents})
|
||||
list(REMOVE_ITEM FileLines "")
|
||||
|
||||
foreach(line ${FileLines})
|
||||
# remove comments from the ends of each line
|
||||
string(REGEX REPLACE "#.*" "" line ${line})
|
||||
|
||||
# remove now-empty lines
|
||||
if("${line}" STREQUAL "")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# try to process includes, if the file exists
|
||||
if(line MATCHES "^-?include (.+)$")
|
||||
set(MAKE_CHILD ${CMAKE_MATCH_1})
|
||||
if(EXISTS ${MAKE_CHILD})
|
||||
_ParseMakefile("${MAKE_CHILD}" ${ARGN})
|
||||
else()
|
||||
message(STATUS "Could not read ${MAKE_CHILD}")
|
||||
endif()
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# turn the assignment into a list with the first item being the variable name
|
||||
string(REPLACE "=" ";" line_split ${line})
|
||||
list(LENGTH line_split count)
|
||||
|
||||
if(count LESS 2)
|
||||
message(STATUS "Skipping ${line}")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
list(GET line_split -1 value)
|
||||
string(STRIP ${value} value)
|
||||
# separate_arguments(value)
|
||||
# string(REPLACE " " ";" value ${value})
|
||||
list(REMOVE_AT line_split -1)
|
||||
|
||||
foreach(var_name ${line_split})
|
||||
string(STRIP ${var_name} var_name)
|
||||
# replace $(?) with the variable ? from cmake
|
||||
if(value MATCHES "\\$\\(([^\\(\\)]+)\\)")
|
||||
set(MAKE_VARIABLE "${CMAKE_MATCH_1}")
|
||||
string(REPLACE "$(${MAKE_VARIABLE})" "${${MAKE_VARIABLE}}" value ${value})
|
||||
endif()
|
||||
|
||||
# look for +, assuming it used to be +=
|
||||
if(${var_name} MATCHES "([^ \\+]+) *\\+")
|
||||
message(STATUS "Appending \"${CMAKE_MATCH_1}\" with \"${value}\"")
|
||||
# read parent variable in local & append
|
||||
set(LOCAL_${CMAKE_MATCH_1} ${CMAKE_MATCH_1})
|
||||
# APPEND accepts spaces between values
|
||||
list(APPEND LOCAL_${CMAKE_MATCH_1} ${value})
|
||||
set(${CMAKE_MATCH_1} ${LOCAL_${CMAKE_MATCH_1}})
|
||||
set(${CMAKE_MATCH_1} ${LOCAL_${CMAKE_MATCH_1}} PARENT_SCOPE)
|
||||
else()
|
||||
# set needs ; between elements to be considered a list
|
||||
string(REGEX REPLACE " +" ";" value ${value})
|
||||
# try to find variable in cache and FORCE wtih INTERNAL if it exists
|
||||
if(DEFINED CACHE${${var_name}})
|
||||
message(STATUS "Caching \"${var_name}\" to \"${value}\"")
|
||||
# set locally so replacement still work
|
||||
set(${var_name} ${value})
|
||||
set(${var_name} ${value} CACHE INTERNAL "")
|
||||
else()
|
||||
message(STATUS "Setting \"${var_name}\" to \"${value}\"")
|
||||
set(${var_name} ${value})
|
||||
set(${var_name} ${value} PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
list(POP_BACK CMAKE_MESSAGE_INDENT)
|
||||
message(CHECK_PASS "Complete")
|
||||
endmacro()
|
||||
@@ -0,0 +1,78 @@
|
||||
include(ParseMakefile)
|
||||
include(Utils)
|
||||
|
||||
macro(process_keyboard)
|
||||
message(CHECK_START "Processing keyboard")
|
||||
list(APPEND CMAKE_MESSAGE_INDENT " ")
|
||||
|
||||
validate_json(${QMK_KEYBOARD_FOLDER_ABS}/info.json keyboard QMK_KEYBOARD_INFO_JSON_STRING)
|
||||
|
||||
# process rules from info.json
|
||||
file(READ ${CMAKE_SOURCE_DIR}/data/mappings/info_rules.hjson JSON_STRING)
|
||||
string(JSON MAPPING_LENGTH LENGTH ${JSON_STRING})
|
||||
math(EXPR MAX "${MAPPING_LENGTH} - 1")
|
||||
foreach(IDX RANGE ${MAX})
|
||||
string(JSON RULE_KEY MEMBER ${JSON_STRING} ${IDX})
|
||||
# string(JSON INFO_KEY GET ${JSON_STRING} ${RULE_KEY} info_key)
|
||||
json_get_with_default(INFO_KEY ${JSON_STRING} _ ${RULE_KEY} info_key)
|
||||
string(REPLACE "." " " INFO_KEYS ${INFO_KEY})
|
||||
string(JSON RULE_VALUE ERROR_VARIABLE RULE_KEY_NOT_FOUND GET ${QMK_KEYBOARD_INFO_JSON_STRING} ${INFO_KEYS})
|
||||
if(${RULE_KEY_NOT_FOUND} STREQUAL "NOTFOUND")
|
||||
json_get_with_default(VALUE_TYPE ${JSON_STRING} raw ${RULE_KEY} value_type)
|
||||
if(${VALUE_TYPE} STREQUAL "list")
|
||||
string(JSON NUM_VALUES LENGTH ${RULE_VALUE})
|
||||
math(EXPR MAX "${NUM_VALUES} - 1")
|
||||
foreach(IDX RANGE ${MAX})
|
||||
string(JSON VALUE GET ${RULE_VALUE} ${IDX})
|
||||
list(APPEND ${RULE_KEY} ${VALUE})
|
||||
endforeach()
|
||||
message(STATUS "Found rule '${INFO_KEY}': '${${RULE_KEY}}' assigned to '${RULE_KEY}'")
|
||||
else()
|
||||
set(${RULE_KEY} ${RULE_VALUE})
|
||||
message(STATUS "Found rule '${INFO_KEY}': '${RULE_VALUE}' assigned to '${RULE_KEY}'")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# process definitions from info.json
|
||||
file(READ ${CMAKE_SOURCE_DIR}/data/mappings/info_config.hjson JSON_STRING)
|
||||
string(JSON MAPPING_LENGTH LENGTH ${JSON_STRING})
|
||||
math(EXPR MAX "${MAPPING_LENGTH} - 1")
|
||||
foreach(IDX RANGE ${MAX})
|
||||
string(JSON CONFIG_KEY MEMBER ${JSON_STRING} ${IDX})
|
||||
json_get_with_default(INFO_KEY ${JSON_STRING} _ ${CONFIG_KEY} info_key)
|
||||
string(REPLACE "." ";" INFO_KEYS ${INFO_KEY})
|
||||
# string(JSON CONFIG_VALUE ERROR_VARIABLE CONFIG_KEY_NOT_FOUND GET ${QMK_KEYBOARD_INFO_JSON_STRING} ${INFO_KEYS})
|
||||
json_get_with_default(CONFIG_VALUE ${QMK_KEYBOARD_INFO_JSON_STRING} NOTFOUND ${INFO_KEYS})
|
||||
if(NOT CONFIG_VALUE STREQUAL "NOTFOUND")
|
||||
set(${CONFIG_KEY} ${CONFIG_VALUE})
|
||||
json_get_with_default(VALUE_TYPE ${JSON_STRING} raw ${CONFIG_KEY} value_type)
|
||||
if(${VALUE_TYPE} STREQUAL "str")
|
||||
add_compile_definitions(${CONFIG_KEY}="${CONFIG_VALUE}")
|
||||
message(STATUS "Found definition '${INFO_KEY}': '\"${CONFIG_VALUE}\"' assigned to '${CONFIG_KEY}'")
|
||||
elseif(${VALUE_TYPE} STREQUAL "bcd_version")
|
||||
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" VERSION_MATCH ${CONFIG_VALUE})
|
||||
set(VERSION_MAJOR ${CMAKE_MATCH_1})
|
||||
set(VERSION_MINOR ${CMAKE_MATCH_2})
|
||||
set(VERSION_PATCH ${CMAKE_MATCH_3})
|
||||
math(EXPR BCD_VERSION "${VERSION_MAJOR} * 10000 + ${VERSION_MINOR} * 100 + ${VERSION_PATCH}" OUTPUT_FORMAT HEXADECIMAL)
|
||||
add_compile_definitions(${CONFIG_KEY}=${BCD_VERSION})
|
||||
message(STATUS "Found definition '${INFO_KEY}': '${BCD_VERSION}' assigned to '${CONFIG_KEY}'")
|
||||
else()
|
||||
add_compile_definitions(${CONFIG_KEY}=${CONFIG_VALUE})
|
||||
message(STATUS "Found definition '${INFO_KEY}': '${CONFIG_VALUE}' assigned to '${CONFIG_KEY}'")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
string(JSON KEYBOARD_NAME GET ${QMK_KEYBOARD_INFO_JSON_STRING} keyboard_name)
|
||||
string(JSON MANUFACTURER GET ${QMK_KEYBOARD_INFO_JSON_STRING} manufacturer)
|
||||
string(JSON URL GET ${QMK_KEYBOARD_INFO_JSON_STRING} url)
|
||||
string(JSON QMK_MCU GET ${QMK_KEYBOARD_INFO_JSON_STRING} processor)
|
||||
|
||||
list(POP_BACK CMAKE_MESSAGE_INDENT)
|
||||
message(CHECK_PASS "info.json validated and loaded")
|
||||
|
||||
|
||||
ParseMakefile(${QMK_KEYBOARD_FOLDER_ABS}/rules.mk)
|
||||
endmacro()
|
||||
@@ -0,0 +1,146 @@
|
||||
include(Utils)
|
||||
|
||||
function(resolve_keyboard KEYBOARD KEYBOAD_FOLDER_ABS_STR)
|
||||
message(VERBOSE "Resolving ${KEYBOARD}")
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/keyboards/${KEYBOARD}")
|
||||
message(VERBOSE "Found in repo: ${KEYBOARD}")
|
||||
set(${KEYBOAD_FOLDER_ABS_STR} "${CMAKE_SOURCE_DIR}/keyboards/${KEYBOARD}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/build/keyboard_repository/${KEYBOARD}")
|
||||
message(VERBOSE "Already checked out: ${KEYBOARD}")
|
||||
set(${KEYBOAD_FOLDER_ABS_STR} "${CMAKE_SOURCE_DIR}/build/keyboard_repository/${KEYBOARD}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
file(READ ${CMAKE_SOURCE_DIR}/data/keyboards.json KEYBOARDS_JSON)
|
||||
string(JSON KEYBOARD_SLUG ERROR_VARIABLE JSON_ERROR GET ${KEYBOARDS_JSON} ${KEYBOARD})
|
||||
if(${JSON_ERROR} STREQUAL "NOTFOUND")
|
||||
message(VERBOSE "Found ${KEYBOARD_SLUG}")
|
||||
if(${KEYBOARD_SLUG} MATCHES "^@([0-9a-zA-Z_]+/[0-9a-zA-Z_]+)")
|
||||
# keyboard slug is mapped to a github repo
|
||||
set(GIT_SLUG ${CMAKE_MATCH_1})
|
||||
# string(MAKE_C_IDENTIFIER ${KEYBOARD} KEYBOARD_NAME)
|
||||
message(VERBOSE "Cloning ${GIT_SLUG}")
|
||||
find_package(Git QUIET)
|
||||
if(GIT_FOUND)
|
||||
file(MAKE_DIRECTORY "${CMAKE_SOURCE_DIR}/build/keyboard_repository/${KEYBOARD}")
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} clone "https://github.com/${GIT_SLUG}.git" .
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/build/keyboard_repository/${KEYBOARD}"
|
||||
RESULT_VARIABLE GIT_SUBMOD_RESULT)
|
||||
if(NOT GIT_SUBMOD_RESULT EQUAL "0")
|
||||
message(FATAL_ERROR "git clone failed with ${GIT_SUBMOD_RESULT}")
|
||||
endif()
|
||||
else()
|
||||
message("Git not found - skipping submodule update")
|
||||
endif()
|
||||
set(${KEYBOAD_FOLDER_ABS_STR} "${CMAKE_SOURCE_DIR}/build/keyboard_repository/${KEYBOARD}" PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR "Didn't match")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Couldn't find")
|
||||
# set(${RESULT_STR} "NOTFOUND" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(resolve_config_h KEYBOARD_FOLDER_ABS CONFIG_H_STR)
|
||||
set(${CONFIG_H_STR} PARENT_SCOPE)
|
||||
if(${IS_KEYBOARDS_FOLDER})
|
||||
file(RELATIVE_PATH RELATIVE_KEYBOARD_FOLDER ${QMK_KEYBOARDS_FOLDER} ${KEYBOARD_FOLDER_ABS})
|
||||
# get the deepest config.h
|
||||
while(NOT ${RELATIVE_KEYBOARD_FOLDER} STREQUAL "")
|
||||
if(EXISTS "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/config.h")
|
||||
parent_list(PREPEND ${CONFIG_H_STR} "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/config.h")
|
||||
# set(${CONFIG_H_STR} "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/config.h" PARENT_SCOPE)
|
||||
# return()
|
||||
endif()
|
||||
get_filename_component(RELATIVE_KEYBOARD_FOLDER ${RELATIVE_KEYBOARD_FOLDER} DIRECTORY)
|
||||
endwhile()
|
||||
# message(FATAL_ERROR "Could not find config.h in ${KEYBOARD_FOLDER_ABS}")
|
||||
else()
|
||||
if(EXISTS "${KEYBOARD_FOLDER_ABS}/config.h")
|
||||
set(${CONFIG_H_STR} "${KEYBOARD_FOLDER_ABS}/config.h" PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR "Could not find config.h in ${KEYBOARD_FOLDER_ABS}")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(resolve_keyboard_h KEYBOARD_FOLDER_ABS KEYBOARD_H_STR)
|
||||
if(${IS_KEYBOARDS_FOLDER})
|
||||
file(RELATIVE_PATH RELATIVE_KEYBOARD_FOLDER ${QMK_KEYBOARDS_FOLDER} ${KEYBOARD_FOLDER_ABS})
|
||||
# get the deepest header
|
||||
while(NOT ${RELATIVE_KEYBOARD_FOLDER} STREQUAL "")
|
||||
get_filename_component(LAST_PART ${RELATIVE_KEYBOARD_FOLDER} NAME)
|
||||
if(EXISTS "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/${LAST_PART}.h")
|
||||
set(${KEYBOARD_H_STR} "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/${LAST_PART}.h" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
get_filename_component(RELATIVE_KEYBOARD_FOLDER ${RELATIVE_KEYBOARD_FOLDER} DIRECTORY)
|
||||
endwhile()
|
||||
message(FATAL_ERROR "Could not find *.h in ${KEYBOARD_FOLDER_ABS}")
|
||||
else()
|
||||
if(EXISTS "${KEYBOARD_FOLDER_ABS}/keyboard.h")
|
||||
set(${KEYBOARD_H_STR} "${KEYBOARD_FOLDER_ABS}/keyboard.h" PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR "Could not find keyboard.h in ${KEYBOARD_FOLDER_ABS}")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(resolve_keymap_c KEYBOARD_FOLDER_ABS KEYMAP_FOLDER KEYMAP_C_STR)
|
||||
if(IS_ABSOLUTE ${KEYMAP_FOLDER})
|
||||
if(EXISTS "${KEYMAP_FOLDER}/keymap.c")
|
||||
set(${KEYMAP_C_STR} "${KEYMAP_FOLDER}/keymap.c" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
else()
|
||||
if(${IS_KEYBOARDS_FOLDER})
|
||||
file(RELATIVE_PATH RELATIVE_KEYBOARD_FOLDER ${QMK_KEYBOARDS_FOLDER} ${KEYBOARD_FOLDER_ABS})
|
||||
# get the deepest keymap.c
|
||||
while(NOT ${RELATIVE_KEYBOARD_FOLDER} STREQUAL "")
|
||||
if(EXISTS "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/keymaps/${KEYMAP_FOLDER}/keymap.c")
|
||||
set(${KEYMAP_C_STR} "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/keymaps/${KEYMAP_FOLDER}/keymap.c" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
get_filename_component(RELATIVE_KEYBOARD_FOLDER ${RELATIVE_KEYBOARD_FOLDER} DIRECTORY)
|
||||
endwhile()
|
||||
else()
|
||||
if(EXISTS "${KEYBOARD_FOLDER_ABS}/keymap.c")
|
||||
set(${KEYMAP_C_STR} "${KEYBOARD_FOLDER_ABS}/keymap.c" PARENT_SCOPE)
|
||||
return()
|
||||
elseif(EXISTS "${KEYBOARD_FOLDER_ABS}/keymaps/${KEYMAP_FOLDER}/keymap.c")
|
||||
set(${KEYMAP_C_STR} "${KEYBOARD_FOLDER_ABS}/keymaps/${KEYMAP_FOLDER}/keymap.c" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# string(JSON COMMUNITY_LAYOUTS ERROR_VARIABLE NO_COMMUNITY_LAYOUTS GET ${QMK_KEYBOARD_INFO_JSON_STRING} community_layouts)
|
||||
|
||||
# if(${NO_COMMUNITY_LAYOUTS} STREQUAL "NOTFOUND")
|
||||
# string(JSON NUM_LAYOUTS LENGTH ${COMMUNITY_LAYOUTS})
|
||||
# math(EXPR MAX "${NUM_LAYOUTS} - 1")
|
||||
foreach(LAYOUT ${LAYOUTS})
|
||||
# foreach(IDX RANGE ${MAX})
|
||||
# string(JSON LAYOUT GET ${COMMUNITY_LAYOUTS} ${IDX})
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/layouts/community/${LAYOUT}/${KEYMAP_FOLDER}/keymap.c")
|
||||
set(${KEYMAP_C_STR} "${CMAKE_SOURCE_DIR}/layouts/community/${LAYOUT}/${KEYMAP_FOLDER}/keymap.c" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
endforeach()
|
||||
# endif()
|
||||
message(FATAL_ERROR "Could not resolve keymap '${KEYMAP_FOLDER}'")
|
||||
endfunction()
|
||||
|
||||
function(resolve_keyboard_includes KEYBOARD_FOLDER_ABS)
|
||||
if(${IS_KEYBOARDS_FOLDER})
|
||||
file(RELATIVE_PATH RELATIVE_KEYBOARD_FOLDER ${QMK_KEYBOARDS_FOLDER} ${KEYBOARD_FOLDER_ABS})
|
||||
while(NOT ${RELATIVE_KEYBOARD_FOLDER} STREQUAL "")
|
||||
target_include_directories(qmk PUBLIC "${CMAKE_SOURCE_DIR}/keyboards/${RELATIVE_KEYBOARD_FOLDER}")
|
||||
get_filename_component(RELATIVE_KEYBOARD_FOLDER ${RELATIVE_KEYBOARD_FOLDER} DIRECTORY)
|
||||
endwhile()
|
||||
else()
|
||||
target_include_directories(qmk PUBLIC "${KEYBOARD_FOLDER_ABS}")
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -0,0 +1,60 @@
|
||||
function(resolve_toolchain PROCESSOR TOOLCHAIN_STR)
|
||||
unset(${TOOLCHAIN_STR} PARENT_SCOPE)
|
||||
if(
|
||||
${PROCESSOR} MATCHES "^at.*"
|
||||
)
|
||||
set(${TOOLCHAIN_STR} "avr" PARENT_SCOPE)
|
||||
set(QMK_EXTENSION ".hex" PARENT_SCOPE)
|
||||
include(FindAVRToolchain)
|
||||
find_avr_toolchain()
|
||||
elseif(
|
||||
${PROCESSOR} MATCHES "^STM.*" OR
|
||||
${PROCESSOR} MATCHES "^WB32.*" OR
|
||||
${PROCESSOR} MATCHES "^MK.*" OR
|
||||
${PROCESSOR} MATCHES "RP2040" OR
|
||||
${PROCESSOR} MATCHES "^GD32.*"
|
||||
)
|
||||
set(${TOOLCHAIN_STR} "arm-none-eabi" PARENT_SCOPE)
|
||||
set(QMK_EXTENSION ".bin" PARENT_SCOPE)
|
||||
include(FindARMToolchain)
|
||||
find_arm_toolchain()
|
||||
elseif(
|
||||
${PROCESSOR} MATCHES "risc-v"
|
||||
)
|
||||
set(${TOOLCHAIN_STR} "riscv32-unknown-elf" PARENT_SCOPE)
|
||||
set(QMK_EXTENSION ".bin" PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR "Could not find toolchain for ${PROCESSOR}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(find_toolchain TOOLCHAIN TOOLCHAIN_ROOT_STR)
|
||||
unset(${TOOLCHAIN_STR} PARENT_SCOPE)
|
||||
if(UNIX)
|
||||
set(OS_SUFFIX "")
|
||||
find_path(TOOLCHAIN_ROOT
|
||||
NAMES
|
||||
${TOOLCHAIN}-gcc${OS_SUFFIX}
|
||||
PATHS
|
||||
"${CMAKE_SOURCE_DIR}/toolchains/avr-gcc/avr-gcc-12.1.0-x64-linux/bin/"
|
||||
"${CMAKE_SOURCE_DIR}/toolchains/gcc-arm-none-eabi-10.3-2021.10/bin/"
|
||||
/usr/bin/
|
||||
/usr/local/bin
|
||||
/bin/
|
||||
$ENV{AVR_ROOT}
|
||||
)
|
||||
elseif(WIN32)
|
||||
set(OS_SUFFIX ".exe")
|
||||
find_path(TOOLCHAIN_ROOT
|
||||
NAMES
|
||||
${TOOLCHAIN}-gcc${OS_SUFFIX}
|
||||
PATHS
|
||||
"${CMAKE_SOURCE_DIR}/toolchains/avr-gcc-12.1.0-x64-windows/bin"
|
||||
"${CMAKE_SOURCE_DIR}/toolchains/gcc-arm-none-eabi-10.3-2021.10/bin/"
|
||||
$ENV{AVR_ROOT}
|
||||
)
|
||||
else()
|
||||
message(FATAL_ERROR "Unsure how to handle this OS")
|
||||
endif(UNIX)
|
||||
set(${TOOLCHAIN_ROOT_STR} ${TOOLCHAIN_ROOT} PARENT_SCOPE)
|
||||
endfunction(find_toolchain)
|
||||
@@ -0,0 +1,22 @@
|
||||
# can be passed a relative path (to CMAKE_SOURCE_DIR) to update/checkout that submodule
|
||||
macro(update_submodule SUBMODULE)
|
||||
find_package(Git QUIET)
|
||||
if(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
||||
option(GIT_SUBMODULE "Check submodules during build" ON)
|
||||
if(GIT_SUBMODULE)
|
||||
message(STATUS "Updating submoudle ${SUBMODULE}")
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} submodule update ${SUBMODULE}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
RESULT_VARIABLE GIT_SUBMOD_RESULT)
|
||||
if(NOT GIT_SUBMOD_RESULT EQUAL "0")
|
||||
message(FATAL_ERROR "git submodule update ${SUBMODULE} failed with ${GIT_SUBMOD_RESULT}, please checkout submodules")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message("Git not found - skipping submodule update")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${CMAKE_SOURCE_DIR}/${SUBMODULE}/.git")
|
||||
message(FATAL_ERROR "The submodule was not downloaded! GIT_SUBMODULE was turned off or failed. Please update submodules and try again.")
|
||||
endif()
|
||||
endmacro()
|
||||
@@ -0,0 +1,25 @@
|
||||
macro(json_get_with_default KEY_STR JSON_STR DEFAULT)
|
||||
# message(STATUS "Getting ${ARGN} for ${KEY_STR}")
|
||||
string(JSON ${KEY_STR} ERROR_VARIABLE JSON_ERROR GET ${JSON_STR} ${ARGN})
|
||||
if(NOT ${JSON_ERROR} STREQUAL "NOTFOUND")
|
||||
set(${KEY_STR} ${DEFAULT})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(json_get KEY_STR JSON_STR)
|
||||
# message(STATUS "Getting ${ARGN} for ${KEY_STR}")
|
||||
string(JSON ${KEY_STR} ERROR_VARIABLE JSON_ERROR GET ${JSON_STR} ${ARGN})
|
||||
if(NOT ${JSON_ERROR} STREQUAL "NOTFOUND")
|
||||
unset(${KEY_STR})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(parent_list ACTION LIST_STR)
|
||||
set(ARGS ${ARGN})
|
||||
string(REPLACE ";" " " ARGS ${ARGS})
|
||||
set(LOCAL_LIST ${${LIST_STR}})
|
||||
list(${ACTION} LOCAL_LIST ${ARGS})
|
||||
# set in current scope too
|
||||
set(${LIST_STR} ${LOCAL_LIST})
|
||||
set(${LIST_STR} ${LOCAL_LIST} PARENT_SCOPE)
|
||||
endmacro()
|
||||
@@ -0,0 +1,199 @@
|
||||
function(validate_json JSON_FILE SCHEMA_NAME JSON_STRING_STR)
|
||||
unset(${JSON_STRING_STR} PARENT_SCOPE)
|
||||
message(VERBOSE "Validating ${JSON_FILE} with '${SCHEMA_NAME}' schema")
|
||||
file(READ ${JSON_FILE} JSON_STRING)
|
||||
file(READ ${CMAKE_SOURCE_DIR}/data/schemas/${SCHEMA_NAME}.jsonschema SCHEMA_STRING)
|
||||
string(JSON SCHEMA_ID GET ${SCHEMA_STRING} $id)
|
||||
|
||||
set(DEFINITIONS "{}")
|
||||
file(READ ${CMAKE_SOURCE_DIR}/data/schemas/definitions.jsonschema DEFINITIONS_STRING)
|
||||
string(JSON DEFINITION_ID GET ${DEFINITIONS_STRING} $id)
|
||||
string(JSON DEFINITIONS SET ${DEFINITIONS} "${DEFINITION_ID}#" ${DEFINITIONS_STRING})
|
||||
|
||||
string(JSON SCHEMA_DEFINITIONS ERROR_VARIABLE JSON_ERROR GET ${SCHEMA_STRING} definitions)
|
||||
if(${JSON_ERROR} STREQUAL "NOTFOUND")
|
||||
string(JSON DEFINITIONS SET ${DEFINITIONS} "#" "{}")
|
||||
string(JSON DEFINITIONS SET ${DEFINITIONS} "#" definitions ${SCHEMA_DEFINITIONS})
|
||||
# string(JSON DEFINITIONS_LENGTH LENGTH ${SCHEMA_DEFINITIONS})
|
||||
# math(EXPR MAX "${DEFINITIONS_LENGTH} - 1")
|
||||
# foreach(IDX RANGE ${MAX})
|
||||
# string(JSON DEFINITION_NAME MEMBER ${SCHEMA_DEFINITIONS} ${IDX})
|
||||
# string(JSON DEFINITION GET ${SCHEMA_DEFINITIONS} ${DEFINITION_NAME})
|
||||
# message(VERBOSE "Loading local definition '${DEFINITION_NAME}'")
|
||||
# string(JSON DEFINITIONS_STRING SET ${DEFINITIONS_STRING} ${DEFINITION_NAME} ${DEFINITION})
|
||||
# endforeach()
|
||||
endif()
|
||||
|
||||
validate_object(${JSON_STRING} ${SCHEMA_STRING} OBJECT_ERROR)
|
||||
if(DEFINED OBJECT_ERROR)
|
||||
message(FATAL_ERROR ${OBJECT_ERROR})
|
||||
else()
|
||||
set(${JSON_STRING_STR} ${JSON_STRING} PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(validate_object JSON_STRING SCHEMA_STRING OBJECT_ERROR_STR)
|
||||
unset(${OBJECT_ERROR_STR} PARENT_SCOPE)
|
||||
set(OBJECT_ERROR)
|
||||
string(JSON PROPERTY_NAME_SCHEMA ERROR_VARIABLE PROPERTY_NAMES_ERROR GET ${SCHEMA_STRING} propertyNames)
|
||||
string(JSON REQUIRED_PROPERTIES ERROR_VARIABLE REQUIRED_PROPERTIES_ERROR GET ${SCHEMA_STRING} required)
|
||||
set(REQUIRED_LIST)
|
||||
if(${REQUIRED_PROPERTIES_ERROR} STREQUAL "NOTFOUND")
|
||||
string(JSON REQUIRED_LENGTH LENGTH ${REQUIRED_PROPERTIES})
|
||||
math(EXPR MAX "${REQUIRED_LENGTH} - 1")
|
||||
foreach(IDX RANGE ${MAX})
|
||||
string(JSON REQUIRED GET ${REQUIRED_PROPERTIES} ${IDX})
|
||||
list(APPEND REQUIRED_LIST ${REQUIRED})
|
||||
endforeach()
|
||||
endif()
|
||||
string(JSON NUM_PROPERTIES LENGTH ${JSON_STRING})
|
||||
math(EXPR MAX "${NUM_PROPERTIES} - 1")
|
||||
foreach(IDX RANGE ${MAX})
|
||||
string(JSON PROPERTY_NAME MEMBER ${JSON_STRING} ${IDX})
|
||||
list(REMOVE_ITEM REQUIRED_LIST ${PROPERTY_NAME})
|
||||
message(VERBOSE "Validating property '${PROPERTY_NAME}'")
|
||||
if(${PROPERTY_NAMES_ERROR} STREQUAL "NOTFOUND")
|
||||
validate_property(${PROPERTY_NAME} ${PROPERTY_NAME_SCHEMA} PROPERTY_NAME_ERROR)
|
||||
if(DEFINED PROPERTY_NAME_ERROR)
|
||||
list(APPEND OBJECT_ERROR "${PROPERTY_NAME_ERROR}")
|
||||
endif()
|
||||
endif()
|
||||
string(JSON PROPERTY GET ${JSON_STRING} ${PROPERTY_NAME})
|
||||
string(JSON SCHEMA_PROPERTIES ERROR_VARIABLE PROPERTIES_ERROR GET ${SCHEMA_STRING} properties ${PROPERTY_NAME})
|
||||
if(${PROPERTIES_ERROR} STREQUAL "NOTFOUND")
|
||||
string(JSON PROPERTY_SCHEMA GET ${SCHEMA_STRING} properties ${PROPERTY_NAME})
|
||||
else()
|
||||
string(JSON PROPERTY_SCHEMA ERROR_VARIABLE ADDITIONAL_PROPERTIES_ERROR GET ${SCHEMA_STRING} additionalProperties)
|
||||
if(NOT ${ADDITIONAL_PROPERTIES_ERROR} STREQUAL "NOTFOUND" OR "${PROPERTY_SCHEMA}" STREQUAL "OFF")
|
||||
list(APPEND OBJECT_ERROR "Additional properties like '${PROPERTY_NAME}' not permitted in '${JSON_STRING}'")
|
||||
endif()
|
||||
endif()
|
||||
validate_property(${PROPERTY} ${PROPERTY_SCHEMA} PROPERTY_ERROR)
|
||||
if(DEFINED PROPERTY_ERROR)
|
||||
list(APPEND OBJECT_ERROR "${PROPERTY_ERROR}")
|
||||
endif()
|
||||
endforeach()
|
||||
list(LENGTH REQUIRED_LIST REQUIRED_REMAINING_LENGTH)
|
||||
if(${REQUIRED_REMAINING_LENGTH} GREATER 0)
|
||||
list(APPEND OBJECT_ERROR "Required properties not found: ${REQUIRED_LIST}")
|
||||
endif()
|
||||
set(${OBJECT_ERROR_STR} ${OBJECT_ERROR} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(validate_property PROPERTY PROPERTY_SCHEMA PROPERTY_ERROR_STR)
|
||||
unset(${PROPERTY_ERROR_STR} PARENT_SCOPE)
|
||||
set(PROPERTY_ERROR)
|
||||
string(JSON PROPERTY_REF ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} $ref)
|
||||
if(${JSON_ERROR} STREQUAL "NOTFOUND")
|
||||
string(REPLACE "/" ";" REF_COMPONENTS "${PROPERTY_REF}")
|
||||
string(JSON PROPERTY_SCHEMA GET ${DEFINITIONS} ${REF_COMPONENTS})
|
||||
endif()
|
||||
string(JSON PROPERTY_TYPE ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} type)
|
||||
if(${JSON_ERROR} STREQUAL "NOTFOUND")
|
||||
message(VERBOSE "Validating property type '${PROPERTY_TYPE}'")
|
||||
if(${PROPERTY_TYPE} STREQUAL "object")
|
||||
validate_object(${PROPERTY} ${PROPERTY_SCHEMA} OBJECT_ERROR)
|
||||
if(DEFINED OBJECT_ERROR)
|
||||
list(APPEND PROPERTY_ERROR ${OBJECT_ERROR})
|
||||
endif()
|
||||
elseif(${PROPERTY_TYPE} STREQUAL "array")
|
||||
string(JSON ARRAY_LENGTH LENGTH ${PROPERTY})
|
||||
string(JSON MAX_ITEMS ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} maxItems)
|
||||
if(${JSON_ERROR} STREQUAL "NOTFOUND" AND ${ARRAY_LENGTH} GREATER ${MAX_ITEMS})
|
||||
list(APPEND PROPERTY_ERROR "Number of items in '${PROPERTY}' exceeds maximum ${MAX_ITEMS}")
|
||||
endif()
|
||||
string(JSON MIN_ITEMS ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} minItems)
|
||||
if(${JSON_ERROR} STREQUAL "NOTFOUND" AND ${ARRAY_LENGTH} LESS ${MIN_ITEMS})
|
||||
list(APPEND PROPERTY_ERROR "Number of items in '${PROPERTY}' is less than ${MIN_ITEMS}")
|
||||
endif()
|
||||
string(JSON ITEM_SCHEMA ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} items)
|
||||
if(${JSON_ERROR} STREQUAL "NOTFOUND")
|
||||
math(EXPR MAX "${ARRAY_LENGTH} - 1")
|
||||
foreach(IDX RANGE ${MAX})
|
||||
string(JSON ITEM GET ${PROPERTY} ${IDX})
|
||||
validate_property(${ITEM} ${ITEM_SCHEMA} ITEM_ERROR)
|
||||
if(DEFINED ITEM_ERROR)
|
||||
list(APPEND PROPERTY_ERROR ${ITEM_ERROR})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
elseif(${PROPERTY_TYPE} STREQUAL "null")
|
||||
if(NOT "${PROPERTY}" STREQUAL "null")
|
||||
list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' is not null'")
|
||||
endif()
|
||||
elseif(${PROPERTY_TYPE} STREQUAL "boolean")
|
||||
if(NOT "${PROPERTY}" STREQUAL "OFF" AND NOT "${PROPERTY}" STREQUAL "ON")
|
||||
list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' is not a boolean'")
|
||||
endif()
|
||||
elseif(${PROPERTY_TYPE} STREQUAL "number")
|
||||
if(NOT "${PROPERTY}" MATCHES "-?[0-9]+\\.?[0-9]*")
|
||||
list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' is not a number'")
|
||||
endif()
|
||||
elseif(${PROPERTY_TYPE} STREQUAL "integer")
|
||||
if(NOT "${PROPERTY}" MATCHES "-?[0-9]+")
|
||||
list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' is not an integer'")
|
||||
endif()
|
||||
string(JSON MIN ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} minimum)
|
||||
if(${JSON_ERROR} STREQUAL "NOTFOUND" AND ${PROPERTY} LESS ${MIN})
|
||||
list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' is less than the minimum of ${MIN}")
|
||||
endif()
|
||||
string(JSON MAX ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} maximum)
|
||||
if(${JSON_ERROR} STREQUAL "NOTFOUND" AND ${PROPERTY} GREATER ${MAX})
|
||||
list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' is greater than the maximum of ${MAX}")
|
||||
endif()
|
||||
elseif(${PROPERTY_TYPE} STREQUAL "string")
|
||||
# cmake regex doesn't support {}, so other options might be needed here
|
||||
string(JSON PATTERN ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} pattern)
|
||||
if(${JSON_ERROR} STREQUAL "NOTFOUND" AND NOT "${PROPERTY}" MATCHES "${PATTERN}")
|
||||
list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' does not match '${PATTERN}'")
|
||||
endif()
|
||||
string(LENGTH ${PROPERTY} STRING_LENGTH)
|
||||
string(JSON MIN_LENGTH ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} minLength)
|
||||
if(${JSON_ERROR} STREQUAL "NOTFOUND" AND ${STRING_LENGTH} LESS ${MIN_LENGTH})
|
||||
list(APPEND PROPERTY_ERROR "Length of property '${PROPERTY}' is less than the minimum of ${MIN_LENGTH}")
|
||||
endif()
|
||||
string(JSON MAX_LENGTH ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} maxLength)
|
||||
if(${JSON_ERROR} STREQUAL "NOTFOUND" AND ${STRING_LENGTH} GREATER ${MAX_LENGTH})
|
||||
list(APPEND PROPERTY_ERROR "Length of property '${PROPERTY}' is greater than the maximum of ${MAX_LENGTH}")
|
||||
endif()
|
||||
string(JSON ENUM_LIST ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} enum)
|
||||
if(${JSON_ERROR} STREQUAL "NOTFOUND")
|
||||
set(FOUND_IN_ENUM_LIST FALSE)
|
||||
string(JSON ENUM_LENGTH LENGTH ${ENUM_LIST})
|
||||
math(EXPR MAX "${ENUM_LENGTH} - 1")
|
||||
foreach(IDX RANGE ${MAX})
|
||||
string(JSON ENUM GET ${PROPERTY_SCHEMA} enum ${IDX})
|
||||
if(${ENUM} STREQUAL ${PROPERTY})
|
||||
set(FOUND_IN_ENUM_LIST TRUE)
|
||||
endif()
|
||||
endforeach()
|
||||
if(NOT ${FOUND_IN_ENUM_LIST})
|
||||
list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' is not defined in the schema's enum: ${ENUM_LIST}")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message(VERBOSE "Unknown type '${PROPERTY_TYPE}'")
|
||||
endif()
|
||||
else()
|
||||
string(JSON PROPERTY_ONEOF ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} oneOf)
|
||||
if(${JSON_ERROR} STREQUAL "NOTFOUND")
|
||||
set(TYPE_SUCCESS FALSE)
|
||||
string(JSON NUM_ONEOF LENGTH ${PROPERTY_ONEOF})
|
||||
math(EXPR MAX "${NUM_ONEOF} - 1")
|
||||
set(ONEOF_ERRORS)
|
||||
foreach(IDX RANGE ${MAX})
|
||||
string(JSON PROPERTY_SCHEMA GET ${PROPERTY_ONEOF} ${IDX})
|
||||
validate_property(${PROPERTY} ${PROPERTY_SCHEMA} ONEOF_ERROR)
|
||||
if(NOT DEFINED ONEOF_ERROR)
|
||||
set(TYPE_SUCCESS TRUE)
|
||||
else()
|
||||
list(APPEND ONEOF_ERRORS "${ONEOF_ERROR}\n")
|
||||
endif()
|
||||
endforeach()
|
||||
if(NOT TYPE_SUCCESS)
|
||||
list(APPEND PROPERTY_ERROR "Could not validate oneOf type '${PROPERTY}' :\n${ONEOF_ERRORS}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
set(${PROPERTY_ERROR_STR} ${PROPERTY_ERROR} PARENT_SCOPE)
|
||||
endfunction()
|
||||
@@ -0,0 +1,2 @@
|
||||
target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/ADCv3/hal_adc_lld.c)
|
||||
target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/ADCv3)
|
||||
@@ -0,0 +1,2 @@
|
||||
target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/CANv1/hal_can_lld.c)
|
||||
target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/CANv1)
|
||||
@@ -0,0 +1,2 @@
|
||||
target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/DACv1/hal_dac_lld.c)
|
||||
target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/DACv1)
|
||||
@@ -0,0 +1,2 @@
|
||||
target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/DMAv1/stm32_dma.c)
|
||||
target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/DMAv1)
|
||||
@@ -0,0 +1,2 @@
|
||||
target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/EXTIv1/stm32_exti.c)
|
||||
target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/EXTIv1)
|
||||
@@ -0,0 +1,2 @@
|
||||
target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/GPIOv2/hal_pal_lld.c)
|
||||
target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/GPIOv2)
|
||||
@@ -0,0 +1,7 @@
|
||||
if(${USE_HAL_I2C_FALLBACK})
|
||||
target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/I2C/hal_i2c_lld.c)
|
||||
target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/I2C)
|
||||
else()
|
||||
target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/I2Cv2/hal_i2c_lld.c)
|
||||
target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/I2Cv2)
|
||||
endif()
|
||||
@@ -0,0 +1,2 @@
|
||||
target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/RTCv2/hal_rtc_lld.c)
|
||||
target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/RTCv2)
|
||||
@@ -0,0 +1,5 @@
|
||||
target_sources(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/SPIv2/hal_i2s_lld.c
|
||||
${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/SPIv2/hal_spi_v2_lld.c
|
||||
)
|
||||
target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/SPIv2)
|
||||
@@ -0,0 +1,2 @@
|
||||
target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/SYSTICKv1/hal_st_lld.c)
|
||||
target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/SYSTICKv1)
|
||||
@@ -0,0 +1,6 @@
|
||||
target_sources(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/TIMv1/hal_gpt_lld.c
|
||||
${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/TIMv1/hal_icu_lld.c
|
||||
${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/TIMv1/hal_pwm_lld.c
|
||||
)
|
||||
target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/TIMv1)
|
||||
@@ -0,0 +1,9 @@
|
||||
target_sources(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/USARTv2/hal_serial_lld.c
|
||||
${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/USARTv2/hal_sio_lld.c
|
||||
${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/USARTv2/hal_uart_lld.c
|
||||
)
|
||||
target_include_directories(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/USART
|
||||
${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/USARTv2
|
||||
)
|
||||
@@ -0,0 +1,6 @@
|
||||
target_sources(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/USBv1/hal_usb_lld.c
|
||||
)
|
||||
target_include_directories(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/USBv1
|
||||
)
|
||||
@@ -0,0 +1,6 @@
|
||||
target_sources(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/xWDGv1/hal_wdg_lld.c
|
||||
)
|
||||
target_include_directories(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/xWDGv1
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
# os/common/ports/ARMv7/compilers/GCC/mk/port.mk
|
||||
target_sources(qmk PUBLIC
|
||||
${CHIBIOS}/os/common/ports/ARMv7-M/chcore.c
|
||||
${CHIBIOS}/os/common/ports/ARMv7-M/compilers/GCC/chcoreasm.S
|
||||
)
|
||||
target_include_directories(qmk PUBLIC
|
||||
${CHIBIOS}/os/common/portability/GCC
|
||||
${CHIBIOS}/os/common/ports/ARM-common
|
||||
${CHIBIOS}/os/common/ports/ARMv7-M
|
||||
)
|
||||
@@ -0,0 +1,25 @@
|
||||
# os/hal/ports/STM32/STM32F3xx/platform.mk
|
||||
target_sources(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c
|
||||
${CHIBIOS}/os/hal/ports/STM32/STM32F3xx/stm32_isr.c
|
||||
${CHIBIOS}/os/hal/ports/STM32/STM32F3xx/hal_lld.c
|
||||
${CHIBIOS}/os/hal/ports/STM32/STM32F3xx/hal_efl_lld.c
|
||||
)
|
||||
target_include_directories(qmk PUBLIC
|
||||
${CHIBIOS}/os/hal/ports/common/ARMCMx
|
||||
${CHIBIOS}/os/hal/ports/STM32/STM32F3xx
|
||||
)
|
||||
include(chibios/LLD/ADCv3)
|
||||
include(chibios/LLD/CANv1)
|
||||
include(chibios/LLD/DACv1)
|
||||
include(chibios/LLD/DMAv1)
|
||||
include(chibios/LLD/EXTIv1)
|
||||
include(chibios/LLD/GPIOv2)
|
||||
include(chibios/LLD/I2Cv2)
|
||||
include(chibios/LLD/RTCv2)
|
||||
include(chibios/LLD/SPIv2)
|
||||
include(chibios/LLD/SYSTICKv1)
|
||||
include(chibios/LLD/TIMv1)
|
||||
include(chibios/LLD/USARTv2)
|
||||
include(chibios/LLD/USBv1)
|
||||
include(chibios/LLD/xWDGv1)
|
||||
@@ -0,0 +1,32 @@
|
||||
option(BACKLIGHT_ENABLE "" TRUE)
|
||||
set(BACKLIGHT_DRIVER "pwm" CACHE STRING "Backlight driver")
|
||||
set_property(CACHE BACKLIGHT_DRIVER PROPERTY STRINGS pwm timer software custom)
|
||||
|
||||
string(JSON BACKLIGHT_PIN ERROR_VARIABLE NO_BACKLIGHT_PIN GET ${QMK_KEYBOARD_INFO_JSON_STRING} backlight pin)
|
||||
if(${BACKLIGHT_ENABLE} AND NOT ${BACKLIGHT_PIN} STREQUAL "backlight-NOTFOUND")
|
||||
target_sources(qmk PUBLIC
|
||||
quantum/backlight/backlight.c
|
||||
quantum/process_keycode/process_backlight.c
|
||||
)
|
||||
target_compile_definitions(qmk PUBLIC
|
||||
BACKLIGHT_ENABLE
|
||||
BACKLIGHT_PIN=${BACKLIGHT_PIN}
|
||||
)
|
||||
if(${BACKLIGHT_DRIVER} STREQUAL "custom")
|
||||
target_compile_definitions(qmk PUBLIC BACKLIGHT_CUSTOM_DRIVER)
|
||||
else()
|
||||
target_sources(qmk PUBLIC quantum/backlight/backlight_driver_common.c)
|
||||
if(${BACKLIGHT_DRIVER} STREQUAL "pwm")
|
||||
target_sources(qmk PUBLIC quantum/backlight/backlight_${QMK_PLATFORM}.c)
|
||||
else()
|
||||
target_sources(qmk PUBLIC quantum/backlight/backlight_${BACKLIGHT_DRIVER}.c)
|
||||
endif()
|
||||
endif()
|
||||
target_include_directories(qmk PUBLIC quantum/backlight)
|
||||
target_include_directories(qmk PUBLIC drivers/oled)
|
||||
# target_link_libraries(backlight qmk)
|
||||
# target_include_directories(backlight PUBLIC quantum/backlight)
|
||||
# target_include_directories(quantum PUBLIC quantum/backlight)
|
||||
# target_link_libraries(backlight ${QMK_TARGET})
|
||||
# target_link_libraries(backlight quantum)
|
||||
endif()
|
||||
@@ -0,0 +1,70 @@
|
||||
set(EEPROM_DRIVER "vendor" CACHE STRING "EEPROM driver")
|
||||
set_property(CACHE EEPROM_DRIVER PROPERTY STRINGS vendor custom transient i2c spi wear_leveling legacy_stm32_flash)
|
||||
set(WEAR_LEVELING_DRIVER "none" CACHE STRING "EEPROM wear-leveling driver")
|
||||
set_property(CACHE WEAR_LEVELING_DRIVER PROPERTY STRINGS custom embedded_flash spi_flash rp2040_flash legacy)
|
||||
|
||||
target_compile_definitions(qmk PUBLIC
|
||||
EEPROM_ENABLE
|
||||
)
|
||||
target_include_directories(qmk PUBLIC
|
||||
platforms/${QMK_PLATFORM}/drivers/eeprom
|
||||
drivers/eeprom
|
||||
platforms/common
|
||||
)
|
||||
|
||||
if(${EEPROM_DRIVER} STREQUAL "wear_leveling")
|
||||
target_compile_definitions(qmk PUBLIC
|
||||
EEPROM_DRIVER
|
||||
EEPROM_WEAR_LEVELING
|
||||
)
|
||||
target_sources(qmk PUBLIC
|
||||
drivers/eeprom/eeprom_driver.c
|
||||
drivers/eeprom/eeprom_wear_leveling.c
|
||||
)
|
||||
elseif(${EEPROM_DRIVER} STREQUAL "vendor")
|
||||
target_compile_definitions(qmk PUBLIC
|
||||
EEPROM_VENDOR
|
||||
)
|
||||
if(${QMK_PLATFORM} STREQUAL "chibios")
|
||||
if(${QMK_MCU} MATCHES "STM32F[1-9].*" OR ${QMK_MCU} MATCHES "WB32.*" OR ${QMK_MCU} MATCHES "GD32.*")
|
||||
target_compile_definitions(qmk PUBLIC
|
||||
EEPROM_DRIVER
|
||||
EEPROM_WEAR_LEVELING
|
||||
)
|
||||
target_sources(qmk PUBLIC
|
||||
drivers/eeprom/eeprom_driver.c
|
||||
drivers/eeprom/eeprom_wear_leveling.c
|
||||
)
|
||||
set(WEAR_LEVELING_DRIVER "embedded_flash")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT ${WEAR_LEVELING_DRIVER} STREQUAL "none")
|
||||
set(FNV_ENABLE TRUE)
|
||||
target_compile_definitions(qmk PUBLIC
|
||||
WEAR_LEVELING_ENABLE
|
||||
)
|
||||
target_include_directories(qmk PUBLIC
|
||||
platforms/${QMK_PLATFORM}/drivers/wear_leveling
|
||||
drivers/wear_leveling
|
||||
quantum/wear_leveling
|
||||
)
|
||||
target_sources(qmk PUBLIC quantum/wear_leveling/wear_leveling.c)
|
||||
|
||||
if(${WEAR_LEVELING_DRIVER} STREQUAL "embedded_flash")
|
||||
target_compile_definitions(qmk PUBLIC
|
||||
HAL_USE_EFL
|
||||
WEAR_LEVELING_EMBEDDED_FLASH
|
||||
)
|
||||
target_sources(qmk PUBLIC
|
||||
platforms/${QMK_PLATFORM}/drivers/wear_leveling/wear_leveling_efl.c
|
||||
)
|
||||
# target_compile_options(qmk PUBLIC
|
||||
# -include ${CMAKE_SOURCE_DIR}/platforms/${QMK_PLATFORM}/drivers/wear_leveling/wear_leveling_efl_config.h
|
||||
# )
|
||||
target_precompile_headers(qmk PUBLIC
|
||||
${CMAKE_SOURCE_DIR}/platforms/${QMK_PLATFORM}/drivers/wear_leveling/wear_leveling_efl_config.h
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,9 @@
|
||||
if(${FNV_ENABLE})
|
||||
target_compile_definitions(qmk PUBLIC FNV_ENABLE)
|
||||
target_include_directories(qmk PUBLIC lib/fnv)
|
||||
target_sources(qmk PUBLIC
|
||||
lib/fnv/qmk_fnv_type_validation.c
|
||||
lib/fnv/hash_32a.c
|
||||
lib/fnv/hash_64a.c
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,9 @@
|
||||
message(STATUS "Custom Matrix: ${CUSTOM_MATRIX}")
|
||||
set(CUSTOM_MATRIX "no" CACHE STRING "Custom matrix-scanning")
|
||||
set_property(CACHE CUSTOM_MATRIX PROPERTY STRINGS yes lite no)
|
||||
if(NOT ${CUSTOM_MATRIX} STREQUAL yes)
|
||||
target_sources(qmk PUBLIC quantum/matrix_common.c)
|
||||
if(NOT ${CUSTOM_MATRIX} STREQUAL lite)
|
||||
target_sources(qmk PUBLIC quantum/matrix.c)
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,10 @@
|
||||
option(OLED_ENABLE "" OFF)
|
||||
if(${OLED_ENABLE})
|
||||
target_sources(qmk PUBLIC
|
||||
drivers/oled/ssd1306_sh1106.c
|
||||
platforms/${QMK_PLATFORM}/drivers/i2c_master.c)
|
||||
target_compile_definitions(qmk PUBLIC OLED_ENABLE)
|
||||
target_include_directories(qmk PUBLIC drivers)
|
||||
target_include_directories(qmk PUBLIC drivers/oled)
|
||||
target_include_directories(qmk PUBLIC platforms/${QMK_PLATFORM}/drivers)
|
||||
endif()
|
||||
@@ -0,0 +1,144 @@
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS on)
|
||||
|
||||
include(ResolveToolchain)
|
||||
|
||||
set(QMK_TOOLCHAIN "arm-none-eabi")
|
||||
set(QMK_PLATFORM "chibios")
|
||||
set(QMK_PROTOCOL "chibios")
|
||||
set(QMK_EXTENSION ".bin")
|
||||
|
||||
if(UNIX)
|
||||
set(OS_SUFFIX "")
|
||||
elseif(WIN32)
|
||||
set(OS_SUFFIX ".exe")
|
||||
endif()
|
||||
|
||||
find_toolchain(arm-none-eabi TOOLCHAIN_ROOT)
|
||||
|
||||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
set(CMAKE_CROSS_COMPILING 1)
|
||||
|
||||
set(CMAKE_C_COMPILER "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-gcc${OS_SUFFIX}" CACHE PATH "gcc" FORCE)
|
||||
set(CMAKE_CXX_COMPILER "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-g++${OS_SUFFIX}" CACHE PATH "g++" FORCE)
|
||||
set(CMAKE_AR "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-ar${OS_SUFFIX}" CACHE PATH "ar" FORCE)
|
||||
set(CMAKE_AS "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-as${OS_SUFFIX}" CACHE PATH "as" FORCE)
|
||||
set(CMAKE_LINKER "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-ld${OS_SUFFIX}" CACHE PATH "linker" FORCE)
|
||||
set(CMAKE_NM "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-nm${OS_SUFFIX}" CACHE PATH "nm" FORCE)
|
||||
set(CMAKE_OBJCOPY "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-objcopy${OS_SUFFIX}" CACHE PATH "objcopy" FORCE)
|
||||
set(CMAKE_OBJDUMP "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-objdump${OS_SUFFIX}" CACHE PATH "objdump" FORCE)
|
||||
set(CMAKE_STRIP "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-strip${OS_SUFFIX}" CACHE PATH "strip" FORCE)
|
||||
set(CMAKE_RANLIB "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-ranlib${OS_SUFFIX}" CACHE PATH "ranlib" FORCE)
|
||||
set(CMAKE_SIZE "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-size${OS_SUFFIX}" CACHE PATH "size" FORCE)
|
||||
|
||||
find_program(CMAKE_MAKE_PROGRAM NAME make
|
||||
PATHS
|
||||
"${CMAKE_SOURCE_DIR}/toolchains/avr-gcc-12.1.0-x64-windows/bin/"
|
||||
"${CMAKE_SOURCE_DIR}/toolchains/avr-gcc-12.1.0-x64-linux/bin/"
|
||||
/usr/bin/
|
||||
/usr/local/bin
|
||||
/bin/
|
||||
)
|
||||
|
||||
add_compile_options(
|
||||
$<$<COMPILE_LANGUAGE:C>:-std=gnu11>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-std=gnu++14>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>
|
||||
# -flto
|
||||
-Os
|
||||
-Wall
|
||||
-Wstrict-prototypes
|
||||
# -fcommon
|
||||
# -g
|
||||
|
||||
-fomit-frame-pointer
|
||||
-ffunction-sections
|
||||
-fdata-sections
|
||||
-fno-common
|
||||
-fshort-wchar
|
||||
-fno-builtin-printf
|
||||
# -funsigned-char
|
||||
# -funsigned-bitfields
|
||||
# -ffunction-sections
|
||||
# -fdata-sections
|
||||
# -fpack-struct
|
||||
# -fshort-enums
|
||||
# -fno-builtin-printf
|
||||
# $<$<COMPILE_LANGUAGE:C>:-fno-inline-small-functions>
|
||||
# $<$<COMPILE_LANGUAGE:C>:-fno-strict-aliasing>
|
||||
# $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
|
||||
)
|
||||
|
||||
add_link_options(
|
||||
-Wl,--gc-sections
|
||||
-nostartfiles
|
||||
-Wl,--no-wchar-size-warning
|
||||
--specs=nano.specs
|
||||
-lm
|
||||
)
|
||||
|
||||
macro(add_qmk_executable target_name)
|
||||
|
||||
set(elf_file ${target_name}.elf)
|
||||
set(map_file ${target_name}.map)
|
||||
set(bin_file ${target_name}.bin)
|
||||
set(lst_file ${target_name}.lst)
|
||||
|
||||
add_link_options(
|
||||
-Wl,-Map=${map_file},--cref
|
||||
)
|
||||
|
||||
# create elf file
|
||||
add_executable(qmk ${ARGN})
|
||||
# add_executable(${elf_file} ${ARGN})
|
||||
# target_link_libraries(${elf_file} qmk)
|
||||
|
||||
set_target_properties(qmk
|
||||
PROPERTIES
|
||||
OUTPUT_NAME ${elf_file}
|
||||
)
|
||||
|
||||
# generate the lst file
|
||||
add_custom_command(
|
||||
OUTPUT ${lst_file}
|
||||
COMMAND ${CMAKE_OBJDUMP} -h -S ${elf_file} > ${lst_file}
|
||||
DEPENDS qmk
|
||||
)
|
||||
|
||||
# add_custom_command(
|
||||
# OUTPUT "print-size-${elf_file}"
|
||||
|
||||
# COMMAND
|
||||
# ${CMAKE_SIZE} ${elf_file}
|
||||
|
||||
# DEPENDS ${elf_file}
|
||||
# )
|
||||
|
||||
# add_custom_command(
|
||||
# OUTPUT "print-size-${bin_file}"
|
||||
|
||||
# COMMAND
|
||||
# ${CMAKE_SIZE} ${bin_file} sizeafter
|
||||
|
||||
# DEPENDS ${bin_file}
|
||||
# )
|
||||
|
||||
add_custom_command(
|
||||
TARGET qmk
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary ${elf_file} ${CMAKE_SOURCE_DIR}/build/${bin_file}
|
||||
# COMMAND ${CMAKE_COMMAND} -E copy ${elf_file} ${CMAKE_SOURCE_DIR}/build/${elf_file}
|
||||
# COMMAND ${CMAKE_COMMAND} -E copy ${lst_file} ${CMAKE_SOURCE_DIR}/build/${lst_file}
|
||||
# COMMAND ${CMAKE_COMMAND} -E copy ${map_file} ${CMAKE_SOURCE_DIR}/build/${map_file}
|
||||
)
|
||||
|
||||
# build the intel hex file for the device
|
||||
add_custom_target(${target_name} ALL
|
||||
DEPENDS ${elf_file} ${lst_file}
|
||||
)
|
||||
|
||||
set_target_properties(${target_name}
|
||||
PROPERTIES
|
||||
OUTPUT_NAME ${bin_file}
|
||||
)
|
||||
endmacro(add_qmk_executable)
|
||||
@@ -0,0 +1,182 @@
|
||||
#
|
||||
# AVR GCC Toolchain file
|
||||
#
|
||||
# @author Natesh Narain
|
||||
# @since Feb 06 2016
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS on)
|
||||
|
||||
include(ResolveToolchain)
|
||||
|
||||
set(QMK_TOOLCHAIN "avr")
|
||||
set(QMK_PLATFORM "avr")
|
||||
set(QMK_PROTOCOL "lufa")
|
||||
set(QMK_EXTENSION ".hex")
|
||||
|
||||
if(UNIX)
|
||||
set(OS_SUFFIX "")
|
||||
elseif(WIN32)
|
||||
set(OS_SUFFIX ".exe")
|
||||
endif()
|
||||
|
||||
find_toolchain(avr TOOLCHAIN_ROOT)
|
||||
|
||||
# setup the AVR compiler variables
|
||||
|
||||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
set(CMAKE_SYSTEM_PROCESSOR avr)
|
||||
set(CMAKE_CROSS_COMPILING 1)
|
||||
|
||||
set(CMAKE_C_COMPILER "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-gcc${OS_SUFFIX}" CACHE PATH "gcc" FORCE)
|
||||
set(CMAKE_CXX_COMPILER "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-g++${OS_SUFFIX}" CACHE PATH "g++" FORCE)
|
||||
set(CMAKE_AR "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-ar${OS_SUFFIX}" CACHE PATH "ar" FORCE)
|
||||
set(CMAKE_AS "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-as${OS_SUFFIX}" CACHE PATH "as" FORCE)
|
||||
set(CMAKE_LINKER "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-ld${OS_SUFFIX}" CACHE PATH "linker" FORCE)
|
||||
set(CMAKE_NM "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-nm${OS_SUFFIX}" CACHE PATH "nm" FORCE)
|
||||
set(CMAKE_OBJCOPY "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-objcopy${OS_SUFFIX}" CACHE PATH "objcopy" FORCE)
|
||||
set(CMAKE_OBJDUMP "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-objdump${OS_SUFFIX}" CACHE PATH "objdump" FORCE)
|
||||
set(CMAKE_STRIP "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-strip${OS_SUFFIX}" CACHE PATH "strip" FORCE)
|
||||
set(CMAKE_RANLIB "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-ranlib${OS_SUFFIX}" CACHE PATH "ranlib" FORCE)
|
||||
set(AVR_SIZE "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-size${OS_SUFFIX}" CACHE PATH "size" FORCE)
|
||||
|
||||
# set(CMAKE_EXE_LINKER_FLAGS "-L /usr/lib/gcc/avr/4.8.2")
|
||||
|
||||
# avr uploader config
|
||||
find_program(AVR_UPLOAD
|
||||
NAME
|
||||
avrdude
|
||||
PATHS
|
||||
/usr/bin/
|
||||
$ENV{AVR_ROOT}
|
||||
)
|
||||
|
||||
find_program(CMAKE_MAKE_PROGRAM NAME make
|
||||
PATHS
|
||||
"${CMAKE_SOURCE_DIR}/toolchains/avr-gcc-12.1.0-x64-windows/bin/"
|
||||
"${CMAKE_SOURCE_DIR}/toolchains/avr-gcc-12.1.0-x64-linux/bin/"
|
||||
/usr/bin/
|
||||
/usr/local/bin
|
||||
/bin/
|
||||
)
|
||||
|
||||
# setup the avr exectable macro
|
||||
|
||||
# set(AVR_LINKER_LIBS "-lc -lm -lgcc -Wl,-lprintf_flt -Wl,-u,vfprintf")
|
||||
|
||||
add_compile_options(
|
||||
$<$<COMPILE_LANGUAGE:C>:-std=gnu11>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-std=gnu++14>
|
||||
-flto
|
||||
# -mrelax
|
||||
-Os
|
||||
-Wall
|
||||
-Wstrict-prototypes
|
||||
-fcommon
|
||||
# -g
|
||||
$<$<BOOL:${WIN32}>:--param=min-pagesize=0>
|
||||
-funsigned-char
|
||||
-funsigned-bitfields
|
||||
-ffunction-sections
|
||||
-fdata-sections
|
||||
-fpack-struct
|
||||
-fshort-enums
|
||||
-mcall-prologues
|
||||
-fno-builtin-printf
|
||||
$<$<COMPILE_LANGUAGE:C>:-fno-inline-small-functions>
|
||||
$<$<COMPILE_LANGUAGE:C>:-fno-strict-aliasing>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
|
||||
)
|
||||
|
||||
add_compile_definitions(
|
||||
F_CPU=16000000
|
||||
F_USB=16000000UL
|
||||
__AVR_ATmega32U4__
|
||||
LTO_ENABLE
|
||||
)
|
||||
|
||||
add_link_options(
|
||||
-Wl,--gc-sections
|
||||
)
|
||||
|
||||
macro(add_qmk_executable target_name)
|
||||
|
||||
set(elf_file ${target_name}.elf)
|
||||
set(map_file ${target_name}.map)
|
||||
set(hex_file ${target_name}.hex)
|
||||
set(lst_file ${target_name}.lst)
|
||||
|
||||
add_compile_options(
|
||||
-mmcu=${QMK_MCU}
|
||||
)
|
||||
|
||||
add_link_options(
|
||||
-mmcu=${QMK_MCU}
|
||||
-Wl,-Map=${map_file}
|
||||
)
|
||||
|
||||
# create elf file
|
||||
# add_executable(${elf_file} ${ARGN})
|
||||
# target_link_libraries(${elf_file} qmk)
|
||||
|
||||
add_executable(qmk ${ARGN})
|
||||
set_target_properties(qmk
|
||||
PROPERTIES
|
||||
OUTPUT_NAME ${elf_file}
|
||||
)
|
||||
|
||||
|
||||
# set_target_properties(${elf_file}
|
||||
# PROPERTIES
|
||||
# COMPILE_FLAGS "-mmcu=${QMK_MCU} ${COMPILE_OPTIONS}"
|
||||
# LINK_FLAGS "-mmcu=${QMK_MCU} ${LINK_OPTIONS}"
|
||||
# )
|
||||
|
||||
# add_custom_target(compileOptions
|
||||
# COMMAND cmake -P ${CMAKE_SOURCE_DIR}/cmake/WriteCompileOptions.cmake
|
||||
# COMMENT "Writing compile_flags.txt"
|
||||
# )
|
||||
|
||||
# generate the lst file
|
||||
add_custom_command(
|
||||
OUTPUT ${lst_file}
|
||||
COMMAND ${CMAKE_OBJDUMP} -h -S ${elf_file} > ${lst_file}
|
||||
DEPENDS ${elf_file}
|
||||
)
|
||||
|
||||
# create hex file
|
||||
add_custom_command(
|
||||
OUTPUT ${hex_file}
|
||||
# COMMAND ${CMAKE_OBJCOPY} -j .text -j .data -O ihex ${elf_file} ${hex_file}
|
||||
COMMAND ${CMAKE_OBJCOPY} -O ihex -R .eeprom -R .fuse -R .lock -R .signature ${elf_file} ${hex_file}
|
||||
DEPENDS ${elf_file}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "print-size-${elf_file}"
|
||||
COMMAND ${AVR_SIZE} ${elf_file}
|
||||
DEPENDS ${elf_file}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "print-size-${hex_file}"
|
||||
COMMAND ${AVR_SIZE} ${hex_file}
|
||||
DEPENDS ${hex_file}
|
||||
)
|
||||
|
||||
add_custom_target(copy_hex
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${hex_file} ${CMAKE_SOURCE_DIR}/build/${hex_file}
|
||||
DEPENDS ${hex_file}
|
||||
)
|
||||
|
||||
# build the intel hex file for the device
|
||||
add_custom_target(${target_name} ALL
|
||||
DEPENDS ${hex_file} ${lst_file} "print-size-${elf_file}" "print-size-${hex_file}" copy_hex
|
||||
)
|
||||
|
||||
set_target_properties(${target_name}
|
||||
PROPERTIES
|
||||
OUTPUT_NAME ${hex_file}
|
||||
)
|
||||
|
||||
|
||||
endmacro(add_qmk_executable)
|
||||
@@ -0,0 +1,16 @@
|
||||
if(${USE_PICOLIBC})
|
||||
add_compile_options(
|
||||
--specs=picolibc.specs
|
||||
)
|
||||
add_compile_definitions(USE_PICOLIBC)
|
||||
add_link_options(
|
||||
-Wl,--defsym=__heap_start=__heap_base__,--defsym=__heap_end=__heap_end__
|
||||
)
|
||||
endif()
|
||||
|
||||
add_compile_options(
|
||||
-march=${MCU_ARCH}
|
||||
-mabi=${MCU_ABI}
|
||||
-mcmodel=${MCU_CMODEL}
|
||||
-mstrict-align
|
||||
)
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"keycodes": {
|
||||
"0x7C79": {
|
||||
"group": "quantum",
|
||||
"key": "QK_REPEAT_KEY",
|
||||
"aliases": [
|
||||
"QK_REP"
|
||||
]
|
||||
},
|
||||
"0x7C7A": {
|
||||
"group": "quantum",
|
||||
"key": "QK_ALT_REPEAT_KEY",
|
||||
"aliases": [
|
||||
"QK_AREP"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"olkb/planck/rev3": "@jackhumbert/test_keyboard",
|
||||
"olkb/planck/rev6": "planck/rev6"
|
||||
}
|
||||
@@ -33,7 +33,7 @@
|
||||
"blok": {
|
||||
"processor": "RP2040",
|
||||
"bootloader": "rp2040",
|
||||
"board": "QMK_BLOK"
|
||||
"board": "QMK_PM2040"
|
||||
},
|
||||
"michi": {
|
||||
"processor": "RP2040",
|
||||
@@ -74,11 +74,6 @@
|
||||
"processor": "RP2040",
|
||||
"bootloader": "rp2040",
|
||||
"board": "QMK_PM2040"
|
||||
},
|
||||
"liatris": {
|
||||
"processor": "RP2040",
|
||||
"bootloader": "rp2040",
|
||||
"board": "QMK_PM2040"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+50
-102
@@ -10,129 +10,95 @@
|
||||
// deprecated: Default `false`. Set to `true` to turn on warning when a value exists
|
||||
// invalid: Default `false`. Set to `true` to generate errors when a value exists
|
||||
// replace_with: use with a key marked deprecated or invalid to designate a replacement
|
||||
|
||||
// APA102
|
||||
"APA102_CI_PIN": {"info_key": "apa102.clock_pin"},
|
||||
"APA102_DEFAULT_BRIGHTNESS": {"info_key": "apa102.default_brightness", "value_type": "int"},
|
||||
"APA102_DI_PIN": {"info_key": "apa102.data_pin"},
|
||||
|
||||
// Audio
|
||||
"AUDIO_VOICES": {"info_key": "audio.voices", "value_type": "bool"},
|
||||
"SENDSTRING_BELL": {"info_key": "audio.macro_beep", "value_type": "bool"},
|
||||
|
||||
// Backlight
|
||||
"BACKLIGHT_BREATHING": {"info_key": "backlight.breathing", "value_type": "bool"},
|
||||
"BREATHING_PERIOD": {"info_key": "backlight.breathing_period", "value_type": "int"},
|
||||
"BACKLIGHT_CAPS_LOCK": {"info_key": "backlight.as_caps_lock", "value_type": "bool"},
|
||||
"BACKLIGHT_LEVELS": {"info_key": "backlight.levels", "value_type": "int"},
|
||||
"BACKLIGHT_LIMIT_VAL": {"info_key": "backlight.max_brightness", "value_type": "int"},
|
||||
"BACKLIGHT_ON_STATE": {"info_key": "backlight.on_state", "value_type": "int"},
|
||||
"BACKLIGHT_PIN": {"info_key": "backlight.pin"},
|
||||
"BACKLIGHT_PINS": {"info_key": "backlight.pins", "value_type": "array"},
|
||||
"BREATHING_PERIOD": {"info_key": "backlight.breathing_period", "value_type": "int"},
|
||||
|
||||
// Bootmagic
|
||||
"BOOTMAGIC_LITE_COLUMN": {"info_key": "bootmagic.matrix.1", "value_type": "int"},
|
||||
"BOOTMAGIC_LITE_COLUMN_RIGHT": {"info_key": "split.bootmagic.matrix.1", "value_type": "int"},
|
||||
"BOOTMAGIC_LITE_ROW": {"info_key": "bootmagic.matrix.0", "value_type": "int"},
|
||||
"BOOTMAGIC_LITE_COLUMN": {"info_key": "bootmagic.matrix.1", "value_type": "int"},
|
||||
"BOOTMAGIC_LITE_ROW_RIGHT": {"info_key": "split.bootmagic.matrix.0", "value_type": "int"},
|
||||
|
||||
// Caps Word
|
||||
"BOOTMAGIC_LITE_COLUMN_RIGHT": {"info_key": "split.bootmagic.matrix.1", "value_type": "int"},
|
||||
"BOTH_SHIFTS_TURNS_ON_CAPS_WORD": {"info_key": "caps_word.both_shifts_turns_on", "value_type": "bool"},
|
||||
"CAPS_WORD_IDLE_TIMEOUT": {"info_key": "caps_word.idle_timeout", "value_type": "int"},
|
||||
"CAPS_WORD_INVERT_ON_SHIFT": {"info_key": "caps_word.invert_on_shift", "value_type": "bool"},
|
||||
"DOUBLE_TAP_SHIFT_TURNS_ON_CAPS_WORD": {"info_key": "caps_word.double_tap_shift_turns_on", "value_type": "bool"},
|
||||
|
||||
// Combos
|
||||
"COMBO_COUNT": {"info_key": "combo.count", "value_type": "int"},
|
||||
"COMBO_TERM": {"info_key": "combo.term", "value_type": "int"},
|
||||
|
||||
// Dynamic Keymap
|
||||
"DEBOUNCE": {"info_key": "debounce", "value_type": "int"},
|
||||
"DIODE_DIRECTION": {"info_key": "diode_direction"},
|
||||
"DOUBLE_TAP_SHIFT_TURNS_ON_CAPS_WORD": {"info_key": "caps_word.double_tap_shift_turns_on", "value_type": "bool"},
|
||||
"FORCE_NKRO": {"info_key": "usb.force_nkro", "value_type": "bool"},
|
||||
"DYNAMIC_KEYMAP_EEPROM_MAX_ADDR": {"info_key": "dynamic_keymap.eeprom_max_addr", "value_type": "int"},
|
||||
"DYNAMIC_KEYMAP_LAYER_COUNT": {"info_key": "dynamic_keymap.layer_count", "value_type": "int"},
|
||||
|
||||
// Indicators
|
||||
"HOLD_ON_OTHER_KEY_PRESS": {"info_key": "tapping.hold_on_other_key_press", "value_type": "bool"},
|
||||
"HOLD_ON_OTHER_KEY_PRESS_PER_KEY": {"info_key": "tapping.hold_on_other_key_press_per_key", "value_type": "bool"},
|
||||
"LAYOUTS": {"info_key": "layout_aliases", "value_type": "mapping"},
|
||||
"LEADER_PER_KEY_TIMING": {"info_key": "leader_key.timing", "value_type": "bool"},
|
||||
"LEADER_KEY_STRICT_KEY_PROCESSING": {"info_key": "leader_key.strict_processing", "value_type": "bool"},
|
||||
"LEADER_TIMEOUT": {"info_key": "leader_key.timeout", "value_type": "int"},
|
||||
"LED_CAPS_LOCK_PIN": {"info_key": "indicators.caps_lock"},
|
||||
"LED_NUM_LOCK_PIN": {"info_key": "indicators.num_lock"},
|
||||
"LED_SCROLL_LOCK_PIN": {"info_key": "indicators.scroll_lock"},
|
||||
"LED_COMPOSE_PIN": {"info_key": "indicators.compose"},
|
||||
"LED_KANA_PIN": {"info_key": "indicators.kana"},
|
||||
"LED_PIN_ON_STATE": {"info_key": "indicators.on_state", "value_type": "int"},
|
||||
|
||||
// Leader Key
|
||||
"LEADER_PER_KEY_TIMING": {"info_key": "leader_key.timing", "value_type": "bool"},
|
||||
"LEADER_KEY_STRICT_KEY_PROCESSING": {"info_key": "leader_key.strict_processing", "value_type": "bool"},
|
||||
"LEADER_TIMEOUT": {"info_key": "leader_key.timeout", "value_type": "int"},
|
||||
|
||||
// LED Matrix
|
||||
"LED_MATRIX_CENTER": {"info_key": "led_matrix.center_point", "value_type": "array.int"},
|
||||
"LED_MATRIX_HUE_STEP": {"info_key": "led_matrix.hue_steps", "value_type": "int"},
|
||||
"LED_MATRIX_MAXIMUM_BRIGHTNESS": {"info_key": "led_matrix.max_brightness", "value_type": "int"},
|
||||
"LED_MATRIX_SAT_STEP": {"info_key": "led_matrix.sat_steps", "value_type": "int"},
|
||||
"LED_MATRIX_SPD_STEP": {"info_key": "led_matrix.speed_steps", "value_type": "int"},
|
||||
"LED_MATRIX_SPLIT": {"info_key": "led_matrix.split_count", "value_type": "array.int"},
|
||||
"LED_MATRIX_TIMEOUT": {"info_key": "led_matrix.timeout", "value_type": "int"},
|
||||
"LED_MATRIX_HUE_STEP": {"info_key": "led_matrix.hue_steps", "value_type": "int"},
|
||||
"LED_MATRIX_SAT_STEP": {"info_key": "led_matrix.sat_steps", "value_type": "int"},
|
||||
"LED_MATRIX_VAL_STEP": {"info_key": "led_matrix.val_steps", "value_type": "int"},
|
||||
|
||||
// LUFA Bootloader
|
||||
"QMK_ESC_INPUT": {"info_key": "qmk_lufa_bootloader.esc_input"},
|
||||
"QMK_ESC_OUTPUT": {"info_key": "qmk_lufa_bootloader.esc_output"},
|
||||
"QMK_LED": {"info_key": "qmk_lufa_bootloader.led"},
|
||||
"QMK_SPEAKER": {"info_key": "qmk_lufa_bootloader.speaker"},
|
||||
|
||||
// Matrix
|
||||
"DEBOUNCE": {"info_key": "debounce", "value_type": "int"},
|
||||
"DIODE_DIRECTION": {"info_key": "diode_direction"},
|
||||
"LED_MATRIX_SPD_STEP": {"info_key": "led_matrix.speed_steps", "value_type": "int"},
|
||||
"MATRIX_HAS_GHOST": {"info_key": "matrix_pins.ghost", "value_type": "bool"},
|
||||
"MATRIX_INPUT_PRESSED_STATE": {"info_key": "matrix_pins.input_pressed_state", "value_type": "int"},
|
||||
"MATRIX_IO_DELAY": {"info_key": "matrix_pins.io_delay", "value_type": "int"},
|
||||
|
||||
// Mouse Keys
|
||||
"MOUSEKEY_DELAY": {"info_key": "mousekey.delay", "value_type": "int"},
|
||||
"MOUSEKEY_INTERVAL": {"info_key": "mousekey.interval", "value_type": "int"},
|
||||
"MOUSEKEY_MAX_SPEED": {"info_key": "mousekey.max_speed", "value_type": "int"},
|
||||
"MOUSEKEY_TIME_TO_MAX": {"info_key": "mousekey.time_to_max", "value_type": "int"},
|
||||
"MOUSEKEY_WHEEL_DELAY": {"info_key": "mousekey.wheel_delay", "value_type": "int"},
|
||||
|
||||
// One Shot
|
||||
"ONESHOT_TIMEOUT": {"info_key": "oneshot.timeout", "value_type": "int"},
|
||||
"ONESHOT_TAP_TOGGLE": {"info_key": "oneshot.tap_toggle", "value_type": "int"},
|
||||
|
||||
// PS/2
|
||||
"PERMISSIVE_HOLD": {"info_key": "tapping.permissive_hold", "value_type": "bool"},
|
||||
"PERMISSIVE_HOLD_PER_KEY": {"info_key": "tapping.permissive_hold_per_key", "value_type": "bool"},
|
||||
"PS2_CLOCK_PIN": {"info_key": "ps2.clock_pin"},
|
||||
"PS2_DATA_PIN": {"info_key": "ps2.data_pin"},
|
||||
|
||||
// RGB Matrix
|
||||
"RGB_MATRIX_CENTER": {"info_key": "rgb_matrix.center_point", "value_type": "array.int"},
|
||||
"RGB_MATRIX_HUE_STEP": {"info_key": "rgb_matrix.hue_steps", "value_type": "int"},
|
||||
"RGB_MATRIX_MAXIMUM_BRIGHTNESS": {"info_key": "rgb_matrix.max_brightness", "value_type": "int"},
|
||||
"RGB_MATRIX_SAT_STEP": {"info_key": "rgb_matrix.sat_steps", "value_type": "int"},
|
||||
"RGB_MATRIX_SPD_STEP": {"info_key": "rgb_matrix.speed_steps", "value_type": "int"},
|
||||
"RGB_MATRIX_SPLIT": {"info_key": "rgb_matrix.split_count", "value_type": "array.int"},
|
||||
"RGB_MATRIX_TIMEOUT": {"info_key": "rgb_matrix.timeout", "value_type": "int"},
|
||||
"RGB_MATRIX_VAL_STEP": {"info_key": "rgb_matrix.val_steps", "value_type": "int"},
|
||||
|
||||
// RGBLight
|
||||
"RETRO_TAPPING": {"info_key": "tapping.retro", "value_type": "bool"},
|
||||
"RETRO_TAPPING_PER_KEY": {"info_key": "tapping.retro_per_key", "value_type": "bool"},
|
||||
"RGB_DI_PIN": {"info_key": "rgblight.pin"},
|
||||
"RGBLED_NUM": {"info_key": "rgblight.led_count", "value_type": "int"},
|
||||
"RGBLED_SPLIT": {"info_key": "rgblight.split_count", "value_type": "array.int"},
|
||||
"RGBLIGHT_HUE_STEP": {"info_key": "rgblight.hue_steps", "value_type": "int"},
|
||||
"RGBLIGHT_LAYER_BLINK": {"info_key": "rgblight.layers.blink", "value_type": "bool"},
|
||||
"RGBLIGHT_LAYERS": {"info_key": "rgblight.layers.enabled", "value_type": "bool"},
|
||||
"RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF": {"info_key": "rgblight.layers.override_rgb", "value_type": "bool"},
|
||||
"RGBLIGHT_LIMIT_VAL": {"info_key": "rgblight.max_brightness", "value_type": "int"},
|
||||
"RGBLIGHT_MAX_LAYERS": {"info_key": "rgblight.layers.max", "value_type": "int"},
|
||||
"RGBLIGHT_HUE_STEP": {"info_key": "rgblight.hue_steps", "value_type": "int"},
|
||||
"RGBLIGHT_SAT_STEP": {"info_key": "rgblight.saturation_steps", "value_type": "int"},
|
||||
"RGBLIGHT_VAL_STEP": {"info_key": "rgblight.brightness_steps", "value_type": "int"},
|
||||
"RGBLIGHT_SLEEP": {"info_key": "rgblight.sleep", "value_type": "bool"},
|
||||
"RGBLIGHT_SPLIT": {"info_key": "rgblight.split", "value_type": "bool"},
|
||||
"RGBLIGHT_VAL_STEP": {"info_key": "rgblight.brightness_steps", "value_type": "int"},
|
||||
"RGB_MATRIX_CENTER": {"info_key": "rgb_matrix.center_point", "value_type": "array.int"},
|
||||
"RGB_MATRIX_MAXIMUM_BRIGHTNESS": {"info_key": "rgb_matrix.max_brightness", "value_type": "int"},
|
||||
"RGB_MATRIX_SPLIT": {"info_key": "rgb_matrix.split_count", "value_type": "array.int"},
|
||||
"RGB_MATRIX_TIMEOUT": {"info_key": "rgb_matrix.timeout", "value_type": "int"},
|
||||
"RGB_MATRIX_HUE_STEP": {"info_key": "rgb_matrix.hue_steps", "value_type": "int"},
|
||||
"RGB_MATRIX_SAT_STEP": {"info_key": "rgb_matrix.sat_steps", "value_type": "int"},
|
||||
"RGB_MATRIX_VAL_STEP": {"info_key": "rgb_matrix.val_steps", "value_type": "int"},
|
||||
"RGB_MATRIX_SPD_STEP": {"info_key": "rgb_matrix.speed_steps", "value_type": "int"},
|
||||
"RGBW": {"info_key": "rgblight.rgbw", "value_type": "bool"},
|
||||
|
||||
// Secure
|
||||
"SECURE_IDLE_TIMEOUT": {"info_key": "secure.idle_timeout", "value_type": "int"},
|
||||
"QMK_ESC_OUTPUT": {"info_key": "qmk_lufa_bootloader.esc_output"},
|
||||
"QMK_ESC_INPUT": {"info_key": "qmk_lufa_bootloader.esc_input"},
|
||||
"QMK_LED": {"info_key": "qmk_lufa_bootloader.led"},
|
||||
"QMK_SPEAKER": {"info_key": "qmk_lufa_bootloader.speaker"},
|
||||
"SECURE_UNLOCK_SEQUENCE": {"info_key": "secure.unlock_sequence", "value_type": "array.array.int", "to_json": false},
|
||||
"SECURE_UNLOCK_TIMEOUT": {"info_key": "secure.unlock_timeout", "value_type": "int"},
|
||||
|
||||
// Split Keyboard
|
||||
"SOFT_SERIAL_PIN": {"info_key": "split.soft_serial_pin"},
|
||||
"SOFT_SERIAL_SPEED": {"info_key": "split.soft_serial_speed"},
|
||||
"SECURE_IDLE_TIMEOUT": {"info_key": "secure.idle_timeout", "value_type": "int"},
|
||||
"SENDSTRING_BELL": {"info_key": "audio.macro_beep", "value_type": "bool"},
|
||||
"SPLIT_MODS_ENABLE": {"info_key": "split.transport.sync_modifiers", "value_type": "bool"},
|
||||
"SPLIT_TRANSPORT_MIRROR": {"info_key": "split.transport.sync_matrix_state", "value_type": "bool"},
|
||||
"SPLIT_USB_DETECT": {"info_key": "split.usb_detect.enabled", "value_type": "bool"},
|
||||
@@ -140,53 +106,35 @@
|
||||
"SPLIT_USB_TIMEOUT_POLL": {"info_key": "split.usb_detect.polling_interval", "value_type": "int"},
|
||||
"SPLIT_WATCHDOG_ENABLE": {"info_key": "split.transport.watchdog", "value_type": "bool"},
|
||||
"SPLIT_WATCHDOG_TIMEOUT": {"info_key": "split.transport.watchdog_timeout", "value_type": "int"},
|
||||
|
||||
// Tapping
|
||||
"HOLD_ON_OTHER_KEY_PRESS": {"info_key": "tapping.hold_on_other_key_press", "value_type": "bool"},
|
||||
"HOLD_ON_OTHER_KEY_PRESS_PER_KEY": {"info_key": "tapping.hold_on_other_key_press_per_key", "value_type": "bool"},
|
||||
"PERMISSIVE_HOLD": {"info_key": "tapping.permissive_hold", "value_type": "bool"},
|
||||
"PERMISSIVE_HOLD_PER_KEY": {"info_key": "tapping.permissive_hold_per_key", "value_type": "bool"},
|
||||
"RETRO_TAPPING": {"info_key": "tapping.retro", "value_type": "bool"},
|
||||
"RETRO_TAPPING_PER_KEY": {"info_key": "tapping.retro_per_key", "value_type": "bool"},
|
||||
"SOFT_SERIAL_PIN": {"info_key": "split.soft_serial_pin"},
|
||||
"SOFT_SERIAL_SPEED": {"info_key": "split.soft_serial_speed"},
|
||||
"TAP_CODE_DELAY": {"info_key": "qmk.tap_keycode_delay", "value_type": "int"},
|
||||
"TAP_HOLD_CAPS_DELAY": {"info_key": "qmk.tap_capslock_delay", "value_type": "int"},
|
||||
"TAPPING_TERM": {"info_key": "tapping.term", "value_type": "int"},
|
||||
"TAPPING_TERM_PER_KEY": {"info_key": "tapping.term_per_key", "value_type": "bool"},
|
||||
"TAPPING_TOGGLE": {"info_key": "tapping.toggle", "value_type": "int"},
|
||||
|
||||
// USB
|
||||
"FORCE_NKRO": {"info_key": "usb.force_nkro", "value_type": "bool"},
|
||||
"USB_MAX_POWER_CONSUMPTION": {"info_key": "usb.max_power", "value_type": "int"},
|
||||
"USB_POLLING_INTERVAL_MS": {"info_key": "usb.polling_interval", "value_type": "int"},
|
||||
"USB_SUSPEND_WAKEUP_DELAY": {"info_key": "usb.suspend_wakeup_delay", "value_type": "int"},
|
||||
|
||||
// WS2812
|
||||
"WS2812_DI_PIN": {"info_key": "ws2812.pin"},
|
||||
"WS2812_I2C_ADDRESS": {"info_key": "ws2812.i2c_address", "value_type": "hex"},
|
||||
"WS2812_I2C_TIMEOUT": {"info_key": "ws2812.i2c_timeout", "value_type": "int"},
|
||||
|
||||
"LAYOUTS": {"info_key": "layout_aliases", "value_type": "mapping"},
|
||||
|
||||
// Items we want flagged in lint
|
||||
"DEBOUNCING_DELAY": {"info_key": "_invalid.debouncing_delay", "invalid": true, "replace_with": "DEBOUNCE"},
|
||||
"DESCRIPTION": {"info_key": "_invalid.usb_description", "invalid": true},
|
||||
"IGNORE_MOD_TAP_INTERRUPT": {"info_key": "_invalid.ignore_mod_tap_interrupt", "value_type": "bool", "invalid": true},
|
||||
"IGNORE_MOD_TAP_INTERRUPT_PER_KEY": {"info_key": "_invalid.ignore_mod_tap_interrupt_per_key", "invalid": true}
|
||||
"NO_ACTION_FUNCTION": {"info_key": "_invalid.no_action_function", "invalid": true},
|
||||
"NO_ACTION_MACRO": {"info_key": "_invalid.no_action_macro", "invalid": true},
|
||||
"NO_ACTION_FUNCTION": {"info_key": "_invalid.no_action_function", "invalid": true},
|
||||
"DESCRIPTION": {"info_key": "_invalid.usb_description", "invalid": true},
|
||||
"DEBOUNCING_DELAY": {"info_key": "_invalid.debouncing_delay", "invalid": true, "replace_with": "DEBOUNCE"},
|
||||
"PREVENT_STUCK_MODIFIERS": {"info_key": "_invalid.prevent_stuck_mods", "invalid": true},
|
||||
"QMK_KEYS_PER_SCAN": {"info_key": "qmk.keys_per_scan", "value_type": "int", "deprecated": true},
|
||||
"RGB_DI_PIN": {"info_key": "rgblight.pin", "invalid": true, "replace_with": "WS2812_DI_PIN or APA102_DI_PIN"},
|
||||
"UNUSED_PINS": {"info_key": "_invalid.unused_pins", "deprecated": true},
|
||||
"RGBLIGHT_ANIMATIONS": {"info_key": "_invalid.rgblight.animations.all", "value_type": "bool", "invalid": true},
|
||||
"QMK_KEYS_PER_SCAN": {"info_key": "qmk.keys_per_scan", "value_type": "int", "deprecated": true},
|
||||
"TAPPING_FORCE_HOLD": {"info_key": "tapping.force_hold", "value_type": "bool", "deprecated": true},
|
||||
"TAPPING_FORCE_HOLD_PER_KEY": {"info_key": "tapping.force_hold_per_key", "value_type": "bool", "deprecated": true},
|
||||
"UNUSED_PINS": {"info_key": "_invalid.unused_pins", "deprecated": true},
|
||||
"COMBO_COUNT": {"info_key": "_invalid.combo.count", "invalid": true},
|
||||
"IGNORE_MOD_TAP_INTERRUPT": {"info_key": "_deprecated.ignore_mod_tap_interrupt", "value_type": "bool", "deprecated": true},
|
||||
"IGNORE_MOD_TAP_INTERRUPT_PER_KEY": {"info_key": "_invalid.ignore_mod_tap_interrupt_per_key", "invalid": true},
|
||||
|
||||
// USB params, need to mark as failure when specified in config.h, rather than deprecated
|
||||
"DEVICE_VER": {"info_key": "usb.device_version", "value_type": "bcd_version", "deprecated": true, "replace_with": "`usb.device_version` in info.json"},
|
||||
"MANUFACTURER": {"info_key": "manufacturer", "value_type": "str", "deprecated": true, "replace_with": "`manufacturer` in info.json"},
|
||||
"PRODUCT": {"info_key": "keyboard_name", "warn_duplicate": false, "value_type": "str", "deprecated": true, "replace_with": "`keyboard_name` in info.json"},
|
||||
"PRODUCT_ID": {"info_key": "usb.pid", "value_type": "hex", "deprecated": true, "replace_with": "`usb.pid` in info.json"},
|
||||
"VENDOR_ID": {"info_key": "usb.vid", "value_type": "hex", "deprecated": true, "replace_with": "`usb.vid` in info.json"},
|
||||
"PRODUCT": {"info_key": "keyboard_name", "warn_duplicate": false, "value_type": "str", "deprecated": true, "replace_with": "`keyboard_name` in info.json"},
|
||||
"MANUFACTURER": {"info_key": "manufacturer", "value_type": "str", "deprecated": true, "replace_with": "`manufacturer` in info.json"},
|
||||
"DEVICE_VER": {"info_key": "usb.device_version", "value_type": "bcd_version", "deprecated": true, "replace_with": "`usb.device_version` in info.json"}
|
||||
}
|
||||
|
||||
@@ -10,38 +10,36 @@
|
||||
// deprecated: Default `false`. Set to `true` to turn on warning when a value exists
|
||||
// invalid: Default `false`. Set to `true` to generate errors when a value exists
|
||||
// replace_with: use with a key marked deprecated or invalid to designate a replacement
|
||||
|
||||
"BACKLIGHT_DRIVER": {"info_key": "backlight.driver"},
|
||||
"BLUETOOTH_DRIVER": {"info_key": "bluetooth.driver"},
|
||||
"BOARD": {"info_key": "board"},
|
||||
"BOOTLOADER": {"info_key": "bootloader", "warn_duplicate": false},
|
||||
"BOOTMAGIC_ENABLE": {"info_key": "bootmagic.enabled", "value_type": "bool"},
|
||||
"BLUETOOTH_DRIVER": {"info_key": "bluetooth.driver"},
|
||||
"BACKLIGHT_DRIVER": {"info_key": "backlight.driver"},
|
||||
"CAPS_WORD_ENABLE": {"info_key": "caps_word.enabled", "value_type": "bool"},
|
||||
"DEBOUNCE_TYPE": {"info_key": "build.debounce_type"},
|
||||
"EEPROM_DRIVER": {"info_key": "eeprom.driver"},
|
||||
"ENCODER_ENABLE": {"info_key": "encoder.enabled", "value_type": "bool"},
|
||||
"FIRMWARE_FORMAT": {"info_key": "build.firmware_format"},
|
||||
"KEYBOARD_SHARED_EP": {"info_key": "usb.shared_endpoint.keyboard", "value_type": "bool"},
|
||||
"MOUSE_SHARED_EP": {"info_key": "usb.shared_endpoint.mouse", "value_type": "bool"},
|
||||
"LAYOUTS": {"info_key": "community_layouts", "value_type": "list"},
|
||||
"LED_MATRIX_DRIVER": {"info_key": "led_matrix.driver"},
|
||||
"RGB_MATRIX_DRIVER": {"info_key": "rgb_matrix.driver"},
|
||||
"LTO_ENABLE": {"info_key": "build.lto", "value_type": "bool"},
|
||||
"MCU": {"info_key": "processor", "warn_duplicate": false},
|
||||
"MOUSE_SHARED_EP": {"info_key": "usb.shared_endpoint.mouse", "value_type": "bool"},
|
||||
"MOUSEKEY_ENABLE": {"info_key": "mouse_key.enabled", "value_type": "bool"},
|
||||
"NO_USB_STARTUP_CHECK": {"info_key": "usb.no_startup_check", "value_type": "bool"},
|
||||
"PIN_COMPATIBLE": {"info_key": "pin_compatible"},
|
||||
"PLATFORM_KEY": {"info_key": "platform_key", "to_json": false},
|
||||
"PS2_DRIVER": {"info_key": "ps2.driver"},
|
||||
"PS2_ENABLE": {"info_key": "ps2.enabled", "value_type": "bool"},
|
||||
"PS2_MOUSE_ENABLE": {"info_key": "ps2.mouse_enabled", "value_type": "bool"},
|
||||
"RGB_MATRIX_DRIVER": {"info_key": "rgb_matrix.driver"},
|
||||
"SECURE_ENABLE": {"info_key": "secure.enabled", "value_type": "bool"},
|
||||
"SPLIT_KEYBOARD": {"info_key": "split.enabled", "value_type": "bool"},
|
||||
"SPLIT_TRANSPORT": {"info_key": "split.transport.protocol", "to_c": false},
|
||||
"WAIT_FOR_USB": {"info_key": "usb.wait_for", "value_type": "bool"},
|
||||
"STENO_ENABLE": {"info_key": "stenography.enabled", "value_type": "bool"},
|
||||
"STENO_PROTOCOL": {"info_key": "stenography.protocol"},
|
||||
"WAIT_FOR_USB": {"info_key": "usb.wait_for", "value_type": "bool"},
|
||||
"WS2812_DRIVER": {"info_key": "ws2812.driver"},
|
||||
"PS2_ENABLE": {"info_key": "ps2.enabled", "value_type": "bool"},
|
||||
"PS2_MOUSE_ENABLE": {"info_key": "ps2.mouse_enabled", "value_type": "bool"},
|
||||
"PS2_DRIVER": {"info_key": "ps2.driver"},
|
||||
|
||||
"PLATFORM_KEY": {"info_key": "platform_key", "to_json": false},
|
||||
|
||||
// Items we want flagged in lint
|
||||
"CTPC": {"info_key": "_deprecated.ctpc", "deprecated": true, "replace_with": "CONVERT_TO=proton_c"},
|
||||
|
||||
@@ -41,9 +41,6 @@
|
||||
"angel64": {
|
||||
"target": "angel64/alpha"
|
||||
},
|
||||
"ashpil/modelm_usbc": {
|
||||
"target": "ibm/model_m/ashpil_usbc"
|
||||
},
|
||||
"at101_blackheart": {
|
||||
"target": "viktus/at101_bh"
|
||||
},
|
||||
@@ -116,15 +113,6 @@
|
||||
"cmm_studio/saka68": {
|
||||
"target": "cmm_studio/saka68/solder"
|
||||
},
|
||||
"converter/modelm101": {
|
||||
"target": "ibm/model_m/teensypp"
|
||||
},
|
||||
"converter/modelm101_teensy2": {
|
||||
"target": "ibm/model_m/teensy2"
|
||||
},
|
||||
"converter/modelm_ssk": {
|
||||
"target": "ibm/model_m_ssk/teensypp_ssk"
|
||||
},
|
||||
"cospad": {
|
||||
"target": "kprepublic/cospad"
|
||||
},
|
||||
@@ -161,15 +149,6 @@
|
||||
"durgod/k320": {
|
||||
"target": "durgod/k3x0/k320"
|
||||
},
|
||||
"durgod/hades": {
|
||||
"target": "durgod/dgk6x/hades_ansi"
|
||||
},
|
||||
"durgod/hades_ansi": {
|
||||
"target": "durgod/dgk6x/hades_ansi"
|
||||
},
|
||||
"durgod/hades_iso": {
|
||||
"target": "durgod/dgk6x/hades_iso"
|
||||
},
|
||||
"dztech/dz60rgb": {
|
||||
"target": "dztech/dz60rgb/v1"
|
||||
},
|
||||
@@ -215,9 +194,6 @@
|
||||
"handwired/ferris": {
|
||||
"target": "ferris/0_1"
|
||||
},
|
||||
"handwired/ibm122m": {
|
||||
"target": "ibm/model_m_122/ibm122m"
|
||||
},
|
||||
"handwired/p1800fl": {
|
||||
"target": "team0110/p1800fl"
|
||||
},
|
||||
@@ -272,9 +248,6 @@
|
||||
"idobo": {
|
||||
"target": "idobao/id75"
|
||||
},
|
||||
"jacky_studio/piggy60": {
|
||||
"target": "jacky_studio/piggy60/rev1"
|
||||
},
|
||||
"jj40": {
|
||||
"target": "kprepublic/jj40"
|
||||
},
|
||||
@@ -287,12 +260,6 @@
|
||||
"jones": {
|
||||
"target": "jones/v03_1"
|
||||
},
|
||||
"kamigakushi": {
|
||||
"target": "jaykeeb/kamigakushi",
|
||||
"layouts": {
|
||||
"LAYOUT": "LAYOUT_65_ansi_blocker_tsangan"
|
||||
}
|
||||
},
|
||||
"katana60": {
|
||||
"target": "rominronin/katana60/rev1"
|
||||
},
|
||||
@@ -440,9 +407,6 @@
|
||||
"montsinger/rebound": {
|
||||
"target": "montsinger/rebound/rev1"
|
||||
},
|
||||
"mschwingen/modelm": {
|
||||
"target": "ibm/model_m/mschwingen"
|
||||
},
|
||||
"noxary/268_2": {
|
||||
"layouts": {
|
||||
"LAYOUT": "LAYOUT_65_ansi_blocker"
|
||||
@@ -961,12 +925,6 @@
|
||||
"m3n3van": {
|
||||
"target": "matthewdias/m3n3van"
|
||||
},
|
||||
"massdrop/thekey": {
|
||||
"target": "drop/thekey/v1"
|
||||
},
|
||||
"massdrop/thekey_v2": {
|
||||
"target": "drop/thekey/v2"
|
||||
},
|
||||
"mechmini/v1": {
|
||||
"target": "mechkeys/mechmini/v1"
|
||||
},
|
||||
@@ -1264,9 +1222,6 @@
|
||||
"treadstone48/rev2": {
|
||||
"target": "marksard/treadstone48/rev2"
|
||||
},
|
||||
"tronguylabs/m122_3270": {
|
||||
"target": "ibm/model_m_122/m122_3270"
|
||||
},
|
||||
"ua62": {
|
||||
"target": "nacly/ua62"
|
||||
},
|
||||
@@ -1327,9 +1282,6 @@
|
||||
"ymdk_np21": {
|
||||
"target": "ymdk/np21"
|
||||
},
|
||||
"yugo_m/model_m_101": {
|
||||
"target": "ibm/model_m/yugo_m"
|
||||
},
|
||||
"yurei": {
|
||||
"target": "kkatano/yurei"
|
||||
},
|
||||
|
||||
@@ -14,15 +14,15 @@
|
||||
},
|
||||
"hex_number_2d": {
|
||||
"type": "string",
|
||||
"pattern": "^0x[0-9A-F]{2}$"
|
||||
"pattern": "^0x[0-9A-F][0-9A-F]$"
|
||||
},
|
||||
"hex_number_4d": {
|
||||
"type": "string",
|
||||
"pattern": "^0x[0-9A-F]{4}$"
|
||||
"pattern": "^0x[0-9A-F][0-9A-F][0-9A-F][0-9A-F]$"
|
||||
},
|
||||
"bcd_version": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9]{1,2}\\.[0-9]\\.[0-9]$"
|
||||
"pattern": "^[0-9][0-9]?\\.[0-9]\\.[0-9]$"
|
||||
},
|
||||
"text_identifier": {
|
||||
"type": "string",
|
||||
@@ -71,38 +71,6 @@
|
||||
"type": "string",
|
||||
"pattern": "^[0-9a-z][0-9a-z_/]*$"
|
||||
},
|
||||
"keycode": {
|
||||
"type": "string",
|
||||
"minLength": 2,
|
||||
"maxLength": 50,
|
||||
"pattern": "^[A-Z][A-Zs_0-9]*$"
|
||||
},
|
||||
"keycode_short": {
|
||||
"type": "string",
|
||||
"minLength": 2,
|
||||
"maxLength": 7,
|
||||
"pattern": "^[A-Z][A-Zs_0-9]*$"
|
||||
},
|
||||
"keycode_decl": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"key"
|
||||
],
|
||||
"properties": {
|
||||
"key": {"$ref": "#/keycode"},
|
||||
"label": {"$ref": "#/text_identifier"},
|
||||
"aliases": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {"$ref": "#/keycode_short"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"keycode_decl_array": {
|
||||
"type": "array",
|
||||
"minItems": 1
|
||||
"items": {"$ref": "#/keycode_decl"}
|
||||
},
|
||||
"mcu_pin_array": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/mcu_pin"}
|
||||
@@ -115,15 +83,15 @@
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^[A-K]\\d{1,2}$"
|
||||
"pattern": "^[A-K]\\d\\d?$"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^LINE_PIN\\d{1,2}$"
|
||||
"pattern": "^LINE_PIN\\d\\d?$"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^GP\\d{1,2}$"
|
||||
"pattern": "^GP\\d\\d?$"
|
||||
},
|
||||
{
|
||||
"type": "integer"
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
},
|
||||
"development_board": {
|
||||
"type": "string",
|
||||
"enum": ["promicro", "elite_c", "elite_pi", "proton_c", "kb2040", "promicro_rp2040", "blok", "michi", "bit_c_pro", "stemcell", "bluepill", "blackpill_f401", "blackpill_f411", "bonsai_c4", "helios", "liatris"]
|
||||
"enum": ["promicro", "elite_c", "elite_pi", "proton_c", "kb2040", "promicro_rp2040", "blok", "michi", "bit_c_pro", "stemcell", "bluepill", "blackpill_f401", "blackpill_f411", "bonsai_c4", "helios"]
|
||||
},
|
||||
"pin_compatible": {
|
||||
"type": "string",
|
||||
@@ -96,19 +96,6 @@
|
||||
"unknown"
|
||||
]
|
||||
},
|
||||
"apa102": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"data_pin": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||
"clock_pin": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||
"default_brightness": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 31
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@@ -146,7 +133,7 @@
|
||||
"properties": {
|
||||
"driver": {
|
||||
"type": "string",
|
||||
"enum": ["BluefruitLE", "RN42", "custom"]
|
||||
"enum": ["BluefruitLE", "RN42"]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -227,8 +214,7 @@
|
||||
"enabled": {"type": "boolean"},
|
||||
"both_shifts_turns_on": {"type": "boolean"},
|
||||
"double_tap_shift_turns_on": {"type": "boolean"},
|
||||
"idle_timeout": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
||||
"invert_on_shift": {"type": "boolean"}
|
||||
"idle_timeout": {"$ref": "qmk.definitions.v1#/unsigned_int"}
|
||||
}
|
||||
},
|
||||
"combo": {
|
||||
@@ -242,11 +228,6 @@
|
||||
"type": "array",
|
||||
"items": {"$ref": "qmk.definitions.v1#/filename"}
|
||||
},
|
||||
"eeprom": {
|
||||
"properties": {
|
||||
"driver": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"encoder": {
|
||||
"$ref": "#/definitions/encoder_config",
|
||||
"properties": {
|
||||
@@ -265,7 +246,6 @@
|
||||
"on_state": {"$ref": "qmk.definitions.v1#/bit"}
|
||||
}
|
||||
},
|
||||
"keycodes": {"$ref": "qmk.definitions.v1#/keycode_decl_array"},
|
||||
"layout_aliases": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"$ref": "qmk.definitions.v1#/layout_macro"}
|
||||
@@ -492,10 +472,7 @@
|
||||
},
|
||||
"led_count": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
||||
"max_brightness": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
||||
"pin": {
|
||||
"$ref": "qmk.definitions.v1#/mcu_pin",
|
||||
"$comment": "Deprecated: use ws2812.pin instead"
|
||||
},
|
||||
"pin": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||
"rgbw": {"type": "boolean"},
|
||||
"saturation_steps": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
||||
"sleep": {"type": "boolean"},
|
||||
@@ -709,19 +686,6 @@
|
||||
"led": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||
"speaker": {"$ref": "qmk.definitions.v1#/mcu_pin"}
|
||||
}
|
||||
},
|
||||
"ws2812": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"driver": {
|
||||
"type": "string",
|
||||
"enum": ["bitbang", "custom", "i2c", "pwm", "spi", "vendor"]
|
||||
},
|
||||
"pin": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||
"i2c_address": {"$ref": "qmk.definitions.v1#/hex_number_2d"},
|
||||
"i2c_timeout": {"$ref": "qmk.definitions.v1#/unsigned_int"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
"type": "string",
|
||||
"minLength": 2,
|
||||
"maxLength": 50,
|
||||
"pattern": "^[A-Z][A-Zs_0-9]*$"
|
||||
"pattern": "^[A-Zs_0-9]*$"
|
||||
},
|
||||
"hex_number_4d": {
|
||||
"type": "string",
|
||||
"pattern": "^0x[0-9A-F]{4}$"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
@@ -30,10 +34,10 @@
|
||||
"keycodes": {
|
||||
"type": "object",
|
||||
"propertyNames": {
|
||||
"$ref": "qmk.definitions.v1#/hex_number_4d"
|
||||
"$ref": "#/definitions/hex_number_4d"
|
||||
},
|
||||
"additionalProperties": {
|
||||
"type": "object", // use 'qmk.definitions.v1#/keycode_decl' when problem keycodes are removed
|
||||
"type": "object",
|
||||
"required": [
|
||||
"key"
|
||||
],
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"keycodes": {"$ref": "qmk.definitions.v1#/keycode_decl_array"},
|
||||
"config": {"$ref": "qmk.keyboard.v1"},
|
||||
"notes": {
|
||||
"type": "string"
|
||||
|
||||
@@ -1,551 +0,0 @@
|
||||
# QMK Breaking Changes - 2023 May 28 Changelog
|
||||
|
||||
## Notable Changes :id=notable-changes
|
||||
|
||||
As per last breaking changes cycle, there has been _a lot_ of emphasis on behind-the-scenes changes, mainly around migration of configurables into `info.json` files, cleanup of `info.json` files, additional layout definitions for keyboards, adding support for general community layouts to keyboards, as well as addressing technical debt.
|
||||
|
||||
Of note for keyboard designers:
|
||||
|
||||
* Layout and matrix definitions in `info.json` are now _mandatory_ for merge into QMK.
|
||||
* Layout macros in `<yourkeyboard>.h` are no longer accepted into QMK Firmware.
|
||||
* Existing keyboards have been meticulously converted by the QMK collaborators
|
||||
* Layouts missing from keyboard definitions have been added in the process
|
||||
* Keys within layouts should not specify `"w":1` or `"h":1` if the key size is 1 -- `w`/`h` should only be present for sizes other than 1
|
||||
* `config_common.h` has been removed and should not be present anywhere in your keyboard code.
|
||||
* `RGB_DI_PIN` will now cause an error during build:
|
||||
* For WS2812-like LEDs, this should be moved to `info.json`: `"ws2812": { "pin": "xxx" }`
|
||||
* For APA102 LEDs, this should be moved to `info.json`: `"apa102": { "data_pin": "xxx" }`
|
||||
* Other mandatory data-driven changes should be automatically flagged during build
|
||||
* Keymaps with `encoder_map` should now have the following change made:
|
||||
* `encoder_map[][NUM_ENCODERS][2]` => `encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS]`
|
||||
* Users assumed the `2` referred to the number of encoders, rather than the number of directions (which is always 2)
|
||||
|
||||
### Repeat last key ([#19700](https://github.com/qmk/qmk_firmware/pull/19700)) :id=repeat-last-key
|
||||
|
||||
A new pair of keys has been added to QMK -- namely `QK_REPEAT_KEY` and `QK_ALT_REPEAT_KEY` (shortened: `QK_REP`/`QK_AREP`). These allow you to repeat the last key pressed, or in the case of the alternate key, press the "opposite" of the last key. For example, if you press `KC_LEFT`, pressing `QK_REPEAT_KEY` afterwards repeats `KC_LEFT`, but pressing `QK_ALT_REPEAT_KEY` instead sends `KC_RIGHT`.
|
||||
|
||||
The full list of default alternate keys is available on the [Repeat Key](feature_repeat_key.md) documentation.
|
||||
|
||||
To enable these keys, in your keymap's `rules.mk`, add:
|
||||
|
||||
```make
|
||||
REPEAT_KEY_ENABLE = yes
|
||||
```
|
||||
|
||||
...and add them to your keymap.
|
||||
|
||||
### User callback for pre process record ([#20584](https://github.com/qmk/qmk_firmware/pull/20584)) :id=user-callback-for-pre-process-record
|
||||
|
||||
Two new boolean callback functions, `pre_process_record_kb` and `pre_process_record_user`, have been added. They are called at the beginning of `process_record`, right before `process_combo`.
|
||||
|
||||
Similar to existing `*_kb` and `*_user` callback functions, returning `false` will halt further processing of key events. The `pre_process_record_user` function will allow user space opportunity to handle or capture an input before it undergoes quantum processing. For example, while action tapping is still resolving the tap or hold output of a mod-tap key, `pre_process_record_user` can capture the next key record of an input event that follows. That key record can be used to influence the [decision of the mod-tap](https://docs.qmk.fm/#/tap_hold) key that is currently undergoing quantum processing.
|
||||
|
||||
### Consolidate modelm ([#14996](https://github.com/qmk/qmk_firmware/pull/14996) :id=consolidate-modelm
|
||||
|
||||
Several build targets for the IBM Model M were cluttered in different folders. The maintainers of several Model M replacement controller projects agreed to consolidate them under one common folder.
|
||||
|
||||
The list of all moved keyboard locations is listed [below](20230528.md#updated-keyboard-codebases).
|
||||
|
||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
||||
|
||||
### `IGNORE_MOD_TAP_INTERRUPT` behaviour changes ([#20211](https://github.com/qmk/qmk_firmware/pull/20211)) :id=i-m-t-i
|
||||
|
||||
Following up from the last breaking changes cycle, `IGNORE_MOD_TAP_INTERRUPT` has been removed and if present in keymap code, will now fail to build. The previous functionality for `IGNORE_MOD_TAP_INTERRUPT` is now default, and should you wish to revert to the old behaviour, you can use `HOLD_ON_OTHER_KEY_PRESS` instead.
|
||||
|
||||
For more information, you are invited to read the section on [HOLD_ON_OTHER_KEY_PRESS](tap_hold.md#hold-on-other-key-press) in the page on [Tap-Hold configuration options](tap_hold.md).
|
||||
|
||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
||||
|
||||
| Old Keyboard Name | New Keyboard Name |
|
||||
|---------------------------------|-------------------------------------|
|
||||
| ashpil/modelm_usbc | ibm/model_m/ashpil_usbc |
|
||||
| binepad/bn009r2 | binepad/bn009/r2 |
|
||||
| converter/modelm101 | ibm/model_m/teensypp |
|
||||
| converter/modelm101_teensy2 | ibm/model_m/teensy2 |
|
||||
| converter/modelm_ssk | ibm/model_m_ssk/teensypp_ssk |
|
||||
| durgod/dgk6x/hades | durgod/dgk6x/hades_ansi |
|
||||
| handwired/ibm122m | ibm/model_m_122/ibm122m |
|
||||
| jacky_studio/piggy60/hotswap | jacky_studio/piggy60/rev1/hotswap |
|
||||
| jacky_studio/piggy60/solder | jacky_studio/piggy60/rev1/solder |
|
||||
| kamigakushi | jaykeeb/kamigakushi |
|
||||
| massdrop/thekey | drop/thekey/v1 |
|
||||
| massdrop/thekey_v2 | drop/thekey/v2 |
|
||||
| mschwingen/modelm | ibm/model_m/mschwingen |
|
||||
| tronguylabs/m122_3270 | ibm/model_m_122/m122_3270 |
|
||||
| tronguylabs/m122_3270/blackpill | ibm/model_m_122/m122_3270/blackpill |
|
||||
| tronguylabs/m122_3270/bluepill | ibm/model_m_122/m122_3270/bluepill |
|
||||
| tronguylabs/m122_3270/teensy | ibm/model_m_122/m122_3270/teensy |
|
||||
| yugo_m/model_m_101 | ibm/model_m/yugo_m |
|
||||
|
||||
## Notable core changes :id=notable-core
|
||||
|
||||
### Encoder functionality fallback ([#20320](https://github.com/qmk/qmk_firmware/pull/20320)) :id=encoder-functionality-fallback
|
||||
|
||||
For keyboards who have not yet been migrated to encoder map, a default set of encoder functionality is now enabled, gracefully degrading functionality depending on which flags are enabled by the keyboard:
|
||||
|
||||
* If `EXTRAKEY_ENABLE` is enabled by the keyboard, the encoder will be mapped to `KC_VOLU`/`KC_VOLD`
|
||||
* If `MOUSEKEY_ENABLE` is enabled by the keyboard, the encoder will be mapped to `KC_MS_WH_UP`/`KC_MS_WH_DOWN`
|
||||
* Otherwise, `KC_PGDN`/`KC_PGUP` will be used
|
||||
|
||||
Additionally, this ensures that builds on QMK Configurator produce some sort of usable encoder mapping.
|
||||
|
||||
### OLED Driver Improvements ([#20331](https://github.com/qmk/qmk_firmware/pull/20331)) :id=oled-driver-improvements
|
||||
|
||||
The "classic" OLED driver picked up support for additional sizes of OLED displays, support for the SH1107 controller, and SPI-based OLED support.
|
||||
|
||||
Other configurable items are available and can be found on the [OLED Driver page](https://docs.qmk.fm/#/feature_oled_driver).
|
||||
|
||||
## Full changelist :id=full-changelist
|
||||
|
||||
Core:
|
||||
* Refactor `keyevent_t` for 1ms timing resolution ([#15847](https://github.com/qmk/qmk_firmware/pull/15847))
|
||||
* PS/2 PIO Driver for RP2040 ([#17893](https://github.com/qmk/qmk_firmware/pull/17893))
|
||||
* Relocate various modifier defines ([#18638](https://github.com/qmk/qmk_firmware/pull/18638))
|
||||
* Added PMW3320 driver ([#19543](https://github.com/qmk/qmk_firmware/pull/19543))
|
||||
* Keymap introspection for combos. ([#19670](https://github.com/qmk/qmk_firmware/pull/19670))
|
||||
* Add direction to dynamic_macro_record_start_user ([#19689](https://github.com/qmk/qmk_firmware/pull/19689))
|
||||
* Add Repeat Key ("repeat last key") as a core feature. ([#19700](https://github.com/qmk/qmk_firmware/pull/19700))
|
||||
* [Cleanup] Quantum Painter ([#19825](https://github.com/qmk/qmk_firmware/pull/19825))
|
||||
* Improve robustness of AW20216 driver ([#19849](https://github.com/qmk/qmk_firmware/pull/19849))
|
||||
* Make "detected_host_os()" available on the SLAVE side of the split keyboard ([#19854](https://github.com/qmk/qmk_firmware/pull/19854))
|
||||
* Add RP2040 Community Edition alias for splitkb.com's Liatris controller ([#19966](https://github.com/qmk/qmk_firmware/pull/19966))
|
||||
* Remove some use of keymap.h ([#19980](https://github.com/qmk/qmk_firmware/pull/19980))
|
||||
* Merge upstream changes to uf2conv ([#19993](https://github.com/qmk/qmk_firmware/pull/19993))
|
||||
* Remove keymap.h ([#20004](https://github.com/qmk/qmk_firmware/pull/20004))
|
||||
* Remove some use of keymap.h ([#20006](https://github.com/qmk/qmk_firmware/pull/20006))
|
||||
* Quantum Painter QoL enhancements -- auto-poweroff, auto-flush, buffer sizing ([#20013](https://github.com/qmk/qmk_firmware/pull/20013))
|
||||
* Make Pointing Device Auto Layer more configurable ([#20061](https://github.com/qmk/qmk_firmware/pull/20061))
|
||||
* Add last activity functions for pointing device ([#20079](https://github.com/qmk/qmk_firmware/pull/20079))
|
||||
* Caps Word "Invert on shift" option: pressing Shift inverts the shift state. ([#20092](https://github.com/qmk/qmk_firmware/pull/20092))
|
||||
* Remove bootloader logic from `mcu_selection.mk` ([#20150](https://github.com/qmk/qmk_firmware/pull/20150))
|
||||
* Update qmk_cli container references ([#20154](https://github.com/qmk/qmk_firmware/pull/20154))
|
||||
* Clean up APA102 config and add DD mapping ([#20159](https://github.com/qmk/qmk_firmware/pull/20159))
|
||||
* Sync activity timestamps between sides. ([#20192](https://github.com/qmk/qmk_firmware/pull/20192))
|
||||
* Update Doxygen comments for some headers ([#20194](https://github.com/qmk/qmk_firmware/pull/20194))
|
||||
* Make IGNORE_MOD_TAP_INTERRUPT the default behaviour for mod-taps ([#20211](https://github.com/qmk/qmk_firmware/pull/20211))
|
||||
* Add some helpers to tidy up XAP ([#20235](https://github.com/qmk/qmk_firmware/pull/20235))
|
||||
* Tidy up duplication of MIN/MAX fallback implementations ([#20236](https://github.com/qmk/qmk_firmware/pull/20236))
|
||||
* Optionally keep intermediate file listings in order to do comparisons between builds. ([#20237](https://github.com/qmk/qmk_firmware/pull/20237))
|
||||
* Add basic profiler. ([#20238](https://github.com/qmk/qmk_firmware/pull/20238))
|
||||
* WS2812 driver improvements ([#20262](https://github.com/qmk/qmk_firmware/pull/20262))
|
||||
* typing_heatmap: Add macro to configure increase steps ([#20300](https://github.com/qmk/qmk_firmware/pull/20300))
|
||||
* Migrate `rgblight.pin` and `RGB_DI_PIN` to `ws2812.pin` ([#20303](https://github.com/qmk/qmk_firmware/pull/20303))
|
||||
* Delete config_common.h ([#20312](https://github.com/qmk/qmk_firmware/pull/20312))
|
||||
* Allow EEPROM_DRIVER from info.json ([#20313](https://github.com/qmk/qmk_firmware/pull/20313))
|
||||
* rp2040: *_PAL_MODE overridable for this platform too ([#20314](https://github.com/qmk/qmk_firmware/pull/20314))
|
||||
* Add core/fallback encoder behaviour ([#20320](https://github.com/qmk/qmk_firmware/pull/20320))
|
||||
* OLED Driver improvements ([#20331](https://github.com/qmk/qmk_firmware/pull/20331))
|
||||
* [Chore] Remove stray mod tap interrupt defines and per key functions ([#20347](https://github.com/qmk/qmk_firmware/pull/20347))
|
||||
* Add swap hands toggle functions ([#20381](https://github.com/qmk/qmk_firmware/pull/20381))
|
||||
* Prevent Tri-Layer keys from stopping caps word ([#20398](https://github.com/qmk/qmk_firmware/pull/20398))
|
||||
* quantum/action_util.c: Use uint8_t for oneshot_layer_data ([#20423](https://github.com/qmk/qmk_firmware/pull/20423))
|
||||
* Encoder map direction define. ([#20454](https://github.com/qmk/qmk_firmware/pull/20454))
|
||||
* Realign and size check EECONFIG structures ([#20541](https://github.com/qmk/qmk_firmware/pull/20541))
|
||||
* Clean up ISSI drivers, Add IS31FL3736 support ([#20572](https://github.com/qmk/qmk_firmware/pull/20572))
|
||||
* Add a user callback for pre process record ([#20584](https://github.com/qmk/qmk_firmware/pull/20584))
|
||||
* Disable debug on QP's internal task ([#20623](https://github.com/qmk/qmk_firmware/pull/20623))
|
||||
* Add required string header file ([#20638](https://github.com/qmk/qmk_firmware/pull/20638))
|
||||
* Add Develop is31fl3736 multi drivers ([#20642](https://github.com/qmk/qmk_firmware/pull/20642))
|
||||
* Support PS/2 mouse 9-bit output with MOUSE_EXTENDED_REPORT ([#20734](https://github.com/qmk/qmk_firmware/pull/20734))
|
||||
* BIOI G60/Morgan65: use custom Bluetooth driver ([#20897](https://github.com/qmk/qmk_firmware/pull/20897))
|
||||
* Move `pre_process_record_kb()` before `process_combo()` ([#20969](https://github.com/qmk/qmk_firmware/pull/20969))
|
||||
* Implement UF2 device type id extension tag ([#21029](https://github.com/qmk/qmk_firmware/pull/21029))
|
||||
|
||||
CLI:
|
||||
* Add force support to 'qmk git-submodule' ([#19705](https://github.com/qmk/qmk_firmware/pull/19705))
|
||||
* JSON encoder: improve sorting of layout dict keys ([#19974](https://github.com/qmk/qmk_firmware/pull/19974))
|
||||
* Increase verbosity of make command ([#20172](https://github.com/qmk/qmk_firmware/pull/20172))
|
||||
* Append user variables to the end of make command ([#20177](https://github.com/qmk/qmk_firmware/pull/20177))
|
||||
* Strip API specific output from `qmk info` ([#20234](https://github.com/qmk/qmk_firmware/pull/20234))
|
||||
* `qmk find`: usability improvements ([#20440](https://github.com/qmk/qmk_firmware/pull/20440))
|
||||
* `qmk format-json`: Expose full key path and respect `sort_keys` ([#20836](https://github.com/qmk/qmk_firmware/pull/20836))
|
||||
* Update json2c to use dump_lines ([#21013](https://github.com/qmk/qmk_firmware/pull/21013))
|
||||
|
||||
Submodule updates:
|
||||
* Update ChibiOS to latest stable 21.11.x ([#20470](https://github.com/qmk/qmk_firmware/pull/20470))
|
||||
|
||||
Keyboards:
|
||||
* Allow a larger int for the idle timeout for urbanvanilla keymap ([#19738](https://github.com/qmk/qmk_firmware/pull/19738))
|
||||
* Change aidansmithdotdev/fine40 to use Encoder Map ([#19912](https://github.com/qmk/qmk_firmware/pull/19912))
|
||||
* Custom keycodes in JSON ([#19925](https://github.com/qmk/qmk_firmware/pull/19925))
|
||||
* Remove `"w":1` and `"h":1` from info.json ([#19961](https://github.com/qmk/qmk_firmware/pull/19961))
|
||||
* Move matrix config to info.json, part 1 ([#19985](https://github.com/qmk/qmk_firmware/pull/19985))
|
||||
* Move matrix config to info.json, part 2 ([#19987](https://github.com/qmk/qmk_firmware/pull/19987))
|
||||
* Move matrix config to info.json, part 3 ([#19991](https://github.com/qmk/qmk_firmware/pull/19991))
|
||||
* Move matrix config to info.json, part 4 ([#20001](https://github.com/qmk/qmk_firmware/pull/20001))
|
||||
* Move matrix config to info.json, part 5 ([#20003](https://github.com/qmk/qmk_firmware/pull/20003))
|
||||
* Move matrix config to info.json, part 6 ([#20019](https://github.com/qmk/qmk_firmware/pull/20019))
|
||||
* Move matrix config to info.json, part 7 ([#20020](https://github.com/qmk/qmk_firmware/pull/20020))
|
||||
* Move matrix config to info.json, part 8 ([#20030](https://github.com/qmk/qmk_firmware/pull/20030))
|
||||
* Remove empty rules.mk from keymaps ([#20056](https://github.com/qmk/qmk_firmware/pull/20056))
|
||||
* Adjust offset for some layouts ([#20075](https://github.com/qmk/qmk_firmware/pull/20075))
|
||||
* Remove useless "ifdef KEYBOARD_*" ([#20078](https://github.com/qmk/qmk_firmware/pull/20078))
|
||||
* Remove pointless `USE_I2C` blocks in keyboard headers ([#20084](https://github.com/qmk/qmk_firmware/pull/20084))
|
||||
* Add support for ISO version of Durgod Hades ([#20110](https://github.com/qmk/qmk_firmware/pull/20110))
|
||||
* Consolidate Binepad BN009 R1 and R2 into common folder ([#20113](https://github.com/qmk/qmk_firmware/pull/20113))
|
||||
* Remove more empty headers ([#20155](https://github.com/qmk/qmk_firmware/pull/20155))
|
||||
* Remove trailing zeroes in info.json layouts ([#20156](https://github.com/qmk/qmk_firmware/pull/20156))
|
||||
* Clean up usage of `QMK_KEYBOARD_H` ([#20167](https://github.com/qmk/qmk_firmware/pull/20167))
|
||||
* Move Keychron Q0 and Q0 Plus data-driven configuration; `keychron` keymap `rules.mk` cleanup ([#20168](https://github.com/qmk/qmk_firmware/pull/20168))
|
||||
* Move ortho & numpad layouts to data driven ([#20183](https://github.com/qmk/qmk_firmware/pull/20183))
|
||||
* Remove `RGB_DI_PIN` ifdefs ([#20218](https://github.com/qmk/qmk_firmware/pull/20218))
|
||||
* Add the KJ-Modify RS40 PCB keyboard ([#20243](https://github.com/qmk/qmk_firmware/pull/20243))
|
||||
* Move `WS2812_DRIVER` to data driven ([#20248](https://github.com/qmk/qmk_firmware/pull/20248))
|
||||
* [jacky_studio/piggy60] move AVR PCB under rev1 ([#20253](https://github.com/qmk/qmk_firmware/pull/20253))
|
||||
* Move 75% and 96% layouts to data driven ([#20289](https://github.com/qmk/qmk_firmware/pull/20289))
|
||||
* Move split layouts to data driven ([#20290](https://github.com/qmk/qmk_firmware/pull/20290))
|
||||
* Move 66% and 68% layouts to data driven ([#20293](https://github.com/qmk/qmk_firmware/pull/20293))
|
||||
* add jacky_studio/piggy60/rev2 ([#20297](https://github.com/qmk/qmk_firmware/pull/20297))
|
||||
* Move 65% layouts to data driven ([#20308](https://github.com/qmk/qmk_firmware/pull/20308))
|
||||
* Move TKL F13 and FRL layouts to data driven ([#20310](https://github.com/qmk/qmk_firmware/pull/20310))
|
||||
* Remove some use of keymap.h ([#20316](https://github.com/qmk/qmk_firmware/pull/20316))
|
||||
* Move fullsize layouts to data driven ([#20317](https://github.com/qmk/qmk_firmware/pull/20317))
|
||||
* Add 36-key layout for Beekeeb Piantor ([#20328](https://github.com/qmk/qmk_firmware/pull/20328))
|
||||
* Add sriwedari70 and move kamigakushi to new folder ([#20334](https://github.com/qmk/qmk_firmware/pull/20334))
|
||||
* Move TKL layouts to data driven ([#20337](https://github.com/qmk/qmk_firmware/pull/20337))
|
||||
* Move Alice and Ergodox layouts to data driven ([#20340](https://github.com/qmk/qmk_firmware/pull/20340))
|
||||
* Move small macropad-ish layouts to data driven ([#20341](https://github.com/qmk/qmk_firmware/pull/20341))
|
||||
* Move `default` layouts to data driven ([#20349](https://github.com/qmk/qmk_firmware/pull/20349))
|
||||
* Move `RGB_MATRIX_DRIVER` to data driven ([#20350](https://github.com/qmk/qmk_firmware/pull/20350))
|
||||
* Move split space/backspace layouts to data driven ([#20356](https://github.com/qmk/qmk_firmware/pull/20356))
|
||||
* Move single `LAYOUT`s to data driven ([#20365](https://github.com/qmk/qmk_firmware/pull/20365))
|
||||
* Add encoder map for Iris Rev. 5 VIA ([#20412](https://github.com/qmk/qmk_firmware/pull/20412))
|
||||
* Move remaining `LAYOUT`s to data driven ([#20422](https://github.com/qmk/qmk_firmware/pull/20422))
|
||||
* Move single `LAYOUT_all`s to data driven ([#20430](https://github.com/qmk/qmk_firmware/pull/20430))
|
||||
* 4pplet/yakiimo Layout Macro Conversion and Additions ([#20436](https://github.com/qmk/qmk_firmware/pull/20436))
|
||||
* Move single `60_ansi`, `60_hhkb` and `60_iso` layouts to data driven ([#20438](https://github.com/qmk/qmk_firmware/pull/20438))
|
||||
* Update brauner preonic layout ([#20439](https://github.com/qmk/qmk_firmware/pull/20439))
|
||||
* AEBoards Satellite Rev1 Layout Macro Conversion ([#20442](https://github.com/qmk/qmk_firmware/pull/20442))
|
||||
* Acheron Austin Layout Macro Conversion and Additions ([#20443](https://github.com/qmk/qmk_firmware/pull/20443))
|
||||
* Move remaining `LAYOUT_all`s to data driven ([#20463](https://github.com/qmk/qmk_firmware/pull/20463))
|
||||
* Update lotus58 RGB config ([#20468](https://github.com/qmk/qmk_firmware/pull/20468))
|
||||
* Cleanup `ekow/akira` ([#20474](https://github.com/qmk/qmk_firmware/pull/20474))
|
||||
* Move 60% layouts to data driven ([#20477](https://github.com/qmk/qmk_firmware/pull/20477))
|
||||
* Move DZ60 and MJ6XY layouts to data driven ([#20478](https://github.com/qmk/qmk_firmware/pull/20478))
|
||||
* AEBoards Constellation Layout Macro Updates ([#20487](https://github.com/qmk/qmk_firmware/pull/20487))
|
||||
* AI03 Equinox Layout Macro Additions ([#20488](https://github.com/qmk/qmk_firmware/pull/20488))
|
||||
* AI03 Vega Layout Macro Additions ([#20489](https://github.com/qmk/qmk_firmware/pull/20489))
|
||||
* AKB OGR Layout Macro Additions ([#20490](https://github.com/qmk/qmk_firmware/pull/20490))
|
||||
* AKB Vero Layout Macro Additions ([#20491](https://github.com/qmk/qmk_firmware/pull/20491))
|
||||
* Alf DC60 Layout Macro Additions ([#20494](https://github.com/qmk/qmk_firmware/pull/20494))
|
||||
* Alf X2 Layout Macro Additions ([#20495](https://github.com/qmk/qmk_firmware/pull/20495))
|
||||
* Koolertron AMAG23 Touch-Up ([#20496](https://github.com/qmk/qmk_firmware/pull/20496))
|
||||
* BIOI G60 Layout Macro Additions ([#20498](https://github.com/qmk/qmk_firmware/pull/20498))
|
||||
* BIOI Morgan65 Layout Macro Additions ([#20499](https://github.com/qmk/qmk_firmware/pull/20499))
|
||||
* BIOI S65 Layout Macro Additions ([#20500](https://github.com/qmk/qmk_firmware/pull/20500))
|
||||
* Boston Layout Macro Additions ([#20504](https://github.com/qmk/qmk_firmware/pull/20504))
|
||||
* Potato65S Layout Macro Additions ([#20508](https://github.com/qmk/qmk_firmware/pull/20508))
|
||||
* Move miscellaneous layouts to data driven ([#20516](https://github.com/qmk/qmk_firmware/pull/20516))
|
||||
* Cable Car Designs Cypher rev6 Layout Additions and Touch-Up ([#20518](https://github.com/qmk/qmk_firmware/pull/20518))
|
||||
* Caffeinated Studios Serpent65 Layout Macro Additions ([#20519](https://github.com/qmk/qmk_firmware/pull/20519))
|
||||
* CannonKeys Adelie Layout Macro Additions ([#20546](https://github.com/qmk/qmk_firmware/pull/20546))
|
||||
* CannonKeys Aella Layout Macro Additions ([#20547](https://github.com/qmk/qmk_firmware/pull/20547))
|
||||
* CannonKeys Balance Layout Macro Additions and Touch-Up ([#20548](https://github.com/qmk/qmk_firmware/pull/20548))
|
||||
* CannonKeys Brutal v2 1800 Layout Macro Additions ([#20549](https://github.com/qmk/qmk_firmware/pull/20549))
|
||||
* CannonKeys Brutal v2 65 Layout Macro Additions ([#20552](https://github.com/qmk/qmk_firmware/pull/20552))
|
||||
* CannonKeys Cloudline Layout Macro Additions ([#20553](https://github.com/qmk/qmk_firmware/pull/20553))
|
||||
* CannonKeys Crin Layout Macro Additions ([#20554](https://github.com/qmk/qmk_firmware/pull/20554))
|
||||
* CannonKeys DevastatingTKL Layout Macro Additions ([#20555](https://github.com/qmk/qmk_firmware/pull/20555))
|
||||
* CannonKeys Ellipse Layout Macro Additions ([#20558](https://github.com/qmk/qmk_firmware/pull/20558))
|
||||
* CannonKeys Ellipse Hotswap Layout Macro Addition & Touch-Up ([#20560](https://github.com/qmk/qmk_firmware/pull/20560))
|
||||
* CannonKeys Gentoo Layout Macro Additions ([#20561](https://github.com/qmk/qmk_firmware/pull/20561))
|
||||
* CannonKeys Gentoo Hotswap Touch-Up ([#20562](https://github.com/qmk/qmk_firmware/pull/20562))
|
||||
* CannonKeys HoodrowG Layout Macro Additions ([#20563](https://github.com/qmk/qmk_firmware/pull/20563))
|
||||
* CannonKeys Moment Layout Macro Additions ([#20564](https://github.com/qmk/qmk_firmware/pull/20564))
|
||||
* CannonKeys Moment Hotswap Touch-Up ([#20565](https://github.com/qmk/qmk_firmware/pull/20565))
|
||||
* CannonKeys Nearfield Layout Macro Addition ([#20566](https://github.com/qmk/qmk_firmware/pull/20566))
|
||||
* CannonKeys Obliterated75 Layout Macro Additions ([#20567](https://github.com/qmk/qmk_firmware/pull/20567))
|
||||
* CannonKeys Onyx Layout Macro Additions ([#20568](https://github.com/qmk/qmk_firmware/pull/20568))
|
||||
* CannonKeys Rekt1800 Layout Macro Additions ([#20569](https://github.com/qmk/qmk_firmware/pull/20569))
|
||||
* CannonKeys Serenity Layout Macro Additions ([#20570](https://github.com/qmk/qmk_firmware/pull/20570))
|
||||
* CannonKeys Vector Layout Macro Additions ([#20571](https://github.com/qmk/qmk_firmware/pull/20571))
|
||||
* Carbo65 Community Layout support ([#20580](https://github.com/qmk/qmk_firmware/pull/20580))
|
||||
* cest73 TKM Layout Macro Additions ([#20583](https://github.com/qmk/qmk_firmware/pull/20583))
|
||||
* Charue Charon Layout Macro Additions ([#20585](https://github.com/qmk/qmk_firmware/pull/20585))
|
||||
* Charue Sunsetter R2 Layout Macro Additions ([#20586](https://github.com/qmk/qmk_firmware/pull/20586))
|
||||
* Remove `FLIP_HALF` layouts and move to data driven ([#20588](https://github.com/qmk/qmk_firmware/pull/20588))
|
||||
* update ymdk/id75/rules.mk for develop ([#20592](https://github.com/qmk/qmk_firmware/pull/20592))
|
||||
* CherryB Studio CB1800 Layout Macro Additions ([#20593](https://github.com/qmk/qmk_firmware/pull/20593))
|
||||
* CherryB Studio CB65 Layout Macro Additions ([#20594](https://github.com/qmk/qmk_firmware/pull/20594))
|
||||
* CherryB Studio CB87RGB Layout Macro Additions ([#20595](https://github.com/qmk/qmk_firmware/pull/20595))
|
||||
* CheckerBoards G_IDB60 Layout Macro Edits ([#20596](https://github.com/qmk/qmk_firmware/pull/20596))
|
||||
* CherryB Studio CB87v2 Layout Macro Additions ([#20597](https://github.com/qmk/qmk_firmware/pull/20597))
|
||||
* CX60 Community Layout Support ([#20598](https://github.com/qmk/qmk_firmware/pull/20598))
|
||||
* Demiurge Layout Macro Touch-Up ([#20599](https://github.com/qmk/qmk_firmware/pull/20599))
|
||||
* Ducky One 2 SF 1967ST Layout Macro Additions ([#20600](https://github.com/qmk/qmk_firmware/pull/20600))
|
||||
* Move `FORCE_NKRO` to data driven ([#20604](https://github.com/qmk/qmk_firmware/pull/20604))
|
||||
* dyz Synthesis60 Layout Macro Addition ([#20610](https://github.com/qmk/qmk_firmware/pull/20610))
|
||||
* DZTech Bocc Layout Macro Additions ([#20611](https://github.com/qmk/qmk_firmware/pull/20611))
|
||||
* E88 Layout Macro Additions ([#20612](https://github.com/qmk/qmk_firmware/pull/20612))
|
||||
* Emery65 Layout Macro Additions ([#20613](https://github.com/qmk/qmk_firmware/pull/20613))
|
||||
* EvyD13 MX5160 Layout Macro Additions ([#20614](https://github.com/qmk/qmk_firmware/pull/20614))
|
||||
* FJLabs AD65 Layout Macro Additions ([#20619](https://github.com/qmk/qmk_firmware/pull/20619))
|
||||
* FJLabs Avalon Layout Additions and Touch-Up ([#20620](https://github.com/qmk/qmk_firmware/pull/20620))
|
||||
* FJLabs Midway60 Layout Macro Additions ([#20621](https://github.com/qmk/qmk_firmware/pull/20621))
|
||||
* FJLabs Polaris Layout Additions and Touch-Up ([#20622](https://github.com/qmk/qmk_firmware/pull/20622))
|
||||
* FJLabs Sinanju WK Layout Additions and Touch-Up ([#20628](https://github.com/qmk/qmk_firmware/pull/20628))
|
||||
* LFK87 refactor ([#20635](https://github.com/qmk/qmk_firmware/pull/20635))
|
||||
* Fox Lab Time80 Layout Macro Additions ([#20636](https://github.com/qmk/qmk_firmware/pull/20636))
|
||||
* FJLabs Solanis Layout Macro Additions ([#20639](https://github.com/qmk/qmk_firmware/pull/20639))
|
||||
* GrayStudio Aero 75 Refactor and Touch-Up ([#20640](https://github.com/qmk/qmk_firmware/pull/20640))
|
||||
* Move `USB_MAX_POWER_CONSUMPTION` to data driven ([#20648](https://github.com/qmk/qmk_firmware/pull/20648))
|
||||
* `info.json` whitespace cleanups ([#20651](https://github.com/qmk/qmk_firmware/pull/20651))
|
||||
* Hand88 Layout Macro Additions ([#20657](https://github.com/qmk/qmk_firmware/pull/20657))
|
||||
* Cyberstar Handwired Layout Macro Additions ([#20658](https://github.com/qmk/qmk_firmware/pull/20658))
|
||||
* split_65 Handwired Layout Macro Addition and Touch-Up ([#20659](https://github.com/qmk/qmk_firmware/pull/20659))
|
||||
* Bebol Handwired Layout Macro Additions ([#20660](https://github.com/qmk/qmk_firmware/pull/20660))
|
||||
* Glacier Handwired Layout Macro Addition and Touch-Up ([#20661](https://github.com/qmk/qmk_firmware/pull/20661))
|
||||
* Koalafications Handwired Layout Macro Additions ([#20662](https://github.com/qmk/qmk_firmware/pull/20662))
|
||||
* The Galleon Handwired Layout Macro Additions ([#20663](https://github.com/qmk/qmk_firmware/pull/20663))
|
||||
* More `info.json` whitespace cleanups ([#20665](https://github.com/qmk/qmk_firmware/pull/20665))
|
||||
* Remove use of layout macros for LFKeyboards LED config ([#20666](https://github.com/qmk/qmk_firmware/pull/20666))
|
||||
* Helix rev2: remove 4 rows option ([#20667](https://github.com/qmk/qmk_firmware/pull/20667))
|
||||
* Wakizashi40 Handwired Touch-Up ([#20671](https://github.com/qmk/qmk_firmware/pull/20671))
|
||||
* yttyx: convert readme to utf-8 encoding ([#20672](https://github.com/qmk/qmk_firmware/pull/20672))
|
||||
* Alicia Cook Layout Macro Additions ([#20675](https://github.com/qmk/qmk_firmware/pull/20675))
|
||||
* Primus75 Layout Macro Additions ([#20676](https://github.com/qmk/qmk_firmware/pull/20676))
|
||||
* Volcano660 Layout Macro Additions ([#20677](https://github.com/qmk/qmk_firmware/pull/20677))
|
||||
* Iris Keyboards Iris60 Layout Macro Additions ([#20678](https://github.com/qmk/qmk_firmware/pull/20678))
|
||||
* Irene Layout Macro Additions ([#20679](https://github.com/qmk/qmk_firmware/pull/20679))
|
||||
* Iron180 Layout Macro Additions ([#20680](https://github.com/qmk/qmk_firmware/pull/20680))
|
||||
* kinesis/alvicstep: remove kicad project files ([#20681](https://github.com/qmk/qmk_firmware/pull/20681))
|
||||
* Remove more junk files and scripts ([#20682](https://github.com/qmk/qmk_firmware/pull/20682))
|
||||
* JKeys Design Gentleman65 Layout Macro Addition and Touch-Up ([#20684](https://github.com/qmk/qmk_firmware/pull/20684))
|
||||
* JKeys Design Gentleman65 Suited Edition Layout Macro Addition ([#20685](https://github.com/qmk/qmk_firmware/pull/20685))
|
||||
* add additional layouts to `dactyl_manuform` variants ([#20688](https://github.com/qmk/qmk_firmware/pull/20688))
|
||||
* TheDogKeyboard Layout Macro Addition ([#20689](https://github.com/qmk/qmk_firmware/pull/20689))
|
||||
* KBDfans Bella Soldered Layout Macro Additions ([#20691](https://github.com/qmk/qmk_firmware/pull/20691))
|
||||
* KBDfans Bounce75 Hotswap Touch-Up ([#20692](https://github.com/qmk/qmk_firmware/pull/20692))
|
||||
* KBDfans KBD66 Layout Additions and Refactor ([#20693](https://github.com/qmk/qmk_firmware/pull/20693))
|
||||
* KBDfans Odin RGB Touch-Up ([#20694](https://github.com/qmk/qmk_firmware/pull/20694))
|
||||
* KBDfans Odin Soldered Layout Additions and Touch-Up ([#20695](https://github.com/qmk/qmk_firmware/pull/20695))
|
||||
* keebzdotnet FMe Layout Additions ([#20696](https://github.com/qmk/qmk_firmware/pull/20696))
|
||||
* Kegen G-Boy Layout Additions ([#20697](https://github.com/qmk/qmk_firmware/pull/20697))
|
||||
* Escape Unicode characters in info.json ([#20698](https://github.com/qmk/qmk_firmware/pull/20698))
|
||||
* Kiko's Lab Ellora65 Layout Additions ([#20699](https://github.com/qmk/qmk_firmware/pull/20699))
|
||||
* Even more `info.json` whitespace cleanups ([#20703](https://github.com/qmk/qmk_firmware/pull/20703))
|
||||
* kkatano Bakeneko 65 V3 Layout Additions ([#20706](https://github.com/qmk/qmk_firmware/pull/20706))
|
||||
* kopibeng MNK65 Layout Additions ([#20708](https://github.com/qmk/qmk_firmware/pull/20708))
|
||||
* kopibeng Typ65+ Layout Additions ([#20710](https://github.com/qmk/qmk_firmware/pull/20710))
|
||||
* kopibeng XT60 Layout Additions ([#20711](https://github.com/qmk/qmk_firmware/pull/20711))
|
||||
* kopibeng XT60_SINGA Layout Additions ([#20712](https://github.com/qmk/qmk_firmware/pull/20712))
|
||||
* kopibeng XT8x Layout Additions ([#20713](https://github.com/qmk/qmk_firmware/pull/20713))
|
||||
* Lefty Touch-Up ([#20714](https://github.com/qmk/qmk_firmware/pull/20714))
|
||||
* Loki65 Layout Additions ([#20715](https://github.com/qmk/qmk_firmware/pull/20715))
|
||||
* Lucid Alexa Solder Layout Additions ([#20716](https://github.com/qmk/qmk_firmware/pull/20716))
|
||||
* Lucid Phantom Soldered Layout Additions ([#20717](https://github.com/qmk/qmk_firmware/pull/20717))
|
||||
* Leftover30 Layout Addition ([#20718](https://github.com/qmk/qmk_firmware/pull/20718))
|
||||
* Matrix Cain RE Touch-Up ([#20719](https://github.com/qmk/qmk_firmware/pull/20719))
|
||||
* Matrix Lab 8XV1.2 OG Layout Updates ([#20720](https://github.com/qmk/qmk_firmware/pull/20720))
|
||||
* Mechlovin Studio Hex6C Layout Additions ([#20722](https://github.com/qmk/qmk_firmware/pull/20722))
|
||||
* Mechlovin.Studio Rogue87 Rev.1 Layout Additions ([#20724](https://github.com/qmk/qmk_firmware/pull/20724))
|
||||
* Mechlovin.Studio Rouge87 Rev.1 Layout Additions ([#20725](https://github.com/qmk/qmk_firmware/pull/20725))
|
||||
* Mechlovin.Studio infinity87 Rev.1 Layout Additions ([#20726](https://github.com/qmk/qmk_firmware/pull/20726))
|
||||
* Mechlovin.Studio Infinity87 RGB Rev1 Layout Additions ([#20727](https://github.com/qmk/qmk_firmware/pull/20727))
|
||||
* Mechlovin9 Layout Addition ([#20728](https://github.com/qmk/qmk_firmware/pull/20728))
|
||||
* 1upkeyboards/pi50 WS2812_DI_PIN patch for develop ([#20731](https://github.com/qmk/qmk_firmware/pull/20731))
|
||||
* Mechlovin.Studio Infinity87 Rev.2 Layout Additions ([#20735](https://github.com/qmk/qmk_firmware/pull/20735))
|
||||
* Mechlovin.Studio Olly JF Layout Additions ([#20736](https://github.com/qmk/qmk_firmware/pull/20736))
|
||||
* Mechlovin Studio Serratus Layout Additions ([#20737](https://github.com/qmk/qmk_firmware/pull/20737))
|
||||
* MechWild Mercutio Layout Addition ([#20738](https://github.com/qmk/qmk_firmware/pull/20738))
|
||||
* MisterKnife Knife66 ISO Layout Addition ([#20739](https://github.com/qmk/qmk_firmware/pull/20739))
|
||||
* MNK1800s Layout Addition ([#20740](https://github.com/qmk/qmk_firmware/pull/20740))
|
||||
* MNK75 Layout Additions ([#20741](https://github.com/qmk/qmk_firmware/pull/20741))
|
||||
* Mode SixtyFive S Layout Additions ([#20742](https://github.com/qmk/qmk_firmware/pull/20742))
|
||||
* Mode SeventyFive H Layout Addition ([#20743](https://github.com/qmk/qmk_firmware/pull/20743))
|
||||
* Monstargear XO87 Soldered Layout Additions ([#20744](https://github.com/qmk/qmk_firmware/pull/20744))
|
||||
* MTBKeys MTB60 Solder Layout Additions ([#20745](https://github.com/qmk/qmk_firmware/pull/20745))
|
||||
* Nix Keyboards Day Off 60 Touch-Up and Layout Additions ([#20746](https://github.com/qmk/qmk_firmware/pull/20746))
|
||||
* Kastenwagen 1840 Layout Addition ([#20747](https://github.com/qmk/qmk_firmware/pull/20747))
|
||||
* Kastenwagen 48 Layout Addition ([#20748](https://github.com/qmk/qmk_firmware/pull/20748))
|
||||
* NovelKeys NK87 Touch-Up ([#20749](https://github.com/qmk/qmk_firmware/pull/20749))
|
||||
* NovelKeys NK87B Touch-Up ([#20750](https://github.com/qmk/qmk_firmware/pull/20750))
|
||||
* Noxary 378 Layout Addition ([#20751](https://github.com/qmk/qmk_firmware/pull/20751))
|
||||
* Noxary Valhalla Layout Addition ([#20752](https://github.com/qmk/qmk_firmware/pull/20752))
|
||||
* Nightly Boards/DeskDaily Daily60 Layout Additions ([#20753](https://github.com/qmk/qmk_firmware/pull/20753))
|
||||
* Odelia Touch-Up ([#20754](https://github.com/qmk/qmk_firmware/pull/20754))
|
||||
* One Key Co Dango40 Touch-Up and Layout Addition ([#20755](https://github.com/qmk/qmk_firmware/pull/20755))
|
||||
* P3D Glitch Layout Addition ([#20763](https://github.com/qmk/qmk_firmware/pull/20763))
|
||||
* Pearl Boards Pandora Layout Additions ([#20764](https://github.com/qmk/qmk_firmware/pull/20764))
|
||||
* Pearl Boards Pearl Layout Addition ([#20765](https://github.com/qmk/qmk_firmware/pull/20765))
|
||||
* support boards with APM32 instead of the STM32 ([#20770](https://github.com/qmk/qmk_firmware/pull/20770))
|
||||
* Pearl Boards Zeus Layout Additions ([#20773](https://github.com/qmk/qmk_firmware/pull/20773))
|
||||
* Peej Rosaline Staggered Layout Additions ([#20774](https://github.com/qmk/qmk_firmware/pull/20774))
|
||||
* plywrks Lune Layout Touch-Up ([#20775](https://github.com/qmk/qmk_firmware/pull/20775))
|
||||
* Project Keyboard Signature65 Layout Additions ([#20776](https://github.com/qmk/qmk_firmware/pull/20776))
|
||||
* protoTypist Allison Layout Additions ([#20777](https://github.com/qmk/qmk_firmware/pull/20777))
|
||||
* Prototypist J-01 Rev1 Layout Additions ([#20778](https://github.com/qmk/qmk_firmware/pull/20778))
|
||||
* Protozoa Cassini Layout Additions ([#20779](https://github.com/qmk/qmk_firmware/pull/20779))
|
||||
* Protozoa P.01 Layout Additions ([#20781](https://github.com/qmk/qmk_firmware/pull/20781))
|
||||
* QwertleKeys Calice Layout Addition ([#20782](https://github.com/qmk/qmk_firmware/pull/20782))
|
||||
* Ramlord WITF Layout Touch-Up and Addition ([#20783](https://github.com/qmk/qmk_firmware/pull/20783))
|
||||
* Rart45: rename LAYOUT_all to LAYOUT ([#20784](https://github.com/qmk/qmk_firmware/pull/20784))
|
||||
* Rart60 Layout Additions ([#20785](https://github.com/qmk/qmk_firmware/pull/20785))
|
||||
* Rart67 Layout Additions ([#20786](https://github.com/qmk/qmk_firmware/pull/20786))
|
||||
* Rart67M: rename LAYOUT_all to LAYOUT ([#20787](https://github.com/qmk/qmk_firmware/pull/20787))
|
||||
* RART75 Layout Additions ([#20788](https://github.com/qmk/qmk_firmware/pull/20788))
|
||||
* RART75 Hotswap Layout Additions ([#20789](https://github.com/qmk/qmk_firmware/pull/20789))
|
||||
* RART75M: rename LAYOUT_all to LAYOUT ([#20790](https://github.com/qmk/qmk_firmware/pull/20790))
|
||||
* RART80 Hotswap Layout Additions ([#20791](https://github.com/qmk/qmk_firmware/pull/20791))
|
||||
* Rartand Layout Additions ([#20799](https://github.com/qmk/qmk_firmware/pull/20799))
|
||||
* Rartlice: rename LAYOUT_all to LAYOUT ([#20800](https://github.com/qmk/qmk_firmware/pull/20800))
|
||||
* Ratio65 Hotswap: rename LAYOUT_all to LAYOUT_65_ansi_blocker ([#20801](https://github.com/qmk/qmk_firmware/pull/20801))
|
||||
* Ratio65 Solder Layout Additions ([#20802](https://github.com/qmk/qmk_firmware/pull/20802))
|
||||
* Specifying the default board file is redundant ([#20807](https://github.com/qmk/qmk_firmware/pull/20807))
|
||||
* RGBKB Pan Layout Additions ([#20809](https://github.com/qmk/qmk_firmware/pull/20809))
|
||||
* saevus cor Layout Additions ([#20810](https://github.com/qmk/qmk_firmware/pull/20810))
|
||||
* Clean up trailing commas from info.json ([#20812](https://github.com/qmk/qmk_firmware/pull/20812))
|
||||
* Enable LTO on salicylic acid 7skb to reduce size ([#20813](https://github.com/qmk/qmk_firmware/pull/20813))
|
||||
* Reduce compiled size for mt64rgb's via keymap ([#20814](https://github.com/qmk/qmk_firmware/pull/20814))
|
||||
* Reduce compiled size for prototypist oceanographer's via keymap ([#20816](https://github.com/qmk/qmk_firmware/pull/20816))
|
||||
* Sauce Mild Layout Additions ([#20818](https://github.com/qmk/qmk_firmware/pull/20818))
|
||||
* VCL x SawnsProjects VCL65 Layout Additions ([#20819](https://github.com/qmk/qmk_firmware/pull/20819))
|
||||
* senselessclay had60 Layout Additions ([#20820](https://github.com/qmk/qmk_firmware/pull/20820))
|
||||
* Space Holdings Nebula12B ([#20821](https://github.com/qmk/qmk_firmware/pull/20821))
|
||||
* SmithRune Iron180 Layout Additions ([#20822](https://github.com/qmk/qmk_firmware/pull/20822))
|
||||
* Stello65 Beta Layout Additions and Clean-Up ([#20824](https://github.com/qmk/qmk_firmware/pull/20824))
|
||||
* Studio Kestra Nue Layout Additions ([#20825](https://github.com/qmk/qmk_firmware/pull/20825))
|
||||
* Switchplate Peripherals 910 Layout Additions ([#20827](https://github.com/qmk/qmk_firmware/pull/20827))
|
||||
* TKC California Layout Addition and Touch-Up ([#20829](https://github.com/qmk/qmk_firmware/pull/20829))
|
||||
* TKC M0lly Layout Additions ([#20830](https://github.com/qmk/qmk_firmware/pull/20830))
|
||||
* TKC TKL A/B87 Layout Additions ([#20831](https://github.com/qmk/qmk_firmware/pull/20831))
|
||||
* Viendi 8L Layout Additions ([#20832](https://github.com/qmk/qmk_firmware/pull/20832))
|
||||
* Viktus Smolka Layout Additions ([#20833](https://github.com/qmk/qmk_firmware/pull/20833))
|
||||
* Viktus SP111 Layout Additions ([#20834](https://github.com/qmk/qmk_firmware/pull/20834))
|
||||
* Viktus SP_Mini Layout Additions ([#20835](https://github.com/qmk/qmk_firmware/pull/20835))
|
||||
* W1-AT Layout Additions ([#20842](https://github.com/qmk/qmk_firmware/pull/20842))
|
||||
* Weirdo Geminate60 Layout Additions ([#20843](https://github.com/qmk/qmk_firmware/pull/20843))
|
||||
* Cypher rev5 Layout Additions ([#20844](https://github.com/qmk/qmk_firmware/pull/20844))
|
||||
* Prophet Layout Additions ([#20845](https://github.com/qmk/qmk_firmware/pull/20845))
|
||||
* Tidy up encoder_map directions ([#20847](https://github.com/qmk/qmk_firmware/pull/20847))
|
||||
* Rama Works Koyu Community Layout Support ([#20848](https://github.com/qmk/qmk_firmware/pull/20848))
|
||||
* Rama Works M65-B Community Layout Support ([#20850](https://github.com/qmk/qmk_firmware/pull/20850))
|
||||
* Rama Works M65-BX Community Layout Support ([#20851](https://github.com/qmk/qmk_firmware/pull/20851))
|
||||
* Rama Works U80-A Community Layout Support ([#20853](https://github.com/qmk/qmk_firmware/pull/20853))
|
||||
* Wilba Tech WT60-B Community Layout Support ([#20854](https://github.com/qmk/qmk_firmware/pull/20854))
|
||||
* Wilba Tech WT60-BX Layout Additions and Touch-Up ([#20855](https://github.com/qmk/qmk_firmware/pull/20855))
|
||||
* Wilba Tech WT60-C Community Layout Support ([#20858](https://github.com/qmk/qmk_firmware/pull/20858))
|
||||
* Wilba Tech WT60-D Layout Addition and Touch-Up ([#20859](https://github.com/qmk/qmk_firmware/pull/20859))
|
||||
* Wilba Tech WT60-G Community Layout Support ([#20860](https://github.com/qmk/qmk_firmware/pull/20860))
|
||||
* Wilba Tech WT60-G2 Community Layout Support ([#20861](https://github.com/qmk/qmk_firmware/pull/20861))
|
||||
* Wilba Tech WT60-H2: rename LAYOUT_all to LAYOUT_60_ansi_tsangan_split_rshift ([#20864](https://github.com/qmk/qmk_firmware/pull/20864))
|
||||
* Wilba Tech WT60-XT Layout Additions and Touch-Up ([#20865](https://github.com/qmk/qmk_firmware/pull/20865))
|
||||
* Wilba Tech WT65-A Community Layout Support and Touch-Up ([#20866](https://github.com/qmk/qmk_firmware/pull/20866))
|
||||
* Wilba Tech WT65-B Layout Addition and Touch-Up ([#20867](https://github.com/qmk/qmk_firmware/pull/20867))
|
||||
* Wilba Tech WT65-F Community Layout Support and Touch-Up ([#20869](https://github.com/qmk/qmk_firmware/pull/20869))
|
||||
* Wilba Tech WT65-FX Community Layout Support ([#20870](https://github.com/qmk/qmk_firmware/pull/20870))
|
||||
* Wilba Tech WT65-G Layout Additions and Touch-Up ([#20871](https://github.com/qmk/qmk_firmware/pull/20871))
|
||||
* Wilba Tech WT65-G2 Layout Additions and Touch-Up ([#20872](https://github.com/qmk/qmk_firmware/pull/20872))
|
||||
* Wilba Tech WT65-XT: rename LAYOUT_all to LAYOUT_65_xt_ansi_blocker_tsangan ([#20873](https://github.com/qmk/qmk_firmware/pull/20873))
|
||||
* Wilba Tech WT65-XTX Layout Additions and Touch-Up ([#20874](https://github.com/qmk/qmk_firmware/pull/20874))
|
||||
* Wilba Tech WT69-A Layout Addition and Touch-Up ([#20875](https://github.com/qmk/qmk_firmware/pull/20875))
|
||||
* Wilba Tech WT70-JB Layout Addition and Touch-Up ([#20876](https://github.com/qmk/qmk_firmware/pull/20876))
|
||||
* Wilba Tech WT75-A Layout Additions and Touch-Up ([#20877](https://github.com/qmk/qmk_firmware/pull/20877))
|
||||
* Wilba Tech WT75-B Layout Additions and Touch-Up ([#20878](https://github.com/qmk/qmk_firmware/pull/20878))
|
||||
* Wilba Tech WT75-C Layout Additions and Touch-Up ([#20879](https://github.com/qmk/qmk_firmware/pull/20879))
|
||||
* Wilba Tech WT80-G Layout Additions and Touch-Up ([#20880](https://github.com/qmk/qmk_firmware/pull/20880))
|
||||
* WinKeys Mini Winni: rename LAYOUT_all to LAYOUT_ortho_2x4 ([#20881](https://github.com/qmk/qmk_firmware/pull/20881))
|
||||
* Scarlet Bandana Layout Additions ([#20882](https://github.com/qmk/qmk_firmware/pull/20882))
|
||||
* Winkeyless B87 Community Layout Support ([#20884](https://github.com/qmk/qmk_firmware/pull/20884))
|
||||
* Xelus AkiS Layout Additions ([#20885](https://github.com/qmk/qmk_firmware/pull/20885))
|
||||
* Xelus Dharma Layout Additions ([#20886](https://github.com/qmk/qmk_firmware/pull/20886))
|
||||
* Xelus Kangaroo Layout Additions ([#20887](https://github.com/qmk/qmk_firmware/pull/20887))
|
||||
* Xelus La+ Layout Addition ([#20888](https://github.com/qmk/qmk_firmware/pull/20888))
|
||||
* Xelus Pachi Mini 32U4 Community Layout Support ([#20889](https://github.com/qmk/qmk_firmware/pull/20889))
|
||||
* Xelus Pachi rev1 Community Layout Support ([#20891](https://github.com/qmk/qmk_firmware/pull/20891))
|
||||
* Xelus Trinity XT TKL Layout Additions ([#20892](https://github.com/qmk/qmk_firmware/pull/20892))
|
||||
* Xelus Valor FRL TKL Layout Additions ([#20893](https://github.com/qmk/qmk_firmware/pull/20893))
|
||||
* YDKB Chili Community Layout Support ([#20895](https://github.com/qmk/qmk_firmware/pull/20895))
|
||||
* YDKB Grape Layout Additions ([#20899](https://github.com/qmk/qmk_firmware/pull/20899))
|
||||
* YMDK Wings Layout Addition ([#20900](https://github.com/qmk/qmk_firmware/pull/20900))
|
||||
* YMDK Wings Hotswap: rename LAYOUT_all to LAYOUT ([#20901](https://github.com/qmk/qmk_firmware/pull/20901))
|
||||
* YMDK YM68 Community Layout Support ([#20906](https://github.com/qmk/qmk_firmware/pull/20906))
|
||||
* Yugo-M Controller Layout Additions ([#20907](https://github.com/qmk/qmk_firmware/pull/20907))
|
||||
* Zicodia TKLFRLNRLMLAO Layout Addition ([#20908](https://github.com/qmk/qmk_firmware/pull/20908))
|
||||
* ZTBoards After Layout Addition ([#20912](https://github.com/qmk/qmk_firmware/pull/20912))
|
||||
* ZTBoards Noon Layout Addition ([#20913](https://github.com/qmk/qmk_firmware/pull/20913))
|
||||
* SawnsProjects Amber80 Solder Community Layout Support ([#20917](https://github.com/qmk/qmk_firmware/pull/20917))
|
||||
* Pearl Boards Atlas Layout Additions ([#20918](https://github.com/qmk/qmk_firmware/pull/20918))
|
||||
* Xiudi XD004: rename LAYOUT_all to LAYOUT_ortho_1x4 ([#20919](https://github.com/qmk/qmk_firmware/pull/20919))
|
||||
* Wilba Tech WT80-BC Community Layout Support ([#20920](https://github.com/qmk/qmk_firmware/pull/20920))
|
||||
* 4pplet Eagle Viper REP Rev B Community Layout Support ([#20921](https://github.com/qmk/qmk_firmware/pull/20921))
|
||||
* FR4Boards unix60 Layout Additions ([#20926](https://github.com/qmk/qmk_firmware/pull/20926))
|
||||
* MC-76K: rename LAYOUT_all to LAYOUT ([#20927](https://github.com/qmk/qmk_firmware/pull/20927))
|
||||
* Mechlovin Studio Jay60 Community Layout Support ([#20928](https://github.com/qmk/qmk_firmware/pull/20928))
|
||||
* MisterKnife Knife66 Layout Additions ([#20929](https://github.com/qmk/qmk_firmware/pull/20929))
|
||||
* MisterKnife Knife66 ISO Layout Additions II ([#20930](https://github.com/qmk/qmk_firmware/pull/20930))
|
||||
* 4pplet Waffling80 Community Layout Support and Touch-Up ([#20932](https://github.com/qmk/qmk_firmware/pull/20932))
|
||||
* Acheron Elongate Delta: rename LAYOUT_all to LAYOUT ([#20956](https://github.com/qmk/qmk_firmware/pull/20956))
|
||||
* ADPenrose Akemipad Layout Addition ([#20957](https://github.com/qmk/qmk_firmware/pull/20957))
|
||||
* ADPenrose Shisaku: rename LAYOUT_all to LAYOUT ([#20958](https://github.com/qmk/qmk_firmware/pull/20958))
|
||||
* AEBoards Aegis Layout Additions ([#20960](https://github.com/qmk/qmk_firmware/pull/20960))
|
||||
* rart/rart80:via: restore rules.mk after #20334 ([#21002](https://github.com/qmk/qmk_firmware/pull/21002))
|
||||
* Remove HHKB RN42 code ([#21007](https://github.com/qmk/qmk_firmware/pull/21007))
|
||||
* Move `thekey` to Drop vendor folder ([#21032](https://github.com/qmk/qmk_firmware/pull/21032))
|
||||
|
||||
Keyboard fixes:
|
||||
* userspace/community layout fixes ([#19998](https://github.com/qmk/qmk_firmware/pull/19998))
|
||||
* Fix layout macro keys with no matrix position ([#20033](https://github.com/qmk/qmk_firmware/pull/20033))
|
||||
* Restore matrix pins for ep/40 ([#20083](https://github.com/qmk/qmk_firmware/pull/20083))
|
||||
* kbdfans/tiger80: remove duplicate keys in info.json ([#20148](https://github.com/qmk/qmk_firmware/pull/20148))
|
||||
* Fixup z70ultra — replace mis-removed file ([#20157](https://github.com/qmk/qmk_firmware/pull/20157))
|
||||
* Fixup CI build for F103C6 onekey. ([#20188](https://github.com/qmk/qmk_firmware/pull/20188))
|
||||
* Fix layouts containing keys with multiple matrix positions ([#20191](https://github.com/qmk/qmk_firmware/pull/20191))
|
||||
* Fix some more missing `#pragma once`s ([#20241](https://github.com/qmk/qmk_firmware/pull/20241))
|
||||
* Fixup CI build for `nack`. ([#20292](https://github.com/qmk/qmk_firmware/pull/20292))
|
||||
* Fixup Pointing device functions ([#20311](https://github.com/qmk/qmk_firmware/pull/20311))
|
||||
* Fix a handful of CLI errors ([#20321](https://github.com/qmk/qmk_firmware/pull/20321))
|
||||
* Fix API errors ([#20326](https://github.com/qmk/qmk_firmware/pull/20326))
|
||||
* Set up DEFAULT_FOLDER for primekb/meridian ([#20367](https://github.com/qmk/qmk_firmware/pull/20367))
|
||||
* Fix up via keymap builds. ([#20383](https://github.com/qmk/qmk_firmware/pull/20383))
|
||||
* Fix up via keymap builds. ([#20397](https://github.com/qmk/qmk_firmware/pull/20397))
|
||||
* Fix some missing QMK_KEYBOARD_H includes in user keymaps ([#20417](https://github.com/qmk/qmk_firmware/pull/20417))
|
||||
* Update ymdk/id75 config ([#20432](https://github.com/qmk/qmk_firmware/pull/20432))
|
||||
* Fix info.json LTO and format encoder definitions ([#20456](https://github.com/qmk/qmk_firmware/pull/20456))
|
||||
* Fixup dymium65 RGB Pin on develop ([#20473](https://github.com/qmk/qmk_firmware/pull/20473))
|
||||
* Fixup missing include in mxss `via` keymap ([#20475](https://github.com/qmk/qmk_firmware/pull/20475))
|
||||
* Fix nk plus ws2812 config ([#20524](https://github.com/qmk/qmk_firmware/pull/20524))
|
||||
* cannonkeys/ellipse_hs: correct layout macro references ([#20577](https://github.com/qmk/qmk_firmware/pull/20577))
|
||||
* Remove use of layout macros for `music_map` ([#20634](https://github.com/qmk/qmk_firmware/pull/20634))
|
||||
* Vertex/angle65 WS2812 pin fix ([#20653](https://github.com/qmk/qmk_firmware/pull/20653))
|
||||
* Fix ws2812 pin for phantagom boards ([#20670](https://github.com/qmk/qmk_firmware/pull/20670))
|
||||
* Fixup 1upkeyboards/pi50 ([#20733](https://github.com/qmk/qmk_firmware/pull/20733))
|
||||
* Fix `test_json2c_no_json()` ([#20756](https://github.com/qmk/qmk_firmware/pull/20756))
|
||||
* Fix mxss rgblight.c compilation issues ([#20804](https://github.com/qmk/qmk_firmware/pull/20804))
|
||||
* Fixup paladin64 ([#20805](https://github.com/qmk/qmk_firmware/pull/20805))
|
||||
* Fixup dogtag ([#20808](https://github.com/qmk/qmk_firmware/pull/20808))
|
||||
* Fixup zwag75 ([#20923](https://github.com/qmk/qmk_firmware/pull/20923))
|
||||
* Fixup latinpadble ([#20924](https://github.com/qmk/qmk_firmware/pull/20924))
|
||||
* Add missing layout data for a handful of boards ([#20931](https://github.com/qmk/qmk_firmware/pull/20931))
|
||||
* Fixup evo70 ([#20949](https://github.com/qmk/qmk_firmware/pull/20949))
|
||||
* Fixup Crkbd default keymap ([#20962](https://github.com/qmk/qmk_firmware/pull/20962))
|
||||
* Fix key display on Corne OLED ([#21044](https://github.com/qmk/qmk_firmware/pull/21044))
|
||||
|
||||
Others:
|
||||
* Add layer-cycle example ([#19069](https://github.com/qmk/qmk_firmware/pull/19069))
|
||||
* Remove remnants of Vagrant. ([#20000](https://github.com/qmk/qmk_firmware/pull/20000))
|
||||
* Develop cleanup IS31FL3736 docs ([#20633](https://github.com/qmk/qmk_firmware/pull/20633))
|
||||
* Organise config/rules <-> info mappings ([#20723](https://github.com/qmk/qmk_firmware/pull/20723))
|
||||
* Add a change log for PR20584 ([#20998](https://github.com/qmk/qmk_firmware/pull/20998))
|
||||
|
||||
Bugs:
|
||||
* Strip whitespace from CONVERT_TO variables ([#19948](https://github.com/qmk/qmk_firmware/pull/19948))
|
||||
* Check all rows have the correct number of columns when parsing `g_led_config` ([#19954](https://github.com/qmk/qmk_firmware/pull/19954))
|
||||
* Fix OSMs getting stuck ([#20034](https://github.com/qmk/qmk_firmware/pull/20034))
|
||||
* Fix rgblight layers when animations aren't enabled ([#20097](https://github.com/qmk/qmk_firmware/pull/20097))
|
||||
* Fixed split keyboard issue where custom LED indicators could activate incorrect LEDs (#20203) ([#20204](https://github.com/qmk/qmk_firmware/pull/20204))
|
||||
* Reduce _validate complexity ([#20274](https://github.com/qmk/qmk_firmware/pull/20274))
|
||||
* `qmk info`: account for ISO enter when calculating layout X offset ([#20325](https://github.com/qmk/qmk_firmware/pull/20325))
|
||||
* Disable specific warnings to mitigate compilation problems with `KEEP_INTERMEDIATES=yes`. ([#20339](https://github.com/qmk/qmk_firmware/pull/20339))
|
||||
* Fix compilation issue with Swap Hands and Encoder Map ([#20348](https://github.com/qmk/qmk_firmware/pull/20348))
|
||||
* Fix preprocessor condition for SPLIT_HAPTIC_ENABLE ([#20411](https://github.com/qmk/qmk_firmware/pull/20411))
|
||||
* Fix compilation issues with PS/2 driver on F4x1 controllers ([#20433](https://github.com/qmk/qmk_firmware/pull/20433))
|
||||
* Fix capital letters not getting sent with sendstring_swiss_fr.h ([#20515](https://github.com/qmk/qmk_firmware/pull/20515))
|
||||
* Duplicate board files for blok converter ([#20629](https://github.com/qmk/qmk_firmware/pull/20629))
|
||||
* Fix Mod-Tap combo regression ([#20669](https://github.com/qmk/qmk_firmware/pull/20669))
|
||||
* Revert use of legacy wear leveling driver now ChibiOS is fixed ([#20806](https://github.com/qmk/qmk_firmware/pull/20806))
|
||||
* Fix compilation error introduced by #20669 ([#20849](https://github.com/qmk/qmk_firmware/pull/20849))
|
||||
* Fix English word list retrieval in qmk generate-autocorrect-data ([#20915](https://github.com/qmk/qmk_firmware/pull/20915))
|
||||
* Improve keymap folder resolution ([#20981](https://github.com/qmk/qmk_firmware/pull/20981))
|
||||
* Fix issue with Repeat Key-Combo test ([#21005](https://github.com/qmk/qmk_firmware/pull/21005))
|
||||
* `qmk info` - Remove printing of "Keyboard Folder" ([#21033](https://github.com/qmk/qmk_firmware/pull/21033))
|
||||
+1
-1
@@ -41,6 +41,7 @@
|
||||
* [Keymap Overview](keymap.md)
|
||||
* Development Environments
|
||||
* [Docker Guide](getting_started_docker.md)
|
||||
* [Vagrant Guide](getting_started_vagrant.md)
|
||||
* Flashing
|
||||
* [Flashing](flashing.md)
|
||||
* [Flashing ATmega32A (ps2avrgb)](flashing_bootloadhid.md)
|
||||
@@ -70,7 +71,6 @@
|
||||
* [Macros](feature_macros.md)
|
||||
* [Mouse Keys](feature_mouse_keys.md)
|
||||
* [Programmable Button](feature_programmable_button.md)
|
||||
* [Repeat Key](feature_repeat_key.md)
|
||||
* [Space Cadet Shift](feature_space_cadet.md)
|
||||
* [US ANSI Shifted Keys](keycodes_us_ansi_shifted.md)
|
||||
|
||||
|
||||
+13
-11
@@ -10,25 +10,27 @@ Practically, this means QMK merges the `develop` branch into the `master` branch
|
||||
|
||||
## What has been included in past Breaking Changes?
|
||||
|
||||
* [2023 May 28](ChangeLog/20230528.md)
|
||||
* [2023 Feb 26](ChangeLog/20230226.md)
|
||||
* [2022 Nov 26](ChangeLog/20221126.md)
|
||||
* [2022 Aug 27](ChangeLog/20220827.md)
|
||||
* [2022 May 28](ChangeLog/20220528.md)
|
||||
* [2022 Feb 26](ChangeLog/20220226.md)
|
||||
* [Older Breaking Changes](breaking_changes_history.md)
|
||||
|
||||
## When is the next Breaking Change?
|
||||
|
||||
The next Breaking Change is scheduled for August 27, 2023.
|
||||
The next Breaking Change is scheduled for May 28, 2023.
|
||||
|
||||
### Important Dates
|
||||
|
||||
* 2023 May 28 - `develop` is tagged with a new release version. Each push to `master` is subsequently merged to `develop` by GitHub actions.
|
||||
* 2023 Jul 30 - `develop` closed to new PRs.
|
||||
* 2023 Jul 30 - Call for testers.
|
||||
* 2023 Aug 13 - Last day for merges -- after this point `develop` is locked for testing and accepts only bugfixes
|
||||
* 2023 Aug 20 - `develop` is locked, only critical bugfix PRs merged.
|
||||
* 2023 Aug 25 - `master` is locked, no PRs merged.
|
||||
* 2023 Aug 27 - Merge `develop` to `master`.
|
||||
* 2023 Aug 27 - `master` is unlocked. PRs can be merged again.
|
||||
* 2023 Feb 26 - `develop` is tagged with a new release version. Each push to `master` is subsequently merged to `develop` by GitHub actions.
|
||||
* 2023 Apr 30 - `develop` closed to new PRs.
|
||||
* 2023 Apr 30 - Call for testers.
|
||||
* 2023 May 14 - Last day for merges -- after this point `develop` is locked for testing and accepts only bugfixes
|
||||
* 2023 May 21 - `develop` is locked, only critical bugfix PRs merged.
|
||||
* 2023 May 26 - `master` is locked, no PRs merged.
|
||||
* 2023 May 28 - Merge `develop` to `master`.
|
||||
* 2023 May 28 - `master` is unlocked. PRs can be merged again.
|
||||
|
||||
## What changes will be included?
|
||||
|
||||
@@ -48,7 +50,7 @@ Criteria for acceptance:
|
||||
|
||||
Strongly suggested:
|
||||
|
||||
* The PR has a ChangeLog file describing the changes under `<qmk_firmware>/docs/Changelog/20230827`.
|
||||
* The PR has a ChangeLog file describing the changes under `<qmk_firmware>/docs/Changelog/20221126`.
|
||||
* This should be in Markdown format, with a name in the format `PR12345.md`, substituting the digits for your PRs ID.
|
||||
* One strong recommendation that the ChangeLog document matches the PR description on GitHub, so as to ensure traceability.
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
This page links to all previous changelogs from the QMK Breaking Changes process.
|
||||
|
||||
* [2023 May 28](ChangeLog/20230528.md) - version 0.21.0
|
||||
* [2023 Feb 26](ChangeLog/20230226.md) - version 0.20.0
|
||||
* [2022 Nov 26](ChangeLog/20221126.md) - version 0.19.0
|
||||
* [2022 Aug 27](ChangeLog/20220827.md) - version 0.18.0
|
||||
|
||||
@@ -23,6 +23,14 @@ If it is determined that your submission is a breaking change, there are a few t
|
||||
|
||||
If you are contributing core code, and the only reason it needs to go through breaking changes is that you are updating keymaps to match your change, consider whether you can submit your feature in a way that the old keymaps continue to work. Then submit a separate PR that goes through the breaking changes process to remove the old code.
|
||||
|
||||
### Contribute a ChangeLog Entry
|
||||
|
||||
We require submissions that go through the Breaking Change process to include a changelog entry. The entry should be a short summary of the changes your pull request makes – [each section here started as a changelog](ChangeLog/20190830.md "n.b. This should link to the 2019 Aug 30 Breaking Changes doc - @noroadsleft").
|
||||
|
||||
Your changelog should be located at `docs/ChangeLog/YYYYMMDD/PR####.md`, where `YYYYMMDD` is the date on which QMK's breaking change branch – usually named `develop` – will be merged into the `master` branch, and `####` is the number of your pull request.
|
||||
|
||||
If your submission requires action on the part of users, your changelog should instruct users what action(s) must be taken, or link to a location that does so.
|
||||
|
||||
### Document Your Changes
|
||||
|
||||
Understanding the purpose for your submission, and possible implications or actions it will require can make the review process more straightforward. A changelog may suffice for this purpose, but more extensive changes may require a level of detail that is ill-suited for a changelog.
|
||||
|
||||
+2
-17
@@ -165,31 +165,16 @@ qmk find -f 'processor=STM32F411'
|
||||
qmk find -f 'processor=STM32F411' -f 'features.rgb_matrix=true'
|
||||
```
|
||||
|
||||
The following filter expressions are also supported:
|
||||
|
||||
- `exists(key)`: Match targets where `key` is present.
|
||||
- `absent(key)`: Match targets where `key` is not present.
|
||||
- `contains(key, value)`: Match targets where `key` contains `value`. Can be used for strings, arrays and object keys.
|
||||
- `length(key, value)`: Match targets where the length of `key` is `value`. Can be used for strings, arrays and objects.
|
||||
|
||||
You can also list arbitrary values for each matched target with `--print`:
|
||||
|
||||
```
|
||||
qmk find -f 'processor=STM32F411' -p 'keyboard_name' -p 'features.rgb_matrix'
|
||||
```
|
||||
|
||||
**Usage**:
|
||||
|
||||
```
|
||||
qmk find [-h] [-km KEYMAP] [-p PRINT] [-f FILTER]
|
||||
qmk find [-h] [-km KEYMAP] [-f FILTER]
|
||||
|
||||
options:
|
||||
-km KEYMAP, --keymap KEYMAP
|
||||
The keymap name to build. Default is 'default'.
|
||||
-p PRINT, --print PRINT
|
||||
For each matched target, print the value of the supplied info.json key. May be passed multiple times.
|
||||
-f FILTER, --filter FILTER
|
||||
Filter the list of keyboards based on their info.json data. Accepts the formats key=value, function(key), or function(key,value), eg. 'features.rgblight=true'. Valid functions are 'absent', 'contains', 'exists' and 'length'. May be passed multiple times; all filters need to match. Value may include wildcards such as '*' and '?'.
|
||||
Filter the list of keyboards based on the supplied value in rules.mk. Matches info.json structure, and accepts the formats 'features.rgblight=true' or 'exists(matrix_pins.direct)'. May be passed multiple times, all filters need to match. Value may include wildcards such as '*' and '?'.
|
||||
```
|
||||
|
||||
## `qmk console`
|
||||
|
||||
@@ -150,7 +150,7 @@ If you define these options you will enable the associated feature, which may in
|
||||
* `#define TAPPING_TERM_PER_KEY`
|
||||
* enables handling for per key `TAPPING_TERM` settings
|
||||
* `#define RETRO_TAPPING`
|
||||
* tap anyway, even after `TAPPING_TERM`, if there was no other key interruption between press and release
|
||||
* tap anyway, even after TAPPING_TERM, if there was no other key interruption between press and release
|
||||
* See [Retro Tapping](tap_hold.md#retro-tapping) for details
|
||||
* `#define RETRO_TAPPING_PER_KEY`
|
||||
* enables handling for per key `RETRO_TAPPING` settings
|
||||
@@ -161,6 +161,9 @@ If you define these options you will enable the associated feature, which may in
|
||||
* See [Permissive Hold](tap_hold.md#permissive-hold) for details
|
||||
* `#define PERMISSIVE_HOLD_PER_KEY`
|
||||
* enabled handling for per key `PERMISSIVE_HOLD` settings
|
||||
* `#define IGNORE_MOD_TAP_INTERRUPT`
|
||||
* makes it possible to do rolling combos (zx) with keys that convert to other keys on hold, by enforcing the `TAPPING_TERM` for both keys.
|
||||
* See [Ignore Mod Tap Interrupt](tap_hold.md#ignore-mod-tap-interrupt) for details
|
||||
* `#define QUICK_TAP_TERM 100`
|
||||
* tap-then-hold timing to use a dual role key to repeat keycode
|
||||
* See [Quick Tap Term](tap_hold.md#quick-tap-term)
|
||||
@@ -186,6 +189,8 @@ If you define these options you will enable the associated feature, which may in
|
||||
* how long before oneshot times out
|
||||
* `#define ONESHOT_TAP_TOGGLE 2`
|
||||
* how many taps before oneshot toggle is triggered
|
||||
* `#define COMBO_COUNT 2`
|
||||
* Set this to the number of combos that you're using in the [Combo](feature_combo.md) feature. Or leave it undefined and programmatically set the count.
|
||||
* `#define COMBO_TERM 200`
|
||||
* how long for the Combo keys to be detected. Defaults to `TAPPING_TERM` if not defined.
|
||||
* `#define COMBO_MUST_HOLD_MODS`
|
||||
@@ -212,7 +217,7 @@ If you define these options you will enable the associated feature, which may in
|
||||
|
||||
## RGB Light Configuration
|
||||
|
||||
* `#define WS2812_DI_PIN D7`
|
||||
* `#define RGB_DI_PIN D7`
|
||||
* pin the DI on the WS2812 is hooked-up to
|
||||
* `#define RGBLIGHT_LAYERS`
|
||||
* Lets you define [lighting layers](feature_rgblight.md?id=lighting-layers) that can be toggled on or off. Great for showing the current keyboard layer or caps lock state.
|
||||
@@ -228,7 +233,7 @@ If you define these options you will enable the associated feature, which may in
|
||||
* `#define RGBLIGHT_SPLIT`
|
||||
* Needed if both halves of the board have RGB LEDs wired directly to the RGB output pin on the controllers instead of passing the output of the left half to the input of the right half
|
||||
* `#define RGBLED_SPLIT { 6, 6 }`
|
||||
* number of LEDs connected that are directly wired to the RGB pin on each half of a split keyboard
|
||||
* number of LEDs connected that are directly wired to `RGB_DI_PIN` on each half of a split keyboard
|
||||
* First value indicates number of LEDs for left half, second value is for the right half
|
||||
* When RGBLED_SPLIT is defined, RGBLIGHT_SPLIT is implicitly defined.
|
||||
* `#define RGBLIGHT_HUE_STEP 12`
|
||||
|
||||
@@ -37,9 +37,9 @@ For more information on bitwise operators in C, click [here](https://en.wikipedi
|
||||
|
||||
In practice, this means that you can check whether a given modifier is active with `get_mods() & MOD_BIT(KC_<modifier>)` (see the [list of modifier keycodes](keycodes_basic.md#modifiers)) or with `get_mods() & MOD_MASK_<modifier>` if the difference between left and right hand modifiers is not important and you want to match both. Same thing can be done for one-shot modifiers if you replace `get_mods()` with `get_oneshot_mods()`.
|
||||
|
||||
To check that *only* a specific set of mods is active at a time, use a simple equality operator: `get_mods() == <mod mask>`.
|
||||
To check that *only* a specific set of mods is active at a time, AND the modifier state and your desired mod mask as explained above and compare the result to the mod mask itself: `get_mods() & <mod mask> == <mod mask>`.
|
||||
|
||||
For example, let's say you want to trigger a piece of custom code if one-shot left control and one-shot left shift are on but every other one-shot mods are off. To do so, you can compose the desired mod mask by combining the mod bits for left control and shift with `(MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT))` and then plug it in: `get_oneshot_mods() == (MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT))`. Using `MOD_MASK_CS` instead for the mod bitmask would have forced you to press four modifier keys (both versions of control and shift) to fulfill the condition.
|
||||
For example, let's say you want to trigger a piece of custom code if one-shot left control and one-shot left shift are on but every other one-shot mods are off. To do so, you can compose the desired mod mask by combining the mod bits for left control and shift with `(MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT))` and then plug it in: `get_oneshot_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT)) == (MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT))`. Using `MOD_MASK_CS` instead for the mod bitmask would have forced you to press four modifier keys (both versions of control and shift) to fulfill the condition.
|
||||
|
||||
The full list of mod masks is as follows:
|
||||
|
||||
@@ -91,7 +91,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
|
||||
case KC_ESC:
|
||||
// Detect the activation of only Left Alt
|
||||
if (get_mods() == MOD_BIT(KC_LALT)) {
|
||||
if ((get_mods() & MOD_BIT(KC_LALT)) == MOD_BIT(KC_LALT)) {
|
||||
if (record->event.pressed) {
|
||||
// No need to register KC_LALT because it's already active.
|
||||
// The Alt modifier will apply on this KC_TAB.
|
||||
@@ -184,4 +184,4 @@ This page used to encompass a large set of features. We have moved many sections
|
||||
|
||||
## Key Overrides :id=key-overrides
|
||||
|
||||
* [Key Overrides](feature_key_overrides.md)
|
||||
* [Key Overrides](feature_key_overrides.md)
|
||||
@@ -90,26 +90,6 @@ by defining `IS_COMMAND()` in config.h:
|
||||
|
||||
## Customizing Caps Word :id=customizing-caps-word
|
||||
|
||||
### Invert on shift :id=invert-on-shift
|
||||
|
||||
By default, Caps Word turns off when Shift keys are pressed, considering them as
|
||||
word-breaking. Alternatively with the `CAPS_WORD_INVERT_ON_SHIFT` option,
|
||||
pressing the Shift key continues Caps Word and inverts the shift state. This
|
||||
is convenient for uncapitalizing one or a few letters within a word, for
|
||||
example with Caps Word on, typing "D, B, Shift+A, Shift+A, S" produces "DBaaS",
|
||||
or typing "P, D, F, Shift+S" produces "PDFs".
|
||||
|
||||
Enable it by adding in config.h
|
||||
|
||||
```c
|
||||
#define CAPS_WORD_INVERT_ON_SHIFT
|
||||
```
|
||||
|
||||
This option works with regular Shift keys `KC_LSFT` and `KC_RSFT`, mod-tap Shift
|
||||
keys, and one-shot Shift keys. Note that while Caps Word is on, one-shot Shift
|
||||
keys behave like regular Shift keys, and have effect only while they are held.
|
||||
|
||||
|
||||
### Idle timeout :id=idle-timeout
|
||||
|
||||
Caps Word turns off automatically if no keys are pressed for
|
||||
|
||||
+29
-6
@@ -4,12 +4,15 @@ The Combo feature is a chording type solution for adding custom actions. It lets
|
||||
|
||||
To enable this feature, you need to add `COMBO_ENABLE = yes` to your `rules.mk`.
|
||||
|
||||
Additionally, in your `config.h`, you'll need to specify the number of combos that you'll be using, by adding `#define COMBO_COUNT 1` (replacing 1 with the number that you're using). It is also possible to not define this and instead set the variable `COMBO_LEN` yourself. There's a trick where we don't need to think about this variable at all. More on this later.
|
||||
|
||||
|
||||
Then, in your `keymap.c` file, you'll need to define a sequence of keys, terminated with `COMBO_END`, and a structure to list the combination of keys, and its resulting action.
|
||||
|
||||
```c
|
||||
const uint16_t PROGMEM test_combo1[] = {KC_A, KC_B, COMBO_END};
|
||||
const uint16_t PROGMEM test_combo2[] = {KC_C, KC_D, COMBO_END};
|
||||
combo_t key_combos[] = {
|
||||
combo_t key_combos[COMBO_COUNT] = {
|
||||
COMBO(test_combo1, KC_ESC),
|
||||
COMBO(test_combo2, LCTL(KC_Z)), // keycodes with modifiers are possible too!
|
||||
};
|
||||
@@ -30,7 +33,7 @@ It is possible to overlap combos. Before, with the example below both combos wou
|
||||
```c
|
||||
const uint16_t PROGMEM test_combo1[] = {LSFT_T(KC_A), LT(1, KC_B), COMBO_END};
|
||||
const uint16_t PROGMEM test_combo2[] = {LSFT_T(KC_A), LT(1, KC_B), KC_C, COMBO_END};
|
||||
combo_t key_combos[] = {
|
||||
combo_t key_combos[COMBO_COUNT] = {
|
||||
COMBO(test_combo1, KC_ESC)
|
||||
COMBO(test_combo2, KC_TAB)
|
||||
};
|
||||
@@ -38,22 +41,24 @@ combo_t key_combos[] = {
|
||||
|
||||
## Examples
|
||||
|
||||
A long list of combos can be defined in an `enum` list:
|
||||
A long list of combos can be defined in an `enum` list that ends with `COMBO_LENGTH` and you can leave `COMBO_COUNT` undefined:
|
||||
|
||||
```c
|
||||
enum combos {
|
||||
AB_ESC,
|
||||
JK_TAB,
|
||||
QW_SFT,
|
||||
SD_LAYER
|
||||
SD_LAYER,
|
||||
COMBO_LENGTH
|
||||
};
|
||||
uint16_t COMBO_LEN = COMBO_LENGTH; // remove the COMBO_COUNT define and use this instead!
|
||||
|
||||
const uint16_t PROGMEM ab_combo[] = {KC_A, KC_B, COMBO_END};
|
||||
const uint16_t PROGMEM jk_combo[] = {KC_J, KC_K, COMBO_END};
|
||||
const uint16_t PROGMEM qw_combo[] = {KC_Q, KC_W, COMBO_END};
|
||||
const uint16_t PROGMEM sd_combo[] = {KC_S, KC_D, COMBO_END};
|
||||
|
||||
combo_t key_combos[] = {
|
||||
combo_t key_combos[COMBO_COUNT] = {
|
||||
[AB_ESC] = COMBO(ab_combo, KC_ESC),
|
||||
[JK_TAB] = COMBO(jk_combo, KC_TAB),
|
||||
[QW_SFT] = COMBO(qw_combo, KC_LSFT),
|
||||
@@ -67,7 +72,9 @@ For a more complicated implementation, you can use the `process_combo_event` fun
|
||||
enum combo_events {
|
||||
EM_EMAIL,
|
||||
BSPC_LSFT_CLEAR,
|
||||
COMBO_LENGTH
|
||||
};
|
||||
uint16_t COMBO_LEN = COMBO_LENGTH; // remove the COMBO_COUNT define and use this instead!
|
||||
|
||||
const uint16_t PROGMEM email_combo[] = {KC_E, KC_M, COMBO_END};
|
||||
const uint16_t PROGMEM clear_line_combo[] = {KC_BSPC, KC_LSFT, COMBO_END};
|
||||
@@ -252,6 +259,18 @@ bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode
|
||||
}
|
||||
```
|
||||
|
||||
### Variable Length Combos
|
||||
If you leave `COMBO_COUNT` undefined in `config.h`, it allows you to programmatically declare the size of the Combo data structure and avoid updating `COMBO_COUNT`. Instead a variable called `COMBO_LEN` has to be set. It can be set with something similar to the following in `keymap.c`: `uint16_t COMBO_LEN = ARRAY_SIZE(key_combos);` or by adding `COMBO_LENGTH` as the *last* entry in the combo enum and then `uint16_t COMBO_LEN = COMBO_LENGTH;` as such:
|
||||
```c
|
||||
enum myCombos {
|
||||
...,
|
||||
COMBO_LENGTH
|
||||
};
|
||||
uint16_t COMBO_LEN = COMBO_LENGTH;
|
||||
```
|
||||
Regardless of the method used to declare `COMBO_LEN`, this also requires to convert the `combo_t key_combos[COMBO_COUNT] = {...};` line to `combo_t key_combos[] = {...};`.
|
||||
|
||||
|
||||
### Combo timer
|
||||
|
||||
Normally, the timer is started on the first key press and then reset on every subsequent key press within the `COMBO_TERM`.
|
||||
@@ -281,8 +300,10 @@ Here's an example where a combo resolves to two modifiers, and on key releases t
|
||||
|
||||
```c
|
||||
enum combos {
|
||||
AB_MODS
|
||||
AB_MODS,
|
||||
COMBO_LENGTH
|
||||
};
|
||||
uint16_t COMBO_LEN = COMBO_LENGTH;
|
||||
|
||||
const uint16_t PROGMEM ab_combo[] = {KC_A, KC_B, COMBO_END};
|
||||
|
||||
@@ -394,4 +415,6 @@ SUBS(TH_THE, "the", KC_T, KC_H) // SUBS uses SEND_STRING to output the give
|
||||
...
|
||||
```
|
||||
|
||||
Now, you can update only one place to add or alter combos. You don't even need to remember to update the `COMBO_COUNT` or the `COMBO_LEN` variables at all. Everything is taken care of. Magic!
|
||||
|
||||
For small to huge ready made dictionaries of combos, you can check out http://combos.gboards.ca/.
|
||||
|
||||
@@ -17,16 +17,15 @@ Currently the following converters are available:
|
||||
| `promicro` | `bit_c_pro` |
|
||||
| `promicro` | `stemcell` |
|
||||
| `promicro` | `bonsai_c4` |
|
||||
| `promicro` | `elite_pi` |
|
||||
| `promicro` | `rp2040_ce` |
|
||||
| `promicro` | `elite_pi` |
|
||||
| `promicro` | `helios` |
|
||||
| `promicro` | `liatris` |
|
||||
| `promicro` | `michi` |
|
||||
| `elite_c` | `stemcell` |
|
||||
| `elite_c` | `rp2040_ce` |
|
||||
| `elite_c` | `elite_pi` |
|
||||
| `elite_c` | `helios` |
|
||||
| `elite_c` | `liatris` |
|
||||
|
||||
See below for more in depth information on each converter.
|
||||
|
||||
@@ -89,7 +88,6 @@ If a board currently supported in QMK uses a [Pro Micro](https://www.sparkfun.co
|
||||
| [customMK Bonsai C4](https://shop.custommk.com/products/bonsai-c4-microcontroller-board) | `bonsai_c4` |
|
||||
| [Elite-Pi](https://keeb.io/products/elite-pi-usb-c-pro-micro-replacement-rp2040) | `elite_pi` |
|
||||
| [0xCB Helios](https://keeb.supply/products/0xcb-helios) | `helios` |
|
||||
| [Liatris](https://splitkb.com/products/liatris) | `liatris` |
|
||||
| [Michi](https://github.com/ci-bus/michi-promicro-rp2040) | `michi` |
|
||||
|
||||
Converter summary:
|
||||
@@ -106,7 +104,6 @@ Converter summary:
|
||||
| `rp2040_ce` | `-e CONVERT_TO=rp2040_ce` | `CONVERT_TO=rp2040_ce` | `#ifdef CONVERT_TO_RP2040_CE` |
|
||||
| `elite_pi` | `-e CONVERT_TO=elite_pi` | `CONVERT_TO=elite_pi` | `#ifdef CONVERT_TO_ELITE_PI` |
|
||||
| `helios` | `-e CONVERT_TO=helios` | `CONVERT_TO=helios` | `#ifdef CONVERT_TO_HELIOS` |
|
||||
| `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` |
|
||||
| `michi` | `-e CONVERT_TO=michi` | `CONVERT_TO=michi` | `#ifdef CONVERT_TO_MICHI` |
|
||||
|
||||
### Proton C :id=proton_c
|
||||
@@ -171,7 +168,7 @@ The Bonsai C4 only has one on-board LED (B2), and by default, both the Pro Micro
|
||||
#define B0 PAL_LINE(GPIOA, 9)
|
||||
```
|
||||
|
||||
### RP2040 Community Edition - Elite-Pi, Helios, and Liatris :id=rp2040_ce
|
||||
### RP2040 Community Edition - Elite-Pi and Helios :id=rp2040_ce
|
||||
|
||||
Feature set currently identical to [Adafruit KB2040](#kb2040).
|
||||
|
||||
@@ -188,7 +185,6 @@ If a board currently supported in QMK uses an [Elite-C](https://keeb.io/products
|
||||
| [STeMCell](https://github.com/megamind4089/STeMCell) | `stemcell` |
|
||||
| [Elite-Pi](https://keeb.io/products/elite-pi-usb-c-pro-micro-replacement-rp2040) | `elite_pi` |
|
||||
| [0xCB Helios](https://keeb.supply/products/0xcb-helios) | `helios` |
|
||||
| [Liatris](https://splitkb.com/products/liatris) | `liatris` |
|
||||
|
||||
Converter summary:
|
||||
|
||||
@@ -198,7 +194,6 @@ Converter summary:
|
||||
| `rp2040_ce` | `-e CONVERT_TO=rp2040_ce` | `CONVERT_TO=rp2040_ce` | `#ifdef CONVERT_TO_RP2040_CE` |
|
||||
| `elite_pi` | `-e CONVERT_TO=elite_pi` | `CONVERT_TO=elite_pi` | `#ifdef CONVERT_TO_ELITE_PI` |
|
||||
| `helios` | `-e CONVERT_TO=helios` | `CONVERT_TO=helios` | `#ifdef CONVERT_TO_HELIOS` |
|
||||
| `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` |
|
||||
|
||||
### STeMCell :id=stemcell_elite
|
||||
|
||||
|
||||
@@ -57,78 +57,78 @@ susceptible to noise, you must choose a debounce method that will also mitigate
|
||||
if the scanning is slow, and you are using a timestamp-based algorithm, you might end up making a debouncing decision based on only two
|
||||
sampled values, which will limit the noise-resistance of the algorithm.
|
||||
* Currently all built-in debounce algorithms support timestamp-based debouncing only. In the future we might
|
||||
implement cycles-based debouncing, and it will be selectable via a `config.h` macro.
|
||||
implement cycles-based debouncing, and it will be selectable via a ```config.h``` macro.
|
||||
|
||||
2) Symmetric vs Asymmetric
|
||||
* Symmetric - apply the same debouncing algorithm, to both key-up and key-down events.
|
||||
* Recommended naming convention: `sym_*`
|
||||
* Recommended naming convention: ```sym_*```
|
||||
* Asymmetric - apply different debouncing algorithms to key-down and key-up events. E.g. Eager key-down, Defer key-up.
|
||||
* Recommended naming convention: `asym_*` followed by details of the type of algorithm in use, in order, for key-down and then key-up
|
||||
* Recommended naming convention: ```asym_*``` followed by details of the type of algorithm in use, in order, for key-down and then key-up
|
||||
|
||||
3) Eager vs Defer
|
||||
* Eager - any key change is reported immediately. All further inputs for DEBOUNCE ms are ignored.
|
||||
* Eager algorithms are not noise-resistant.
|
||||
* Recommended naming conventions:
|
||||
* `sym_eager_*`
|
||||
* `asym_eager_*_*`: key-down is using eager algorithm
|
||||
* `asym_*_eager_*`: key-up is using eager algorithm
|
||||
* ```sym_eager_*```
|
||||
* ```asym_eager_*_*```: key-down is using eager algorithm
|
||||
* ```asym_*_eager_*```: key-up is using eager algorithm
|
||||
* Defer - wait for no changes for DEBOUNCE ms before reporting change.
|
||||
* Defer algorithms are noise-resistant
|
||||
* Recommended naming conventions:
|
||||
* `sym_defer_*`
|
||||
* `asym_defer_*_*`: key-down is using defer algorithm
|
||||
* `asym_*_defer_*`: key-up is using defer algorithm
|
||||
* ```sym_defer_*```
|
||||
* ```asym_defer_*_*```: key-down is using defer algorithm
|
||||
* ```asym_*_defer_*```: key-up is using defer algorithm
|
||||
|
||||
4) Global vs Per-Key vs Per-Row
|
||||
* Global - one timer for all keys. Any key change state affects global timer
|
||||
* Recommended naming convention: `*_g`
|
||||
* Recommended naming convention: ```*_g```
|
||||
* Per-key - one timer per key
|
||||
* Recommended naming convention: `*_pk`
|
||||
* Recommended naming convention: ```*_pk```
|
||||
* Per-row - one timer per row
|
||||
* Recommended naming convention: `*_pr`
|
||||
* Recommended naming convention: ```*_pr```
|
||||
* Per-key and per-row algorithms consume more resources (in terms of performance,
|
||||
and ram usage), but fast typists might prefer them over global.
|
||||
|
||||
## Supported Debounce Algorithms
|
||||
## Debounce algorithms supported by QMK
|
||||
|
||||
QMK supports multiple algorithms through its debounce API.
|
||||
QMK supports multiple debounce algorithms through its debounce API.
|
||||
|
||||
### Debounce Time
|
||||
### Debounce selection
|
||||
|
||||
Default debounce time is 5 milliseconds and it can be changed with the following line in `config.h`:
|
||||
```
|
||||
#define DEBOUNCE 10
|
||||
```
|
||||
?> Setting `DEBOUNCE` to `0` will disable this feature.
|
||||
| DEBOUNCE_TYPE | Description | What else is needed |
|
||||
| ------------- | --------------------------------------------------- | ----------------------------- |
|
||||
| Not defined | Use the default algorithm, currently sym_defer_g | Nothing |
|
||||
| custom | Use your own debounce code | ```SRC += debounce.c``` add your own debounce.c and implement necessary functions |
|
||||
| Anything Else | Use another algorithm from quantum/debounce/* | Nothing |
|
||||
|
||||
### Debounce Method
|
||||
**Regarding split keyboards**:
|
||||
The debounce code is compatible with split keyboards.
|
||||
|
||||
Keyboards may select one of the core debounce methods by adding the following line into `rules.mk`:
|
||||
### Selecting an included debouncing method
|
||||
Keyboards may select one of the already implemented debounce methods, by adding to ```rules.mk``` the following line:
|
||||
```
|
||||
DEBOUNCE_TYPE = <name of algorithm>
|
||||
```
|
||||
Name of algorithm is one of:
|
||||
Where name of algorithm is one of:
|
||||
* ```sym_defer_g``` - debouncing per keyboard. On any state change, a global timer is set. When ```DEBOUNCE``` milliseconds of no changes has occurred, all input changes are pushed.
|
||||
* This is the current default algorithm. This is the highest performance algorithm with lowest memory usage, and it's also noise-resistant.
|
||||
* ```sym_eager_pr``` - debouncing per row. On any state change, response is immediate, followed by locking the row ```DEBOUNCE``` milliseconds of no further input for that row.
|
||||
For use in keyboards where refreshing ```NUM_KEYS``` 8-bit counters is computationally expensive / low scan rate, and fingers usually only hit one row at a time. This could be
|
||||
appropriate for the ErgoDox models; the matrix is rotated 90°, and hence its "rows" are really columns, and each finger only hits a single "row" at a time in normal use.
|
||||
* ```sym_eager_pk``` - debouncing per key. On any state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key
|
||||
* ```sym_defer_pr``` - debouncing per row. On any state change, a per-row timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that row, the entire row is pushed. Can improve responsiveness over `sym_defer_g` while being less susceptible than per-key debouncers to noise.
|
||||
* ```sym_defer_pk``` - debouncing per key. On any state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that key, the key status change is pushed.
|
||||
* ```asym_eager_defer_pk``` - debouncing per key. On a key-down state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key. On a key-up state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that key, the key-up status change is pushed.
|
||||
|
||||
| Algorithm | Description |
|
||||
| --------------------- | ----------- |
|
||||
| `sym_defer_g` | Debouncing per keyboard. On any state change, a global timer is set. When `DEBOUNCE` milliseconds of no changes has occurred, all input changes are pushed. This is the highest performance algorithm with lowest memory usage and is noise-resistant. |
|
||||
| `sym_defer_pr` | Debouncing per row. On any state change, a per-row timer is set. When `DEBOUNCE` milliseconds of no changes have occurred on that row, the entire row is pushed. This can improve responsiveness over `sym_defer_g` while being less susceptible to noise than per-key algorithm. |
|
||||
| `sym_defer_pk` | Debouncing per key. On any state change, a per-key timer is set. When `DEBOUNCE` milliseconds of no changes have occurred on that key, the key status change is pushed. |
|
||||
| `sym_eager_pr` | Debouncing per row. On any state change, response is immediate, followed by `DEBOUNCE` milliseconds of no further input for that row. |
|
||||
| `sym_eager_pk` | Debouncing per key. On any state change, response is immediate, followed by `DEBOUNCE` milliseconds of no further input for that key. |
|
||||
| `asym_eager_defer_pk` | Debouncing per key. On a key-down state change, response is immediate, followed by `DEBOUNCE` milliseconds of no further input for that key. On a key-up state change, a per-key timer is set. When `DEBOUNCE` milliseconds of no changes have occurred on that key, the key-up status change is pushed. |
|
||||
### A couple algorithms that could be implemented in the future:
|
||||
* ```sym_defer_pr```
|
||||
* ```sym_eager_g```
|
||||
|
||||
?> `sym_defer_g` is the default if `DEBOUNCE_TYPE` is undefined.
|
||||
|
||||
?> `sym_eager_pr` is suitable for use in keyboards where refreshing `NUM_KEYS` 8-bit counters is computationally expensive or has low scan rate while fingers usually hit one row at a time. This could be appropriate for the ErgoDox models where the matrix is rotated 90°. Hence its "rows" are really columns and each finger only hits a single "row" at a time with normal usage.
|
||||
|
||||
### Implementing your own debouncing code
|
||||
|
||||
You have the option to implement you own debouncing algorithm with the following steps:
|
||||
|
||||
* Set `DEBOUNCE_TYPE = custom` in `rules.mk`.
|
||||
* Add `SRC += debounce.c` in `rules.mk`
|
||||
* Implement your own `debounce.c`. See `quantum/debounce` for examples.
|
||||
### Use your own debouncing code
|
||||
You have the option to implement you own debouncing algorithm. To do this:
|
||||
* Set ```DEBOUNCE_TYPE = custom``` in ```rules.mk```.
|
||||
* Add ```SRC += debounce.c``` in ```rules.mk```
|
||||
* Add your own ```debounce.c```. Look at current implementations in ```quantum/debounce``` for examples.
|
||||
* Debouncing occurs after every raw matrix scan.
|
||||
* Use num_rows instead of MATRIX_ROWS to support split keyboards correctly.
|
||||
* If your custom algorithm is applicable to other keyboards, please consider making a pull request.
|
||||
* Use num_rows rather than MATRIX_ROWS, so that split keyboards are supported correctly.
|
||||
* If the algorithm might be applicable to other keyboards, please consider adding it to ```quantum/debounce```
|
||||
|
||||
@@ -59,7 +59,7 @@ There are a number of hooks that you can use to add custom functionality and fee
|
||||
|
||||
Note, that direction indicates which macro it is, with `1` being Macro 1, `-1` being Macro 2, and 0 being no macro.
|
||||
|
||||
* `dynamic_macro_record_start_user(int8_t direction)` - Triggered when you start recording a macro.
|
||||
* `dynamic_macro_record_start_user(void)` - Triggered when you start recording a macro.
|
||||
* `dynamic_macro_play_user(int8_t direction)` - Triggered when you play back a macro.
|
||||
* `dynamic_macro_record_key_user(int8_t direction, keyrecord_t *record)` - Triggered on each keypress while recording a macro.
|
||||
* `dynamic_macro_record_end_user(int8_t direction)` - Triggered when the macro recording is stopped.
|
||||
|
||||
@@ -81,7 +81,7 @@ Your `keymap.c` will then need an encoder mapping defined (for four layers and t
|
||||
|
||||
```c
|
||||
#if defined(ENCODER_MAP_ENABLE)
|
||||
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
|
||||
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
|
||||
[_BASE] = { ENCODER_CCW_CW(KC_MS_WH_UP, KC_MS_WH_DOWN), ENCODER_CCW_CW(KC_VOLD, KC_VOLU) },
|
||||
[_LOWER] = { ENCODER_CCW_CW(RGB_HUD, RGB_HUI), ENCODER_CCW_CW(RGB_SAD, RGB_SAI) },
|
||||
[_RAISE] = { ENCODER_CCW_CW(RGB_VAD, RGB_VAI), ENCODER_CCW_CW(RGB_SPD, RGB_SPI) },
|
||||
@@ -102,9 +102,9 @@ Using encoder mapping pumps events through the normal QMK keycode processing pip
|
||||
|
||||
## Callbacks
|
||||
|
||||
?> [**Default Behaviour**](https://github.com/qmk/qmk_firmware/blob/master/quantum/encoder.c#L79-#L98): all encoders installed will function as volume up (`KC_VOLU`) on clockwise rotation and volume down (`KC_VOLD`) on counter-clockwise rotation. If you do not wish to override this, no further configuration is necessary.
|
||||
When not using `ENCODER_MAP_ENABLE = yes`, the callback functions can be inserted into your `<keyboard>.c`:
|
||||
|
||||
If you would like the alter the default behaviour, and are not using `ENCODER_MAP_ENABLE = yes`, the callback functions can be inserted into your `<keyboard>.c`:
|
||||
?> Those who are adding new keyboard support where encoders are enabled at the keyboard level should include basic encoder functionality at the keyboard level (`<keyboard>.c`) using the `encoder_update_kb()` function, that way it works for QMK Configuator users and exists in general.
|
||||
|
||||
```c
|
||||
bool encoder_update_kb(uint8_t index, bool clockwise) {
|
||||
@@ -113,9 +113,9 @@ bool encoder_update_kb(uint8_t index, bool clockwise) {
|
||||
}
|
||||
if (index == 0) { /* First encoder */
|
||||
if (clockwise) {
|
||||
tap_code(KC_PGDN);
|
||||
tap_code_delay(KC_VOLU, 10);
|
||||
} else {
|
||||
tap_code(KC_PGUP);
|
||||
tap_code_delay(KC_VOLD, 10);
|
||||
}
|
||||
} else if (index == 1) { /* Second encoder */
|
||||
if (clockwise) {
|
||||
@@ -134,9 +134,9 @@ or `keymap.c`:
|
||||
bool encoder_update_user(uint8_t index, bool clockwise) {
|
||||
if (index == 0) { /* First encoder */
|
||||
if (clockwise) {
|
||||
tap_code(KC_PGDN);
|
||||
tap_code_delay(KC_VOLU, 10);
|
||||
} else {
|
||||
tap_code(KC_PGUP);
|
||||
tap_code_delay(KC_VOLD, 10);
|
||||
}
|
||||
} else if (index == 1) { /* Second encoder */
|
||||
if (clockwise) {
|
||||
@@ -149,7 +149,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
|
||||
}
|
||||
```
|
||||
|
||||
!> If you return `true` in the keymap level `_user` function, it will allow the keyboard/core level encoder code to run on top of your own. Returning `false` will override the keyboard level function, if setup correctly. This is generally the safest option to avoid confusion.
|
||||
!> If you return `true` in the keymap level `_user` function, it will allow the keyboard level encoder code to run on top of your own. Returning `false` will override the keyboard level function, if setup correctly. This is generally the safest option to avoid confusion.
|
||||
|
||||
## Hardware
|
||||
|
||||
|
||||
@@ -127,54 +127,6 @@ layer_state_t layer_state_set_user(layer_state_t state) {
|
||||
}
|
||||
```
|
||||
|
||||
### Example: Keycode to cycle through layers
|
||||
|
||||
This example shows how to implement a custom keycode to cycle through a range of layers.
|
||||
|
||||
```c
|
||||
// Define the keycode, `QK_USER` avoids collisions with existing keycodes
|
||||
enum keycodes {
|
||||
KC_CYCLE_LAYERS = QK_USER,
|
||||
};
|
||||
|
||||
// 1st layer on the cycle
|
||||
#define LAYER_CYCLE_START 0
|
||||
// Last layer on the cycle
|
||||
#define LAYER_CYCLE_END 4
|
||||
|
||||
// Add the behaviour of this new keycode
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
switch (keycode) {
|
||||
case KC_CYCLE_LAYERS:
|
||||
// Our logic will happen on presses, nothing is done on releases
|
||||
if (!record->event.pressed) {
|
||||
// We've already handled the keycode (doing nothing), let QMK know so no further code is run unnecessarily
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t current_layer = get_highest_layer(layer_state);
|
||||
|
||||
// Check if we are within the range, if not quit
|
||||
if (curent_layer > LAYER_CYCLE_END || current_layer < LAYER_CYCLE_START) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t next_layer = current_layer + 1;
|
||||
if (next_layer > LAYER_CYCLE_END) {
|
||||
next_layer = LAYER_CYCLE_START;
|
||||
}
|
||||
layer_move(next_layer);
|
||||
return false;
|
||||
|
||||
// Process other keycodes normally
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Place `KC_CYCLE_LAYERS` as a keycode in your keymap
|
||||
```
|
||||
|
||||
Use the `IS_LAYER_ON_STATE(state, layer)` and `IS_LAYER_OFF_STATE(state, layer)` macros to check the status of a particular layer.
|
||||
|
||||
Outside of `layer_state_set_*` functions, you can use the `IS_LAYER_ON(layer)` and `IS_LAYER_OFF(layer)` macros to check global layer state.
|
||||
|
||||
@@ -378,7 +378,13 @@ For inspiration and examples, check out the built-in effects under `quantum/led_
|
||||
|
||||
## EEPROM storage :id=eeprom-storage
|
||||
|
||||
The EEPROM for it is currently shared with the RGB Matrix system (it's generally assumed only one feature would be used at a time).
|
||||
The EEPROM for it is currently shared with the RGB Matrix system (it's generally assumed only one feature would be used at a time), but could be configured to use its own 32bit address with:
|
||||
|
||||
```c
|
||||
#define EECONFIG_LED_MATRIX (uint32_t *)28
|
||||
```
|
||||
|
||||
Where `28` is an unused index from `eeconfig.h`.
|
||||
|
||||
### Direct Operation :id=direct-operation
|
||||
|Function |Description |
|
||||
|
||||
+34
-81
@@ -2,18 +2,15 @@
|
||||
|
||||
## Supported Hardware
|
||||
|
||||
OLED modules using SSD1306, SH1106 or SH1107 driver ICs, communicating over I2C or SPI.
|
||||
OLED modules using SSD1306 or SH1106 driver ICs, communicating over I2C.
|
||||
Tested combinations:
|
||||
|
||||
|IC |Size |Platform|Notes |
|
||||
|---------|-------|--------|------------------------|
|
||||
|SSD1306 |128x32 |AVR |Primary support |
|
||||
|SSD1306 |128x64 |AVR |Verified working |
|
||||
|SSD1306 |128x32 |Arm | |
|
||||
|SH1106 |128x64 |AVR |No scrolling |
|
||||
|SH1107 |64x128 |AVR |No scrolling |
|
||||
|SH1107 |64x128 |Arm |No scrolling |
|
||||
|SH1107 |128x128|Arm |No scrolling |
|
||||
|IC |Size |Platform|Notes |
|
||||
|---------|------|--------|------------------------|
|
||||
|SSD1306 |128x32|AVR |Primary support |
|
||||
|SSD1306 |128x64|AVR |Verified working |
|
||||
|SSD1306 |128x32|Arm | |
|
||||
|SH1106 |128x64|AVR |No rotation or scrolling|
|
||||
|
||||
Hardware configurations using Arm-based microcontrollers or different sizes of OLED modules may be compatible, but are untested.
|
||||
|
||||
@@ -26,26 +23,15 @@ OLED_ENABLE = yes
|
||||
```
|
||||
|
||||
## OLED type
|
||||
|
||||
|OLED Driver |Supported Device |
|
||||
|-------------------|------------------------------------|
|
||||
|SSD1306 (default) |For both SSD1306, SH1106, and SH1107|
|
||||
|OLED Driver |Supported Device |
|
||||
|-------------------|---------------------------|
|
||||
|SSD1306 (default) |For both SSD1306 and SH1106|
|
||||
|
||||
e.g.
|
||||
```make
|
||||
OLED_DRIVER = SSD1306
|
||||
```
|
||||
|
||||
|OLED Transport | |
|
||||
|---------------|------------------------------------------------|
|
||||
|i2c (default) | Uses I2C for communication with the OLED panel |
|
||||
|spi | Uses SPI for communication with the OLED panel |
|
||||
|
||||
e.g.
|
||||
```make
|
||||
OLED_TRANSPORT = i2c
|
||||
```
|
||||
|
||||
Then in your `keymap.c` file, implement the OLED task call. This example assumes your keymap has three layers named `_QWERTY`, `_FN` and `_ADJ`:
|
||||
|
||||
```c
|
||||
@@ -173,57 +159,32 @@ These configuration options should be placed in `config.h`. Example:
|
||||
#define OLED_BRIGHTNESS 128
|
||||
```
|
||||
|
||||
|Define |Default |Description |
|
||||
|---------------------------|-------------------------------|---------------------------------------------------------------------------------------------------------------------|
|
||||
|`OLED_BRIGHTNESS` |`255` |The default brightness level of the OLED, from 0 to 255. |
|
||||
|`OLED_COLUMN_OFFSET` |`0` |Shift output to the right this many pixels.<br />Useful for 128x64 displays centered on a 132x64 SH1106 IC. |
|
||||
|`OLED_DISPLAY_CLOCK` |`0x80` |Set the display clock divide ratio/oscillator frequency. |
|
||||
|`OLED_FONT_H` |`"glcdfont.c"` |The font code file to use for custom fonts |
|
||||
|`OLED_FONT_START` |`0` |The starting character index for custom fonts |
|
||||
|`OLED_FONT_END` |`223` |The ending character index for custom fonts |
|
||||
|`OLED_FONT_WIDTH` |`6` |The font width |
|
||||
|`OLED_FONT_HEIGHT` |`8` |The font height (untested) |
|
||||
|`OLED_IC` |`OLED_IC_SSD1306` |Set to `OLED_IC_SH1106` or `OLED_IC_SH1107` if the corresponding controller chip is used. |
|
||||
|`OLED_FADE_OUT` |*Not defined* |Enables fade out animation. Use together with `OLED_TIMEOUT`. |
|
||||
|`OLED_FADE_OUT_INTERVAL` |`0` |The speed of fade out animation, from 0 to 15. Larger values are slower. |
|
||||
|`OLED_SCROLL_TIMEOUT` |`0` |Scrolls the OLED screen after 0ms of OLED inactivity. Helps reduce OLED Burn-in. Set to 0 to disable. |
|
||||
|`OLED_SCROLL_TIMEOUT_RIGHT`|*Not defined* |Scroll timeout direction is right when defined, left when undefined. |
|
||||
|`OLED_TIMEOUT` |`60000` |Turns off the OLED screen after 60000ms of screen update inactivity. Helps reduce OLED Burn-in. Set to 0 to disable. |
|
||||
|`OLED_UPDATE_INTERVAL` |`0` (`50` for split keyboards) |Set the time interval for updating the OLED display in ms. This will improve the matrix scan rate. |
|
||||
|`OLED_UPDATE_PROCESS_LIMIT'|`1` |Set the number of dirty blocks to render per loop. Increasing may degrade performance. |
|
||||
|
||||
### I2C Configuration
|
||||
|Define |Default |Description |
|
||||
|---------------------------|-----------------|--------------------------------------------------------------------------------------------------------------------------|
|
||||
|`OLED_DISPLAY_ADDRESS` |`0x3C` |The i2c address of the OLED Display |
|
||||
|`OLED_FONT_H` |`"glcdfont.c"` |The font code file to use for custom fonts |
|
||||
|`OLED_FONT_START` |`0` |The starting character index for custom fonts |
|
||||
|`OLED_FONT_END` |`223` |The ending character index for custom fonts |
|
||||
|`OLED_FONT_WIDTH` |`6` |The font width |
|
||||
|`OLED_FONT_HEIGHT` |`8` |The font height (untested) |
|
||||
|`OLED_TIMEOUT` |`60000` |Turns off the OLED screen after 60000ms of screen update inactivity. Helps reduce OLED Burn-in. Set to 0 to disable. |
|
||||
|`OLED_FADE_OUT` |*Not defined* |Enables fade out animation. Use together with `OLED_TIMEOUT`. |
|
||||
|`OLED_FADE_OUT_INTERVAL` |`0` |The speed of fade out animation, from 0 to 15. Larger values are slower. |
|
||||
|`OLED_SCROLL_TIMEOUT` |`0` |Scrolls the OLED screen after 0ms of OLED inactivity. Helps reduce OLED Burn-in. Set to 0 to disable. |
|
||||
|`OLED_SCROLL_TIMEOUT_RIGHT`|*Not defined* |Scroll timeout direction is right when defined, left when undefined. |
|
||||
|`OLED_IC` |`OLED_IC_SSD1306`|Set to `OLED_IC_SH1106` if you're using the SH1106 OLED controller. |
|
||||
|`OLED_COLUMN_OFFSET` |`0` |(SH1106 only.) Shift output to the right this many pixels.<br />Useful for 128x64 displays centered on a 132x64 SH1106 IC.|
|
||||
|`OLED_BRIGHTNESS` |`255` |The default brightness level of the OLED, from 0 to 255. |
|
||||
|`OLED_UPDATE_INTERVAL` |`0` |Set the time interval for updating the OLED display in ms. This will improve the matrix scan rate. |
|
||||
|
||||
### SPI Configuration
|
||||
## 128x64 & Custom sized OLED Displays
|
||||
|
||||
|Define |Default |Description |
|
||||
|---------------------------|-----------------|--------------------------------------------------------------------------------------------------------------------------|
|
||||
|`OLED_DC_PIN` | Required |The pin used for the DC connection of the OLED Display. |
|
||||
|`OLED_CS_PIN` | Required |The pin used for the CS connection of the OLED Display. |
|
||||
|`OLED_RST_PIN` | *Not defined* |The pin used for the RST connection of the OLED Display (may be left undefined if the RST pin is not connected). |
|
||||
|`OLED_SPI_MODE` |`3` (default) |The SPI Mode for the OLED Display (not typically changed). |
|
||||
|`OLED_SPI_DIVISOR` |`2` (default) |The SPI Multiplier to use for the OLED Display. |
|
||||
|
||||
## 128x64 & Custom sized OLED Displays
|
||||
|
||||
The default display size for this feature is 128x32, and the defaults are set with that in mind. However, there are a number of additional presets for common sizes that we have added. You can define one of these values to use the presets. If your display doesn't match one of these presets, you can define `OLED_DISPLAY_CUSTOM` to manually specify all of the values.
|
||||
|
||||
|Define |Default |Description |
|
||||
|----------------------|---------------|---------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|`OLED_DISPLAY_128X64` |*Not defined* |Changes the display defines for use with 128x64 displays. |
|
||||
|`OLED_DISPLAY_64X32` |*Not defined* |Changes the display defines for use with 64x32 displays. |
|
||||
|`OLED_DISPLAY_64X48` |*Not defined* |Changes the display defines for use with 64x48 displays. |
|
||||
|`OLED_DISPLAY_64X128` |*Not defined* |Changes the display defines for use with 64x128 displays. |
|
||||
|`OLED_DISPLAY_128X128`|*Not defined* |Changes the display defines for use with 128x128 displays. |
|
||||
|`OLED_DISPLAY_CUSTOM` |*Not defined* |Changes the display defines for use with custom displays.<br>Requires user to implement the below defines. |
|
||||
|
||||
!> 64x128 and 128x128 displays default to the SH1107 IC type, as these heights are not supported by the other IC types.
|
||||
The default display size for this feature is 128x32 and all necessary defines are precalculated with that in mind. We have added a define, `OLED_DISPLAY_128X64`, to switch all the values to be used in a 128x64 display, as well as added a custom define, `OLED_DISPLAY_CUSTOM`, that allows you to provide the necessary values to the driver.
|
||||
|
||||
|Define |Default |Description |
|
||||
| --------------------|---------------|----------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|---------------------|---------------|----------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|`OLED_DISPLAY_128X64`|*Not defined* |Changes the display defines for use with 128x64 displays. |
|
||||
|`OLED_DISPLAY_CUSTOM`|*Not defined* |Changes the display defines for use with custom displays.<br>Requires user to implement the below defines. |
|
||||
|`OLED_DISPLAY_WIDTH` |`128` |The width of the OLED display. |
|
||||
|`OLED_DISPLAY_HEIGHT`|`32` |The height of the OLED display. |
|
||||
|`OLED_MATRIX_SIZE` |`512` |The local buffer size to allocate.<br>`(OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH)`. |
|
||||
@@ -231,13 +192,14 @@ These configuration options should be placed in `config.h`. Example:
|
||||
|`OLED_BLOCK_COUNT` |`16` |The number of blocks the display is divided into for dirty rendering.<br>`(sizeof(OLED_BLOCK_TYPE) * 8)`. |
|
||||
|`OLED_BLOCK_SIZE` |`32` |The size of each block for dirty rendering<br>`(OLED_MATRIX_SIZE / OLED_BLOCK_COUNT)`. |
|
||||
|`OLED_COM_PINS` |`COM_PINS_SEQ` |How the SSD1306 chip maps it's memory to display.<br>Options are `COM_PINS_SEQ`, `COM_PINS_ALT`, `COM_PINS_SEQ_LR`, & `COM_PINS_ALT_LR`.|
|
||||
|`OLED_COM_PIN_COUNT` |*Not defined* |Number of COM pins supported by the controller.<br>If not defined, the value appropriate for the defined `OLED_IC` is used. |
|
||||
|`OLED_COM_PIN_OFFSET`|`0` |Number of the first COM pin used by the OLED matrix. |
|
||||
|`OLED_SOURCE_MAP` |`{ 0, ... N }` |Precalculated source array to use for mapping source buffer to target OLED memory in 90 degree rendering. |
|
||||
|`OLED_TARGET_MAP` |`{ 24, ... N }`|Precalculated target array to use for mapping source buffer to target OLED memory in 90 degree rendering. |
|
||||
|
||||
|
||||
### 90 Degree Rotation - Technical Mumbo Jumbo
|
||||
|
||||
!> Rotation is unsupported on the SH1106.
|
||||
|
||||
```c
|
||||
// OLED Rotation enum values are flags
|
||||
typedef enum {
|
||||
@@ -248,7 +210,7 @@ typedef enum {
|
||||
} oled_rotation_t;
|
||||
```
|
||||
|
||||
OLED displays driven by SSD1306, SH1106 or SH1107 drivers only natively support in hardware 0 degree and 180 degree rendering. This feature is done in software and not free. Using this feature will increase the time to calculate what data to send over i2c to the OLED. If you are strapped for cycles, this can cause keycodes to not register. In testing however, the rendering time on an ATmega32U4 board only went from 2ms to 5ms and keycodes not registering was only noticed once we hit 15ms.
|
||||
OLED displays driven by SSD1306 drivers only natively support in hardware 0 degree and 180 degree rendering. This feature is done in software and not free. Using this feature will increase the time to calculate what data to send over i2c to the OLED. If you are strapped for cycles, this can cause keycodes to not register. In testing however, the rendering time on an ATmega32U4 board only went from 2ms to 5ms and keycodes not registering was only noticed once we hit 15ms.
|
||||
|
||||
90 degree rotation is achieved by using bitwise operations to rotate each 8 block of memory and uses two precalculated arrays to remap buffer memory to OLED memory. The memory map defines are precalculated for remap performance and are calculated based on the display height, width, and block size. For example, in the 128x32 implementation with a `uint8_t` block type, we have a 64 byte block size. This gives us eight 8 byte blocks that need to be rotated and rendered. The OLED renders horizontally two 8 byte blocks before moving down a page, e.g:
|
||||
|
||||
@@ -270,8 +232,6 @@ However the local buffer is stored as if it was Height x Width display instead o
|
||||
|
||||
So those precalculated arrays just index the memory offsets in the order in which each one iterates its data.
|
||||
|
||||
Rotation on SH1106 and SH1107 is noticeably less efficient than on SSD1306, because these controllers do not support the “horizontal addressing mode”, which allows transferring the data for the whole rotated block at once; instead, separate address setup commands for every page in the block are required. The screen refresh time for SH1107 is therefore about 45% higher than for a same size screen with SSD1306 when using STM32 MCUs (on AVR the slowdown is about 20%, because the code which actually rotates the bitmap consumes more time).
|
||||
|
||||
## OLED API
|
||||
|
||||
```c
|
||||
@@ -293,11 +253,6 @@ bool oled_init(oled_rotation_t rotation);
|
||||
oled_rotation_t oled_init_kb(oled_rotation_t rotation);
|
||||
oled_rotation_t oled_init_user(oled_rotation_t rotation);
|
||||
|
||||
// Send commands/data to screen
|
||||
bool oled_send_cmd(const uint8_t *data, uint16_t size);
|
||||
bool oled_send_cmd_P(const uint8_t *data, uint16_t size);
|
||||
bool oled_send_data(const uint8_t *data, uint16_t size);
|
||||
|
||||
// Clears the display buffer, resets cursor position to 0, and sets the buffer to dirty for rendering
|
||||
void oled_clear(void);
|
||||
|
||||
@@ -431,9 +386,7 @@ uint8_t oled_max_chars(void);
|
||||
uint8_t oled_max_lines(void);
|
||||
```
|
||||
|
||||
!> Scrolling is unsupported on the SH1106 and SH1107.
|
||||
|
||||
!> Scrolling does not work properly on the SSD1306 if the display width is smaller than 128.
|
||||
!> Scrolling and rotation are unsupported on the SH1106.
|
||||
|
||||
## SSD1306.h Driver Conversion Guide
|
||||
|
||||
|
||||
@@ -197,24 +197,6 @@ The Pimoroni Trackball module is a I2C based breakout board with an RGB enable t
|
||||
| `PIMORONI_TRACKBALL_DEBOUNCE_CYCLES` | (Optional) The number of scan cycles used for debouncing on the ball press. | `20` |
|
||||
| `PIMORONI_TRACKBALL_ERROR_COUNT` | (Optional) Specifies the number of read/write errors until the sensor is disabled. | `10` |
|
||||
|
||||
### PMW3320 Sensor
|
||||
|
||||
To use the PMW3320 sensor, add this to your `rules.mk`
|
||||
|
||||
```make
|
||||
POINTING_DEVICE_DRIVER = pmw3320
|
||||
```
|
||||
|
||||
The PMW3320 sensor uses a serial type protocol for communication, and requires an additional light source (it could work without one, but expect it to be out of service early).
|
||||
|
||||
| Setting | Description | Default |
|
||||
| ------------------- | ------------------------------------------------------------------- | -------------------------- |
|
||||
| `PMW3320_SCLK_PIN` | (Required) The pin connected to the clock pin of the sensor. | `POINTING_DEVICE_SCLK_PIN` |
|
||||
| `PMW3320_SDIO_PIN` | (Required) The pin connected to the data pin of the sensor. | `POINTING_DEVICE_SDIO_PIN` |
|
||||
| `PMW3320_CS_PIN` | (Required) The pin connected to the cable select pin of the sensor. | `POINTING_DEVICE_CS_PIN` |
|
||||
|
||||
The CPI range is 500-3500, in increments of 250. Defaults to 1000 CPI.
|
||||
|
||||
### PMW 3360 and PMW 3389 Sensor
|
||||
|
||||
This drivers supports both the PMW 3360 and PMW 3389 sensor as well as multiple sensors of the same type _per_ controller, so 2 can be attached at the same side for split keyboards (or unsplit keyboards).
|
||||
@@ -452,75 +434,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
|
||||
This allows you to toggle between scrolling and cursor movement by pressing the DRAG_SCROLL key.
|
||||
|
||||
### Advanced Drag Scroll
|
||||
|
||||
Sometimes, like with the Cirque trackpad, you will run into issues where the scrolling may be too fast.
|
||||
|
||||
Here is a slightly more advanced example of drag scrolling. You will be able to change the scroll speed based on the values in set in `SCROLL_DIVISOR_H` and `SCROLL_DIVISOR_V`. This bit of code is also set up so that instead of toggling the scrolling state with set_scrolling = !set_scrolling, the set_scrolling variable is set directly to record->event.pressed. This way, the drag scrolling will only be active while the DRAG_SCROLL button is held down.
|
||||
|
||||
```c
|
||||
enum custom_keycodes {
|
||||
DRAG_SCROLL = SAFE_RANGE,
|
||||
};
|
||||
|
||||
bool set_scrolling = false;
|
||||
|
||||
// Modify these values to adjust the scrolling speed
|
||||
#define SCROLL_DIVISOR_H 8.0
|
||||
#define SCROLL_DIVISOR_V 8.0
|
||||
|
||||
// Variables to store accumulated scroll values
|
||||
float scroll_accumulated_h = 0;
|
||||
float scroll_accumulated_v = 0;
|
||||
|
||||
// Function to handle mouse reports and perform drag scrolling
|
||||
report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) {
|
||||
// Check if drag scrolling is active
|
||||
if (set_scrolling) {
|
||||
// Calculate and accumulate scroll values based on mouse movement and divisors
|
||||
scroll_accumulated_h += (float)mouse_report.x / SCROLL_DIVISOR_H;
|
||||
scroll_accumulated_v += (float)mouse_report.y / SCROLL_DIVISOR_V;
|
||||
|
||||
// Assign integer parts of accumulated scroll values to the mouse report
|
||||
mouse_report.h = (int8_t)scroll_accumulated_h;
|
||||
mouse_report.v = (int8_t)scroll_accumulated_v;
|
||||
|
||||
// Update accumulated scroll values by subtracting the integer parts
|
||||
scroll_accumulated_h -= (int8_t)scroll_accumulated_h;
|
||||
scroll_accumulated_v -= (int8_t)scroll_accumulated_v;
|
||||
|
||||
// Clear the X and Y values of the mouse report
|
||||
mouse_report.x = 0;
|
||||
mouse_report.y = 0;
|
||||
}
|
||||
return mouse_report;
|
||||
}
|
||||
|
||||
// Function to handle key events and enable/disable drag scrolling
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
switch (keycode) {
|
||||
case DRAG_SCROLL:
|
||||
// Toggle set_scrolling when DRAG_SCROLL key is pressed or released
|
||||
set_scrolling = record->event.pressed;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Function to handle layer changes and disable drag scrolling when not in AUTO_MOUSE_DEFAULT_LAYER
|
||||
layer_state_t layer_state_set_user(layer_state_t state) {
|
||||
// Disable set_scrolling if the current layer is not the AUTO_MOUSE_DEFAULT_LAYER
|
||||
if (get_highest_layer(state) != AUTO_MOUSE_DEFAULT_LAYER) {
|
||||
set_scrolling = false;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Split Examples
|
||||
|
||||
The following examples make use the `SPLIT_POINTING_ENABLE` functionality and show how to manipulate the mouse report for a scrolling mode.
|
||||
@@ -689,10 +602,6 @@ There are several functions that allow for more advanced interaction with the au
|
||||
| `auto_mouse_layer_off(void)` | Disable target layer if appropriate will call (makes call to `layer_state_set`) | | `void`(None) |
|
||||
| `auto_mouse_toggle(void)` | Toggle on/off target toggle state (disables layer deactivation when true) | | `void`(None) |
|
||||
| `get_auto_mouse_toggle(void)` | Return value of toggling state variable | | `bool` |
|
||||
| `set_auto_mouse_timeout(uint16_t timeout)` | Change/set the timeout for turing off the layer | | `void`(None) |
|
||||
| `get_auto_mouse_timeout(void)` | Return the current timeout for turing off the layer | | `uint16_t` |
|
||||
| `set_auto_mouse_debounce(uint16_t timeout)` | Change/set the debounce for preventing layer activation | | `void`(None) |
|
||||
| `get_auto_mouse_debounce(void)` | Return the current debounce for preventing layer activation | | `uint8_t` |
|
||||
|
||||
_NOTES:_
|
||||
- _Due to the nature of how some functions work, the `auto_mouse_trigger_reset`, and `auto_mouse_layer_off` functions should never be called in the `layer_state_set_*` stack as this can cause indefinite loops._
|
||||
@@ -804,7 +713,7 @@ _Note: The Cirque pinnacle track pad already implements a custom activation func
|
||||
When using a custom pointing device (overwriting `pointing_device_task`) the following code should be somewhere in the `pointing_device_task_*` stack:
|
||||
|
||||
```c
|
||||
bool pointing_device_task(void) {
|
||||
void pointing_device_task(void) {
|
||||
//...Custom pointing device task code
|
||||
|
||||
// handle automatic mouse layer (needs report_mouse_t as input)
|
||||
@@ -812,7 +721,7 @@ bool pointing_device_task(void) {
|
||||
|
||||
//...More custom pointing device task code
|
||||
|
||||
return pointing_device_send();
|
||||
pointing_device_send();
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -1,457 +0,0 @@
|
||||
# Repeat Key
|
||||
|
||||
The Repeat Key performs the action of the last pressed key. Tapping the Repeat
|
||||
Key after tapping the <kbd>Z</kbd> key types another "`z`." This is useful for
|
||||
typing doubled letters, like the `z` in "`dazzle`": a double tap on <kbd>Z</kbd>
|
||||
can instead be a roll from <kbd>Z</kbd> to <kbd>Repeat</kbd>, which is
|
||||
potentially faster and more comfortable. The Repeat Key is also useful for
|
||||
hotkeys, like repeating Ctrl + Shift + Right Arrow to select by word.
|
||||
|
||||
Repeat Key remembers mods that were active with the last key press. These mods
|
||||
are combined with any additional mods while pressing the Repeat Key. If the last
|
||||
press key was <kbd>Ctrl</kbd> + <kbd>Z</kbd>, then <kbd>Shift</kbd> +
|
||||
<kbd>Repeat</kbd> performs Ctrl + Shift + `Z`.
|
||||
|
||||
## How do I enable Repeat Key
|
||||
|
||||
In your `rules.mk`, add:
|
||||
|
||||
```make
|
||||
REPEAT_KEY_ENABLE = yes
|
||||
```
|
||||
|
||||
Then pick a key in your keymap and assign it the keycode `QK_REPEAT_KEY` (short
|
||||
alias `QK_REP`). Optionally, use the keycode `QK_ALT_REPEAT_KEY` (short alias
|
||||
`QK_AREP`) on another key.
|
||||
|
||||
## Keycodes
|
||||
|
||||
|Keycode |Aliases |Description |
|
||||
|-----------------------|---------|-------------------------------------|
|
||||
|`QK_REPEAT_KEY` |`QK_REP` |Repeat the last pressed key |
|
||||
|`QK_ALT_REPEAT_KEY` |`QK_AREP`|Perform alternate of the last key |
|
||||
|
||||
## Alternate Repeating
|
||||
|
||||
The Alternate Repeat Key performs the "alternate" action of the last pressed key
|
||||
if it is defined. By default, Alternate Repeat is defined for navigation keys to
|
||||
act in the reverse direction. When the last key is the common "select by word"
|
||||
hotkey Ctrl + Shift + Right Arrow, the Alternate Repeat Key performs Ctrl +
|
||||
Shift + Left Arrow, which together with the Repeat Key enables convenient
|
||||
selection by words in either direction.
|
||||
|
||||
Alternate Repeat is enabled with the Repeat Key by default. Optionally, to
|
||||
reduce firmware size, Alternate Repeat may be disabled by adding in config.h:
|
||||
|
||||
```c
|
||||
#define NO_ALT_REPEAT_KEY
|
||||
```
|
||||
|
||||
The following alternate keys are defined by default. See
|
||||
`get_alt_repeat_key_keycode_user()` below for how to change or add to these
|
||||
definitions. Where it makes sense, these definitions also include combinations
|
||||
with mods, like Ctrl + Left ↔ Ctrl + Right Arrow.
|
||||
|
||||
**Navigation**
|
||||
|
||||
|Keycodes |Description |
|
||||
|-----------------------------------|-----------------------------------|
|
||||
|`KC_LEFT` ↔ `KC_RGHT` | Left ↔ Right Arrow |
|
||||
|`KC_UP` ↔ `KC_DOWN` | Up ↔ Down Arrow |
|
||||
|`KC_HOME` ↔ `KC_END` | Home ↔ End |
|
||||
|`KC_PGUP` ↔ `KC_PGDN` | Page Up ↔ Page Down |
|
||||
|`KC_MS_L` ↔ `KC_MS_R` | Mouse Cursor Left ↔ Right |
|
||||
|`KC_MS_U` ↔ `KC_MS_D` | Mouse Cursor Up ↔ Down |
|
||||
|`KC_WH_L` ↔ `KC_WH_R` | Mouse Wheel Left ↔ Right |
|
||||
|`KC_WH_U` ↔ `KC_WH_D` | Mouse Wheel Up ↔ Down |
|
||||
|
||||
**Misc**
|
||||
|
||||
|Keycodes |Description |
|
||||
|-----------------------------------|-----------------------------------|
|
||||
|`KC_BSPC` ↔ `KC_DEL` | Backspace ↔ Delete |
|
||||
|`KC_LBRC` ↔ `KC_RBRC` | `[` ↔ `]` |
|
||||
|`KC_LCBR` ↔ `KC_RCBR` | `{` ↔ `}` |
|
||||
|
||||
**Media**
|
||||
|
||||
|Keycodes |Description |
|
||||
|-----------------------------------|-----------------------------------|
|
||||
|`KC_WBAK` ↔ `KC_WFWD` | Browser Back ↔ Forward |
|
||||
|`KC_MNXT` ↔ `KC_MPRV` | Next ↔ Previous Media Track |
|
||||
|`KC_MFFD` ↔ `KC_MRWD` | Fast Forward ↔ Rewind Media |
|
||||
|`KC_VOLU` ↔ `KC_VOLD` | Volume Up ↔ Down |
|
||||
|`KC_BRIU` ↔ `KC_BRID` | Brightness Up ↔ Down |
|
||||
|
||||
**Hotkeys in Vim, Emacs, and other programs**
|
||||
|
||||
|Keycodes |Description |
|
||||
|-----------------------------------|-----------------------------------|
|
||||
|mod + `KC_F` ↔ mod + `KC_B` | Forward ↔ Backward |
|
||||
|mod + `KC_D` ↔ mod + `KC_U` | Down ↔ Up |
|
||||
|mod + `KC_N` ↔ mod + `KC_P` | Next ↔ Previous |
|
||||
|mod + `KC_A` ↔ mod + `KC_E` | Home ↔ End |
|
||||
|mod + `KC_O` ↔ mod + `KC_I` | Vim jump list Older ↔ Newer |
|
||||
|`KC_J` ↔ `KC_K` | Down ↔ Up |
|
||||
|`KC_H` ↔ `KC_L` | Left ↔ Right |
|
||||
|`KC_W` ↔ `KC_B` | Forward ↔ Backward by Word |
|
||||
|
||||
(where above, "mod" is Ctrl, Alt, or GUI)
|
||||
|
||||
|
||||
## Defining alternate keys
|
||||
|
||||
Use the `get_alt_repeat_key_keycode_user()` callback to define the "alternate"
|
||||
for additional keys or override the default definitions. For example, to define
|
||||
Ctrl + Y as the alternate of Ctrl + Z, and vice versa, add the following in
|
||||
keymap.c:
|
||||
|
||||
```c
|
||||
uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods) {
|
||||
if ((mods & MOD_MASK_CTRL)) { // Was Ctrl held?
|
||||
switch (keycode) {
|
||||
case KC_Y: return C(KC_Z); // Ctrl + Y reverses to Ctrl + Z.
|
||||
case KC_Z: return C(KC_Y); // Ctrl + Z reverses to Ctrl + Y.
|
||||
}
|
||||
}
|
||||
|
||||
return KC_TRNS; // Defer to default definitions.
|
||||
}
|
||||
```
|
||||
|
||||
The `keycode` and `mods` args are the keycode and mods that were active with the
|
||||
last pressed key. The meaning of the return value from this function is:
|
||||
|
||||
* `KC_NO` – do nothing (any predefined alternate key is not used);
|
||||
* `KC_TRNS` – use the default alternate key if it exists;
|
||||
* anything else – use the specified keycode. Any keycode may be returned
|
||||
as an alternate key, including custom keycodes.
|
||||
|
||||
Another example, defining Shift + Tab as the alternate of Tab, and vice versa:
|
||||
|
||||
```c
|
||||
uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods) {
|
||||
bool shifted = (mods & MOD_MASK_SHIFT); // Was Shift held?
|
||||
switch (keycode) {
|
||||
case KC_TAB:
|
||||
if (shifted) { // If the last key was Shift + Tab,
|
||||
return KC_TAB; // ... the reverse is Tab.
|
||||
} else { // Otherwise, the last key was Tab,
|
||||
return S(KC_TAB); // ... and the reverse is Shift + Tab.
|
||||
}
|
||||
}
|
||||
|
||||
return KC_TRNS;
|
||||
}
|
||||
```
|
||||
|
||||
#### Eliminating SFBs
|
||||
|
||||
Alternate Repeat can be configured more generally to perform an action that
|
||||
"complements" the last key. Alternate Repeat is not limited to reverse
|
||||
repeating, and it need not be symmetric. You can use it to eliminate cases of
|
||||
same-finger bigrams in your layout, that is, pairs of letters typed by the same
|
||||
finger. The following addresses the top 5 same-finger bigrams in English on
|
||||
QWERTY, so that for instance "`ed`" may be typed as <kbd>E</kbd>, <kbd>Alt
|
||||
Repeat</kbd>.
|
||||
|
||||
```c
|
||||
uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods) {
|
||||
switch (keycode) {
|
||||
case KC_E: return KC_D; // For "ED" bigram.
|
||||
case KC_D: return KC_E; // For "DE" bigram.
|
||||
case KC_C: return KC_E; // For "CE" bigram.
|
||||
case KC_L: return KC_O; // For "LO" bigram.
|
||||
case KC_U: return KC_N; // For "UN" bigram.
|
||||
}
|
||||
|
||||
return KC_TRNS;
|
||||
}
|
||||
```
|
||||
|
||||
#### Typing shortcuts
|
||||
|
||||
A useful possibility is having Alternate Repeat press [a
|
||||
macro](feature_macros.md). This way macros can be used without having to
|
||||
dedicate keys to them. The following defines a couple shortcuts.
|
||||
|
||||
* Typing <kbd>K</kbd>, <kbd>Alt Repeat</kbd> produces "`keyboard`," with the
|
||||
initial "`k`" typed as usual and the "`eybord`" produced by the macro.
|
||||
* Typing <kbd>.</kbd>, <kbd>Alt Repeat</kbd> produces "`../`," handy for "up
|
||||
directory" on the shell. Similary, <kbd>.</kbd> types the initial "`.`" and
|
||||
"`./`" is produced by the macro.
|
||||
|
||||
```c
|
||||
enum custom_keycodes {
|
||||
M_KEYBOARD = SAFE_RANGE,
|
||||
M_UPDIR,
|
||||
// Other custom keys...
|
||||
};
|
||||
|
||||
uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods) {
|
||||
switch (keycode) {
|
||||
case KC_K: return M_KEYBOARD;
|
||||
case KC_DOT: return M_UPDIR;
|
||||
}
|
||||
|
||||
return KC_TRNS;
|
||||
}
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t* record) {
|
||||
switch (keycode) {
|
||||
case M_KEYBOARD: SEND_STRING(/*k*/"eyboard"); break;
|
||||
case M_UPDIR: SEND_STRING(/*.*/"./"); break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
## Ignoring certain keys and mods
|
||||
|
||||
In tracking what is "the last key" to be repeated or alternate repeated,
|
||||
modifier and layer switch keys are always ignored. This makes it possible to set
|
||||
some mods and change layers between pressing a key and repeating it. By default,
|
||||
all other (non-modifier, non-layer switch) keys are remembered so that they are
|
||||
eligible for repeating. To configure additional keys to be ignored, define
|
||||
`remember_last_key_user()` in your keymap.c.
|
||||
|
||||
#### Ignoring a key
|
||||
|
||||
The following ignores the Backspace key:
|
||||
|
||||
```c
|
||||
bool remember_last_key_user(uint16_t keycode, keyrecord_t* record,
|
||||
uint8_t* remembered_mods) {
|
||||
switch (keycode) {
|
||||
case KC_BSPC:
|
||||
return false; // Ignore backspace.
|
||||
}
|
||||
|
||||
return true; // Other keys can be repeated.
|
||||
}
|
||||
```
|
||||
|
||||
Then for instance, the Repeat key in <kbd>Left Arrow</kbd>,
|
||||
<kbd>Backspace</kbd>, <kbd>Repeat</kbd> sends Left Arrow again instead of
|
||||
repeating Backspace.
|
||||
|
||||
The `remember_last_key_user()` callback is called on every key press excluding
|
||||
modifiers and layer switches. Returning true indicates the key is remembered,
|
||||
while false means it is ignored.
|
||||
|
||||
#### Filtering remembered mods
|
||||
|
||||
The `remembered_mods` arg represents the mods that will be remembered with
|
||||
this key. It can be modified to forget certain mods. This may be
|
||||
useful to forget capitalization when repeating shifted letters, so that "Aaron"
|
||||
does not becom "AAron":
|
||||
|
||||
```c
|
||||
bool remember_last_key_user(uint16_t keycode, keyrecord_t* record,
|
||||
uint8_t* remembered_mods) {
|
||||
// Forget Shift on letter keys when Shift or AltGr are the only mods.
|
||||
switch (keycode) {
|
||||
case KC_A ... KC_Z:
|
||||
if ((*remembered_mods & ~(MOD_MASK_SHIFT | MOD_BIT(KC_RALT))) == 0) {
|
||||
*remembered_mods &= ~MOD_MASK_SHIFT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
#### Further conditions
|
||||
|
||||
Besides checking the keycode, this callback could also make conditions based on
|
||||
the current layer state (with `IS_LAYER_ON(layer)`) or mods (`get_mods()`). For
|
||||
example, the following ignores keys on layer 2 as well as key combinations
|
||||
involving GUI:
|
||||
|
||||
```c
|
||||
bool remember_last_key_user(uint16_t keycode, keyrecord_t* record,
|
||||
uint8_t* remembered_mods) {
|
||||
if (IS_LAYER_ON(2) || (get_mods() & MOD_MASK_GUI)) {
|
||||
return false; // Ignore layer 2 keys and GUI chords.
|
||||
}
|
||||
|
||||
return true; // Other keys can be repeated.
|
||||
}
|
||||
```
|
||||
|
||||
?> See [Layer Functions](feature_layers.md#functions) and [Checking Modifier
|
||||
State](feature_advanced_keycodes.md#checking-modifier-state) for further
|
||||
details.
|
||||
|
||||
|
||||
## Handle how a key is repeated
|
||||
|
||||
By default, pressing the Repeat Key will simply behave as if the last key
|
||||
were pressed again. This also works with macro keys with custom handlers,
|
||||
invoking the macro again. In case fine-tuning is needed for sensible repetition,
|
||||
you can handle how a key is repeated with `get_repeat_key_count()` within
|
||||
`process_record_user()`.
|
||||
|
||||
The `get_repeat_key_count()` function returns a signed count of times the key
|
||||
has been repeated or alternate repeated. When a key is pressed as usual,
|
||||
`get_repeat_key_count()` is 0. On the first repeat, it is 1, then the second
|
||||
repeat, 2, and so on. Negative counts are used similarly for alternate
|
||||
repeating. For instance supposing `MY_MACRO` is a custom keycode used in the
|
||||
layout:
|
||||
|
||||
```c
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t* record) {
|
||||
switch (keycode) {
|
||||
case MY_MACRO:
|
||||
if (get_repeat_key_count() > 0) {
|
||||
// MY_MACRO is being repeated!
|
||||
if (record->event.pressed) {
|
||||
SEND_STRING("repeat!");
|
||||
}
|
||||
} else {
|
||||
// MY_MACRO is being used normally.
|
||||
if (record->event.pressed) {
|
||||
SEND_STRING("macro");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
// Other macros...
|
||||
}
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
## Handle how a key is alternate repeated
|
||||
|
||||
Pressing the Alternate Repeat Key behaves as if the "alternate" of the last
|
||||
pressed key were pressed, if an alternate is defined. To define how a particular
|
||||
key is alternate repeated, use the `get_alt_repeat_key_keycode_user()` callback
|
||||
as described above to define which keycode to use as its alternate. Beyond this,
|
||||
`get_repeat_key_count()` may be used in custom handlers to fine-tune behavior
|
||||
when alternate repeating.
|
||||
|
||||
The following example defines `MY_MACRO` as its own alternate, and specially
|
||||
handles repeating and alternate repeating:
|
||||
|
||||
```c
|
||||
uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods) {
|
||||
switch (keycode) {
|
||||
case MY_MACRO: return MY_MACRO; // MY_MACRO is its own alternate.
|
||||
}
|
||||
return KC_TRNS;
|
||||
}
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t* record) {
|
||||
switch (keycode) {
|
||||
case MY_MACRO:
|
||||
if (get_repeat_key_count() > 0) { // Repeating.
|
||||
if (record->event.pressed) {
|
||||
SEND_STRING("repeat!");
|
||||
}
|
||||
} else if (get_repeat_key_count() < 0) { // Alternate repeating.
|
||||
if (record->event.pressed) {
|
||||
SEND_STRING("alt repeat!");
|
||||
}
|
||||
} else { // Used normally.
|
||||
if (record->event.pressed) {
|
||||
SEND_STRING("macro");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
// Other macros...
|
||||
}
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Functions
|
||||
|
||||
| Function | Description |
|
||||
|--------------------------------|------------------------------------------------------------------------|
|
||||
| `get_last_keycode()` | The last key's keycode, the key to be repeated. |
|
||||
| `get_last_mods()` | Mods to apply when repeating. |
|
||||
| `set_last_keycode(kc)` | Set the keycode to be repeated. |
|
||||
| `set_last_mods(mods)` | Set the mods to apply when repeating. |
|
||||
| `get_repeat_key_count()` | Signed count of times the key has been repeated or alternate repeated. |
|
||||
| `get_alt_repeat_key_keycode()` | Keycode to be used for alternate repeating. |
|
||||
|
||||
|
||||
## Additional "Alternate" keys
|
||||
|
||||
By leveraging `get_last_keycode()` in macros, it is possible to define
|
||||
additional, distinct "Alternate Repeat"-like keys. The following defines two
|
||||
keys `ALTREP2` and `ALTREP3` and implements ten shortcuts with them for common
|
||||
English 5-gram letter patterns, taking inspiration from
|
||||
[Stenotype](feature_stenography.md):
|
||||
|
||||
|
||||
| Typing | Produces | Typing | Produces |
|
||||
|----------------------------------|----------|----------------------------------|----------|
|
||||
| <kbd>A</kbd>, <kbd>ALTREP2</kbd> | `ation` | <kbd>A</kbd>, <kbd>ALTREP3</kbd> | `about` |
|
||||
| <kbd>I</kbd>, <kbd>ALTREP2</kbd> | `ition` | <kbd>I</kbd>, <kbd>ALTREP3</kbd> | `inter` |
|
||||
| <kbd>S</kbd>, <kbd>ALTREP2</kbd> | `ssion` | <kbd>S</kbd>, <kbd>ALTREP3</kbd> | `state` |
|
||||
| <kbd>T</kbd>, <kbd>ALTREP2</kbd> | `their` | <kbd>T</kbd>, <kbd>ALTREP3</kbd> | `there` |
|
||||
| <kbd>W</kbd>, <kbd>ALTREP2</kbd> | `which` | <kbd>W</kbd>, <kbd>ALTREP3</kbd> | `would` |
|
||||
|
||||
```c
|
||||
enum custom_keycodes {
|
||||
ALTREP2 = SAFE_RANGE,
|
||||
ALTREP3,
|
||||
};
|
||||
|
||||
// Use ALTREP2 and ALTREP3 in your layout...
|
||||
|
||||
bool remember_last_key_user(uint16_t keycode, keyrecord_t* record,
|
||||
uint8_t* remembered_mods) {
|
||||
switch (keycode) {
|
||||
case ALTREP2:
|
||||
case ALTREP3:
|
||||
return false; // Ignore ALTREP keys.
|
||||
}
|
||||
|
||||
return true; // Other keys can be repeated.
|
||||
}
|
||||
|
||||
static void process_altrep2(uint16_t keycode, uint8_t mods) {
|
||||
switch (keycode) {
|
||||
case KC_A: SEND_STRING(/*a*/"tion"); break;
|
||||
case KC_I: SEND_STRING(/*i*/"tion"); break;
|
||||
case KC_S: SEND_STRING(/*s*/"sion"); break;
|
||||
case KC_T: SEND_STRING(/*t*/"heir"); break;
|
||||
case KC_W: SEND_STRING(/*w*/"hich"); break;
|
||||
}
|
||||
}
|
||||
|
||||
static void process_altrep3(uint16_t keycode, uint8_t mods) {
|
||||
switch (keycode) {
|
||||
case KC_A: SEND_STRING(/*a*/"bout"); break;
|
||||
case KC_I: SEND_STRING(/*i*/"nter"); break;
|
||||
case KC_S: SEND_STRING(/*s*/"tate"); break;
|
||||
case KC_T: SEND_STRING(/*t*/"here"); break;
|
||||
case KC_W: SEND_STRING(/*w*/"ould"); break;
|
||||
}
|
||||
}
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t* record) {
|
||||
switch (keycode) {
|
||||
case ALTREP2:
|
||||
if (record->event.pressed) {
|
||||
process_altrep2(get_last_keycode(), get_last_mods());
|
||||
}
|
||||
return false;
|
||||
|
||||
case ALTREP3:
|
||||
if (record->event.pressed) {
|
||||
process_altrep3(get_last_keycode(), get_last_mods());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user