Compare commits

...

No commits in common. "master" and "gh-pages" have entirely different histories.

22552 changed files with 45400 additions and 1828245 deletions

View file

@ -1,30 +0,0 @@
---
BasedOnStyle: Google
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: 'true'
AlignConsecutiveDeclarations: 'true'
AlignOperands: 'true'
AllowAllParametersOfDeclarationOnNextLine: 'false'
AllowShortCaseLabelsOnASingleLine: 'false'
AllowShortFunctionsOnASingleLine: Empty
AllowShortLoopsOnASingleLine: 'false'
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: 'false'
BinPackArguments: 'true'
BinPackParameters: 'true'
ColumnLimit: '1000'
IndentCaseLabels: 'true'
IndentPPDirectives: AfterHash
IndentWidth: '4'
MaxEmptyLinesToKeep: '1'
PointerAlignment: Right
SortIncludes: 'false'
SpaceBeforeAssignmentOperators: 'true'
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: 'false'
SpacesBeforeTrailingComments: 1
TabWidth: '4'
UseTab: Never
...

33
.clangd
View file

@ -1,33 +0,0 @@
CompileFlags:
Add:
[
-Wno-unknown-attributes,
-Wno-maybe-uninitialized,
-Wno-unknown-warning-option,
-Wno-pointer-to-int-cast,
-Wno-int-to-void-pointer-cast,
-DPROGMEM=,
]
Remove:
[
-W*,
-mmcu=*,
-mcpu=*,
-mfpu=*,
-mfloat-abi=*,
-mno-unaligned-access,
-mno-thumb-interwork,
-mcall-prologues,
-D__has_include*,
-mlra,
]
Compiler: clang
Diagnostics:
UnusedIncludes: None
Suppress:
[
asm_invalid_output_constraint,
asm_invalid_input_constraint,
invalid_asm_value_for_constraint,
anyx86_interrupt_attribute,
]

View file

@ -1,43 +0,0 @@
# EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
end_of_line = lf
indent_style = space
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
# To match GitHub Actions formatting
[*.{yaml,yml}]
indent_size = 2
[*.md]
trim_trailing_whitespace = false
[{Makefile,*.mk}]
indent_style = tab
# Don't override anything in `lib/`...
[lib/**]
indent_style = unset
indent_size = unset
tab_width = unset
end_of_line = unset
charset = unset
spelling_language = unset
trim_trailing_whitespace = unset
insert_final_newline = unset
# ...except QMK's `lib/python`.
[{*.py,lib/python/**.py}]
end_of_line = lf
indent_style = space
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 200

96
.gitattributes vendored
View file

@ -1,96 +0,0 @@
# auto for anything unspecified
* text=auto
# sources
*.c text eol=lf
*.cc text eol=lf
*.cxx text eol=lf
*.cpp text eol=lf
*.c++ text eol=lf
*.hpp text eol=lf
*.h text eol=lf
*.h++ text eol=lf
*.hh text eol=lf
*.bat text eol=crlf
*.cmd text eol=crlf
*.coffee text eol=lf
*.css text eol=lf
*.htm text eol=lf
*.html text eol=lf
*.inc text eol=lf
*.ini text eol=crlf
*.js text eol=lf
*.jsx text eol=lf
*.json text eol=lf
*.less text eol=lf
*.php text eol=lf
*.pl text eol=lf
*.py text eol=lf
*.rb text eol=lf
*.sass text eol=lf
*.scm text eol=lf
*.scss text eol=lf
*.sh text eol=lf
*.sql text eol=lf
*.styl text eol=lf
*.ts text eol=lf
*.xml text eol=lf
*.xhtml text eol=lf
# make files (need to always use lf for compatibility with Windows 10 bash)
Makefile eol=lf
*.mk eol=lf
# make files (need to always use lf for compatibility with Windows 10 bash)
*.sh eol=lf
# documentation
*.markdown text eol=lf
*.md text eol=lf
*.mdwn text eol=lf
*.mdown text eol=lf
*.mkd text eol=lf
*.mkdn text eol=lf
*.mdtxt text eol=lf
*.mdtext text eol=lf
*.txt text eol=lf
AUTHORS text eol=lf
CHANGELOG text eol=lf
CHANGES text eol=lf
CONTRIBUTING text eol=lf
COPYING text eol=lf
INSTALL text eol=lf
license text eol=lf
LICENSE text eol=lf
NEWS text eol=lf
readme text eol=lf
*README* text eol=lf
TODO text eol=lf
GRAPHICS
*.ai binary
*.bmp binary
*.eps binary
*.gif binary
*.ico binary
*.jng binary
*.jp2 binary
*.jpg binary
*.jpeg binary
*.jpx binary
*.jxr binary
*.pdf binary
*.png binary
*.psb binary
*.psd binary
*.svg text eol=lf
*.svgz binary
*.tif binary
*.tiff binary
*.wbmp binary
*.webp binary
# hex files
*.hex binary
*.eep binary
nix/sources.nix linguist-generated=true

View file

@ -1,41 +0,0 @@
name: Bug report
description: Create a report to help us improve QMK Firmware.
title: "[Bug] "
labels: ["bug", "help wanted"]
body:
- type: markdown
attributes:
value: |
Provide a general summary of the bug in the title above.
- type: textarea
attributes:
label: Describe the Bug
description: A clear and concise description of what the bug is.
- type: input
attributes:
label: Keyboard Used
description: The name of the keyboard from the `make` or `qmk compile`/`qmk flash` commands, eg. `planck/rev6`.
- type: input
attributes:
label: Link to product page (if applicable)
- type: input
attributes:
label: Operating System
- type: textarea
attributes:
label: qmk doctor Output
description: Output from running the `qmk doctor` command.
render: text
- type: checkboxes
attributes:
label: Is AutoHotKey / Karabiner installed
options:
- label: AutoHotKey (Windows)
- label: Karabiner (macOS)
- type: input
attributes:
label: Other keyboard-related software installed
- type: textarea
attributes:
label: Additional Context
description: Add any other relevant information about the problem here.

View file

@ -1,8 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: QMK Discord
url: https://discord.gg/qmk
about: Ask questions, discuss issues and features. Chill.
- name: OLKB Subreddit
url: https://www.reddit.com/r/olkb
about: All things OLKB and QMK.

View file

@ -1,24 +0,0 @@
name: Feature request
description: Suggest a new feature or changes to existing features.
title: "[Feature Request] "
labels: ["enhancement", "help wanted"]
body:
- type: markdown
attributes:
value: |
Provide a general summary of the changes you want in the title above.
Please refrain from asking maintainers to add support for specific keyboards -- it is unlikely they will have hardware available, and will not be able to help.
Your best bet is to take the initiative, add support, then submit a PR yourself.
- type: checkboxes
attributes:
label: Feature Request Type
options:
- label: Core functionality
- label: Add-on hardware support (eg. audio, RGB, OLED screen, etc.)
- label: Alteration (enhancement/optimization) of existing feature(s)
- label: New behavior
- type: textarea
attributes:
label: Description
description: A few sentences describing what it is that you'd like to see in QMK. Additional information (such as links to spec sheets, licensing info, other related issues or PRs, etc) would be helpful.

View file

@ -1,19 +0,0 @@
name: Other issues
description: Anything else that doesn't fall into the above categories.
labels: ["help wanted", "question"]
body:
- type: markdown
attributes:
value: |
Provide a general summary of the changes you want in the title above.
- type: markdown
attributes:
value: |
Please check [https://docs.qmk.fm/#/support](https://docs.qmk.fm/#/support) for additional resources first. If that doesn't answer your question, choose the bug report template instead, as that may be more appropriate.
Please refrain from asking maintainers to add support for specific keyboards -- it is unlikely they will have hardware available, and will not be able to help.
Your best bet is to take the initiative, add support, then submit a PR yourself.
- type: textarea
attributes:
label: Issue Description
description: Describe your issue in as much detail as possible.

View file

@ -1,11 +0,0 @@
---
name: Blank issue
about: If you're 100% sure that you don't need one of the other issue templates, use
this one instead.
title: ''
labels: help wanted, question
assignees: ''
---

View file

@ -1,34 +0,0 @@
<!--- Provide a general summary of your changes in the title above. -->
<!--- Anything on lines wrapped in comments like these will not show up in the final text. -->
## Description
<!--- Describe your changes in detail here. -->
## Types of Changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply. -->
- [ ] Core
- [ ] Bugfix
- [ ] New feature
- [ ] Enhancement/optimization
- [ ] Keyboard (addition or update)
- [ ] Keymap/layout (addition or update)
- [ ] Documentation
## Issues Fixed or Closed by This PR
*
## Checklist
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [ ] My code follows the code style of this project: [**C**](https://docs.qmk.fm/#/coding_conventions_c), [**Python**](https://docs.qmk.fm/#/coding_conventions_python)
- [ ] I have read the [**PR Checklist** document](https://docs.qmk.fm/#/pr_checklist) and have made the appropriate changes.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [ ] I have read the [**CONTRIBUTING** document](https://docs.qmk.fm/#/contributing).
- [ ] I have added tests to cover my changes.
- [ ] I have tested the changes and verified that they work and don't break anything (as well as I can manage).

View file

@ -1,9 +0,0 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
labels: CI
reviewers:
- "qmk/collaborators"
schedule:
interval: "daily"

60
.github/labeler.yml vendored
View file

@ -1,60 +0,0 @@
core:
- changed-files:
- any-glob-to-any-file:
- quantum/**
- tmk_core/**
- drivers/**
- tests/**
- util/**
- platforms/**
- builddefs/*.mk
- Makefile
- '*.mk'
dependencies:
- changed-files:
- all-globs-to-any-file:
- lib/**
- '!lib/python/**'
keyboard:
- changed-files:
- all-globs-to-any-file:
- keyboards/**
- '!keyboards/**/keymaps/**'
keymap:
- changed-files:
- any-glob-to-any-file:
- users/**
- layouts/**
- keyboards/**/keymaps/**
via:
- changed-files:
- any-glob-to-any-file:
- keyboards/**/keymaps/via/*
cli:
- changed-files:
- any-glob-to-any-file:
- requirements.txt
- lib/python/**
python:
- changed-files:
- any-glob-to-any-file:
- '**/*.py'
documentation:
- changed-files:
- any-glob-to-any-file:
- docs/**
- builddefs/docsgen/**
CI:
- changed-files:
- any-glob-to-any-file:
- .github/**
dd:
- changed-files:
- any-glob-to-any-file:
- data/constants/**
- data/mappings/**
- data/schemas/**
community_module:
- changed-files:
- any-glob-to-any-file:
- modules/**

View file

@ -1,50 +0,0 @@
name: Update API Data
permissions:
contents: read
on:
push:
branches:
- master
- develop
paths:
- 'keyboards/**'
- 'layouts/community/**'
- 'lib/python/**'
- 'data/**'
- '.github/workflows/api.yml'
workflow_dispatch:
jobs:
api_data:
runs-on: ubuntu-latest
container: ghcr.io/qmk/qmk_cli
# protect against those who work in their fork on 'important' branches
if: github.repository == 'qmk/qmk_firmware'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
persist-credentials: false
- name: Install dependencies
run: |
pip3 install -r requirements-dev.txt
- name: Generate API Data
run: |
qmk generate-api
- name: Upload API Data
uses: jakejarvis/s3-sync-action@master
with:
args: --acl public-read --follow-symlinks --delete
env:
AWS_S3_BUCKET: ${{ github.ref == 'refs/heads/develop' && secrets['API_SPACE_DEVELOP'] || secrets['API_SPACE_MASTER'] }}
AWS_ACCESS_KEY_ID: ${{ secrets.SPACES_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.SPACES_SECRET_KEY }}
AWS_S3_ENDPOINT: https://nyc3.digitaloceanspaces.com
SOURCE_DIR: '.build/api_data'

View file

@ -1,20 +0,0 @@
name: Automatic Approve
permissions: {}
on:
schedule:
- cron: "*/5 * * * *"
jobs:
automatic_approve:
runs-on: ubuntu-latest
if: github.repository == 'qmk/qmk_firmware'
steps:
- uses: zvecr/automatic-approve-action@safe_files
with:
token: ${{ secrets.QMK_BOT_TOKEN }}
workflows: "labeler.yml,lint.yml,docs.yml"
safe_files: "keyboards/,docs/"

View file

@ -1,39 +0,0 @@
name: Essential files modified
permissions:
contents: write
on:
workflow_dispatch:
push:
branches:
- master
paths:
- builddefs/**/*
- drivers/**/*
- platforms/**/*
- quantum/**/*
- tests/**/*
- tmk_core/**/*
- lib/python/**/*
- util/**/*
- Makefile
- '*.mk'
jobs:
tag:
runs-on: ubuntu-latest
# protect against those who develop with their fork on master
if: github.repository == 'qmk/qmk_firmware'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Bump version and push tag
uses: anothrNick/github-tag-action@1.66.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DEFAULT_BUMP: 'patch'

View file

@ -1,139 +0,0 @@
name: CI Build Major Branch
permissions:
contents: read
actions: write
on:
push:
branches: [master, develop]
workflow_dispatch:
inputs:
branch:
type: choice
description: "Branch to build"
options: [master, develop]
env:
# https://docs.github.com/en/actions/learn-github-actions/usage-limits-billing-and-administration#usage-limits
# We've decreased it from 20 to 15 to allow for other GHA to run unimpeded
CONCURRENT_JOBS: 15
# Ensure we only have one build running at a time, cancelling any active builds if a new commit is pushed to the respective branch
concurrency:
group: ci_build-${{ github.event.inputs.branch || github.ref_name }}
cancel-in-progress: true
jobs:
determine_concurrency:
name: "Determine concurrency"
if: github.repository == 'qmk/qmk_firmware'
runs-on: ubuntu-latest
container: ghcr.io/qmk/qmk_cli
outputs:
slice_length: ${{ steps.generate_slice_length.outputs.slice_length }}
steps:
- name: Install prerequisites
run: |
apt-get update
apt-get install -y jq
- name: Disable safe.directory check
run: |
git config --global --add safe.directory '*'
- name: Checkout QMK Firmware
uses: actions/checkout@v4
- name: Determine concurrency
id: generate_slice_length
run: |
target_count=$( {
qmk find -km default 2>/dev/null
# qmk find -km xap 2>/dev/null
} | sort | uniq | wc -l)
slice_length=$((target_count / ($CONCURRENT_JOBS - 1))) # Err on the side of caution
echo "slice_length=$slice_length" >> $GITHUB_OUTPUT
build_targets:
name: "Compile keymap ${{ matrix.keymap }}"
needs: determine_concurrency
strategy:
fail-fast: false
matrix:
keymap: [default]
# keymap: [default, xap]
uses: ./.github/workflows/ci_build_major_branch_keymap.yml
with:
branch: ${{ inputs.branch || github.ref_name }}
keymap: ${{ matrix.keymap }}
slice_length: ${{ needs.determine_concurrency.outputs.slice_length }}
secrets: inherit
rollup_tasks:
name: "Consolidation"
needs: build_targets
runs-on: ubuntu-latest
steps:
- name: Disable safe.directory check
run: |
git config --global --add safe.directory '*'
- name: Checkout QMK Firmware
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download firmwares
uses: actions/download-artifact@v4
with:
pattern: firmware-*
path: .
merge-multiple: true
- name: Generate index page
run: |
python3 -m pip install -r ./util/ci/requirements.txt
./util/ci/index_generator.py > index.html
./util/ci/firmware_list_generator.py > firmware_list.json
- name: Upload to https://ci.qmk.fm/${{ inputs.branch || github.ref_name }}/${{ github.sha }}
uses: jakejarvis/s3-sync-action@master
with:
args: --acl public-read --follow-symlinks --delete --exclude '*' --include 'index.html' --include 'firmware_list.json' --include '*.hex' --include '*.bin' --include '*.uf2'
env:
AWS_S3_BUCKET: ${{ vars.CI_QMK_FM_SPACES_BUCKET }}
AWS_ACCESS_KEY_ID: ${{ secrets.CI_QMK_FM_SPACES_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CI_QMK_FM_SPACES_SECRET }}
AWS_REGION: ${{ vars.CI_QMK_FM_SPACES_REGION }}
AWS_S3_ENDPOINT: ${{ vars.CI_QMK_FM_SPACES_ENDPOINT }}
SOURCE_DIR: .
DEST_DIR: ${{ inputs.branch || github.ref_name }}/${{ github.sha }}
- name: Upload to https://ci.qmk.fm/${{ inputs.branch || github.ref_name }}/latest
uses: jakejarvis/s3-sync-action@master
with:
args: --acl public-read --follow-symlinks --delete --exclude '*' --include 'index.html' --include 'firmware_list.json' --include '*.hex' --include '*.bin' --include '*.uf2'
env:
AWS_S3_BUCKET: ${{ vars.CI_QMK_FM_SPACES_BUCKET }}
AWS_ACCESS_KEY_ID: ${{ secrets.CI_QMK_FM_SPACES_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CI_QMK_FM_SPACES_SECRET }}
AWS_REGION: ${{ vars.CI_QMK_FM_SPACES_REGION }}
AWS_S3_ENDPOINT: ${{ vars.CI_QMK_FM_SPACES_ENDPOINT }}
SOURCE_DIR: .
DEST_DIR: ${{ inputs.branch || github.ref_name }}/latest
- name: Check if failure marker file exists
id: check_failure_marker
uses: andstor/file-existence-action@v3
with:
files: ./.failed
- name: Fail build if needed
if: steps.check_failure_marker.outputs.files_exists == 'true'
run: |
# Exit with failure if the compilation stage failed
exit 1

View file

@ -1,181 +0,0 @@
name: CI Build Major Branch Keymap
permissions:
contents: read
actions: write
on:
workflow_call:
inputs:
branch:
type: string
required: true
keymap:
type: string
required: true
slice_length:
type: string
required: true
jobs:
generate_targets:
name: "Generate targets (${{ inputs.keymap }})"
runs-on: ubuntu-latest
container: ghcr.io/qmk/qmk_cli
outputs:
targets: ${{ steps.generate_targets.outputs.targets }}
steps:
- name: Install prerequisites
run: |
apt-get update
apt-get install -y jq
- name: Disable safe.directory check
run: |
git config --global --add safe.directory '*'
- name: Checkout QMK Firmware
uses: actions/checkout@v4
- name: Generate build targets
id: generate_targets
run: |
{ # Intentionally use `shuf` here so that we share manufacturers across all build groups -- some have a lot of ARM-based boards which inherently take longer
counter=0
echo -n '{'
qmk find -km ${{ inputs.keymap }} 2>/dev/null | sort | uniq | shuf | xargs -L${{ inputs.slice_length }} | while IFS=$'\n' read target ; do
if [ $counter -gt 0 ]; then
echo -n ','
fi
counter=$((counter+1))
printf "\"group %02d\":{" $counter
echo -n '"targets":"'
echo $target | tr ' ' '\n' | sort | uniq | xargs echo -n
echo -n '"}'
done
echo -n '}'
} | sed -e 's@\n@@g' > targets.json
# Output the target keys as a variable
echo "targets=$(jq -c 'keys' targets.json)" >> $GITHUB_OUTPUT
- name: Upload targets json
uses: actions/upload-artifact@v4
with:
name: targets-${{ inputs.keymap }}
path: targets.json
build_targets:
name: "Compile ${{ matrix.target }} (${{ inputs.keymap }})"
needs: generate_targets
runs-on: ubuntu-latest
container: ghcr.io/qmk/qmk_cli
continue-on-error: true
strategy:
matrix:
target: ${{ fromJson(needs.generate_targets.outputs.targets) }}
steps:
- name: Install prerequisites
run: |
apt-get update
apt-get install -y jq
- name: Disable safe.directory check
run: |
git config --global --add safe.directory '*'
- name: Checkout QMK Firmware
uses: actions/checkout@v4
- name: Get target definitions
uses: actions/download-artifact@v4
with:
name: targets-${{ inputs.keymap }}
path: .
- name: Deploy submodules
run: |
qmk git-submodule -f
- name: Dump targets
run: |
jq -r '.["${{ matrix.target }}"].targets' targets.json | tr ' ' '\n' | sort
- name: Build targets
continue-on-error: true
run: |
export NCPUS=$(( $(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null) -1 ))
qmk mass-compile -t -j $NCPUS -e DUMP_CI_METADATA=yes $(jq -r '.["${{ matrix.target }}"].targets' targets.json) || touch .failed
- name: Upload binaries
uses: actions/upload-artifact@v4
with:
name: firmware-${{ inputs.keymap }}-${{ matrix.target }}
if-no-files-found: ignore
path: |
*.bin
*.hex
*.uf2
.build/failed.*
.failed
- name: Fail build if any group failed
run: |
# Exit with failure if the compilation stage failed
[ ! -f .failed ] || exit 1
repack_firmware:
if: always()
name: "Repack artifacts"
needs: build_targets
runs-on: ubuntu-latest
steps:
- name: Checkout QMK Firmware
uses: actions/checkout@v4
- name: Download firmwares
uses: actions/download-artifact@v4
with:
pattern: firmware-${{ inputs.keymap }}-*
path: .
merge-multiple: true
- name: Upload all firmwares
uses: actions/upload-artifact@v4
with:
name: firmware-${{ inputs.keymap }}
if-no-files-found: ignore
path: |
*.bin
*.hex
*.uf2
.build/failed.*
.failed
- name: Generate output logs
run: |
# Generate the step summary markdown
./util/ci/generate_failure_markdown.sh > $GITHUB_STEP_SUMMARY || true
# Truncate to a maximum of 1MB to deal with GitHub workflow limit
truncate --size='<960K' $GITHUB_STEP_SUMMARY || true
- name: Delete temporary build artifacts
uses: geekyeggo/delete-artifact@v5
with:
name: |
firmware-${{ inputs.keymap }}-*
targets-${{ inputs.keymap }}
- name: 'CI Discord Notification'
if: always() && !cancelled()
working-directory: util/ci/
env:
DISCORD_WEBHOOK: ${{ secrets.CI_DISCORD_WEBHOOK }}
run: |
python3 -m pip install -r requirements.txt
python3 ./discord-results.py --branch ${{ inputs.branch || github.ref_name }} --sha $(git rev-parse HEAD) --keymap ${{ inputs.keymap }} --url ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

View file

@ -1,34 +0,0 @@
name: CLI CI
permissions:
contents: read
on:
push:
branches:
- master
- develop
pull_request:
paths:
- 'lib/python/**'
- 'requirements.txt'
- '.github/workflows/cli.yml'
jobs:
test:
runs-on: ubuntu-latest
container: ghcr.io/qmk/qmk_cli
steps:
- name: Disable safe.directory check
run : git config --global --add safe.directory '*'
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install dependencies
run: pip3 install -r requirements-dev.txt
- name: Run tests
run: qmk pytest

View file

@ -1,37 +0,0 @@
name: Update develop after master merge
permissions:
contents: write
on:
push:
branches:
- master
jobs:
develop_update:
runs-on: ubuntu-latest
if: github.repository == 'qmk/qmk_firmware'
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.QMK_BOT_TOKEN }}
fetch-depth: 0
- name: Disable automatic eol conversion
run: |
echo "* -text" > .git/info/attributes
- name: Checkout develop
run: |
git fetch origin master develop
git checkout develop
- name: Update develop from master
run: |
git config --global user.name "QMK Bot"
git config --global user.email "hello@qmk.fm"
git merge origin/master
git push origin develop

View file

@ -1,65 +0,0 @@
name: Generate Docs
permissions:
contents: write
on:
push:
branches:
- master
paths:
- 'builddefs/docsgen/**'
- 'tmk_core/**'
- 'quantum/**'
- 'platforms/**'
- 'docs/**'
- '.github/workflows/docs.yml'
pull_request:
paths:
- 'builddefs/docsgen/**'
- 'docs/**'
- '.github/workflows/docs.yml'
defaults:
run:
shell: bash
jobs:
generate:
runs-on: ubuntu-latest
container: ghcr.io/qmk/qmk_cli
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Install dependencies
run: |
apt-get update && apt-get install -y rsync doxygen
# install nvm
touch $HOME/.bashrc
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
- name: Install node
run: |
source $HOME/.bashrc
nvm install 20
nvm use 20
corepack enable
- name: Build docs
run: |
source $HOME/.bashrc
nvm use 20
qmk --verbose generate-docs
- name: Deploy
if: ${{ github.event_name == 'push' && github.repository == 'qmk/qmk_firmware' }}
uses: JamesIves/github-pages-deploy-action@v4.7.3
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: gh-pages
folder: .build/docs
git-config-name: QMK Bot
git-config-email: hello@qmk.fm

View file

@ -1,43 +0,0 @@
name: Update feature branches after develop merge
permissions:
contents: write
on:
push:
branches:
- develop
jobs:
feature_branch_update:
runs-on: ubuntu-latest
if: github.repository == 'qmk/qmk_firmware'
strategy:
matrix:
branch:
- xap
- riot
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.QMK_BOT_TOKEN }}
fetch-depth: 0
- name: Disable automatic eol conversion
run: |
echo "* -text" > .git/info/attributes
- name: Checkout branch
run: |
git fetch origin develop ${{ matrix.branch }}
git checkout ${{ matrix.branch }}
- name: Update branch from develop
run: |
git config --global user.name "QMK Bot"
git config --global user.email "hello@qmk.fm"
git merge origin/develop
git push origin ${{ matrix.branch }}

View file

@ -1,58 +0,0 @@
name: PR Lint Format
permissions:
contents: read
on:
pull_request:
paths:
- 'drivers/**'
- 'lib/arm_atsam/**'
- 'lib/lib8tion/**'
- 'lib/python/**'
- 'modules/**'
- 'platforms/**'
- 'quantum/**'
- 'tests/**'
- 'tmk_core/**'
jobs:
lint:
runs-on: ubuntu-latest
container: ghcr.io/qmk/qmk_cli
steps:
- name: Disable safe.directory check
run : git config --global --add safe.directory '*'
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install dependencies
run: |
pip3 install -r requirements-dev.txt
- name: Get changed files
id: file_changes
uses: tj-actions/changed-files@v46
with:
use_rest_api: true
- name: Run qmk formatters
shell: 'bash {0}'
run: |
echo '${{ steps.file_changes.outputs.added_files}}' '${{ steps.file_changes.outputs.modified_files}}' > ~/files_changed.txt
qmk format-c --core-only $(< ~/files_changed.txt) || true
qmk format-python $(< ~/files_changed.txt) || true
qmk format-text $(< ~/files_changed.txt) || true
- name: Fail when formatting required
run: |
git diff
for file in $(git diff --name-only); do
echo "File '${file}' Requires Formatting"
echo "::error file=${file}::Requires Formatting"
done
test -z "$(git diff --name-only)"

View file

@ -1,59 +0,0 @@
name: Lint Format
permissions:
contents: read
on:
push:
branches:
- master
- develop
jobs:
lint:
runs-on: ubuntu-latest
container: ghcr.io/qmk/qmk_cli
steps:
- name: Disable safe.directory check
run : git config --global --add safe.directory '*'
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Disable automatic eol conversion
run: |
echo "* -text" > .git/info/attributes
- name: Install dependencies
run: |
pip3 install -r requirements-dev.txt
- name: Run qmk formatters
shell: 'bash {0}'
run: |
qmk format-c -a
qmk format-python -a
qmk format-text -a
git diff
- uses: rlespinasse/github-slug-action@v5
- name: Become QMK Bot
run: |
git config user.name 'QMK Bot'
git config user.email 'hello@qmk.fm'
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
if: ${{ github.repository == 'qmk/qmk_firmware'}}
with:
token: ${{ secrets.QMK_BOT_TOKEN }}
delete-branch: true
branch: bugfix/format_${{ env.GITHUB_REF_SLUG }}
author: QMK Bot <hello@qmk.fm>
committer: QMK Bot <hello@qmk.fm>
commit-message: Format code according to conventions
title: '[CI] Format code according to conventions'

View file

@ -1,13 +0,0 @@
name: "Pull Request Labeler"
on:
- pull_request_target
jobs:
triage:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v5

View file

@ -1,87 +0,0 @@
name: PR Lint keyboards
permissions:
contents: read
on:
pull_request:
paths:
- 'keyboards/**'
jobs:
lint:
runs-on: ubuntu-latest
container: ghcr.io/qmk/qmk_cli
steps:
- name: Disable safe.directory check
run : git config --global --add safe.directory '*'
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install dependencies
run: pip3 install -r requirements-dev.txt
- name: Get changed files
id: file_changes
uses: tj-actions/changed-files@v46
with:
use_rest_api: true
- name: Print info
run: |
git rev-parse --short HEAD
echo ${{ github.event.pull_request.base.sha }}
echo '${{ steps.file_changes.outputs.all_changed_files}}'
- name: Run qmk lint
if: always()
shell: 'bash {0}'
run: |
QMK_CHANGES=$(echo -e '${{ steps.file_changes.outputs.all_changed_files}}' | sed 's/ /\n/g')
QMK_KEYBOARDS=$(qmk list-keyboards)
exit_code=0
for KB in $QMK_KEYBOARDS; do
KEYBOARD_CHANGES=$(echo "$QMK_CHANGES" | grep -E '^(keyboards/'${KB}'/)')
if [[ -z "$KEYBOARD_CHANGES" ]]; then
# skip as no changes for this keyboard
continue
fi
KEYMAP_ONLY=$(echo "$KEYBOARD_CHANGES" | grep -cv /keymaps/)
if [[ $KEYMAP_ONLY -gt 0 ]]; then
echo "linting ${KB}"
qmk lint --keyboard ${KB} && qmk info -l --keyboard ${KB}
exit_code=$(($exit_code + $?))
fi
done
qmk format-text ${{ steps.file_changes.outputs.all_changed_files}} || true
for file in ${{ steps.file_changes.outputs.all_changed_files}}; do
if [[ -f $file ]]; then
if ! git diff --quiet $file; then
echo "File '${file}' Requires Formatting"
echo "::error file=${file}::Requires Formatting"
exit_code=$(($exit_code + 1))
fi
fi
done
if [[ $exit_code -gt 255 ]]; then
exit 255
fi
exit $exit_code
- name: Verify keyboard aliases
if: always()
shell: 'bash {0}'
run: |
git reset --hard
git clean -xfd
qmk ci-validate-aliases

View file

@ -1,36 +0,0 @@
name: PR Regenerate Files
permissions:
contents: read
on:
pull_request:
paths:
- 'data/constants/**'
- 'lib/python/**'
jobs:
regen:
runs-on: ubuntu-latest
container: ghcr.io/qmk/qmk_cli
steps:
- name: Disable safe.directory check
run : git config --global --add safe.directory '*'
- uses: actions/checkout@v4
- name: Run qmk generators
run: |
util/regen.sh
git diff
- name: Fail when regeneration required
run: |
git diff
for file in $(git diff --name-only); do
echo "File '${file}' Requires Regeneration"
echo "::error file=${file}::Requires Regeneration"
done
test -z "$(git diff --name-only)"

View file

@ -1,46 +0,0 @@
name: Regenerate Files
permissions:
contents: write
on:
push:
branches:
- master
- develop
jobs:
regen:
runs-on: ubuntu-latest
container: ghcr.io/qmk/qmk_cli
steps:
- name: Disable safe.directory check
run : git config --global --add safe.directory '*'
- uses: actions/checkout@v4
- name: Run qmk generators
run: |
util/regen.sh
git diff
- uses: rlespinasse/github-slug-action@v5
- name: Become QMK Bot
run: |
git config user.name 'QMK Bot'
git config user.email 'hello@qmk.fm'
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
if: ${{ github.repository == 'qmk/qmk_firmware'}}
with:
token: ${{ secrets.QMK_BOT_TOKEN }}
delete-branch: true
branch: bugfix/regen_${{ env.GITHUB_REF_SLUG }}
author: QMK Bot <hello@qmk.fm>
committer: QMK Bot <hello@qmk.fm>
commit-message: Regenerate Files
title: '[CI] Regenerate Files'

View file

@ -1,66 +0,0 @@
name: 'Close stale issues and PRs'
permissions:
issues: write
pull-requests: write
actions: write
on:
schedule:
- cron: '30 1 * * *'
workflow_dispatch:
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@main
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
remove-stale-when-updated: true
exempt-draft-pr: true
ascending: true
operations-per-run: 150
stale-issue-label: stale
days-before-issue-stale: 90
days-before-issue-close: 30
exempt-issue-labels: bug,in progress,on hold,discussion,to do
stale-issue-message: >
This issue has been automatically marked as stale because it has not had activity in the
last 90 days. It will be closed in the next 30 days unless it is tagged properly or other activity
occurs.
For maintainers: Please label with `bug`, `in progress`, `on hold`, `discussion` or `to do` to prevent
the issue from being re-flagged.
close-issue-message: >
This issue has been automatically closed because it has not had activity in the last 30 days.
If this issue is still valid, re-open the issue and let us know.
// [stale-action-closed]
stale-pr-label: stale
days-before-pr-stale: 45
days-before-pr-close: 30
exempt-pr-labels: bug,awaiting review,breaking_change,in progress,on hold,needs-core-wireless,crippled-firmware
stale-pr-message: >
Thank you for your contribution!
This pull request has been automatically marked as stale because it has not had
activity in the last 45 days. It will be closed in 30 days if no further activity occurs.
Please feel free to give a status update now, or re-open when it's ready.
For maintainers: Please label with `bug`, `awaiting review`, `breaking_change`, `in progress`, or `on hold`
to prevent the issue from being re-flagged.
close-pr-message: >
Thank you for your contribution!
This pull request has been automatically closed because it has not had activity in the last 30 days.
Please feel free to give a status update now, ping for review, or re-open when it's ready.
// [stale-action-closed]

View file

@ -1,35 +0,0 @@
name: Unit Tests
permissions:
contents: read
on:
push:
branches:
- master
- develop
pull_request:
paths:
- 'builddefs/**'
- 'quantum/**'
- 'platforms/**'
- 'tmk_core/**'
- 'tests/**'
- '*.mk'
- 'Makefile'
- '.github/workflows/unit_test.yml'
jobs:
test:
runs-on: ubuntu-latest
container: ghcr.io/qmk/qmk_cli
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install dependencies
run: pip3 install -r requirements-dev.txt
- name: Run tests
run: qmk test-c

122
.gitignore vendored
View file

@ -1,122 +0,0 @@
# Junk files
*.bak
*.swp
*~
.DS_Store
._*
# Merge files
*.orig
*.rej
# Build artifacts
.clang_complete
.build/
*.elf
*.log
*.lss
*.lst
*.map
*.o
*.a
*.so
*.dylib
*.dll
*.la
*.stackdump
*.sym
index.html
firmware_list.json
# QMK-specific
api_data/v1
quantum/version.h
*.bin
*.eep
*.hex
*.qmk
*.uf2
# DD config at wrong location
/keyboards/**/keymaps/*/info.json
/keyboards/**/keymaps/*/keyboard.json
# Old-style QMK Makefiles
/keyboards/**/Makefile
# kbfirmware....
/keyboards/**/kb.h
/keyboards/**/kb.c
# Eclipse/PyCharm/Other IDE Settings
*.iml
.browse.VC.db*
.cproject
.idea
.idea/
.project
.settings/
# ?
.dep
.history/
build/
cmake-build-debug
CMakeLists.txt
*.pdf
# Let these ones be user specific, since we have so many different configurations
*.code-workspace
.stfolder
.tags
.vscode/c_cpp_properties.json
.vscode/ipch/
.vscode/last.sql
.vscode/launch.json
.vscode/tasks.json
.vscode/temp.sql
tags
# Ignore image/font files
*.bmp
*.wbmp
*.gif
*.jpg
*.jpeg
*.png
*.apng
*.mng
*.svg
*.webp
*.webm
*.avi
*.mp4
*.mpeg
*.ttf
*.otf
# Things Travis sees
/.vs
id_rsa_*
secrets.tar
# Python things
__pycache__
.python-version
.venv
# Prerequisites for updating ChibiOS
/util/fmpp*
# Allow to exist but don't include it in the repo
user_song_list.h
# clangd
compile_commands.json
.clangd/
.cache/
# VIA(L) files that don't belong in QMK repo
via*.json
/keyboards/**/keymaps/via/*
/keyboards/**/keymaps/vial/*

27
.gitmodules vendored
View file

@ -1,27 +0,0 @@
[submodule "lib/chibios"]
path = lib/chibios
url = https://github.com/qmk/ChibiOS
branch = master
[submodule "lib/chibios-contrib"]
path = lib/chibios-contrib
url = https://github.com/qmk/ChibiOS-Contrib
branch = master
[submodule "lib/googletest"]
path = lib/googletest
url = https://github.com/qmk/googletest
[submodule "lib/lufa"]
path = lib/lufa
url = https://github.com/qmk/lufa
[submodule "lib/vusb"]
path = lib/vusb
url = https://github.com/qmk/v-usb
[submodule "lib/printf"]
path = lib/printf
url = https://github.com/qmk/printf
[submodule "lib/pico-sdk"]
path = lib/pico-sdk
url = https://github.com/qmk/pico-sdk.git
[submodule "lib/lvgl"]
path = lib/lvgl
url = https://github.com/qmk/lvgl.git
branch = release/v8.2

View file

@ -1,10 +0,0 @@
// Suggested extensions
{
"recommendations": [
"EditorConfig.EditorConfig",
"xaver.clang-format",
"llvm-vs-code-extensions.vscode-clangd",
"bierner.github-markdown-preview",
"donjayamanne.git-extension-pack"
]
}

57
.vscode/settings.json vendored
View file

@ -1,57 +0,0 @@
// Place your settings in this file to overwrite default and user settings.
{
// Unofficially, QMK uses spaces for indentation
"editor.insertSpaces": true,
// Configure glob patterns for excluding files and folders.
"files.exclude": {
"**/.build": true,
"**/*.hex": true,
"**/*.bin": true,
"**/*.uf2": true
},
"files.associations": {
// QMK Filetypes
"keyboard.json": "jsonc",
"info.json": "jsonc",
"keymap.json": "jsonc",
"qmk.json": "jsonc",
"qmk_module.json": "jsonc",
// Standard filetypes
"*.h": "c",
"*.c": "c",
"*.inc": "c",
"*.cpp": "cpp",
"*.hpp": "cpp",
"xstddef": "c",
"type_traits": "c",
"utility": "c",
"ranges": "c"
},
"[markdown]": {
"editor.trimAutoWhitespace": false,
"files.trimTrailingWhitespace": false
},
"python.formatting.provider": "yapf",
"[json]": {
"editor.formatOnSave": false
},
"clangd.arguments": ["--header-insertion=never"],
"json.schemas": [
{
"fileMatch": ["qmk.json"],
"url": "./data/schemas/user_repo_v1_1.jsonschema"
},
{
"fileMatch": ["qmk_module.json"],
"url": "./data/schemas/community_module.jsonschema"
},
{
"fileMatch": ["keyboard.json", "info.json"],
"url": "./data/schemas/keyboard.jsonschema"
},
{
"fileMatch": ["keymap.json"],
"url": "./data/schemas/keymap.jsonschema"
}
]
}

1
CNAME Normal file
View file

@ -0,0 +1 @@
docs.qmk.fm

View file

@ -7,7 +7,7 @@ This document marks the inaugural Breaking Change merge. A list of changes follo
## Core code formatting with clang-format ## Core code formatting with clang-format
* All core files (`drivers/`, `quantum/`, `tests/`, and `tmk_core/`) have been formatted with clang-format * All core files (`drivers/`, `quantum/`, `tests/`, and `tmk_core/`) have been formatted with clang-format
* A travis process to reformat PRs on merge has been instituted * A travis process to reformat PR's on merge has been instituted
* You can use the new CLI command `qmk cformat` to format before submitting your PR if you wish. * You can use the new CLI command `qmk cformat` to format before submitting your PR if you wish.
## LUFA USB descriptor cleanup ## LUFA USB descriptor cleanup
@ -20,7 +20,7 @@ This document marks the inaugural Breaking Change merge. A list of changes follo
* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()` * `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()`
* The end result of removing this obsolete feature should result in a decent reduction in firmware size and code complexity * The end result of removing this obsolete feature should result in a decent reduction in firmware size and code complexity
* All keymaps affected are recommended to switch away from `fn_actions` in favour of the [custom keycode](../custom_quantum_functions) and [macro](../feature_macros) features * All keymaps affected are recommended to switch away from `fn_actions` in favour of the [custom keycode](https://docs.qmk.fm/#/custom_quantum_functions) and [macro](https://docs.qmk.fm/#/feature_macros) features
## Update Atreus to current code conventions ## Update Atreus to current code conventions
@ -30,20 +30,20 @@ This document marks the inaugural Breaking Change merge. A list of changes follo
## Backport changes to keymap language files from ZSA fork ## Backport changes to keymap language files from ZSA fork
* Fixes an issue in the `keymap_br_abnt2.h` file that includes the wrong source (`keymap_common.h` instead of `keymap.h`) * Fixes an issue in the `keymap_br_abnt2.h` file that includes the wrong source (`keymap_common.h` instead of `keymap.h`)
* Updates the `keymap_swedish.h` file to be specific to swedish, and not just "nordic" in general. * Updates the `keymap_swedish.h` file to be specific to swedish, and not just "nordic" in general.
* Any keymaps using this will need to remove `NO_*` and replace it with `SE_*`. * Any keymaps using this will need to remove `NO_*` and replace it with `SE_*`.
## Update repo to use LUFA as a git submodule ## Update repo to use LUFA as a git submodule
* `/lib/LUFA` removed from the repo * `/lib/LUFA` removed from the repo
* LUFA set as a submodule, pointing to qmk/lufa * LUFA set as a submodule, pointing to qmk/lufa
* This should allow more flexibility with LUFA, and allow us to keep the sub-module up to date, a lot more easily. It was ~2 years out of date with no easy path to fix that. This prevents that from being an issue in the future * This should allow more flexibility with LUFA, and allow us to keep the sub-module up to date, a lot more easily. It was ~2 years out of date with no easy path to fix that. This prevents that from being an issue in the future
## Migrating `ACTION_BACKLIGHT_*()` entries in `fn_actions` to `BL_` keycodes ## Migrating `ACTION_BACKLIGHT_*()` entries in `fn_actions` to `BL_` keycodes
* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()` * `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()`
* All keymaps using these actions have had the relevant `KC_FN*` keys replaced with the equivalent `BL_*` keys * All keymaps using these actions have had the relevant `KC_FN*` keys replaced with the equivalent `BL_*` keys
* If you currently use `KC_FN*` you will need to replace `fn_actions` with the [custom keycode](../custom_quantum_functions) and [macro](../feature_macros) features * If you currently use `KC_FN*` you will need to replace `fn_actions` with the [custom keycode](https://docs.qmk.fm/#/custom_quantum_functions) and [macro](https://docs.qmk.fm/#/feature_macros) features
## Remove `KC_DELT` alias in favor of `KC_DEL` ## Remove `KC_DELT` alias in favor of `KC_DEL`

View file

@ -51,7 +51,7 @@ Four times a year QMK runs a process for merging Breaking Changes. A Breaking Ch
* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()` * `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()`
* The end result of removing this obsolete feature should result in a decent reduction in firmware size and code complexity * The end result of removing this obsolete feature should result in a decent reduction in firmware size and code complexity
* All keymaps affected are recommended to switch away from `fn_actions` in favour of the [custom keycode](../custom_quantum_functions) and [macro](../feature_macros) features * All keymaps affected are recommended to switch away from `fn_actions` in favour of the [custom keycode](https://docs.qmk.fm/#/custom_quantum_functions) and [macro](https://docs.qmk.fm/#/feature_macros) features
## Moving backlight keycode handling to `process_keycode/` ## Moving backlight keycode handling to `process_keycode/`

View file

@ -3,9 +3,9 @@
Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps. Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps.
## Changes Requiring User Action {#changes-requiring-user-action} ## Changes Requiring User Action :id=changes-requiring-user-action
### Relocated Keyboards {#relocated-keyboards} ### Relocated Keyboards :id=relocated-keyboards
#### The Key Company project consolidation ([#9547](https://github.com/qmk/qmk_firmware/pull/9547)) #### The Key Company project consolidation ([#9547](https://github.com/qmk/qmk_firmware/pull/9547))
#### relocating boards by flehrad to flehrad/ folder ([#9635](https://github.com/qmk/qmk_firmware/pull/9635)) #### relocating boards by flehrad to flehrad/ folder ([#9635](https://github.com/qmk/qmk_firmware/pull/9635))
@ -24,7 +24,7 @@ handwired/numbrero | flehrad/numbrero
snagpad | flehrad/snagpad snagpad | flehrad/snagpad
handwired/tradestation | flehrad/tradestation handwired/tradestation | flehrad/tradestation
### Updated Keyboard Codebases {#keyboard-updates} ### Updated Keyboard Codebases :id=keyboard-updates
#### Keebio RGB wiring update ([#7754](https://github.com/qmk/qmk_firmware/pull/7754)) #### Keebio RGB wiring update ([#7754](https://github.com/qmk/qmk_firmware/pull/7754))
@ -46,7 +46,7 @@ This change affects:
* Quefrency rev1 * Quefrency rev1
* Viterbi, revs. 1 and 2 * Viterbi, revs. 1 and 2
### Changes to Core Functionality {#core-updates} ### Changes to Core Functionality :id=core-updates
* Bigger Combo index ([#9318](https://github.com/qmk/qmk_firmware/pull/9318)) * Bigger Combo index ([#9318](https://github.com/qmk/qmk_firmware/pull/9318))
@ -58,14 +58,14 @@ Any fork that uses `process_combo_event` needs to update the function's first ar
* New function: `void process_combo_event(uint16_t combo_index, bool pressed)` * New function: `void process_combo_event(uint16_t combo_index, bool pressed)`
## Core Changes {#core-changes} ## Core Changes :id=core-changes
### Fixes {#core-fixes} ### Fixes :id=core-fixes
* Mousekeys: scrolling acceleration is no longer coupled to mouse movement acceleration ([#9174](https://github.com/qmk/qmk_firmware/pull/9174)) * Mousekeys: scrolling acceleration is no longer coupled to mouse movement acceleration ([#9174](https://github.com/qmk/qmk_firmware/pull/9174))
* Keymap Extras: correctly assign Question Mark in Czech layout ([#9987](https://github.com/qmk/qmk_firmware/pull/9987)) * Keymap Extras: correctly assign Question Mark in Czech layout ([#9987](https://github.com/qmk/qmk_firmware/pull/9987))
### Additions and Enhancements {#core-additions} ### Additions and Enhancements :id=core-additions
* allow for WS2812 PWM to work on DMAMUX-capable devices ([#9471](https://github.com/qmk/qmk_firmware/pull/9471)) * allow for WS2812 PWM to work on DMAMUX-capable devices ([#9471](https://github.com/qmk/qmk_firmware/pull/9471))
* Newer STM32 MCUs have a DMAMUX peripheral, which allows mapping of DMAs to different DMA streams, rather than hard-defining the target streams in silicon. * Newer STM32 MCUs have a DMAMUX peripheral, which allows mapping of DMAs to different DMA streams, rather than hard-defining the target streams in silicon.
@ -109,7 +109,7 @@ Any fork that uses `process_combo_event` needs to update the function's first ar
* The K-Type has been refactored to use QMK's native matrix scanning routine, and now has partial support for the RGB Matrix feature. * The K-Type has been refactored to use QMK's native matrix scanning routine, and now has partial support for the RGB Matrix feature.
* Joysticks can now be used without defining analog pins ([#10169](https://github.com/qmk/qmk_firmware/pull/10169)) * Joysticks can now be used without defining analog pins ([#10169](https://github.com/qmk/qmk_firmware/pull/10169))
### Clean-ups and Optimizations {#core-optimizations} ### Clean-ups and Optimizations :id=core-optimizations
* iWRAP protocol removed ([#9284](https://github.com/qmk/qmk_firmware/pull/9284)) * iWRAP protocol removed ([#9284](https://github.com/qmk/qmk_firmware/pull/9284))
* work begun for consolidation of ChibiOS platform files ([#8327](https://github.com/qmk/qmk_firmware/pull/8327) and [#9315](https://github.com/qmk/qmk_firmware/pull/9315)) * work begun for consolidation of ChibiOS platform files ([#8327](https://github.com/qmk/qmk_firmware/pull/8327) and [#9315](https://github.com/qmk/qmk_firmware/pull/9315))
@ -140,7 +140,7 @@ Any fork that uses `process_combo_event` needs to update the function's first ar
* remove support for Adafruit EZ Key Bluetooth controller ([#10103](https://github.com/qmk/qmk_firmware/pull/10103)) * remove support for Adafruit EZ Key Bluetooth controller ([#10103](https://github.com/qmk/qmk_firmware/pull/10103))
## QMK Infrastructure and Internals {#qmk-internals} ## QMK Infrastructure and Internals :id=qmk-internals
* Attempt to fix CI for non-master branches. ([#9308](https://github.com/qmk/qmk_firmware/pull/9308)) * Attempt to fix CI for non-master branches. ([#9308](https://github.com/qmk/qmk_firmware/pull/9308))
* Actually fetch the branch we're attempting to compare against. * Actually fetch the branch we're attempting to compare against.

View file

@ -3,9 +3,9 @@
Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps. Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps.
## Changes Requiring User Action {#changes-requiring-user-action} ## Changes Requiring User Action :id=changes-requiring-user-action
### Relocated Keyboards {#relocated-keyboards} ### Relocated Keyboards :id=relocated-keyboards
#### Reduce Helix keyboard build variation ([#8669](https://github.com/qmk/qmk_firmware/pull/8669)) #### Reduce Helix keyboard build variation ([#8669](https://github.com/qmk/qmk_firmware/pull/8669))
@ -88,21 +88,21 @@ The Valor and Dawn60 keyboards by Xelus22 both now require their revisions to be
| xelus/valor | xelus/valor/rev1 | | xelus/valor | xelus/valor/rev1 |
### Updated Keyboard Codebases {#keyboard-updates} ### Updated Keyboard Codebases :id=keyboard-updates
#### AEboards EXT65 Refactor ([#10820](https://github.com/qmk/qmk_firmware/pull/10820)) #### AEboards EXT65 Refactor ([#10820](https://github.com/qmk/qmk_firmware/pull/10820))
The EXT65 codebase has been reworked so keymaps can be used with either revision. The EXT65 codebase has been reworked so keymaps can be used with either revision.
## Core Changes {#core-changes} ## Core Changes :id=core-changes
### Fixes {#core-fixes} ### Fixes :id=core-fixes
* Reconnect the USB if users wake up a computer from the keyboard to restore the USB state ([#10088](https://github.com/qmk/qmk_firmware/pull/10088)) * Reconnect the USB if users wake up a computer from the keyboard to restore the USB state ([#10088](https://github.com/qmk/qmk_firmware/pull/10088))
* Fix cursor position bug in oled_write_raw functions ([#10800](https://github.com/qmk/qmk_firmware/pull/10800)) * Fix cursor position bug in oled_write_raw functions ([#10800](https://github.com/qmk/qmk_firmware/pull/10800))
### Additions and Enhancements {#core-additions} ### Additions and Enhancements :id=core-additions
* Allow MATRIX_ROWS to be greater than 32 ([#10183](https://github.com/qmk/qmk_firmware/pull/10183)) * Allow MATRIX_ROWS to be greater than 32 ([#10183](https://github.com/qmk/qmk_firmware/pull/10183))
* Add support for soft serial to ATmega32U2 ([#10204](https://github.com/qmk/qmk_firmware/pull/10204)) * Add support for soft serial to ATmega32U2 ([#10204](https://github.com/qmk/qmk_firmware/pull/10204))
@ -119,7 +119,7 @@ The EXT65 codebase has been reworked so keymaps can be used with either revision
* Add AT90USB support for serial.c ([#10706](https://github.com/qmk/qmk_firmware/pull/10706)) * Add AT90USB support for serial.c ([#10706](https://github.com/qmk/qmk_firmware/pull/10706))
* Auto shift: support repeats and early registration (#9826) * Auto shift: support repeats and early registration (#9826)
### Clean-ups and Optimizations {#core-optimizations} ### Clean-ups and Optimizations :id=core-optimizations
* Haptic and solenoid cleanup ([#9700](https://github.com/qmk/qmk_firmware/pull/9700)) * Haptic and solenoid cleanup ([#9700](https://github.com/qmk/qmk_firmware/pull/9700))
* XD75 cleanup ([#10524](https://github.com/qmk/qmk_firmware/pull/10524)) * XD75 cleanup ([#10524](https://github.com/qmk/qmk_firmware/pull/10524))
@ -129,7 +129,7 @@ The EXT65 codebase has been reworked so keymaps can be used with either revision
* Remove references to HD44780 ([#10735](https://github.com/qmk/qmk_firmware/pull/10735)) * Remove references to HD44780 ([#10735](https://github.com/qmk/qmk_firmware/pull/10735))
## QMK Infrastructure and Internals {#qmk-internals} ## QMK Infrastructure and Internals :id=qmk-internals
* Add ability to build a subset of all keyboards based on platform. ([#10420](https://github.com/qmk/qmk_firmware/pull/10420)) * Add ability to build a subset of all keyboards based on platform. ([#10420](https://github.com/qmk/qmk_firmware/pull/10420))
* Initialise EEPROM drivers at startup, instead of upon first execution ([#10438](https://github.com/qmk/qmk_firmware/pull/10438)) * Initialise EEPROM drivers at startup, instead of upon first execution ([#10438](https://github.com/qmk/qmk_firmware/pull/10438))

View file

@ -1,30 +1,30 @@
# QMK Breaking Changes - 2021 May 29 Changelog # QMK Breaking Changes - 2021 May 29 Changelog
## Notable Changes {#notable-changes} ## Notable Changes :id=notable-changes
### RGB Matrix support for split common ([#11055](https://github.com/qmk/qmk_firmware/pull/11055)) {#rgb-matrix-split-common} ### RGB Matrix support for split common ([#11055](https://github.com/qmk/qmk_firmware/pull/11055)) :id=rgb-matrix-split-common
Split boards can now use RGB Matrix without defining a custom matrix. Split boards can now use RGB Matrix without defining a custom matrix.
### Teensy 3.6 support ([#12258](https://github.com/qmk/qmk_firmware/pull/12258)) {#teensy-3-6-support} ### Teensy 3.6 support ([#12258](https://github.com/qmk/qmk_firmware/pull/12258)) :id=teensy-3-6-support
Added support for MK66F18 (Teensy 3.6) microcontroller. Added support for MK66F18 (Teensy 3.6) microcontroller.
### New command: qmk console ([#12828](https://github.com/qmk/qmk_firmware/pull/12828)) {#new-command-qmk-console} ### New command: qmk console ([#12828](https://github.com/qmk/qmk_firmware/pull/12828)) :id=new-command-qmk-console
A new `qmk console` command has been added for attaching to your keyboard's console. It operates similiarly to QMK Toolbox by allowing you to connect to one or more keyboard consoles to display debugging messages. A new `qmk console` command has been added for attaching to your keyboard's console. It operates similiarly to QMK Toolbox by allowing you to connect to one or more keyboard consoles to display debugging messages.
### Improved command: qmk config {#improve-command-qmk-config} ### Improved command: qmk config :id=improve-command-qmk-config
We've updated the `qmk config` command to show only the configuration items you have actually set. You can now display (almost) all of the available configuration options, along with their default values, using `qmk config -a`. We've updated the `qmk config` command to show only the configuration items you have actually set. You can now display (almost) all of the available configuration options, along with their default values, using `qmk config -a`.
### LED Matrix Improvements ([#12509](https://github.com/qmk/qmk_firmware/pull/12509), [#12580](https://github.com/qmk/qmk_firmware/pull/12580), [#12588](https://github.com/qmk/qmk_firmware/pull/12588), [#12633](https://github.com/qmk/qmk_firmware/pull/12633), [#12651](https://github.com/qmk/qmk_firmware/pull/12651), [#12685](https://github.com/qmk/qmk_firmware/pull/12685)) {#led-matrix-improvements} ### LED Matrix Improvements ([#12509](https://github.com/qmk/qmk_firmware/pull/12509), [#12580](https://github.com/qmk/qmk_firmware/pull/12580), [#12588](https://github.com/qmk/qmk_firmware/pull/12588), [#12633](https://github.com/qmk/qmk_firmware/pull/12633), [#12651](https://github.com/qmk/qmk_firmware/pull/12651), [#12685](https://github.com/qmk/qmk_firmware/pull/12685)) :id=led-matrix-improvements
LED Matrix has been improved with effects, CIE1931 curves, and a task system. LED Matrix has been improved with effects, CIE1931 curves, and a task system.
## Changes Requiring User Action {#changes-requiring-user-action} ## Changes Requiring User Action :id=changes-requiring-user-action
### Updated Keyboard Codebases {#updated-keyboard-codebases} ### Updated Keyboard Codebases :id=updated-keyboard-codebases
* Durgod keyboard refactor in preparation for adding additional durgod keyboards ([#11978](https://github.com/qmk/qmk_firmware/pull/11978)) * Durgod keyboard refactor in preparation for adding additional durgod keyboards ([#11978](https://github.com/qmk/qmk_firmware/pull/11978))
* Updated Function96 with V2 files and removed chconf.h and halconf.h ([#12613](https://github.com/qmk/qmk_firmware/pull/12613)) * Updated Function96 with V2 files and removed chconf.h and halconf.h ([#12613](https://github.com/qmk/qmk_firmware/pull/12613))
@ -52,7 +52,7 @@ The codebase for the [Durgod K320](https://github.com/qmk/qmk_firmware/tree/0.13
Additionally, the `crkbd/rev1/legacy` keyboard has been removed. Additionally, the `crkbd/rev1/legacy` keyboard has been removed.
### Bootmagic Deprecation and Refactor ([#12172](https://github.com/qmk/qmk_firmware/pull/12172)) {#bootmagic-deprecation-and-refactor} ### Bootmagic Deprecation and Refactor ([#12172](https://github.com/qmk/qmk_firmware/pull/12172)) :id=bootmagic-deprecation-and-refactor
QMK has decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option. QMK has decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option.
@ -68,11 +68,11 @@ This is the current planned roadmap for the behavior of `BOOTMAGIC_ENABLE`:
- From 2021 Aug 28, `BOOTMAGIC_ENABLE` must be either `yes`, `lite`, or `no` setting `BOOTMAGIC_ENABLE = full` will cause compilation to fail. - From 2021 Aug 28, `BOOTMAGIC_ENABLE` must be either `yes`, `lite`, or `no` setting `BOOTMAGIC_ENABLE = full` will cause compilation to fail.
- From 2021 Nov 27, `BOOTMAGIC_ENABLE` must be either `yes` or `no` setting `BOOTMAGIC_ENABLE = lite` will cause compilation to fail. - From 2021 Nov 27, `BOOTMAGIC_ENABLE` must be either `yes` or `no` setting `BOOTMAGIC_ENABLE = lite` will cause compilation to fail.
### Removal of LAYOUT_kc ([#12160](https://github.com/qmk/qmk_firmware/pull/12160)) {#removal-of-layout-kc} ### Removal of LAYOUT_kc ([#12160](https://github.com/qmk/qmk_firmware/pull/12160)) :id=removal-of-layout-kc
We've removed support for `LAYOUT_kc` macros, if your keymap uses one you will need to update it use a regular `LAYOUT` macro. We've removed support for `LAYOUT_kc` macros, if your keymap uses one you will need to update it use a regular `LAYOUT` macro.
### Encoder callbacks are now boolean ([#12805](https://github.com/qmk/qmk_firmware/pull/12805), [#12985](https://github.com/qmk/qmk_firmware/pull/12985)) {#encoder-callback-boolean} ### Encoder callbacks are now boolean ([#12805](https://github.com/qmk/qmk_firmware/pull/12805), [#12985](https://github.com/qmk/qmk_firmware/pull/12985)) :id=encoder-callback-boolean
To allow for keyboards to override (or not) keymap level code the `encoder_update_kb` function has been changed from `void` to `bool`. You will need to update your function definition to reflect this and ensure that you return a `true` or `false` value. To allow for keyboards to override (or not) keymap level code the `encoder_update_kb` function has been changed from `void` to `bool`. You will need to update your function definition to reflect this and ensure that you return a `true` or `false` value.
@ -127,9 +127,9 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
} }
``` ```
## Core Changes {#core-changes} ## Core Changes :id=core-changes
### Fixes {#core-fixes} ### Fixes :id=core-fixes
* Fix connection issue in split keyboards when slave and OLED display are connected via I2C (fixes #9335) ([#11487](https://github.com/qmk/qmk_firmware/pull/11487)) * Fix connection issue in split keyboards when slave and OLED display are connected via I2C (fixes #9335) ([#11487](https://github.com/qmk/qmk_firmware/pull/11487))
* Terrazzo: Fix wrong LED Matrix function names ([#12561](https://github.com/qmk/qmk_firmware/pull/12561)) * Terrazzo: Fix wrong LED Matrix function names ([#12561](https://github.com/qmk/qmk_firmware/pull/12561))
@ -147,7 +147,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
* [Keyboard] Fix Terrazzo build failure ([#12977](https://github.com/qmk/qmk_firmware/pull/12977)) * [Keyboard] Fix Terrazzo build failure ([#12977](https://github.com/qmk/qmk_firmware/pull/12977))
* Do not hard set config in CPTC files ([#11864](https://github.com/qmk/qmk_firmware/pull/11864)) * Do not hard set config in CPTC files ([#11864](https://github.com/qmk/qmk_firmware/pull/11864))
### Additions and Enhancements {#core-additions} ### Additions and Enhancements :id=core-additions
* ARM - Refactor SLEEP_LED to support more platforms ([#8403](https://github.com/qmk/qmk_firmware/pull/8403)) * ARM - Refactor SLEEP_LED to support more platforms ([#8403](https://github.com/qmk/qmk_firmware/pull/8403))
* Add ability to toggle One Shot functionality ([#4198](https://github.com/qmk/qmk_firmware/pull/4198)) * Add ability to toggle One Shot functionality ([#4198](https://github.com/qmk/qmk_firmware/pull/4198))
@ -193,7 +193,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
* Backlight: add defines for default level and breathing state ([#12560](https://github.com/qmk/qmk_firmware/pull/12560), [#13024](https://github.com/qmk/qmk_firmware/pull/13024)) * Backlight: add defines for default level and breathing state ([#12560](https://github.com/qmk/qmk_firmware/pull/12560), [#13024](https://github.com/qmk/qmk_firmware/pull/13024))
* Add dire message about LUFA mass storage bootloader ([#13014](https://github.com/qmk/qmk_firmware/pull/13014)) * Add dire message about LUFA mass storage bootloader ([#13014](https://github.com/qmk/qmk_firmware/pull/13014))
### Clean-ups and Optimizations {#core-optimizations} ### Clean-ups and Optimizations :id=core-optimizations
* Overhaul bootmagic logic to have single entrypoint ([#8532](https://github.com/qmk/qmk_firmware/pull/8532)) * Overhaul bootmagic logic to have single entrypoint ([#8532](https://github.com/qmk/qmk_firmware/pull/8532))
* Refactor of USB code within split_common ([#11890](https://github.com/qmk/qmk_firmware/pull/11890)) * Refactor of USB code within split_common ([#11890](https://github.com/qmk/qmk_firmware/pull/11890))
@ -218,7 +218,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
* Deprecate `send_unicode_hex_string()` ([#12602](https://github.com/qmk/qmk_firmware/pull/12602)) * Deprecate `send_unicode_hex_string()` ([#12602](https://github.com/qmk/qmk_firmware/pull/12602))
* [Keyboard] Remove redundant legacy and common headers for crkbd ([#13023](https://github.com/qmk/qmk_firmware/pull/13023)) * [Keyboard] Remove redundant legacy and common headers for crkbd ([#13023](https://github.com/qmk/qmk_firmware/pull/13023))
### QMK Infrastructure and Internals {#qmk-internals} ### QMK Infrastructure and Internals :id=qmk-internals
* trivial change to trigger api update ([`b15288fb87`](https://github.com/qmk/qmk_firmware/commit/b15288fb87)) * trivial change to trigger api update ([`b15288fb87`](https://github.com/qmk/qmk_firmware/commit/b15288fb87))
* fix some references to bin/qmk that slipped in ([#12832](https://github.com/qmk/qmk_firmware/pull/12832)) * fix some references to bin/qmk that slipped in ([#12832](https://github.com/qmk/qmk_firmware/pull/12832))

View file

@ -1,28 +1,28 @@
# QMK Breaking Changes - 2021 August 28 Changelog # QMK Breaking Changes - 2021 August 28 Changelog
## Notable Features {#notable-features} ## Notable Features :id=notable-features
### Combo processing improvements ([#8591](https://github.com/qmk/qmk_firmware/pull/8591)) {#combo-processing-improvements} ### Combo processing improvements ([#8591](https://github.com/qmk/qmk_firmware/pull/8591)) :id=combo-processing-improvements
Combo processing has been reordered with respect to keypress handling, allowing for much better compatibility with mod taps. Combo processing has been reordered with respect to keypress handling, allowing for much better compatibility with mod taps.
It is also now possible to define combos that have keys overlapping with other combos, triggering only one. For example, a combo of `A`, `B` can coexist with a longer combo of `A`, `B`, `C` -- previous functionality would trigger both combos if all three keys were pressed. It is also now possible to define combos that have keys overlapping with other combos, triggering only one. For example, a combo of `A`, `B` can coexist with a longer combo of `A`, `B`, `C` -- previous functionality would trigger both combos if all three keys were pressed.
### Key Overrides ([#11422](https://github.com/qmk/qmk_firmware/pull/11422)) {#key-overrides} ### Key Overrides ([#11422](https://github.com/qmk/qmk_firmware/pull/11422)) :id=key-overrides
QMK now has a new feature: [key overrides](../features/key_overrides). This feature allows for overriding the output of key combinations involving modifiers. As an example, pressing <kbd>Shift+2</kbd> normally results in an <kbd>@</kbd> on US-ANSI keyboard layouts -- the new key overrides allow for adding similar functionality, but for any <kbd>modifier + key</kbd> press. QMK now has a new feature: [key overrides](https://docs.qmk.fm/#/feature_key_overrides). This feature allows for overriding the output of key combinations involving modifiers. As an example, pressing <kbd>Shift+2</kbd> normally results in an <kbd>@</kbd> on US-ANSI keyboard layouts -- the new key overrides allow for adding similar functionality, but for any <kbd>modifier + key</kbd> press.
To illustrate, it's now possible to use the key overrides feature to translate <kbd>Shift + Backspace</kbd> into <kbd>Delete</kbd> -- an often-requested example of where this functionality comes in handy. To illustrate, it's now possible to use the key overrides feature to translate <kbd>Shift + Backspace</kbd> into <kbd>Delete</kbd> -- an often-requested example of where this functionality comes in handy.
There's far more to describe that what lives in this changelog, so head over to the [key overrides documentation](../features/key_overrides) for more examples and info. There's far more to describe that what lives in this changelog, so head over to the [key overrides documentation](https://docs.qmk.fm/#/feature_key_overrides) for more examples and info.
### Digitizer support ([#12851](https://github.com/qmk/qmk_firmware/pull/12851)) ### Digitizer support ([#12851](https://github.com/qmk/qmk_firmware/pull/12851))
QMK gained the ability to pretend to be a digitizer device -- much like a tablet device. A mouse uses delta-coordinates -- move up, move right -- but a digitizer works with absolute coordinates -- top left, bottom right. QMK gained the ability to pretend to be a digitizer device -- much like a tablet device. A mouse uses delta-coordinates -- move up, move right -- but a digitizer works with absolute coordinates -- top left, bottom right.
## Changes Requiring User Action {#changes-requiring-user-action} ## Changes Requiring User Action :id=changes-requiring-user-action
### Updated Keyboard Codebases {#updated-keyboard-codebases} ### Updated Keyboard Codebases :id=updated-keyboard-codebases
The following keyboards have had their source moved within QMK: The following keyboards have had their source moved within QMK:
@ -69,7 +69,7 @@ xd84pro | xiudi/xd84pro
xd87 | xiudi/xd87 xd87 | xiudi/xd87
xd96 | xiudi/xd96 xd96 | xiudi/xd96
### Bootmagic Full Removal ([#13846](https://github.com/qmk/qmk_firmware/pull/13846)) {#bootmagic-full-removal} ### Bootmagic Full Removal ([#13846](https://github.com/qmk/qmk_firmware/pull/13846)) :id=bootmagic-full-removal
As noted during last breaking changes cycle, QMK has decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option. As noted during last breaking changes cycle, QMK has decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option.
@ -85,7 +85,7 @@ This is the current roadmap for the behavior of `BOOTMAGIC_ENABLE`:
- (now) From 2021 Aug 28, `BOOTMAGIC_ENABLE` must be either `yes`, `lite`, or `no` setting `BOOTMAGIC_ENABLE = full` will cause compilation to fail. - (now) From 2021 Aug 28, `BOOTMAGIC_ENABLE` must be either `yes`, `lite`, or `no` setting `BOOTMAGIC_ENABLE = full` will cause compilation to fail.
- (next) From 2021 Nov 27, `BOOTMAGIC_ENABLE` must be either `yes` or `no` setting `BOOTMAGIC_ENABLE = lite` will cause compilation to fail. - (next) From 2021 Nov 27, `BOOTMAGIC_ENABLE` must be either `yes` or `no` setting `BOOTMAGIC_ENABLE = lite` will cause compilation to fail.
### DIP switch callbacks are now boolean ([#13399](https://github.com/qmk/qmk_firmware/pull/13399)) {#dip-switch-boolean} ### DIP switch callbacks are now boolean ([#13399](https://github.com/qmk/qmk_firmware/pull/13399)) :id=dip-switch-boolean
To match the encoder change last breaking changes cycle, DIP switch callbacks now return `bool`, too. To match the encoder change last breaking changes cycle, DIP switch callbacks now return `bool`, too.
@ -149,9 +149,9 @@ bool dip_switch_update_mask_user(uint32_t state) {
} }
``` ```
## Notable core changes {#notable-core} ## Notable core changes :id=notable-core
### Split transport improvements {#split-transport-improvements} ### Split transport improvements :id=split-transport-improvements
Split keyboards gained a significant amount of improvements during this breaking changes cycle, specifically: Split keyboards gained a significant amount of improvements during this breaking changes cycle, specifically:
@ -160,11 +160,9 @@ Split keyboards gained a significant amount of improvements during this breaking
* Make solo half of split keyboards (more) usable. ([#13523](https://github.com/qmk/qmk_firmware/pull/13523)) -- allows the slave to be disconnected, enabling one-handed use. * Make solo half of split keyboards (more) usable. ([#13523](https://github.com/qmk/qmk_firmware/pull/13523)) -- allows the slave to be disconnected, enabling one-handed use.
* Switch split_common to CRC subsystem ([#13418](https://github.com/qmk/qmk_firmware/pull/13418)) * Switch split_common to CRC subsystem ([#13418](https://github.com/qmk/qmk_firmware/pull/13418))
::: warning !> If you're updating your split keyboard, you will need to flash both sides of the split with the your firmware.
If you're updating your split keyboard, you will need to flash both sides of the split with the your firmware.
:::
### Teensy 4.x support ([#13056](https://github.com/qmk/qmk_firmware/pull/13056), [#13076](https://github.com/qmk/qmk_firmware/pull/13076), [#13077](https://github.com/qmk/qmk_firmware/pull/13077)) {#teensy-4-x-support} ### Teensy 4.x support ([#13056](https://github.com/qmk/qmk_firmware/pull/13056), [#13076](https://github.com/qmk/qmk_firmware/pull/13076), [#13077](https://github.com/qmk/qmk_firmware/pull/13077)) :id=teensy-4-x-support
Updated ChibiOS and ChibiOS-Contrib, which brought in support for Teensy 4.x dev boards, running NXP i.MX1062. Updated ChibiOS and ChibiOS-Contrib, which brought in support for Teensy 4.x dev boards, running NXP i.MX1062.
@ -245,7 +243,7 @@ We've added dozens of new keys to `info.json` so that you can configure more tha
* `usb.force_nkro`, `usb.max_power`, `usb.no_startup_check`, `usb.polling_interval`, `usb.shared_endpoint.keyboard`, `usb.shared_endpoint.mouse`, `usb.suspend_wakeup_delay`, `usb.wait_for` * `usb.force_nkro`, `usb.max_power`, `usb.no_startup_check`, `usb.polling_interval`, `usb.shared_endpoint.keyboard`, `usb.shared_endpoint.mouse`, `usb.suspend_wakeup_delay`, `usb.wait_for`
* `qmk.keys_per_scan`, `qmk.tap_keycode_delay`, `qmk.tap_capslock_delay` * `qmk.keys_per_scan`, `qmk.tap_keycode_delay`, `qmk.tap_capslock_delay`
### Codebase restructure and cleanup {#codebase-restructure} ### Codebase restructure and cleanup :id=codebase-restructure
QMK was originally based on TMK, and has grown in size considerably since its first inception. To keep moving things forward, restructure of some of the core areas of the code is needed to support new concepts and new hardware, and progress is happening along those lines: QMK was originally based on TMK, and has grown in size considerably since its first inception. To keep moving things forward, restructure of some of the core areas of the code is needed to support new concepts and new hardware, and progress is happening along those lines:

View file

@ -1,6 +1,6 @@
# QMK Breaking Changes - 2021 November 27 Changelog # QMK Breaking Changes - 2021 November 27 Changelog
## 2000 keyboards! {#qmk-2000th-keyboard} ## 2000 keyboards! :id=qmk-2000th-keyboard
QMK had it's 2000th keyboard submitted during this breaking changes cycle.... and it only _just_ made the cut-off! QMK had it's 2000th keyboard submitted during this breaking changes cycle.... and it only _just_ made the cut-off!
@ -11,9 +11,9 @@ QMK had it's 2000th keyboard submitted during this breaking changes cycle.... an
From the whole QMK team, a major thankyou to the community for embracing QMK as your preferred keyboard firmware! From the whole QMK team, a major thankyou to the community for embracing QMK as your preferred keyboard firmware!
## Notable Features {#notable-features} ## Notable Features :id=notable-features
### Expanded Pointing Device support ([#14343](https://github.com/qmk/qmk_firmware/pull/14343)) {#expanded-pointing-device} ### Expanded Pointing Device support ([#14343](https://github.com/qmk/qmk_firmware/pull/14343)) :id=expanded-pointing-device
Pointing device support has been reworked and reimplemented to allow for easier integration of new peripherals. Pointing device support has been reworked and reimplemented to allow for easier integration of new peripherals.
@ -31,9 +31,9 @@ QMK now has core-supplied support for the following pointing device peripherals:
| `POINTING_DEVICE_DRIVER = pimoroni_trackball` | Pimoroni Trackball | | `POINTING_DEVICE_DRIVER = pimoroni_trackball` | Pimoroni Trackball |
| `POINTING_DEVICE_DRIVER = pmw3360` | PMW 3360 | | `POINTING_DEVICE_DRIVER = pmw3360` | PMW 3360 |
See the new documentation for the [Pointing Device](../features/pointing_device) feature for more information on specific configuration for each driver. See the new documentation for the [Pointing Device](../feature_pointing_device.md) feature for more information on specific configuration for each driver.
### Dynamic Tapping Term ([#11036](https://github.com/qmk/qmk_firmware/pull/11036)) {#dynamic-tapping-term} ### Dynamic Tapping Term ([#11036](https://github.com/qmk/qmk_firmware/pull/11036)) :id=dynamic-tapping-term
For people who are starting out with tapping keys, or for people who think tapping keys don't "feel right", it's sometimes quite difficult to determine what duration of tapping term to use to make things seem natural. For people who are starting out with tapping keys, or for people who think tapping keys don't "feel right", it's sometimes quite difficult to determine what duration of tapping term to use to make things seem natural.
@ -47,28 +47,28 @@ If you're in this stage of discovery, you can now add `DYNAMIC_TAPPING_TERM_ENAB
Coupled with the use of `qmk console` or QMK Toolbox to show console output from your keyboard, you can tweak the tapping term dynamically in order to narrow down what "feels right" to you. Once you're happy, drop in the resulting number into your keymap's `config.h` and you're good to go! Coupled with the use of `qmk console` or QMK Toolbox to show console output from your keyboard, you can tweak the tapping term dynamically in order to narrow down what "feels right" to you. Once you're happy, drop in the resulting number into your keymap's `config.h` and you're good to go!
### Macros in JSON keymaps ([#14374](https://github.com/qmk/qmk_firmware/pull/14374)) {#macros-in-keymap-json} ### Macros in JSON keymaps ([#14374](https://github.com/qmk/qmk_firmware/pull/14374)) :id=macros-in-keymap-json
You can now define up to 32 macros in your `keymap.json` file, as used by [QMK Configurator](../newbs_building_firmware_configurator), and `qmk compile`. You can define these macros in a list under the `macros` keyword, like this: You can now define up to 32 macros in your `keymap.json` file, as used by [QMK Configurator](newbs_building_firmware_configurator.md), and `qmk compile`. You can define these macros in a list under the `macros` keyword, like this:
```json ```json
{ {
"keyboard": "handwired/my_macropad", "keyboard": "handwired/my_macropad",
"keymap": "my_keymap", "keymap": "my_keymap",
"macros": [ "macros": [
[ // first listed is QK_MACRO_0... [ // first listed is MACRO_0...
{"action":"down", "keycodes": ["LSFT"]}, {"action":"down", "keycodes": ["LSFT"]},
"hello world1", "hello world1",
{"action": "up","keycodes": ["LSFT"]} {"action": "up","keycodes": ["LSFT"]}
], ],
[ // ...then QK_MACRO_1... [ // ...then MACRO_1...
{"action":"tap", "keycodes": ["LCTL", "LALT", "DEL"]} {"action":"tap", "keycodes": ["LCTL", "LALT", "DEL"]}
], ],
[ // ...then QK_MACRO_2... [ // ...then MACRO_2...
"ding!", "ding!",
{"action":"beep"} {"action":"beep"}
], ],
[ // ...and QK_MACRO_3. [ // ...and MACRO_3.
{"action":"tap", "keycodes": ["F1"]}, {"action":"tap", "keycodes": ["F1"]},
{"action":"delay", "duration": "1000"}, {"action":"delay", "duration": "1000"},
{"action":"tap", "keycodes": ["PGDN"]} {"action":"tap", "keycodes": ["PGDN"]}
@ -76,16 +76,16 @@ You can now define up to 32 macros in your `keymap.json` file, as used by [QMK C
], ],
"layout": "LAYOUT_all", "layout": "LAYOUT_all",
"layers": [ "layers": [
["QK_MACRO_0", "QK_MACRO_1", "QK_MACRO_2", "QK_MACRO_3"] ["MACRO_0", "MACRO_1", "MACRO_2", "MACRO_3"]
] ]
} }
``` ```
In due course, [QMK Configurator](https://config.qmk.fm/) will pick up support for defining these in its UI, but for now the json is the only way to define macros. In due course, [QMK Configurator](https://config.qmk.fm/) will pick up support for defining these in its UI, but for now the json is the only way to define macros.
## Changes Requiring User Action {#changes-requiring-user-action} ## Changes Requiring User Action :id=changes-requiring-user-action
### Updated Keyboard Codebases {#updated-keyboard-codebases} ### Updated Keyboard Codebases :id=updated-keyboard-codebases
The following keyboards have had their source moved within QMK: The following keyboards have had their source moved within QMK:
@ -104,21 +104,21 @@ The following keyboards have had their source moved within QMK:
| signum/3_0/elitec | signum/3_0 | | signum/3_0/elitec | signum/3_0 |
| tgr/jane | tgr/jane/v2 | | tgr/jane | tgr/jane/v2 |
### Squeezing space out of AVR ([#15243](https://github.com/qmk/qmk_firmware/pull/15243)) {#squeezing-space-from-avr} ### Squeezing space out of AVR ([#15243](https://github.com/qmk/qmk_firmware/pull/15243)) :id=squeezing-space-from-avr
The AVR platform has been problematic for some time, in the sense that it is severely resource-constrained -- this makes life difficult for anyone attempting to add new functionality such as display panels to their keymap code. The illustrious Drashna has contributed some newer documentation on how to attempt to free up some space on AVR-based keyboards that are in short supply. The AVR platform has been problematic for some time, in the sense that it is severely resource-constrained -- this makes life difficult for anyone attempting to add new functionality such as display panels to their keymap code. The illustrious Drashna has contributed some newer documentation on how to attempt to free up some space on AVR-based keyboards that are in short supply.
Of course, there are much fewer constraints with ARM chips... ;) Of course, there are much fewer constraints with ARM chips... ;)
### Require explicit enabling of RGB Matrix modes ([#15018](https://github.com/qmk/qmk_firmware/pull/15018)) {#explicit-rgb-modes} ### Require explicit enabling of RGB Matrix modes ([#15018](https://github.com/qmk/qmk_firmware/pull/15018)) :id=explicit-rgb-modes
Related to the previous section -- RGB Matrix modes have now been made to be opt-in, rather than opt-out. As these animations are now opt-in, you may find that your keyboard no longer has all the RGB modes you're expecting -- you may need to configure and recompile your firmware and enable your animations of choice... with any luck they'll still fit in the space available. Related to the previous section -- RGB Matrix modes have now been made to be opt-in, rather than opt-out. As these animations are now opt-in, you may find that your keyboard no longer has all the RGB modes you're expecting -- you may need to configure and recompile your firmware and enable your animations of choice... with any luck they'll still fit in the space available.
Most keyboards keep their original functionality, but over time the QMK maintainers have found that removal of animations ends up being the quickest way to free up space... and some keyboards have had animations such as reactive effects disabled by default in order to still fit within the flash space available. Most keyboards keep their original functionality, but over time the QMK maintainers have found that removal of animations ends up being the quickest way to free up space... and some keyboards have had animations such as reactive effects disabled by default in order to still fit within the flash space available.
The full list of configurables to turn specific animations back on can be found at on the [RGB Matrix documentation](../features/rgb_matrix#rgb-matrix-effects) page. The full list of configurables to turn specific animations back on can be found at on the [RGB Matrix documentation](feature_rgb_matrix.md#rgb-matrix-effects) page.
### OLED task refactoring ([#14864](https://github.com/qmk/qmk_firmware/pull/14864)) {#oled-task-refactor} ### OLED task refactoring ([#14864](https://github.com/qmk/qmk_firmware/pull/14864)) :id=oled-task-refactor
OLED display code was traditionally difficult to override in keymaps as they did not follow the standard pattern of `bool *_kb()` deferring to `bool *_user()` functions, allowing signalling to the higher level that processing had already been done. OLED display code was traditionally difficult to override in keymaps as they did not follow the standard pattern of `bool *_kb()` deferring to `bool *_user()` functions, allowing signalling to the higher level that processing had already been done.
@ -152,7 +152,7 @@ bool oled_task_kb(void) {
} }
``` ```
### Bootmagic Full Removal ([#15002](https://github.com/qmk/qmk_firmware/pull/15002)) {#bootmagic-full-removal} ### Bootmagic Full Removal ([#15002](https://github.com/qmk/qmk_firmware/pull/15002)) :id=bootmagic-full-removal
As noted during previous breaking changes cycles, QMK decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option. As noted during previous breaking changes cycles, QMK decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option.
@ -170,13 +170,13 @@ This is the historical timeline for the behavior of `BOOTMAGIC_ENABLE`:
- (done) From 2021 Aug 28, `BOOTMAGIC_ENABLE` must be either `yes`, `lite`, or `no` setting `BOOTMAGIC_ENABLE = full` will cause compilation to fail. - (done) From 2021 Aug 28, `BOOTMAGIC_ENABLE` must be either `yes`, `lite`, or `no` setting `BOOTMAGIC_ENABLE = full` will cause compilation to fail.
- (now) From 2021 Nov 27, `BOOTMAGIC_ENABLE` must be either `yes` or `no` setting `BOOTMAGIC_ENABLE = lite` will cause compilation to fail. - (now) From 2021 Nov 27, `BOOTMAGIC_ENABLE` must be either `yes` or `no` setting `BOOTMAGIC_ENABLE = lite` will cause compilation to fail.
### Remove QWIIC_DRIVERS ([#14174](https://github.com/qmk/qmk_firmware/pull/14174)) {#remove-qwiic} ### Remove QWIIC_DRIVERS ([#14174](https://github.com/qmk/qmk_firmware/pull/14174)) :id=remove-qwiic
Due to minimal QWIIC adoption and other options for similar functionality, the QWIIC drivers were removed from QMK. Existing OLED usages have been migrated across to the normal QMK OLED driver instead. Due to minimal QWIIC adoption and other options for similar functionality, the QWIIC drivers were removed from QMK. Existing OLED usages have been migrated across to the normal QMK OLED driver instead.
## Notable core changes {#notable-core} ## Notable core changes :id=notable-core
### New MCU Support {#new-mcu-support} ### New MCU Support :id=new-mcu-support
QMK firmware picked up support for a handful of new MCU families, potentially making it a bit easier to source components. QMK firmware picked up support for a handful of new MCU families, potentially making it a bit easier to source components.
@ -187,7 +187,7 @@ QMK firmware is now no longer limited to AVR and ARM - it also picked up support
* Westberrytech pr ([#14422](https://github.com/qmk/qmk_firmware/pull/14422)) * Westberrytech pr ([#14422](https://github.com/qmk/qmk_firmware/pull/14422))
* Initial pass of F405 support ([#14584](https://github.com/qmk/qmk_firmware/pull/14584)) * Initial pass of F405 support ([#14584](https://github.com/qmk/qmk_firmware/pull/14584))
### EEPROM Changes {#eeprom-changes} ### EEPROM Changes :id=eeprom-changes
There were a few EEPROM-related changes that landed during this breaking changes cycle, most prominently the long-awaited ability for the Drop boards to gain persistent storage. Any users of the Drop CTRL or Drop ALT should update QMK Toolbox as well -- coupled with a QMK firmware update settings should now be saved. There were a few EEPROM-related changes that landed during this breaking changes cycle, most prominently the long-awaited ability for the Drop boards to gain persistent storage. Any users of the Drop CTRL or Drop ALT should update QMK Toolbox as well -- coupled with a QMK firmware update settings should now be saved.
@ -197,7 +197,7 @@ There were a few EEPROM-related changes that landed during this breaking changes
* Further tidy up of STM32 eeprom emulation ([#14591](https://github.com/qmk/qmk_firmware/pull/14591)) * Further tidy up of STM32 eeprom emulation ([#14591](https://github.com/qmk/qmk_firmware/pull/14591))
* Enable eeprom with F401xE ld ([#14752](https://github.com/qmk/qmk_firmware/pull/14752)) * Enable eeprom with F401xE ld ([#14752](https://github.com/qmk/qmk_firmware/pull/14752))
### Compilation Database {#compile-commands} ### Compilation Database :id=compile-commands
A clang-compatible compilation database generator has been added as an option in order to help development environments such as Visual Studio Code. A clang-compatible compilation database generator has been added as an option in order to help development environments such as Visual Studio Code.
@ -208,7 +208,7 @@ Do note that switching keyboards will require re-generation of this file.
* New CLI subcommand to create clang-compatible compilation database (`compile_commands.json`) ([#14370](https://github.com/qmk/qmk_firmware/pull/14370)) * New CLI subcommand to create clang-compatible compilation database (`compile_commands.json`) ([#14370](https://github.com/qmk/qmk_firmware/pull/14370))
* compiledb: query include paths from gcc directly. ([#14462](https://github.com/qmk/qmk_firmware/pull/14462)) * compiledb: query include paths from gcc directly. ([#14462](https://github.com/qmk/qmk_firmware/pull/14462))
### Codebase restructure and cleanup {#codebase-restructure} ### Codebase restructure and cleanup :id=codebase-restructure
QMK continues on its restructuring journey, in order to make it easier to integrate newer features and add support for new hardware. This quarter's batch of changes include: QMK continues on its restructuring journey, in order to make it easier to integrate newer features and add support for new hardware. This quarter's batch of changes include:

View file

@ -1,6 +1,6 @@
# QMK Breaking Changes - 2022 February 26 Changelog # QMK Breaking Changes - 2022 February 26 Changelog
## Notable Features {#notable-features} ## Notable Features :id=notable-features
### Default USB Polling rate now 1kHz ([#15352](https://github.com/qmk/qmk_firmware/pull/15352)) ### Default USB Polling rate now 1kHz ([#15352](https://github.com/qmk/qmk_firmware/pull/15352))
@ -12,13 +12,13 @@ Something something *Lets go gamers!*
Pointing devices can now be shared across a split keyboard with support for a single pointing device or a pointing device on each side. Pointing devices can now be shared across a split keyboard with support for a single pointing device or a pointing device on each side.
See the [Pointing Device](../features/pointing_device) documentation for further configuration options. See the [Pointing Device](feature_pointing_device.md) documentation for further configuration options.
## Changes Requiring User Action {#changes-requiring-user-action} ## Changes Requiring User Action :id=changes-requiring-user-action
### Legacy macro and action_function system removed ([#16025](https://github.com/qmk/qmk_firmware/pull/16025)) ### Legacy macro and action_function system removed ([#16025](https://github.com/qmk/qmk_firmware/pull/16025))
The long time deprecated `MACRO()` and `action_get_macro` methods have been removed. Where possible, existing usages have been migrated over to core [Macros](../feature_macros). The long time deprecated `MACRO()` and `action_get_macro` methods have been removed. Where possible, existing usages have been migrated over to core [Macros](feature_macros.md).
### Create a build error if no bootloader is specified ([#16181](https://github.com/qmk/qmk_firmware/pull/16181)) ### Create a build error if no bootloader is specified ([#16181](https://github.com/qmk/qmk_firmware/pull/16181))
@ -31,7 +31,7 @@ Bootloader configuration is no longer assumed. Keyboards must now set either:
In preparation of future bluetooth work, the `AdafruitBLE` integration has been renamed to allow potential for any other Adafruit BLE products. In preparation of future bluetooth work, the `AdafruitBLE` integration has been renamed to allow potential for any other Adafruit BLE products.
### Updated Keyboard Codebases {#updated-keyboard-codebases} ### Updated Keyboard Codebases :id=updated-keyboard-codebases
The following keyboards have had their source moved within QMK: The following keyboards have had their source moved within QMK:
@ -241,9 +241,9 @@ The following keyboards have had their source moved within QMK:
| zinc/rev1 | 25keys/zinc/rev1 | | zinc/rev1 | 25keys/zinc/rev1 |
| zinc/reva | 25keys/zinc/reva | | zinc/reva | 25keys/zinc/reva |
## Notable core changes {#notable-core} ## Notable core changes :id=notable-core
### New MCU Support {#new-mcu-support} ### New MCU Support :id=new-mcu-support
Building on previous cycles, QMK firmware picked up support for a couple extra MCU variants: Building on previous cycles, QMK firmware picked up support for a couple extra MCU variants:

266
Doxyfile
View file

@ -1,266 +0,0 @@
# Doxyfile 1.8.14
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for qmk_firmware (github.com/qmk/qmk_firmware)
#
# All text after a double hash (##) is considered a comment and is placed in
# front of the TAG it is preceding.
#
# All text after a single hash (#) is considered a comment and will be ignored.
# The format is:
# TAG = value [value, ...]
# For lists, items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (\" \").
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "QMK Firmware"
PROJECT_NUMBER = https://github.com/qmk/qmk_firmware
PROJECT_BRIEF = "Keyboard controller firmware for Atmel AVR and ARM USB families"
OUTPUT_DIRECTORY = .build/docs/static/doxygen
ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 4
ALIASES =
TCL_SUBST =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES
TOC_INCLUDE_HEADINGS = 2
AUTOLINK_SUPPORT = YES
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
GROUP_NESTED_COMPOUNDS = NO
SUBGROUPING = YES
INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS = NO
TYPEDEF_HIDES_STRUCT = NO
LOOKUP_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_PACKAGE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = NO
HIDE_SCOPE_NAMES = YES
HIDE_COMPOUND_REFERENCE= NO
SHOW_INCLUDE_FILES = YES
SHOW_GROUPED_MEMB_INC = NO
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
STRICT_PROTO_MATCHING = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_FILES = YES
SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
LAYOUT_FILE =
CITE_BIB_FILES =
#---------------------------------------------------------------------------
# Configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_AS_ERROR = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = tmk_core quantum drivers
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.c \
*.cc \
*.cxx \
*.cpp \
*.c++ \
*.h \
*.hh \
*.hxx \
*.hpp \
*.h++
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
USE_MDFILE_AS_MAINPAGE =
#---------------------------------------------------------------------------
# Configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
SOURCE_TOOLTIPS = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to disabled outputs
#---------------------------------------------------------------------------
GENERATE_HTML = NO
GENERATE_LATEX = NO
GENERATE_RTF = NO
GENERATE_MAN = NO
GENERATE_DOCBOOK = NO
GENERATE_AUTOGEN_DEF = NO
GENERATE_PERLMOD = NO
#---------------------------------------------------------------------------
# Configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = YES
XML_OUTPUT = xml
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED = __DOXYGEN__ PROGMEM
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration options related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
DIA_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
DOT_NUM_THREADS = 0
DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
UML_LIMIT_NUM_FIELDS = 10
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
INTERACTIVE_SVG = NO
DOT_PATH =
DOTFILE_DIRS =
MSCFILE_DIRS =
DIAFILE_DIRS =
PLANTUML_JAR_PATH =
PLANTUML_CFG_FILE =
PLANTUML_INCLUDE_PATH =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES

339
LICENSE
View file

@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

495
Makefile
View file

@ -1,495 +0,0 @@
ifndef VERBOSE
.SILENT:
endif
# Never run this makefile in parallel, as it could screw things up
# It won't affect the submakes, so you still get the speedup from specifying -jx
.NOTPARALLEL:
# Allow the silent with lower caps to work the same way as upper caps
ifdef silent
SILENT = $(silent)
endif
ifdef SILENT
SUB_IS_SILENT := $(SILENT)
endif
# We need to make sure that silent is always turned off at the top level
# Otherwise the [OK], [ERROR] and [WARN] messages won't be displayed correctly
override SILENT := false
ifeq ($(shell git rev-parse --is-inside-work-tree 2>/dev/null),)
export SKIP_GIT := yes
export NOT_REPO := yes
endif
ifdef SKIP_VERSION
export SKIP_GIT := yes
endif
ifndef SUB_IS_SILENT
ifndef SKIP_GIT
QMK_VERSION := $(shell git describe --abbrev=0 --tags 2>/dev/null)
endif
ifneq ($(QMK_VERSION),)
$(info QMK Firmware $(QMK_VERSION))
endif
endif
# Try to determine userspace from qmk config, if set.
ifeq ($(QMK_USERSPACE),)
QMK_USERSPACE = $(shell qmk config -ro user.overlay_dir | cut -d= -f2 | sed -e 's@^None$$@@g')
endif
# Determine which qmk cli to use
QMK_BIN := qmk
# avoid 'Entering|Leaving directory' messages
MAKEFLAGS += --no-print-directory
ON_ERROR := error_occurred=1
BREAK_ON_ERRORS = no
ROOT_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
ifeq ($(ROOT_DIR),)
ROOT_DIR := .
endif
include paths.mk
include $(BUILDDEFS_PATH)/support.mk
TEST_OUTPUT_DIR := $(BUILD_DIR)/test
ERROR_FILE := $(BUILD_DIR)/error_occurred
.DEFAULT_GOAL := all:all
# Compare the start of the RULE variable with the first argument($1)
# If the rules equals $1 or starts with $1:, RULE_FOUND is set to true
# and $1 is removed from the RULE variable
# Otherwise the RULE_FOUND variable is set to false, and RULE left as it was
# The function is a bit tricky, since there's no built in $(startswith) function
define COMPARE_AND_REMOVE_FROM_RULE_HELPER
ifeq ($1,$$(RULE))
RULE:=
RULE_FOUND := true
else
STARTCOLON_REMOVED=$$(subst START$1:,,START$$(RULE))
ifneq ($$(STARTCOLON_REMOVED),START$$(RULE))
RULE_FOUND := true
RULE := $$(STARTCOLON_REMOVED)
else
RULE_FOUND := false
endif
endif
endef
# This makes it easier to call COMPARE_AND_REMOVE_FROM_RULE, since it makes it behave like
# a function that returns the value
COMPARE_AND_REMOVE_FROM_RULE = $(eval $(call COMPARE_AND_REMOVE_FROM_RULE_HELPER,$1))$(RULE_FOUND)
# Try to find a match for the start of the rule to be checked
# $1 The list to be checked
# If a match is found, then RULE_FOUND is set to true
# and MATCHED_ITEM to the item that was matched
define TRY_TO_MATCH_RULE_FROM_LIST_HELPER
# Split on ":", padding with empty strings to avoid indexing issues
TOKEN1:=$$(shell python3 -c "import sys; print((sys.argv[1].split(':',1)+[''])[0])" $$(RULE))
TOKENr:=$$(shell python3 -c "import sys; print((sys.argv[1].split(':',1)+[''])[1])" $$(RULE))
FOUNDx:=$$(shell echo $1 | tr " " "\n" | grep -Fx $$(TOKEN1))
ifneq ($$(FOUNDx),)
RULE := $$(TOKENr)
RULE_FOUND := true
MATCHED_ITEM := $$(TOKEN1)
else
RULE_FOUND := false
MATCHED_ITEM :=
endif
endef
# Make it easier to call TRY_TO_MATCH_RULE_FROM_LIST
TRY_TO_MATCH_RULE_FROM_LIST = $(eval $(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER,$1))$(RULE_FOUND)
# As TRY_TO_MATCH_RULE_FROM_LIST_HELPER, but with additional
# resolution of DEFAULT_FOLDER and keyboard_aliases.hjson for provided rule
define TRY_TO_MATCH_RULE_FROM_LIST_HELPER_KB
# Split on ":", padding with empty strings to avoid indexing issues
TOKEN1:=$$(shell python3 -c "import sys; print((sys.argv[1].split(':',1)+[''])[0])" $$(RULE))
TOKENr:=$$(shell python3 -c "import sys; print((sys.argv[1].split(':',1)+[''])[1])" $$(RULE))
TOKEN1:=$$(shell $(QMK_BIN) resolve-alias --allow-unknown $$(TOKEN1))
FOUNDx:=$$(shell echo $1 | tr " " "\n" | grep -Fx $$(TOKEN1))
ifneq ($$(FOUNDx),)
RULE := $$(TOKENr)
RULE_FOUND := true
MATCHED_ITEM := $$(TOKEN1)
else
RULE_FOUND := false
MATCHED_ITEM :=
endif
endef
# Make it easier to call TRY_TO_MATCH_RULE_FROM_LIST_KB
TRY_TO_MATCH_RULE_FROM_LIST_KB = $(eval $(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER_KB,$1))$(RULE_FOUND)
define ALL_IN_LIST_LOOP
OLD_RULE$1 := $$(RULE)
$$(eval $$(call $1,$$(ITEM$1)))
RULE := $$(OLD_RULE$1)
endef
define PARSE_ALL_IN_LIST
$$(foreach ITEM$1,$2,$$(eval $$(call ALL_IN_LIST_LOOP,$1)))
endef
# The entry point for rule parsing
# parses a rule in the format <keyboard>:<keymap>:<target>
# but this particular function only deals with the first <keyboard> part
define PARSE_RULE
RULE := $1
COMMANDS :=
# If the rule starts with all, then continue the parsing from
# PARSE_ALL_KEYBOARDS
ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,all),true)
KEYBOARD_RULE=all
$$(eval $$(call PARSE_ALL_KEYBOARDS))
else ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,test),true)
$$(eval $$(call PARSE_TEST))
# If the rule starts with the name of a known keyboard, then continue
# the parsing from PARSE_KEYBOARD
else ifeq ($$(call TRY_TO_MATCH_RULE_FROM_LIST_KB,$$(shell $(QMK_BIN) list-keyboards)),true)
KEYBOARD_RULE=$$(MATCHED_ITEM)
$$(eval $$(call PARSE_KEYBOARD,$$(MATCHED_ITEM)))
else
$$(info make: *** No rule to make target '$1'. Stop.)
$$(info |)
$$(info | QMK's make format is:)
$$(info | make keyboard_folder:keymap_folder[:target])
$$(info |)
$$(info | Where `keyboard_folder` is the path to the keyboard relative to)
$$(info | `qmk_firmware/keyboards/`, and `keymap_folder` is the name of the)
$$(info | keymap folder under that board's `keymaps/` directory.)
$$(info |)
$$(info | Examples:)
$$(info | keyboards/dz60, keyboards/dz60/keymaps/default)
$$(info | -> make dz60:default)
$$(info | -> qmk compile -kb dz60 -km default)
$$(info | keyboards/planck/rev6, keyboards/planck/keymaps/default)
$$(info | -> make planck/rev6:default:flash)
$$(info | -> qmk flash -kb planck/rev6 -km default)
$$(info |)
endif
endef
# $1 = Keyboard
# Parses a rule in the format <keymap>:<target>
# the keyboard is already known when entering this function
define PARSE_KEYBOARD
# If we want to compile the default subproject, then we need to
# include the correct makefile to determine the actual name of it
CURRENT_KB := $1
# 5/4/3/2/1
KEYBOARD_FOLDER_PATH_1 := $$(CURRENT_KB)
KEYBOARD_FOLDER_PATH_2 := $$(patsubst %/,%,$$(dir $$(KEYBOARD_FOLDER_PATH_1)))
KEYBOARD_FOLDER_PATH_3 := $$(patsubst %/,%,$$(dir $$(KEYBOARD_FOLDER_PATH_2)))
KEYBOARD_FOLDER_PATH_4 := $$(patsubst %/,%,$$(dir $$(KEYBOARD_FOLDER_PATH_3)))
KEYBOARD_FOLDER_PATH_5 := $$(patsubst %/,%,$$(dir $$(KEYBOARD_FOLDER_PATH_4)))
KEYMAPS :=
# get a list of all keymaps
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_1)/keymaps/*/.)))
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_2)/keymaps/*/.)))
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_3)/keymaps/*/.)))
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_4)/keymaps/*/.)))
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_5)/keymaps/*/.)))
ifneq ($(QMK_USERSPACE),)
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(QMK_USERSPACE)/keyboards/$$(KEYBOARD_FOLDER_PATH_1)/keymaps/*/.)))
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(QMK_USERSPACE)/keyboards/$$(KEYBOARD_FOLDER_PATH_2)/keymaps/*/.)))
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(QMK_USERSPACE)/keyboards/$$(KEYBOARD_FOLDER_PATH_3)/keymaps/*/.)))
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(QMK_USERSPACE)/keyboards/$$(KEYBOARD_FOLDER_PATH_4)/keymaps/*/.)))
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(QMK_USERSPACE)/keyboards/$$(KEYBOARD_FOLDER_PATH_5)/keymaps/*/.)))
endif
KEYBOARD_LAYOUTS := $(shell $(QMK_BIN) list-layouts --keyboard $1)
LAYOUT_KEYMAPS :=
$$(foreach LAYOUT,$$(KEYBOARD_LAYOUTS),$$(eval LAYOUT_KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/layouts/*/$$(LAYOUT)/*/.)))))
ifneq ($(QMK_USERSPACE),)
$$(foreach LAYOUT,$$(KEYBOARD_LAYOUTS),$$(eval LAYOUT_KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(QMK_USERSPACE)/layouts/$$(LAYOUT)/*/.)))))
endif
KEYMAPS := $$(sort $$(KEYMAPS) $$(LAYOUT_KEYMAPS))
# if the rule after removing the start of it is empty (we haven't specified a kemap or target)
# compile all the keymaps
ifeq ($$(RULE),)
$$(eval $$(call PARSE_ALL_KEYMAPS))
# The same if all was specified
else ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,all),true)
$$(eval $$(call PARSE_ALL_KEYMAPS))
# List all keymaps for the given keyboard
else ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,list-keymaps),true)
$$(eval $$(call LIST_ALL_KEYMAPS))
# Try to match the specified keyamp with the list of known keymaps
else ifeq ($$(call TRY_TO_MATCH_RULE_FROM_LIST,$$(KEYMAPS)),true)
$$(eval $$(call PARSE_KEYMAP,$$(MATCHED_ITEM)))
# Otherwise try to match the keymap from the current folder, or arguments to the make command
else ifneq ($$(KEYMAP),)
$$(eval $$(call PARSE_KEYMAP,$$(KEYMAP)))
# Otherwise if we are running make all:<user> just skip
else ifeq ($$(KEYBOARD_RULE),all)
# $$(info Skipping: No user keymap for $$(CURRENT_KB))
# Otherwise, make all keymaps, again this is consistent with how it works without
# any arguments
else
$$(eval $$(call PARSE_ALL_KEYMAPS))
endif
endef
# if we are going to compile all keyboards, match the rest of the rule
# for each of them
define PARSE_ALL_KEYBOARDS
$$(eval $$(call PARSE_ALL_IN_LIST,PARSE_KEYBOARD,$(shell $(QMK_BIN) list-keyboards --no-resolve-defaults)))
endef
# Prints a list of all known keymaps for the given keyboard
define LIST_ALL_KEYMAPS
COMMAND_true_LIST_KEYMAPS := \
printf "$$(KEYMAPS)\n";
COMMAND_false_LIST_KEYMAPS := \
printf "$$(MSG_AVAILABLE_KEYMAPS)\n"; \
printf "$$(KEYMAPS)\n";
COMMANDS += LIST_KEYMAPS
endef
# $1 Keymap
# This is the meat of compiling a keyboard, when entering this, everything is known
# keyboard, subproject, and keymap
# Note that we are not directly calling the command here, but instead building a list,
# which will later be processed
define PARSE_KEYMAP
CURRENT_KM = $1
# The rest of the rule is the target
# Remove the leading ":" from the target, as it acts as a separator
MAKE_TARGET := $$(patsubst :%,%,$$(RULE))
# We need to generate an unique identifier to append to the COMMANDS list
CURRENT_KB_UNDER := $$(subst /,_,$$(CURRENT_KB))
COMMAND := COMMAND_KEYBOARD_$$(CURRENT_KB_UNDER)_KEYMAP_$$(CURRENT_KM)
# If we are compiling a keyboard without a subproject, we want to display just the name
# of the keyboard, otherwise keyboard/subproject
KB_SP := $$(CURRENT_KB)
# Format it in bold
KB_SP := $(BOLD)$$(KB_SP)$(NO_COLOR)
# Specify the variables that we are passing forward to submake
MAKE_VARS := KEYBOARD=$$(CURRENT_KB) KEYMAP=$$(CURRENT_KM) QMK_BIN=$$(QMK_BIN)
# And the first part of the make command
MAKE_CMD := $$(MAKE) -r -R -C $(ROOT_DIR) -f $(BUILDDEFS_PATH)/build_keyboard.mk $$(MAKE_TARGET)
# The message to display
MAKE_MSG := $$(MSG_MAKE_KB)
# We run the command differently, depending on if we want more output or not
# The true version for silent output and the false version otherwise
$$(eval $$(call BUILD))
endef
define BUILD
MAKE_VARS += VERBOSE=$(VERBOSE) COLOR=$(COLOR)
COMMANDS += $$(COMMAND)
COMMAND_true_$$(COMMAND) := \
printf "$$(MAKE_MSG)" | \
$$(MAKE_MSG_FORMAT); \
LOG=$$$$($$(MAKE_CMD) $$(MAKE_VARS) SILENT=true 2>&1) ; \
if [ $$$$? -gt 0 ]; \
then $$(PRINT_ERROR_PLAIN); \
elif [ "$$$$LOG" = "skipped" ] ; \
then $$(PRINT_SKIPPED_PLAIN); \
elif [ "$$$$LOG" != "" ] ; \
then $$(PRINT_WARNING_PLAIN); \
else \
$$(PRINT_OK); \
fi;
COMMAND_false_$$(COMMAND) := \
printf "$$(MAKE_MSG)\n\n"; \
$$(MAKE_CMD) $$(MAKE_VARS) SILENT=false; \
if [ $$$$? -gt 0 ]; \
then error_occurred=1; \
fi;
endef
# Just parse all the keymaps for a specific keyboard
define PARSE_ALL_KEYMAPS
$$(eval $$(call PARSE_ALL_IN_LIST,PARSE_KEYMAP,$$(KEYMAPS)))
endef
define BUILD_TEST
TEST_PATH := $1
TEST_NAME := $$(notdir $$(TEST_PATH))
TEST_FULL_NAME := $$(subst /,_,$$(patsubst $$(ROOT_DIR)tests/%,%,$$(TEST_PATH)))
MAKE_TARGET := $2
COMMAND := $1
MAKE_CMD := $$(MAKE) -r -R -C $(ROOT_DIR) -f $(BUILDDEFS_PATH)/build_test.mk $$(MAKE_TARGET)
MAKE_VARS := TEST=$$(TEST_NAME) TEST_OUTPUT=$$(TEST_FULL_NAME) TEST_PATH=$$(TEST_PATH) FULL_TESTS="$$(FULL_TESTS)"
MAKE_MSG := $$(MSG_MAKE_TEST)
$$(eval $$(call BUILD))
ifneq ($$(MAKE_TARGET),clean)
TEST_EXECUTABLE := $$(TEST_OUTPUT_DIR)/$$(TEST_FULL_NAME).elf
TESTS += $$(TEST_FULL_NAME)
TEST_MSG := $$(MSG_TEST)
$$(TEST_FULL_NAME)_COMMAND := \
printf "$$(TEST_MSG)\n"; \
$$(TEST_EXECUTABLE); \
if [ $$$$? -gt 0 ]; \
then error_occurred=1; \
fi; \
printf "\n";
endif
endef
define LIST_TEST
include $(BUILDDEFS_PATH)/testlist.mk
FOUND_TESTS := $$(patsubst ./tests/%,%,$$(TEST_LIST))
$$(info $$(FOUND_TESTS))
endef
define PARSE_TEST
TESTS :=
TEST_NAME := $$(firstword $$(subst :, ,$$(RULE)))
TEST_TARGET := $$(subst $$(TEST_NAME),,$$(subst $$(TEST_NAME):,,$$(RULE)))
include $(BUILDDEFS_PATH)/testlist.mk
ifeq ($$(TEST_NAME),all)
MATCHED_TESTS := $$(TEST_LIST)
else
MATCHED_TESTS := $$(foreach TEST, $$(TEST_LIST),$$(if $$(findstring x$$(TEST_NAME)x, x$$(patsubst ./tests/%,%,$$(TEST)x)), $$(TEST),))
endif
$$(foreach TEST,$$(MATCHED_TESTS),$$(eval $$(call BUILD_TEST,$$(TEST),$$(TEST_TARGET))))
endef
# Set the silent mode depending on if we are trying to compile multiple keyboards or not
# By default it's on in that case, but it can be overridden by specifying silent=false
# from the command line
define SET_SILENT_MODE
ifdef SUB_IS_SILENT
SILENT_MODE := $(SUB_IS_SILENT)
else ifeq ($$(words $$(COMMANDS)),1)
SILENT_MODE := false
else
SILENT_MODE := true
endif
endef
include $(BUILDDEFS_PATH)/message.mk
ifeq ($(strip $(BREAK_ON_ERRORS)), yes)
HANDLE_ERROR = exit 1
else
HANDLE_ERROR = echo $$error_occurred > $(ERROR_FILE)
endif
# The empty line is important here, as it will force a new shell to be created for each command
# Otherwise the command line will become too long with a lot of keyboards and keymaps
define RUN_COMMAND
+error_occurred=0;\
$(COMMAND_$(SILENT_MODE)_$(COMMAND))\
if [ $$error_occurred -gt 0 ]; then $(HANDLE_ERROR); fi;
endef
define RUN_TEST
+error_occurred=0;\
$($(TEST)_COMMAND)\
if [ $$error_occurred -gt 0 ]; then $(HANDLE_ERROR); fi;
endef
# Catch everything and parse the command line ourselves.
.PHONY: %
%:
# Ensure that $(QMK_BIN) works.
if ! $(QMK_BIN) hello 1> /dev/null 2>&1; then printf "$(MSG_PYTHON_MISSING)"; exit 1; fi
ifdef NOT_REPO
printf "$(MSG_NOT_REPO)"
endif
ifndef SKIP_GIT
$(QMK_BIN) git-submodule --sync
# Check if the submodules are dirty, and display a warning if they are
if ! $(QMK_BIN) git-submodule --check 1> /dev/null 2>&1; then printf "$(MSG_SUBMODULE_DIRTY)"; fi
endif
rm -f $(ERROR_FILE) > /dev/null 2>&1
$(eval $(call PARSE_RULE,$@))
$(eval $(call SET_SILENT_MODE))
# Run all the commands in the same shell, notice the + at the first line
# it has to be there to allow parallel execution of the submake
# This always tries to compile everything, even if error occurs in the middle
# But we return the error code at the end, to trigger travis failures
# The sort at this point is to remove duplicates
$(foreach COMMAND,$(sort $(COMMANDS)),$(RUN_COMMAND))
if [ -f $(ERROR_FILE) ]; then printf "$(MSG_ERRORS)" & exit 1; fi;
$(foreach TEST,$(sort $(TESTS)),$(RUN_TEST))
if [ -f $(ERROR_FILE) ]; then printf "$(MSG_ERRORS)" & exit 1; fi;
lib/%:
git submodule sync $?
git submodule update --init $?
.PHONY: git-submodule
git-submodule:
$(QMK_BIN) git-submodule
.PHONY: git-submodules
git-submodules: git-submodule
.PHONY: list-keyboards
list-keyboards:
$(QMK_BIN) list-keyboards --no-resolve-defaults | tr '\n' ' '
.PHONY: list-tests
list-tests:
$(eval $(call LIST_TEST))
.PHONY: generate-keyboards-file
generate-keyboards-file:
$(QMK_BIN) list-keyboards --no-resolve-defaults
.PHONY: clean
clean:
echo -n 'Deleting .build/ ... '
rm -rf $(BUILD_DIR)
echo 'done.'
.PHONY: distclean distclean_qmk
distclean: distclean_qmk
distclean_qmk: clean
echo -n 'Deleting *.bin, *.hex, and *.uf2 ... '
rm -f *.bin *.hex *.uf2
echo 'done.'
ifneq ($(QMK_USERSPACE),)
.PHONY: distclean_userspace
distclean: distclean_userspace
distclean_userspace: clean
echo -n 'Deleting userspace *.bin, *.hex, and *.uf2 ... '
rm -f $(QMK_USERSPACE)/*.bin $(QMK_USERSPACE)/*.hex $(QMK_USERSPACE)/*.uf2
echo 'done.'
endif
# Extra targets for formatting and/or pytest, running within the qmk/qmk_cli container to match GHA.
CONTAINER_PREAMBLE := export HOME="/tmp"; export PATH="/tmp/.local/bin:\$$PATH"; python3 -m pip install --upgrade pip; python3 -m pip install -r requirements-dev.txt
.PHONY: format-core
format-core:
RUNTIME=docker ./util/docker_cmd.sh bash -lic "$(CONTAINER_PREAMBLE); qmk format-c --core-only -a && qmk format-python -a"
.PHONY: pytest
pytest:
RUNTIME=docker ./util/docker_cmd.sh bash -lic "$(CONTAINER_PREAMBLE); qmk pytest"
.PHONY: format-and-pytest
format-and-pytest:
RUNTIME=docker ./util/docker_cmd.sh bash -lic "$(CONTAINER_PREAMBLE); qmk format-c --core-only -a && qmk format-python -a && qmk pytest"

37
README.md Normal file
View file

@ -0,0 +1,37 @@
# Quantum Mechanical Keyboard Firmware
## What is QMK Firmware?
QMK (*Quantum Mechanical Keyboard*) is an open source community centered around developing computer input devices. The community encompasses all sorts of input devices, such as keyboards, mice, and MIDI devices. A core group of collaborators maintains [QMK Firmware](https://github.com/qmk/qmk_firmware), [QMK Configurator](https://config.qmk.fm), [QMK Toolbox](https://github.com/qmk/qmk_toolbox), [qmk.fm](https://qmk.fm), and this documentation with the help of community members like you.
## Get Started
<div class="flex-container">
?> **Basic** [QMK Configurator](newbs_building_firmware_configurator.md) <br>
User friendly graphical interfaces, no programming knowledge required.
?> **Advanced** [Use The Source](newbs.md) <br>
More powerful, but harder to use.
</div>
## Make It Yours
QMK has lots of features to explore, and a good deal of reference documentation to dig through. Most features are taken advantage of by modifying your [keymap](keymap.md), and changing the [keycodes](keycodes.md).
## Need help?
Check out the [support page](support.md) to see how you can get help using QMK.
## Give Back
There are a lot of ways you can contribute to the QMK Community. The easiest way to get started is to use it and spread the word to your friends.
* Help people out on our forums and chat rooms:
* [/r/olkb](https://www.reddit.com/r/olkb/)
* [Discord Server](https://discord.gg/Uq7gcHh)
* Contribute to our documentation by clicking "Edit This Page" at the bottom
* [Translate our documentation into your language](translating.md)
* [Report a bug](https://github.com/qmk/qmk_firmware/issues/new/choose)
* [Open a Pull Request](contributing.md)

4
_langs.md Normal file
View file

@ -0,0 +1,4 @@
- Translations
- [:uk: English](/)
- [:cn: 简体中文](/zh-cn/)
- [:jp: 日本語](/ja/)

192
_summary.md Normal file
View file

@ -0,0 +1,192 @@
* Tutorial
* [Introduction](newbs.md)
* [Setup](newbs_getting_started.md)
* [Building Your First Firmware](newbs_building_firmware.md)
* [Flashing Firmware](newbs_flashing.md)
* [Getting Help/Support](support.md)
* [Other Resources](newbs_learn_more_resources.md)
* [Syllabus](syllabus.md)
* FAQs
* [General FAQ](faq_general.md)
* [Build/Compile QMK](faq_build.md)
* [Troubleshooting QMK](faq_misc.md)
* [Debugging QMK](faq_debug.md)
* [Keymap FAQ](faq_keymap.md)
* [Squeezing Space from AVR](squeezing_avr.md)
* [Glossary](reference_glossary.md)
* Configurator
* [Overview](newbs_building_firmware_configurator.md)
* [Step by Step](configurator_step_by_step.md)
* [Troubleshooting](configurator_troubleshooting.md)
* [Architecture](configurator_architecture.md)
* QMK API
* [Overview](api_overview.md)
* [API Documentation](api_docs.md)
* [Keyboard Support](reference_configurator_support.md)
* [Adding Default Keymaps](configurator_default_keymaps.md)
* CLI
* [Overview](cli.md)
* [Configuration](cli_configuration.md)
* [Commands](cli_commands.md)
* [Tab Completion](cli_tab_complete.md)
* Using QMK
* Guides
* [Customizing Functionality](custom_quantum_functions.md)
* [Driver Installation with Zadig](driver_installation_zadig.md)
* [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)
* IDEs
* [Using Eclipse with QMK](other_eclipse.md)
* [Using VSCode with QMK](other_vscode.md)
* Git Best Practices
* [Introduction](newbs_git_best_practices.md)
* [Your Fork](newbs_git_using_your_master_branch.md)
* [Merge Conflicts](newbs_git_resolving_merge_conflicts.md)
* [Fixing Your Branch](newbs_git_resynchronize_a_branch.md)
* Simple Keycodes
* [Full List](keycodes.md)
* [Basic Keycodes](keycodes_basic.md)
* [Language-Specific Keycodes](reference_keymap_extras.md)
* [Modifier Keys](feature_advanced_keycodes.md)
* [Quantum Keycodes](quantum_keycodes.md)
* [Magic Keycodes](keycodes_magic.md)
* Advanced Keycodes
* [Command](feature_command.md)
* [Dynamic Macros](feature_dynamic_macros.md)
* [Grave Escape](feature_grave_esc.md)
* [Leader Key](feature_leader_key.md)
* [Mod-Tap](mod_tap.md)
* [Macros](feature_macros.md)
* [Mouse Keys](feature_mouse_keys.md)
* [Programmable Button](feature_programmable_button.md)
* [Space Cadet Shift](feature_space_cadet.md)
* [US ANSI Shifted Keys](keycodes_us_ansi_shifted.md)
* Software Features
* [Auto Shift](feature_auto_shift.md)
* [Combos](feature_combo.md)
* [Debounce API](feature_debounce_type.md)
* [Key Lock](feature_key_lock.md)
* [Key Overrides](feature_key_overrides.md)
* [Layers](feature_layers.md)
* [One Shot Keys](one_shot_keys.md)
* [Pointing Device](feature_pointing_device.md)
* [Raw HID](feature_rawhid.md)
* [Sequencer](feature_sequencer.md)
* [Swap Hands](feature_swap_hands.md)
* [Tap Dance](feature_tap_dance.md)
* [Tap-Hold Configuration](tap_hold.md)
* [Terminal](feature_terminal.md)
* [Unicode](feature_unicode.md)
* [Userspace](feature_userspace.md)
* [WPM Calculation](feature_wpm.md)
* Hardware Features
* Displays
* [HD44780 LCD Controller](feature_hd44780.md)
* [ST7565 LCD Driver](feature_st7565.md)
* [OLED Driver](feature_oled_driver.md)
* Lighting
* [Backlight](feature_backlight.md)
* [LED Matrix](feature_led_matrix.md)
* [RGB Lighting](feature_rgblight.md)
* [RGB Matrix](feature_rgb_matrix.md)
* [Audio](feature_audio.md)
* [Bluetooth](feature_bluetooth.md)
* [Bootmagic Lite](feature_bootmagic.md)
* [Custom Matrix](custom_matrix.md)
* [Digitizer](feature_digitizer.md)
* [DIP Switch](feature_dip_switch.md)
* [Encoders](feature_encoders.md)
* [Haptic Feedback](feature_haptic_feedback.md)
* [Joystick](feature_joystick.md)
* [LED Indicators](feature_led_indicators.md)
* [MIDI](feature_midi.md)
* [Proton C Conversion](proton_c_conversion.md)
* [PS/2 Mouse](feature_ps2_mouse.md)
* [Split Keyboard](feature_split_keyboard.md)
* [Stenography](feature_stenography.md)
* [Thermal Printer](feature_thermal_printer.md)
* [Velocikey](feature_velocikey.md)
* Keyboard Building
* [Easy Maker for One Offs](easy_maker.md)
* [Porting Keyboards](porting_your_keyboard_to_qmk.md)
* [Hand Wiring Guide](hand_wire.md)
* [ISP Flashing Guide](isp_flashing_guide.md)
* Developing QMK
* [PR Checklist](pr_checklist.md)
* Breaking Changes
* [Overview](breaking_changes.md)
* [My Pull Request Was Flagged](breaking_changes_instructions.md)
* [Most Recent ChangeLog](ChangeLog/20220226.md "QMK v0.16.0 - 2022 Feb 26")
* [Past Breaking Changes](breaking_changes_history.md)
* C Development
* [ARM Debugging Guide](arm_debugging.md)
* [Coding Conventions](coding_conventions_c.md)
* [Compatible Microcontrollers](compatible_microcontrollers.md)
* [Drivers](hardware_drivers.md)
* [ADC Driver](adc_driver.md)
* [Audio Driver](audio_driver.md)
* [I2C Driver](i2c_driver.md)
* [SPI Driver](spi_driver.md)
* [WS2812 Driver](ws2812_driver.md)
* [EEPROM Driver](eeprom_driver.md)
* ['serial' Driver](serial_driver.md)
* [UART Driver](uart_driver.md)
* [GPIO Controls](internals_gpio_control.md)
* [Keyboard Guidelines](hardware_keyboard_guidelines.md)
* Python Development
* [Coding Conventions](coding_conventions_python.md)
* [QMK CLI Development](cli_development.md)
* Configurator Development
* QMK API
* [Development Environment](api_development_environment.md)
* [Architecture Overview](api_development_overview.md)
* Hardware Platform Development
* Arm/ChibiOS
* [Selecting an MCU](platformdev_selecting_arm_mcu.md)
* [Early initialization](platformdev_chibios_earlyinit.md)
* QMK Reference
* [Contributing to QMK](contributing.md)
* [Translating the QMK Docs](translating.md)
* [Config Options](config_options.md)
* [Data Driven Configuration](data_driven_config.md)
* [Make Documentation](getting_started_make_guide.md)
* [Documentation Best Practices](documentation_best_practices.md)
* [Documentation Templates](documentation_templates.md)
* [Community Layouts](feature_layouts.md)
* [Unit Testing](unit_testing.md)
* [Useful Functions](ref_functions.md)
* [info.json Format](reference_info_json.md)
* For a Deeper Understanding
* [How Keyboards Work](how_keyboards_work.md)
* [How a Matrix Works](how_a_matrix_works.md)
* [Understanding QMK](understanding_qmk.md)
* QMK Internals (In Progress)
* [Defines](internals_defines.md)
* [Input Callback Reg](internals_input_callback_reg.md)
* [Midi Device](internals_midi_device.md)
* [Midi Device Setup Process](internals_midi_device_setup_process.md)
* [Midi Util](internals_midi_util.md)
* [Send Functions](internals_send_functions.md)
* [Sysex Tools](internals_sysex_tools.md)

156
adc_driver.md Normal file
View file

@ -0,0 +1,156 @@
# ADC Driver
QMK can leverage the Analog-to-Digital Converter (ADC) on supported MCUs to measure voltages on certain pins. This can be useful for implementing things such as battery level indicators for Bluetooth keyboards, or volume controls using a potentiometer, as opposed to a [rotary encoder](feature_encoders.md).
This driver currently supports both AVR and a limited selection of ARM devices. The values returned are 10-bit integers (0-1023) mapped between 0V and VCC (usually 5V or 3.3V for AVR, 3.3V only for ARM), however on ARM there is more flexibility in control of operation through `#define`s if you need more precision.
## Usage
To use this driver, add the following to your `rules.mk`:
```make
SRC += analog.c
```
Then place this include at the top of your code:
```c
#include "analog.h"
```
## Channels
### AVR
|Channel|AT90USB64/128|ATmega16/32U4|ATmega32A|ATmega328/P|
|-------|-------------|-------------|---------|----------|
|0 |`F0` |`F0` |`A0` |`C0` |
|1 |`F1` |`F1` |`A1` |`C1` |
|2 |`F2` | |`A2` |`C2` |
|3 |`F3` | |`A3` |`C3` |
|4 |`F4` |`F4` |`A4` |`C4` |
|5 |`F5` |`F5` |`A5` |`C5` |
|6 |`F6` |`F6` |`A6` |* |
|7 |`F7` |`F7` |`A7` |* |
|8 | |`D4` | | |
|9 | |`D6` | | |
|10 | |`D7` | | |
|11 | |`B4` | | |
|12 | |`B5` | | |
|13 | |`B6` | | |
<sup>\* The ATmega328/P possesses two extra ADC channels; however, they are not present on the DIP pinout, and are not shared with GPIO pins. You can use `adc_read()` directly to gain access to these.</sup>
### ARM
Note that some of these pins are doubled-up on ADCs with the same channel. This is because the pins can be used for either ADC.
Also note that the F0 and F3 use different numbering schemes. The F0 has a single ADC and the channels are 0-indexed, whereas the F3 has 4 ADCs and the channels are 1-indexed. This is because the F0 uses the `ADCv1` implementation of the ADC, whereas the F3 uses the `ADCv3` implementation.
|ADC|Channel|STM32F0xx|STM32F1xx|STM32F3xx|STM32F4xx|
|---|-------|---------|---------|---------|---------|
|1 |0 |`A0` |`A0` | |`A0` |
|1 |1 |`A1` |`A1` |`A0` |`A1` |
|1 |2 |`A2` |`A2` |`A1` |`A2` |
|1 |3 |`A3` |`A3` |`A2` |`A3` |
|1 |4 |`A4` |`A4` |`A3` |`A4` |
|1 |5 |`A5` |`A5` |`F4` |`A5` |
|1 |6 |`A6` |`A6` |`C0` |`A6` |
|1 |7 |`A7` |`A7` |`C1` |`A7` |
|1 |8 |`B0` |`B0` |`C2` |`B0` |
|1 |9 |`B1` |`B1` |`C3` |`B1` |
|1 |10 |`C0` |`C0` |`F2` |`C0` |
|1 |11 |`C1` |`C1` | |`C1` |
|1 |12 |`C2` |`C2` | |`C2` |
|1 |13 |`C3` |`C3` | |`C3` |
|1 |14 |`C4` |`C4` | |`C4` |
|1 |15 |`C5` |`C5` | |`C5` |
|1 |16 | | | | |
|2 |0 | |`A0`¹ | |`A0`² |
|2 |1 | |`A1`¹ |`A4` |`A1`² |
|2 |2 | |`A2`¹ |`A5` |`A2`² |
|2 |3 | |`A3`¹ |`A6` |`A3`² |
|2 |4 | |`A4`¹ |`A7` |`A4`² |
|2 |5 | |`A5`¹ |`C4` |`A5`² |
|2 |6 | |`A6`¹ |`C0` |`A6`² |
|2 |7 | |`A7`¹ |`C1` |`A7`² |
|2 |8 | |`B0`¹ |`C2` |`B0`² |
|2 |9 | |`B1`¹ |`C3` |`B1`² |
|2 |10 | |`C0`¹ |`F2` |`C0`² |
|2 |11 | |`C1`¹ |`C5` |`C1`² |
|2 |12 | |`C2`¹ |`B2` |`C2`² |
|2 |13 | |`C3`¹ | |`C3`² |
|2 |14 | |`C4`¹ | |`C4`² |
|2 |15 | |`C5`¹ | |`C5`² |
|2 |16 | | | | |
|3 |0 | |`A0`¹ | |`A0`² |
|3 |1 | |`A1`¹ |`B1` |`A1`² |
|3 |2 | |`A2`¹ |`E9` |`A2`² |
|3 |3 | |`A3`¹ |`E13` |`A3`² |
|3 |4 | |`F6`¹ | |`F6`² |
|3 |5 | |`F7`¹ |`B13` |`F7`² |
|3 |6 | |`F8`¹ |`E8` |`F8`² |
|3 |7 | |`F9`¹ |`D10` |`F9`² |
|3 |8 | |`F10`¹ |`D11` |`F10`² |
|3 |9 | | |`D12` |`F3`² |
|3 |10 | |`C0`¹ |`D13` |`C0`² |
|3 |11 | |`C1`¹ |`D14` |`C1`² |
|3 |12 | |`C2`¹ |`B0` |`C2`² |
|3 |13 | |`C3`¹ |`E7` |`C3`² |
|3 |14 | | |`E10` |`F4`² |
|3 |15 | | |`E11` |`F5`² |
|3 |16 | | |`E12` | |
|4 |1 | | |`E14` | |
|4 |2 | | |`E15` | |
|4 |3 | | |`B12` | |
|4 |4 | | |`B14` | |
|4 |5 | | |`B15` | |
|4 |6 | | |`E8` | |
|4 |7 | | |`D10` | |
|4 |8 | | |`D11` | |
|4 |9 | | |`D12` | |
|4 |10 | | |`D13` | |
|4 |11 | | |`D14` | |
|4 |12 | | |`D8` | |
|4 |13 | | |`D9` | |
|4 |14 | | | | |
|4 |15 | | | | |
|4 |16 | | | | |
<sup>¹ As of ChibiOS 20.3.4, the ADC driver for STM32F1xx devices supports only ADC1, therefore any configurations involving ADC2 or ADC3 cannot actually be used. In particular, pins `F6``F10`, which are present at least on some STM32F103x[C-G] devices, cannot be used as ADC inputs because of this driver limitation.</sup>
<sup>² Not all STM32F4xx devices have ADC2 and/or ADC3, therefore some configurations shown in this table may be unavailable; in particular, pins `F4``F10` cannot be used as ADC inputs on devices which do not have ADC3. Check the device datasheet to confirm which pin functions are supported.</sup>
## Functions
### AVR
|Function |Description |
|----------------------------|-------------------------------------------------------------------------------------------------------------------|
|`analogReference(mode)` |Sets the analog voltage reference source. Must be one of `ADC_REF_EXTERNAL`, `ADC_REF_POWER` or `ADC_REF_INTERNAL`.|
|`analogReadPin(pin)` |Reads the value from the specified pin, eg. `F6` for ADC6 on the ATmega32U4. |
|`pinToMux(pin)` |Translates a given pin to a mux value. If an unsupported pin is given, returns the mux value for "0V (GND)". |
|`adc_read(mux)` |Reads the value from the ADC according to the specified mux. See your MCU's datasheet for more information. |
### ARM
|Function |Description |
|----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|`analogReadPin(pin)` |Reads the value from the specified pin, eg. `A0` for channel 0 on the STM32F0 and ADC1 channel 1 on the STM32F3. Note that if a pin can be used for multiple ADCs, it will pick the lower numbered ADC for this function. eg. `C0` will be channel 6 of ADC 1 when it could be used for ADC 2 as well.|
|`analogReadPinAdc(pin, adc)`|Reads the value from the specified pin and ADC, eg. `C0, 1` will read from channel 6, ADC 2 instead of ADC 1. Note that the ADCs are 0-indexed for this function. |
|`pinToMux(pin)` |Translates a given pin to a channel and ADC combination. If an unsupported pin is given, returns the mux value for "0V (GND)". |
|`adc_read(mux)` |Reads the value from the ADC according to the specified pin and ADC combination. See your MCU's datasheet for more information. |
## Configuration
## ARM
The ARM implementation of the ADC has a few additional options that you can override in your own keyboards and keymaps to change how it operates. Please consult the corresponding `hal_adc_lld.h` in ChibiOS for your specific microcontroller for further documentation on your available options.
|`#define` |Type |Default |Description |
|---------------------|------|----------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|`ADC_CIRCULAR_BUFFER`|`bool`|`false` |If `true`, then the implementation will use a circular buffer. |
|`ADC_NUM_CHANNELS` |`int` |`1` |Sets the number of channels that will be scanned as part of an ADC operation. The current implementation only supports `1`. |
|`ADC_BUFFER_DEPTH` |`int` |`2` |Sets the depth of each result. Since we are only getting a 10-bit result by default, we set this to 2 bytes so we can contain our one value. This could be set to 1 if you opt for an 8-bit or lower result.|
|`ADC_SAMPLING_RATE` |`int` |`ADC_SMPR_SMP_1P5` |Sets the sampling rate of the ADC. By default, it is set to the fastest setting. |
|`ADC_RESOLUTION` |`int` |`ADC_CFGR1_RES_10BIT` or `ADC_CFGR_RES_10BITS`|The resolution of your result. We choose 10 bit by default, but you can opt for 12, 10, 8, or 6 bit. Different MCUs use slightly different names for the resolution constants. |

View file

@ -0,0 +1,44 @@
# QMK Compiler Development Guide
This page attempts to introduce developers to the QMK Compiler. It does not go into nitty gritty details- for that you should read code. What this will give you is a framework to hang your understanding on as you read the code.
# Overview
The QMK Compile API consists of a few movings parts:
![Architecture Diagram](https://raw.githubusercontent.com/qmk/qmk_api/master/docs/architecture.svg)
API Clients interact exclusively with the API service. This is where they submit jobs, check status, and download results. The API service inserts compile jobs into [Redis Queue](https://python-rq.org) and checks both RQ and S3 for the results of those jobs.
Workers fetch new compile jobs from RQ, compile them, and then upload the source and the binary to an S3 compatible storage engine.
# Workers
QMK Compiler Workers are responsible for doing the actual building. When a worker pulls a job from RQ it does several things to complete that job:
* Make a fresh qmk_firmware checkout
* Use the supplied layers and keyboard metadata to build a `keymap.c`
* Build the firmware
* Zip a copy of the source
* Upload the firmware, source zip, and a metadata file to S3.
* Report the status of the job to RQ
# API Service
The API service is a relatively simple Flask application. There are a few main views you should understand.
## @app.route('/v1/compile', methods=['POST'])
This is the main entrypoint for the API. A client's interaction starts here. The client POST's a JSON document describing their keyboard, and the API does some (very) basic validation of that JSON before submitting the compile job.
## @app.route('/v1/compile/&lt;string:job_id&gt;', methods=['GET'])
This is the most frequently called endpoint. It pulls the job details from redis, if they're still available, or the cached job details on S3 if they're not.
## @app.route('/v1/compile/&lt;string:job_id&gt;/download', methods=['GET'])
This method allows users to download the compiled firmware file.
## @app.route('/v1/compile/&lt;string:job_id&gt;/source', methods=['GET'])
This method allows users to download the source for their firmware.

68
api_docs.md Normal file
View file

@ -0,0 +1,68 @@
# QMK API
This page describes using the QMK API. If you are an application developer you can use this API to compile firmware for any [QMK](https://qmk.fm) Keyboard.
## Overview
This service is an asynchronous API for compiling custom keymaps. You POST some JSON to the API, periodically check the status, and when your firmware has finished compiling you can download the resulting firmware and (if desired) source code for that firmware.
#### Example JSON Payload:
```json
{
"keyboard": "clueboard/66/rev2",
"keymap": "my_awesome_keymap",
"layout": "LAYOUT_all",
"layers": [
["KC_GRV","KC_1","KC_2","KC_3","KC_4","KC_5","KC_6","KC_7","KC_8","KC_9","KC_0","KC_MINS","KC_EQL","KC_GRV","KC_BSPC","KC_PGUP","KC_TAB","KC_Q","KC_W","KC_E","KC_R","KC_T","KC_Y","KC_U","KC_I","KC_O","KC_P","KC_LBRC","KC_RBRC","KC_BSLS","KC_PGDN","KC_CAPS","KC_A","KC_S","KC_D","KC_F","KC_G","KC_H","KC_J","KC_K","KC_L","KC_SCLN","KC_QUOT","KC_NUHS","KC_ENT","KC_LSFT","KC_NUBS","KC_Z","KC_X","KC_C","KC_V","KC_B","KC_N","KC_M","KC_COMM","KC_DOT","KC_SLSH","KC_RO","KC_RSFT","KC_UP","KC_LCTL","KC_LGUI","KC_LALT","KC_MHEN","KC_SPC","KC_SPC","KC_HENK","KC_RALT","KC_RCTL","MO(1)","KC_LEFT","KC_DOWN","KC_RIGHT"],
["KC_ESC","KC_F1","KC_F2","KC_F3","KC_F4","KC_F5","KC_F6","KC_F7","KC_F8","KC_F9","KC_F10","KC_F11","KC_F12","KC_TRNS","KC_DEL","BL_STEP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","_______","KC_TRNS","KC_PSCR","KC_SLCK","KC_PAUS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_PGUP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_LEFT","KC_PGDN","KC_RGHT"],
["KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","RESET","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_TRNS","KC_TRNS","KC_TRNS"]
]
}
```
As you can see the payload describes all aspects of a keyboard necessary to create and generate a firmware. Each layer is a single list of QMK keycodes the same length as the keyboard's `LAYOUT` macro. If a keyboard supports mulitple `LAYOUT` macros you can specify which macro to use.
## Submitting a Compile Job
To compile your keymap into a firmware simply POST your JSON to the `/v1/compile` endpoint. In the following example we've placed the JSON payload into a file named `json_data`.
```
$ curl -H "Content-Type: application/json" -X POST -d "$(< json_data)" https://api.qmk.fm/v1/compile
{
"enqueued": true,
"job_id": "ea1514b3-bdfc-4a7b-9b5c-08752684f7f6"
}
```
## Checking The Status
After submitting your keymap you can check the status using a simple HTTP GET call:
```
$ curl https://api.qmk.fm/v1/compile/ea1514b3-bdfc-4a7b-9b5c-08752684f7f6
{
"created_at": "Sat, 19 Aug 2017 21:39:12 GMT",
"enqueued_at": "Sat, 19 Aug 2017 21:39:12 GMT",
"id": "f5f9b992-73b4-479b-8236-df1deb37c163",
"status": "running",
"result": null
}
```
This shows us that the job has made it through the queue and is currently running. There are 5 possible statuses:
* **failed**: Something about the compiling service has broken.
* **finished**: The compilation is complete and you should check `result` to see the results.
* **queued**: The keymap is waiting for a compilation server to become available.
* **running**: The compilation is in progress and should be complete soon.
* **unknown**: A serious error has occurred and you should [file a bug](https://github.com/qmk/qmk_compiler/issues).
## Examining Finished Results
Once your compile job has finished you'll check the `result` key. The value of this key is a hash containing several key bits of information:
* `firmware_binary_url`: A list of URLs for the flashable firmware
* `firmware_keymap_url`: A list of URLs for the `keymap.c`
* `firmware_source_url`: A list of URLs for the full firmware source code
* `output`: The stdout and stderr for this compile job. Errors will be found here.

15
api_overview.md Normal file
View file

@ -0,0 +1,15 @@
# QMK API
The QMK API provides an asynchronous API that Web and GUI tools can use to compile arbitrary keymaps for any keyboard supported by [QMK](https://qmk.fm/). The stock keymap template supports all QMK keycodes that do not require supporting C code. Keyboard maintainers can supply their own custom templates to enable more functionality.
## App Developers
If you are an app developer interested in using this API in your application you should head over to [Using The API](api_docs.md).
## Keyboard Maintainers
If you would like to enhance your keyboard's support in the QMK Compiler API head over to the [Keyboard Support](reference_configurator_support.md) section.
## Backend Developers
If you are interested in working on the API itself you should start by setting up a [Development Environment](api_development_environment.md), then check out [Hacking On The API](api_development_overview.md).

221
audio_driver.md Normal file
View file

@ -0,0 +1,221 @@
# Audio Driver :id=audio-driver
The [Audio feature](feature_audio.md) breaks the hardware specifics out into separate, exchangeable driver units, with a common interface to the audio-"core" - which itself handles playing songs and notes while tracking their progress in an internal state, initializing/starting/stopping the driver as needed.
Not all MCUs support every available driver, either the platform-support is not there (yet?) or the MCU simply does not have the required hardware peripheral.
## AVR :id=avr
Boards built around an Atmega32U4 can use two sets of PWM capable pins, each driving a separate speaker.
The possible configurations are:
| | Timer3 | Timer1 |
|--------------|-------------|--------------|
| one speaker | C4,C5 or C6 | |
| one speaker | | B4, B5 or B7 |
| two speakers | C4,C5 or C6 | B4, B5 or B7 |
Currently there is only one/default driver for AVR based boards, which is automatically configured to:
```make
AUDIO_DRIVER = pwm_hardware
```
## ARM :id=arm
For Arm based boards, QMK depends on ChibiOS - hence any MCU supported by the later is likely usable, as long as certain hardware peripherals are available.
Supported wiring configurations, with their ChibiOS/MCU peripheral requirement are listed below;
piezo speakers are marked with :one: for the first/primary and :two: for the secondary.
| driver | GPTD6<br>Tim6 | GPTD7<br>Tim7 | GPTD8<br>Tim8 | PWMD1<sup>1</sup><br>Tim1_Ch1 |
|--------------|------------------------------------------|------------------------|---------------|-------------------------------|
| dac_basic | A4+DACD1 = :one: | A5+DACD2 = :one: | state | |
| | A4+DACD1 = :one: + Gnd | A5+DACD2 = :two: + Gnd | state | |
| | A4+DACD1 = :two: + Gnd | A5+DACD2 = :one: + Gnd | state | |
| | A4+DACD1 = :one: + Gnd | | state | |
| | | A5+DACD2 = :one: + Gnd | state | |
| dac_additive | A4+DACD1 = :one: + Gnd | | | |
| | A5+DACD2 = :one: + Gnd | | | |
| | A4+DACD1 + A5+DACD2 = :one: <sup>2</sup> | | | |
| pwm_software | state-update | | | any = :one: |
| pwm hardware | state-update | | | A8 = :one: <sup>3</sup> |
<sup>1</sup>: the routing and alternate functions for PWM differ sometimes between STM32 MCUs, if in doubt consult the data-sheet
<sup>2</sup>: one piezo connected to A4 and A5, with AUDIO_PIN_ALT_AS_NEGATIVE set
<sup>3</sup>: TIM1_CH1 = A8 on STM32F103C8, other combinations are possible, see Data-sheet. configured with: AUDIO_PWM_DRIVER and AUDIO_PWM_CHANNEL
### DAC basic :id=dac-basic
The default driver for ARM boards, in absence of an overriding configuration.
This driver needs one Timer per enabled/used DAC channel, to trigger conversion; and a third timer to trigger state updates with the audio-core.
Additionally, in the board config, you'll want to make changes to enable the DACs, GPT for Timers 6, 7 and 8:
```c
//halconf.h:
#define HAL_USE_DAC TRUE
#define HAL_USE_GPT TRUE
#include_next <halconf.h>
```
```c
// mcuconf.h:
#include_next <mcuconf.h>
#undef STM32_DAC_USE_DAC1_CH1
#define STM32_DAC_USE_DAC1_CH1 TRUE
#undef STM32_DAC_USE_DAC1_CH2
#define STM32_DAC_USE_DAC1_CH2 TRUE
#undef STM32_GPT_USE_TIM6
#define STM32_GPT_USE_TIM6 TRUE
#undef STM32_GPT_USE_TIM7
#define STM32_GPT_USE_TIM7 TRUE
#undef STM32_GPT_USE_TIM8
#define STM32_GPT_USE_TIM8 TRUE
```
?> Note: DAC1 (A4) uses TIM6, DAC2 (A5) uses TIM7, and the audio state timer uses TIM8 (configurable).
You can also change the timer used for the overall audio state by defining the driver. For instance:
```c
#define AUDIO_STATE_TIMER GPTD9
```
### DAC additive :id=dac-additive
only needs one timer (GPTD6, Tim6) to trigger the DAC unit to do a conversion; the audio state updates are in turn triggered during the DAC callback.
Additionally, in the board config, you'll want to make changes to enable the DACs, GPT for Timer 6:
```c
//halconf.h:
#define HAL_USE_DAC TRUE
#define HAL_USE_GPT TRUE
#include_next <halconf.h>
```
```c
// mcuconf.h:
#include_next <mcuconf.h>
#undef STM32_DAC_USE_DAC1_CH1
#define STM32_DAC_USE_DAC1_CH1 TRUE
#undef STM32_DAC_USE_DAC1_CH2
#define STM32_DAC_USE_DAC1_CH2 TRUE
#undef STM32_GPT_USE_TIM6
#define STM32_GPT_USE_TIM6 TRUE
```
### DAC Config
| Define | Defaults | Description --------------------------------------------------------------------------------------------- |
| `AUDIO_DAC_SAMPLE_MAX` | `4095U` | Highest value allowed. Lower value means lower volume. And 4095U is the upper limit, since this is limited to a 12 bit value. Only effects non-pregenerated samples. |
| `AUDIO_DAC_OFF_VALUE` | `AUDIO_DAC_SAMPLE_MAX / 2` | The value of the DAC when notplaying anything. Some setups may require a high (`AUDIO_DAC_SAMPLE_MAX`) or low (`0`) value here. |
| `AUDIO_MAX_SIMULTANEOUS_TONES` | __see next table__ | The number of tones that can be played simultaneously. A value that is too high may freeze the controller or glitch out when too many tones are being played. |
| `AUDIO_DAC_SAMPLE_RATE` | __see next table__ | Effective bit rate of the DAC (in hertz), higher limits simultaneous tones, and lower sacrifices quality. |
There are a number of predefined quality settings that you can use, with "sane minimum" being the default. You can use custom values by simply defining the sample rate and number of simultaneous tones, instead of using one of the listed presets.
| Define | Sample Rate | Simultaneous tones |
| `AUDIO_DAC_QUALITY_VERY_LOW` | `11025U` | `8` |
| `AUDIO_DAC_QUALITY_LOW` | `22040U` | `4` |
| `AUDIO_DAC_QUALITY_HIGH` | `44100U` | `2` |
| `AUDIO_DAC_QUALITY_VERY_HIGH` | `88200U` | `1` |
| `AUDIO_DAC_QUALITY_SANE_MINIMUM` | `16384U` | `8` |
```c
/* zero crossing (or approach, whereas zero == DAC_OFF_VALUE, which can be configured to anything from 0 to DAC_SAMPLE_MAX)
* ============================*=*========================== AUDIO_DAC_SAMPLE_MAX
* * *
* * *
* ---------------------------------------------------------
* * * } AUDIO_DAC_SAMPLE_MAX/100
* --------------------------------------------------------- AUDIO_DAC_OFF_VALUE
* * * } AUDIO_DAC_SAMPLE_MAX/100
* ---------------------------------------------------------
* *
* * *
* * *
* =====*=*================================================= 0x0
*/
```
### PWM hardware :id=pwm-hardware
This driver uses the ChibiOS-PWM system to produce a square-wave on specific output pins that are connected to the PWM hardware.
The hardware directly toggles the pin via its alternate function. See your MCU's data-sheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function.
A configuration example for the STM32F103C8 would be:
```c
//halconf.h:
#define HAL_USE_PWM TRUE
#define HAL_USE_PAL TRUE
#define HAL_USE_GPT TRUE
#include_next <halconf.h>
```
```c
// mcuconf.h:
#include_next <mcuconf.h>
#undef STM32_PWM_USE_TIM1
#define STM32_PWM_USE_TIM1 TRUE
#undef STM32_GPT_USE_TIM4
#define STM32_GPT_USE_TIM4 TRUE
```
If we now target pin A8, looking through the data-sheet of the STM32F103C8, for the timers and alternate functions
- TIM1_CH1 = PA8 <- alternate0
- TIM1_CH2 = PA9
- TIM1_CH3 = PA10
- TIM1_CH4 = PA11
with all this information, the configuration would contain these lines:
```c
//config.h:
#define AUDIO_PIN A8
#define AUDIO_PWM_DRIVER PWMD1
#define AUDIO_PWM_CHANNEL 1
#define AUDIO_STATE_TIMER GPTD4
```
ChibiOS uses GPIOv1 for the F103, which only knows of one alternate function.
On 'larger' STM32s, GPIOv2 or GPIOv3 are used; with them it is also necessary to configure `AUDIO_PWM_PAL_MODE` to the correct alternate function for the selected pin, timer and timer-channel.
### PWM software :id=pwm-software
This driver uses the PWM callbacks from PWMD1 with TIM1_CH1 to toggle the selected AUDIO_PIN in software.
During the same callback, with AUDIO_PIN_ALT_AS_NEGATIVE set, the AUDIO_PIN_ALT is toggled inversely to AUDIO_PIN. This is useful for setups that drive a piezo from two pins (instead of one and Gnd).
You can also change the timer used for software PWM by defining the driver. For instance:
```c
#define AUDIO_STATE_TIMER GPTD8
```
### Testing Notes :id=testing-notes
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
| | DAC basic | DAC additive | PWM hardware | PWM software |
|--------------------------|--------------------|--------------------|--------------------|--------------------|
| Atmega32U4 | :o: | :o: | :heavy_check_mark: | :o: |
| STM32F103C8 (bluepill) | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
| STM32F303CCT6 (proton-c) | :heavy_check_mark: | :heavy_check_mark: | ? | :heavy_check_mark: |
| STM32F405VG | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| L0xx | :x: (no Tim8) | ? | ? | ? |
:heavy_check_mark: : works and was tested
:o: : does not apply
:x: : not supported by MCU
*Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.*

121
breaking_changes.md Normal file
View file

@ -0,0 +1,121 @@
# Breaking Changes
This document describes QMK's Breaking Change process. A Breaking Change is any change which modifies how QMK behaves in a way that in incompatible or potentially dangerous. We limit these changes so that users can have confidence that updating their QMK tree will not break their keymaps.
This also includes any keyboard moves within the repository.
The breaking change period is when we will merge PR's that change QMK in dangerous or unexpected ways. There is a built-in period of testing so we are confident that any problems caused are rare or unable to be predicted.
## What has been included in past Breaking Changes?
* [2022 Feb 26](ChangeLog/20220226.md)
* [2021 Nov 27](ChangeLog/20211127.md)
* [2021 Aug 28](ChangeLog/20210828.md)
* [2021 May 29](ChangeLog/20210529.md)
* [2021 Feb 27](ChangeLog/20210227.md)
* [2020 Nov 28](ChangeLog/20201128.md)
* [2020 Aug 29](ChangeLog/20200829.md)
* [2020 May 30](ChangeLog/20200530.md)
* [2020 Feb 29](ChangeLog/20200229.md)
* [2019 Aug 30](ChangeLog/20190830.md)
## When is the next Breaking Change?
The next Breaking Change is scheduled for May 28, 2022.
### Important Dates
* [x] 2022 Feb 26 - `develop` is tagged with a new release version. Each push to `master` is subsequently merged to `develop` by GitHub actions.
* [ ] 2022 Apr 31 - `develop` closed to new PR's.
* [ ] 2022 Apr 31 - Call for testers.
* [ ] 2022 May 14 - Last day for merges -- after this point `develop` is locked for testing and accepts only bugfixes
* [ ] 2022 May 26 - `master` is locked, no PR's merged.
* [ ] 2022 May 28 - Merge `develop` to `master`.
* [ ] 2022 May 28 - `master` is unlocked. PR's can be merged again.
## What changes will be included?
To see a list of breaking change candidates you can look at the [`breaking_change` label](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+label%3Abreaking_change+is%3Apr). New changes might be added between now and when `develop` is closed, and a PR with that label applied is not guaranteed to be merged.
If you want your breaking change to be included in this round you need to create a PR with the `breaking_change` label and have it accepted before `develop` closes. After `develop` closes no new breaking changes will be accepted.
Criteria for acceptance:
* The PR is complete and ready to merge
* The PR has a ChangeLog file describing the changes under `<qmk_firmware>/docs/Changelog/20220226`.
* This should be in Markdown format, with a name in the format `PR12345.md`, substituting the digits for your PR's ID.
* One strong recommendation that the ChangeLog document matches the PR description on GitHub, so as to ensure traceability.
# Checklists
This section documents various processes we use when running the Breaking Changes process.
## Creating the `develop` branch
This happens immediately after the previous `develop` branch is merged.
* `qmk_firmware` git commands
* [ ] `git checkout master`
* [ ] `git pull --ff-only`
* [ ] `git checkout -b develop`
* [ ] Edit `readme.md`
* [ ] Add a big notice at the top that this is a testing branch.
* [ ] Include a link to this document
* [ ] `git commit -m 'Branch point for <DATE> Breaking Change'`
* [ ] `git tag breakpoint_<YYYY>_<MM>_<DD>`
* [ ] `git tag <next_version>` # Prevent the breakpoint tag from confusing version incrementing
* [ ] `git push upstream develop`
* [ ] `git push --tags`
## 4 Weeks Before Merge
* `develop` is now closed to new PR's, only fixes for current PR's may be merged
* Post call for testers
* [ ] Discord
* [ ] GitHub PR
* [ ] https://reddit.com/r/olkb
## 2 Weeks Before Merge
* `develop` is now closed to existing PR merges, only bugfixes for previous merges may be included
* Post call for testers
* [ ] Discord
* [ ] GitHub PR
* [ ] https://reddit.com/r/olkb
## 1 Week Before Merge
* Announce that master will be closed from <2 Days Before> to <Day of Merge>
* [ ] Discord
* [ ] GitHub PR
* [ ] https://reddit.com/r/olkb
## 2 Days Before Merge
* Announce that master is closed for 2 days
* [ ] Discord
* [ ] GitHub PR
* [ ] https://reddit.com/r/olkb
## Day Of Merge
* `qmk_firmware` git commands
* [ ] `git checkout develop`
* [ ] `git pull --ff-only`
* [ ] Edit `readme.md`
* [ ] Remove the notes about `develop`
* [ ] Roll up the ChangeLog into one file.
* [ ] `git commit -m 'Merge point for <DATE> Breaking Change'`
* [ ] `git push upstream develop`
* GitHub Actions
* [ ] Create a PR for `develop`
* [ ] **Turn off 'Automatically delete head branches' for the repository** -- confirm with @qmk/directors that it is done before continuing
* `qmk_firmware` git commands
* [ ] `git checkout master`
* [ ] `git pull --ff-only`
* [ ] `git merge --no-ff develop`
* [ ] `git push upstream master`
## Post-merge operations
* (Optional) [update ChibiOS + ChibiOS-Contrib on `develop`](chibios_upgrade_instructions.md)

View file

@ -0,0 +1,14 @@
# Past Breaking Changes
This page links to all previous changelogs from the QMK Breaking Changes process.
* [2022 Feb 26](ChangeLog/20220226.md) - version 0.16.0
* [2021 Nov 27](ChangeLog/20211127.md) - version 0.15.0
* [2021 Aug 28](ChangeLog/20210828.md) - version 0.14.0
* [2021 May 29](ChangeLog/20210529.md) - version 0.13.0
* [2021 Feb 27](ChangeLog/20210227.md) - version 0.12.0
* [2020 Nov 28](ChangeLog/20201128.md) - version 0.11.0
* [2020 Aug 29](ChangeLog/20200829.md) - version 0.10.0
* [2020 May 30](ChangeLog/20200530.md) - version 0.9.0
* [2020 Feb 29](ChangeLog/20200229.md) - version 0.8.0
* [2019 Aug 30](ChangeLog/20190830.md) - version 0.7.0

View file

@ -0,0 +1,42 @@
# Breaking Changes: My Pull Request Was Flagged
A QMK member may have replied to your pull request stating that your submission is a breaking change. In their judgment, the changes you have proposed have greater implications for either QMK, or its users.
Some things that may cause a pull request to be flagged are:
- **Edits to User Keymaps**
A user may submit their keymap to QMK, then some time later open a pull request with further updates, only to find it can't be merged because it was edited in the `qmk/qmk_firmware` repository. As not all users are proficient at using Git or GitHub, the user may find themself unable to fix the issue on their own.
- **Changes to Expected Behavior**
Changes to QMK behavior may cause users to believe their hardware or QMK is broken if they flash new firmware that incorporates changes to existing QMK features, and find themselves without a means to restore the desired behavior.
- **Changes Requiring User Action**
Changes may also require action to be taken by users, such as updating a toolchain or taking some action in Git.
- **Changes Necessitating Increased Scrutiny**
On occasion, a submission may have implications for QMK as a project. This could be copyright/licensing issues, coding conventions, large feature overhauls, "high-risk" changes that need wider testing by our community, or something else entirely.
- **Changes Requiring Communication to End Users**
This includes warnings about future deprecations, outdated practices, and anything else that needs to be communicated but doesn't fit into one of the above categories.
## What Do I Do?
If it is determined that your submission is a breaking change, there are a few things you can do to smooth the process:
### Consider Splitting Up Your PR
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 &ndash; [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 &ndash; usually named `develop` &ndash; 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.
Commenting on your pull request and being responsive to questions, comments, and change requests is much appreciated.
### Ask for Help
Having your submission flagged may have caught you off guard. If you find yourself intimidated or overwhelmed, let us know. Comment on your pull request, or [reach out to the QMK team on Discord](https://discord.gg/Uq7gcHh).

View file

@ -1,37 +0,0 @@
# Copyright 2017 Fred Sundvik
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
$(TEST_OUTPUT)_INC := \
tests/test_common/common_config.h
$(TEST_OUTPUT)_SRC := \
$(QUANTUM_SRC) \
$(SRC) \
$(QUANTUM_PATH)/keymap_introspection.c \
tests/test_common/matrix.c \
tests/test_common/pointing_device_driver.c \
tests/test_common/test_driver.cpp \
tests/test_common/keyboard_report_util.cpp \
tests/test_common/mouse_report_util.cpp \
tests/test_common/test_fixture.cpp \
tests/test_common/test_keymap_key.cpp \
tests/test_common/test_logger.cpp \
$(patsubst $(ROOTDIR)/%,%,$(wildcard $(TEST_PATH)/*.cpp))
$(TEST_OUTPUT)_DEFS := $(OPT_DEFS) "-DKEYMAP_C=\"keymap.c\""
$(TEST_OUTPUT)_CONFIG := $(TEST_PATH)/config.h
VPATH += $(TOP_DIR)/tests/test_common

View file

@ -1,36 +0,0 @@
# Look for a json keymap file
ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_5)/keymap.json)","")
KEYMAP_JSON := $(MAIN_KEYMAP_PATH_5)/keymap.json
KEYMAP_JSON_PATH := $(MAIN_KEYMAP_PATH_5)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_4)/keymap.json)","")
KEYMAP_JSON := $(MAIN_KEYMAP_PATH_4)/keymap.json
KEYMAP_JSON_PATH := $(MAIN_KEYMAP_PATH_4)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_3)/keymap.json)","")
KEYMAP_JSON := $(MAIN_KEYMAP_PATH_3)/keymap.json
KEYMAP_JSON_PATH := $(MAIN_KEYMAP_PATH_3)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_2)/keymap.json)","")
KEYMAP_JSON := $(MAIN_KEYMAP_PATH_2)/keymap.json
KEYMAP_JSON_PATH := $(MAIN_KEYMAP_PATH_2)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_1)/keymap.json)","")
KEYMAP_JSON := $(MAIN_KEYMAP_PATH_1)/keymap.json
KEYMAP_JSON_PATH := $(MAIN_KEYMAP_PATH_1)
endif
ifneq ($(QMK_USERSPACE),)
ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_5)/keymap.json)","")
KEYMAP_JSON := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_5)/keymap.json
KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_5)
else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_4)/keymap.json)","")
KEYMAP_JSON := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_4)/keymap.json
KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_4)
else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_3)/keymap.json)","")
KEYMAP_JSON := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_3)/keymap.json
KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_3)
else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_2)/keymap.json)","")
KEYMAP_JSON := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_2)/keymap.json
KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_2)
else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_1)/keymap.json)","")
KEYMAP_JSON := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_1)/keymap.json
KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_1)
endif
endif

View file

@ -1,621 +0,0 @@
# Determine what keyboard we are building and setup the build environment.
#
# We support folders up to 5 levels deep below `keyboards/`. This file is
# responsible for determining which folder is being used and doing the
# corresponding environment setup.
ifndef VERBOSE
.SILENT:
endif
.DEFAULT_GOAL := all
include paths.mk
include $(BUILDDEFS_PATH)/support.mk
include $(BUILDDEFS_PATH)/message.mk
# Helper to add defines with a 'QMK_' prefix
define add_qmk_prefix_defs
ifdef $1
# Need to cater for 'STM32L4xx+'
OPT_DEFS += -DQMK_$(2)="$($1)" -DQMK_$(2)_$(shell echo $($1) | sed -e 's@+@Plus@g' -e 's@[^a-zA-Z0-9]@_@g' | tr '[:lower:]' '[:upper:]')
endif
endef
# Set the qmk cli to use
QMK_BIN ?= qmk
# Set the filename for the final firmware binary
KEYBOARD_FILESAFE := $(subst /,_,$(KEYBOARD))
TARGET ?= $(KEYBOARD_FILESAFE)_$(KEYMAP)
ifeq ($(strip $(DUMP_CI_METADATA)),yes)
$(info CI Metadata: KEYBOARD=$(KEYBOARD))
$(info CI Metadata: KEYMAP=$(KEYMAP))
endif
# Force expansion
override TARGET := $(TARGET)
ifneq ($(FORCE_LAYOUT),)
override TARGET := $(TARGET)_$(FORCE_LAYOUT)
endif
ifneq ($(CONVERT_TO),)
override TARGET := $(TARGET)_$(CONVERT_TO)
endif
# Object files and generated keymap directory
# To put object files in current directory, use a dot (.), do NOT make
# this an empty or blank macro!
INTERMEDIATE_OUTPUT := $(BUILD_DIR)/obj_$(TARGET)
ifdef SKIP_VERSION
OPT_DEFS += -DSKIP_VERSION
endif
# Generate the version.h file
VERSION_H_FLAGS :=
ifdef SKIP_VERSION
VERSION_H_FLAGS += --skip-all
endif
ifdef SKIP_GIT
VERSION_H_FLAGS += --skip-git
endif
# Determine which subfolders exist.
KEYBOARD_FOLDER_PATH_1 := $(KEYBOARD)
KEYBOARD_FOLDER_PATH_2 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_1)))
KEYBOARD_FOLDER_PATH_3 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_2)))
KEYBOARD_FOLDER_PATH_4 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_3)))
KEYBOARD_FOLDER_PATH_5 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_4)))
KEYBOARD_FOLDER_1 := $(notdir $(KEYBOARD_FOLDER_PATH_1))
KEYBOARD_FOLDER_2 := $(notdir $(KEYBOARD_FOLDER_PATH_2))
KEYBOARD_FOLDER_3 := $(notdir $(KEYBOARD_FOLDER_PATH_3))
KEYBOARD_FOLDER_4 := $(notdir $(KEYBOARD_FOLDER_PATH_4))
KEYBOARD_FOLDER_5 := $(notdir $(KEYBOARD_FOLDER_PATH_5))
KEYBOARD_PATHS :=
KEYBOARD_PATH_1 := keyboards/$(KEYBOARD_FOLDER_PATH_1)
KEYBOARD_PATH_2 := keyboards/$(KEYBOARD_FOLDER_PATH_2)
KEYBOARD_PATH_3 := keyboards/$(KEYBOARD_FOLDER_PATH_3)
KEYBOARD_PATH_4 := keyboards/$(KEYBOARD_FOLDER_PATH_4)
KEYBOARD_PATH_5 := keyboards/$(KEYBOARD_FOLDER_PATH_5)
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/)","")
KEYBOARD_PATHS += $(KEYBOARD_PATH_5)
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/)","")
KEYBOARD_PATHS += $(KEYBOARD_PATH_4)
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/)","")
KEYBOARD_PATHS += $(KEYBOARD_PATH_3)
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/)","")
KEYBOARD_PATHS += $(KEYBOARD_PATH_2)
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/)","")
KEYBOARD_PATHS += $(KEYBOARD_PATH_1)
endif
# Pull in rules.mk files from all our subfolders
-include $(KEYBOARD_PATH_5)/rules.mk
-include $(KEYBOARD_PATH_4)/rules.mk
-include $(KEYBOARD_PATH_3)/rules.mk
-include $(KEYBOARD_PATH_2)/rules.mk
-include $(KEYBOARD_PATH_1)/rules.mk
# Create dependencies on DD keyboard config - structure validated elsewhere
DD_CONFIG_FILES :=
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/info.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_1)/info.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/info.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_2)/info.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/info.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_3)/info.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/info.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_4)/info.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/info.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_5)/info.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/keyboard.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_1)/keyboard.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/keyboard.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_2)/keyboard.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/keyboard.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_3)/keyboard.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/keyboard.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_4)/keyboard.json
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/keyboard.json)","")
DD_CONFIG_FILES += $(KEYBOARD_PATH_5)/keyboard.json
endif
MAIN_KEYMAP_PATH_1 := $(KEYBOARD_PATH_1)/keymaps/$(KEYMAP)
MAIN_KEYMAP_PATH_2 := $(KEYBOARD_PATH_2)/keymaps/$(KEYMAP)
MAIN_KEYMAP_PATH_3 := $(KEYBOARD_PATH_3)/keymaps/$(KEYMAP)
MAIN_KEYMAP_PATH_4 := $(KEYBOARD_PATH_4)/keymaps/$(KEYMAP)
MAIN_KEYMAP_PATH_5 := $(KEYBOARD_PATH_5)/keymaps/$(KEYMAP)
# Pull in rules from DD keyboard config
INFO_RULES_MK = $(shell $(QMK_BIN) generate-rules-mk --quiet --escape --keyboard $(KEYBOARD) --output $(INTERMEDIATE_OUTPUT)/src/info_rules.mk)
include $(INFO_RULES_MK)
# Check for keymap.json first, so we can regenerate keymap.c
include $(BUILDDEFS_PATH)/build_json.mk
# Pull in keymap level rules.mk
ifeq ("$(wildcard $(KEYMAP_PATH))", "")
# Look through the possible keymap folders until we find a matching keymap.c
ifneq ($(QMK_USERSPACE),)
ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_1)/keymap.c)","")
-include $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_1)/rules.mk
KEYMAP_C := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_1)/keymap.c
KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_1)
else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_2)/keymap.c)","")
-include $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_2)/rules.mk
KEYMAP_C := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_2)/keymap.c
KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_2)
else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_3)/keymap.c)","")
-include $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_3)/rules.mk
KEYMAP_C := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_3)/keymap.c
KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_3)
else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_4)/keymap.c)","")
-include $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_4)/rules.mk
KEYMAP_C := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_4)/keymap.c
KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_4)
else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_5)/keymap.c)","")
-include $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_5)/rules.mk
KEYMAP_C := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_5)/keymap.c
KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_5)
endif
endif
ifeq ($(KEYMAP_PATH),)
ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_1)/keymap.c)","")
-include $(MAIN_KEYMAP_PATH_1)/rules.mk
KEYMAP_C := $(MAIN_KEYMAP_PATH_1)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_2)/keymap.c)","")
-include $(MAIN_KEYMAP_PATH_2)/rules.mk
KEYMAP_C := $(MAIN_KEYMAP_PATH_2)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_2)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_3)/keymap.c)","")
-include $(MAIN_KEYMAP_PATH_3)/rules.mk
KEYMAP_C := $(MAIN_KEYMAP_PATH_3)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_3)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_4)/keymap.c)","")
-include $(MAIN_KEYMAP_PATH_4)/rules.mk
KEYMAP_C := $(MAIN_KEYMAP_PATH_4)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_4)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_5)/keymap.c)","")
-include $(MAIN_KEYMAP_PATH_5)/rules.mk
KEYMAP_C := $(MAIN_KEYMAP_PATH_5)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_5)
else ifneq ($(LAYOUTS),)
# If we haven't found a keymap yet fall back to community layouts
include $(BUILDDEFS_PATH)/build_layout.mk
else ifeq ("$(wildcard $(KEYMAP_JSON_PATH))", "") # Not finding keymap.c is fine if we found a keymap.json
$(call CATASTROPHIC_ERROR,Invalid keymap,Could not find keymap)
# this state should never be reached
endif
endif
endif
# Have we found a keymap.json?
ifneq ("$(wildcard $(KEYMAP_JSON))", "")
ifneq ("$(wildcard $(KEYMAP_C))", "")
# Allow a separately-found keymap.c next to keymap.json -- the keymap.c
# generator will include the other keymap.c in the process, if supplied.
OTHER_KEYMAP_C := $(KEYMAP_C)
OPT_DEFS += -DOTHER_KEYMAP_C=\"$(OTHER_KEYMAP_C)\"
endif
KEYMAP_PATH := $(KEYMAP_JSON_PATH)
KEYMAP_C := $(INTERMEDIATE_OUTPUT)/src/keymap.c
KEYMAP_H := $(INTERMEDIATE_OUTPUT)/src/config.h
ifeq ($(OTHER_KEYMAP_C),)
# Load the keymap-level rules.mk if exists (and we havent already loaded it for keymap.c)
-include $(KEYMAP_PATH)/rules.mk
endif
# Load any rules.mk content from keymap.json
INFO_RULES_MK = $(shell $(QMK_BIN) generate-rules-mk --quiet --escape --output $(INTERMEDIATE_OUTPUT)/src/rules.mk $(KEYMAP_JSON))
include $(INFO_RULES_MK)
# Add rules to generate the keymap files - indentation here is important
$(INTERMEDIATE_OUTPUT)/src/keymap.c: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) json2c --quiet --output $(KEYMAP_C) $(KEYMAP_JSON))
@$(BUILD_CMD)
$(INTERMEDIATE_OUTPUT)/src/config.h: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-config-h --quiet --output $(KEYMAP_H) $(KEYMAP_JSON))
@$(BUILD_CMD)
$(INTERMEDIATE_OUTPUT)/src/keymap.h: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-keymap-h --quiet --output $(INTERMEDIATE_OUTPUT)/src/keymap.h $(KEYMAP_JSON))
@$(BUILD_CMD)
generated-files: $(INTERMEDIATE_OUTPUT)/src/config.h $(INTERMEDIATE_OUTPUT)/src/keymap.c $(INTERMEDIATE_OUTPUT)/src/keymap.h
endif
# Community modules
COMMUNITY_RULES_MK = $(shell $(QMK_BIN) generate-community-modules-rules-mk -kb $(KEYBOARD) --quiet --escape --output $(INTERMEDIATE_OUTPUT)/src/community_rules.mk $(KEYMAP_JSON))
include $(COMMUNITY_RULES_MK)
$(INTERMEDIATE_OUTPUT)/src/community_modules.h: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-community-modules-h -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules.h $(KEYMAP_JSON))
@$(BUILD_CMD)
$(INTERMEDIATE_OUTPUT)/src/community_modules.c: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-community-modules-c -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules.c $(KEYMAP_JSON))
@$(BUILD_CMD)
$(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.c: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-community-modules-introspection-c -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.c $(KEYMAP_JSON))
@$(BUILD_CMD)
$(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-community-modules-introspection-h -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h $(KEYMAP_JSON))
@$(BUILD_CMD)
$(INTERMEDIATE_OUTPUT)/src/led_matrix_community_modules.inc: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-led-matrix-community-modules-inc -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/led_matrix_community_modules.inc $(KEYMAP_JSON))
@$(BUILD_CMD)
$(INTERMEDIATE_OUTPUT)/src/rgb_matrix_community_modules.inc: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-rgb-matrix-community-modules-inc -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/rgb_matrix_community_modules.inc $(KEYMAP_JSON))
@$(BUILD_CMD)
SRC += $(INTERMEDIATE_OUTPUT)/src/community_modules.c
generated-files: $(INTERMEDIATE_OUTPUT)/src/community_modules.h $(INTERMEDIATE_OUTPUT)/src/community_modules.c $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.c $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h $(INTERMEDIATE_OUTPUT)/src/led_matrix_community_modules.inc $(INTERMEDIATE_OUTPUT)/src/rgb_matrix_community_modules.inc
include $(BUILDDEFS_PATH)/converters.mk
# Generate the board's version.h file.
$(shell $(QMK_BIN) generate-version-h $(VERSION_H_FLAGS) -q -o $(INTERMEDIATE_OUTPUT)/src/version.h)
MCU_ORIG := $(MCU)
include $(wildcard $(PLATFORM_PATH)/*/mcu_selection.mk)
# PLATFORM_KEY should be detected in DD keyboard config via key 'processor' (or rules.mk 'MCU')
ifeq ($(PLATFORM_KEY),)
$(call CATASTROPHIC_ERROR,Platform not defined)
endif
PLATFORM=$(shell echo $(PLATFORM_KEY) | tr '[:lower:]' '[:upper:]')
# Find all the C source files to be compiled in subfolders.
KEYBOARD_SRC :=
KEYBOARD_C_1 := $(KEYBOARD_PATH_1)/$(KEYBOARD_FOLDER_1).c
KEYBOARD_C_2 := $(KEYBOARD_PATH_2)/$(KEYBOARD_FOLDER_2).c
KEYBOARD_C_3 := $(KEYBOARD_PATH_3)/$(KEYBOARD_FOLDER_3).c
KEYBOARD_C_4 := $(KEYBOARD_PATH_4)/$(KEYBOARD_FOLDER_4).c
KEYBOARD_C_5 := $(KEYBOARD_PATH_5)/$(KEYBOARD_FOLDER_5).c
ifneq ("$(wildcard $(KEYBOARD_C_5))","")
KEYBOARD_SRC += $(KEYBOARD_C_5)
endif
ifneq ("$(wildcard $(KEYBOARD_C_4))","")
KEYBOARD_SRC += $(KEYBOARD_C_4)
endif
ifneq ("$(wildcard $(KEYBOARD_C_3))","")
KEYBOARD_SRC += $(KEYBOARD_C_3)
endif
ifneq ("$(wildcard $(KEYBOARD_C_2))","")
KEYBOARD_SRC += $(KEYBOARD_C_2)
endif
ifneq ("$(wildcard $(KEYBOARD_C_1))","")
KEYBOARD_SRC += $(KEYBOARD_C_1)
endif
# Generate KEYBOARD_name_subname for all levels of the keyboard folder
KEYBOARD_FILESAFE_1 := $(subst .,,$(subst /,_,$(KEYBOARD_FOLDER_PATH_1)))
KEYBOARD_FILESAFE_2 := $(subst .,,$(subst /,_,$(KEYBOARD_FOLDER_PATH_2)))
KEYBOARD_FILESAFE_3 := $(subst .,,$(subst /,_,$(KEYBOARD_FOLDER_PATH_3)))
KEYBOARD_FILESAFE_4 := $(subst .,,$(subst /,_,$(KEYBOARD_FOLDER_PATH_4)))
KEYBOARD_FILESAFE_5 := $(subst .,,$(subst /,_,$(KEYBOARD_FOLDER_PATH_5)))
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/)","")
OPT_DEFS += -DKEYBOARD_$(KEYBOARD_FILESAFE_5)
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/)","")
OPT_DEFS += -DKEYBOARD_$(KEYBOARD_FILESAFE_4)
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/)","")
OPT_DEFS += -DKEYBOARD_$(KEYBOARD_FILESAFE_3)
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/)","")
OPT_DEFS += -DKEYBOARD_$(KEYBOARD_FILESAFE_2)
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/)","")
OPT_DEFS += -DKEYBOARD_$(KEYBOARD_FILESAFE_1)
endif
# Setup the define for QMK_KEYBOARD_H. This is used inside of keymaps so
# that the same keymap may be used on multiple keyboards.
#
# We grab the most top-level include file that we can. That file should
# use #ifdef statements to include all the necessary subfolder includes,
# as described here:
#
# https://docs.qmk.fm/#/feature_layouts?id=tips-for-making-layouts-keyboard-agnostic
#
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/$(KEYBOARD_FOLDER_1).h)","")
FOUND_KEYBOARD_H = $(KEYBOARD_FOLDER_1).h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/$(KEYBOARD_FOLDER_2).h)","")
FOUND_KEYBOARD_H = $(KEYBOARD_FOLDER_2).h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/$(KEYBOARD_FOLDER_3).h)","")
FOUND_KEYBOARD_H = $(KEYBOARD_FOLDER_3).h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/$(KEYBOARD_FOLDER_4).h)","")
FOUND_KEYBOARD_H = $(KEYBOARD_FOLDER_4).h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/$(KEYBOARD_FOLDER_5).h)","")
FOUND_KEYBOARD_H = $(KEYBOARD_FOLDER_5).h
endif
# Find all of the config.h files and add them to our CONFIG_H define.
CONFIG_H :=
define config_h_community_module_appender
ifneq ("$(wildcard $(1)/config.h)","")
CONFIG_H += $(1)/config.h
endif
endef
$(foreach module,$(COMMUNITY_MODULE_PATHS),$(eval $(call config_h_community_module_appender,$(module))))
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/config.h)","")
CONFIG_H += $(KEYBOARD_PATH_5)/config.h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/config.h)","")
CONFIG_H += $(KEYBOARD_PATH_4)/config.h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/config.h)","")
CONFIG_H += $(KEYBOARD_PATH_3)/config.h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/config.h)","")
CONFIG_H += $(KEYBOARD_PATH_2)/config.h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/config.h)","")
CONFIG_H += $(KEYBOARD_PATH_1)/config.h
endif
POST_CONFIG_H :=
define post_config_h_community_module_appender
ifneq ("$(wildcard $(1)/post_config.h)","")
POST_CONFIG_H += $(1)/post_config.h
endif
endef
$(foreach module,$(COMMUNITY_MODULE_PATHS),$(eval $(call post_config_h_community_module_appender,$(module))))
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/post_config.h)","")
POST_CONFIG_H += $(KEYBOARD_PATH_1)/post_config.h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/post_config.h)","")
POST_CONFIG_H += $(KEYBOARD_PATH_2)/post_config.h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/post_config.h)","")
POST_CONFIG_H += $(KEYBOARD_PATH_3)/post_config.h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/post_config.h)","")
POST_CONFIG_H += $(KEYBOARD_PATH_4)/post_config.h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/post_config.h)","")
POST_CONFIG_H += $(KEYBOARD_PATH_5)/post_config.h
endif
CONFIG_H += $(INTERMEDIATE_OUTPUT)/src/info_config.h
KEYBOARD_SRC += $(INTERMEDIATE_OUTPUT)/src/default_keyboard.c
$(INTERMEDIATE_OUTPUT)/src/info_config.h: $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-config-h --quiet --keyboard $(KEYBOARD) --output $(INTERMEDIATE_OUTPUT)/src/info_config.h)
@$(BUILD_CMD)
$(INTERMEDIATE_OUTPUT)/src/default_keyboard.c: $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-keyboard-c --quiet --keyboard $(KEYBOARD) --output $(INTERMEDIATE_OUTPUT)/src/default_keyboard.c)
@$(BUILD_CMD)
$(INTERMEDIATE_OUTPUT)/src/default_keyboard.h: $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-keyboard-h --quiet --keyboard $(KEYBOARD) --include $(FOUND_KEYBOARD_H) --output $(INTERMEDIATE_OUTPUT)/src/default_keyboard.h)
@$(BUILD_CMD)
generated-files: $(INTERMEDIATE_OUTPUT)/src/info_config.h $(INTERMEDIATE_OUTPUT)/src/default_keyboard.c $(INTERMEDIATE_OUTPUT)/src/default_keyboard.h
generated-files: $(INTERMEDIATE_OUTPUT)/src/info_deps.d
$(INTERMEDIATE_OUTPUT)/src/info_deps.d:
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-make-dependencies -kb $(KEYBOARD) -km $(KEYMAP) -o $(INTERMEDIATE_OUTPUT)/src/info_deps.d)
@$(BUILD_CMD)
-include $(INTERMEDIATE_OUTPUT)/src/info_deps.d
.INTERMEDIATE : generated-files
# Userspace setup and definitions
ifeq ("$(USER_NAME)","")
USER_NAME := $(KEYMAP)
endif
USER_PATH := users/$(USER_NAME)
# If we have userspace, then add it to the lookup VPATH
ifneq ($(wildcard $(QMK_USERSPACE)),)
VPATH += $(QMK_USERSPACE)
endif
# If the equivalent users directory exists in userspace, use that in preference to anything currently in the main repo
ifneq ($(wildcard $(QMK_USERSPACE)/$(USER_PATH)),)
USER_PATH := $(QMK_USERSPACE)/$(USER_PATH)
endif
# Pull in user level rules.mk
-include $(USER_PATH)/rules.mk
ifneq ("$(wildcard $(USER_PATH)/config.h)","")
CONFIG_H += $(USER_PATH)/config.h
endif
ifneq ("$(wildcard $(USER_PATH)/post_config.h)","")
POST_CONFIG_H += $(USER_PATH)/post_config.h
endif
# Disable features that a keyboard doesn't support
-include $(BUILDDEFS_PATH)/disable_features.mk
ifneq ("$(CONVERTER)","")
-include $(CONVERTER)/post_converter.mk
endif
# Pull in post_rules.mk files from all our subfolders
-include $(KEYBOARD_PATH_1)/post_rules.mk
-include $(KEYBOARD_PATH_2)/post_rules.mk
-include $(KEYBOARD_PATH_3)/post_rules.mk
-include $(KEYBOARD_PATH_4)/post_rules.mk
-include $(KEYBOARD_PATH_5)/post_rules.mk
define post_rules_mk_community_module_includer
ifneq ("$(wildcard $(1)/post_rules.mk)","")
include $(1)/post_rules.mk
endif
endef
$(foreach module,$(COMMUNITY_MODULE_PATHS),$(eval $(call post_rules_mk_community_module_includer,$(module))))
ifneq ("$(wildcard $(KEYMAP_PATH)/config.h)","")
CONFIG_H += $(KEYMAP_PATH)/config.h
endif
ifneq ("$(KEYMAP_H)","")
CONFIG_H += $(KEYMAP_H)
endif
ifeq ($(KEYMAP_C),)
$(call CATASTROPHIC_ERROR,Invalid keymap,Could not find keymap)
endif
OPT_DEFS += -DKEYMAP_C=\"$(KEYMAP_C)\"
# If a keymap or userspace places their keymap array in another file instead, allow for it to be included
# !!NOTE!! -- For this to work, the source file cannot be part of $(SRC), so users should not add it via `SRC += <file>`
ifneq ($(strip $(INTROSPECTION_KEYMAP_C)),)
OPT_DEFS += -DINTROSPECTION_KEYMAP_C=\"$(strip $(INTROSPECTION_KEYMAP_C))\"
endif
# project specific files
SRC += \
$(KEYBOARD_SRC) \
$(QUANTUM_DIR)/keymap_introspection.c \
$(QUANTUM_SRC) \
$(QUANTUM_DIR)/main.c \
# Optimize size but this may cause error "relocation truncated to fit"
#EXTRALDFLAGS = -Wl,--relax
# Search Path
VPATH += $(KEYMAP_PATH)
VPATH += $(USER_PATH)
VPATH += $(KEYBOARD_PATHS)
VPATH += $(COMMON_VPATH)
VPATH += $(INTERMEDIATE_OUTPUT)/src
include $(BUILDDEFS_PATH)/common_features.mk
include $(BUILDDEFS_PATH)/generic_features.mk
include $(TMK_PATH)/protocol.mk
include $(PLATFORM_PATH)/common.mk
SRC += $(patsubst %.c,%.clib,$(LIB_SRC))
SRC += $(patsubst %.c,%.clib,$(QUANTUM_LIB_SRC))
-include $(PLATFORM_PATH)/$(PLATFORM_KEY)/bootloader.mk
include $(PLATFORM_PATH)/$(PLATFORM_KEY)/platform.mk
-include $(PLATFORM_PATH)/$(PLATFORM_KEY)/flash.mk
ifneq ($(strip $(PROTOCOL)),)
PROTOCOL_KEY = $(strip $(shell echo $(PROTOCOL) | tr '[:upper:]' '[:lower:]'))
else
PROTOCOL_KEY = $(PLATFORM_KEY)
endif
include $(TMK_PATH)/protocol/$(PROTOCOL_KEY)/$(PROTOCOL_KEY).mk
# Setup definitions based on the selected MCU
$(eval $(call add_qmk_prefix_defs,MCU_ORIG,MCU))
$(eval $(call add_qmk_prefix_defs,MCU_ARCH,MCU_ARCH))
$(eval $(call add_qmk_prefix_defs,MCU_PORT_NAME,MCU_PORT_NAME))
$(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))
$(eval $(call add_qmk_prefix_defs,OPT,OPT))
# 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
OUTPUTS := $(INTERMEDIATE_OUTPUT)
$(INTERMEDIATE_OUTPUT)_SRC := $(SRC) $(PLATFORM_SRC)
$(INTERMEDIATE_OUTPUT)_DEFS := \
-DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYBOARD_H=\"$(INTERMEDIATE_OUTPUT)/src/default_keyboard.h\" \
-DQMK_KEYMAP=\"$(KEYMAP)\" -DQMK_KEYMAP_H=\"$(KEYMAP).h\" -DQMK_KEYMAP_CONFIG_H=\"$(KEYMAP_PATH)/config.h\" \
$(OPT_DEFS)
$(INTERMEDIATE_OUTPUT)_INC := $(VPATH) $(EXTRAINCDIRS) $(KEYBOARD_PATHS)
$(INTERMEDIATE_OUTPUT)_CONFIG := $(CONFIG_H) $(POST_CONFIG_H)
# Default target.
all: build check-size
build: elf cpfirmware
check-size: build
check-md5: build
objs-size: build
ifneq ($(strip $(TOP_SYMBOLS)),)
ifeq ($(strip $(TOP_SYMBOLS)),yes)
NUM_TOP_SYMBOLS := 10
else
NUM_TOP_SYMBOLS := $(strip $(TOP_SYMBOLS))
endif
all: top-symbols
check-size: top-symbols
top-symbols: build
echo "###########################################"
echo "# Highest flash usage:"
$(NM) -Crtd --size-sort $(BUILD_DIR)/$(TARGET).elf | grep ' [RrTt] ' | head -n$(NUM_TOP_SYMBOLS) | sed -e 's#^0000000# #g' -e 's#^000000# #g' -e 's#^00000# #g' -e 's#^0000# #g' -e 's#^000# #g' -e 's#^00# #g' -e 's#^0# #g'
echo "###########################################"
echo "# Highest RAM usage:"
$(NM) -Crtd --size-sort $(BUILD_DIR)/$(TARGET).elf | grep ' [BbCDdGgSs] ' | head -n$(NUM_TOP_SYMBOLS) | sed -e 's#^0000000# #g' -e 's#^000000# #g' -e 's#^00000# #g' -e 's#^0000# #g' -e 's#^000# #g' -e 's#^00# #g' -e 's#^0# #g'
echo "###########################################"
endif
include $(BUILDDEFS_PATH)/show_options.mk
include $(BUILDDEFS_PATH)/common_rules.mk
# Ensure we have generated files available for each of the objects
define GEN_FILES
$1: generated-files
endef
$(foreach O,$(OBJ),$(eval $(call GEN_FILES,$(patsubst %.a,%.o,$(O)))))

View file

@ -1,36 +0,0 @@
LAYOUTS_PATH := layouts
LAYOUTS_REPOS := $(patsubst %/,%,$(sort $(dir $(wildcard $(LAYOUTS_PATH)/*/))))
ifneq ($(QMK_USERSPACE),)
LAYOUTS_REPOS += $(patsubst %/,%,$(QMK_USERSPACE)/$(LAYOUTS_PATH))
endif
define SEARCH_LAYOUTS_REPO
LAYOUT_KEYMAP_PATH := $$(LAYOUTS_REPO)/$$(LAYOUT)/$$(KEYMAP)
LAYOUT_KEYMAP_JSON := $$(LAYOUT_KEYMAP_PATH)/keymap.json
LAYOUT_KEYMAP_C := $$(LAYOUT_KEYMAP_PATH)/keymap.c
ifneq ("$$(wildcard $$(LAYOUT_KEYMAP_JSON))","")
-include $$(LAYOUT_KEYMAP_PATH)/rules.mk
KEYMAP_JSON := $$(LAYOUT_KEYMAP_JSON)
KEYMAP_PATH := $$(LAYOUT_KEYMAP_PATH)
else ifneq ("$$(wildcard $$(LAYOUT_KEYMAP_C))","")
-include $$(LAYOUT_KEYMAP_PATH)/rules.mk
KEYMAP_C := $$(LAYOUT_KEYMAP_C)
KEYMAP_PATH := $$(LAYOUT_KEYMAP_PATH)
endif
endef
define SEARCH_LAYOUTS
$$(foreach LAYOUTS_REPO,$$(LAYOUTS_REPOS),$$(eval $$(call SEARCH_LAYOUTS_REPO)))
endef
ifneq ($(FORCE_LAYOUT),)
ifneq (,$(findstring $(FORCE_LAYOUT),$(LAYOUTS)))
$(info Forcing layout: $(FORCE_LAYOUT))
LAYOUTS := $(FORCE_LAYOUT)
else
$(call CATASTROPHIC_ERROR,Invalid layout,Forced layout does not exist)
endif
endif
$(foreach LAYOUT,$(LAYOUTS),$(eval $(call SEARCH_LAYOUTS)))

View file

@ -1,94 +0,0 @@
ifndef VERBOSE
.SILENT:
endif
.DEFAULT_GOAL := all
OPT = g
include paths.mk
include $(BUILDDEFS_PATH)/support.mk
include $(BUILDDEFS_PATH)/message.mk
TARGET=test/$(TEST_OUTPUT)
GTEST_OUTPUT = $(BUILD_DIR)/gtest
TEST_OBJ = $(BUILD_DIR)/test_obj
OUTPUTS := $(TEST_OBJ)/$(TEST_OUTPUT) $(GTEST_OUTPUT)
GTEST_INC := \
$(LIB_PATH)/googletest/googletest/include \
$(LIB_PATH)/googletest/googlemock/include
GTEST_INTERNAL_INC := \
$(LIB_PATH)/googletest/googletest \
$(LIB_PATH)/googletest/googlemock
$(GTEST_OUTPUT)_SRC := \
googletest/src/gtest-all.cc\
googlemock/src/gmock-all.cc
$(GTEST_OUTPUT)_DEFS :=
$(GTEST_OUTPUT)_INC := $(GTEST_INC) $(GTEST_INTERNAL_INC)
LDFLAGS += -lstdc++ -lpthread -shared-libgcc
CREATE_MAP := no
VPATH += \
$(LIB_PATH)/googletest \
$(LIB_PATH)/googlemock \
$(COMMON_VPATH) \
$(TEST_PATH)
all: elf
PLATFORM:=TEST
PLATFORM_KEY:=test
BOOTLOADER_TYPE:=none
DEBUG ?= 0
ifneq ($(strip $(DEBUG)), 0)
CONSOLE_ENABLE = yes
endif
ifneq ($(filter $(FULL_TESTS),$(TEST)),)
include tests/test_common/build.mk
include $(TEST_PATH)/test.mk
endif
include $(BUILDDEFS_PATH)/common_features.mk
include $(BUILDDEFS_PATH)/generic_features.mk
include $(PLATFORM_PATH)/common.mk
include $(TMK_PATH)/protocol.mk
include $(QUANTUM_PATH)/debounce/tests/rules.mk
include $(QUANTUM_PATH)/encoder/tests/rules.mk
include $(QUANTUM_PATH)/os_detection/tests/rules.mk
include $(QUANTUM_PATH)/sequencer/tests/rules.mk
include $(QUANTUM_PATH)/wear_leveling/tests/rules.mk
include $(QUANTUM_PATH)/logging/print.mk
include $(PLATFORM_PATH)/test/rules.mk
ifneq ($(filter $(FULL_TESTS),$(TEST)),)
include $(BUILDDEFS_PATH)/build_full_test.mk
endif
$(TEST_OUTPUT)_SRC += \
tests/test_common/main.cpp \
$(QUANTUM_PATH)/logging/print.c
ifneq ($(strip $(INTROSPECTION_KEYMAP_C)),)
$(TEST_OUTPUT)_DEFS += -DINTROSPECTION_KEYMAP_C=\"$(strip $(INTROSPECTION_KEYMAP_C))\"
endif
$(TEST_OBJ)/$(TEST_OUTPUT)_SRC := $($(TEST_OUTPUT)_SRC)
$(TEST_OBJ)/$(TEST_OUTPUT)_INC := $($(TEST_OUTPUT)_INC) $(VPATH) $(GTEST_INC)
$(TEST_OBJ)/$(TEST_OUTPUT)_DEFS := $($(TEST_OUTPUT)_DEFS)
$(TEST_OBJ)/$(TEST_OUTPUT)_CONFIG := $($(TEST_OUTPUT)_CONFIG)
include $(PLATFORM_PATH)/$(PLATFORM_KEY)/platform.mk
include $(BUILDDEFS_PATH)/common_rules.mk
$(shell mkdir -p $(BUILD_DIR)/test 2>/dev/null)
$(shell mkdir -p $(TEST_OBJ) 2>/dev/null)

File diff suppressed because it is too large Load diff

View file

@ -1,408 +0,0 @@
# Hey Emacs, this is a -*- makefile -*-
#----------------------------------------------------------------------------
# Enable vpath searching for source files only
# Without this, output files, could be read from the wrong .build directories
VPATH_SRC := $(VPATH)
vpath %.c $(VPATH_SRC)
vpath %.h $(VPATH_SRC)
vpath %.cpp $(VPATH_SRC)
vpath %.cc $(VPATH_SRC)
vpath %.hpp $(VPATH_SRC)
vpath %.S $(VPATH_SRC)
VPATH :=
# Helper to return the distinct elements of a list
uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
# Convert all SRC to OBJ
define OBJ_FROM_SRC
$(patsubst %.c,$1/%.o,$(patsubst %.cpp,$1/%.o,$(patsubst %.cc,$1/%.o,$(patsubst %.S,$1/%.o,$(patsubst %.clib,$1/%.a,$($1_SRC))))))
endef
$(foreach OUTPUT,$(OUTPUTS),$(eval $(OUTPUT)_OBJ +=$(call OBJ_FROM_SRC,$(OUTPUT))))
# Define a list of all objects
OBJ := $(foreach OUTPUT,$(OUTPUTS),$($(OUTPUT)_OBJ))
NO_LTO_OBJ := $(filter %.a,$(OBJ))
MASTER_OUTPUT := $(firstword $(OUTPUTS))
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
# Optimization level, can be [0, 1, 2, 3, s].
OPT ?= s
# Compiler flag to set the C and C++ language standard level
CSTANDARD = -std=gnu11
CXXSTANDARD = -std=gnu++14
# Speed up recompilations by opt-in usage of ccache
USE_CCACHE ?= no
ifneq ($(USE_CCACHE),no)
CC_PREFIX ?= ccache
endif
#---------------- Debug Options ----------------
DEBUG_ENABLE ?= no
ifeq ($(strip $(DEBUG_ENABLE)),yes)
CFLAGS += -ggdb3
CXXFLAGS += -ggdb3
ASFLAGS += -ggdb3
# Create a map file when debugging
LDFLAGS += -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref
endif
#---------------- C Compiler Options ----------------
ifeq ($(strip $(LTO_ENABLE)), yes)
CDEFS += -flto
CDEFS += -DLTO_ENABLE
endif
CFLAGS += $(CDEFS)
CFLAGS += -O$(OPT)
# add color
ifeq ($(COLOR),true)
ifeq ("$(shell echo "int main(){}" | $(CC) -fdiagnostics-color -x c - -o /dev/null 2>&1)", "")
CFLAGS+= -fdiagnostics-color
endif
endif
CFLAGS += -Wall
CFLAGS += -Wstrict-prototypes
ifneq ($(strip $(ALLOW_WARNINGS)), yes)
CFLAGS += -Werror
endif
CFLAGS += $(CSTANDARD)
# This fixes lots of keyboards linking errors but SHOULDN'T BE A FINAL SOLUTION
# Fixing of multiple variable definitions must be made.
CFLAGS += -fcommon
#---------------- C++ Compiler Options ----------------
CXXFLAGS += $(CXXDEFS)
CXXFLAGS += -O$(OPT)
# to suppress "warning: only initialized variables can be placed into program memory area"
CXXFLAGS += -w
CXXFLAGS += -Wall
CXXFLAGS += -Wundef
ifneq ($(strip $(ALLOW_WARNINGS)), yes)
CXXFLAGS += -Werror
endif
#---------------- Assembler Options ----------------
ASFLAGS += $(ADEFS)
ifeq ($(VERBOSE_AS_CMD),yes)
ASFLAGS += -v
endif
#---------------- Linker Options ----------------
ifeq ($(VERBOSE_LD_CMD),yes)
LDFLAGS += -v
endif
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
LDFLAGS += -lm
# You can give EXTRALDFLAGS at 'make' command line.
LDFLAGS += $(EXTRALDFLAGS)
#---------------- Assembler Listings ----------------
ADHLNS_ENABLE ?= no
ifeq ($(ADHLNS_ENABLE),yes)
# Avoid "Options to '-Xassembler' do not match" - only specify assembler options at LTO link time
ifeq ($(strip $(LTO_ENABLE)), yes)
LDFLAGS += -Wa,-adhlns=$(BUILD_DIR)/$(TARGET).lst
else
CFLAGS += -Wa,-adhlns=$(@:%.o=%.lst)
CXXFLAGS += -Wa,-adhlns=$(@:%.o=%.lst)
ASFLAGS += -Wa,-adhlns=$(@:%.o=%.lst),--listing-cont-lines=100
endif
endif
# Define programs and commands.
SHELL = sh
SED = sed
REMOVE = rm -f
REMOVEDIR = rmdir
COPY = cp
WINSHELL = cmd
SECHO = $(SILENT) || echo
MD5SUM ?= md5sum
ifneq ($(filter Darwin FreeBSD,$(shell uname -s)),)
MD5SUM = md5
endif
# UF2 format settings
# 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.
#GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
GENDEPFLAGS = -MMD -MP -MF $(patsubst %.o,%.td,$@)
# Combine all necessary flags and optional flags.
# Add target processor to flags.
# You can give extra flags at 'make' command line like: make EXTRAFLAGS=-DFOO=bar
ALL_CFLAGS = $(MCUFLAGS) $(CFLAGS) $(EXTRAFLAGS)
ALL_CXXFLAGS = $(MCUFLAGS) -x c++ $(CXXFLAGS) $(EXTRAFLAGS)
ALL_ASFLAGS = $(MCUFLAGS) -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS)
define NO_LTO
$(patsubst %.a,%.o,$1): NOLTO_CFLAGS += -fno-lto
endef
$(foreach LOBJ, $(NO_LTO_OBJ), $(eval $(call NO_LTO,$(LOBJ))))
MOVE_DEP = mv -f $(patsubst %.o,%.td,$@) $(patsubst %.o,%.d,$@)
# For a ChibiOS build, ensure that the board files have the hook overrides injected
define BOARDSRC_INJECT_HOOKS
$(INTERMEDIATE_OUTPUT)/$(patsubst %.c,%.o,$(patsubst ./%,%,$1)): FILE_SPECIFIC_CFLAGS += -include $(TOP_DIR)/tmk_core/protocol/chibios/init_hooks.h
endef
$(foreach LOBJ, $(BOARDSRC), $(eval $(call BOARDSRC_INJECT_HOOKS,$(LOBJ))))
# Add QMK specific flags
DFU_SUFFIX ?= dfu-suffix
DFU_SUFFIX_ARGS ?=
elf: $(BUILD_DIR)/$(TARGET).elf
hex: $(BUILD_DIR)/$(TARGET).hex
uf2: $(BUILD_DIR)/$(TARGET).uf2
cpfirmware_qmk: $(FIRMWARE_FORMAT)
$(SILENT) || printf "Copying $(TARGET).$(FIRMWARE_FORMAT) to qmk_firmware folder" | $(AWK_CMD)
$(COPY) $(BUILD_DIR)/$(TARGET).$(FIRMWARE_FORMAT) $(TARGET).$(FIRMWARE_FORMAT) && $(PRINT_OK)
eep: $(BUILD_DIR)/$(TARGET).eep
lss: $(BUILD_DIR)/$(TARGET).lss
sym: $(BUILD_DIR)/$(TARGET).sym
LIBNAME=lib$(TARGET).a
lib: $(LIBNAME)
cpfirmware: cpfirmware_qmk
ifneq ($(QMK_USERSPACE),)
cpfirmware: cpfirmware_userspace
cpfirmware_userspace: cpfirmware_qmk
$(SILENT) || printf "Copying $(TARGET).$(FIRMWARE_FORMAT) to userspace folder" | $(AWK_CMD)
$(COPY) $(BUILD_DIR)/$(TARGET).$(FIRMWARE_FORMAT) $(QMK_USERSPACE)/$(TARGET).$(FIRMWARE_FORMAT) && $(PRINT_OK)
endif
# Display size of file, modifying the output so people don't mistakenly grab the hex output
BINARY_SIZE = $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex | $(SED) -e 's/\.build\/.*$$/$(TARGET).$(FIRMWARE_FORMAT)/g'
sizebefore:
@if test -f $(BUILD_DIR)/$(TARGET).hex; then $(SECHO) $(MSG_SIZE_BEFORE); $(SILENT) || $(BINARY_SIZE); \
2>/dev/null; $(SECHO); fi
sizeafter: $(BUILD_DIR)/$(TARGET).hex
@if test -f $(BUILD_DIR)/$(TARGET).hex; then $(SECHO); $(SECHO) $(MSG_SIZE_AFTER); $(SILENT) || $(BINARY_SIZE); \
2>/dev/null; $(SECHO); fi
# Display compiler version information.
gccversion :
@$(SILENT) || $(CC) --version
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
$(eval CMD=$(HEX) $< $@)
#@$(SILENT) || printf "$(MSG_EXECUTING) '$(CMD)':\n"
@$(SILENT) || printf "$(MSG_FLASH) $@" | $(AWK_CMD)
@$(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)
#@$(SILENT) || printf "$(MSG_EXECUTING) '$(CMD)':\n"
@$(SILENT) || printf "$(MSG_UF2) $@" | $(AWK_CMD)
@$(BUILD_CMD)
%.eep: %.elf
$(eval CMD=$(EEP) $< $@ || exit 0)
#@$(SILENT) || printf "$(MSG_EXECUTING) '$(CMD)':\n"
@$(SILENT) || printf "$(MSG_EEPROM) $@" | $(AWK_CMD)
@$(BUILD_CMD)
# Create extended listing file from ELF output file.
%.lss: %.elf
$(eval CMD=$(OBJDUMP) -h -S -z $< > $@)
#@$(SILENT) || printf "$(MSG_EXECUTING) '$(CMD)':\n"
@$(SILENT) || printf "$(MSG_EXTENDED_LISTING) $@" | $(AWK_CMD)
@$(BUILD_CMD)
# Create a symbol table from ELF output file.
%.sym: %.elf
$(eval CMD=$(NM) -n $< > $@ )
#@$(SILENT) || printf "$(MSG_EXECUTING) '$(CMD)':\n"
@$(SILENT) || printf "$(MSG_SYMBOL_TABLE) $@" | $(AWK_CMD)
@$(BUILD_CMD)
%.bin: %.elf
$(eval CMD=$(BIN) $< $@ || exit 0)
#@$(SILENT) || printf "$(MSG_EXECUTING) '$(CMD)':\n"
@$(SILENT) || printf "$(MSG_BIN) $@" | $(AWK_CMD)
@$(BUILD_CMD)
if [ ! -z "$(DFU_SUFFIX_ARGS)" ]; then \
$(DFU_SUFFIX) $(DFU_SUFFIX_ARGS) -a $(BUILD_DIR)/$(TARGET).bin 1>/dev/null ;\
fi
#$(SILENT) || printf "$(MSG_EXECUTING) '$(DFU_SUFFIX) $(DFU_SUFFIX_ARGS) -a $(BUILD_DIR)/$(TARGET).bin 1>/dev/null':\n" ;\
$(COPY) $(BUILD_DIR)/$(TARGET).bin $(TARGET).bin;
BEGIN = gccversion sizebefore
# Link: create ELF output file from object files.
.SECONDARY : $(BUILD_DIR)/$(TARGET).elf
.PRECIOUS : $(OBJ)
# Note the obj.txt depeendency is there to force linking if a source file is deleted
%.elf: $(OBJ) $(MASTER_OUTPUT)/cflags.txt $(MASTER_OUTPUT)/ldflags.txt $(MASTER_OUTPUT)/obj.txt | $(BEGIN)
@$(SILENT) || printf "$(MSG_LINKING) $@" | $(AWK_CMD)
$(eval CMD=MAKE=$(MAKE) $(CC) $(ALL_CFLAGS) $(call uniq,$(OBJ)) --output $@ $(LDFLAGS))
@$(BUILD_CMD)
define GEN_OBJRULE
$1_INCFLAGS := $$(patsubst %,-I%,$$($1_INC))
ifdef $1_CONFIG
$1_CONFIG_FLAGS += $$(patsubst %,-include %,$$($1_CONFIG))
endif
$1_CFLAGS = $$(ALL_CFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS) $$(NOLTO_CFLAGS)
$1_CXXFLAGS = $$(ALL_CXXFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS) $$(NOLTO_CFLAGS)
$1_ASFLAGS = $$(ALL_ASFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS)
# Compile: create object files from C source files.
$1/%.o : %.c $1/%.d $1/cflags.txt $1/compiler.txt | $(BEGIN)
@mkdir -p $$(@D)
@$$(SILENT) || printf "$$(MSG_COMPILING) $$<" | $$(AWK_CMD)
$$(eval CC_EXEC := $$(CC))
ifneq ($$(VERBOSE_C_CMD),)
$$(if $$(filter $$(notdir $$(VERBOSE_C_CMD)),$$(notdir $$<)),$$(eval CC_EXEC += -v))
endif
ifneq ($$(VERBOSE_C_INCLUDE),)
$$(if $$(filter $$(notdir $$(VERBOSE_C_INCLUDE)),$$(notdir $$<)),$$(eval CC_EXEC += -H))
endif
$$(eval CMD := $$(CC_EXEC) -c $$($1_CFLAGS) $$(FILE_SPECIFIC_CFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP))
@$$(BUILD_CMD)
ifneq ($$(DUMP_C_MACROS),)
$$(eval CMD := $$(CC) -E -dM $$($1_CFLAGS) $$(FILE_SPECIFIC_CFLAGS) $$(GENDEPFLAGS) $$<)
@$$(if $$(filter $$(notdir $$(DUMP_C_MACROS)),$$(notdir $$<)),$$(BUILD_CMD))
endif
# Compile: create object files from C++ source files.
$1/%.o : %.cpp $1/%.d $1/cxxflags.txt $1/compiler.txt | $(BEGIN)
@mkdir -p $$(@D)
@$$(SILENT) || printf "$$(MSG_COMPILING_CXX) $$<" | $$(AWK_CMD)
$$(eval CMD=$$(CC) -c $$($1_CXXFLAGS) $$(FILE_SPECIFIC_CFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP))
@$$(BUILD_CMD)
$1/%.o : %.cc $1/%.d $1/cxxflags.txt $1/compiler.txt | $(BEGIN)
@mkdir -p $$(@D)
@$$(SILENT) || printf "$$(MSG_COMPILING_CXX) $$<" | $$(AWK_CMD)
$$(eval CMD=$$(CC) -c $$($1_CXXFLAGS) $$(FILE_SPECIFIC_CFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP))
@$$(BUILD_CMD)
# Assemble: create object files from assembler source files.
$1/%.o : %.S $1/asflags.txt $1/compiler.txt | $(BEGIN)
@mkdir -p $$(@D)
@$(SILENT) || printf "$$(MSG_ASSEMBLING) $$<" | $$(AWK_CMD)
$$(eval CMD=$$(CC) -c $$($1_ASFLAGS) $$< -o $$@)
@$$(BUILD_CMD)
$1/%.a : $1/%.o
@mkdir -p $$(@D)
@$(SILENT) || printf "Archiving: $$<" | $$(AWK_CMD)
$$(eval CMD=$$(AR) rcs $$@ $$<)
@$$(BUILD_CMD)
$1/force:
$1/cflags.txt: $1/force
echo '$$($1_CFLAGS)' | cmp -s - $$@ || echo '$$($1_CFLAGS)' > $$@
$1/cxxflags.txt: $1/force
echo '$$($1_CXXFLAGS)' | cmp -s - $$@ || echo '$$($1_CXXFLAGS)' > $$@
$1/asflags.txt: $1/force
echo '$$($1_ASFLAGS)' | cmp -s - $$@ || echo '$$($1_ASFLAGS)' > $$@
$1/compiler.txt: $1/force
test -f $$@ || touch $$@
$$(CC) --version | cmp -s - $$@ || $$(CC) --version > $$@
endef
.PRECIOUS: $(MASTER_OUTPUT)/obj.txt
$(MASTER_OUTPUT)/obj.txt: $(MASTER_OUTPUT)/force
echo '$(OBJ)' | cmp -s - $@ || echo '$(OBJ)' > $@
.PRECIOUS: $(MASTER_OUTPUT)/ldflags.txt
$(MASTER_OUTPUT)/ldflags.txt: $(MASTER_OUTPUT)/force
echo '$(LDFLAGS)' | cmp -s - $@ || echo '$(LDFLAGS)' > $@
# We have to use static rules for the .d files for some reason
DEPS = $(patsubst %.o,%.d,$(patsubst %.a,%.o,$(OBJ)))
# Keep the .d files
.PRECIOUS: $(DEPS)
# Empty rule to force recompilation if the .d file is missing
$(DEPS):
$(foreach OUTPUT,$(OUTPUTS),$(eval $(call GEN_OBJRULE,$(OUTPUT))))
# Create preprocessed source for use in sending a bug report.
%.i : %.c | $(BEGIN)
$(CC) -E -mmcu=$(MCU) $(CFLAGS) $< -o $@
# Target: clean project.
clean:
$(foreach OUTPUT,$(OUTPUTS), $(REMOVE) -r $(OUTPUT) 2>/dev/null)
$(REMOVE) $(BUILD_DIR)/$(TARGET).*
show_path:
@echo VPATH=$(VPATH)
@echo SRC=$(SRC)
@echo OBJ=$(OBJ)
dump_vars: ERROR_IF_EMPTY=""
dump_vars: ERROR_IF_NONBOOL=""
dump_vars: ERROR_IF_UNSET=""
dump_vars: CATASTROPHIC_ERROR=""
dump_vars:
@$(foreach V,$(sort $(.VARIABLES)),$(if $(filter-out environment% default automatic,$(origin $V)),$(info $V=$($V))))
objs-size:
for i in $(OBJ); do echo $$i; done | sort | xargs $(SIZE)
# size check optionally implemented in its platform.mk
check-size:
check-md5:
$(MD5SUM) $(BUILD_DIR)/$(TARGET).$(FIRMWARE_FORMAT)
# Create build directory
$(shell mkdir -p $(BUILD_DIR) 2>/dev/null)
# Create object files directory
$(eval $(foreach OUTPUT,$(OUTPUTS),$(shell mkdir -p $(OUTPUT) 2>/dev/null)))
# Include the dependency files.
-include $(patsubst %.o,%.d,$(patsubst %.a,%.o,$(OBJ)))
# Listing of phony targets.
.PHONY : all dump_vars finish sizebefore sizeafter qmkversion \
gccversion build elf hex uf2 eep lss sym coff extcoff \
clean clean_list debug gdb-config show_path \
program teensy dfu dfu-ee dfu-start \
flash dfu-split-left dfu-split-right \
avrdude-split-left avrdude-split-right \
avrdude-loop usbasp

View file

@ -1,39 +0,0 @@
ifneq (,$(filter $(MCU),atmega32u4))
# TODO: opt in rather than assume everything uses a pro micro
PIN_COMPATIBLE ?= promicro
endif
# 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)
ifeq ($(PIN_COMPATIBLE),)
$(call CATASTROPHIC_ERROR,Converting to '$(CONVERT_TO)' not possible!)
endif
# glob to search each platfrorm and/or check for valid converter
CONVERTER := $(wildcard $(PLATFORM_PATH)/*/converters/$(PIN_COMPATIBLE)_to_$(CONVERT_TO)/)
ifeq ($(CONVERTER),)
$(call CATASTROPHIC_ERROR,Converting from '$(PIN_COMPATIBLE)' to '$(CONVERT_TO)' not possible!)
endif
-include $(CONVERTER)/pre_converter.mk
PLATFORM_KEY = $(shell echo $(CONVERTER) | cut -d "/" -f2)
# Configure any defaults
OPT_DEFS += -DCONVERT_TO_$(shell echo $(CONVERT_TO) | tr '[:lower:]' '[:upper:]')
OPT_DEFS += -DCONVERTER_TARGET=\"$(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:]')
# Finally run any converter specific logic
include $(CONVERTER)/converter.mk
endif

View file

@ -1,27 +0,0 @@
# Unconditionally disable features that a keyboard advertises it doesn't support
FEATURE_NAMES :=
FEATURE_NAMES += AUDIO
FEATURE_NAMES += BACKLIGHT
FEATURE_NAMES += BLUETOOTH
FEATURE_NAMES += DIP_SWITCH
FEATURE_NAMES += DYNAMIC_KEYMAP
FEATURE_NAMES += ENCODER
FEATURE_NAMES += HAPTIC
FEATURE_NAMES += HD44780
FEATURE_NAMES += IOS_DEVICE
FEATURE_NAMES += LCD_BACKLIGHT
FEATURE_NAMES += LCD
FEATURE_NAMES += OLED
FEATURE_NAMES += POINTING_DEVICE
FEATURE_NAMES += PS2_MOUSE
FEATURE_NAMES += RGBLIGHT
FEATURE_NAMES += RGB_MATRIX
FEATURE_NAMES += SLEEP_LED
FEATURE_NAMES += STENO
FEATURE_NAMES += SWAP_HANDS
FEATURE_NAMES += WATCHDOG
FEATURE_NAMES += XT
$(foreach AFEATURE,$(FEATURE_NAMES),\
$(if $(filter $($(AFEATURE)_SUPPORTED),no),$(eval $(AFEATURE)_ENABLE=no)))

View file

@ -1,5 +0,0 @@
node_modules
.vitepress/cache
.vitepress/.temp
.vitepress/dist
docs

View file

@ -1,58 +0,0 @@
import { defineConfig } from "vitepress";
import { tabsMarkdownPlugin } from "vitepress-plugin-tabs";
import sidebar from "../../../docs/_sidebar.json";
// https://vitepress.dev/reference/site-config
export default defineConfig(({ mode }) => {
const prod = mode === "production";
return {
title: "QMK Firmware",
description: "Documentation for QMK Firmware",
srcDir: prod ? "docs" : "../../docs",
outDir: "../../.build/docs",
cleanUrls: true,
markdown: {
config(md) {
md.use(tabsMarkdownPlugin);
},
},
vite: {
resolve: {
preserveSymlinks: true,
},
},
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
logo: {
light: "/qmk-logo-light.svg",
dark: "/qmk-logo-dark.svg",
},
title: 'QMK Firmware',
nav: [{ text: "Home", link: "/" }],
search: {
provider: "local",
},
editLink: {
pattern: 'https://github.com/qmk/qmk_firmware/edit/master/docs/:path'
},
lastUpdated: true,
sidebar: sidebar,
externalLinkIcon: true,
socialLinks: [
{ icon: { svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50px" height="50px"><path d="M 29 3 C 28.0625 3 27.164063 3.382813 26.5 4 C 25.835938 4.617188 25.363281 5.433594 25 6.40625 C 24.355469 8.140625 24.085938 10.394531 24.03125 13.03125 C 19.234375 13.179688 14.820313 14.421875 11.28125 16.46875 C 10.214844 15.46875 8.855469 14.96875 7.5 14.96875 C 6.089844 14.96875 4.675781 15.511719 3.59375 16.59375 C 1.425781 18.761719 1.425781 22.238281 3.59375 24.40625 L 3.84375 24.65625 C 3.3125 26.035156 3 27.488281 3 29 C 3 33.527344 5.566406 37.585938 9.5625 40.4375 C 13.558594 43.289063 19.007813 45 25 45 C 30.992188 45 36.441406 43.289063 40.4375 40.4375 C 44.433594 37.585938 47 33.527344 47 29 C 47 27.488281 46.6875 26.035156 46.15625 24.65625 L 46.40625 24.40625 C 48.574219 22.238281 48.574219 18.761719 46.40625 16.59375 C 45.324219 15.511719 43.910156 14.96875 42.5 14.96875 C 41.144531 14.96875 39.785156 15.46875 38.71875 16.46875 C 35.195313 14.433594 30.800781 13.191406 26.03125 13.03125 C 26.09375 10.546875 26.363281 8.46875 26.875 7.09375 C 27.164063 6.316406 27.527344 5.757813 27.875 5.4375 C 28.222656 5.117188 28.539063 5 29 5 C 29.460938 5 29.683594 5.125 30.03125 5.40625 C 30.378906 5.6875 30.785156 6.148438 31.3125 6.6875 C 32.253906 7.652344 33.695313 8.714844 36.09375 8.9375 C 36.539063 11.238281 38.574219 13 41 13 C 43.75 13 46 10.75 46 8 C 46 5.25 43.75 3 41 3 C 38.605469 3 36.574219 4.710938 36.09375 6.96875 C 34.3125 6.796875 33.527344 6.109375 32.75 5.3125 C 32.300781 4.851563 31.886719 4.3125 31.3125 3.84375 C 30.738281 3.375 29.9375 3 29 3 Z M 41 5 C 42.667969 5 44 6.332031 44 8 C 44 9.667969 42.667969 11 41 11 C 39.332031 11 38 9.667969 38 8 C 38 6.332031 39.332031 5 41 5 Z M 25 15 C 30.609375 15 35.675781 16.613281 39.28125 19.1875 C 42.886719 21.761719 45 25.226563 45 29 C 45 32.773438 42.886719 36.238281 39.28125 38.8125 C 35.675781 41.386719 30.609375 43 25 43 C 19.390625 43 14.324219 41.386719 10.71875 38.8125 C 7.113281 36.238281 5 32.773438 5 29 C 5 25.226563 7.113281 21.761719 10.71875 19.1875 C 14.324219 16.613281 19.390625 15 25 15 Z M 7.5 16.9375 C 8.203125 16.9375 8.914063 17.148438 9.53125 17.59375 C 7.527344 19.03125 5.886719 20.769531 4.75 22.71875 C 3.582031 21.296875 3.660156 19.339844 5 18 C 5.714844 17.285156 6.609375 16.9375 7.5 16.9375 Z M 42.5 16.9375 C 43.390625 16.9375 44.285156 17.285156 45 18 C 46.339844 19.339844 46.417969 21.296875 45.25 22.71875 C 44.113281 20.769531 42.472656 19.03125 40.46875 17.59375 C 41.085938 17.148438 41.796875 16.9375 42.5 16.9375 Z M 17 22 C 14.800781 22 13 23.800781 13 26 C 13 28.199219 14.800781 30 17 30 C 19.199219 30 21 28.199219 21 26 C 21 23.800781 19.199219 22 17 22 Z M 33 22 C 30.800781 22 29 23.800781 29 26 C 29 28.199219 30.800781 30 33 30 C 35.199219 30 37 28.199219 37 26 C 37 23.800781 35.199219 22 33 22 Z M 17 24 C 18.117188 24 19 24.882813 19 26 C 19 27.117188 18.117188 28 17 28 C 15.882813 28 15 27.117188 15 26 C 15 24.882813 15.882813 24 17 24 Z M 33 24 C 34.117188 24 35 24.882813 35 26 C 35 27.117188 34.117188 28 33 28 C 31.882813 28 31 27.117188 31 26 C 31 24.882813 31.882813 24 33 24 Z M 34.15625 33.84375 C 34.101563 33.851563 34.050781 33.859375 34 33.875 C 33.683594 33.9375 33.417969 34.144531 33.28125 34.4375 C 33.28125 34.4375 32.757813 35.164063 31.4375 36 C 30.117188 36.835938 28.058594 37.6875 25 37.6875 C 21.941406 37.6875 19.882813 36.835938 18.5625 36 C 17.242188 35.164063 16.71875 34.4375 16.71875 34.4375 C 16.492188 34.082031 16.066406 33.90625 15.65625 34 C 15.332031 34.082031 15.070313 34.316406 14.957031 34.632813 C 14.84375 34.945313 14.894531 35.292969 15.09375 35.5625 C 15.09375 35.5625 15.863281 36.671875 17.46875 37.6875 C 19.074219 38.703125 21.558594 39.6875 25 39.6875 C 28.441406 39.6875 30.925781 38.703125 32.53125 37.6875 C 34.136719 36.671875 34.90625 35.5625 34.90625 35.5625 C 35.207031 35.273438 35.296875 34.824219 35.128906 34.441406 C 34.960938 34.058594 34.574219 33.820313 34.15625 33.84375 Z"/></svg>' }, link: "https://reddit.com/r/olkb" },
{ icon: "discord", link: "https://discord.gg/qmk" },
{ icon: "github", link: "https://github.com/qmk/qmk_firmware" },
],
}
};
});

View file

@ -1,29 +0,0 @@
<script setup>
import DefaultTheme from 'vitepress/theme'
import { useRouter } from 'vitepress'
import { onBeforeMount } from 'vue';
import aliases from "../../../../docs/_aliases.json";
const router = useRouter()
onBeforeMount(async () => {
// Convert from docsify-style to vitepress-style URLs
let newUrl = window.location.href.replace(/\/#\//, '/').replace(/\?id=/, '#');
// Convert any aliases
let testUrl = new URL(newUrl);
while (testUrl.pathname in aliases) {
testUrl.pathname = aliases[testUrl.pathname];
}
newUrl = testUrl.toString();
// Redirect if required
if (newUrl != window.location.href) {
window.history.replaceState({}, '', newUrl);
await router.go(newUrl);
}
});
</script>
<template>
<DefaultTheme.Layout/>
</template>

View file

@ -1,19 +0,0 @@
/* Override <kbd> as vitepress doesn't put them with borders */
kbd {
border: 1px solid var(--vp-c-text-1);
border-radius: 5px;
margin: 0.2em;
padding: 0.2em;
}
:root {
--vp-nav-logo-height: 32px;
--vp-layout-max-width: calc(98% + 64px);
--vp-sidebar-width: 300px;
}
.VPDoc.has-aside .content-container {
max-width: unset !important;
}

View file

@ -1,13 +0,0 @@
import type { Theme } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import { enhanceAppWithTabs } from 'vitepress-plugin-tabs/client'
import QMKLayout from './QMKLayout.vue'
import './custom.css'
export default {
extends: DefaultTheme,
Layout: QMKLayout,
enhanceApp({ app }) {
enhanceAppWithTabs(app)
}
} satisfies Theme

View file

@ -1,6 +0,0 @@
#!/usr/bin/env bash
cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
yarn install
[[ -e docs ]] || ln -sf ../../docs docs
DEBUG='vitepress:*,vite:*' yarn run docs:build

View file

@ -1,14 +0,0 @@
{
"license": "GPL-2.0-or-later",
"devDependencies": {
"vite": "^5.4.19",
"vitepress": "^1.1.0",
"vitepress-plugin-tabs": "^0.5.0",
"vue": "^3.4.24"
},
"scripts": {
"docs:dev": "vitepress dev --host 0.0.0.0",
"docs:build": "vitepress build",
"docs:preview": "vitepress preview --host 0.0.0.0"
}
}

View file

@ -1,5 +0,0 @@
#!/usr/bin/env bash
cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
yarn install
DEBUG='vitepress:*,vite:*' yarn run docs:dev

View file

@ -1,820 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@algolia/autocomplete-core@1.9.3":
version "1.9.3"
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz#1d56482a768c33aae0868c8533049e02e8961be7"
integrity sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==
dependencies:
"@algolia/autocomplete-plugin-algolia-insights" "1.9.3"
"@algolia/autocomplete-shared" "1.9.3"
"@algolia/autocomplete-plugin-algolia-insights@1.9.3":
version "1.9.3"
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz#9b7f8641052c8ead6d66c1623d444cbe19dde587"
integrity sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==
dependencies:
"@algolia/autocomplete-shared" "1.9.3"
"@algolia/autocomplete-preset-algolia@1.9.3":
version "1.9.3"
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz#64cca4a4304cfcad2cf730e83067e0c1b2f485da"
integrity sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==
dependencies:
"@algolia/autocomplete-shared" "1.9.3"
"@algolia/autocomplete-shared@1.9.3":
version "1.9.3"
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz#2e22e830d36f0a9cf2c0ccd3c7f6d59435b77dfa"
integrity sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==
"@algolia/cache-browser-local-storage@4.23.3":
version "4.23.3"
resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.23.3.tgz#0cc26b96085e1115dac5fcb9d826651ba57faabc"
integrity sha512-vRHXYCpPlTDE7i6UOy2xE03zHF2C8MEFjPN2v7fRbqVpcOvAUQK81x3Kc21xyb5aSIpYCjWCZbYZuz8Glyzyyg==
dependencies:
"@algolia/cache-common" "4.23.3"
"@algolia/cache-common@4.23.3":
version "4.23.3"
resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.23.3.tgz#3bec79092d512a96c9bfbdeec7cff4ad36367166"
integrity sha512-h9XcNI6lxYStaw32pHpB1TMm0RuxphF+Ik4o7tcQiodEdpKK+wKufY6QXtba7t3k8eseirEMVB83uFFF3Nu54A==
"@algolia/cache-in-memory@4.23.3":
version "4.23.3"
resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.23.3.tgz#3945f87cd21ffa2bec23890c85305b6b11192423"
integrity sha512-yvpbuUXg/+0rbcagxNT7un0eo3czx2Uf0y4eiR4z4SD7SiptwYTpbuS0IHxcLHG3lq22ukx1T6Kjtk/rT+mqNg==
dependencies:
"@algolia/cache-common" "4.23.3"
"@algolia/client-account@4.23.3":
version "4.23.3"
resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.23.3.tgz#8751bbf636e6741c95e7c778488dee3ee430ac6f"
integrity sha512-hpa6S5d7iQmretHHF40QGq6hz0anWEHGlULcTIT9tbUssWUriN9AUXIFQ8Ei4w9azD0hc1rUok9/DeQQobhQMA==
dependencies:
"@algolia/client-common" "4.23.3"
"@algolia/client-search" "4.23.3"
"@algolia/transporter" "4.23.3"
"@algolia/client-analytics@4.23.3":
version "4.23.3"
resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.23.3.tgz#f88710885278fe6fb6964384af59004a5a6f161d"
integrity sha512-LBsEARGS9cj8VkTAVEZphjxTjMVCci+zIIiRhpFun9jGDUlS1XmhCW7CTrnaWeIuCQS/2iPyRqSy1nXPjcBLRA==
dependencies:
"@algolia/client-common" "4.23.3"
"@algolia/client-search" "4.23.3"
"@algolia/requester-common" "4.23.3"
"@algolia/transporter" "4.23.3"
"@algolia/client-common@4.23.3":
version "4.23.3"
resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.23.3.tgz#891116aa0db75055a7ecc107649f7f0965774704"
integrity sha512-l6EiPxdAlg8CYhroqS5ybfIczsGUIAC47slLPOMDeKSVXYG1n0qGiz4RjAHLw2aD0xzh2EXZ7aRguPfz7UKDKw==
dependencies:
"@algolia/requester-common" "4.23.3"
"@algolia/transporter" "4.23.3"
"@algolia/client-personalization@4.23.3":
version "4.23.3"
resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.23.3.tgz#35fa8e5699b0295fbc400a8eb211dc711e5909db"
integrity sha512-3E3yF3Ocr1tB/xOZiuC3doHQBQ2zu2MPTYZ0d4lpfWads2WTKG7ZzmGnsHmm63RflvDeLK/UVx7j2b3QuwKQ2g==
dependencies:
"@algolia/client-common" "4.23.3"
"@algolia/requester-common" "4.23.3"
"@algolia/transporter" "4.23.3"
"@algolia/client-search@4.23.3":
version "4.23.3"
resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.23.3.tgz#a3486e6af13a231ec4ab43a915a1f318787b937f"
integrity sha512-P4VAKFHqU0wx9O+q29Q8YVuaowaZ5EM77rxfmGnkHUJggh28useXQdopokgwMeYw2XUht49WX5RcTQ40rZIabw==
dependencies:
"@algolia/client-common" "4.23.3"
"@algolia/requester-common" "4.23.3"
"@algolia/transporter" "4.23.3"
"@algolia/logger-common@4.23.3":
version "4.23.3"
resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.23.3.tgz#35c6d833cbf41e853a4f36ba37c6e5864920bfe9"
integrity sha512-y9kBtmJwiZ9ZZ+1Ek66P0M68mHQzKRxkW5kAAXYN/rdzgDN0d2COsViEFufxJ0pb45K4FRcfC7+33YB4BLrZ+g==
"@algolia/logger-console@4.23.3":
version "4.23.3"
resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.23.3.tgz#30f916781826c4db5f51fcd9a8a264a06e136985"
integrity sha512-8xoiseoWDKuCVnWP8jHthgaeobDLolh00KJAdMe9XPrWPuf1by732jSpgy2BlsLTaT9m32pHI8CRfrOqQzHv3A==
dependencies:
"@algolia/logger-common" "4.23.3"
"@algolia/recommend@4.23.3":
version "4.23.3"
resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-4.23.3.tgz#53d4f194d22d9c72dc05f3f7514c5878f87c5890"
integrity sha512-9fK4nXZF0bFkdcLBRDexsnGzVmu4TSYZqxdpgBW2tEyfuSSY54D4qSRkLmNkrrz4YFvdh2GM1gA8vSsnZPR73w==
dependencies:
"@algolia/cache-browser-local-storage" "4.23.3"
"@algolia/cache-common" "4.23.3"
"@algolia/cache-in-memory" "4.23.3"
"@algolia/client-common" "4.23.3"
"@algolia/client-search" "4.23.3"
"@algolia/logger-common" "4.23.3"
"@algolia/logger-console" "4.23.3"
"@algolia/requester-browser-xhr" "4.23.3"
"@algolia/requester-common" "4.23.3"
"@algolia/requester-node-http" "4.23.3"
"@algolia/transporter" "4.23.3"
"@algolia/requester-browser-xhr@4.23.3":
version "4.23.3"
resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.23.3.tgz#9e47e76f60d540acc8b27b4ebc7a80d1b41938b9"
integrity sha512-jDWGIQ96BhXbmONAQsasIpTYWslyjkiGu0Quydjlowe+ciqySpiDUrJHERIRfELE5+wFc7hc1Q5hqjGoV7yghw==
dependencies:
"@algolia/requester-common" "4.23.3"
"@algolia/requester-common@4.23.3":
version "4.23.3"
resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.23.3.tgz#7dbae896e41adfaaf1d1fa5f317f83a99afb04b3"
integrity sha512-xloIdr/bedtYEGcXCiF2muajyvRhwop4cMZo+K2qzNht0CMzlRkm8YsDdj5IaBhshqfgmBb3rTg4sL4/PpvLYw==
"@algolia/requester-node-http@4.23.3":
version "4.23.3"
resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.23.3.tgz#c9f94a5cb96a15f48cea338ab6ef16bbd0ff989f"
integrity sha512-zgu++8Uj03IWDEJM3fuNl34s746JnZOWn1Uz5taV1dFyJhVM/kTNw9Ik7YJWiUNHJQXcaD8IXD1eCb0nq/aByA==
dependencies:
"@algolia/requester-common" "4.23.3"
"@algolia/transporter@4.23.3":
version "4.23.3"
resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.23.3.tgz#545b045b67db3850ddf0bbecbc6c84ff1f3398b7"
integrity sha512-Wjl5gttqnf/gQKJA+dafnD0Y6Yw97yvfY8R9h0dQltX1GXTgNs1zWgvtWW0tHl1EgMdhAyw189uWiZMnL3QebQ==
dependencies:
"@algolia/cache-common" "4.23.3"
"@algolia/logger-common" "4.23.3"
"@algolia/requester-common" "4.23.3"
"@babel/parser@^7.24.4":
version "7.24.4"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.4.tgz#234487a110d89ad5a3ed4a8a566c36b9453e8c88"
integrity sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==
"@docsearch/css@3.6.0", "@docsearch/css@^3.6.0":
version "3.6.0"
resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.6.0.tgz#0e9f56f704b3a34d044d15fd9962ebc1536ba4fb"
integrity sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ==
"@docsearch/js@^3.6.0":
version "3.6.0"
resolved "https://registry.yarnpkg.com/@docsearch/js/-/js-3.6.0.tgz#f9e46943449b9092d874944f7a80bcc071004cfb"
integrity sha512-QujhqINEElrkIfKwyyyTfbsfMAYCkylInLYMRqHy7PHc8xTBQCow73tlo/Kc7oIwBrCLf0P3YhjlOeV4v8hevQ==
dependencies:
"@docsearch/react" "3.6.0"
preact "^10.0.0"
"@docsearch/react@3.6.0":
version "3.6.0"
resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.6.0.tgz#b4f25228ecb7fc473741aefac592121e86dd2958"
integrity sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w==
dependencies:
"@algolia/autocomplete-core" "1.9.3"
"@algolia/autocomplete-preset-algolia" "1.9.3"
"@docsearch/css" "3.6.0"
algoliasearch "^4.19.1"
"@esbuild/aix-ppc64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f"
integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==
"@esbuild/android-arm64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052"
integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==
"@esbuild/android-arm@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28"
integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==
"@esbuild/android-x64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e"
integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==
"@esbuild/darwin-arm64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a"
integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==
"@esbuild/darwin-x64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22"
integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==
"@esbuild/freebsd-arm64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e"
integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==
"@esbuild/freebsd-x64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261"
integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==
"@esbuild/linux-arm64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b"
integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==
"@esbuild/linux-arm@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9"
integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==
"@esbuild/linux-ia32@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2"
integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==
"@esbuild/linux-loong64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df"
integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==
"@esbuild/linux-mips64el@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe"
integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==
"@esbuild/linux-ppc64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4"
integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==
"@esbuild/linux-riscv64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc"
integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==
"@esbuild/linux-s390x@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de"
integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==
"@esbuild/linux-x64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0"
integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==
"@esbuild/netbsd-x64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047"
integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==
"@esbuild/openbsd-x64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70"
integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==
"@esbuild/sunos-x64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b"
integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==
"@esbuild/win32-arm64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d"
integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==
"@esbuild/win32-ia32@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b"
integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==
"@esbuild/win32-x64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c"
integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==
"@jridgewell/sourcemap-codec@^1.4.15":
version "1.4.15"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
"@rollup/rollup-android-arm-eabi@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.31.0.tgz#d4dd60da0075a6ce9a6c76d71b8204f3e1822285"
integrity sha512-9NrR4033uCbUBRgvLcBrJofa2KY9DzxL2UKZ1/4xA/mnTNyhZCWBuD8X3tPm1n4KxcgaraOYgrFKSgwjASfmlA==
"@rollup/rollup-android-arm64@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.31.0.tgz#25c4d33259a7a2ccd2f52a5ffcc0bb3ab3f0729d"
integrity sha512-iBbODqT86YBFHajxxF8ebj2hwKm1k8PTBQSojSt3d1FFt1gN+xf4CowE47iN0vOSdnd+5ierMHBbu/rHc7nq5g==
"@rollup/rollup-darwin-arm64@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.31.0.tgz#d137dff254b19163a6b52ac083a71cd055dae844"
integrity sha512-WHIZfXgVBX30SWuTMhlHPXTyN20AXrLH4TEeH/D0Bolvx9PjgZnn4H677PlSGvU6MKNsjCQJYczkpvBbrBnG6g==
"@rollup/rollup-darwin-x64@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.31.0.tgz#58ff20b5dacb797d3adca19f02a21c532f9d55bf"
integrity sha512-hrWL7uQacTEF8gdrQAqcDy9xllQ0w0zuL1wk1HV8wKGSGbKPVjVUv/DEwT2+Asabf8Dh/As+IvfdU+H8hhzrQQ==
"@rollup/rollup-freebsd-arm64@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.31.0.tgz#96ce1a241c591ec3e068f4af765d94eddb24e60c"
integrity sha512-S2oCsZ4hJviG1QjPY1h6sVJLBI6ekBeAEssYKad1soRFv3SocsQCzX6cwnk6fID6UQQACTjeIMB+hyYrFacRew==
"@rollup/rollup-freebsd-x64@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.31.0.tgz#e59e7ede505be41f0b4311b0b943f8eb44938467"
integrity sha512-pCANqpynRS4Jirn4IKZH4tnm2+2CqCNLKD7gAdEjzdLGbH1iO0zouHz4mxqg0uEMpO030ejJ0aA6e1PJo2xrPA==
"@rollup/rollup-linux-arm-gnueabihf@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.31.0.tgz#e455ca6e4ff35bd46d62201c153352e717000a7b"
integrity sha512-0O8ViX+QcBd3ZmGlcFTnYXZKGbFu09EhgD27tgTdGnkcYXLat4KIsBBQeKLR2xZDCXdIBAlWLkiXE1+rJpCxFw==
"@rollup/rollup-linux-arm-musleabihf@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.31.0.tgz#bc1a93d807d19e70b1e343a5bfea43723bcd6327"
integrity sha512-w5IzG0wTVv7B0/SwDnMYmbr2uERQp999q8FMkKG1I+j8hpPX2BYFjWe69xbhbP6J9h2gId/7ogesl9hwblFwwg==
"@rollup/rollup-linux-arm64-gnu@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.31.0.tgz#f38bf843f1dc3d5de680caf31084008846e3efae"
integrity sha512-JyFFshbN5xwy6fulZ8B/8qOqENRmDdEkcIMF0Zz+RsfamEW+Zabl5jAb0IozP/8UKnJ7g2FtZZPEUIAlUSX8cA==
"@rollup/rollup-linux-arm64-musl@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.31.0.tgz#b3987a96c18b7287129cf735be2dbf83e94d9d05"
integrity sha512-kpQXQ0UPFeMPmPYksiBL9WS/BDiQEjRGMfklVIsA0Sng347H8W2iexch+IEwaR7OVSKtr2ZFxggt11zVIlZ25g==
"@rollup/rollup-linux-loongarch64-gnu@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.31.0.tgz#0f0324044e71c4f02e9f49e7ec4e347b655b34ee"
integrity sha512-pMlxLjt60iQTzt9iBb3jZphFIl55a70wexvo8p+vVFK+7ifTRookdoXX3bOsRdmfD+OKnMozKO6XM4zR0sHRrQ==
"@rollup/rollup-linux-powerpc64le-gnu@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.31.0.tgz#809479f27f1fd5b4eecd2aa732132ad952d454ba"
integrity sha512-D7TXT7I/uKEuWiRkEFbed1UUYZwcJDU4vZQdPTcepK7ecPhzKOYk4Er2YR4uHKme4qDeIh6N3XrLfpuM7vzRWQ==
"@rollup/rollup-linux-riscv64-gnu@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.31.0.tgz#7bc75c4f22db04d3c972f83431739cfa41c6a36e"
integrity sha512-wal2Tc8O5lMBtoePLBYRKj2CImUCJ4UNGJlLwspx7QApYny7K1cUYlzQ/4IGQBLmm+y0RS7dwc3TDO/pmcneTw==
"@rollup/rollup-linux-s390x-gnu@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.31.0.tgz#cfe8052345c55864d83ae343362cf1912480170e"
integrity sha512-O1o5EUI0+RRMkK9wiTVpk2tyzXdXefHtRTIjBbmFREmNMy7pFeYXCFGbhKFwISA3UOExlo5GGUuuj3oMKdK6JQ==
"@rollup/rollup-linux-x64-gnu@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.31.0.tgz#c6b048f1e25f3fea5b4bd246232f4d07a159c5a0"
integrity sha512-zSoHl356vKnNxwOWnLd60ixHNPRBglxpv2g7q0Cd3Pmr561gf0HiAcUBRL3S1vPqRC17Zo2CX/9cPkqTIiai1g==
"@rollup/rollup-linux-x64-musl@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.31.0.tgz#615273ac52d1a201f4de191cbd3389016a9d7d80"
integrity sha512-ypB/HMtcSGhKUQNiFwqgdclWNRrAYDH8iMYH4etw/ZlGwiTVxBz2tDrGRrPlfZu6QjXwtd+C3Zib5pFqID97ZA==
"@rollup/rollup-win32-arm64-msvc@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.31.0.tgz#32ed85810c1b831c648eca999d68f01255b30691"
integrity sha512-JuhN2xdI/m8Hr+aVO3vspO7OQfUFO6bKLIRTAy0U15vmWjnZDLrEgCZ2s6+scAYaQVpYSh9tZtRijApw9IXyMw==
"@rollup/rollup-win32-ia32-msvc@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.31.0.tgz#d47effada68bcbfdccd30c4a788d42e4542ff4d3"
integrity sha512-U1xZZXYkvdf5MIWmftU8wrM5PPXzyaY1nGCI4KI4BFfoZxHamsIe+BtnPLIvvPykvQWlVbqUXdLa4aJUuilwLQ==
"@rollup/rollup-win32-x64-msvc@4.31.0":
version "4.31.0"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.31.0.tgz#7a2d89a82cf0388d60304964217dd7beac6de645"
integrity sha512-ul8rnCsUumNln5YWwz0ted2ZHFhzhRRnkpBZ+YRuHoRAlUji9KChpOUOndY7uykrPEPXVbHLlsdo6v5yXo/TXw==
"@shikijs/core@1.3.0", "@shikijs/core@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-1.3.0.tgz#5b93b51ddb8def1e3a1543107f9b5b0540f716f6"
integrity sha512-7fedsBfuILDTBmrYZNFI8B6ATTxhQAasUHllHmjvSZPnoq4bULWoTpHwmuQvZ8Aq03/tAa2IGo6RXqWtHdWaCA==
"@shikijs/transformers@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@shikijs/transformers/-/transformers-1.3.0.tgz#b03c5733ef61e25e4f53666bf11889f8876f34e9"
integrity sha512-3mlpg2I9CjhjE96dEWQOGeCWoPcyTov3s4aAsHmgvnTHa8MBknEnCQy8/xivJPSpD+olqOqIEoHnLfbNJK29AA==
dependencies:
shiki "1.3.0"
"@types/estree@1.0.6":
version "1.0.6"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
"@types/linkify-it@*":
version "3.0.5"
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.5.tgz#1e78a3ac2428e6d7e6c05c1665c242023a4601d8"
integrity sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==
"@types/markdown-it@^14.0.1":
version "14.0.1"
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-14.0.1.tgz#3d3fdf9dba83b69edececc070d39ec72b84270a7"
integrity sha512-6WfOG3jXR78DW8L5cTYCVVGAsIFZskRHCDo5tbqa+qtKVt4oDRVH7hyIWu1SpDQJlmIoEivNQZ5h+AGAOrgOtQ==
dependencies:
"@types/linkify-it" "*"
"@types/mdurl" "*"
"@types/mdurl@*":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.5.tgz#3e0d2db570e9fb6ccb2dc8fde0be1d79ac810d39"
integrity sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==
"@types/web-bluetooth@^0.0.20":
version "0.0.20"
resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz#f066abfcd1cbe66267cdbbf0de010d8a41b41597"
integrity sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==
"@vitejs/plugin-vue@^5.0.4":
version "5.0.4"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz#508d6a0f2440f86945835d903fcc0d95d1bb8a37"
integrity sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==
"@vue/compiler-core@3.4.24":
version "3.4.24"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.24.tgz#6b4a5ffddcd874a692f2acfa68981201bcd7096b"
integrity sha512-vbW/tgbwJYj62N/Ww99x0zhFTkZDTcGh3uwJEuadZ/nF9/xuFMC4693P9r+3sxGXISABpDKvffY5ApH9pmdd1A==
dependencies:
"@babel/parser" "^7.24.4"
"@vue/shared" "3.4.24"
entities "^4.5.0"
estree-walker "^2.0.2"
source-map-js "^1.2.0"
"@vue/compiler-dom@3.4.24":
version "3.4.24"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.24.tgz#b7335a49f095b6d35e48b6f7be8da513c1fa52b8"
integrity sha512-4XgABML/4cNndVsQndG6BbGN7+EoisDwi3oXNovqL/4jdNhwvP8/rfRMTb6FxkxIxUUtg6AI1/qZvwfSjxJiWA==
dependencies:
"@vue/compiler-core" "3.4.24"
"@vue/shared" "3.4.24"
"@vue/compiler-sfc@3.4.24":
version "3.4.24"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.24.tgz#2872e353147ce2a145169a33ddd4d68dc95c3a18"
integrity sha512-nRAlJUK02FTWfA2nuvNBAqsDZuERGFgxZ8sGH62XgFSvMxO2URblzulExsmj4gFZ8e+VAyDooU9oAoXfEDNxTA==
dependencies:
"@babel/parser" "^7.24.4"
"@vue/compiler-core" "3.4.24"
"@vue/compiler-dom" "3.4.24"
"@vue/compiler-ssr" "3.4.24"
"@vue/shared" "3.4.24"
estree-walker "^2.0.2"
magic-string "^0.30.10"
postcss "^8.4.38"
source-map-js "^1.2.0"
"@vue/compiler-ssr@3.4.24":
version "3.4.24"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.24.tgz#0d11fe54dabd17cbd6393a16bf7f785da1cfab46"
integrity sha512-ZsAtr4fhaUFnVcDqwW3bYCSDwq+9Gk69q2r/7dAHDrOMw41kylaMgOP4zRnn6GIEJkQznKgrMOGPMFnLB52RbQ==
dependencies:
"@vue/compiler-dom" "3.4.24"
"@vue/shared" "3.4.24"
"@vue/devtools-api@^7.0.27":
version "7.1.2"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-7.1.2.tgz#8808b0f008842b756bf1e9c30788837abb62ab3a"
integrity sha512-AKd49cN3BdRgttmX5Aw8op7sx6jmaPwaILcDjaa05UKc1yIHDYST7P8yGZs6zd2pKFETAQz40gmyG7+b57slsQ==
dependencies:
"@vue/devtools-kit" "^7.1.2"
"@vue/devtools-kit@^7.1.2":
version "7.1.2"
resolved "https://registry.yarnpkg.com/@vue/devtools-kit/-/devtools-kit-7.1.2.tgz#dfb7306edf895dadc556dd5f0c516809c2f94826"
integrity sha512-UTrcUSOhlI9eXqbPMHUWwA6NQiiPT3onzXsVk2JHGR8ZFFSkzsWTTpHyVA1woG8zvgu2HNV/wigW2k87p858zw==
dependencies:
"@vue/devtools-shared" "^7.1.2"
hookable "^5.5.3"
mitt "^3.0.1"
perfect-debounce "^1.0.0"
speakingurl "^14.0.1"
"@vue/devtools-shared@^7.1.2":
version "7.1.2"
resolved "https://registry.yarnpkg.com/@vue/devtools-shared/-/devtools-shared-7.1.2.tgz#7b1c1de10bab4756f271c377370a62833b4ee94b"
integrity sha512-r9cUf93VMhKSsxF2/cBbf6Lm1nRBx+r1pRuji5CiAf3JIPYPOjeEqJ13OuwP1fauYh1tyBFcCxt3eJPvHT59gg==
dependencies:
rfdc "^1.3.1"
"@vue/reactivity@3.4.24":
version "3.4.24"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.24.tgz#150584316ca2acc4ed19a24f9f29863c3a17a7b2"
integrity sha512-nup3fSYg4i4LtNvu9slF/HF/0dkMQYfepUdORBcMSsankzRPzE7ypAFurpwyRBfU1i7Dn1kcwpYsE1wETSh91g==
dependencies:
"@vue/shared" "3.4.24"
"@vue/runtime-core@3.4.24":
version "3.4.24"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.24.tgz#066c544dc59a07a96c12874a57b750c239124874"
integrity sha512-c7iMfj6cJMeAG3s5yOn9Rc5D9e2/wIuaozmGf/ICGCY3KV5H7mbTVdvEkd4ZshTq7RUZqj2k7LMJWVx+EBiY1g==
dependencies:
"@vue/reactivity" "3.4.24"
"@vue/shared" "3.4.24"
"@vue/runtime-dom@3.4.24":
version "3.4.24"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.24.tgz#4f8e7acbe1e8ffa7c55af1366e4438729ebe9b20"
integrity sha512-uXKzuh/Emfad2Y7Qm0ABsLZZV6H3mAJ5ZVqmAOlrNQRf+T5mxpPGZBfec1hkP41t6h6FwF6RSGCs/gd8WbuySQ==
dependencies:
"@vue/runtime-core" "3.4.24"
"@vue/shared" "3.4.24"
csstype "^3.1.3"
"@vue/server-renderer@3.4.24":
version "3.4.24"
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.24.tgz#80dd546f8d6a9f5c4f8b68083fe9cc2d62299332"
integrity sha512-H+DLK4sQF6sRgzKyofmlEVBIV/9KrQU6HIV7nt6yIwSGGKvSwlV8pqJlebUKLpbXaNHugdSfAbP6YmXF69lxow==
dependencies:
"@vue/compiler-ssr" "3.4.24"
"@vue/shared" "3.4.24"
"@vue/shared@3.4.24":
version "3.4.24"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.24.tgz#278ac71f492b392b9b17fe8fc7d324db1a8842db"
integrity sha512-BW4tajrJBM9AGAknnyEw5tO2xTmnqgup0VTnDAMcxYmqOX0RG0b9aSUGAbEKolD91tdwpA6oCwbltoJoNzpItw==
"@vueuse/core@10.9.0", "@vueuse/core@^10.9.0":
version "10.9.0"
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.9.0.tgz#7d779a95cf0189de176fee63cee4ba44b3c85d64"
integrity sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==
dependencies:
"@types/web-bluetooth" "^0.0.20"
"@vueuse/metadata" "10.9.0"
"@vueuse/shared" "10.9.0"
vue-demi ">=0.14.7"
"@vueuse/integrations@^10.9.0":
version "10.9.0"
resolved "https://registry.yarnpkg.com/@vueuse/integrations/-/integrations-10.9.0.tgz#2b1a9556215ad3c1f96d39cbfbef102cf6e0ec05"
integrity sha512-acK+A01AYdWSvL4BZmCoJAcyHJ6EqhmkQEXbQLwev1MY7NBnS+hcEMx/BzVoR9zKI+UqEPMD9u6PsyAuiTRT4Q==
dependencies:
"@vueuse/core" "10.9.0"
"@vueuse/shared" "10.9.0"
vue-demi ">=0.14.7"
"@vueuse/metadata@10.9.0":
version "10.9.0"
resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.9.0.tgz#769a1a9db65daac15cf98084cbf7819ed3758620"
integrity sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==
"@vueuse/shared@10.9.0":
version "10.9.0"
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.9.0.tgz#13af2a348de15d07b7be2fd0c7fc9853a69d8fe0"
integrity sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==
dependencies:
vue-demi ">=0.14.7"
algoliasearch@^4.19.1:
version "4.23.3"
resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.23.3.tgz#e09011d0a3b0651444916a3e6bbcba064ec44b60"
integrity sha512-Le/3YgNvjW9zxIQMRhUHuhiUjAlKY/zsdZpfq4dlLqg6mEm0nL6yk+7f2hDOtLpxsgE4jSzDmvHL7nXdBp5feg==
dependencies:
"@algolia/cache-browser-local-storage" "4.23.3"
"@algolia/cache-common" "4.23.3"
"@algolia/cache-in-memory" "4.23.3"
"@algolia/client-account" "4.23.3"
"@algolia/client-analytics" "4.23.3"
"@algolia/client-common" "4.23.3"
"@algolia/client-personalization" "4.23.3"
"@algolia/client-search" "4.23.3"
"@algolia/logger-common" "4.23.3"
"@algolia/logger-console" "4.23.3"
"@algolia/recommend" "4.23.3"
"@algolia/requester-browser-xhr" "4.23.3"
"@algolia/requester-common" "4.23.3"
"@algolia/requester-node-http" "4.23.3"
"@algolia/transporter" "4.23.3"
csstype@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
entities@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
esbuild@^0.21.3:
version "0.21.5"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d"
integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==
optionalDependencies:
"@esbuild/aix-ppc64" "0.21.5"
"@esbuild/android-arm" "0.21.5"
"@esbuild/android-arm64" "0.21.5"
"@esbuild/android-x64" "0.21.5"
"@esbuild/darwin-arm64" "0.21.5"
"@esbuild/darwin-x64" "0.21.5"
"@esbuild/freebsd-arm64" "0.21.5"
"@esbuild/freebsd-x64" "0.21.5"
"@esbuild/linux-arm" "0.21.5"
"@esbuild/linux-arm64" "0.21.5"
"@esbuild/linux-ia32" "0.21.5"
"@esbuild/linux-loong64" "0.21.5"
"@esbuild/linux-mips64el" "0.21.5"
"@esbuild/linux-ppc64" "0.21.5"
"@esbuild/linux-riscv64" "0.21.5"
"@esbuild/linux-s390x" "0.21.5"
"@esbuild/linux-x64" "0.21.5"
"@esbuild/netbsd-x64" "0.21.5"
"@esbuild/openbsd-x64" "0.21.5"
"@esbuild/sunos-x64" "0.21.5"
"@esbuild/win32-arm64" "0.21.5"
"@esbuild/win32-ia32" "0.21.5"
"@esbuild/win32-x64" "0.21.5"
estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
focus-trap@^7.5.4:
version "7.5.4"
resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-7.5.4.tgz#6c4e342fe1dae6add9c2aa332a6e7a0bbd495ba2"
integrity sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==
dependencies:
tabbable "^6.2.0"
fsevents@~2.3.2, fsevents@~2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
hookable@^5.5.3:
version "5.5.3"
resolved "https://registry.yarnpkg.com/hookable/-/hookable-5.5.3.tgz#6cfc358984a1ef991e2518cb9ed4a778bbd3215d"
integrity sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==
magic-string@^0.30.10:
version "0.30.10"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.10.tgz#123d9c41a0cb5640c892b041d4cfb3bd0aa4b39e"
integrity sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==
dependencies:
"@jridgewell/sourcemap-codec" "^1.4.15"
mark.js@8.11.1:
version "8.11.1"
resolved "https://registry.yarnpkg.com/mark.js/-/mark.js-8.11.1.tgz#180f1f9ebef8b0e638e4166ad52db879beb2ffc5"
integrity sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==
minisearch@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/minisearch/-/minisearch-6.3.0.tgz#985a2f1ca3c73c2d65af94f0616bfe57164b0b6b"
integrity sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ==
mitt@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1"
integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==
nanoid@^3.3.8:
version "3.3.8"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf"
integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==
perfect-debounce@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz#9c2e8bc30b169cc984a58b7d5b28049839591d2a"
integrity sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==
picocolors@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
postcss@^8.4.38, postcss@^8.4.43:
version "8.5.1"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.1.tgz#e2272a1f8a807fafa413218245630b5db10a3214"
integrity sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==
dependencies:
nanoid "^3.3.8"
picocolors "^1.1.1"
source-map-js "^1.2.1"
preact@^10.0.0:
version "10.20.2"
resolved "https://registry.yarnpkg.com/preact/-/preact-10.20.2.tgz#0b343299a8c020562311cc25db93b3d832ec5e71"
integrity sha512-S1d1ernz3KQ+Y2awUxKakpfOg2CEmJmwOP+6igPx6dgr6pgDvenqYviyokWso2rhHvGtTlWWnJDa7RaPbQerTg==
rfdc@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.1.tgz#2b6d4df52dffe8bb346992a10ea9451f24373a8f"
integrity sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==
rollup@^4.20.0:
version "4.31.0"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.31.0.tgz#b84af969a0292cb047dce2c0ec5413a9457597a4"
integrity sha512-9cCE8P4rZLx9+PjoyqHLs31V9a9Vpvfo4qNcs6JCiGWYhw2gijSetFbH6SSy1whnkgcefnUwr8sad7tgqsGvnw==
dependencies:
"@types/estree" "1.0.6"
optionalDependencies:
"@rollup/rollup-android-arm-eabi" "4.31.0"
"@rollup/rollup-android-arm64" "4.31.0"
"@rollup/rollup-darwin-arm64" "4.31.0"
"@rollup/rollup-darwin-x64" "4.31.0"
"@rollup/rollup-freebsd-arm64" "4.31.0"
"@rollup/rollup-freebsd-x64" "4.31.0"
"@rollup/rollup-linux-arm-gnueabihf" "4.31.0"
"@rollup/rollup-linux-arm-musleabihf" "4.31.0"
"@rollup/rollup-linux-arm64-gnu" "4.31.0"
"@rollup/rollup-linux-arm64-musl" "4.31.0"
"@rollup/rollup-linux-loongarch64-gnu" "4.31.0"
"@rollup/rollup-linux-powerpc64le-gnu" "4.31.0"
"@rollup/rollup-linux-riscv64-gnu" "4.31.0"
"@rollup/rollup-linux-s390x-gnu" "4.31.0"
"@rollup/rollup-linux-x64-gnu" "4.31.0"
"@rollup/rollup-linux-x64-musl" "4.31.0"
"@rollup/rollup-win32-arm64-msvc" "4.31.0"
"@rollup/rollup-win32-ia32-msvc" "4.31.0"
"@rollup/rollup-win32-x64-msvc" "4.31.0"
fsevents "~2.3.2"
shiki@1.3.0, shiki@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/shiki/-/shiki-1.3.0.tgz#3eda35cb49f6f0a98525e9da48fc072e6c655a3f"
integrity sha512-9aNdQy/etMXctnPzsje1h1XIGm9YfRcSksKOGqZWXA/qP9G18/8fpz5Bjpma8bOgz3tqIpjERAd6/lLjFyzoww==
dependencies:
"@shikijs/core" "1.3.0"
source-map-js@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==
source-map-js@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
speakingurl@^14.0.1:
version "14.0.1"
resolved "https://registry.yarnpkg.com/speakingurl/-/speakingurl-14.0.1.tgz#f37ec8ddc4ab98e9600c1c9ec324a8c48d772a53"
integrity sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==
tabbable@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97"
integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==
vite@^5.2.9, vite@^5.4.19:
version "5.4.19"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.19.tgz#20efd060410044b3ed555049418a5e7d1998f959"
integrity sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==
dependencies:
esbuild "^0.21.3"
postcss "^8.4.43"
rollup "^4.20.0"
optionalDependencies:
fsevents "~2.3.3"
vitepress-plugin-tabs@^0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/vitepress-plugin-tabs/-/vitepress-plugin-tabs-0.5.0.tgz#2b193a72ed36b9fcd63e3907d3044fe7b6cf3e4e"
integrity sha512-SIhFWwGsUkTByfc2b279ray/E0Jt8vDTsM1LiHxmCOBAEMmvzIBZSuYYT1DpdDTiS3SuJieBheJkYnwCq/yD9A==
vitepress@^1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/vitepress/-/vitepress-1.1.3.tgz#ded22392f5274680aaba8bb81dd4fb1c4741c02e"
integrity sha512-hGrIYN0w9IHWs0NQSnlMjKV/v/HLfD+Ywv5QdvCSkiT32mpNOOwUrZjnqZv/JL/WBPpUc94eghTUvmipxw0xrA==
dependencies:
"@docsearch/css" "^3.6.0"
"@docsearch/js" "^3.6.0"
"@shikijs/core" "^1.3.0"
"@shikijs/transformers" "^1.3.0"
"@types/markdown-it" "^14.0.1"
"@vitejs/plugin-vue" "^5.0.4"
"@vue/devtools-api" "^7.0.27"
"@vueuse/core" "^10.9.0"
"@vueuse/integrations" "^10.9.0"
focus-trap "^7.5.4"
mark.js "8.11.1"
minisearch "^6.3.0"
shiki "^1.3.0"
vite "^5.2.9"
vue "^3.4.23"
vue-demi@>=0.14.7:
version "0.14.7"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.7.tgz#8317536b3ef74c5b09f268f7782e70194567d8f2"
integrity sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==
vue@^3.4.23, vue@^3.4.24:
version "3.4.24"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.24.tgz#f269549939a6c092480f018aa0bd886ba64f4c6f"
integrity sha512-NPdx7dLGyHmKHGRRU5bMRYVE+rechR+KDU5R2tSTNG36PuMwbfAJ+amEvOAw7BPfZp5sQulNELSLm5YUkau+Sg==
dependencies:
"@vue/compiler-dom" "3.4.24"
"@vue/compiler-sfc" "3.4.24"
"@vue/runtime-dom" "3.4.24"
"@vue/server-renderer" "3.4.24"
"@vue/shared" "3.4.24"

View file

@ -1,74 +0,0 @@
# Copyright 2021 QMK
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
GRAVE_ESC_ENABLE ?= yes
MAGIC_ENABLE ?= yes
SEND_STRING_ENABLE ?= yes
SPACE_CADET_ENABLE ?= yes
GENERIC_FEATURES = \
AUTO_SHIFT \
AUTOCORRECT \
BOOTMAGIC \
CAPS_WORD \
COMBO \
COMMAND \
CONNECTION \
CRC \
DEFERRED_EXEC \
DIGITIZER \
DIP_SWITCH \
DYNAMIC_KEYMAP \
DYNAMIC_MACRO \
DYNAMIC_TAPPING_TERM \
GRAVE_ESC \
HAPTIC \
KEYCODE_STRING \
KEY_LOCK \
KEY_OVERRIDE \
LAYER_LOCK \
LEADER \
MAGIC \
MOUSEKEY \
MUSIC \
OS_DETECTION \
PROGRAMMABLE_BUTTON \
REPEAT_KEY \
SECURE \
SEND_STRING \
SEQUENCER \
SPACE_CADET \
SWAP_HANDS \
TAP_DANCE \
TRI_LAYER \
VIA \
VIRTSER \
WPM \
define HANDLE_GENERIC_FEATURE
# $$(info "Processing: $1_ENABLE $2.c")
SRC += $$(wildcard $$(QUANTUM_DIR)/process_keycode/process_$2.c)
SRC += $$(wildcard $$(QUANTUM_DIR)/$2/$2.c)
SRC += $$(wildcard $$(QUANTUM_DIR)/$2.c)
SRC += $$(wildcard $$(QUANTUM_DIR)/nvm/$$(NVM_DRIVER_LOWER)/nvm_$2.c)
VPATH += $$(wildcard $$(QUANTUM_DIR)/$2/)
OPT_DEFS += -D$1_ENABLE
endef
$(foreach F,$(GENERIC_FEATURES),\
$(if $(filter yes, $(strip $($(F)_ENABLE))),\
$(eval $(call HANDLE_GENERIC_FEATURE,$(F),$(shell echo $(F) | tr '[:upper:]' '[:lower:]'))) \
) \
)

View file

@ -1,113 +0,0 @@
COLOR ?= true
ifeq ($(COLOR),true)
NO_COLOR=\033[0m
OK_COLOR=\033[32;01m
ERROR_COLOR=\033[31;01m
WARN_COLOR=\033[33;01m
SKIPPED_COLOR=\033[36;01m
BLUE=\033[0;34m
BOLD=\033[1m
endif
ifneq ($(shell echo "1 2 3" | awk '{ printf "%2s", $$3; }' 2>/dev/null)," 3")
AWK=awk
else
AWK=cat && test
endif
ON_ERROR ?= exit 1
OK_STRING=$(OK_COLOR)[OK]$(NO_COLOR)\n
ERROR_STRING=$(ERROR_COLOR)[ERRORS]$(NO_COLOR)\n
WARN_STRING=$(WARN_COLOR)[WARNINGS]$(NO_COLOR)\n
SKIPPED_STRING=$(SKIPPED_COLOR)[SKIPPED]$(NO_COLOR)\n
TAB_LOG = printf "\n%s\n\n" "$$LOG" | $(AWK) '{ sub(/^/," | "); print }'
TAB_LOG_PLAIN = printf "%s\n" "$$LOG"
AWK_STATUS = $(AWK) '{ printf " %-10s\n", $$1; }'
AWK_CMD = $(AWK) '{ printf "%-99s", $$0; }'
PRINT_ERROR = ($(SILENT) ||printf " $(ERROR_STRING)" | $(AWK_STATUS)) && $(TAB_LOG) && $(ON_ERROR)
PRINT_WARNING = ($(SILENT) || printf " $(WARN_STRING)" | $(AWK_STATUS)) && $(TAB_LOG)
PRINT_ERROR_PLAIN = ($(SILENT) ||printf " $(ERROR_STRING)" | $(AWK_STATUS)) && $(TAB_LOG_PLAIN) && $(ON_ERROR)
PRINT_WARNING_PLAIN = ($(SILENT) || printf " $(WARN_STRING)" | $(AWK_STATUS)) && $(TAB_LOG_PLAIN)
PRINT_SKIPPED_PLAIN = ($(SILENT) || printf " $(SKIPPED_STRING)" | $(AWK_STATUS))
PRINT_OK = $(SILENT) || printf " $(OK_STRING)" | $(AWK_STATUS)
BUILD_CMD = LOG=$$($(CMD) 2>&1) ; if [ $$? -gt 0 ]; then $(PRINT_ERROR); elif [ "$$LOG" != "" ] ; then $(PRINT_WARNING); else $(PRINT_OK); fi;
MAKE_MSG_FORMAT = $(AWK) '{ printf "%-118s", $$0;}'
# The UNSYNC_OUTPUT_CMD command disables the `--output-sync` for the current command, if the `--output-sync` granularity is `target` or lower.
# This is achieved by telling make to treat the current command as if it invokes a recursive make subcommand (as if by calling `$(MAKE)`).
UNSYNC_OUTPUT_CMD = +true
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_ERRORS = $(ERROR_COLOR)Make finished with errors\n$(NO_COLOR)
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for flashing:
MSG_UF2 = Creating UF2 file for deployment:
MSG_EEPROM = Creating load file for EEPROM:
MSG_BIN = Creating binary load file for flashing:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_EXECUTING = Executing:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling:
MSG_COMPILING_CXX = Compiling:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
MSG_CREATING_LIBRARY = Creating library:
MSG_GENERATING = Generating:
MSG_NOT_REPO = $(WARN_COLOR)WARNING:$(NO_COLOR) Target folder is not a git repo, you probably downloaded a zip file instead of cloning.\n\
Please consider following $(BOLD)https://docs.qmk.fm/\#/newbs_getting_started$(NO_COLOR).\n\n
MSG_SUBMODULE_DIRTY = $(WARN_COLOR)WARNING:$(NO_COLOR) Some git submodules are out of date or modified.\n\
Please consider running $(BOLD)qmk git-submodule$(NO_COLOR).\n\n
define GENERATE_MSG_MAKE_KB
MSG_MAKE_KB_ACTUAL := Making $$(KB_SP) with keymap $(BOLD)$$(CURRENT_KM)$(NO_COLOR)
ifneq ($$(MAKE_TARGET),)
MSG_MAKE_KB_ACTUAL += and target $(BOLD)$$(MAKE_TARGET)$(NO_COLOR)
endif
endef
MSG_MAKE_KB = $(eval $(call GENERATE_MSG_MAKE_KB))$(MSG_MAKE_KB_ACTUAL)
define GENERATE_MSG_MAKE_TEST
MSG_MAKE_TEST_ACTUAL := Making test $(BOLD)$(TEST_NAME)$(NO_COLOR)
ifneq ($$(MAKE_TARGET),)
MSG_MAKE_TEST_ACTUAL += with target $(BOLD)$$(MAKE_TARGET)$(NO_COLOR)
endif
endef
MSG_MAKE_TEST = $(eval $(call GENERATE_MSG_MAKE_TEST))$(MSG_MAKE_TEST_ACTUAL)
MSG_TEST = Testing $(BOLD)$(TEST_NAME)$(NO_COLOR)
define GENERATE_MSG_AVAILABLE_KEYMAPS
MSG_AVAILABLE_KEYMAPS_ACTUAL := Available keymaps for $(BOLD)$$(CURRENT_KB)$(NO_COLOR):
endef
MSG_AVAILABLE_KEYMAPS = $(eval $(call GENERATE_MSG_AVAILABLE_KEYMAPS))$(MSG_AVAILABLE_KEYMAPS_ACTUAL)
MSG_BOOTLOADER_NOT_FOUND_BASE = Bootloader not found. Make sure the board is in bootloader mode. See https://docs.qmk.fm/\#/newbs_flashing\n
MSG_CHECK_FILESIZE = Checking file size of $(TARGET).$(FIRMWARE_FORMAT)
MSG_FILE_TOO_BIG = $(ERROR_COLOR)The firmware is too large!$(NO_COLOR) $(CURRENT_SIZE)/$(MAX_SIZE) ($(OVER_SIZE) bytes over)\n
MSG_FILE_TOO_SMALL = The firmware is too small! $(CURRENT_SIZE)/$(MAX_SIZE)\n
MSG_FILE_JUST_RIGHT = The firmware size is fine - $(CURRENT_SIZE)/$(MAX_SIZE) ($(PERCENT_SIZE)%%, $(FREE_SIZE) bytes free)\n
MSG_FILE_NEAR_LIMIT = The firmware size is approaching the maximum - $(CURRENT_SIZE)/$(MAX_SIZE) ($(PERCENT_SIZE)%%, $(FREE_SIZE) bytes free)\n
MSG_PYTHON_MISSING = $(ERROR_COLOR)ERROR:$(NO_COLOR) Cannot run \"qmk hello\"!\n\n\
Please run $(BOLD)qmk setup$(NO_COLOR) to install all the dependencies QMK requires.\n\n
MSG_FLASH_BOOTLOADER = $(WARN_COLOR)WARNING:$(NO_COLOR) This board's bootloader is not specified or is not supported by the \":flash\" target at this time.\n\n
MSG_FLASH_ARCH = $(WARN_COLOR)WARNING:$(NO_COLOR) This board's architecture is not supported by the \":flash\" target at this time.\n\n
MSG_BOOTLOADER_NOT_FOUND = $(ERROR_COLOR)ERROR:$(NO_COLOR) $(MSG_BOOTLOADER_NOT_FOUND_BASE) Trying again in 5s (Ctrl+C to cancel)\n
BOOTLOADER_RETRY_TIME ?= 0.5
MSG_BOOTLOADER_NOT_FOUND_QUICK_RETRY = $(MSG_BOOTLOADER_NOT_FOUND_BASE) Trying again every $(BOOTLOADER_RETRY_TIME)s (Ctrl+C to cancel)
define WARNING_MESSAGE
$(shell printf "\n %-99s $(WARN_STRING)\n" "$1" >&2)
endef
define CATASTROPHIC_ERROR
$(shell printf "\n * %-99s $(ERROR_STRING)\n" "$2" >&2)
$(error $1)
endef

View file

@ -1,151 +0,0 @@
BUILD_OPTION_NAMES = \
BOOTMAGIC_ENABLE \
MOUSEKEY_ENABLE \
EXTRAKEY_ENABLE \
CONSOLE_ENABLE \
COMMAND_ENABLE \
NKRO_ENABLE \
CUSTOM_MATRIX \
DEBOUNCE_TYPE \
SPLIT_KEYBOARD \
DYNAMIC_KEYMAP_ENABLE \
USB_HID_ENABLE \
VIA_ENABLE
HARDWARE_OPTION_NAMES = \
SLEEP_LED_ENABLE \
BACKLIGHT_ENABLE \
BACKLIGHT_DRIVER \
RGBLIGHT_ENABLE \
RGBLIGHT_DRIVER \
RGB_MATRIX_ENABLE \
RGB_MATRIX_DRIVER \
CIE1931_CURVE \
MIDI_ENABLE \
BLUETOOTH_ENABLE \
BLUETOOTH_DRIVER \
AUDIO_ENABLE \
HD44780_ENABLE \
ENCODER_ENABLE \
LED_TABLES \
POINTING_DEVICE_ENABLE \
DIP_SWITCH_ENABLE
OTHER_OPTION_NAMES = \
UNICODE_ENABLE \
UCIS_ENABLE \
UNICODEMAP_ENABLE \
UNICODE_COMMON \
AUTO_SHIFT_ENABLE \
DYNAMIC_TAPPING_TERM_ENABLE \
COMBO_ENABLE \
KEY_LOCK_ENABLE \
KEY_OVERRIDE_ENABLE \
LEADER_ENABLE \
STENO_ENABLE \
STENO_PROTOCOL \
TAP_DANCE_ENABLE \
VIRTSER_ENABLE \
OLED_ENABLE \
OLED_DRIVER \
LED_BACK_ENABLE \
LED_UNDERGLOW_ENABLE \
LED_ANIMATIONS \
IOS_DEVICE_ENABLE \
HELIX ZINC \
AUTOLOG_ENABLE \
DEBUG_ENABLE \
ENCODER_MAP_ENABLE \
ENCODER_ENABLE_CUSTOM \
GERMAN_ENABLE \
HAPTIC_ENABLE \
KEYLOGGER_ENABLE \
LCD_BACKLIGHT_ENABLE \
MACROS_ENABLED \
PS2_ENABLE \
PS2_MOUSE_ENABLE \
PS2_DRIVER \
RAW_ENABLE \
SWAP_HANDS_ENABLE \
WATCHDOG_ENABLE \
ERGOINU \
NO_USB_STARTUP_CHECK \
DISABLE_PROMICRO_LEDs \
MITOSIS_DATAGROK_BOTTOMSPACE \
MITOSIS_DATAGROK_SLOWUART \
RGB_MATRIX_KEYPRESSES \
LED_MIRRORED \
RGBLIGHT_FULL_POWER \
LTO_ENABLE \
PROGRAMMABLE_BUTTON_ENABLE \
SECURE_ENABLE \
CAPS_WORD_ENABLE \
AUTOCORRECT_ENABLE \
TRI_LAYER_ENABLE \
REPEAT_KEY_ENABLE
define NAME_ECHO
@printf " %-30s = %-16s # %s\\n" "$1" "$($1)" "$(origin $1)"
endef
define YAML_NAME_ECHO
@echo ' $1 : "$(strip $($1))"'
endef
.PHONY: show_build_options0 show_build_options
show_build_options0:
@echo " KEYBOARD = $(KEYBOARD)"
@echo " KEYMAP = $(KEYMAP)"
@echo " MCU = $(MCU)"
@echo " MCU_SERIES = $(MCU_SERIES)"
@echo " PLATFORM = $(PLATFORM)"
@echo " BOOTLOADER = $(BOOTLOADER)"
@echo " FIRMWARE_FORMAT = $(FIRMWARE_FORMAT)"
@echo
@echo "Build Options:"
$(foreach A_OPTION_NAME,$(sort $(BUILD_OPTION_NAMES)),\
$(call NAME_ECHO,$(A_OPTION_NAME)))
show_build_options: show_build_options0
@echo
@echo "If you want to know more, please try 'show_all_features' or 'show_full_features'"
@echo
.PHONY: show_all_features
show_all_features: show_build_options0
@echo
@echo "Hardware Options:"
$(foreach A_OPTION_NAME,$(sort $(HARDWARE_OPTION_NAMES)),\
$(if $($(A_OPTION_NAME)),$(call NAME_ECHO,$(A_OPTION_NAME))))
@echo
@echo "Other Options:"
$(foreach A_OPTION_NAME,$(sort $(OTHER_OPTION_NAMES)),\
$(if $($(A_OPTION_NAME)),$(call NAME_ECHO,$(A_OPTION_NAME))))
.PHONY: show_full_features
show_full_features: show_build_options0
@echo
@echo "Hardware Options:"
$(foreach A_OPTION_NAME,$(sort $(HARDWARE_OPTION_NAMES)),\
$(call NAME_ECHO,$(A_OPTION_NAME)))
@echo
@echo "Other Options:"
$(foreach A_OPTION_NAME,$(sort $(OTHER_OPTION_NAMES)),\
$(call NAME_ECHO,$(A_OPTION_NAME)))
.PHONY: yaml_build_options
yaml_build_options:
@echo '- KEYBOARD : "$(KEYBOARD)"'
@echo ' KEYMAP : "$(KEYMAP)"'
@echo ' MCU : "$(MCU)"'
@echo ' MCU_SERIES : "$(MCU_SERIES)"'
@echo ' PLATFORM : "$(PLATFORM)"'
@echo ' FIRMWARE_FORMAT : "$(FIRMWARE_FORMAT)"'
$(foreach A_OPTION_NAME,$(sort $(BUILD_OPTION_NAMES)),\
$(call YAML_NAME_ECHO,$(A_OPTION_NAME)))
$(foreach A_OPTION_NAME,$(sort $(HARDWARE_OPTION_NAMES)),\
$(if $($(A_OPTION_NAME)),$(call YAML_NAME_ECHO,$(A_OPTION_NAME))))
$(foreach A_OPTION_NAME,$(sort $(OTHER_OPTION_NAMES)),\
$(if $($(A_OPTION_NAME)),$(call YAML_NAME_ECHO,$(A_OPTION_NAME))))

View file

@ -1,11 +0,0 @@
# Helper to determine if a compiler option is supported
# Args:
# $(1) = option to test, if successful will be output
# $(2) = option to use if $(1) is not supported
# $(3) = additional arguments to pass to the compiler during the test, but aren't contained in the output
cc-option = $(shell \
if { echo 'int main(){return 0;}' | $(CC) $(1) $(3) -o /dev/null -x c /dev/null >/dev/null 2>&1; }; \
then echo "$(1)"; else echo "$(2)"; fi)
# Helper to pass comma character to make functions (use with `$(,)` to pass in `$(call ...)` arguments)
, := ,

View file

@ -1,22 +0,0 @@
TEST_LIST = $(sort $(patsubst %/test.mk,%, $(shell find $(ROOT_DIR)tests -type f -name test.mk)))
FULL_TESTS := $(notdir $(TEST_LIST))
include $(QUANTUM_PATH)/debounce/tests/testlist.mk
include $(QUANTUM_PATH)/encoder/tests/testlist.mk
include $(QUANTUM_PATH)/os_detection/tests/testlist.mk
include $(QUANTUM_PATH)/sequencer/tests/testlist.mk
include $(QUANTUM_PATH)/wear_leveling/tests/testlist.mk
include $(PLATFORM_PATH)/test/testlist.mk
define VALIDATE_TEST_LIST
ifneq ($1,)
ifeq ($$(findstring -,$1),-)
$$(call CATASTROPHIC_ERROR,Invalid test name,Test names can't contain '-', but '$1' does.)
else
$$(eval $$(call VALIDATE_TEST_LIST,$$(firstword $2),$$(wordlist 2,9999,$2)))
endif
endif
endef
$(eval $(call VALIDATE_TEST_LIST,$(firstword $(TEST_LIST)),$(wordlist 2,9999,$(TEST_LIST))))

View file

@ -4,7 +4,7 @@ ChibiOS and ChibiOS-Contrib need to be updated in tandem -- the latter has a bra
## Getting ChibiOS ## Getting ChibiOS
* `svn` Initialization: * `svn` Initialisation:
* Only needed to be done once * Only needed to be done once
* You might need to separately install `git-svn` package in your OS's package manager * You might need to separately install `git-svn` package in your OS's package manager
* `git svn init --stdlayout --prefix='svn/' http://svn.osdn.net/svnroot/chibios/` * `git svn init --stdlayout --prefix='svn/' http://svn.osdn.net/svnroot/chibios/`
@ -21,7 +21,7 @@ ChibiOS and ChibiOS-Contrib need to be updated in tandem -- the latter has a bra
## Getting ChibiOS-Contrib ## Getting ChibiOS-Contrib
* `git` Initialization: * `git` Initialisation:
* `git clone git@github.com:qmk/ChibiOS-Contrib` * `git clone git@github.com:qmk/ChibiOS-Contrib`
* `git remote add upstream https://github.com/ChibiOS/ChibiOS-Contrib` * `git remote add upstream https://github.com/ChibiOS/ChibiOS-Contrib`
* `git checkout -b chibios-20.3.x upstream/chibios-20.3.x` * `git checkout -b chibios-20.3.x upstream/chibios-20.3.x`
@ -51,22 +51,9 @@ ChibiOS and ChibiOS-Contrib need to be updated in tandem -- the latter has a bra
* `./util/chibios_conf_updater.sh` * `./util/chibios_conf_updater.sh`
* Build everything * Build everything
* `cd $QMK_FIRMWARE` * `cd $QMK_FIRMWARE`
* `qmk mass-compile -j 4` * `qmk multibuild -j4`
* Make sure there are no errors * Make sure there are no errors
* Push to the repo * Push to the repo
* `git commit -am 'Update ChibiOS to 99.9.9'` * `git commit -am 'Update ChibiOS to 99.9.9'`
* `git push --set-upstream origin chibios-version-bump` * `git push --set-upstream origin chibios-version-bump`
* Make a PR to qmk_firmware with the new branch * Make a PR to qmk_firmware with the new branch
## When merging a PR containing an upgrade of ChibiOS/ChibiOS-Contrib:
* Update the target branch if the merge target was `master`:
* `git checkout qmk-master`
* `git reset --hard develop_YYYY_qN`
* `git push origin qmk-master --force-with-lease`
* Update the target branch if the merge target was `develop`:
* `git checkout qmk-develop`
* `git reset --hard develop_YYYY_qN`
* `git push origin qmk-develop --force-with-lease`
Note that when merging `develop` to `master`, the first workflow should still be followed.

38
cli.md Normal file
View file

@ -0,0 +1,38 @@
# QMK CLI :id=qmk-cli
## Overview :id=overview
The QMK CLI makes building and working with QMK keyboards easier. We have provided a number of commands to simplify and streamline tasks such as obtaining and compiling the QMK firmware, creating keymaps, and more.
### Requirements :id=requirements
QMK requires Python 3.6 or greater. We try to keep the number of requirements small but you will also need to install the packages listed in [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt). These are installed automatically when you install the QMK CLI.
### Install Using Homebrew (macOS, some Linux) :id=install-using-homebrew
If you have installed [Homebrew](https://brew.sh) you can tap and install QMK:
```
brew install qmk/qmk/qmk
export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware`
qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment
```
### Install Using pip :id=install-using-easy_install-or-pip
If your system is not listed above you can install QMK manually. First ensure that you have Python 3.6 (or later) installed and have installed pip. Then install QMK with this command:
```
python3 -m pip install qmk
export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware`
qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment
```
### Packaging For Other Operating Systems :id=packaging-for-other-operating-systems
We are looking for people to create and maintain a `qmk` package for more operating systems. If you would like to create a package for your OS please follow these guidelines:
* Follow best practices for your OS when they conflict with these guidelines
* Document why in a comment when you do deviate
* Install using a virtualenv
* Instruct the user to set the environment variable `QMK_HOME` to have the firmware source checked out somewhere other than `~/qmk_firmware`.

517
cli_commands.md Normal file
View file

@ -0,0 +1,517 @@
# QMK CLI Commands
# User Commands
## `qmk compile`
This command allows you to compile firmware from any directory. You can compile JSON exports from <https://config.qmk.fm>, compile keymaps in the repo, or compile the keyboard in the current working directory.
This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory.
**Usage for Configurator Exports**:
```
qmk compile [-c] <configuratorExport.json>
```
**Usage for Keymaps**:
```
qmk compile [-c] [-e <var>=<value>] [-j <num_jobs>] -kb <keyboard_name> -km <keymap_name>
```
**Usage in Keyboard Directory**:
Must be in keyboard directory with a default keymap, or in keymap directory for keyboard, or supply one with `--keymap <keymap_name>`
```
qmk compile
```
**Usage for building all keyboards that support a specific keymap**:
```
qmk compile -kb all -km <keymap_name>
```
**Example**:
```
$ qmk config compile.keymap=default
$ cd ~/qmk_firmware/keyboards/planck/rev6
$ qmk compile
Ψ Compiling keymap with make planck/rev6:default
...
```
or with optional keymap argument
```
$ cd ~/qmk_firmware/keyboards/clueboard/66/rev4
$ qmk compile -km 66_iso
Ψ Compiling keymap with make clueboard/66/rev4:66_iso
...
```
or in keymap directory
```
$ cd ~/qmk_firmware/keyboards/gh60/satan/keymaps/colemak
$ qmk compile
Ψ Compiling keymap with make gh60/satan:colemak
...
```
**Usage in Layout Directory**:
Must be under `qmk_firmware/layouts/`, and in a keymap folder.
```
qmk compile -kb <keyboard_name>
```
**Example**:
```
$ cd ~/qmk_firmware/layouts/community/60_ansi/mechmerlin-ansi
$ qmk compile -kb dz60
Ψ Compiling keymap with make dz60:mechmerlin-ansi
...
```
**Parallel Compilation**:
It is possible to speed up compilation by adding the `-j`/`--parallel` flag.
```
qmk compile -j <num_jobs> -kb <keyboard_name>
```
The `num_jobs` argument determines the maximum number of jobs that can be used. Setting it to zero will enable parallel compilation without limiting the maximum number of jobs.
```
qmk compile -j 0 -kb <keyboard_name>
```
## `qmk flash`
This command is similar to `qmk compile`, but can also target a bootloader. The bootloader is optional, and is set to `:flash` by default. To specify a different bootloader, use `-bl <bootloader>`. Visit the [Flashing Firmware](flashing.md) guide for more details of the available bootloaders.
This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory.
**Usage for Configurator Exports**:
```
qmk flash [-bl <bootloader>] [-c] [-e <var>=<value>] [-j <num_jobs>] <configuratorExport.json>
```
**Usage for Keymaps**:
```
qmk flash -kb <keyboard_name> -km <keymap_name> [-bl <bootloader>] [-c] [-e <var>=<value>] [-j <num_jobs>]
```
**Listing the Bootloaders**
```
qmk flash -b
```
## `qmk config`
This command lets you configure the behavior of QMK. For the full `qmk config` documentation see [CLI Configuration](cli_configuration.md).
**Usage**:
```
qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN]
```
## `qmk cd`
This command opens a new shell in your `qmk_firmware` directory.
Note that if you are already somewhere within `QMK_HOME` (for example, the `keyboards/` folder), nothing will happen.
To exit out into the parent shell, simply type `exit`.
**Usage**:
```
qmk cd
```
## `qmk console`
This command lets you connect to keyboard consoles to get debugging messages. It only works if your keyboard firmware has been compiled with `CONSOLE_ENABLE=yes`.
**Usage**:
```
qmk console [-d <pid>:<vid>[:<index>]] [-l] [-n] [-t] [-w <seconds>]
```
**Examples**:
Connect to all available keyboards and show their console messages:
```
qmk console
```
List all devices:
```
qmk console -l
```
Show only messages from clueboard/66/rev3 keyboards:
```
qmk console -d C1ED:2370
```
Show only messages from the second clueboard/66/rev3:
```
qmk console -d C1ED:2370:2
```
Show timestamps and VID:PID instead of names:
```
qmk console -n -t
```
Disable bootloader messages:
```
qmk console --no-bootloaders
```
## `qmk doctor`
This command examines your environment and alerts you to potential build or flash problems. It can fix many of them if you want it to.
**Usage**:
```
qmk doctor [-y] [-n]
```
**Examples**:
Check your environment for problems and prompt to fix them:
qmk doctor
Check your environment and automatically fix any problems found:
qmk doctor -y
Check your environment and report problems only:
qmk doctor -n
## `qmk format-json`
Formats a JSON file in a (mostly) human-friendly way. Will usually correctly detect the format of the JSON (info.json or keymap.json) but you can override this with `--format` if neccesary.
**Usage**:
```
qmk format-json [-f FORMAT] <json_file>
```
## `qmk info`
Displays information about keyboards and keymaps in QMK. You can use this to get information about a keyboard, show the layouts, display the underlying key matrix, or to pretty-print JSON keymaps.
**Usage**:
```
qmk info [-f FORMAT] [-m] [-l] [-km KEYMAP] [-kb KEYBOARD]
```
This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory.
**Examples**:
Show basic information for a keyboard:
qmk info -kb planck/rev5
Show the matrix for a keyboard:
qmk info -kb ergodox_ez -m
Show a JSON keymap for a keyboard:
qmk info -kb clueboard/california -km default
## `qmk json2c`
Creates a keymap.c from a QMK Configurator export.
**Usage**:
```
qmk json2c [-o OUTPUT] filename
```
## `qmk c2json`
Creates a keymap.json from a keymap.c.
**Note:** Parsing C source files is not easy, therefore this subcommand may not work with your keymap. In some cases not using the C pre-processor helps.
**Usage**:
```
qmk c2json -km KEYMAP -kb KEYBOARD [-q] [--no-cpp] [-o OUTPUT] filename
```
## `qmk lint`
Checks over a keyboard and/or keymap and highlights common errors, problems, and anti-patterns.
**Usage**:
```
qmk lint [-km KEYMAP] [-kb KEYBOARD] [--strict]
```
This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory.
**Examples**:
Do a basic lint check:
qmk lint -kb rominronin/katana60/rev2
## `qmk list-keyboards`
This command lists all the keyboards currently defined in `qmk_firmware`
**Usage**:
```
qmk list-keyboards
```
## `qmk list-keymaps`
This command lists all the keymaps for a specified keyboard (and revision).
This command is directory aware. It will automatically fill in KEYBOARD if you are in a keyboard directory.
**Usage**:
```
qmk list-keymaps -kb planck/ez
```
## `qmk new-keyboard`
This command creates a new keyboard based on available templates.
Any arguments that are not provided will prompt for input. If `-u` is not passed and `user.name` is set in .gitconfig, it will be used as the default username in the prompt.
**Usage**:
```
qmk new-keyboard [-kb KEYBOARD] [-t {atmega32u4,STM32F303,etc}] [-l {60_ansi,75_iso,etc}] -u USERNAME
```
## `qmk new-keymap`
This command creates a new keymap based on a keyboard's existing default keymap.
This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory.
**Usage**:
```
qmk new-keymap [-kb KEYBOARD] [-km KEYMAP]
```
## `qmk clean`
This command cleans up the `.build` folder. If `--all` is passed, any .hex or .bin files present in the `qmk_firmware` directory will also be deleted.
**Usage**:
```
qmk clean [-a]
```
## `qmk via2json`
This command an generate a keymap.json from a VIA keymap backup. Both the layers and the macros are converted, enabling users to easily move away from a VIA-enabled firmware without writing any code or reimplementing their keymaps in QMK Configurator.
**Usage**:
```
qmk via2json -kb KEYBOARD [-l LAYOUT] [-km KEYMAP] [-o OUTPUT] filename
```
**Example:**
```
$ qmk via2json -kb ai03/polaris -o polaris_keymap.json polaris_via_backup.json
Ψ Wrote keymap to /home/you/qmk_firmware/polaris_keymap.json
```
---
# Developer Commands
## `qmk format-text`
This command formats text files to have proper line endings.
Every text file in the repository needs to have Unix (LF) line ending.
If you are working on **Windows**, you must ensure that line endings are corrected in order to get your PRs merged.
```
qmk format-text
```
## `qmk format-c`
This command formats C code using clang-format.
Run it with no arguments to format all core code that has been changed. Default checks `origin/master` with `git diff`, branch can be changed using `-b <branch_name>`
Run it with `-a` to format all core code, or pass filenames on the command line to run it on specific files.
**Usage for specified files**:
```
qmk format-c [file1] [file2] [...] [fileN]
```
**Usage for all core files**:
```
qmk format-c -a
```
**Usage for only changed files against origin/master**:
```
qmk format-c
```
**Usage for only changed files against branch_name**:
```
qmk format-c -b branch_name
```
## `qmk generate-compilation-database`
**Usage**:
```
qmk generate-compilation-database [-kb KEYBOARD] [-km KEYMAP]
```
Creates a `compile_commands.json` file.
Does your IDE/editor use a language server but doesn't _quite_ find all the necessary include files? Do you hate red squigglies? Do you wish your editor could figure out `#include QMK_KEYBOARD_H`? You might need a [compilation database](https://clang.llvm.org/docs/JSONCompilationDatabase.html)! The qmk tool can build this for you.
This command needs to know which keyboard and keymap to build. It uses the same configuration options as the `qmk compile` command: arguments, current directory, and config files.
**Example:**
```
$ cd ~/qmk_firmware/keyboards/gh60/satan/keymaps/colemak
$ qmk generate-compilation-database
Ψ Making clean
Ψ Gathering build instructions from make -n gh60/satan:colemak
Ψ Found 50 compile commands
Ψ Writing build database to /Users/you/src/qmk_firmware/compile_commands.json
```
Now open your dev environment and live a squiggly-free life.
## `qmk docs`
This command starts a local HTTP server which you can use for browsing or improving the docs. Default port is 8936.
Use the `-b`/`--browser` flag to automatically open the local webserver in your default browser.
This command runs `docsify serve` if `docsify-cli` is installed (which provides live reload), otherwise Python's builtin HTTP server module will be used.
**Usage**:
```
qmk docs [-b] [-p PORT]
```
## `qmk generate-docs`
This command allows you to generate QMK documentation locally. It can be uses for general browsing or improving the docs. External tools such as [serve](https://www.npmjs.com/package/serve) can be used to browse the generated files.
**Usage**:
```
qmk generate-docs
```
## `qmk generate-rgb-breathe-table`
This command generates a lookup table (LUT) header file for the [RGB Lighting](feature_rgblight.md) feature's breathing animation. Place this file in your keyboard or keymap directory as `rgblight_breathe_table.h` to override the default LUT in `quantum/rgblight/`.
**Usage**:
```
qmk generate-rgb-breathe-table [-q] [-o OUTPUT] [-m MAX] [-c CENTER]
```
## `qmk kle2json`
This command allows you to convert from raw KLE data to QMK Configurator JSON. It accepts either an absolute file path, or a file name in the current directory. By default it will not overwrite `info.json` if it is already present. Use the `-f` or `--force` flag to overwrite.
**Usage**:
```
qmk kle2json [-f] <filename>
```
**Examples**:
```
$ qmk kle2json kle.txt
☒ File info.json already exists, use -f or --force to overwrite.
```
```
$ qmk kle2json -f kle.txt -f
Ψ Wrote out to info.json
```
## `qmk format-python`
This command formats python code in `qmk_firmware`.
**Usage**:
```
qmk format-python
```
## `qmk pytest`
This command runs the python test suite. If you make changes to python code you should ensure this runs successfully.
**Usage**:
```
qmk pytest [-t TEST]
```
**Examples**:
Run entire test suite:
qmk pytest
Run test group:
qmk pytest -t qmk.tests.test_cli_commands
Run single test:
qmk pytest -t qmk.tests.test_cli_commands.test_c2json
qmk pytest -t qmk.tests.test_qmk_path

121
cli_configuration.md Normal file
View file

@ -0,0 +1,121 @@
# QMK CLI Configuration
This document explains how `qmk config` works.
# Introduction
Configuration for the QMK CLI is a key/value system. Each key consists of a subcommand and an argument name separated by a period. This allows for a straightforward and direct translation between config keys and the arguments they set.
## Simple Example
As an example let's look at the command `qmk compile --keyboard clueboard/66/rev4 --keymap default`.
There are two command line arguments that could be read from configuration instead:
* `compile.keyboard`
* `compile.keymap`
Let's set these now:
```
$ qmk config compile.keyboard=clueboard/66/rev4 compile.keymap=default
compile.keyboard: None -> clueboard/66/rev4
compile.keymap: None -> default
Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini'
```
Now I can run `qmk compile` without specifying my keyboard and keymap each time.
## Setting User Defaults
Sometimes you want to share a setting between multiple commands. For example, multiple commands take the argument `--keyboard`. Rather than setting this value for every command you can set a user value which will be used by any command that takes that argument.
Example:
```
$ qmk config user.keyboard=clueboard/66/rev4 user.keymap=default
user.keyboard: None -> clueboard/66/rev4
user.keymap: None -> default
Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini'
```
# CLI Documentation (`qmk config`)
The `qmk config` command is used to interact with the underlying configuration. When run with no argument it shows the current configuration. When arguments are supplied they are assumed to be configuration tokens, which are strings containing no spaces with the following form:
<subcommand|general|default>[.<key>][=<value>]
## Setting Configuration Values
You can set configuration values by putting an equal sign (=) into your config key. The key must always be the full `<section>.<key>` form.
Example:
```
$ qmk config default.keymap=default
default.keymap: None -> default
Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini'
```
## Reading Configuration Values
You can read configuration values for the entire configuration, a single key, or for an entire section. You can also specify multiple keys to display more than one value.
### Entire Configuration Example
qmk config
### Whole Section Example
qmk config compile
### Single Key Example
qmk config compile.keyboard
### Multiple Keys Example
qmk config user compile.keyboard compile.keymap
## Deleting Configuration Values
You can delete a configuration value by setting it to the special string `None`.
Example:
```
$ qmk config default.keymap=None
default.keymap: default -> None
Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini'
```
## Multiple Operations
You can combine multiple read and write operations into a single command. They will be executed and displayed in order:
```
$ qmk config compile default.keymap=default compile.keymap=None
compile.keymap=skully
compile.keyboard=clueboard/66_hotswap/gen1
default.keymap: None -> default
compile.keymap: skully -> None
Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini'
```
# User Configuration Options
| Key | Default Value | Description |
|-----|---------------|-------------|
| user.keyboard | None | The keyboard path (Example: `clueboard/66/rev4`) |
| user.keymap | None | The keymap name (Example: `default`) |
| user.name | None | The user's GitHub username. |
# All Configuration Options
| Key | Default Value | Description |
|-----|---------------|-------------|
| compile.keyboard | None | The keyboard path (Example: `clueboard/66/rev4`) |
| compile.keymap | None | The keymap name (Example: `default`) |
| hello.name | None | The name to greet when run. |
| new_keyboard.keyboard | None | The keyboard path (Example: `clueboard/66/rev4`) |
| new_keyboard.keymap | None | The keymap name (Example: `default`) |

219
cli_development.md Normal file
View file

@ -0,0 +1,219 @@
# QMK CLI Development
This document has useful information for developers wishing to write new `qmk` subcommands.
# Overview
The QMK CLI operates using the subcommand pattern made famous by git. The main `qmk` script is simply there to setup the environment and pick the correct entrypoint to run. Each subcommand is a self-contained module with an entrypoint (decorated by `@cli.subcommand()`) that performs some action and returns a shell returncode, or None.
## Developer mode:
If you intend to maintain keyboards and/or contribute to QMK, you can enable the CLI's "Developer" mode:
`qmk config user.developer=True`
This will allow you to see all available subcommands.
**Note:** You will have to install additional requirements:
```
python3 -m pip install -r requirements-dev.txt
```
# Subcommands
[MILC](https://github.com/clueboard/milc) is the CLI framework `qmk` uses to handle argument parsing, configuration, logging, and many other features. It lets you focus on writing your tool without wasting your time writing glue code.
Subcommands in the local CLI are always found in `qmk_firmware/lib/python/qmk/cli`.
Let's start by looking at an example subcommand. This is `lib/python/qmk/cli/hello.py`:
```python
"""QMK Python Hello World
This is an example QMK CLI script.
"""
from milc import cli
@cli.argument('-n', '--name', default='World', help='Name to greet.')
@cli.subcommand('QMK Hello World.')
def hello(cli):
"""Log a friendly greeting.
"""
cli.log.info('Hello, %s!', cli.config.hello.name)
```
First we import the `cli` object from `milc`. This is how we interact with the user and control the script's behavior. We use `@cli.argument()` to define a command line flag, `--name`. This also creates a configuration variable named `hello.name` (and the corresponding `user.name`) which the user can set so they don't have to specify the argument. The `cli.subcommand()` decorator designates this function as a subcommand. The name of the subcommand will be taken from the name of the function.
Once inside our function we find a typical "Hello, World!" program. We use `cli.log` to access the underlying [Logger Object](https://docs.python.org/3.6/library/logging.html#logger-objects), whose behavior is user controllable. We also access the value for name supplied by the user as `cli.config.hello.name`. The value for `cli.config.hello.name` will be determined by looking at the `--name` argument supplied by the user, if not provided it will use the value in the `qmk.ini` config file, and if neither of those is provided it will fall back to the default supplied in the `cli.argument()` decorator.
# User Interaction
MILC and the QMK CLI have several nice tools for interacting with the user. Using these standard tools will allow you to colorize your text for easier interactions, and allow the user to control when and how that information is displayed and stored.
## Printing Text
There are two main methods for outputting text in a subcommand- `cli.log` and `cli.echo()`. They operate in similar ways but you should prefer to use `cli.log.info()` for most general purpose printing.
You can use special tokens to colorize your text, to make it easier to understand the output of your program. See [Colorizing Text](#colorizing-text) below.
Both of these methods support built-in string formatting using python's [printf style string format operations](https://docs.python.org/3.6/library/stdtypes.html#old-string-formatting). You can use tokens such as `%s` and `%d` within your text strings then pass the values as arguments. See our Hello, World program above for an example.
You should never use the format operator (`%`) directly, always pass values as arguments.
### Logging (`cli.log`)
The `cli.log` object gives you access to a [Logger Object](https://docs.python.org/3.6/library/logging.html#logger-objects). We have configured our log output to show the user a nice emoji for each log level (or the log level name if their terminal does not support unicode.) This way the user can tell at a glance which messages are most important when something goes wrong.
The default log level is `INFO`. If the user runs `qmk -v <subcommand>` the default log level will be set to `DEBUG`.
| Function | Emoji |
|----------|-------|
| cli.log.critical | `{bg_red}{fg_white}¬_¬{style_reset_all}` |
| cli.log.error | `{fg_red}☒{style_reset_all}` |
| cli.log.warning | `{fg_yellow}⚠{style_reset_all}` |
| cli.log.info | `{fg_blue}Ψ{style_reset_all}` |
| cli.log.debug | `{fg_cyan}☐{style_reset_all}` |
| cli.log.notset | `{style_reset_all}¯\\_(o_o)_/¯` |
### Printing (`cli.echo`)
Sometimes you simply need to print text outside of the log system. This is appropriate if you are outputting fixed data or writing out something that should never be logged. Most of the time you should prefer `cli.log.info()` over `cli.echo`.
### Colorizing Text
You can colorize the output of your text by including color tokens within text. Use color to highlight, not to convey information. Remember that the user can disable color, and your subcommand should still be usable if they do.
You should generally avoid setting the background color, unless it's integral to what you are doing. Remember that users have a lot of preferences when it comes to their terminal color, so you should pick colors that work well against both black and white backgrounds.
Colors prefixed with 'fg' will affect the foreground (text) color. Colors prefixed with 'bg' will affect the background color.
| Color | Background | Extended Background | Foreground | Extended Foreground|
|-------|------------|---------------------|------------|--------------------|
| Black | {bg_black} | {bg_lightblack_ex} | {fg_black} | {fg_lightblack_ex} |
| Blue | {bg_blue} | {bg_lightblue_ex} | {fg_blue} | {fg_lightblue_ex} |
| Cyan | {bg_cyan} | {bg_lightcyan_ex} | {fg_cyan} | {fg_lightcyan_ex} |
| Green | {bg_green} | {bg_lightgreen_ex} | {fg_green} | {fg_lightgreen_ex} |
| Magenta | {bg_magenta} | {bg_lightmagenta_ex} | {fg_magenta} | {fg_lightmagenta_ex} |
| Red | {bg_red} | {bg_lightred_ex} | {fg_red} | {fg_lightred_ex} |
| White | {bg_white} | {bg_lightwhite_ex} | {fg_white} | {fg_lightwhite_ex} |
| Yellow | {bg_yellow} | {bg_lightyellow_ex} | {fg_yellow} | {fg_lightyellow_ex} |
There are also control sequences that can be used to change the behavior of
ANSI output:
| Control Sequences | Description |
|-------------------|-------------|
| {style_bright} | Make the text brighter |
| {style_dim} | Make the text dimmer |
| {style_normal} | Make the text normal (neither `{style_bright}` nor `{style_dim}`) |
| {style_reset_all} | Reset all text attributes to default. (This is automatically added to the end of every string.) |
| {bg_reset} | Reset the background color to the user's default |
| {fg_reset} | Reset the foreground color to the user's default |
# Arguments and Configuration
QMK handles the details of argument parsing and configuration for you. When you add a new argument it is automatically incorporated into the config tree based on your subcommand's name and the long name of the argument. You can access this configuration in `cli.config`, using either attribute-style access (`cli.config.<subcommand>.<argument>`) or dictionary-style access (`cli.config['<subcommand>']['<argument>']`).
Under the hood QMK uses [ConfigParser](https://docs.python.org/3/library/configparser.html) to store configurations. This gives us an easy and straightforward way to represent the configuration in a human-editable way. We have wrapped access to this configuration to provide some nicities that ConfigParser does not normally have.
## Reading Configuration Values
You can interact with `cli.config` in all the ways you'd normally expect. For example the `qmk compile` command gets the keyboard name from `cli.config.compile.keyboard`. It does not need to know whether that value came from the command line, an environment variable, or the configuration file.
Iteration is also supported:
```
for section in cli.config:
for key in cli.config[section]:
cli.log.info('%s.%s: %s', section, key, cli.config[section][key])
```
## Setting Configuration Values
You can set configuration values in the usual ways.
Dictionary style:
```
cli.config['<section>']['<key>'] = <value>
```
Attribute style:
```
cli.config.<section>.<key> = <value>
```
## Deleting Configuration Values
You can delete configuration values in the usual ways.
Dictionary style:
```
del(cli.config['<section>']['<key>'])
```
Attribute style:
```
del(cli.config.<section>.<key>)
```
## Writing The Configuration File
The configuration is not written out when it is changed. Most commands do not need to do this. We prefer to have the user change their configuration deliberitely using `qmk config`.
You can use `cli.save_config()` to write out the configuration.
## Excluding Arguments From Configuration
Some arguments should not be propagated to the configuration file. These can be excluded by adding `arg_only=True` when creating the argument.
Example:
```
@cli.argument('-o', '--output', arg_only=True, help='File to write to')
@cli.argument('filename', arg_only=True, help='Configurator JSON file')
@cli.subcommand('Create a keymap.c from a QMK Configurator export.')
def json_keymap(cli):
pass
```
You will only be able to access these arguments using `cli.args`. For example:
```
cli.log.info('Reading from %s and writing to %s', cli.args.filename, cli.args.output)
```
# Testing, and Linting, and Formatting (oh my!)
We use nose2, flake8, and yapf to test, lint, and format code. You can use the `pytest` and `format-python` subcommands to run these tests:
### Testing and Linting
qmk pytest
### Formatting
qmk format-python
## Formatting Details
We use [yapf](https://github.com/google/yapf) to automatically format code. Our configuration is in the `[yapf]` section of `setup.cfg`.
?> Tip- Many editors can use yapf as a plugin to automatically format code as you type.
## Testing Details
Our tests can be found in `lib/python/qmk/tests/`. You will find both unit and integration tests in this directory. We hope you will write both unit and integration tests for your code, but if you do not please favor integration tests.
If your PR does not include a comprehensive set of tests please add comments like this to your code so that other people know where they can help:
# TODO(unassigned/<your_github_username>): Write <unit|integration> tests
We use [nose2](https://nose2.readthedocs.io/en/latest/getting_started.html) to run our tests. You can refer to the nose2 documentation for more details on what you can do in your test functions.
## Linting Details
We use flake8 to lint our code. Your code should pass flake8 before you open a PR. This will be checked when you run `qmk pytest` and by CI when you submit a PR.

27
cli_tab_complete.md Normal file
View file

@ -0,0 +1,27 @@
# Tab Completion for QMK
If you are using Bash 4.2 or later, Zsh, or FiSH you can enable Tab Completion for the QMK CLI. This will let you tab complete the names of flags, keyboards, files, and other `qmk` options.
## Setup
There are several ways you can setup tab completion.
### For Your User Only
Add this to the end of your `.profile` or `.bashrc`:
source ~/qmk_firmware/util/qmk_tab_complete.sh
If you put `qmk_firmware` into another location you will need to adjust this path.
### System Wide Symlink
If you want the tab completion available to all users of the system you can add a symlink to the `qmk_tab_complete.sh` script:
ln -s ~/qmk_firmware/util/qmk_tab_complete.sh /etc/profile.d/qmk_tab_complete.sh
### System Wide Copy
In some cases a symlink may not work. Instead you can copy the file directly into place. Be aware that updates to the tab complete script may happen from time to time, you will want to recopy the file periodically.
cp util/qmk_tab_complete.sh /etc/profile.d

58
coding_conventions_c.md Normal file
View file

@ -0,0 +1,58 @@
# Coding Conventions (C)
Most of our style is pretty easy to pick up on, but right now it's not entirely consistent. You should match the style of the code surrounding your change, but if that code is inconsistent or unclear use the following guidelines:
* We indent using four (4) spaces (soft tabs)
* We use a modified One True Brace Style
* Opening Brace: At the end of the same line as the statement that opens the block
* Closing Brace: Lined up with the first character of the statement that opens the block
* Else If: Place the closing brace at the beginning of the line and the next opening brace at the end of the same line.
* Optional Braces: Always include optional braces.
* Good: if (condition) { return false; }
* Bad: if (condition) return false;
* We encourage use of C style comments: `/* */`
* Think of them as a story describing the feature
* Use them liberally to explain why particular decisions were made.
* Do not write obvious comments
* If you're not sure if a comment is obvious, go ahead and include it.
* In general we don't wrap lines, they can be as long as needed. If you do choose to wrap lines please do not wrap any wider than 76 columns.
* We use `#pragma once` at the start of header files rather than old-style include guards (`#ifndef THIS_FILE_H`, `#define THIS_FILE_H`, ..., `#endif`)
* We accept both forms of preprocessor if's: `#ifdef DEFINED` and `#if defined(DEFINED)`
* If you are not sure which to prefer use the `#if defined(DEFINED)` form.
* Do not change existing code from one style to the other, except when moving to a multiple condition `#if`.
* When deciding how (or if) to indent preprocessor directives, keep these points in mind:
* Readability is more important than consistency.
* Follow the file's existing style. If the file is mixed, follow the style that makes sense for the section you are modifying.
* When indenting, keep the hash at the start of the line and add whitespace between `#` and `if`, starting with 4 spaces after the `#`.
* You can follow the indention level of the surrounding C code, or preprocessor directives can have their own indentation levels. Choose the style that best communicates the intent of your code.
Here is an example for easy reference:
```c
/* Enums for foo */
enum foo_state {
FOO_BAR,
FOO_BAZ,
};
/* Returns a value */
int foo(void) {
if (some_condition) {
return FOO_BAR;
} else {
return -1;
}
}
```
# Auto-formatting with clang-format
[Clang-format](https://clang.llvm.org/docs/ClangFormat.html) is part of LLVM and can automatically format your code for you, because ain't nobody got time to do it manually. We supply a configuration file for it that applies most of the coding conventions listed above. It will only change whitespace and newlines, so you will still have to remember to include optional braces yourself.
Use the [full LLVM installer](https://llvm.org/builds/) to get clang-format on Windows, or use `sudo apt install clang-format` on Ubuntu.
If you run it from the command-line, pass `-style=file` as an option and it will automatically find the .clang-format configuration file in the QMK root directory.
If you use VSCode, the standard C/C++ plugin supports clang-format, alternatively there is a [separate extension](https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.ClangFormat) for it.
Some things (like LAYOUT macros) are destroyed by clang-format, so either don't run it on those files, or wrap the sensitive code in `// clang-format off` and `// clang-format on`.

View file

@ -0,0 +1,326 @@
# Coding Conventions (Python)
Most of our style follows PEP8 with some local modifications to make things less nit-picky.
* We target Python 3.7 for compatability with all supported platforms.
* We indent using four (4) spaces (soft tabs)
* We encourage liberal use of comments
* Think of them as a story describing the feature
* Use them liberally to explain why particular decisions were made.
* Do not write obvious comments
* If you're not sure if a comment is obvious, go ahead and include it.
* We require useful docstrings for all functions.
* In general we don't wrap lines, they can be as long as needed. If you do choose to wrap lines please do not wrap any wider than 76 columns.
* Some of our practices conflict with the wider python community to make our codebase more approachable to non-pythonistas.
# YAPF
You can use [yapf](https://github.com/google/yapf) to style your code. We provide a config in [setup.cfg](setup.cfg).
# Imports
We don't have a hard and fast rule for when to use `import ...` vs `from ... import ...`. Understandability and maintainability is our ultimate goal.
Generally we prefer to import specific function and class names from a module to keep code shorter and easier to understand. Sometimes this results in a name that is ambiguous, and in such cases we prefer to import the module instead. You should avoid using the "as" keyword when importing, unless you are importing a compatability module.
Imports should be one line per module. We group import statements together using the standard python rules- system, 3rd party, local.
Do not use `from foo import *`. Supply a list of objects you want to import instead, or import the whole module.
## Import Examples
Good:
```
from qmk import effects
effects.echo()
```
Bad:
```
from qmk.effects import echo
echo() # It's unclear where echo comes from
```
Good:
```
from qmk.keymap import compile_firmware
compile_firmware()
```
OK, but the above is better:
```
import qmk.keymap
qmk.keymap.compile_firmware()
```
# Statements
One statement per line.
Even when allowed (EG `if foo: bar`) we do not combine 2 statements onto a single line.
# Naming
`module_name`, `package_name`, `ClassName`, `method_name`, `ExceptionName`, `function_name`, `GLOBAL_CONSTANT_NAME`, `global_var_name`, `instance_var_name`, `function_parameter_name`, `local_var_name`.
Function names, variable names, and filenames should be descriptive; eschew abbreviation. In particular, do not use abbreviations that are ambiguous or unfamiliar to readers outside your project, and do not abbreviate by deleting letters within a word.
Always use a .py filename extension. Never use dashes.
## Names to Avoid
* single character names except for counters or iterators. You may use `e` as an exception identifier in try/except statements.
* dashes (`-`) in any package/module name
* `__double_leading_and_trailing_underscore__` names (reserved by Python)
# Docstrings
To maintain consistency with our docstrings we've set out the following guidelines.
* Use markdown formatting
* Always use triple-dquote docstrings with at least one linebreak: `"""\n"""`
* First line is a short (< 70 char) description of what the function does
* If you need more in your docstring leave a blank line between the description and the rest.
* Start indented lines at the same indent level as the opening triple-dquote
* Document all function arguments using the format described below
* If present, Args:, Returns:, and Raises: should be the last three things in the docstring, separated by a blank line each.
## Simple docstring example
```
def my_awesome_function():
"""Return the number of seconds since 1970 Jan 1 00:00 UTC.
"""
return int(time.time())
```
## Complex docstring example
```
def my_awesome_function():
"""Return the number of seconds since 1970 Jan 1 00:00 UTC.
This function always returns an integer number of seconds.
"""
return int(time.time())
```
## Function arguments docstring example
```
def my_awesome_function(start=None, offset=0):
"""Return the number of seconds since 1970 Jan 1 00:00 UTC.
This function always returns an integer number of seconds.
Args:
start
The time to start at instead of 1970 Jan 1 00:00 UTC
offset
Return an answer that has this number of seconds subtracted first
Returns:
An integer describing a number of seconds.
Raises:
ValueError
When `start` or `offset` are not positive numbers
"""
if start < 0 or offset < 0:
raise ValueError('start and offset must be positive numbers.')
if not start:
start = time.time()
return int(start - offset)
```
# Exceptions
Exceptions are used to handle exceptional situations. They should not be used for flow control. This is a break from the python norm of "ask for forgiveness." If you are catching an exception it should be to handle a situation that is unusual.
If you use a catch-all exception for any reason you must log the exception and stacktrace using cli.log.
Make your try/except blocks as short as possible. If you need a lot of try statements you may need to restructure your code.
# Tuples
When defining one-item tuples always include a trailing comma so that it is obvious you are using a tuple. Do not rely on implicit one-item tuple unpacking. Better still use a list which is unambiguous.
This is particularly important when using the printf-style format strings that are commonly used.
# Lists and Dictionaries
We have configured YAPF to differentiate between sequence styles with a trailing comma. When a trailing comma is omitted YAPF will format the sequence as a single line. When a trailing comma is included YAPF will format the sequence with one item per line.
You should generally prefer to keep short definition on a single line. Break out to multiple lines sooner rather than later to aid readability and maintainability.
# Parentheses
Avoid excessive parentheses, but do use parentheses to make code easier to understand. Do not use them in return statements unless you are explicitly returning a tuple, or it is part of a math expression.
# Format Strings
We generally prefer printf-style format strings. Example:
```
name = 'World'
print('Hello, %s!' % (name,))
```
This style is used by the logging module, which we make use of extensively, and we have adopted it in other places for consistency. It is also more familiar to C programmers, who are a big part of our casual audience.
Our included CLI module has support for using these without using the percent (%) operator. Look at `cli.echo()` and the various `cli.log` functions (EG, `cli.log.info()`) for more details.
# Comprehensions & Generator Expressions
We encourage the liberal use of comprehensions and generators, but do not let them get too complex. If you need complexity fall back to a for loop that is easier to understand.
# Lambdas
OK to use but probably should be avoided. With comprehensions and generators the need for lambdas is not as strong as it once was.
# Conditional Expressions
OK in variable assignment, but otherwise should be avoided.
Conditional expressions are if statements that are in line with code. For example:
```
x = 1 if cond else 2
```
It's generally not a good idea to use these as function arguments, sequence items, etc. It's too easy to overlook.
# Default Argument Values
Encouraged, but values must be immutable objects.
When specifying default values in argument lists always be careful to specify objects that can't be modified in place. If you use a mutable object the changes you make will persist between calls, which is usually not what you want. Even if that is what you intend to do it is confusing for others and will hinder understanding.
Bad:
```
def my_func(foo={}):
pass
```
Good:
```
def my_func(foo=None):
if not foo:
foo = {}
```
# Properties
Always use properties instead of getter and setter functions.
```
class Foo(object):
def __init__(self):
self._bar = None
@property
def bar(self):
return self._bar
@bar.setter
def bar(self, bar):
self._bar = bar
```
# True/False Evaluations
You should generally prefer the implicit True/False evaluation in if statements, rather than checking equivalency.
Bad:
```
if foo == True:
pass
if bar == False:
pass
```
Good:
```
if foo:
pass
if not bar:
pass
```
# Decorators
Use when appropriate. Try to avoid too much magic unless it helps with understanding.
# Threading and Multiprocessing
Should be avoided. If you need this you will have to make a strong case before we merge your code.
# Power Features
Python is an extremely flexible language and gives you many fancy features such as custom metaclasses, access to bytecode, on-the-fly compilation, dynamic inheritance, object reparenting, import hacks, reflection, modification of system internals, etc.
Don't use these.
Performance is not a critical concern for us, and code understandability is. We want our codebase to be approachable by someone who only has a day or two to play with it. These features generally come with a cost to easy understanding, and we would prefer to have code that can be readily understood over faster or more compact code.
Note that some standard library modules use these techniques and it is ok to make use of those modules. But please keep readability and understandability in mind when using them.
# Type Annotated Code
For now we are not using any type annotation system, and would prefer that code remain unannotated. We may revisit this in the future.
# Function length
Prefer small and focused functions.
We recognize that long functions are sometimes appropriate, so no hard limit is placed on function length. If a function exceeds about 40 lines, think about whether it can be broken up without harming the structure of the program.
Even if your long function works perfectly now, someone modifying it in a few months may add new behavior. This could result in bugs that are hard to find. Keeping your functions short and simple makes it easier for other people to read and modify your code.
You could find long and complicated functions when working with some code. Do not be intimidated by modifying existing code: if working with such a function proves to be difficult, you find that errors are hard to debug, or you want to use a piece of it in several different contexts, consider breaking up the function into smaller and more manageable pieces.
# FIXMEs
It is OK to leave FIXMEs in code. Why? Encouraging people to at least document parts of code that need to be thought out more (or that are confusing) is better than leaving this code undocumented.
All FIXMEs should be formatted like:
```
FIXME(username): Revisit this code when the frob feature is done.
```
...where username is your GitHub username.
# Testing
We use a combination of Integration and Unit testing to ensure that the our code is as bug-free as possible. All the tests can be found in `lib/python/qmk/tests/`. You can run all the tests with `qmk pytest`.
At the time of this writing our tests are not very comprehensive. Looking at the current tests and writing new test cases for untested situations is a great way to both familiarize yourself with the codebase and contribute to QMK.
## Integration Tests
Integration tests can be found in `lib/python/qmk/tests/test_cli_commands.py`. This is where CLI commands are actually run and their overall behavior is verified. We use [`subprocess`](https://docs.python.org/3.6/library/subprocess.html#module-subprocess) to launch each CLI command and a combination of checking output and returncode to determine if the right thing happened.
## Unit Tests
The other `test_*.py` files in `lib/python/qmk/tests/` contain unit tests. You can write tests for individual functions inside `lib/python/qmk/` here. Generally these files are named after the module, with dots replaced by underscores.
At the time of this writing we do not do any mocking for our tests. If you would like to help us change this please [open an issue](https://github.com/qmk/qmk_firmware/issues/new?assignees=&labels=cli%2C+python&template=other_issues.md&title=) or [join #cli on Discord](https://discord.gg/heQPAgy) and start a conversation there.

View file

@ -0,0 +1,73 @@
# Compatible Microcontrollers
QMK runs on any USB-capable AVR or ARM microcontroller with enough flash space - generally 32kB+ for AVR, and 64kB+ for ARM. With significant disabling of features, QMK may *just* squeeze into 16kB AVR MCUs.
## Atmel AVR
The following use [LUFA](https://www.fourwalledcubicle.com/LUFA.php) as the USB stack:
* [ATmega16U2](https://www.microchip.com/wwwproducts/en/ATmega16U2) / [ATmega32U2](https://www.microchip.com/wwwproducts/en/ATmega32U2)
* [ATmega16U4](https://www.microchip.com/wwwproducts/en/ATmega16U4) / [ATmega32U4](https://www.microchip.com/wwwproducts/en/ATmega32U4)
* SparkFun Pro Micro (and clones)
* PJRC Teensy 2.0
* Adafruit Feather 32U4
* [AT90USB64](https://www.microchip.com/wwwproducts/en/AT90USB646) / [AT90USB128](https://www.microchip.com/wwwproducts/en/AT90USB1286)
* PJRC Teensy++ 2.0
* [AT90USB162](https://www.microchip.com/wwwproducts/en/AT90USB162)
Certain MCUs which do not have native USB will use [V-USB](https://www.obdev.at/products/vusb/index.html) instead:
* [ATmega32A](https://www.microchip.com/wwwproducts/en/ATmega32A)
* [ATmega328P](https://www.microchip.com/wwwproducts/en/ATmega328P)
* [ATmega328](https://www.microchip.com/wwwproducts/en/ATmega328)
## ARM
You can also use any ARM chip with USB that [ChibiOS](https://www.chibios.org) supports. Most have plenty of flash. Known to work are:
### STMicroelectronics (STM32)
* [STM32F0x2](https://www.st.com/en/microcontrollers-microprocessors/stm32f0x2.html)
* [STM32F103](https://www.st.com/en/microcontrollers-microprocessors/stm32f103.html)
* Bluepill (with STM32duino bootloader)
* [STM32F303](https://www.st.com/en/microcontrollers-microprocessors/stm32f303.html)
* QMK Proton-C
* [STM32F401](https://www.st.com/en/microcontrollers-microprocessors/stm32f401.html)
* WeAct Blackpill
* [STM32F405](https://www.st.com/en/microcontrollers-microprocessors/stm32f405-415.html)
* [STM32F407](https://www.st.com/en/microcontrollers-microprocessors/stm32f407-417.html)
* [STM32F411](https://www.st.com/en/microcontrollers-microprocessors/stm32f411.html)
* WeAct Blackpill
* [STM32F446](https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html)
* [STM32G431](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x1.html)
* [STM32G474](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x4.html)
* [STM32L412](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
* [STM32L422](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
* [STM32L432](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
* [STM32L433](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html)
* [STM32L442](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
* [STM32L443](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html)
### WestBerryTech (WB32)
* [WB32F3G71xx](http://www.westberrytech.com)
### NXP (Kinetis)
* [MKL26Z64](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/kl-series-cortex-m0-plus/kinetis-kl2x-72-96-mhz-usb-ultra-low-power-microcontrollers-mcus-based-on-arm-cortex-m0-plus-core:KL2x)
* PJRC Teensy LC
* [MK20DX128](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-50-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-based-on-arm-cortex-m4-core:K20_50)
* [MK20DX256](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-72-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-mcus-based-on-arm-cortex-m4-core:K20_72)
* PJRC Teensy 3.2
* [MK66FX1M0](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k6x-ethernet/kinetis-k66-180-mhz-dual-high-speed-full-speed-usbs-2mb-flash-microcontrollers-mcus-based-on-arm-cortex-m4-core:K66_180)
* PJRC Teensy 3.6
## Atmel ATSAM
There is limited support for one of Atmel's ATSAM microcontrollers, that being the [ATSAMD51J18A](https://www.microchip.com/wwwproducts/en/ATSAMD51J18A) used by the [Massdrop keyboards](https://github.com/qmk/qmk_firmware/tree/master/keyboards/massdrop). However, it is not recommended to design a board with this microcontroller as the support is quite specialized to Massdrop hardware.
## RISC-V
### GigaDevice
[ChibiOS-Contrib](https://github.com/ChibiOS/ChibiOS-Contrib) has support for the GigaDevice [GD32VF103 series](https://www.gigadevice.com/products/microcontrollers/gd32/risc-v/mainstream-line/gd32vf103-series/) microcontrollers and provides configurations for the [SiPeed Longan Nano](https://longan.sipeed.com/en/) development board that uses this microcontroller. It is largely pin and feature compatible with STM32F103 and STM32F303 microcontrollers.

478
config_options.md Normal file
View file

@ -0,0 +1,478 @@
# Configuring QMK
QMK is nearly infinitely configurable. Wherever possible we err on the side of allowing users to customize their keyboard, even at the expense of code size. That level of flexibility makes for a daunting configuration experience, however.
There are two main types of configuration files in QMK- `config.h` and `rules.mk`. These files exist at various levels in QMK and all files of the same type are combined to build the final configuration. The levels, from lowest priority to highest priority, are:
* QMK Default
* Keyboard
* Folders (Up to 5 levels deep)
* Keymap
## QMK Default
Every available setting in QMK has a default. If that setting is not set at the Keyboard, Folder, or Keymap level this is the setting that will be used.
## Keyboard
This level contains config options that should apply to the whole keyboard. Some settings won't change in revisions, or most keymaps. Other settings are merely defaults for this keyboard and can be overridden by folders and/or keymaps.
## Folders
Some keyboards have folders and sub-folders to allow for different hardware configurations. Most keyboards only go 1 folder deep, but QMK supports structures up to 5 folders deep. Each folder can have its own `config.h` and `rules.mk` files that are incorporated into the final configuration.
## Keymap
This level contains all of the options for that particular keymap. If you wish to override a previous declaration, you can use `#undef <variable>` to undefine it, where you can then redefine it without an error.
# The `config.h` File
This is a C header file that is one of the first things included, and will persist over the whole project (if included). Lots of variables can be set here and accessed elsewhere. The `config.h` file shouldn't be including other `config.h` files, or anything besides this:
```c
#include "config_common.h"
```
## Hardware Options
* `#define VENDOR_ID 0x1234`
* defines your VID, and for most DIY projects, can be whatever you want
* `#define PRODUCT_ID 0x5678`
* defines your PID, and for most DIY projects, can be whatever you want
* `#define DEVICE_VER 0`
* defines the device version (often used for revisions)
* `#define MANUFACTURER Me`
* generally who/whatever brand produced the board
* `#define PRODUCT Board`
* the name of the keyboard
* `#define MATRIX_ROWS 5`
* the number of rows in your keyboard's matrix
* `#define MATRIX_COLS 15`
* the number of columns in your keyboard's matrix
* `#define MATRIX_ROW_PINS { D0, D5, B5, B6 }`
* pins of the rows, from top to bottom
* may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information.
* `#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }`
* pins of the columns, from left to right
* may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information.
* `#define MATRIX_IO_DELAY 30`
* the delay in microseconds when between changing matrix pin state and reading values
* `#define UNUSED_PINS { D1, D2, D3, B1, B2, B3 }`
* pins unused by the keyboard for reference
* `#define MATRIX_HAS_GHOST`
* define is matrix has ghost (unlikely)
* `#define MATRIX_UNSELECT_DRIVE_HIGH`
* On un-select of matrix pins, rather than setting pins to input-high, sets them to output-high.
* `#define DIODE_DIRECTION COL2ROW`
* COL2ROW or ROW2COL - how your matrix is configured. COL2ROW means the black mark on your diode is facing to the rows, and between the switch and the rows.
* `#define DIRECT_PINS { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }`
* pins mapped to rows and columns, from left to right. Defines a matrix where each switch is connected to a separate pin and ground.
* `#define AUDIO_VOICES`
* turns on the alternate audio voices (to cycle through)
* `#define C4_AUDIO`
* enables audio on pin C4
* Deprecated. Use `#define AUDIO_PIN C4`
* `#define C5_AUDIO`
* enables audio on pin C5
* Deprecated. Use `#define AUDIO_PIN C5`
* `#define C6_AUDIO`
* enables audio on pin C6
* Deprecated. Use `#define AUDIO_PIN C6`
* `#define B5_AUDIO`
* enables audio on pin B5 (duophony is enabled if one of B pins is enabled along with one of C pins)
* Deprecated. Use `#define AUDIO_PIN B5`, or use `#define AUDIO_PIN_ALT B5` if a `C` pin is enabled with `AUDIO_PIN`
* `#define B6_AUDIO`
* enables audio on pin B6 (duophony is enabled if one of B pins is enabled along with one of C pins)
* Deprecated. Use `#define AUDIO_PIN B6`, or use `#define AUDIO_PIN_ALT B6` if a `C` pin is enabled with `AUDIO_PIN`
* `#define B7_AUDIO`
* enables audio on pin B7 (duophony is enabled if one of B pins is enabled along with one of C pins)
* Deprecated. Use `#define AUDIO_PIN B7`, or use `#define AUDIO_PIN_ALT B7` if a `C` pin is enabled with `AUDIO_PIN`
* `#define BACKLIGHT_PIN B7`
* pin of the backlight
* `#define BACKLIGHT_LEVELS 3`
* number of levels your backlight will have (maximum 31 excluding off)
* `#define BACKLIGHT_BREATHING`
* enables backlight breathing
* `#define BREATHING_PERIOD 6`
* the length of one backlight "breath" in seconds
* `#define DEBOUNCE 5`
* the delay when reading the value of the pin (5 is default)
* `#define LOCKING_SUPPORT_ENABLE`
* mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap
* `#define LOCKING_RESYNC_ENABLE`
* tries to keep switch state consistent with keyboard LED state
* `#define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT)`
* key combination that allows the use of magic commands (useful for debugging)
* `#define USB_MAX_POWER_CONSUMPTION 500`
* sets the maximum power (in mA) over USB for the device (default: 500)
* `#define USB_POLLING_INTERVAL_MS 10`
* sets the USB polling rate in milliseconds for the keyboard, mouse, and shared (NKRO/media keys) interfaces
* `#define USB_SUSPEND_WAKEUP_DELAY 200`
* set the number of milliseconde to pause after sending a wakeup packet
* `#define F_SCL 100000L`
* sets the I2C clock rate speed for keyboards using I2C. The default is `400000L`, except for keyboards using `split_common`, where the default is `100000L`.
## Features That Can Be Disabled
If you define these options you will disable the associated feature, which can save on code size.
* `#define NO_DEBUG`
* disable debugging
* `#define NO_PRINT`
* disable printing/debugging using hid_listen
* `#define NO_ACTION_LAYER`
* disable layers
* `#define NO_ACTION_TAPPING`
* disable tap dance and other tapping features
* `#define NO_ACTION_ONESHOT`
* disable one-shot modifiers
## Features That Can Be Enabled
If you define these options you will enable the associated feature, which may increase your code size.
* `#define FORCE_NKRO`
* NKRO by default requires to be turned on, this forces it on during keyboard startup regardless of EEPROM setting. NKRO can still be turned off but will be turned on again if the keyboard reboots.
* `#define STRICT_LAYER_RELEASE`
* force a key release to be evaluated using the current layer stack instead of remembering which layer it came from (used for advanced cases)
## Behaviors That Can Be Configured
* `#define TAPPING_TERM 200`
* how long before a tap becomes a hold, if set above 500, a key tapped during the tapping term will turn it into a hold too
* `#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
* See [Retro Tapping](tap_hold.md#retro-tapping) for details
* `#define RETRO_TAPPING_PER_KEY`
* enables handling for per key `RETRO_TAPPING` settings
* `#define TAPPING_TOGGLE 2`
* how many taps before triggering the toggle
* `#define PERMISSIVE_HOLD`
* makes tap and hold keys trigger the hold if another key is pressed before releasing, even if it hasn't hit the `TAPPING_TERM`
* 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 IGNORE_MOD_TAP_INTERRUPT_PER_KEY`
* enables handling for per key `IGNORE_MOD_TAP_INTERRUPT` settings
* `#define TAPPING_FORCE_HOLD`
* makes it possible to use a dual role key as modifier shortly after having been tapped
* See [Tapping Force Hold](tap_hold.md#tapping-force-hold)
* Breaks any Tap Toggle functionality (`TT` or the One Shot Tap Toggle)
* `#define TAPPING_FORCE_HOLD_PER_KEY`
* enables handling for per key `TAPPING_FORCE_HOLD` settings
* `#define LEADER_TIMEOUT 300`
* how long before the leader key times out
* If you're having issues finishing the sequence before it times out, you may need to increase the timeout setting. Or you may want to enable the `LEADER_PER_KEY_TIMING` option, which resets the timeout after each key is tapped.
* `#define LEADER_PER_KEY_TIMING`
* sets the timer for leader key chords to run on each key press rather than overall
* `#define LEADER_KEY_STRICT_KEY_PROCESSING`
* Disables keycode filtering for Mod-Tap and Layer-Tap keycodes. Eg, if you enable this, you would need to specify `MT(MOD_CTL, KC_A)` if you want to use `KC_A`.
* `#define ONESHOT_TIMEOUT 300`
* how long before oneshot times out
* `#define ONESHOT_TAP_TOGGLE 2`
* how many taps before oneshot toggle is triggered
* `#define QMK_KEYS_PER_SCAN 4`
* Allows sending more than one key per scan. By default, only one key event gets
sent via `process_record()` per scan. This has little impact on most typing, but
if you're doing a lot of chords, or your scan rate is slow to begin with, you can
have some delay in processing key events. Each press and release is a separate
event. For a keyboard with 1ms or so scan times, even a very fast typist isn't
going to produce the 500 keystrokes a second needed to actually get more than a
few ms of delay from this. But if you're doing chording on something with 3-4ms
scan times? You probably want this.
* `#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`
* Flag for enabling extending timeout on Combos containing modifers
* `#define COMBO_MOD_TERM 200`
* Allows for extending COMBO_TERM for mod keys while mid-combo.
* `#define COMBO_MUST_HOLD_PER_COMBO`
* Flag to enable per-combo COMBO_TERM extension and `get_combo_must_hold()` function
* `#define COMBO_TERM_PER_COMBO`
* Flag to enable per-combo COMBO_TERM extension and `get_combo_term()` function
* `#define COMBO_STRICT_TIMER`
* Only start the combo timer on the first key press instead of on all key presses.
* `#define COMBO_NO_TIMER`
* Disable the combo timer completely for relaxed combos.
* `#define TAP_CODE_DELAY 100`
* Sets the delay between `register_code` and `unregister_code`, if you're having issues with it registering properly (common on VUSB boards). The value is in milliseconds.
* `#define TAP_HOLD_CAPS_DELAY 80`
* Sets the delay for Tap Hold keys (`LT`, `MT`) when using `KC_CAPS_LOCK` keycode, as this has some special handling on MacOS. The value is in milliseconds, and defaults to 80 ms if not defined. For macOS, you may want to set this to 200 or higher.
* `#define KEY_OVERRIDE_REPEAT_DELAY 500`
* Sets the key repeat interval for [key overrides](feature_key_overrides.md).
## RGB Light Configuration
* `#define RGB_DI_PIN D7`
* pin the DI on the WS2812 is hooked-up to
* `#define RGBLIGHT_ANIMATIONS`
* run RGB animations
* `#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.
* `#define RGBLIGHT_MAX_LAYERS`
* Defaults to 8. Can be expanded up to 32 if more [lighting layers](feature_rgblight.md?id=lighting-layers) are needed.
* Note: Increasing the maximum will increase the firmware size and slow sync on split keyboards.
* `#define RGBLIGHT_LAYER_BLINK`
* Adds ability to [blink](feature_rgblight.md?id=lighting-layer-blink) a lighting layer for a specified number of milliseconds (e.g. to acknowledge an action).
* `#define RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF`
* If defined, then [lighting layers](feature_rgblight?id=overriding-rgb-lighting-onoff-status) will be shown even if RGB Light is off.
* `#define RGBLED_NUM 12`
* number of LEDs
* `#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 `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`
* units to step when in/decreasing hue
* `#define RGBLIGHT_SAT_STEP 25`
* units to step when in/decreasing saturation
* `#define RGBLIGHT_VAL_STEP 12`
* units to step when in/decreasing value (brightness)
* `#define RGBW`
* Enables RGBW LED support
## Mouse Key Options
* `#define MOUSEKEY_INTERVAL 20`
* `#define MOUSEKEY_DELAY 0`
* `#define MOUSEKEY_TIME_TO_MAX 60`
* `#define MOUSEKEY_MAX_SPEED 7`
* `#define MOUSEKEY_WHEEL_DELAY 0`
## Split Keyboard Options
Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk
* `SPLIT_TRANSPORT = custom`
* Allows replacing the standard split communication routines with a custom one. ARM based split keyboards must use this at present.
### Setting Handedness
One thing to remember, the side that the USB port is plugged into is always the master half. The side not plugged into USB is the slave.
There are a few different ways to set handedness for split keyboards (listed in order of precedence):
1. Set `SPLIT_HAND_PIN`: Reads a pin to determine handedness. If pin is high, it's the left side, if low, the half is determined to be the right side
2. Set `EE_HANDS` and flash `eeprom-lefthand.eep`/`eeprom-righthand.eep` to each half
* For boards with DFU bootloader you can use `:dfu-split-left`/`:dfu-split-right` to flash these EEPROM files
* For boards with Caterina bootloader (like stock Pro Micros), use `:avrdude-split-left`/`:avrdude-split-right`
* For boards with ARM DFU bootloader (like Proton C), use `:dfu-util-split-left`/`:dfu-util-split-right`
3. Set `MASTER_RIGHT`: Half that is plugged into the USB port is determined to be the master and right half (inverse of the default)
4. Default: The side that is plugged into the USB port is the master half and is assumed to be the left half. The slave side is the right half
#### Defines for handedness
* `#define SPLIT_HAND_PIN B7`
* For using high/low pin to determine handedness, low = right hand, high = left hand. Replace `B7` with the pin you are using. This is optional, and if you leave `SPLIT_HAND_PIN` undefined, then you can still use the EE_HANDS method or MASTER_LEFT / MASTER_RIGHT defines like the stock Let's Split uses.
* `#define SPLIT_HAND_MATRIX_GRID <out_pin>,<in_pin>`
* The handedness is determined by using the intersection of the keyswitches in the key matrix, which does not exist. Normally, when this intersection is shorted (level low), it is considered left. If you define `#define SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT`, it is determined to be right when the level is low.
* `#define EE_HANDS` (only works if `SPLIT_HAND_PIN` and `SPLIT_HAND_MATRIX_GRID` are not defined)
* Reads the handedness value stored in the EEPROM after `eeprom-lefthand.eep`/`eeprom-righthand.eep` has been flashed to their respective halves.
* `#define MASTER_RIGHT`
* Master half is defined to be the right half.
### Other Options
* `#define USE_I2C`
* For using I2C instead of Serial (default is serial; serial transport is supported on ARM -- I2C is AVR-only)
* `#define SOFT_SERIAL_PIN D0`
* When using serial, define this. `D0` or `D1`,`D2`,`D3`,`E6`.
* `#define MATRIX_ROW_PINS_RIGHT { <row pins> }`
* `#define MATRIX_COL_PINS_RIGHT { <col pins> }`
* If you want to specify a different pinout for the right half than the left half, you can define `MATRIX_ROW_PINS_RIGHT`/`MATRIX_COL_PINS_RIGHT`. Currently, the size of `MATRIX_ROW_PINS` must be the same as `MATRIX_ROW_PINS_RIGHT` and likewise for the definition of columns.
* may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information.
* `#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }`
* If you want to specify a different direct pinout for the right half than the left half, you can define `DIRECT_PINS_RIGHT`. Currently, the size of `DIRECT_PINS` must be the same as `DIRECT_PINS_RIGHT`.
* `#define RGBLED_SPLIT { 6, 6 }`
* See [RGB Light Configuration](#rgb-light-configuration)
* `#define SELECT_SOFT_SERIAL_SPEED <speed>` (default speed is 1)
* Sets the protocol speed when using serial communication
* Speeds:
* 0: about 189kbps (Experimental only)
* 1: about 137kbps (default)
* 2: about 75kbps
* 3: about 39kbps
* 4: about 26kbps
* 5: about 20kbps
* `#define SPLIT_USB_DETECT`
* Detect (with timeout) USB connection when delegating master/slave
* Default behavior for ARM
* Required for AVR Teensy (without hardware mods)
* `#define SPLIT_USB_TIMEOUT 2000`
* Maximum timeout when detecting master/slave when using `SPLIT_USB_DETECT`
* `#define SPLIT_USB_TIMEOUT_POLL 10`
* Poll frequency when detecting master/slave when using `SPLIT_USB_DETECT`
* `#define FORCED_SYNC_THROTTLE_MS 100`
* Deadline for synchronizing data from master to slave when using the QMK-provided split transport.
* `#define SPLIT_TRANSPORT_MIRROR`
* Mirrors the master-side matrix on the slave when using the QMK-provided split transport.
* `#define SPLIT_LAYER_STATE_ENABLE`
* Ensures the current layer state is available on the slave when using the QMK-provided split transport.
* `#define SPLIT_LED_STATE_ENABLE`
* Ensures the current host indicator state (caps/num/scroll) is available on the slave when using the QMK-provided split transport.
* `#define SPLIT_MODS_ENABLE`
* Ensures the current modifier state (normal, weak, and oneshot) is available on the slave when using the QMK-provided split transport.
* `#define SPLIT_WPM_ENABLE`
* Ensures the current WPM is available on the slave when using the QMK-provided split transport.
* `#define SPLIT_OLED_ENABLE`
* Syncs the on/off state of the OLED between the halves.
* `#define SPLIT_ST7565_ENABLE`
* Syncs the on/off state of the ST7565 screen between the halves.
* `#define SPLIT_TRANSACTION_IDS_KB .....`
* `#define SPLIT_TRANSACTION_IDS_USER .....`
* Allows for custom data sync with the slave when using the QMK-provided split transport. See [custom data sync between sides](feature_split_keyboard.md#custom-data-sync) for more information.
# The `rules.mk` File
This is a [make](https://www.gnu.org/software/make/manual/make.html) file that is included by the top-level `Makefile`. It is used to set some information about the MCU that we will be compiling for as well as enabling and disabling certain features.
## Build Options
* `DEFAULT_FOLDER`
* Used to specify a default folder when a keyboard has more than one sub-folder.
* `FIRMWARE_FORMAT`
* Defines which format (bin, hex) is copied to the root `qmk_firmware` folder after building.
* `SRC`
* Used to add files to the compilation/linking list.
* `LIB_SRC`
* Used to add files as a library to the compilation/linking list.
The files specified by `LIB_SRC` is linked after the files specified by `SRC`.
For example, if you specify:
```
SRC += a.c
LIB_SRC += lib_b.c
SRC += c.c
LIB_SRC += lib_d.c
```
The link order is as follows.
```
... a.o c.o ... lib_b.a lib_d.a ...
```
* `LAYOUTS`
* A list of [layouts](feature_layouts.md) this keyboard supports.
* `LTO_ENABLE`
* Enables Link Time Optimization (LTO) when compiling the keyboard. This makes the process take longer, but it can significantly reduce the compiled size (and since the firmware is small, the added time is not noticeable).
## AVR MCU Options
* `MCU = atmega32u4`
* `F_CPU = 16000000`
* `ARCH = AVR8`
* `F_USB = $(F_CPU)`
* `OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT`
* `BOOTLOADER = atmel-dfu` with the following options:
* `atmel-dfu`
* `lufa-dfu`
* `qmk-dfu`
* `halfkay`
* `caterina`
* `bootloadhid`
* `usbasploader`
## Feature Options :id=feature-options
Use these to enable or disable building certain features. The more you have enabled the bigger your firmware will be, and you run the risk of building a firmware too large for your MCU.
* `MAGIC_ENABLE`
* MAGIC actions (BOOTMAGIC without the boot)
* `BOOTMAGIC_ENABLE`
* Enable Bootmagic Lite
* `MOUSEKEY_ENABLE`
* Mouse keys
* `EXTRAKEY_ENABLE`
* Audio control and System control
* `CONSOLE_ENABLE`
* Console for debug
* `COMMAND_ENABLE`
* Commands for debug and configuration
* `COMBO_ENABLE`
* Key combo feature
* `NKRO_ENABLE`
* USB N-Key Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
* `RING_BUFFERED_6KRO_REPORT_ENABLE`
* USB 6-Key Rollover - Instead of stopping any new input once 6 keys are pressed, the oldest key is released and the new key is pressed.
* `AUDIO_ENABLE`
* Enable the audio subsystem.
* `KEY_OVERRIDE_ENABLE`
* Enable the key override feature
* `RGBLIGHT_ENABLE`
* Enable keyboard underlight functionality
* `LEADER_ENABLE`
* Enable leader key chording
* `MIDI_ENABLE`
* MIDI controls
* `UNICODE_ENABLE`
* Unicode
* `BLUETOOTH_ENABLE`
* Current options are BluefruitLE, RN42
* `SPLIT_KEYBOARD`
* Enables split keyboard support (dual MCU like the let's split and bakingpy's boards) and includes all necessary files located at quantum/split_common
* `CUSTOM_MATRIX`
* Allows replacing the standard matrix scanning routine with a custom one.
* `DEBOUNCE_TYPE`
* Allows replacing the standard key debouncing routine with an alternative or custom one.
* `WAIT_FOR_USB`
* Forces the keyboard to wait for a USB connection to be established before it starts up
* `NO_USB_STARTUP_CHECK`
* Disables usb suspend check after keyboard startup. Usually the keyboard waits for the host to wake it up before any tasks are performed. This is useful for split keyboards as one half will not get a wakeup call but must send commands to the master.
* `DEFERRED_EXEC_ENABLE`
* Enables deferred executor support -- timed delays before callbacks are invoked. See [deferred execution](custom_quantum_functions.md#deferred-execution) for more information.
* `DYNAMIC_TAPPING_TERM_ENABLE`
* Allows to configure the global tapping term on the fly.
## USB Endpoint Limitations
In order to provide services over USB, QMK has to use USB endpoints.
These are a finite resource: each microcontroller has only a certain number.
This limits what features can be enabled together.
If the available endpoints are exceeded, a build error is thrown.
The following features can require separate endpoints:
* `MOUSEKEY_ENABLE`
* `EXTRAKEY_ENABLE`
* `CONSOLE_ENABLE`
* `NKRO_ENABLE`
* `MIDI_ENABLE`
* `RAW_ENABLE`
* `VIRTSER_ENABLE`
In order to improve utilisation of the endpoints, the HID features can be combined to use a single endpoint.
By default, `MOUSEKEY`, `EXTRAKEY`, and `NKRO` are combined into a single endpoint.
The base keyboard functionality can also be combined into the endpoint,
by setting `KEYBOARD_SHARED_EP = yes`.
This frees up one more endpoint,
but it can prevent the keyboard working in some BIOSes,
as they do not implement Boot Keyboard protocol switching.
Combining the mouse also breaks Boot Mouse compatibility.
The mouse can be uncombined by setting `MOUSE_SHARED_EP = no` if this functionality is required.

View file

@ -0,0 +1,193 @@
# Adding Default Keymaps to QMK Configurator :id=adding-default-keymaps
This page covers how to add a default keymap for a keyboard to QMK Configurator.
## Technical Information :id=technical-information
QMK Configurator uses JSON as its native file format for keymaps. As much as possible, these should be kept such that they behave the same as running `make <keyboard>:default` from `qmk_firmware`.
Keymaps in this directory require four key-value pairs:
* `keyboard` (string)
* This is the name of the keyboard, the same as would be used when running a compile job through `make` (e.g. `make 1upkeyboards/1up60rgb:default`).
* `keymap` (string)
* Should be set to `default`.
* `layout` (string)
* This is the layout macro used by the default keymap.
* `layers` (array)
* The keymap itself. This key should contain one array per layer, which themselves should contain the keycodes that make up that layer.
Additionally, most keymaps contain a `commit` key. This key is not consumed by the API that back-stops QMK Configurator, but is used by Configurator's maintainers to tell which version of a keymap was used to create the JSON keymap in this repository. The value is the SHA of the last commit to modify a board's default `keymap.c` in the `qmk_firmware` repository. The SHA is found by checking out [the `master` branch of the `qmk/qmk_firmware` repository](https://github.com/qmk/qmk_firmware/tree/master/) and running `git log -1 --pretty=oneline -- keyboards/<keyboard>/keymaps/default/keymap.c` (use `keymap.json` if the keyboard in question has this file instead), which should return something similar to:
```
f14629ed1cd7c7ec9089604d64f29a99981558e8 Remove/migrate action_get_macro()s from default keymaps (#5625)
```
In this example, `f14629ed1cd7c7ec9089604d64f29a99981558e8` is the value that should be used for `commit`.
## Example :id=example
If one wished to add a default keymap for the H87a by Hineybush, one would run the `git log` command above against the H87a's default keymap in `qmk_firmware`:
```
user ~/qmk_firmware (master)
$ git log -1 --pretty=oneline master -- keyboards/hineybush/h87a/keymaps/default/keymap.c
ef8878fba5d3786e3f9c66436da63a560cd36ac9 Hineybush h87a lock indicators (#8237)
```
Now that we have the commit hash, we need the keymap (edited for readability):
```c
...
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_all(
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SCRL, KC_PAUS,
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_BSPC, KC_INS, KC_HOME, KC_PGUP,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN,
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_ENT,
KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_TRNS, KC_UP,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RGUI, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
[1] = LAYOUT_all(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, BL_TOGG, BL_DEC, BL_INC,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_MNXT, KC_VOLD,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
};
```
The default keymap uses the `LAYOUT_all` macro, so that will be the value of the `layout` key. Compiled to a QMK Configurator JSON keymap, our resulting file should be:
```json
{
"keyboard": "hineybush/h87a",
"keymap": "default",
"commit": "ef8878fba5d3786e3f9c66436da63a560cd36ac9",
"layout": "LAYOUT_all",
"layers": [
[
"KC_ESC", "KC_F1", "KC_F2", "KC_F3", "KC_F4", "KC_F5", "KC_F6", "KC_F7", "KC_F8", "KC_F9", "KC_F10", "KC_F11", "KC_F12", "KC_PSCR", "KC_SCRL", "KC_PAUS",
"KC_GRV", "KC_1", "KC_2", "KC_3", "KC_4", "KC_5", "KC_6", "KC_7", "KC_8", "KC_9", "KC_0", "KC_MINS", "KC_EQL", "KC_BSPC", "KC_BSPC", "KC_INS", "KC_HOME", "KC_PGUP",
"KC_TAB", "KC_Q", "KC_W", "KC_E", "KC_R", "KC_T", "KC_Y", "KC_U", "KC_I", "KC_O", "KC_P", "KC_LBRC", "KC_RBRC", "KC_BSLS", "KC_DEL", "KC_END", "KC_PGDN",
"KC_CAPS", "KC_A", "KC_S", "KC_D", "KC_F", "KC_G", "KC_H", "KC_J", "KC_K", "KC_L", "KC_SCLN", "KC_QUOT", "KC_NUHS", "KC_ENT",
"KC_LSFT", "KC_NUBS", "KC_Z", "KC_X", "KC_C", "KC_V", "KC_B", "KC_N", "KC_M", "KC_COMM", "KC_DOT", "KC_SLSH", "KC_RSFT", "KC_TRNS", "KC_UP",
"KC_LCTL", "KC_LGUI", "KC_LALT", "KC_SPC", "KC_RALT", "MO(1)", "KC_RGUI", "KC_RCTL", "KC_LEFT", "KC_DOWN", "KC_RGHT"
],
[
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "RGB_TOG", "RGB_MOD", "RGB_HUD", "RGB_HUI", "RGB_SAD", "RGB_SAI", "RGB_VAD", "RGB_VAI", "BL_TOGG", "BL_DEC", "BL_INC",
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_VOLU",
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "RESET", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_MPLY", "KC_MNXT", "KC_VOLD",
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS"
]
]
}
```
The white space in the `layers` arrays have no effect on the functionality of the keymap, but are used to make these files easier for humans to read.
## Caveats :id=caveats
### Layers can only be referenced by number :id=layer-references
A common QMK convention is to name layers using a series of `#define`s, or an `enum` statement:
```c
enum layer_names {
_BASE,
_MEDIA,
_FN
};
```
This works in C, but for Configurator, you *must* use the layer's numeric index `MO(_FN)` would need to be `MO(2)` in the above example.
### No support for custom code of any kind :id=custom-code
Features that require adding functions to the keymap.c file, such as Tap Dance or Unicode, can not be compiled in Configurator **at all**. Even setting `TAP_DANCE_ENABLE = yes` in the `qmk_firmware` repository at the keyboard level will prevent Configurator from compiling **any** firmware for that keyboard. This is limited both by the API and the current spec of our JSON keymap format.
### Limited Support for Custom keycodes :id=custom-keycodes
There is a way to support custom keycodes: if the logic for a custom keycode is implemented at the keyboard level instead of the keymap level in qmk_firmware, that keycode *can* be used in Configurator and it *will* compile and work. Instead of using the following in your `keymap.c`:
```c
enum custom_keycodes {
MACRO_1 = SAFE_RANGE,
MACRO_2,
MACRO_3
};
...
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch(keycode) {
case MACRO_1:
if (record->event.pressed) {
SEND_STRING("This is macro #1.");
}
return false;
case MACRO_2:
if (record->event.pressed) {
SEND_STRING("This is macro #2.");
}
return false;
case MACRO_3:
if (record->event.pressed) {
SEND_STRING("This is macro #3.");
}
return false;
}
return true;
};
```
... add the keycode `enum` block to your keyboard's header file (`<keyboard>.h`) as follows (note that the `enum` is named `keyboard_keycodes` here):
```c
enum keyboard_keycodes {
MACRO_1 = SAFE_RANGE,
MACRO_2,
MACRO_3,
NEW_SAFE_RANGE // Important!
};
```
... then the logic to your `<keyboard>.c` through `process_record_kb()`:
```c
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
switch(keycode) {
case MACRO_1:
if (record->event.pressed) {
SEND_STRING("This is macro #1.");
}
return false;
case MACRO_2:
if (record->event.pressed) {
SEND_STRING("This is macro #2.");
}
return false;
case MACRO_3:
if (record->event.pressed) {
SEND_STRING("This is macro #3.");
}
return false;
}
return process_record_user(keycode, record);
};
```
Note the call to `process_record_user()` at the end. Additionally, users of the keyboard will need to use `NEW_SAFE_RANGE` instead of `SAFE_RANGE` if they wish to add their own custom keycodes at keymap level, beyond what is provided by the keyboard.
## Additional Reading :id=additional-reading
For QMK Configurator to support your keyboard, your keyboard must be present in the `master` branch of the `qmk_firmware` repository. For instructions on this, please see [Supporting Your Keyboard in QMK Configurator](reference_configurator_support.md).

View file

@ -1 +1 @@
<mxfile host="Electron" modified="2021-08-09T19:46:29.036Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/14.6.13 Chrome/89.0.4389.128 Electron/12.0.7 Safari/537.36" etag="PQ2r34UrZa0TfW4Fw0EV" version="14.6.13" type="device"><diagram id="NEtccoSKIy4HskWlhJpu" name="Page-1">5VvbcqM4EP2a1O4+hOLqy2Ni5zKX1CTxzszOU0oG2dZEIBZEYu/XbwuEDQg7csZ2vFlXjQca0RLdR+eohXPiDML5VYLi2Q0LMD2xzWB+4gxPbNvqezb8JywLaTFtr7BMExJI28owIv/gsqG0ZiTAaa0hZ4xyEteNPosi7POaDSUJe643mzBa7zVGU6wYRj6iqvU7CfissPY8c2W/xmQ6K3u2THklRGVjaUhnKGDPFZNzceIMEsZ4cRTOB5iK6JVxKe67XHN1ObAER1znhgfT76Zzxxp3Z49j5+7zjw/z+NSS+XlCNJNPLEfLF2UIcAARkacs4TM2ZRGiFyvrecKyKMCiHxPOVm0+MxaD0QLjT8z5QqYXZZyBacZDKq/iKDgTyYLTiEW4sFwSSqXLAKWz3L9orD64jEXKssTHG57WlQBCyRTzTVGRDsWTV3qQcb3CLMQ8WUCDBFPEyVMdK0hCbrpst8oKHMjEbJEk9+UckTDHcTWm0jQk4RR6pWQM3z4l8QNKuDhkYZxxnKRw/J0ljymHJ2HRg2X35vDPiKPp2kA/4YTj+cbIyKunjmv0zMpHeljSQXH6XJla0jSrzKrStvPIei9Hdgm9HNoZpyTCgyXZmPWYI0qmERz7EDGcgIGiMaa3LCUittULIoQEaOZzo8GYcc7CSoMz6ZKLqXQOJBKLgYXzqSBc4xmPKcy11JgSPsvG0GLCIn6JQkJFiK8xfcLCjbwgJyDM+uJ8wChL8ud0ivSILnjCHnHblQlMyIp9kn/ADkMJCK55G14OL4YXmybrFhhyOzXQtKEGdMVwVeBUzDvHTjmKjdS54jWfojQlfpP3YCR/CRwZXnn6o3ptOJcgK84W8gwma8JVz7lZ0qZVI9Ff401PkzddTdqsJM5rme6lTZtdZQ+3jMCTLXFjlRkqyaZJI8Vzy7uqytl01Gk4chqOisAojnJYLR/7F5BWTpkV0gZUTDjgbnOUxTEorqCosxO7QyGG5+MEjqbiaDBLoPsTGzo2L0mCJ2yuNhri9FHQi21+iehCAfHzjHA8ilEOkWegnTqGm0QVkiDIVwU5950j/3Garw9Kdsjd7YYZlmurkhlUYrDNFoB19qUnltPCCUW40xhFZcBnnIvl65noTChxNCFT4+/w0ZiEZXOwV+9Qk9bmd0SiKYTeNm+F9AM2RKTX3tno4iN6QiM/IbFYHXz7eqHeOJI8AeM2YbTQDL4fiuFnCeIs0RvmNUt54eWqUK1iwOnaZ28Asr7cfC0894E/q2PYehDs7w2CGqtFdbndqklVRaoI1BpN2tEaXVdryql2JGKzTKiEgvdasXHchqNDi01XAz/vpiK0tOHW0YTbYUpC6/1ULj9TuH0XlWZ93riOuhjotsz/rmf09pWkjpKkuvI/4sWYoSRIG+K/ks9PsgV4ucEcBYgjXV2ekCR8hoiq7a+uoeGZX+RN3PQ1BsdiwXB2+wG+h629rFR7SKDaRPSLj4VIm7n2ptsuG2voPKRIu7Zt9N9apHtbiXRr7VirASVHVgtAc4cFoDZNekclypZnWK5p9Tp9y+v1up1y73nRQMbWBWHdz3LP90ASbav14HuW6L4m9spsHotE95Us3d18Kkm2mS5KSZziik76lGXBy+XNLpTTq8O5Y6rKadkts3Rv27JlZ2uFE8VkrWTeX4z+nGS0DLSeWILDTYp3jyJ/Bqsf2xRrFXP4Bb6+3fy2tegdUuc6pqenct29pVFjkfryDulhtzDLWXskCnbarCtd75WadaoUlpqqBelBi0qzWDRINwzZanTkOObmkTVv8Pq1G+CgGMNuRVSl53csonZXV0R7RyWitrobIasPMMoCRGF4WY807b+PnD+OS3idXh347fuHrdrbt8qWu4+5WpzU1RcE81QocLTwHcMPIiMoUsJEPtI8+obPWqRZRlNK7+kLoqskejut3UWCeg1msh3L6PYrn54qsf2WbO3thYOjrpTeTGK1Oea4ikSQ/EaSX7t1qwiZfeC9W6ft9dO71TSn/D3YS3hz7KPSNEct3+/vlDyVciS2/FLOEnwYSWpskXS7ai3YOSjB2WqwcEDEm+9cjEwRuqaGfGTineJdhrOW3c/2AjApnO6/BNxBkpqVXrfz1pWes91Lx73KkPZ+UTkP31qHyiw26zFt2fEacGiWiPtWHXWNXvwuIIwpETNmDbPhuZhhAcvG+RWrJj3Wm2x99Vt+QXLYrS9XXdAVu4YDCCehIpztbHefRVH+a07dX22sc/efoLy+/daU5+pswh+I8vRXQt3joDyZVbeW015ztaxLgHU3/eZbnT3Tn6uuULYGwoF/z+lo7wYdF16AHes00GuuO/V3Qxui2bP0ULP1bqjTYK5yS2Gvm5vu/6sQ1IVzKa67KwTXEJK3GVu6KLWd14H0ZRjB6eovj4rmqz/gci7+BQ==</diagram></mxfile> <mxfile host="Electron" modified="2021-08-09T19:46:29.036Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/14.6.13 Chrome/89.0.4389.128 Electron/12.0.7 Safari/537.36" etag="PQ2r34UrZa0TfW4Fw0EV" version="14.6.13" type="device"><diagram id="NEtccoSKIy4HskWlhJpu" name="Page-1">5VvbcqM4EP2a1O4+hOLqy2Ni5zKX1CTxzszOU0oG2dZEIBZEYu/XbwuEDQg7csZ2vFlXjQca0RLdR+eohXPiDML5VYLi2Q0LMD2xzWB+4gxPbNvqezb8JywLaTFtr7BMExJI28owIv/gsqG0ZiTAaa0hZ4xyEteNPosi7POaDSUJe643mzBa7zVGU6wYRj6iqvU7CfissPY8c2W/xmQ6K3u2THklRGVjaUhnKGDPFZNzceIMEsZ4cRTOB5iK6JVxKe67XHN1ObAER1znhgfT76Zzxxp3Z49j5+7zjw/z+NSS+XlCNJNPLEfLF2UIcAARkacs4TM2ZRGiFyvrecKyKMCiHxPOVm0+MxaD0QLjT8z5QqYXZZyBacZDKq/iKDgTyYLTiEW4sFwSSqXLAKWz3L9orD64jEXKssTHG57WlQBCyRTzTVGRDsWTV3qQcb3CLMQ8WUCDBFPEyVMdK0hCbrpst8oKHMjEbJEk9+UckTDHcTWm0jQk4RR6pWQM3z4l8QNKuDhkYZxxnKRw/J0ljymHJ2HRg2X35vDPiKPp2kA/4YTj+cbIyKunjmv0zMpHeljSQXH6XJla0jSrzKrStvPIei9Hdgm9HNoZpyTCgyXZmPWYI0qmERz7EDGcgIGiMaa3LCUittULIoQEaOZzo8GYcc7CSoMz6ZKLqXQOJBKLgYXzqSBc4xmPKcy11JgSPsvG0GLCIn6JQkJFiK8xfcLCjbwgJyDM+uJ8wChL8ud0ivSILnjCHnHblQlMyIp9kn/ADkMJCK55G14OL4YXmybrFhhyOzXQtKEGdMVwVeBUzDvHTjmKjdS54jWfojQlfpP3YCR/CRwZXnn6o3ptOJcgK84W8gwma8JVz7lZ0qZVI9Ff401PkzddTdqsJM5rme6lTZtdZQ+3jMCTLXFjlRkqyaZJI8Vzy7uqytl01Gk4chqOisAojnJYLR/7F5BWTpkV0gZUTDjgbnOUxTEorqCosxO7QyGG5+MEjqbiaDBLoPsTGzo2L0mCJ2yuNhri9FHQi21+iehCAfHzjHA8ilEOkWegnTqGm0QVkiDIVwU5950j/3Garw9Kdsjd7YYZlmurkhlUYrDNFoB19qUnltPCCUW40xhFZcBnnIvl65noTChxNCFT4+/w0ZiEZXOwV+9Qk9bmd0SiKYTeNm+F9AM2RKTX3tno4iN6QiM/IbFYHXz7eqHeOJI8AeM2YbTQDL4fiuFnCeIs0RvmNUt54eWqUK1iwOnaZ28Asr7cfC0894E/q2PYehDs7w2CGqtFdbndqklVRaoI1BpN2tEaXVdryql2JGKzTKiEgvdasXHchqNDi01XAz/vpiK0tOHW0YTbYUpC6/1ULj9TuH0XlWZ93riOuhjotsz/rmf09pWkjpKkuvI/4sWYoSRIG+K/ks9PsgV4ucEcBYgjXV2ekCR8hoiq7a+uoeGZX+RN3PQ1BsdiwXB2+wG+h629rFR7SKDaRPSLj4VIm7n2ptsuG2voPKRIu7Zt9N9apHtbiXRr7VirASVHVgtAc4cFoDZNekclypZnWK5p9Tp9y+v1up1y73nRQMbWBWHdz3LP90ASbav14HuW6L4m9spsHotE95Us3d18Kkm2mS5KSZziik76lGXBy+XNLpTTq8O5Y6rKadkts3Rv27JlZ2uFE8VkrWTeX4z+nGS0DLSeWILDTYp3jyJ/Bqsf2xRrFXP4Bb6+3fy2tegdUuc6pqenct29pVFjkfryDulhtzDLWXskCnbarCtd75WadaoUlpqqBelBi0qzWDRINwzZanTkOObmkTVv8Pq1G+CgGMNuRVSl53csonZXV0R7RyWitrobIasPMMoCRGF4WY807b+PnD+OS3idXh347fuHrdrbt8qWu4+5WpzU1RcE81QocLTwHcMPIiMoUsJEPtI8+obPWqRZRlNK7+kLoqskejut3UWCeg1msh3L6PYrn54qsf2WbO3thYOjrpTeTGK1Oea4ikSQ/EaSX7t1qwiZfeC9W6ft9dO71TSn/D3YS3hz7KPSNEct3+/vlDyVciS2/FLOEnwYSWpskXS7ai3YOSjB2WqwcEDEm+9cjEwRuqaGfGTineJdhrOW3c/2AjApnO6/BNxBkpqVXrfz1pWes91Lx73KkPZ+UTkP31qHyiw26zFt2fEacGiWiPtWHXWNXvwuIIwpETNmDbPhuZhhAcvG+RWrJj3Wm2x99Vt+QXLYrS9XXdAVu4YDCCehIpztbHefRVH+a07dX22sc/efoLy+/daU5+pswh+I8vRXQt3joDyZVbeW015ztaxLgHU3/eZbnT3Tn6uuULYGwoF/z+lo7wYdF16AHes00GuuO/V3Qxui2bP0ULP1bqjTYK5yS2Gvm5vu/6sQ1IVzKa67KwTXEJK3GVu6KLWd14H0ZRjB6eovj4rmqz/gci7+BQ==</diagram></mxfile>

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Before After
Before After

View file

@ -0,0 +1,58 @@
# QMK Configurator: Step by Step
This page describes the steps for building your firmware in QMK Configurator.
## Step 1: Select Your Keyboard
Click the drop down box and select the keyboard you want to create a keymap for.
?> If your keyboard has several versions, make sure you select the correct one.
I'll say that again because it's important:
!> **MAKE SURE YOU SELECT THE RIGHT VERSION!**
If your keyboard has been advertised to be powered by QMK but is not in the list, chances are a developer hasn't gotten to it yet or we haven't had a chance to merge it in yet. File an issue at [qmk_firmware](https://github.com/qmk/qmk_firmware/issues) requesting to support that particular keyboard, if there is no active [Pull Request](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+is%3Apr+label%3Akeyboard) for it. There are also QMK powered keyboards that are in their manufacturer's own GitHub accounts. Double check for that as well. <!-- FIXME(skullydazed): This feels too wordy and I'm not sure we want to encourage these kinds of issues. Also, should we prompt them to bug the manufacutrer? -->
## Step 2: Select Your Keyboard Layout
Choose the layout that best represents the keymap you want to create. Some keyboards do not have enough layouts or correct layouts defined yet. They will be supported in the future.
!> Sometimes there isn't a layout that supports your exact build. In that case select `LAYOUT_all`.
## Step 3: Name Your Keymap
Call this keymap what you want.
?> If you are running into issues when compiling, it may be worth changing this name, as it may already exist in the QMK Firmware repo.
## Step 4: Define Your Keymap
Keycode Entry is accomplished in one of 3 ways:
1. Drag and drop
2. Clicking on an empty spot on the layout, then clicking the keycode you desire
3. Clicking on an empty spot on the layout, then pressing the physical key on your keyboard
?> Hover your mouse over a key and a short blurb will tell you what that keycode does. For a more verbose description please see:
* [Basic Keycode Reference](keycodes_basic.md)
* [Advanced Keycode Reference](feature_advanced_keycodes.md)
!> If your selected layout doesn't match your physical build leave the unused keys blank. If you're not sure which key is in use, for example you have a one backspace key but `LAYOUT_all` has 2 keys, put the same keycode in both locations.
## Step 5: Save Your Keymap for Future Changes
When you're satisfied with your keymap or just want to work on it later, press the `Download this QMK Keymap JSON File` button. It will save your keymap to your computer. You can then load this .json file in the future by pressing the `Upload a QMK Keymap JSON File` button.
!> **CAUTION:** This is not the same type of .json file used for kbfirmware.com or any other tool. If you try to use this for those tools, or the .json from those tools with QMK Configurator, you will encounter problems.
## Step 6: Compile Your Firmware File
Press the green `Compile` button.
When the compilation is done, you will be able to press the green `Download Firmware` button.
## Next steps: Flashing Your Keyboard
Please refer to [Flashing Firmware](newbs_flashing.md).

View file

@ -0,0 +1,26 @@
# Configurator Troubleshooting
## My .json file is not working
If the .json file was generated with QMK Configurator, congratulations you have stumbled upon a bug. File an issue at [qmk_configurator](https://github.com/qmk/qmk_configurator/issues).
If not... how did you miss the big bold message at the top saying not to use other .json files?
## There are extra spaces in my layout? What do I do?
If you're referring to having three spots for space bar, the best course of action is to just fill them all with Space. The same can be done for Backspace and Shift keys.
## What is the keycode for...
Please see:
* [Basic Keycode Reference](keycodes_basic.md)
* [Advanced Keycode Reference](feature_advanced_keycodes.md)
## It won't compile
Please double check the other layers of your keymap to make sure there are no random keys present.
## Problems and Bugs
We are always accepting customer requests and bug reports. Please file them at [qmk_configurator](https://github.com/qmk/qmk_configurator/issues).

Some files were not shown because too many files have changed in this diff Show more