forked from mirrors/qmk_firmware
Compare commits
No commits in common. "develop" and "gh-pages" have entirely different histories.
30979 changed files with 24267 additions and 2010277 deletions
|
@ -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
|
|
||||||
|
|
||||||
...
|
|
4
.clangd
4
.clangd
|
@ -1,4 +0,0 @@
|
||||||
CompileFlags:
|
|
||||||
Add: [-Wno-unknown-attributes, -Wno-maybe-uninitialized, -Wno-unknown-warning-option]
|
|
||||||
Remove: [-W*, -mcall-prologues]
|
|
||||||
Compiler: clang
|
|
|
@ -1,42 +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
|
|
||||||
|
|
||||||
[{*.yaml,*.yml}] # To match GitHub Actions formatting
|
|
||||||
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
|
|
1
.envrc
1
.envrc
|
@ -1 +0,0 @@
|
||||||
use nix
|
|
96
.gitattributes
vendored
96
.gitattributes
vendored
|
@ -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
|
|
41
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
41
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
@ -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.
|
|
8
.github/ISSUE_TEMPLATE/config.yml
vendored
8
.github/ISSUE_TEMPLATE/config.yml
vendored
|
@ -1,8 +0,0 @@
|
||||||
blank_issues_enabled: false
|
|
||||||
contact_links:
|
|
||||||
- name: QMK Discord
|
|
||||||
url: https://discord.gg/Uq7gcHh
|
|
||||||
about: Ask questions, discuss issues and features. Chill.
|
|
||||||
- name: OLKB Subreddit
|
|
||||||
url: https://www.reddit.com/r/olkb
|
|
||||||
about: All things OLKB and QMK.
|
|
24
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
24
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
|
@ -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.
|
|
19
.github/ISSUE_TEMPLATE/other_issues.yml
vendored
19
.github/ISSUE_TEMPLATE/other_issues.yml
vendored
|
@ -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.
|
|
11
.github/ISSUE_TEMPLATE/zzz_blank.md
vendored
11
.github/ISSUE_TEMPLATE/zzz_blank.md
vendored
|
@ -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: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
35
.github/PULL_REQUEST_TEMPLATE.md
vendored
35
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -1,35 +0,0 @@
|
||||||
<!--- Provide a general summary of your changes in the title above. -->
|
|
||||||
|
|
||||||
<!--- This template is entirely optional and can be removed, but is here to help both you and us. -->
|
|
||||||
<!--- 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/userspace (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).
|
|
9
.github/dependabot.yml
vendored
9
.github/dependabot.yml
vendored
|
@ -1,9 +0,0 @@
|
||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: "github-actions"
|
|
||||||
directory: "/"
|
|
||||||
labels: CI
|
|
||||||
reviewers:
|
|
||||||
- "qmk/collaborators"
|
|
||||||
schedule:
|
|
||||||
interval: "daily"
|
|
46
.github/labeler.yml
vendored
46
.github/labeler.yml
vendored
|
@ -1,46 +0,0 @@
|
||||||
core:
|
|
||||||
- quantum/**/*
|
|
||||||
- tmk_core/**/*
|
|
||||||
- drivers/**/*
|
|
||||||
- tests/**/*
|
|
||||||
- util/**/*
|
|
||||||
- platforms/**/*
|
|
||||||
- builddefs/**/*
|
|
||||||
- Makefile
|
|
||||||
- '*.mk'
|
|
||||||
dependencies:
|
|
||||||
- any:
|
|
||||||
- 'lib/**/*'
|
|
||||||
- '!lib/python/**/*'
|
|
||||||
keyboard:
|
|
||||||
- any:
|
|
||||||
- 'keyboards/**/*'
|
|
||||||
- '!keyboards/**/keymaps/**/*'
|
|
||||||
keymap:
|
|
||||||
- users/**/*
|
|
||||||
- layouts/**/*
|
|
||||||
- keyboards/**/keymaps/**/*
|
|
||||||
via:
|
|
||||||
- keyboards/**/keymaps/via/*
|
|
||||||
cli:
|
|
||||||
- requirements.txt
|
|
||||||
- lib/python/**/*
|
|
||||||
python:
|
|
||||||
- '**/*.py'
|
|
||||||
documentation:
|
|
||||||
- docs/**/*
|
|
||||||
translation:
|
|
||||||
- docs/fr-fr/**/*
|
|
||||||
- docs/es/**/*
|
|
||||||
- docs/ja/**/*
|
|
||||||
- docs/he-il/**/*
|
|
||||||
- docs/pt-br/**/*
|
|
||||||
- docs/zh-cn/**/*
|
|
||||||
- docs/de/**/*
|
|
||||||
- docs/ru-ru/**/*
|
|
||||||
CI:
|
|
||||||
- .github/**/*
|
|
||||||
dd:
|
|
||||||
- data/constants/**/*
|
|
||||||
- data/mappings/**/*
|
|
||||||
- data/schemas/**/*
|
|
50
.github/workflows/api.yml
vendored
50
.github/workflows/api.yml
vendored
|
@ -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'
|
|
20
.github/workflows/auto_approve.yml
vendored
20
.github/workflows/auto_approve.yml
vendored
|
@ -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: mheap/automatic-approve-action@v1
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.QMK_BOT_TOKEN }}
|
|
||||||
workflows: "format.yml,lint.yml,unit_test.yml"
|
|
||||||
dangerous_files: "lib/python/,Makefile,paths.mk,builddefs/"
|
|
38
.github/workflows/auto_tag.yml
vendored
38
.github/workflows/auto_tag.yml
vendored
|
@ -1,38 +0,0 @@
|
||||||
name: Essential files modified
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
paths:
|
|
||||||
- builddefs/**/*
|
|
||||||
- drivers/**/*
|
|
||||||
- platforms/**/*
|
|
||||||
- quantum/**/*
|
|
||||||
- tests/**/*
|
|
||||||
- tmk_core/**/*
|
|
||||||
- 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'
|
|
74
.github/workflows/ci_builds.yml
vendored
74
.github/workflows/ci_builds.yml
vendored
|
@ -1,74 +0,0 @@
|
||||||
name: CI Builds
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [master, develop]
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
branch:
|
|
||||||
type: choice
|
|
||||||
description: 'Branch to build'
|
|
||||||
options: [master, develop]
|
|
||||||
|
|
||||||
concurrency: ci_build-${{ github.event.inputs.branch || github.ref_name }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
ci_builds:
|
|
||||||
if: github.repository == 'qmk/qmk_firmware'
|
|
||||||
name: "CI Build"
|
|
||||||
runs-on: self-hosted
|
|
||||||
timeout-minutes: 1380
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
keymap: [default, via]
|
|
||||||
|
|
||||||
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
|
|
||||||
ref: ${{ github.event.inputs.branch || github.ref }}
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: pip3 install -r requirements.txt
|
|
||||||
|
|
||||||
- name: Run `qmk mass-compile` (keymap ${{ matrix.keymap }})
|
|
||||||
run: |
|
|
||||||
export NCPUS=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null)
|
|
||||||
qmk mass-compile -t -j $NCPUS -km ${{ matrix.keymap }} -e DUMP_CI_METADATA=yes || touch .failed
|
|
||||||
# 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
|
|
||||||
# Exit with failure if the compilation stage failed
|
|
||||||
[ ! -f .failed ] || exit 1
|
|
||||||
|
|
||||||
- name: 'Upload artifacts'
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
if: always()
|
|
||||||
with:
|
|
||||||
name: artifacts-${{ github.event.inputs.branch || github.ref_name }}-${{ matrix.keymap }}
|
|
||||||
if-no-files-found: ignore
|
|
||||||
path: |
|
|
||||||
*.bin
|
|
||||||
*.hex
|
|
||||||
*.uf2
|
|
||||||
.build/failed.*
|
|
||||||
|
|
||||||
- name: 'CI Discord Notification'
|
|
||||||
if: always()
|
|
||||||
working-directory: util/ci/
|
|
||||||
env:
|
|
||||||
DISCORD_WEBHOOK: ${{ secrets.CI_DISCORD_WEBHOOK }}
|
|
||||||
run: |
|
|
||||||
python3 -m pip install -r requirements.txt
|
|
||||||
python3 ./discord-results.py --branch ${{ github.event.inputs.branch || github.ref_name }} --keymap ${{ matrix.keymap }} --url ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
34
.github/workflows/cli.yml
vendored
34
.github/workflows/cli.yml
vendored
|
@ -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
|
|
37
.github/workflows/develop_update.yml
vendored
37
.github/workflows/develop_update.yml
vendored
|
@ -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
|
|
46
.github/workflows/docs.yml
vendored
46
.github/workflows/docs.yml
vendored
|
@ -1,46 +0,0 @@
|
||||||
name: Generate Docs
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
paths:
|
|
||||||
- 'tmk_core/**'
|
|
||||||
- 'quantum/**'
|
|
||||||
- 'platforms/**'
|
|
||||||
- 'docs/**'
|
|
||||||
- '.github/workflows/docs.yml'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
generate:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container: ghcr.io/qmk/qmk_cli
|
|
||||||
|
|
||||||
# protect against those who develop with their fork on master
|
|
||||||
if: github.repository == 'qmk/qmk_firmware'
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 1
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
apt-get update && apt-get install -y rsync nodejs npm doxygen
|
|
||||||
npm install -g moxygen
|
|
||||||
|
|
||||||
- name: Build docs
|
|
||||||
run: |
|
|
||||||
qmk --verbose generate-docs
|
|
||||||
|
|
||||||
- name: Deploy
|
|
||||||
uses: JamesIves/github-pages-deploy-action@v4.5.0
|
|
||||||
with:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
BASE_BRANCH: master
|
|
||||||
BRANCH: gh-pages
|
|
||||||
FOLDER: .build/docs
|
|
||||||
GIT_CONFIG_EMAIL: hello@qmk.fm
|
|
43
.github/workflows/feature_branch_update.yml
vendored
43
.github/workflows/feature_branch_update.yml
vendored
|
@ -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 }}
|
|
57
.github/workflows/format.yml
vendored
57
.github/workflows/format.yml
vendored
|
@ -1,57 +0,0 @@
|
||||||
name: PR Lint Format
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- 'drivers/**'
|
|
||||||
- 'lib/arm_atsam/**'
|
|
||||||
- 'lib/lib8tion/**'
|
|
||||||
- 'lib/python/**'
|
|
||||||
- '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@v44
|
|
||||||
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)"
|
|
59
.github/workflows/format_push.yml
vendored
59
.github/workflows/format_push.yml
vendored
|
@ -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@v3.x
|
|
||||||
|
|
||||||
- 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@v6
|
|
||||||
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'
|
|
18
.github/workflows/labeler.yml
vendored
18
.github/workflows/labeler.yml
vendored
|
@ -1,18 +0,0 @@
|
||||||
name: "Pull Request Labeler"
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request_target:
|
|
||||||
types: [opened, synchronize, reopened, ready_for_review, locked]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
triage:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/labeler@v4
|
|
||||||
with:
|
|
||||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
|
||||||
configuration-path: '.github/labeler.yml'
|
|
87
.github/workflows/lint.yml
vendored
87
.github/workflows/lint.yml
vendored
|
@ -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@v44
|
|
||||||
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
|
|
36
.github/workflows/regen.yml
vendored
36
.github/workflows/regen.yml
vendored
|
@ -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)"
|
|
46
.github/workflows/regen_push.yml
vendored
46
.github/workflows/regen_push.yml
vendored
|
@ -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@v3.x
|
|
||||||
|
|
||||||
- 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@v6
|
|
||||||
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'
|
|
66
.github/workflows/stale.yml
vendored
66
.github/workflows/stale.yml
vendored
|
@ -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
|
|
||||||
|
|
||||||
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]
|
|
35
.github/workflows/unit_test.yml
vendored
35
.github/workflows/unit_test.yml
vendored
|
@ -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: make test:all
|
|
119
.gitignore
vendored
119
.gitignore
vendored
|
@ -1,119 +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
|
|
||||||
|
|
||||||
# QMK-specific
|
|
||||||
api_data/v1
|
|
||||||
quantum/version.h
|
|
||||||
*.bin
|
|
||||||
*.eep
|
|
||||||
*.hex
|
|
||||||
*.qmk
|
|
||||||
*.uf2
|
|
||||||
|
|
||||||
# DD config at wrong location
|
|
||||||
/keyboards/**/keymaps/*/info.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/vial/*
|
|
||||||
.direnv
|
|
27
.gitmodules
vendored
27
.gitmodules
vendored
|
@ -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
|
|
10
.vscode/extensions.json
vendored
10
.vscode/extensions.json
vendored
|
@ -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"
|
|
||||||
]
|
|
||||||
}
|
|
34
.vscode/settings.json
vendored
34
.vscode/settings.json
vendored
|
@ -1,34 +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": {
|
|
||||||
"*.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"
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -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
|
|
@ -56,19 +56,19 @@ You can now define up to 32 macros in your `keymap.json` file, as used by [QMK C
|
||||||
"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,7 +76,7 @@ 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"]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
266
Doxyfile
266
Doxyfile
|
@ -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/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 = */protocol/arm_atsam/*
|
|
||||||
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
339
LICENSE
|
@ -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.
|
|
467
Makefile
467
Makefile
|
@ -1,467 +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
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
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,$$(shell $(QMK_BIN) list-keyboards --no-resolve-defaults)),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
|
|
||||||
|
|
||||||
# KEYBOARD_FOLDERS := $$(subst /, , $(CURRENT_KB))
|
|
||||||
|
|
||||||
DEFAULT_FOLDER := $$(CURRENT_KB)
|
|
||||||
|
|
||||||
# We assume that every rules.mk will contain the full default value
|
|
||||||
$$(eval include $(ROOT_DIR)/keyboards/$$(CURRENT_KB)/rules.mk)
|
|
||||||
ifneq ($$(DEFAULT_FOLDER),$$(CURRENT_KB))
|
|
||||||
$$(eval include $(ROOT_DIR)/keyboards/$$(DEFAULT_FOLDER)/rules.mk)
|
|
||||||
endif
|
|
||||||
CURRENT_KB := $$(DEFAULT_FOLDER)
|
|
||||||
|
|
||||||
# 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
|
|
194
_summary.md
Normal file
194
_summary.md
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
* 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)
|
||||||
|
* [Caps Word](feature_caps_word.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
|
||||||
|
* [Quantum Painter](quantum_painter.md)
|
||||||
|
* [HD44780 LCD Driver](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/20220528.md "QMK v0.17.0 - 2022 May 28")
|
||||||
|
* [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](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)
|
|
@ -9,7 +9,7 @@ This driver currently supports both AVR and a limited selection of ARM devices.
|
||||||
To use this driver, add the following to your `rules.mk`:
|
To use this driver, add the following to your `rules.mk`:
|
||||||
|
|
||||||
```make
|
```make
|
||||||
ANALOG_DRIVER_REQUIRED = yes
|
SRC += analog.c
|
||||||
```
|
```
|
||||||
|
|
||||||
Then place this include at the top of your code:
|
Then place this include at the top of your code:
|
||||||
|
@ -43,8 +43,6 @@ Then place this include at the top of your code:
|
||||||
|
|
||||||
### ARM
|
### ARM
|
||||||
|
|
||||||
#### STM32
|
|
||||||
|
|
||||||
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.
|
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.
|
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.
|
||||||
|
@ -123,21 +121,6 @@ Also note that the F0 and F3 use different numbering schemes. The F0 has a singl
|
||||||
|
|
||||||
<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>
|
<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>
|
||||||
|
|
||||||
#### RP2040
|
|
||||||
|
|
||||||
RP2040 has only a single ADC (`ADCD1` in ChibiOS); in the QMK API the index for that ADC is 0.
|
|
||||||
|
|
||||||
|Channel|Pin |
|
|
||||||
|-------|-------------------|
|
|
||||||
|0 |`GP26` |
|
|
||||||
|1 |`GP27` |
|
|
||||||
|2 |`GP28` |
|
|
||||||
|3 |`GP29` |
|
|
||||||
|4 |Temperature sensor*|
|
|
||||||
|
|
||||||
|
|
||||||
<sup>* The temperature sensor is disabled by default and needs to be enabled by the RP2040-specific function: `adcRPEnableTS(&ADCD1)`. The ADC must be initialized before calling that function; an easy way to ensure that is to perform a dummy conversion.</sup>
|
|
||||||
|
|
||||||
## Functions
|
## Functions
|
||||||
|
|
||||||
### AVR
|
### AVR
|
68
api_docs.md
Normal file
68
api_docs.md
Normal 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.
|
|
@ -113,35 +113,20 @@ Additionally, in the board config, you'll want to make changes to enable the DAC
|
||||||
|
|
||||||
### DAC Config
|
### DAC Config
|
||||||
|
|
||||||
| Define | Defaults | Description |
|
| 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_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 not playing anything. Some setups may require a high (`AUDIO_DAC_SAMPLE_MAX`) or low (`0`) value here. |
|
| `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_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. |
|
| `AUDIO_DAC_SAMPLE_RATE` | __see next table__ | Effective bit rate of the DAC (in hertz), higher limits simultaneous tones, and lower sacrifices quality. |
|
||||||
| `AUDIO_DAC_BUFFER_SIZE` | __see next table__ | Number of samples generated every refill. Too few may cause excessive CPU load; too many may cause freezes, RAM or flash exhaustion or lags during matrix scanning. |
|
|
||||||
|
|
||||||
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, number of simultaneous tones and buffer size, instead of using one of the listed presets.
|
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 | Buffer size |
|
| Define | Sample Rate | Simultaneous tones |
|
||||||
| --------------------------------- | ----------- | ------------------- | ----------- |
|
| `AUDIO_DAC_QUALITY_VERY_LOW` | `11025U` | `8` |
|
||||||
| `AUDIO_DAC_QUALITY_VERY_LOW` | `11025U` | `8` | `64U` |
|
| `AUDIO_DAC_QUALITY_LOW` | `22040U` | `4` |
|
||||||
| `AUDIO_DAC_QUALITY_LOW` | `22050U` | `4` | `128U` |
|
| `AUDIO_DAC_QUALITY_HIGH` | `44100U` | `2` |
|
||||||
| `AUDIO_DAC_QUALITY_HIGH` | `44100U` | `2` | `256U` |
|
| `AUDIO_DAC_QUALITY_VERY_HIGH` | `88200U` | `1` |
|
||||||
| `AUDIO_DAC_QUALITY_VERY_HIGH` | `88200U` | `1` | `256U` |
|
| `AUDIO_DAC_QUALITY_SANE_MINIMUM` | `16384U` | `8` |
|
||||||
| `AUDIO_DAC_QUALITY_SANE_MINIMUM` | `16384U` | `8` | `64U` |
|
|
||||||
|
|
||||||
#### Notes on buffer size :id=buffer-size
|
|
||||||
|
|
||||||
By default, the buffer size attempts to keep to these constraints:
|
|
||||||
|
|
||||||
* The interval between buffer refills can't be too short, since the microcontroller would then only be servicing buffer refills and would freeze up.
|
|
||||||
* On the additive driver, the interval between buffer refills can't be too long, since matrix scanning would suffer lengthy pauses every so often, which would delay key presses or releases or lose some short taps altogether.
|
|
||||||
* The interval between buffer refills is kept to a minimum, which allows notes to stop as soon as possible after they should.
|
|
||||||
* For greater compatibility, the buffer size should be a power of 2.
|
|
||||||
* The buffer size being too large causes resource exhaustion leading to build failures or freezing at runtime: RAM usage (on the additive driver) or flash usage (on the basic driver).
|
|
||||||
|
|
||||||
You can lower the buffer size if you need a bit more space in your firmware, or raise it if your keyboard freezes up.
|
|
||||||
|
|
||||||
|
|
||||||
```c
|
```c
|
||||||
|
@ -172,6 +157,7 @@ A configuration example for the STM32F103C8 would be:
|
||||||
//halconf.h:
|
//halconf.h:
|
||||||
#define HAL_USE_PWM TRUE
|
#define HAL_USE_PWM TRUE
|
||||||
#define HAL_USE_PAL TRUE
|
#define HAL_USE_PAL TRUE
|
||||||
|
#define HAL_USE_GPT TRUE
|
||||||
#include_next <halconf.h>
|
#include_next <halconf.h>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -180,6 +166,8 @@ A configuration example for the STM32F103C8 would be:
|
||||||
#include_next <mcuconf.h>
|
#include_next <mcuconf.h>
|
||||||
#undef STM32_PWM_USE_TIM1
|
#undef STM32_PWM_USE_TIM1
|
||||||
#define STM32_PWM_USE_TIM1 TRUE
|
#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
|
If we now target pin A8, looking through the data-sheet of the STM32F103C8, for the timers and alternate functions
|
||||||
|
@ -194,16 +182,12 @@ with all this information, the configuration would contain these lines:
|
||||||
#define AUDIO_PIN A8
|
#define AUDIO_PIN A8
|
||||||
#define AUDIO_PWM_DRIVER PWMD1
|
#define AUDIO_PWM_DRIVER PWMD1
|
||||||
#define AUDIO_PWM_CHANNEL 1
|
#define AUDIO_PWM_CHANNEL 1
|
||||||
|
#define AUDIO_STATE_TIMER GPTD4
|
||||||
```
|
```
|
||||||
|
|
||||||
ChibiOS uses GPIOv1 for the F103, which only knows of one alternate function.
|
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.
|
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.
|
||||||
|
|
||||||
You can also use the Complementary output (`TIMx_CHyN`) for PWM on supported controllers. To enable this functionality, you will need to make the following changes:
|
|
||||||
```c
|
|
||||||
// config.h:
|
|
||||||
#define AUDIO_PWM_COMPLEMENTARY_OUTPUT
|
|
||||||
```
|
|
||||||
|
|
||||||
### PWM software :id=pwm-software
|
### PWM software :id=pwm-software
|
||||||
|
|
||||||
|
@ -222,14 +206,14 @@ You can also change the timer used for software PWM by defining the driver. For
|
||||||
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
|
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
|
||||||
|
|
||||||
| | DAC basic | DAC additive | PWM hardware | PWM software |
|
| | DAC basic | DAC additive | PWM hardware | PWM software |
|
||||||
| ------------------------ | ------------------ | ------------------ | ------------------ | ------------------ |
|
|--------------------------|--------------------|--------------------|--------------------|--------------------|
|
||||||
| Atmega32U4 | :o: | :o: | :heavy_check_mark: | :o: |
|
| Atmega32U4 | :o: | :o: | :heavy_check_mark: | :o: |
|
||||||
| RP2040 | :x: | :x: | :heavy_check_mark: | ? |
|
|
||||||
| STM32F103C8 (bluepill) | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
|
| STM32F103C8 (bluepill) | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
|
||||||
| STM32F303CCT6 (proton-c) | :heavy_check_mark: | :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: |
|
| STM32F405VG | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||||
| L0xx | :x: (no Tim8) | ? | ? | ? |
|
| L0xx | :x: (no Tim8) | ? | ? | ? |
|
||||||
|
|
||||||
|
|
||||||
:heavy_check_mark: : works and was tested
|
:heavy_check_mark: : works and was tested
|
||||||
:o: : does not apply
|
:o: : does not apply
|
||||||
:x: : not supported by MCU
|
:x: : not supported by MCU
|
136
breaking_changes.md
Normal file
136
breaking_changes.md
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
# 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 May 28](ChangeLog/20220528.md)
|
||||||
|
* [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 August 27, 2022.
|
||||||
|
|
||||||
|
### Important Dates
|
||||||
|
|
||||||
|
* [x] 2022 May 28 - `develop` is tagged with a new release version. Each push to `master` is subsequently merged to `develop` by GitHub actions.
|
||||||
|
* [ ] 2022 Jul 31 - `develop` closed to new PR's.
|
||||||
|
* [ ] 2022 Jul 31 - Call for testers.
|
||||||
|
* [ ] 2022 Aug 13 - Last day for merges -- after this point `develop` is locked for testing and accepts only bugfixes
|
||||||
|
* [ ] 2022 Aug 25 - `master` is locked, no PR's merged.
|
||||||
|
* [ ] 2022 Aug 27 - Merge `develop` to `master`.
|
||||||
|
* [ ] 2022 Aug 27 - `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/20220827`.
|
||||||
|
* 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.
|
||||||
|
|
||||||
|
### 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 tag <next_version>` # Prevent the breakpoint tag from confusing version incrementing
|
||||||
|
* [ ] `git push upstream <next_version>`
|
||||||
|
* [ ] `git push upstream master`
|
||||||
|
|
||||||
|
## Post-merge operations
|
||||||
|
|
||||||
|
### Updating the `develop` branch
|
||||||
|
|
||||||
|
This happens immediately after the previous `develop` branch is merged to `master`.
|
||||||
|
|
||||||
|
* `qmk_firmware` git commands
|
||||||
|
* [ ] `git checkout master`
|
||||||
|
* [ ] `git pull --ff-only`
|
||||||
|
* [ ] `git checkout develop`
|
||||||
|
* [ ] `git pull --ff-only`
|
||||||
|
* [ ] `git merge --no-ff master`
|
||||||
|
* [ ] 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 push upstream breakpoint_<YYYY>_<MM>_<DD>`
|
||||||
|
|
||||||
|
* All submodules under `lib` now need to be checked against their QMK-based forks:
|
||||||
|
* [ ] `git submodule foreach git log -n1`
|
||||||
|
* [ ] Validate each submodule SHA1 matches the qmk fork, e.g. for ChibiOS:
|
||||||
|
* Go to [qmk/ChibiOS](https://github.com/qmk/ChibiOS)
|
||||||
|
* Compare the commit hash in the above output to the commit hash in the repository
|
||||||
|
* If there's a mismatch:
|
||||||
|
* [ ] `cd lib/chibios`
|
||||||
|
* [ ] `git fetch --all`
|
||||||
|
* [ ] `git checkout master`
|
||||||
|
* [ ] `git reset --hard <commit hash>`
|
||||||
|
* [ ] `git push origin master --force-with-lease`
|
||||||
|
|
||||||
|
* (Optional) [update ChibiOS + ChibiOS-Contrib on `develop`](chibios_upgrade_instructions.md)
|
15
breaking_changes_history.md
Normal file
15
breaking_changes_history.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Past Breaking Changes
|
||||||
|
|
||||||
|
This page links to all previous changelogs from the QMK Breaking Changes process.
|
||||||
|
|
||||||
|
* [2022 May 28](ChangeLog/20220528.md) - version 0.17.0
|
||||||
|
* [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
|
|
@ -23,6 +23,14 @@ If it is determined that your submission is a breaking change, there are a few t
|
||||||
|
|
||||||
If you are contributing core code, and the only reason it needs to go through breaking changes is that you are updating keymaps to match your change, consider whether you can submit your feature in a way that the old keymaps continue to work. Then submit a separate PR that goes through the breaking changes process to remove the old code.
|
If you are contributing core code, and the only reason it needs to go through breaking changes is that you are updating keymaps to match your change, consider whether you can submit your feature in a way that the old keymaps continue to work. Then submit a separate PR that goes through the breaking changes process to remove the old code.
|
||||||
|
|
||||||
|
### Contribute a ChangeLog Entry
|
||||||
|
|
||||||
|
We require submissions that go through the Breaking Change process to include a changelog entry. The entry should be a short summary of the changes your pull request makes – [each section here started as a changelog](ChangeLog/20190830.md "n.b. This should link to the 2019 Aug 30 Breaking Changes doc - @noroadsleft").
|
||||||
|
|
||||||
|
Your changelog should be located at `docs/ChangeLog/YYYYMMDD/PR####.md`, where `YYYYMMDD` is the date on which QMK's breaking change branch – usually named `develop` – will be merged into the `master` branch, and `####` is the number of your pull request.
|
||||||
|
|
||||||
|
If your submission requires action on the part of users, your changelog should instruct users what action(s) must be taken, or link to a location that does so.
|
||||||
|
|
||||||
### Document Your Changes
|
### 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.
|
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.
|
|
@ -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/test_driver.cpp \
|
|
||||||
tests/test_common/keyboard_report_util.cpp \
|
|
||||||
tests/test_common/keycode_util.cpp \
|
|
||||||
tests/test_common/keycode_table.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
|
|
|
@ -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
|
|
|
@ -1,558 +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)/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
|
|
||||||
TARGET := $(TARGET)
|
|
||||||
|
|
||||||
ifneq ($(FORCE_LAYOUT),)
|
|
||||||
TARGET := $(TARGET)_$(FORCE_LAYOUT)
|
|
||||||
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
|
|
||||||
|
|
||||||
# Generate the board's version.h file.
|
|
||||||
$(shell $(QMK_BIN) generate-version-h $(VERSION_H_FLAGS) -q -o $(INTERMEDIATE_OUTPUT)/src/version.h)
|
|
||||||
|
|
||||||
# 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
|
|
||||||
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/rules.mk)","")
|
|
||||||
include $(KEYBOARD_PATH_5)/rules.mk
|
|
||||||
endif
|
|
||||||
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/rules.mk)","")
|
|
||||||
include $(KEYBOARD_PATH_4)/rules.mk
|
|
||||||
endif
|
|
||||||
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/rules.mk)","")
|
|
||||||
include $(KEYBOARD_PATH_3)/rules.mk
|
|
||||||
endif
|
|
||||||
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/rules.mk)","")
|
|
||||||
include $(KEYBOARD_PATH_2)/rules.mk
|
|
||||||
endif
|
|
||||||
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/rules.mk)","")
|
|
||||||
include $(KEYBOARD_PATH_1)/rules.mk
|
|
||||||
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 info.json
|
|
||||||
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))", "")
|
|
||||||
$(call WARNING_MESSAGE,Keymap is specified as both keymap.json and keymap.c -- keymap.json file wins.)
|
|
||||||
endif
|
|
||||||
|
|
||||||
KEYMAP_PATH := $(KEYMAP_JSON_PATH)
|
|
||||||
|
|
||||||
KEYMAP_C := $(INTERMEDIATE_OUTPUT)/src/keymap.c
|
|
||||||
KEYMAP_H := $(INTERMEDIATE_OUTPUT)/src/config.h
|
|
||||||
|
|
||||||
# Load the keymap-level rules.mk if exists
|
|
||||||
-include $(KEYMAP_PATH)/rules.mk
|
|
||||||
|
|
||||||
# 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)
|
|
||||||
@$(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)
|
|
||||||
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
|
|
||||||
$(eval CMD=$(QMK_BIN) generate-config-h --quiet --output $(KEYMAP_H) $(KEYMAP_JSON))
|
|
||||||
@$(BUILD_CMD)
|
|
||||||
|
|
||||||
generated-files: $(INTERMEDIATE_OUTPUT)/src/config.h $(INTERMEDIATE_OUTPUT)/src/keymap.c
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(BUILDDEFS_PATH)/converters.mk
|
|
||||||
|
|
||||||
MCU_ORIG := $(MCU)
|
|
||||||
include $(wildcard $(PLATFORM_PATH)/*/mcu_selection.mk)
|
|
||||||
|
|
||||||
# PLATFORM_KEY should be detected in info.json 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 :=
|
|
||||||
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 :=
|
|
||||||
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
|
|
||||||
|
|
||||||
# Pull in stuff from info.json
|
|
||||||
INFO_JSON_FILES :=
|
|
||||||
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/info.json)","")
|
|
||||||
INFO_JSON_FILES += $(KEYBOARD_PATH_1)/info.json
|
|
||||||
endif
|
|
||||||
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/info.json)","")
|
|
||||||
INFO_JSON_FILES += $(KEYBOARD_PATH_2)/info.json
|
|
||||||
endif
|
|
||||||
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/info.json)","")
|
|
||||||
INFO_JSON_FILES += $(KEYBOARD_PATH_3)/info.json
|
|
||||||
endif
|
|
||||||
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/info.json)","")
|
|
||||||
INFO_JSON_FILES += $(KEYBOARD_PATH_4)/info.json
|
|
||||||
endif
|
|
||||||
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/info.json)","")
|
|
||||||
INFO_JSON_FILES += $(KEYBOARD_PATH_5)/info.json
|
|
||||||
endif
|
|
||||||
|
|
||||||
CONFIG_H += $(INTERMEDIATE_OUTPUT)/src/info_config.h
|
|
||||||
KEYBOARD_SRC += $(INTERMEDIATE_OUTPUT)/src/default_keyboard.c
|
|
||||||
|
|
||||||
$(INTERMEDIATE_OUTPUT)/src/info_config.h: $(INFO_JSON_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: $(INFO_JSON_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: $(INFO_JSON_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
|
|
||||||
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/post_rules.mk)","")
|
|
||||||
include $(KEYBOARD_PATH_1)/post_rules.mk
|
|
||||||
endif
|
|
||||||
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/post_rules.mk)","")
|
|
||||||
include $(KEYBOARD_PATH_2)/post_rules.mk
|
|
||||||
endif
|
|
||||||
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/post_rules.mk)","")
|
|
||||||
include $(KEYBOARD_PATH_3)/post_rules.mk
|
|
||||||
endif
|
|
||||||
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/post_rules.mk)","")
|
|
||||||
include $(KEYBOARD_PATH_4)/post_rules.mk
|
|
||||||
endif
|
|
||||||
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/post_rules.mk)","")
|
|
||||||
include $(KEYBOARD_PATH_5)/post_rules.mk
|
|
||||||
endif
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
# TODO: remove this bodge?
|
|
||||||
PROJECT_DEFS := $(OPT_DEFS)
|
|
||||||
PROJECT_INC := $(VPATH) $(EXTRAINCDIRS) $(KEYBOARD_PATHS)
|
|
||||||
PROJECT_CONFIG := $(CONFIG_H)
|
|
||||||
|
|
||||||
CONFIG_H += $(POST_CONFIG_H)
|
|
||||||
ALL_CONFIGS := $(PROJECT_CONFIG) $(CONFIG_H)
|
|
||||||
|
|
||||||
OUTPUTS := $(INTERMEDIATE_OUTPUT)
|
|
||||||
$(INTERMEDIATE_OUTPUT)_SRC := $(SRC) $(PLATFORM_SRC)
|
|
||||||
$(INTERMEDIATE_OUTPUT)_DEFS := $(OPT_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\" \
|
|
||||||
$(PROJECT_DEFS)
|
|
||||||
$(INTERMEDIATE_OUTPUT)_INC := $(VPATH) $(EXTRAINCDIRS) $(PROJECT_INC)
|
|
||||||
$(INTERMEDIATE_OUTPUT)_CONFIG := $(CONFIG_H) $(PROJECT_CONFIG)
|
|
||||||
|
|
||||||
# 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)))))
|
|
|
@ -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)))
|
|
|
@ -1,92 +0,0 @@
|
||||||
ifndef VERBOSE
|
|
||||||
.SILENT:
|
|
||||||
endif
|
|
||||||
|
|
||||||
.DEFAULT_GOAL := all
|
|
||||||
|
|
||||||
OPT = g
|
|
||||||
|
|
||||||
include paths.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
|
|
||||||
|
|
||||||
ifeq ($(strip $(DEBUG)), 1)
|
|
||||||
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)
|
|
|
@ -1,974 +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/>.
|
|
||||||
|
|
||||||
QUANTUM_SRC += \
|
|
||||||
$(QUANTUM_DIR)/quantum.c \
|
|
||||||
$(QUANTUM_DIR)/bitwise.c \
|
|
||||||
$(QUANTUM_DIR)/led.c \
|
|
||||||
$(QUANTUM_DIR)/action.c \
|
|
||||||
$(QUANTUM_DIR)/action_layer.c \
|
|
||||||
$(QUANTUM_DIR)/action_tapping.c \
|
|
||||||
$(QUANTUM_DIR)/action_util.c \
|
|
||||||
$(QUANTUM_DIR)/eeconfig.c \
|
|
||||||
$(QUANTUM_DIR)/keyboard.c \
|
|
||||||
$(QUANTUM_DIR)/keymap_common.c \
|
|
||||||
$(QUANTUM_DIR)/keycode_config.c \
|
|
||||||
$(QUANTUM_DIR)/sync_timer.c \
|
|
||||||
$(QUANTUM_DIR)/logging/debug.c \
|
|
||||||
$(QUANTUM_DIR)/logging/sendchar.c \
|
|
||||||
|
|
||||||
VPATH += $(QUANTUM_DIR)/logging
|
|
||||||
# Fall back to lib/printf if there is no platform provided print
|
|
||||||
ifeq ("$(wildcard $(PLATFORM_PATH)/$(PLATFORM_KEY)/printf.mk)","")
|
|
||||||
include $(QUANTUM_PATH)/logging/print.mk
|
|
||||||
else
|
|
||||||
include $(PLATFORM_PATH)/$(PLATFORM_KEY)/printf.mk
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(DEBUG_MATRIX_SCAN_RATE_ENABLE)), yes)
|
|
||||||
OPT_DEFS += -DDEBUG_MATRIX_SCAN_RATE
|
|
||||||
CONSOLE_ENABLE = yes
|
|
||||||
else ifeq ($(strip $(DEBUG_MATRIX_SCAN_RATE_ENABLE)), api)
|
|
||||||
OPT_DEFS += -DDEBUG_MATRIX_SCAN_RATE
|
|
||||||
endif
|
|
||||||
|
|
||||||
AUDIO_ENABLE ?= no
|
|
||||||
ifeq ($(strip $(AUDIO_ENABLE)), yes)
|
|
||||||
ifeq ($(PLATFORM),CHIBIOS)
|
|
||||||
AUDIO_DRIVER ?= dac_basic
|
|
||||||
ifeq ($(strip $(AUDIO_DRIVER)), dac_basic)
|
|
||||||
OPT_DEFS += -DAUDIO_DRIVER_DAC
|
|
||||||
else ifeq ($(strip $(AUDIO_DRIVER)), dac_additive)
|
|
||||||
OPT_DEFS += -DAUDIO_DRIVER_DAC
|
|
||||||
## stm32f2 and above have a usable DAC unit, f1 do not, and need to use pwm instead
|
|
||||||
else ifeq ($(strip $(AUDIO_DRIVER)), pwm_software)
|
|
||||||
OPT_DEFS += -DAUDIO_DRIVER_PWM
|
|
||||||
else ifeq ($(strip $(AUDIO_DRIVER)), pwm_hardware)
|
|
||||||
OPT_DEFS += -DAUDIO_DRIVER_PWM
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
# fallback for all other platforms is pwm
|
|
||||||
AUDIO_DRIVER ?= pwm_hardware
|
|
||||||
OPT_DEFS += -DAUDIO_DRIVER_PWM
|
|
||||||
endif
|
|
||||||
OPT_DEFS += -DAUDIO_ENABLE
|
|
||||||
COMMON_VPATH += $(QUANTUM_PATH)/audio
|
|
||||||
MUSIC_ENABLE = yes
|
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c
|
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_clicky.c
|
|
||||||
SRC += $(QUANTUM_DIR)/audio/audio.c ## common audio code, hardware agnostic
|
|
||||||
SRC += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/audio_$(strip $(AUDIO_DRIVER)).c
|
|
||||||
SRC += $(QUANTUM_DIR)/audio/voices.c
|
|
||||||
SRC += $(QUANTUM_DIR)/audio/luts.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(SEQUENCER_ENABLE)), yes)
|
|
||||||
MUSIC_ENABLE = yes
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(MIDI_ENABLE)), yes)
|
|
||||||
OPT_DEFS += -DMIDI_ENABLE
|
|
||||||
MUSIC_ENABLE = yes
|
|
||||||
COMMON_VPATH += $(QUANTUM_PATH)/midi
|
|
||||||
SRC += $(QUANTUM_DIR)/midi/midi.c
|
|
||||||
SRC += $(QUANTUM_DIR)/midi/midi_device.c
|
|
||||||
SRC += $(QUANTUM_DIR)/midi/qmk_midi.c
|
|
||||||
SRC += $(QUANTUM_DIR)/midi/sysex_tools.c
|
|
||||||
SRC += $(QUANTUM_DIR)/midi/bytequeue/bytequeue.c
|
|
||||||
SRC += $(QUANTUM_DIR)/midi/bytequeue/interrupt_setting.c
|
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
VALID_STENO_PROTOCOL_TYPES := geminipr txbolt all
|
|
||||||
STENO_PROTOCOL ?= all
|
|
||||||
ifeq ($(strip $(STENO_ENABLE)), yes)
|
|
||||||
ifeq ($(filter $(STENO_PROTOCOL),$(VALID_STENO_PROTOCOL_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid STENO_PROTOCOL,STENO_PROTOCOL="$(STENO_PROTOCOL)" is not a valid stenography protocol)
|
|
||||||
else
|
|
||||||
OPT_DEFS += -DSTENO_ENABLE
|
|
||||||
VIRTSER_ENABLE ?= yes
|
|
||||||
|
|
||||||
ifeq ($(strip $(STENO_PROTOCOL)), geminipr)
|
|
||||||
OPT_DEFS += -DSTENO_ENABLE_GEMINI
|
|
||||||
endif
|
|
||||||
ifeq ($(strip $(STENO_PROTOCOL)), txbolt)
|
|
||||||
OPT_DEFS += -DSTENO_ENABLE_BOLT
|
|
||||||
endif
|
|
||||||
ifeq ($(strip $(STENO_PROTOCOL)), all)
|
|
||||||
OPT_DEFS += -DSTENO_ENABLE_ALL
|
|
||||||
OPT_DEFS += -DSTENO_ENABLE_GEMINI
|
|
||||||
OPT_DEFS += -DSTENO_ENABLE_BOLT
|
|
||||||
endif
|
|
||||||
|
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_steno.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(MOUSEKEY_ENABLE)), yes)
|
|
||||||
MOUSE_ENABLE := yes
|
|
||||||
endif
|
|
||||||
|
|
||||||
VALID_POINTING_DEVICE_DRIVER_TYPES := adns5050 adns9800 analog_joystick azoteq_iqs5xx cirque_pinnacle_i2c cirque_pinnacle_spi paw3204 pmw3320 pmw3360 pmw3389 pimoroni_trackball custom
|
|
||||||
ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
|
|
||||||
ifeq ($(filter $(POINTING_DEVICE_DRIVER),$(VALID_POINTING_DEVICE_DRIVER_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid POINTING_DEVICE_DRIVER,POINTING_DEVICE_DRIVER="$(POINTING_DEVICE_DRIVER)" is not a valid pointing device type)
|
|
||||||
else
|
|
||||||
OPT_DEFS += -DPOINTING_DEVICE_ENABLE
|
|
||||||
MOUSE_ENABLE := yes
|
|
||||||
VPATH += $(QUANTUM_DIR)/pointing_device
|
|
||||||
SRC += $(QUANTUM_DIR)/pointing_device/pointing_device.c
|
|
||||||
SRC += $(QUANTUM_DIR)/pointing_device/pointing_device_drivers.c
|
|
||||||
SRC += $(QUANTUM_DIR)/pointing_device/pointing_device_auto_mouse.c
|
|
||||||
ifneq ($(strip $(POINTING_DEVICE_DRIVER)), custom)
|
|
||||||
SRC += drivers/sensors/$(strip $(POINTING_DEVICE_DRIVER)).c
|
|
||||||
OPT_DEFS += -DPOINTING_DEVICE_DRIVER_$(strip $(shell echo $(POINTING_DEVICE_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
|
||||||
endif
|
|
||||||
OPT_DEFS += -DPOINTING_DEVICE_DRIVER_$(strip $(POINTING_DEVICE_DRIVER))
|
|
||||||
ifeq ($(strip $(POINTING_DEVICE_DRIVER)), adns9800)
|
|
||||||
SPI_DRIVER_REQUIRED = yes
|
|
||||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), analog_joystick)
|
|
||||||
ANALOG_DRIVER_REQUIRED = yes
|
|
||||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), azoteq_iqs5xx)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), cirque_pinnacle_i2c)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
SRC += drivers/sensors/cirque_pinnacle.c
|
|
||||||
SRC += drivers/sensors/cirque_pinnacle_gestures.c
|
|
||||||
SRC += $(QUANTUM_DIR)/pointing_device/pointing_device_gestures.c
|
|
||||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), cirque_pinnacle_spi)
|
|
||||||
SPI_DRIVER_REQUIRED = yes
|
|
||||||
SRC += drivers/sensors/cirque_pinnacle.c
|
|
||||||
SRC += drivers/sensors/cirque_pinnacle_gestures.c
|
|
||||||
SRC += $(QUANTUM_DIR)/pointing_device/pointing_device_gestures.c
|
|
||||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pimoroni_trackball)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
else ifneq ($(filter $(strip $(POINTING_DEVICE_DRIVER)),pmw3360 pmw3389),)
|
|
||||||
SPI_DRIVER_REQUIRED = yes
|
|
||||||
SRC += drivers/sensors/pmw33xx_common.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
QUANTUM_PAINTER_ENABLE ?= no
|
|
||||||
ifeq ($(strip $(QUANTUM_PAINTER_ENABLE)), yes)
|
|
||||||
include $(QUANTUM_DIR)/painter/rules.mk
|
|
||||||
endif
|
|
||||||
|
|
||||||
VALID_EEPROM_DRIVER_TYPES := vendor custom transient i2c spi wear_leveling legacy_stm32_flash
|
|
||||||
EEPROM_DRIVER ?= vendor
|
|
||||||
ifeq ($(filter $(EEPROM_DRIVER),$(VALID_EEPROM_DRIVER_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid EEPROM_DRIVER,EEPROM_DRIVER="$(EEPROM_DRIVER)" is not a valid EEPROM driver)
|
|
||||||
else
|
|
||||||
OPT_DEFS += -DEEPROM_ENABLE
|
|
||||||
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/eeprom
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
|
||||||
COMMON_VPATH += $(PLATFORM_COMMON_DIR)
|
|
||||||
ifeq ($(strip $(EEPROM_DRIVER)), custom)
|
|
||||||
# Custom EEPROM implementation -- only needs to implement init/erase/read_block/write_block
|
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_CUSTOM
|
|
||||||
SRC += eeprom_driver.c
|
|
||||||
else ifeq ($(strip $(EEPROM_DRIVER)), wear_leveling)
|
|
||||||
# Wear-leveling EEPROM implementation
|
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING
|
|
||||||
SRC += eeprom_driver.c eeprom_wear_leveling.c
|
|
||||||
else ifeq ($(strip $(EEPROM_DRIVER)), i2c)
|
|
||||||
# External I2C EEPROM implementation
|
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_I2C
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
SRC += eeprom_driver.c eeprom_i2c.c
|
|
||||||
else ifeq ($(strip $(EEPROM_DRIVER)), spi)
|
|
||||||
# External SPI EEPROM implementation
|
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_SPI
|
|
||||||
SPI_DRIVER_REQUIRED = yes
|
|
||||||
SRC += eeprom_driver.c eeprom_spi.c
|
|
||||||
else ifeq ($(strip $(EEPROM_DRIVER)), legacy_stm32_flash)
|
|
||||||
# STM32 Emulated EEPROM, backed by MCU flash (soon to be deprecated)
|
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_LEGACY_EMULATED_FLASH
|
|
||||||
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/flash
|
|
||||||
SRC += eeprom_driver.c eeprom_legacy_emulated_flash.c legacy_flash_ops.c
|
|
||||||
else ifeq ($(strip $(EEPROM_DRIVER)), transient)
|
|
||||||
# Transient EEPROM implementation -- no data storage but provides runtime area for it
|
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
|
|
||||||
SRC += eeprom_driver.c eeprom_transient.c
|
|
||||||
else ifeq ($(strip $(EEPROM_DRIVER)), vendor)
|
|
||||||
# Vendor-implemented EEPROM
|
|
||||||
OPT_DEFS += -DEEPROM_VENDOR
|
|
||||||
ifeq ($(PLATFORM),AVR)
|
|
||||||
# Automatically provided by avr-libc, nothing required
|
|
||||||
else ifeq ($(PLATFORM),CHIBIOS)
|
|
||||||
ifneq ($(filter %_STM32F072xB %_STM32F042x6, $(MCU_SERIES)_$(MCU_LDSCRIPT)),)
|
|
||||||
# STM32 Emulated EEPROM, backed by MCU flash (soon to be deprecated)
|
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_LEGACY_EMULATED_FLASH
|
|
||||||
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/flash
|
|
||||||
SRC += eeprom_driver.c eeprom_legacy_emulated_flash.c legacy_flash_ops.c
|
|
||||||
else ifneq ($(filter $(MCU_SERIES),STM32F1xx STM32F3xx STM32F4xx STM32L4xx STM32G4xx WB32F3G71xx WB32FQ95xx GD32VF103),)
|
|
||||||
# Wear-leveling EEPROM implementation, backed by MCU flash
|
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING
|
|
||||||
SRC += eeprom_driver.c eeprom_wear_leveling.c
|
|
||||||
WEAR_LEVELING_DRIVER ?= embedded_flash
|
|
||||||
else ifneq ($(filter $(MCU_SERIES),STM32L0xx STM32L1xx),)
|
|
||||||
# True EEPROM on STM32L0xx, L1xx
|
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_L0_L1
|
|
||||||
SRC += eeprom_driver.c eeprom_stm32_L0_L1.c
|
|
||||||
else ifneq ($(filter $(MCU_SERIES),RP2040),)
|
|
||||||
# Wear-leveling EEPROM implementation, backed by RP2040 flash
|
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING
|
|
||||||
SRC += eeprom_driver.c eeprom_wear_leveling.c
|
|
||||||
WEAR_LEVELING_DRIVER ?= rp2040_flash
|
|
||||||
else ifneq ($(filter $(MCU_SERIES),KL2x K20x),)
|
|
||||||
# Teensy EEPROM implementations
|
|
||||||
OPT_DEFS += -DEEPROM_KINETIS_FLEXRAM
|
|
||||||
SRC += eeprom_kinetis_flexram.c
|
|
||||||
else
|
|
||||||
# Fall back to transient, i.e. non-persistent
|
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
|
|
||||||
SRC += eeprom_driver.c eeprom_transient.c
|
|
||||||
endif
|
|
||||||
else ifeq ($(PLATFORM),ARM_ATSAM)
|
|
||||||
# arm_atsam EEPROM
|
|
||||||
OPT_DEFS += -DEEPROM_SAMD
|
|
||||||
SRC += eeprom_samd.c
|
|
||||||
else ifeq ($(PLATFORM),TEST)
|
|
||||||
# Test harness "EEPROM"
|
|
||||||
OPT_DEFS += -DEEPROM_TEST_HARNESS
|
|
||||||
SRC += eeprom.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
VALID_WEAR_LEVELING_DRIVER_TYPES := custom embedded_flash spi_flash rp2040_flash legacy
|
|
||||||
WEAR_LEVELING_DRIVER ?= none
|
|
||||||
ifneq ($(strip $(WEAR_LEVELING_DRIVER)),none)
|
|
||||||
ifeq ($(filter $(WEAR_LEVELING_DRIVER),$(VALID_WEAR_LEVELING_DRIVER_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid WEAR_LEVELING_DRIVER,WEAR_LEVELING_DRIVER="$(WEAR_LEVELING_DRIVER)" is not a valid wear leveling driver)
|
|
||||||
else
|
|
||||||
FNV_ENABLE := yes
|
|
||||||
OPT_DEFS += -DWEAR_LEVELING_ENABLE
|
|
||||||
OPT_DEFS += -DWEAR_LEVELING_$(strip $(shell echo $(WEAR_LEVELING_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
|
||||||
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/wear_leveling
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/wear_leveling
|
|
||||||
COMMON_VPATH += $(QUANTUM_DIR)/wear_leveling
|
|
||||||
SRC += wear_leveling.c
|
|
||||||
ifeq ($(strip $(WEAR_LEVELING_DRIVER)), embedded_flash)
|
|
||||||
OPT_DEFS += -DHAL_USE_EFL
|
|
||||||
SRC += wear_leveling_efl.c
|
|
||||||
POST_CONFIG_H += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/wear_leveling/wear_leveling_efl_config.h
|
|
||||||
else ifeq ($(strip $(WEAR_LEVELING_DRIVER)), spi_flash)
|
|
||||||
FLASH_DRIVER := spi
|
|
||||||
SRC += wear_leveling_flash_spi.c
|
|
||||||
POST_CONFIG_H += $(DRIVER_PATH)/wear_leveling/wear_leveling_flash_spi_config.h
|
|
||||||
else ifeq ($(strip $(WEAR_LEVELING_DRIVER)), rp2040_flash)
|
|
||||||
SRC += wear_leveling_rp2040_flash.c
|
|
||||||
POST_CONFIG_H += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_PATH)/wear_leveling/wear_leveling_rp2040_flash_config.h
|
|
||||||
else ifeq ($(strip $(WEAR_LEVELING_DRIVER)), legacy)
|
|
||||||
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash
|
|
||||||
SRC += legacy_flash_ops.c wear_leveling_legacy.c
|
|
||||||
POST_CONFIG_H += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/wear_leveling/wear_leveling_legacy_config.h
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
VALID_FLASH_DRIVER_TYPES := spi
|
|
||||||
FLASH_DRIVER ?= none
|
|
||||||
ifneq ($(strip $(FLASH_DRIVER)), none)
|
|
||||||
ifeq ($(filter $(FLASH_DRIVER),$(VALID_FLASH_DRIVER_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid FLASH_DRIVER,FLASH_DRIVER="$(FLASH_DRIVER)" is not a valid flash driver)
|
|
||||||
else
|
|
||||||
OPT_DEFS += -DFLASH_ENABLE
|
|
||||||
ifeq ($(strip $(FLASH_DRIVER)),spi)
|
|
||||||
SPI_DRIVER_REQUIRED = yes
|
|
||||||
OPT_DEFS += -DFLASH_DRIVER -DFLASH_SPI
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/flash
|
|
||||||
SRC += flash_spi.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
RGBLIGHT_ENABLE ?= no
|
|
||||||
VALID_RGBLIGHT_TYPES := ws2812 apa102 custom
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
|
|
||||||
RGBLIGHT_DRIVER ?= ws2812
|
|
||||||
|
|
||||||
ifeq ($(filter $(RGBLIGHT_DRIVER),$(VALID_RGBLIGHT_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid RGBLIGHT_DRIVER,RGBLIGHT_DRIVER="$(RGBLIGHT_DRIVER)" is not a valid RGB type)
|
|
||||||
else
|
|
||||||
COMMON_VPATH += $(QUANTUM_DIR)/rgblight
|
|
||||||
POST_CONFIG_H += $(QUANTUM_DIR)/rgblight/rgblight_post_config.h
|
|
||||||
OPT_DEFS += -DRGBLIGHT_ENABLE
|
|
||||||
OPT_DEFS += -DRGBLIGHT_$(strip $(shell echo $(RGBLIGHT_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
|
||||||
SRC += $(QUANTUM_DIR)/color.c
|
|
||||||
SRC += $(QUANTUM_DIR)/rgblight/rgblight.c
|
|
||||||
SRC += $(QUANTUM_DIR)/rgblight/rgblight_drivers.c
|
|
||||||
CIE1931_CURVE := yes
|
|
||||||
RGB_KEYCODES_ENABLE := yes
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGBLIGHT_DRIVER)), ws2812)
|
|
||||||
WS2812_DRIVER_REQUIRED := yes
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGBLIGHT_DRIVER)), apa102)
|
|
||||||
APA102_DRIVER_REQUIRED := yes
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(VELOCIKEY_ENABLE)), yes)
|
|
||||||
OPT_DEFS += -DVELOCIKEY_ENABLE
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Deprecated driver names - do not use
|
|
||||||
ifeq ($(strip $(LED_MATRIX_DRIVER)), aw20216)
|
|
||||||
LED_MATRIX_DRIVER := aw20216s
|
|
||||||
endif
|
|
||||||
ifeq ($(strip $(LED_MATRIX_DRIVER)), ckled2001)
|
|
||||||
LED_MATRIX_DRIVER := snled27351
|
|
||||||
endif
|
|
||||||
|
|
||||||
LED_MATRIX_ENABLE ?= no
|
|
||||||
VALID_LED_MATRIX_TYPES := is31fl3218 is31fl3729 is31fl3731 is31fl3733 is31fl3736 is31fl3737 is31fl3741 is31fl3742a is31fl3743a is31fl3745 is31fl3746a snled27351 custom
|
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_ENABLE)), yes)
|
|
||||||
ifeq ($(filter $(LED_MATRIX_DRIVER),$(VALID_LED_MATRIX_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid LED_MATRIX_DRIVER,LED_MATRIX_DRIVER="$(LED_MATRIX_DRIVER)" is not a valid matrix type)
|
|
||||||
endif
|
|
||||||
OPT_DEFS += -DLED_MATRIX_ENABLE
|
|
||||||
OPT_DEFS += -DLED_MATRIX_$(strip $(shell echo $(LED_MATRIX_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
|
||||||
|
|
||||||
COMMON_VPATH += $(QUANTUM_DIR)/led_matrix
|
|
||||||
COMMON_VPATH += $(QUANTUM_DIR)/led_matrix/animations
|
|
||||||
COMMON_VPATH += $(QUANTUM_DIR)/led_matrix/animations/runners
|
|
||||||
POST_CONFIG_H += $(QUANTUM_DIR)/led_matrix/post_config.h
|
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_backlight.c
|
|
||||||
SRC += $(QUANTUM_DIR)/led_matrix/led_matrix.c
|
|
||||||
SRC += $(QUANTUM_DIR)/led_matrix/led_matrix_drivers.c
|
|
||||||
LIB8TION_ENABLE := yes
|
|
||||||
CIE1931_CURVE := yes
|
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_DRIVER)), is31fl3218)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3218-mono.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_DRIVER)), is31fl3729)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3729-mono.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_DRIVER)), is31fl3731)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3731-mono.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_DRIVER)), is31fl3733)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3733-mono.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_DRIVER)), is31fl3736)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3736-mono.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_DRIVER)), is31fl3737)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3737-mono.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_DRIVER)), is31fl3741)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3741-mono.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_DRIVER)), is31fl3742a)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3742a-mono.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_DRIVER)), is31fl3743a)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3743a-mono.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_DRIVER)), is31fl3745)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3745-mono.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_DRIVER)), is31fl3746a)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3746a-mono.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_DRIVER)), snled27351)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led
|
|
||||||
SRC += snled27351-mono.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Deprecated driver names - do not use
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), aw20216)
|
|
||||||
RGB_MATRIX_DRIVER := aw20216s
|
|
||||||
endif
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), ckled2001)
|
|
||||||
RGB_MATRIX_DRIVER := snled27351
|
|
||||||
endif
|
|
||||||
|
|
||||||
RGB_MATRIX_ENABLE ?= no
|
|
||||||
|
|
||||||
VALID_RGB_MATRIX_TYPES := aw20216s is31fl3218 is31fl3729 is31fl3731 is31fl3733 is31fl3736 is31fl3737 is31fl3741 is31fl3742a is31fl3743a is31fl3745 is31fl3746a snled27351 ws2812 custom
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
|
|
||||||
ifeq ($(filter $(RGB_MATRIX_DRIVER),$(VALID_RGB_MATRIX_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid RGB_MATRIX_DRIVER,RGB_MATRIX_DRIVER="$(RGB_MATRIX_DRIVER)" is not a valid matrix type)
|
|
||||||
endif
|
|
||||||
OPT_DEFS += -DRGB_MATRIX_ENABLE
|
|
||||||
OPT_DEFS += -DRGB_MATRIX_$(strip $(shell echo $(RGB_MATRIX_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
|
||||||
|
|
||||||
COMMON_VPATH += $(QUANTUM_DIR)/rgb_matrix
|
|
||||||
COMMON_VPATH += $(QUANTUM_DIR)/rgb_matrix/animations
|
|
||||||
COMMON_VPATH += $(QUANTUM_DIR)/rgb_matrix/animations/runners
|
|
||||||
POST_CONFIG_H += $(QUANTUM_DIR)/rgb_matrix/post_config.h
|
|
||||||
SRC += $(QUANTUM_DIR)/color.c
|
|
||||||
SRC += $(QUANTUM_DIR)/rgb_matrix/rgb_matrix.c
|
|
||||||
SRC += $(QUANTUM_DIR)/rgb_matrix/rgb_matrix_drivers.c
|
|
||||||
LIB8TION_ENABLE := yes
|
|
||||||
CIE1931_CURVE := yes
|
|
||||||
RGB_KEYCODES_ENABLE := yes
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), aw20216s)
|
|
||||||
SPI_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led
|
|
||||||
SRC += aw20216s.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), is31fl3218)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3218.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), is31fl3729)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3729.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), is31fl3731)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3731.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), is31fl3733)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3733.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), is31fl3736)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3736.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), is31fl3737)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3737.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), is31fl3741)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3741.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), is31fl3742a)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3742a.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), is31fl3743a)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3743a.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), is31fl3745)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3745.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), is31fl3746a)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
|
||||||
SRC += is31fl3746a.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), snled27351)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led
|
|
||||||
SRC += snled27351.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), ws2812)
|
|
||||||
WS2812_DRIVER_REQUIRED := yes
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), apa102)
|
|
||||||
APA102_DRIVER_REQUIRED := yes
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_CUSTOM_KB)), yes)
|
|
||||||
OPT_DEFS += -DRGB_MATRIX_CUSTOM_KB
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_CUSTOM_USER)), yes)
|
|
||||||
OPT_DEFS += -DRGB_MATRIX_CUSTOM_USER
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_KEYCODES_ENABLE)), yes)
|
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_rgb.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
VARIABLE_TRACE ?= no
|
|
||||||
ifneq ($(strip $(VARIABLE_TRACE)),no)
|
|
||||||
SRC += $(QUANTUM_DIR)/variable_trace.c
|
|
||||||
OPT_DEFS += -DNUM_TRACED_VARIABLES=$(strip $(VARIABLE_TRACE))
|
|
||||||
ifneq ($(strip $(MAX_VARIABLE_TRACE_SIZE)),)
|
|
||||||
OPT_DEFS += -DMAX_VARIABLE_TRACE_SIZE=$(strip $(MAX_VARIABLE_TRACE_SIZE))
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(SLEEP_LED_ENABLE)), yes)
|
|
||||||
SRC += $(PLATFORM_COMMON_DIR)/sleep_led.c
|
|
||||||
OPT_DEFS += -DSLEEP_LED_ENABLE
|
|
||||||
|
|
||||||
NO_SUSPEND_POWER_DOWN := yes
|
|
||||||
endif
|
|
||||||
|
|
||||||
VALID_BACKLIGHT_TYPES := pwm timer software custom
|
|
||||||
|
|
||||||
BACKLIGHT_ENABLE ?= no
|
|
||||||
BACKLIGHT_DRIVER ?= pwm
|
|
||||||
ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
|
|
||||||
ifeq ($(filter $(BACKLIGHT_DRIVER),$(VALID_BACKLIGHT_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid BACKLIGHT_DRIVER,BACKLIGHT_DRIVER="$(BACKLIGHT_DRIVER)" is not a valid backlight type)
|
|
||||||
endif
|
|
||||||
|
|
||||||
COMMON_VPATH += $(QUANTUM_DIR)/backlight
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/backlight
|
|
||||||
SRC += $(QUANTUM_DIR)/backlight/backlight.c
|
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_backlight.c
|
|
||||||
OPT_DEFS += -DBACKLIGHT_ENABLE
|
|
||||||
OPT_DEFS += -DBACKLIGHT_$(strip $(shell echo $(BACKLIGHT_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
|
||||||
|
|
||||||
ifneq ($(strip $(BACKLIGHT_DRIVER)), custom)
|
|
||||||
SRC += $(QUANTUM_DIR)/backlight/backlight_driver_common.c
|
|
||||||
|
|
||||||
ifeq ($(strip $(BACKLIGHT_DRIVER)), software)
|
|
||||||
SRC += $(DRIVER_PATH)/backlight/backlight_software.c
|
|
||||||
else
|
|
||||||
SRC += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/backlight_$(strip $(BACKLIGHT_DRIVER)).c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(CIE1931_CURVE)), yes)
|
|
||||||
OPT_DEFS += -DUSE_CIE1931_CURVE
|
|
||||||
LED_TABLES := yes
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(LED_TABLES)), yes)
|
|
||||||
SRC += $(QUANTUM_DIR)/led_tables.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(VIA_ENABLE)), yes)
|
|
||||||
DYNAMIC_KEYMAP_ENABLE := yes
|
|
||||||
RAW_ENABLE := yes
|
|
||||||
BOOTMAGIC_ENABLE := yes
|
|
||||||
TRI_LAYER_ENABLE := yes
|
|
||||||
endif
|
|
||||||
|
|
||||||
VALID_CUSTOM_MATRIX_TYPES:= yes lite no
|
|
||||||
|
|
||||||
CUSTOM_MATRIX ?= no
|
|
||||||
ifneq ($(strip $(CUSTOM_MATRIX)), yes)
|
|
||||||
ifeq ($(filter $(CUSTOM_MATRIX),$(VALID_CUSTOM_MATRIX_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid CUSTOM_MATRIX,CUSTOM_MATRIX="$(CUSTOM_MATRIX)" is not a valid custom matrix type)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Include common stuff for all non custom matrix users
|
|
||||||
QUANTUM_SRC += $(QUANTUM_DIR)/matrix_common.c
|
|
||||||
|
|
||||||
# if 'lite' then skip the actual matrix implementation
|
|
||||||
ifneq ($(strip $(CUSTOM_MATRIX)), lite)
|
|
||||||
# Include the standard or split matrix code if needed
|
|
||||||
QUANTUM_SRC += $(QUANTUM_DIR)/matrix.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Debounce Modules. Set DEBOUNCE_TYPE=custom if including one manually.
|
|
||||||
DEBOUNCE_TYPE ?= sym_defer_g
|
|
||||||
ifneq ($(strip $(DEBOUNCE_TYPE)), custom)
|
|
||||||
QUANTUM_SRC += $(QUANTUM_DIR)/debounce/$(strip $(DEBOUNCE_TYPE)).c
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
VALID_SERIAL_DRIVER_TYPES := bitbang usart vendor
|
|
||||||
|
|
||||||
SERIAL_DRIVER ?= bitbang
|
|
||||||
ifeq ($(filter $(SERIAL_DRIVER),$(VALID_SERIAL_DRIVER_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid SERIAL_DRIVER,SERIAL_DRIVER="$(SERIAL_DRIVER)" is not a valid SERIAL driver)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
|
|
||||||
POST_CONFIG_H += $(QUANTUM_DIR)/split_common/post_config.h
|
|
||||||
OPT_DEFS += -DSPLIT_KEYBOARD
|
|
||||||
CRC_ENABLE := yes
|
|
||||||
|
|
||||||
# Include files used by all split keyboards
|
|
||||||
QUANTUM_SRC += $(QUANTUM_DIR)/split_common/split_util.c
|
|
||||||
|
|
||||||
# Determine which (if any) transport files are required
|
|
||||||
ifneq ($(strip $(SPLIT_TRANSPORT)), custom)
|
|
||||||
QUANTUM_SRC += $(QUANTUM_DIR)/split_common/transport.c \
|
|
||||||
$(QUANTUM_DIR)/split_common/transactions.c
|
|
||||||
|
|
||||||
OPT_DEFS += -DSPLIT_COMMON_TRANSACTIONS
|
|
||||||
|
|
||||||
# Functions added via QUANTUM_LIB_SRC are only included in the final binary if they're called.
|
|
||||||
# Unused functions are pruned away, which is why we can add multiple drivers here without bloat.
|
|
||||||
ifeq ($(PLATFORM),AVR)
|
|
||||||
ifneq ($(NO_I2C),yes)
|
|
||||||
QUANTUM_LIB_SRC += i2c_master.c \
|
|
||||||
i2c_slave.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
OPT_DEFS += -DSERIAL_DRIVER_$(strip $(shell echo $(SERIAL_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
|
||||||
ifeq ($(strip $(SERIAL_DRIVER)), bitbang)
|
|
||||||
QUANTUM_LIB_SRC += serial.c
|
|
||||||
else
|
|
||||||
QUANTUM_LIB_SRC += serial_protocol.c
|
|
||||||
QUANTUM_LIB_SRC += serial_$(strip $(SERIAL_DRIVER)).c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
COMMON_VPATH += $(QUANTUM_PATH)/split_common
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(FNV_ENABLE)), yes)
|
|
||||||
OPT_DEFS += -DFNV_ENABLE
|
|
||||||
VPATH += $(LIB_PATH)/fnv
|
|
||||||
SRC += qmk_fnv_type_validation.c hash_32a.c hash_64a.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(LIB8TION_ENABLE)), yes)
|
|
||||||
ifneq (,$(filter $(MCU), atmega16u2 atmega32u2 at90usb162))
|
|
||||||
# ATmegaxxU2 does not have hardware MUL instruction - lib8tion must be told to use software multiplication routines
|
|
||||||
OPT_DEFS += -DLIB8_ATTINY
|
|
||||||
endif
|
|
||||||
SRC += $(LIB_PATH)/lib8tion/lib8tion.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
VALID_HAPTIC_DRIVER_TYPES := drv2605l solenoid
|
|
||||||
ifeq ($(strip $(HAPTIC_ENABLE)),yes)
|
|
||||||
ifeq ($(filter $(HAPTIC_DRIVER),$(VALID_HAPTIC_DRIVER_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid HAPTIC_DRIVER,HAPTIC_DRIVER="$(HAPTIC_DRIVER)" is not a valid Haptic driver)
|
|
||||||
else
|
|
||||||
OPT_DEFS += -DHAPTIC_$(strip $(shell echo $(HAPTIC_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/haptic
|
|
||||||
|
|
||||||
ifeq ($(strip $(HAPTIC_DRIVER)), drv2605l)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
SRC += drv2605l.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(HAPTIC_DRIVER)), solenoid)
|
|
||||||
SRC += solenoid.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(HD44780_ENABLE)), yes)
|
|
||||||
OPT_DEFS += -DHD44780_ENABLE
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/lcd
|
|
||||||
SRC += hd44780.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
VALID_OLED_DRIVER_TYPES := custom ssd1306
|
|
||||||
OLED_DRIVER ?= ssd1306
|
|
||||||
VALID_OLED_TRANSPORT_TYPES := i2c spi custom
|
|
||||||
OLED_TRANSPORT ?= i2c
|
|
||||||
ifeq ($(strip $(OLED_ENABLE)), yes)
|
|
||||||
ifeq ($(filter $(OLED_DRIVER),$(VALID_OLED_DRIVER_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid OLED_DRIVER,OLED_DRIVER="$(OLED_DRIVER)" is not a valid OLED driver)
|
|
||||||
else
|
|
||||||
ifeq ($(filter $(OLED_TRANSPORT),$(VALID_OLED_TRANSPORT_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid OLED_TRANSPORT,OLED_TRANSPORT="$(OLED_TRANSPORT)" is not a valid OLED transport)
|
|
||||||
else
|
|
||||||
OPT_DEFS += -DOLED_ENABLE
|
|
||||||
OPT_DEFS += -DOLED_$(strip $(shell echo $(OLED_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/oled
|
|
||||||
ifneq ($(strip $(OLED_DRIVER)), custom)
|
|
||||||
SRC += oled_driver.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
OPT_DEFS += -DOLED_TRANSPORT_$(strip $(shell echo $(OLED_TRANSPORT) | tr '[:lower:]' '[:upper:]'))
|
|
||||||
ifeq ($(strip $(OLED_TRANSPORT)), i2c)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
endif
|
|
||||||
ifeq ($(strip $(OLED_TRANSPORT)), spi)
|
|
||||||
SPI_DRIVER_REQUIRED = yes
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(ST7565_ENABLE)), yes)
|
|
||||||
OPT_DEFS += -DST7565_ENABLE
|
|
||||||
SPI_DRIVER_REQUIRED = yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/oled # For glcdfont.h
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/lcd
|
|
||||||
SRC += st7565.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(UCIS_ENABLE)), yes)
|
|
||||||
OPT_DEFS += -DUCIS_ENABLE
|
|
||||||
UNICODE_COMMON := yes
|
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_ucis.c \
|
|
||||||
$(QUANTUM_DIR)/unicode/ucis.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(UNICODEMAP_ENABLE)), yes)
|
|
||||||
OPT_DEFS += -DUNICODEMAP_ENABLE
|
|
||||||
UNICODE_COMMON := yes
|
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_unicodemap.c \
|
|
||||||
$(QUANTUM_DIR)/unicode/unicodemap.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(UNICODE_ENABLE)), yes)
|
|
||||||
OPT_DEFS += -DUNICODE_ENABLE
|
|
||||||
UNICODE_COMMON := yes
|
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(UNICODE_COMMON)), yes)
|
|
||||||
OPT_DEFS += -DUNICODE_COMMON_ENABLE
|
|
||||||
COMMON_VPATH += $(QUANTUM_DIR)/unicode
|
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c \
|
|
||||||
$(QUANTUM_DIR)/unicode/unicode.c \
|
|
||||||
$(QUANTUM_DIR)/unicode/utf8.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(PS2_MOUSE_ENABLE)), yes)
|
|
||||||
PS2_ENABLE := yes
|
|
||||||
MOUSE_ENABLE := yes
|
|
||||||
SRC += ps2_mouse.c
|
|
||||||
OPT_DEFS += -DPS2_MOUSE_ENABLE
|
|
||||||
endif
|
|
||||||
|
|
||||||
VALID_PS2_DRIVER_TYPES := busywait interrupt usart vendor
|
|
||||||
|
|
||||||
PS2_DRIVER ?= busywait
|
|
||||||
ifeq ($(strip $(PS2_ENABLE)), yes)
|
|
||||||
ifeq ($(filter $(PS2_DRIVER),$(VALID_PS2_DRIVER_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid PS2_DRIVER,PS2_DRIVER="$(PS2_DRIVER)" is not a valid PS/2 driver)
|
|
||||||
endif
|
|
||||||
|
|
||||||
OPT_DEFS += -DPS2_DRIVER_$(strip $(shell echo $(PS2_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
|
||||||
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/ps2
|
|
||||||
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/ps2
|
|
||||||
OPT_DEFS += -DPS2_ENABLE
|
|
||||||
|
|
||||||
ifneq ($(strip $(PS2_DRIVER)), vendor)
|
|
||||||
SRC += ps2_io.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
SRC += ps2_$(strip $(PS2_DRIVER)).c
|
|
||||||
endif
|
|
||||||
|
|
||||||
JOYSTICK_ENABLE ?= no
|
|
||||||
VALID_JOYSTICK_TYPES := analog digital
|
|
||||||
JOYSTICK_DRIVER ?= analog
|
|
||||||
ifeq ($(strip $(JOYSTICK_ENABLE)), yes)
|
|
||||||
ifeq ($(filter $(JOYSTICK_DRIVER),$(VALID_JOYSTICK_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid JOYSTICK_DRIVER,JOYSTICK_DRIVER="$(JOYSTICK_DRIVER)" is not a valid joystick driver)
|
|
||||||
endif
|
|
||||||
OPT_DEFS += -DJOYSTICK_ENABLE
|
|
||||||
OPT_DEFS += -DJOYSTICK_$(strip $(shell echo $(JOYSTICK_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_joystick.c
|
|
||||||
SRC += $(QUANTUM_DIR)/joystick.c
|
|
||||||
|
|
||||||
ifeq ($(strip $(JOYSTICK_DRIVER)), analog)
|
|
||||||
ANALOG_DRIVER_REQUIRED = yes
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
USBPD_ENABLE ?= no
|
|
||||||
VALID_USBPD_DRIVER_TYPES = custom vendor
|
|
||||||
USBPD_DRIVER ?= vendor
|
|
||||||
ifeq ($(strip $(USBPD_ENABLE)), yes)
|
|
||||||
ifeq ($(filter $(strip $(USBPD_DRIVER)),$(VALID_USBPD_DRIVER_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid USBPD_DRIVER,USBPD_DRIVER="$(USBPD_DRIVER)" is not a valid USBPD driver)
|
|
||||||
else
|
|
||||||
OPT_DEFS += -DUSBPD_ENABLE
|
|
||||||
ifeq ($(strip $(USBPD_DRIVER)), vendor)
|
|
||||||
# Vendor-specific implementations
|
|
||||||
OPT_DEFS += -DUSBPD_VENDOR
|
|
||||||
ifeq ($(strip $(MCU_SERIES)), STM32G4xx)
|
|
||||||
OPT_DEFS += -DUSBPD_STM32G4
|
|
||||||
SRC += usbpd_stm32g4.c
|
|
||||||
else
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid USBPD_DRIVER,There is no vendor-provided USBPD driver available)
|
|
||||||
endif
|
|
||||||
else ifeq ($(strip $(USBPD_DRIVER)), custom)
|
|
||||||
OPT_DEFS += -DUSBPD_CUSTOM
|
|
||||||
# Board designers can add their own driver to $(SRC)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
BLUETOOTH_ENABLE ?= no
|
|
||||||
VALID_BLUETOOTH_DRIVER_TYPES := bluefruit_le custom rn42
|
|
||||||
ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
|
|
||||||
ifeq ($(filter $(strip $(BLUETOOTH_DRIVER)),$(VALID_BLUETOOTH_DRIVER_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid BLUETOOTH_DRIVER,BLUETOOTH_DRIVER="$(BLUETOOTH_DRIVER)" is not a valid Bluetooth driver type)
|
|
||||||
endif
|
|
||||||
OPT_DEFS += -DBLUETOOTH_ENABLE
|
|
||||||
OPT_DEFS += -DBLUETOOTH_$(strip $(shell echo $(BLUETOOTH_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
|
||||||
NO_USB_STARTUP_CHECK := yes
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/bluetooth
|
|
||||||
SRC += outputselect.c
|
|
||||||
|
|
||||||
ifeq ($(strip $(BLUETOOTH_DRIVER)), bluefruit_le)
|
|
||||||
SPI_DRIVER_REQUIRED = yes
|
|
||||||
ANALOG_DRIVER_REQUIRED = yes
|
|
||||||
SRC += $(DRIVER_PATH)/bluetooth/bluetooth.c
|
|
||||||
SRC += $(DRIVER_PATH)/bluetooth/bluefruit_le.cpp
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(BLUETOOTH_DRIVER)), rn42)
|
|
||||||
UART_DRIVER_REQUIRED = yes
|
|
||||||
SRC += $(DRIVER_PATH)/bluetooth/bluetooth.c
|
|
||||||
SRC += $(DRIVER_PATH)/bluetooth/rn42.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ENCODER_ENABLE ?= no
|
|
||||||
ENCODER_DRIVER ?= quadrature
|
|
||||||
VALID_ENCODER_DRIVER_TYPES := quadrature custom
|
|
||||||
ifeq ($(strip $(ENCODER_ENABLE)), yes)
|
|
||||||
ifeq ($(filter $(ENCODER_DRIVER),$(VALID_ENCODER_DRIVER_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid ENCODER_DRIVER,ENCODER_DRIVER="$(ENCODER_DRIVER)" is not a valid encoder driver)
|
|
||||||
endif
|
|
||||||
SRC += $(QUANTUM_DIR)/encoder.c
|
|
||||||
OPT_DEFS += -DENCODER_ENABLE
|
|
||||||
OPT_DEFS += -DENCODER_DRIVER_$(strip $(shell echo $(ENCODER_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
|
||||||
|
|
||||||
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/encoder
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/encoder
|
|
||||||
|
|
||||||
ifneq ($(strip $(ENCODER_DRIVER)), custom)
|
|
||||||
SRC += encoder_$(strip $(ENCODER_DRIVER)).c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(ENCODER_MAP_ENABLE)), yes)
|
|
||||||
OPT_DEFS += -DENCODER_MAP_ENABLE
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(DIP_SWITCH_ENABLE)), yes)
|
|
||||||
ifeq ($(strip $(DIP_SWITCH_MAP_ENABLE)), yes)
|
|
||||||
OPT_DEFS += -DDIP_SWITCH_MAP_ENABLE
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
VALID_WS2812_DRIVER_TYPES := bitbang custom i2c pwm spi vendor
|
|
||||||
|
|
||||||
WS2812_DRIVER ?= bitbang
|
|
||||||
ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes)
|
|
||||||
ifeq ($(filter $(WS2812_DRIVER),$(VALID_WS2812_DRIVER_TYPES)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,Invalid WS2812_DRIVER,WS2812_DRIVER="$(WS2812_DRIVER)" is not a valid WS2812 driver)
|
|
||||||
endif
|
|
||||||
|
|
||||||
OPT_DEFS += -DWS2812_$(strip $(shell echo $(WS2812_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
|
||||||
|
|
||||||
SRC += ws2812_$(strip $(WS2812_DRIVER)).c
|
|
||||||
|
|
||||||
ifeq ($(strip $(PLATFORM)), CHIBIOS)
|
|
||||||
ifeq ($(strip $(WS2812_DRIVER)), pwm)
|
|
||||||
OPT_DEFS += -DSTM32_DMA_REQUIRED=TRUE
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
# add extra deps
|
|
||||||
ifeq ($(strip $(WS2812_DRIVER)), i2c)
|
|
||||||
I2C_DRIVER_REQUIRED = yes
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(APA102_DRIVER_REQUIRED)), yes)
|
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led
|
|
||||||
SRC += apa102.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(ANALOG_DRIVER_REQUIRED)), yes)
|
|
||||||
OPT_DEFS += -DHAL_USE_ADC=TRUE
|
|
||||||
QUANTUM_LIB_SRC += analog.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(I2C_DRIVER_REQUIRED)), yes)
|
|
||||||
OPT_DEFS += -DHAL_USE_I2C=TRUE
|
|
||||||
QUANTUM_LIB_SRC += i2c_master.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(SPI_DRIVER_REQUIRED)), yes)
|
|
||||||
OPT_DEFS += -DHAL_USE_SPI=TRUE
|
|
||||||
QUANTUM_LIB_SRC += spi_master.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(UART_DRIVER_REQUIRED)), yes)
|
|
||||||
ifeq ($(strip $(PLATFORM)), CHIBIOS)
|
|
||||||
ifneq ($(filter $(MCU_SERIES),RP2040),)
|
|
||||||
OPT_DEFS += -DHAL_USE_SIO=TRUE
|
|
||||||
QUANTUM_LIB_SRC += uart_sio.c
|
|
||||||
else
|
|
||||||
OPT_DEFS += -DHAL_USE_SERIAL=TRUE
|
|
||||||
QUANTUM_LIB_SRC += uart_serial.c
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
QUANTUM_LIB_SRC += uart.c
|
|
||||||
endif
|
|
||||||
endif
|
|
|
@ -1,419 +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
|
|
||||||
|
|
||||||
#---------------- C Compiler Options ----------------
|
|
||||||
|
|
||||||
ifeq ($(strip $(LTO_ENABLE)), yes)
|
|
||||||
ifeq ($(PLATFORM),ARM_ATSAM)
|
|
||||||
$(info Enabling LTO on arm_atsam-targeting boards is known to have a high likelihood of failure.)
|
|
||||||
$(info If unsure, set LTO_ENABLE = no.)
|
|
||||||
endif
|
|
||||||
CDEFS += -flto
|
|
||||||
CDEFS += -DLTO_ENABLE
|
|
||||||
endif
|
|
||||||
|
|
||||||
DEBUG_ENABLE ?= yes
|
|
||||||
ifeq ($(strip $(SKIP_DEBUG_INFO)),yes)
|
|
||||||
DEBUG_ENABLE=no
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(DEBUG_ENABLE)),yes)
|
|
||||||
CFLAGS += -g$(DEBUG)
|
|
||||||
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 ----------------
|
|
||||||
|
|
||||||
ifeq ($(strip $(DEBUG_ENABLE)),yes)
|
|
||||||
CXXFLAGS += -g$(DEBUG)
|
|
||||||
endif
|
|
||||||
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 ----------------
|
|
||||||
|
|
||||||
CREATE_MAP ?= yes
|
|
||||||
ifeq ($(CREATE_MAP),yes)
|
|
||||||
LDFLAGS += -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref
|
|
||||||
endif
|
|
||||||
ifeq ($(VERBOSE_LD_CMD),yes)
|
|
||||||
LDFLAGS += -v
|
|
||||||
endif
|
|
||||||
#LDFLAGS += -Wl,--relax
|
|
||||||
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)
|
|
||||||
ifeq ($(strip $(DEBUG_ENABLE)),yes)
|
|
||||||
ASFLAGS = -Wa,-adhlns=$(@:%.o=%.lst),-gstabs,--listing-cont-lines=100
|
|
||||||
else
|
|
||||||
ASFLAGS = -Wa,-adhlns=$(@:%.o=%.lst),--listing-cont-lines=100
|
|
||||||
endif
|
|
||||||
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)): INIT_HOOK_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) $$(INIT_HOOK_CFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP))
|
|
||||||
@$$(BUILD_CMD)
|
|
||||||
ifneq ($$(DUMP_C_MACROS),)
|
|
||||||
$$(eval CMD := $$(CC) -E -dM $$($1_CFLAGS) $$(INIT_HOOK_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) $$(INIT_HOOK_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) $$(INIT_HOOK_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
|
|
|
@ -1,49 +0,0 @@
|
||||||
# Note for new boards -- CTPC and CONVERT_TO_PROTON_C are deprecated terms
|
|
||||||
# and should not be replicated for new boards. These will be removed from
|
|
||||||
# documentation as well as existing keymaps in due course.
|
|
||||||
ifneq ($(findstring yes, $(CTPC)$(CONVERT_TO_PROTON_C)),)
|
|
||||||
$(call CATASTROPHIC_ERROR,The `CONVERT_TO_PROTON_C` and `CTPC` options are now deprecated. `CONVERT_TO=proton_c` should be used instead.)
|
|
||||||
endif
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
# force setting as value can be from environment
|
|
||||||
override TARGET := $(TARGET)_$(CONVERT_TO)
|
|
||||||
|
|
||||||
# Configure any defaults
|
|
||||||
OPT_DEFS += -DCONVERT_TO_$(shell echo $(CONVERT_TO) | tr '[:lower:]' '[:upper:]')
|
|
||||||
OPT_DEFS += -DCONVERTER_TARGET=\"$(CONVERT_TO)\"
|
|
||||||
OPT_DEFS += -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
|
|
|
@ -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)))
|
|
|
@ -1,70 +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 \
|
|
||||||
CRC \
|
|
||||||
DEFERRED_EXEC \
|
|
||||||
DIGITIZER \
|
|
||||||
DIP_SWITCH \
|
|
||||||
DYNAMIC_KEYMAP \
|
|
||||||
DYNAMIC_MACRO \
|
|
||||||
DYNAMIC_TAPPING_TERM \
|
|
||||||
GRAVE_ESC \
|
|
||||||
HAPTIC \
|
|
||||||
KEY_LOCK \
|
|
||||||
KEY_OVERRIDE \
|
|
||||||
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)
|
|
||||||
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:]'))) \
|
|
||||||
) \
|
|
||||||
)
|
|
|
@ -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
|
|
|
@ -1,152 +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 \
|
|
||||||
RING_BUFFERED_6KRO_REPORT_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))))
|
|
|
@ -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))))
|
|
|
@ -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.
|
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
## Overview :id=overview
|
## Overview :id=overview
|
||||||
|
|
||||||
The QMK CLI (command line interface) 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.
|
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
|
### Requirements :id=requirements
|
||||||
|
|
||||||
QMK requires Python 3.7 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.
|
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
|
### Install Using Homebrew (macOS, some Linux) :id=install-using-homebrew
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build
|
||||||
|
|
||||||
### Install Using pip :id=install-using-easy_install-or-pip
|
### 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.7 (or later) installed and have installed pip. Then install QMK with this command:
|
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
|
python3 -m pip install qmk
|
529
cli_commands.md
Normal file
529
cli_commands.md
Normal file
|
@ -0,0 +1,529 @@
|
||||||
|
# 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
|
||||||
|
|
||||||
|
## `qmk painter-convert-graphics`
|
||||||
|
|
||||||
|
This command converts images to a format usable by QMK, i.e. the QGF File Format. See the [Quantum Painter](quantum_painter.md?id=quantum-painter-cli) documentation for more information on this command.
|
||||||
|
|
||||||
|
## `qmk painter-make-font-image`
|
||||||
|
|
||||||
|
This command converts a TTF font to an intermediate format for editing, before converting to the QFF File Format. See the [Quantum Painter](quantum_painter.md?id=quantum-painter-cli) documentation for more information on this command.
|
||||||
|
|
||||||
|
## `qmk painter-convert-font-image`
|
||||||
|
|
||||||
|
This command converts an intermediate font image to the QFF File Format. See the [Quantum Painter](quantum_painter.md?id=quantum-painter-cli) documentation for more information on this command.
|
|
@ -44,7 +44,7 @@ def hello(cli):
|
||||||
|
|
||||||
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.
|
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.7/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.
|
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
|
# User Interaction
|
||||||
|
|
||||||
|
@ -56,13 +56,13 @@ There are two main methods for outputting text in a subcommand- `cli.log` and `c
|
||||||
|
|
||||||
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.
|
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.7/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.
|
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.
|
You should never use the format operator (`%`) directly, always pass values as arguments.
|
||||||
|
|
||||||
### Logging (`cli.log`)
|
### Logging (`cli.log`)
|
||||||
|
|
||||||
The `cli.log` object gives you access to a [Logger Object](https://docs.python.org/3.7/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 `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`.
|
The default log level is `INFO`. If the user runs `qmk -v <subcommand>` the default log level will be set to `DEBUG`.
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ del(cli.config.<section>.<key>)
|
||||||
|
|
||||||
## Writing The Configuration File
|
## 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 deliberately using `qmk config`.
|
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.
|
You can use `cli.save_config()` to write out the configuration.
|
||||||
|
|
|
@ -8,8 +8,8 @@ Most of our style is pretty easy to pick up on, but right now it's not entirely
|
||||||
* Closing Brace: Lined up with the first character of 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.
|
* 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.
|
* Optional Braces: Always include optional braces.
|
||||||
* Good: `if (condition) { return false; }`
|
* Good: if (condition) { return false; }
|
||||||
* Bad: `if (condition) return false;`
|
* Bad: if (condition) return false;
|
||||||
* We encourage use of C style comments: `/* */`
|
* We encourage use of C style comments: `/* */`
|
||||||
* Think of them as a story describing the feature
|
* Think of them as a story describing the feature
|
||||||
* Use them liberally to explain why particular decisions were made.
|
* Use them liberally to explain why particular decisions were made.
|
||||||
|
@ -24,7 +24,7 @@ Most of our style is pretty easy to pick up on, but right now it's not entirely
|
||||||
* Readability is more important than consistency.
|
* 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.
|
* 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 `#`.
|
* 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 indentation 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.
|
* 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:
|
Here is an example for easy reference:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
Most of our style follows PEP8 with some local modifications to make things less nit-picky.
|
Most of our style follows PEP8 with some local modifications to make things less nit-picky.
|
||||||
|
|
||||||
* We target Python 3.7 for compatibility with all supported platforms.
|
* We target Python 3.7 for compatability with all supported platforms.
|
||||||
* We indent using four (4) spaces (soft tabs)
|
* We indent using four (4) spaces (soft tabs)
|
||||||
* We encourage liberal use of comments
|
* We encourage liberal use of comments
|
||||||
* Think of them as a story describing the feature
|
* Think of them as a story describing the feature
|
||||||
|
@ -21,7 +21,7 @@ You can use [yapf](https://github.com/google/yapf) to style your code. We provid
|
||||||
|
|
||||||
We don't have a hard and fast rule for when to use `import ...` vs `from ... import ...`. Understandability and maintainability is our ultimate goal.
|
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 compatibility module.
|
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.
|
Imports should be one line per module. We group import statements together using the standard python rules- system, 3rd party, local.
|
||||||
|
|
||||||
|
@ -317,7 +317,7 @@ At the time of this writing our tests are not very comprehensive. Looking at the
|
||||||
|
|
||||||
## Integration Tests
|
## 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.7/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.
|
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
|
## Unit Tests
|
||||||
|
|
|
@ -43,8 +43,6 @@ You can also use any ARM chip with USB that [ChibiOS](https://www.chibios.org) s
|
||||||
* [STM32F446](https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html)
|
* [STM32F446](https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html)
|
||||||
* [STM32G431](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x1.html)
|
* [STM32G431](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x1.html)
|
||||||
* [STM32G474](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x4.html)
|
* [STM32G474](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x4.html)
|
||||||
* [STM32H723](https://www.st.com/en/microcontrollers-microprocessors/stm32h723-733.html)
|
|
||||||
* [STM32H733](https://www.st.com/en/microcontrollers-microprocessors/stm32h723-733.html)
|
|
||||||
* [STM32L412](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
|
* [STM32L412](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
|
||||||
* [STM32L422](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)
|
* [STM32L432](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
|
||||||
|
@ -64,17 +62,9 @@ You can also use any ARM chip with USB that [ChibiOS](https://www.chibios.org) s
|
||||||
* [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)
|
* [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)
|
* [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
|
* PJRC Teensy 3.2
|
||||||
* [MK64FX512](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k6x-ethernet/kinetis-k64-120-mhz-256-kb-sram-microcontrollers-mcus-based-on-arm-cortex-m4-core:K64_120)
|
|
||||||
* PJRC Teensy 3.5
|
|
||||||
* [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)
|
* [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
|
* PJRC Teensy 3.6
|
||||||
|
|
||||||
### Raspberry Pi
|
|
||||||
|
|
||||||
* [RP2040](https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html)
|
|
||||||
|
|
||||||
For a detailed overview about the RP2040 support by QMK see the [dedicated RP2040 page](platformdev_rp2040.md).
|
|
||||||
|
|
||||||
## Atmel ATSAM
|
## 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.
|
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.
|
480
config_options.md
Normal file
480
config_options.md
Normal file
|
@ -0,0 +1,480 @@
|
||||||
|
# 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 ENABLE_COMPILE_KEYCODE`
|
||||||
|
* Enables the `QK_MAKE` keycode
|
||||||
|
* `#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.
|
193
configurator_default_keymaps.md
Normal file
193
configurator_default_keymaps.md
Normal 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).
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
168
contributing.md
Normal file
168
contributing.md
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
# How to Contribute
|
||||||
|
|
||||||
|
👍🎉 First off, thanks for taking the time to read this and contribute! 🎉👍
|
||||||
|
|
||||||
|
Third-party contributions help us grow and improve QMK. We want to make the pull request and contribution process useful and easy for both contributors and maintainers. To this end we've put together some guidelines for contributors to help your pull request be accepted without major changes.
|
||||||
|
|
||||||
|
* [Project Overview](#project-overview)
|
||||||
|
* [Coding Conventions](#coding-conventions)
|
||||||
|
* [General Guidelines](#general-guidelines)
|
||||||
|
* [What does the Code of Conduct mean for me?](#what-does-the-code-of-conduct-mean-for-me)
|
||||||
|
|
||||||
|
## I Don't Want to Read This Whole Thing! I Just Have a Question!
|
||||||
|
|
||||||
|
If you'd like to ask questions about QMK you can do so on the [OLKB Subreddit](https://reddit.com/r/olkb) or on [Discord](https://discord.gg/Uq7gcHh).
|
||||||
|
|
||||||
|
Please keep these things in mind:
|
||||||
|
|
||||||
|
* It may take several hours for someone to respond to your question. Please be patient!
|
||||||
|
* Everyone involved with QMK is donating their time and energy. We don't get paid to work on or answer questions about QMK.
|
||||||
|
* Try to ask your question so it's as easy to answer as possible. If you're not sure how to do that these are some good guides:
|
||||||
|
* https://opensource.com/life/16/10/how-ask-technical-questions
|
||||||
|
* http://www.catb.org/esr/faqs/smart-questions.html
|
||||||
|
|
||||||
|
# Project Overview
|
||||||
|
|
||||||
|
QMK is largely written in C, with specific features and parts written in C++. It targets embedded processors found in keyboards, particularly AVR ([LUFA](https://www.fourwalledcubicle.com/LUFA.php)) and ARM ([ChibiOS](https://www.chibios.org)). If you are already well versed in Arduino programming you'll find a lot of the concepts and limitations familiar. Prior experience with Arduino is not required to successfully contribute to QMK.
|
||||||
|
|
||||||
|
<!-- FIXME: We should include a list of resources for learning C here. -->
|
||||||
|
|
||||||
|
# Where Can I Go for Help?
|
||||||
|
|
||||||
|
If you need help you can [open an issue](https://github.com/qmk/qmk_firmware/issues) or [chat on Discord](https://discord.gg/Uq7gcHh).
|
||||||
|
|
||||||
|
# How Do I Make a Contribution?
|
||||||
|
|
||||||
|
Never made an open source contribution before? Wondering how contributions work in QMK? Here's a quick rundown!
|
||||||
|
|
||||||
|
0. Sign up for a [GitHub](https://github.com) account.
|
||||||
|
1. Put together a keymap to contribute, [find an issue](https://github.com/qmk/qmk_firmware/issues) you are interested in addressing, or [a feature](https://github.com/qmk/qmk_firmware/issues?q=is%3Aopen+is%3Aissue+label%3Afeature) you would like to add.
|
||||||
|
2. Fork the repository associated with the issue to your GitHub account. This means that you will have a copy of the repository under `your-GitHub-username/qmk_firmware`.
|
||||||
|
3. Clone the repository to your local machine using `git clone https://github.com/github-username/repository-name.git`.
|
||||||
|
4. If you're working on a new feature consider opening an issue to talk with us about the work you're about to undertake.
|
||||||
|
5. Create a new branch for your fix using `git checkout -b branch-name-here`.
|
||||||
|
6. Make the appropriate changes for the issue you are trying to address or the feature that you want to add.
|
||||||
|
7. Use `git add insert-paths-of-changed-files-here` to add the file contents of the changed files to the "snapshot" git uses to manage the state of the project, also known as the index.
|
||||||
|
8. Use `git commit -m "Insert a short message of the changes made here"` to store the contents of the index with a descriptive message.
|
||||||
|
9. Push the changes to your repository on GitHub using `git push origin branch-name-here`.
|
||||||
|
10. Submit a pull request to [QMK Firmware](https://github.com/qmk/qmk_firmware/pull/new/master).
|
||||||
|
11. Title the pull request with a short description of the changes made and the issue or bug number associated with your change. For example, you can title an issue like so "Added more log outputting to resolve #4352".
|
||||||
|
12. In the description of the pull request explain the changes that you made, any issues you think exist with the pull request you made, and any questions you have for the maintainer. It's OK if your pull request is not perfect (no pull request is), the reviewer will be able to help you fix any problems and improve it!
|
||||||
|
13. Wait for the pull request to be reviewed by a maintainer.
|
||||||
|
14. Make changes to the pull request if the reviewing maintainer recommends them.
|
||||||
|
15. Celebrate your success after your pull request is merged!
|
||||||
|
|
||||||
|
# Coding Conventions
|
||||||
|
|
||||||
|
Most of our style is pretty easy to pick up on. If you are familiar with either C or Python you should not have too much trouble with our local styles.
|
||||||
|
|
||||||
|
* [Coding Conventions - C](coding_conventions_c.md)
|
||||||
|
* [Coding Conventions - Python](coding_conventions_python.md)
|
||||||
|
|
||||||
|
# General Guidelines
|
||||||
|
|
||||||
|
We have a few different types of changes in QMK, each requiring a different level of rigor. We'd like you to keep the following guidelines in mind no matter what type of change you're making.
|
||||||
|
|
||||||
|
* Separate PRs into logical units. For example, do not submit one PR covering two separate features, instead submit a separate PR for each feature.
|
||||||
|
* Check for unnecessary whitespace with `git diff --check` before committing.
|
||||||
|
* Make sure your code change actually compiles.
|
||||||
|
* Keymaps: Make sure that `make keyboard:your_new_keymap` does not return any errors.
|
||||||
|
* Keyboards: Make sure that `make keyboard:all` does not return any errors.
|
||||||
|
* Core: Make sure that `make all` does not return any errors.
|
||||||
|
* Make sure commit messages are understandable on their own. You should put a short description (no more than 70 characters) on the first line, the second line should be empty, and on the 3rd and later lines you should describe your commit in detail, if required. Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
Adjust the fronzlebop for the kerpleplork
|
||||||
|
|
||||||
|
The kerpleplork was intermittently failing with error code 23. The root cause was the fronzlebop setting, which causes the kerpleplork to activate every N iterations.
|
||||||
|
|
||||||
|
Limited experimentation on the devices I have available shows that 7 is high enough to avoid confusing the kerpleplork, but I'd like to get some feedback from people with ARM devices to be sure.
|
||||||
|
```
|
||||||
|
|
||||||
|
!> **IMPORTANT:** If you would like to contribute a bugfix or improvement to user code, such as non-default keymaps, userspace and layouts, be sure to tag the original submitter of the code in your PR. Many users, regardless of skill level with Git and GitHub, may be confused or frustrated at their code being modified without their knowledge.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Documentation is one of the easiest ways to get started contributing to QMK. Finding places where the documentation is wrong or incomplete and fixing those is easy! We also very badly need someone to edit our documentation, so if you have editing skills but aren't sure where or how to jump in please [reach out for help](#where-can-i-go-for-help)!
|
||||||
|
|
||||||
|
You'll find all our documentation in the `qmk_firmware/docs` directory, or if you'd rather use a web based workflow you can click the "Edit this page" link at the bottom of each page on https://docs.qmk.fm/.
|
||||||
|
|
||||||
|
When providing code examples in your documentation, try to observe naming conventions used elsewhere in the docs. For example, standardizing enums as `my_layers` or `my_keycodes` for consistency:
|
||||||
|
|
||||||
|
```c
|
||||||
|
enum my_layers {
|
||||||
|
_FIRST_LAYER,
|
||||||
|
_SECOND_LAYER
|
||||||
|
};
|
||||||
|
|
||||||
|
enum my_keycodes {
|
||||||
|
FIRST_LAYER = SAFE_RANGE,
|
||||||
|
SECOND_LAYER
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Previewing the Documentation :id=previewing-the-documentation
|
||||||
|
|
||||||
|
Before opening a pull request, you can preview your changes if you have set up the development environment by running this command from the `qmk_firmware/` folder:
|
||||||
|
|
||||||
|
qmk docs
|
||||||
|
|
||||||
|
or if you only have Python 3 installed:
|
||||||
|
|
||||||
|
python3 -m http.server 8936 --directory docs
|
||||||
|
|
||||||
|
and navigating to `http://localhost:8936/`.
|
||||||
|
|
||||||
|
## Keymaps
|
||||||
|
|
||||||
|
Most first-time QMK contributors start with their personal keymaps. We try to keep keymap standards pretty casual (keymaps, after all, reflect the personality of their creators) but we do ask that you follow these guidelines to make it easier for others to discover and learn from your keymap.
|
||||||
|
|
||||||
|
* Write a `readme.md` using [the template](documentation_templates.md).
|
||||||
|
* All Keymap PR's are squashed, so if you care about how your commits are squashed you should do it yourself
|
||||||
|
* Do not lump features in with keymap PR's. Submit the feature first and then a second PR for the keymap.
|
||||||
|
* Do not include `Makefile`s in your keymap folder (they're no longer used)
|
||||||
|
* Update copyrights in file headers (look for `%YOUR_NAME%`)
|
||||||
|
|
||||||
|
## Keyboards
|
||||||
|
|
||||||
|
Keyboards are the raison d'être for QMK. Some keyboards are community maintained, while others are maintained by the people responsible for making a particular keyboard. The `readme.md` should tell you who maintains a particular keyboard. If you have questions relating to a particular keyboard you can [Open An Issue](https://github.com/qmk/qmk_firmware/issues) and tag the maintainer in your question.
|
||||||
|
|
||||||
|
We also ask that you follow these guidelines:
|
||||||
|
|
||||||
|
* Write a `readme.md` using [the template](documentation_templates.md).
|
||||||
|
* Keep the number of commits reasonable or we will squash your PR
|
||||||
|
* Do not lump core features in with new keyboards. Submit the feature first and then submit a separate PR for the keyboard.
|
||||||
|
* Name `.c`/`.h` file after the immediate parent folder, eg `/keyboards/<kb1>/<kb2>/<kb2>.[ch]`
|
||||||
|
* Do not include `Makefile`s in your keyboard folder (they're no longer used)
|
||||||
|
* Update copyrights in file headers (look for `%YOUR_NAME%`)
|
||||||
|
|
||||||
|
## Quantum/TMK Core
|
||||||
|
|
||||||
|
Before you put a lot of work into building your new feature you should make sure you are implementing it in the best way. You can get a basic understanding of QMK by reading [Understanding QMK](understanding_qmk.md), which will take you on a tour of the QMK program flow. From here you should talk to us to get a sense of the best way to implement your idea. There are two main ways to do this:
|
||||||
|
|
||||||
|
* [Chat on Discord](https://discord.gg/Uq7gcHh)
|
||||||
|
* [Open an Issue](https://github.com/qmk/qmk_firmware/issues/new)
|
||||||
|
|
||||||
|
Feature and Bug Fix PR's affect all keyboards. We are also in the process of restructuring QMK. For this reason it is especially important for significant changes to be discussed before implementation has happened. If you open a PR without talking to us first please be prepared to do some significant rework if your choices do not mesh well with our planned direction.
|
||||||
|
|
||||||
|
Here are some things to keep in mind when working on your feature or bug fix.
|
||||||
|
|
||||||
|
* **Disabled by default** - memory is a pretty limited on most chips QMK supports, and it's important that current keymaps aren't broken, so please allow your feature to be turned **on**, rather than being turned off. If you think it should be on by default, or reduces the size of the code, please talk with us about it.
|
||||||
|
* **Compile locally before submitting** - hopefully this one is obvious, but things need to compile! You should always make sure your changes compile before opening a pull request.
|
||||||
|
* **Consider revisions and different chip-bases** - there are several keyboards that have revisions that allow for slightly different configurations, and even different chip-bases. Try to make a feature supported in ARM and AVR, or automatically disabled on platforms it doesn't work on.
|
||||||
|
* **Explain your feature** - Document it in `docs/`, either as a new file or as part of an existing file. If you don't document it other people won't be able to benefit from your hard work.
|
||||||
|
|
||||||
|
We also ask that you follow these guidelines:
|
||||||
|
|
||||||
|
* Keep the number of commits reasonable or we will squash your PR
|
||||||
|
* Do not lump keyboards or keymaps in with core changes. Submit your core changes first.
|
||||||
|
* Write [Unit Tests](unit_testing.md) for your feature
|
||||||
|
* Follow the style of the file you are editing. If the style is unclear or there are mixed styles you should conform to the [coding conventions](#coding-conventions) above.
|
||||||
|
|
||||||
|
## Refactoring
|
||||||
|
|
||||||
|
To maintain a clear vision of how things are laid out in QMK we try to plan out refactors in-depth and have a collaborator make the changes. If you have an idea for refactoring, or suggestions, [open an issue](https://github.com/qmk/qmk_firmware/issues), we'd love to talk about how QMK can be improved.
|
||||||
|
|
||||||
|
# What Does the Code of Conduct Mean for Me?
|
||||||
|
|
||||||
|
Our [Code of Conduct](https://qmk.fm/coc/) means that you are responsible for treating everyone on the project with respect and courtesy regardless of their identity. If you are the victim of any inappropriate behavior or comments as described in our Code of Conduct, we are here for you and will do the best to ensure that the abuser is reprimanded appropriately, per our code.
|
108
custom_matrix.md
Normal file
108
custom_matrix.md
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
# Custom Matrix
|
||||||
|
|
||||||
|
QMK provides a mechanism to supplement or replace the default matrix scanning routine with your own code.
|
||||||
|
|
||||||
|
The reasons to use this feature include:
|
||||||
|
|
||||||
|
* Extra hardware between the keyboard's switches and MCU pins
|
||||||
|
* I/O multiplexer
|
||||||
|
* Line decoder
|
||||||
|
* Irregular switch matrix
|
||||||
|
* Simultaneous use of `COL2ROW` and `ROW2COL`
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Implementing custom matrix usually involves compilation of an additional source file. It is recommended that for consistency, this file is called `matrix.c`.
|
||||||
|
|
||||||
|
Add a new file to your keyboard directory:
|
||||||
|
```
|
||||||
|
keyboards/<keyboard>/matrix.c
|
||||||
|
```
|
||||||
|
|
||||||
|
And to configure compilation for the new file, add this to your `rules.mk`:
|
||||||
|
```make
|
||||||
|
SRC += matrix.c
|
||||||
|
```
|
||||||
|
|
||||||
|
## 'lite'
|
||||||
|
|
||||||
|
Provides a default implementation for various scanning functions, reducing the boilerplate code when implementing custom matrix.
|
||||||
|
To configure it, add this to your `rules.mk`:
|
||||||
|
|
||||||
|
```make
|
||||||
|
CUSTOM_MATRIX = lite
|
||||||
|
```
|
||||||
|
|
||||||
|
And implement the following functions in a `matrix.c` file in your keyboard folder:
|
||||||
|
|
||||||
|
```c
|
||||||
|
void matrix_init_custom(void) {
|
||||||
|
// TODO: initialize hardware here
|
||||||
|
}
|
||||||
|
|
||||||
|
bool matrix_scan_custom(matrix_row_t current_matrix[]) {
|
||||||
|
bool matrix_has_changed = false;
|
||||||
|
|
||||||
|
// TODO: add matrix scanning routine here
|
||||||
|
|
||||||
|
return matrix_has_changed;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Full Replacement
|
||||||
|
|
||||||
|
When more control over the scanning routine is required, you can choose to implement the full scanning routine.
|
||||||
|
To configure it, add this to your rules.mk:
|
||||||
|
|
||||||
|
```make
|
||||||
|
CUSTOM_MATRIX = yes
|
||||||
|
```
|
||||||
|
|
||||||
|
And implement the following functions in a `matrix.c` file in your keyboard folder:
|
||||||
|
|
||||||
|
```c
|
||||||
|
matrix_row_t matrix_get_row(uint8_t row) {
|
||||||
|
// TODO: return the requested row data
|
||||||
|
}
|
||||||
|
|
||||||
|
void matrix_print(void) {
|
||||||
|
// TODO: use print() to dump the current matrix state to console
|
||||||
|
}
|
||||||
|
|
||||||
|
void matrix_init(void) {
|
||||||
|
// TODO: initialize hardware and global matrix state here
|
||||||
|
|
||||||
|
// Unless hardware debouncing - Init the configured debounce routine
|
||||||
|
debounce_init(MATRIX_ROWS);
|
||||||
|
|
||||||
|
// This *must* be called for correct keyboard behavior
|
||||||
|
matrix_init_quantum();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t matrix_scan(void) {
|
||||||
|
bool matrix_has_changed = false;
|
||||||
|
|
||||||
|
// TODO: add matrix scanning routine here
|
||||||
|
|
||||||
|
// Unless hardware debouncing - use the configured debounce routine
|
||||||
|
debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
|
||||||
|
|
||||||
|
// This *must* be called for correct keyboard behavior
|
||||||
|
matrix_scan_quantum();
|
||||||
|
|
||||||
|
return matrix_has_changed;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And also provide defaults for the following callbacks:
|
||||||
|
|
||||||
|
```c
|
||||||
|
__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); }
|
||||||
|
|
||||||
|
__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); }
|
||||||
|
|
||||||
|
__attribute__((weak)) void matrix_init_user(void) {}
|
||||||
|
|
||||||
|
__attribute__((weak)) void matrix_scan_user(void) {}
|
||||||
|
```
|
473
custom_quantum_functions.md
Normal file
473
custom_quantum_functions.md
Normal file
|
@ -0,0 +1,473 @@
|
||||||
|
# How to Customize Your Keyboard's Behavior
|
||||||
|
|
||||||
|
For a lot of people a custom keyboard is about more than sending button presses to your computer. You want to be able to do things that are more complex than simple button presses and macros. QMK has hooks that allow you to inject code, override functionality, and otherwise customize how your keyboard behaves in different situations.
|
||||||
|
|
||||||
|
This page does not assume any special knowledge about QMK, but reading [Understanding QMK](understanding_qmk.md) will help you understand what is going on at a more fundamental level.
|
||||||
|
|
||||||
|
## A Word on Core vs Keyboards vs Keymap :id=a-word-on-core-vs-keyboards-vs-keymap
|
||||||
|
|
||||||
|
We have structured QMK as a hierarchy:
|
||||||
|
|
||||||
|
* Core (`_quantum`)
|
||||||
|
* Keyboard/Revision (`_kb`)
|
||||||
|
* Keymap (`_user`)
|
||||||
|
|
||||||
|
Each of the functions described below can be defined with a `_kb()` suffix or a `_user()` suffix. We intend for you to use the `_kb()` suffix at the Keyboard/Revision level, while the `_user()` suffix should be used at the Keymap level.
|
||||||
|
|
||||||
|
When defining functions at the Keyboard/Revision level it is important that your `_kb()` implementation call `_user()` before executing anything else- otherwise the keymap level function will never be called.
|
||||||
|
|
||||||
|
# Custom Keycodes
|
||||||
|
|
||||||
|
By far the most common task is to change the behavior of an existing keycode or to create a new keycode. From a code standpoint the mechanism for each is very similar.
|
||||||
|
|
||||||
|
## Defining a New Keycode
|
||||||
|
|
||||||
|
The first step to creating your own custom keycode(s) is to enumerate them. This means both naming them and assigning a unique number to that keycode. Rather than limit custom keycodes to a fixed range of numbers QMK provides the `SAFE_RANGE` macro. You can use `SAFE_RANGE` when enumerating your custom keycodes to guarantee that you get a unique number.
|
||||||
|
|
||||||
|
|
||||||
|
Here is an example of enumerating 2 keycodes. After adding this block to your `keymap.c` you will be able to use `FOO` and `BAR` inside your keymap.
|
||||||
|
|
||||||
|
```c
|
||||||
|
enum my_keycodes {
|
||||||
|
FOO = SAFE_RANGE,
|
||||||
|
BAR
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Programming the Behavior of Any Keycode :id=programming-the-behavior-of-any-keycode
|
||||||
|
|
||||||
|
When you want to override the behavior of an existing key, or define the behavior for a new key, you should use the `process_record_kb()` and `process_record_user()` functions. These are called by QMK during key processing before the actual key event is handled. If these functions return `true` QMK will process the keycodes as usual. That can be handy for extending the functionality of a key rather than replacing it. If these functions return `false` QMK will skip the normal key handling, and it will be up to you to send any key up or down events that are required.
|
||||||
|
|
||||||
|
These function are called every time a key is pressed or released.
|
||||||
|
|
||||||
|
### Example `process_record_user()` Implementation
|
||||||
|
|
||||||
|
This example does two things. It defines the behavior for a custom keycode called `FOO`, and it supplements our Enter key by playing a tone whenever it is pressed.
|
||||||
|
|
||||||
|
```c
|
||||||
|
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
switch (keycode) {
|
||||||
|
case FOO:
|
||||||
|
if (record->event.pressed) {
|
||||||
|
// Do something when pressed
|
||||||
|
} else {
|
||||||
|
// Do something else when release
|
||||||
|
}
|
||||||
|
return false; // Skip all further processing of this key
|
||||||
|
case KC_ENTER:
|
||||||
|
// Play a tone when enter is pressed
|
||||||
|
if (record->event.pressed) {
|
||||||
|
PLAY_SONG(tone_qwerty);
|
||||||
|
}
|
||||||
|
return true; // Let QMK send the enter press/release events
|
||||||
|
default:
|
||||||
|
return true; // Process all other keycodes normally
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `process_record_*` Function Documentation
|
||||||
|
|
||||||
|
* Keyboard/Revision: `bool process_record_kb(uint16_t keycode, keyrecord_t *record)`
|
||||||
|
* Keymap: `bool process_record_user(uint16_t keycode, keyrecord_t *record)`
|
||||||
|
|
||||||
|
The `keycode` argument is whatever is defined in your keymap, eg `MO(1)`, `KC_L`, etc. You should use a `switch...case` block to handle these events.
|
||||||
|
|
||||||
|
The `record` argument contains information about the actual press:
|
||||||
|
|
||||||
|
```c
|
||||||
|
keyrecord_t record {
|
||||||
|
keyevent_t event {
|
||||||
|
keypos_t key {
|
||||||
|
uint8_t col
|
||||||
|
uint8_t row
|
||||||
|
}
|
||||||
|
bool pressed
|
||||||
|
uint16_t time
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# Keyboard Initialization Code
|
||||||
|
|
||||||
|
There are several steps in the keyboard initialization process. Depending on what you want to do, it will influence which function you should use.
|
||||||
|
|
||||||
|
These are the three main initialization functions, listed in the order that they're called.
|
||||||
|
|
||||||
|
* `keyboard_pre_init_*` - Happens before most anything is started. Good for hardware setup that you want running very early.
|
||||||
|
* `matrix_init_*` - Happens midway through the firmware's startup process. Hardware is initialized, but features may not be yet.
|
||||||
|
* `keyboard_post_init_*` - Happens at the end of the firmware's startup process. This is where you'd want to put "customization" code, for the most part.
|
||||||
|
|
||||||
|
!> For most people, the `keyboard_post_init_user` function is what you want to call. For instance, this is where you want to set up things for RGB Underglow.
|
||||||
|
|
||||||
|
## Keyboard Pre Initialization code
|
||||||
|
|
||||||
|
This runs very early during startup, even before the USB has been started.
|
||||||
|
|
||||||
|
Shortly after this, the matrix is initialized.
|
||||||
|
|
||||||
|
For most users, this shouldn't be used, as it's primarily for hardware oriented initialization.
|
||||||
|
|
||||||
|
However, if you have hardware stuff that you need initialized, this is the best place for it (such as initializing LED pins).
|
||||||
|
|
||||||
|
### Example `keyboard_pre_init_user()` Implementation
|
||||||
|
|
||||||
|
This example, at the keyboard level, sets up B0, B1, B2, B3, and B4 as LED pins.
|
||||||
|
|
||||||
|
```c
|
||||||
|
void keyboard_pre_init_user(void) {
|
||||||
|
// Call the keyboard pre init code.
|
||||||
|
|
||||||
|
// Set our LED pins as output
|
||||||
|
setPinOutput(B0);
|
||||||
|
setPinOutput(B1);
|
||||||
|
setPinOutput(B2);
|
||||||
|
setPinOutput(B3);
|
||||||
|
setPinOutput(B4);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `keyboard_pre_init_*` Function Documentation
|
||||||
|
|
||||||
|
* Keyboard/Revision: `void keyboard_pre_init_kb(void)`
|
||||||
|
* Keymap: `void keyboard_pre_init_user(void)`
|
||||||
|
|
||||||
|
## Matrix Initialization Code
|
||||||
|
|
||||||
|
This is called when the matrix is initialized, and after some of the hardware has been set up, but before many of the features have been initialized.
|
||||||
|
|
||||||
|
This is useful for setting up stuff that you may need elsewhere, but isn't hardware related nor is dependant on where it's started.
|
||||||
|
|
||||||
|
|
||||||
|
### `matrix_init_*` Function Documentation
|
||||||
|
|
||||||
|
* Keyboard/Revision: `void matrix_init_kb(void)`
|
||||||
|
* Keymap: `void matrix_init_user(void)`
|
||||||
|
|
||||||
|
### Low-level Matrix Overrides Function Documentation :id=low-level-matrix-overrides
|
||||||
|
|
||||||
|
* GPIO pin initialisation: `void matrix_init_pins(void)`
|
||||||
|
* This needs to perform the low-level initialisation of all row and column pins. By default this will initialise the input/output state of each of the GPIO pins listed in `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no initialisation of pin state will occur within QMK itself, instead deferring to the keyboard's override.
|
||||||
|
* `COL2ROW`-based row reads: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)`
|
||||||
|
* `ROW2COL`-based column reads: `void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col, matrix_row_t row_shifter)`
|
||||||
|
* `DIRECT_PINS`-based reads: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)`
|
||||||
|
* These three functions need to perform the low-level retrieval of matrix state of relevant input pins, based on the matrix type. Only one of the functions should be implemented, if needed. By default this will iterate through `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, configuring the inputs and outputs based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no manipulation of matrix GPIO pin state will occur within QMK itself, instead deferring to the keyboard's override.
|
||||||
|
|
||||||
|
## Keyboard Post Initialization code
|
||||||
|
|
||||||
|
This is ran as the very last task in the keyboard initialization process. This is useful if you want to make changes to certain features, as they should be initialized by this point.
|
||||||
|
|
||||||
|
|
||||||
|
### Example `keyboard_post_init_user()` Implementation
|
||||||
|
|
||||||
|
This example, running after everything else has initialized, sets up the rgb underglow configuration.
|
||||||
|
|
||||||
|
```c
|
||||||
|
void keyboard_post_init_user(void) {
|
||||||
|
// Call the post init code.
|
||||||
|
rgblight_enable_noeeprom(); // enables Rgb, without saving settings
|
||||||
|
rgblight_sethsv_noeeprom(180, 255, 255); // sets the color to teal/cyan without saving
|
||||||
|
rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3); // sets mode to Fast breathing without saving
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `keyboard_post_init_*` Function Documentation
|
||||||
|
|
||||||
|
* Keyboard/Revision: `void keyboard_post_init_kb(void)`
|
||||||
|
* Keymap: `void keyboard_post_init_user(void)`
|
||||||
|
|
||||||
|
# Matrix Scanning Code
|
||||||
|
|
||||||
|
Whenever possible you should customize your keyboard by using `process_record_*()` and hooking into events that way, to ensure that your code does not have a negative performance impact on your keyboard. However, in rare cases it is necessary to hook into the matrix scanning. Be extremely careful with the performance of code in these functions, as it will be called at least 10 times per second.
|
||||||
|
|
||||||
|
### Example `matrix_scan_*` Implementation
|
||||||
|
|
||||||
|
This example has been deliberately omitted. You should understand enough about QMK internals to write this without an example before hooking into such a performance sensitive area. If you need help please [open an issue](https://github.com/qmk/qmk_firmware/issues/new) or [chat with us on Discord](https://discord.gg/Uq7gcHh).
|
||||||
|
|
||||||
|
### `matrix_scan_*` Function Documentation
|
||||||
|
|
||||||
|
* Keyboard/Revision: `void matrix_scan_kb(void)`
|
||||||
|
* Keymap: `void matrix_scan_user(void)`
|
||||||
|
|
||||||
|
This function gets called at every matrix scan, which is basically as often as the MCU can handle. Be careful what you put here, as it will get run a lot.
|
||||||
|
|
||||||
|
You should use this function if you need custom matrix scanning code. It can also be used for custom status output (such as LEDs or a display) or other functionality that you want to trigger regularly even when the user isn't typing.
|
||||||
|
|
||||||
|
# Keyboard housekeeping
|
||||||
|
|
||||||
|
* Keyboard/Revision: `void housekeeping_task_kb(void)`
|
||||||
|
* Keymap: `void housekeeping_task_user(void)`
|
||||||
|
|
||||||
|
This function gets called at the end of all QMK processing, before starting the next iteration. You can safely assume that QMK has dealt with the last matrix scan at the time that these functions are invoked -- layer states have been updated, USB reports have been sent, LEDs have been updated, and displays have been drawn.
|
||||||
|
|
||||||
|
Similar to `matrix_scan_*`, these are called as often as the MCU can handle. To keep your board responsive, it's suggested to do as little as possible during these function calls, potentially throtting their behaviour if you do indeed require implementing something special.
|
||||||
|
|
||||||
|
# Keyboard Idling/Wake Code
|
||||||
|
|
||||||
|
If the board supports it, it can be "idled", by stopping a number of functions. A good example of this is RGB lights or backlights. This can save on power consumption, or may be better behavior for your keyboard.
|
||||||
|
|
||||||
|
This is controlled by two functions: `suspend_power_down_*` and `suspend_wakeup_init_*`, which are called when the system board is idled and when it wakes up, respectively.
|
||||||
|
|
||||||
|
|
||||||
|
### Example suspend_power_down_user() and suspend_wakeup_init_user() Implementation
|
||||||
|
|
||||||
|
|
||||||
|
```c
|
||||||
|
void suspend_power_down_user(void) {
|
||||||
|
// code will run multiple times while keyboard is suspended
|
||||||
|
}
|
||||||
|
|
||||||
|
void suspend_wakeup_init_user(void) {
|
||||||
|
// code will run on keyboard wakeup
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Keyboard suspend/wake Function Documentation
|
||||||
|
|
||||||
|
* Keyboard/Revision: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)`
|
||||||
|
* Keymap: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)`
|
||||||
|
|
||||||
|
# Layer Change Code :id=layer-change-code
|
||||||
|
|
||||||
|
This runs code every time that the layers get changed. This can be useful for layer indication, or custom layer handling.
|
||||||
|
|
||||||
|
### Example `layer_state_set_*` Implementation
|
||||||
|
|
||||||
|
This example shows how to set the [RGB Underglow](feature_rgblight.md) lights based on the layer, using the Planck as an example.
|
||||||
|
|
||||||
|
```c
|
||||||
|
layer_state_t layer_state_set_user(layer_state_t state) {
|
||||||
|
switch (get_highest_layer(state)) {
|
||||||
|
case _RAISE:
|
||||||
|
rgblight_setrgb (0x00, 0x00, 0xFF);
|
||||||
|
break;
|
||||||
|
case _LOWER:
|
||||||
|
rgblight_setrgb (0xFF, 0x00, 0x00);
|
||||||
|
break;
|
||||||
|
case _PLOVER:
|
||||||
|
rgblight_setrgb (0x00, 0xFF, 0x00);
|
||||||
|
break;
|
||||||
|
case _ADJUST:
|
||||||
|
rgblight_setrgb (0x7A, 0x00, 0xFF);
|
||||||
|
break;
|
||||||
|
default: // for any other layers, or the default layer
|
||||||
|
rgblight_setrgb (0x00, 0xFF, 0xFF);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the `IS_LAYER_ON_STATE(state, layer)` and `IS_LAYER_OFF_STATE(state, layer)` macros to check the status of a particular layer.
|
||||||
|
|
||||||
|
Outside of `layer_state_set_*` functions, you can use the `IS_LAYER_ON(layer)` and `IS_LAYER_OFF(layer)` macros to check global layer state.
|
||||||
|
|
||||||
|
### `layer_state_set_*` Function Documentation
|
||||||
|
|
||||||
|
* Keyboard/Revision: `layer_state_t layer_state_set_kb(layer_state_t state)`
|
||||||
|
* Keymap: `layer_state_t layer_state_set_user(layer_state_t state)`
|
||||||
|
|
||||||
|
|
||||||
|
The `state` is the bitmask of the active layers, as explained in the [Keymap Overview](keymap.md#keymap-layer-status)
|
||||||
|
|
||||||
|
|
||||||
|
# Persistent Configuration (EEPROM)
|
||||||
|
|
||||||
|
This allows you to configure persistent settings for your keyboard. These settings are stored in the EEPROM of your controller, and are retained even after power loss. The settings can be read with `eeconfig_read_kb` and `eeconfig_read_user`, and can be written to using `eeconfig_update_kb` and `eeconfig_update_user`. This is useful for features that you want to be able to toggle (like toggling rgb layer indication). Additionally, you can use `eeconfig_init_kb` and `eeconfig_init_user` to set the default values for the EEPROM.
|
||||||
|
|
||||||
|
The complicated part here, is that there are a bunch of ways that you can store and access data via EEPROM, and there is no "correct" way to do this. However, you only have a DWORD (4 bytes) for each function.
|
||||||
|
|
||||||
|
Keep in mind that EEPROM has a limited number of writes. While this is very high, it's not the only thing writing to the EEPROM, and if you write too often, you can potentially drastically shorten the life of your MCU.
|
||||||
|
|
||||||
|
* If you don't understand the example, then you may want to avoid using this feature, as it is rather complicated.
|
||||||
|
|
||||||
|
### Example Implementation
|
||||||
|
|
||||||
|
This is an example of how to add settings, and read and write it. We're using the user keymap for the example here. This is a complex function, and has a lot going on. In fact, it uses a lot of the above functions to work!
|
||||||
|
|
||||||
|
|
||||||
|
In your keymap.c file, add this to the top:
|
||||||
|
```c
|
||||||
|
typedef union {
|
||||||
|
uint32_t raw;
|
||||||
|
struct {
|
||||||
|
bool rgb_layer_change :1;
|
||||||
|
};
|
||||||
|
} user_config_t;
|
||||||
|
|
||||||
|
user_config_t user_config;
|
||||||
|
```
|
||||||
|
|
||||||
|
This sets up a 32 bit structure that we can store settings with in memory, and write to the EEPROM. Using this removes the need to define variables, since they're defined in this structure. Remember that `bool` (boolean) values use 1 bit, `uint8_t` uses 8 bits, `uint16_t` uses up 16 bits. You can mix and match, but changing the order can cause issues, as it will change the values that are read and written.
|
||||||
|
|
||||||
|
We're using `rgb_layer_change`, for the `layer_state_set_*` function, and use `keyboard_post_init_user` and `process_record_user` to configure everything.
|
||||||
|
|
||||||
|
Now, using the `keyboard_post_init_user` code above, you want to add `eeconfig_read_user()` to it, to populate the structure you've just created. And you can then immediately use this structure to control functionality in your keymap. And It should look like:
|
||||||
|
```c
|
||||||
|
void keyboard_post_init_user(void) {
|
||||||
|
// Call the keymap level matrix init.
|
||||||
|
|
||||||
|
// Read the user config from EEPROM
|
||||||
|
user_config.raw = eeconfig_read_user();
|
||||||
|
|
||||||
|
// Set default layer, if enabled
|
||||||
|
if (user_config.rgb_layer_change) {
|
||||||
|
rgblight_enable_noeeprom();
|
||||||
|
rgblight_sethsv_noeeprom_cyan();
|
||||||
|
rgblight_mode_noeeprom(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
The above function will use the EEPROM config immediately after reading it, to set the default layer's RGB color. The "raw" value of it is converted in a usable structure based on the "union" that you created above.
|
||||||
|
|
||||||
|
```c
|
||||||
|
layer_state_t layer_state_set_user(layer_state_t state) {
|
||||||
|
switch (get_highest_layer(state)) {
|
||||||
|
case _RAISE:
|
||||||
|
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_magenta(); rgblight_mode_noeeprom(1); }
|
||||||
|
break;
|
||||||
|
case _LOWER:
|
||||||
|
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_red(); rgblight_mode_noeeprom(1); }
|
||||||
|
break;
|
||||||
|
case _PLOVER:
|
||||||
|
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_green(); rgblight_mode_noeeprom(1); }
|
||||||
|
break;
|
||||||
|
case _ADJUST:
|
||||||
|
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_white(); rgblight_mode_noeeprom(1); }
|
||||||
|
break;
|
||||||
|
default: // for any other layers, or the default layer
|
||||||
|
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_cyan(); rgblight_mode_noeeprom(1); }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
This will cause the RGB underglow to be changed ONLY if the value was enabled. Now to configure this value, create a new keycode for `process_record_user` called `RGB_LYR`. Additionally, we want to make sure that if you use the normal RGB codes, that it turns off Using the example above, make it look this:
|
||||||
|
```c
|
||||||
|
|
||||||
|
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
switch (keycode) {
|
||||||
|
case FOO:
|
||||||
|
if (record->event.pressed) {
|
||||||
|
// Do something when pressed
|
||||||
|
} else {
|
||||||
|
// Do something else when release
|
||||||
|
}
|
||||||
|
return false; // Skip all further processing of this key
|
||||||
|
case KC_ENTER:
|
||||||
|
// Play a tone when enter is pressed
|
||||||
|
if (record->event.pressed) {
|
||||||
|
PLAY_SONG(tone_qwerty);
|
||||||
|
}
|
||||||
|
return true; // Let QMK send the enter press/release events
|
||||||
|
case RGB_LYR: // This allows me to use underglow as layer indication, or as normal
|
||||||
|
if (record->event.pressed) {
|
||||||
|
user_config.rgb_layer_change ^= 1; // Toggles the status
|
||||||
|
eeconfig_update_user(user_config.raw); // Writes the new status to EEPROM
|
||||||
|
if (user_config.rgb_layer_change) { // if layer state indication is enabled,
|
||||||
|
layer_state_set(layer_state); // then immediately update the layer color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // For any of the RGB codes (see quantum_keycodes.h, L400 for reference)
|
||||||
|
if (record->event.pressed) { //This disables layer indication, as it's assumed that if you're changing this ... you want that disabled
|
||||||
|
if (user_config.rgb_layer_change) { // only if this is enabled
|
||||||
|
user_config.rgb_layer_change = false; // disable it, and
|
||||||
|
eeconfig_update_user(user_config.raw); // write the setings to EEPROM
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true; break;
|
||||||
|
default:
|
||||||
|
return true; // Process all other keycodes normally
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
And lastly, you want to add the `eeconfig_init_user` function, so that when the EEPROM is reset, you can specify default values, and even custom actions. To force an EEPROM reset, use the `EEP_RST` keycode or [Bootmagic Lite](feature_bootmagic.md) functionallity. For example, if you want to set rgb layer indication by default, and save the default valued.
|
||||||
|
|
||||||
|
```c
|
||||||
|
void eeconfig_init_user(void) { // EEPROM is getting reset!
|
||||||
|
user_config.raw = 0;
|
||||||
|
user_config.rgb_layer_change = true; // We want this enabled by default
|
||||||
|
eeconfig_update_user(user_config.raw); // Write default value to EEPROM now
|
||||||
|
|
||||||
|
// use the non noeeprom versions, to write these values to EEPROM too
|
||||||
|
rgblight_enable(); // Enable RGB by default
|
||||||
|
rgblight_sethsv_cyan(); // Set it to CYAN by default
|
||||||
|
rgblight_mode(1); // set to solid by default
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And you're done. The RGB layer indication will only work if you want it to. And it will be saved, even after unplugging the board. And if you use any of the RGB codes, it will disable the layer indication, so that it stays on the mode and color that you set it to.
|
||||||
|
|
||||||
|
### 'EECONFIG' Function Documentation
|
||||||
|
|
||||||
|
* Keyboard/Revision: `void eeconfig_init_kb(void)`, `uint32_t eeconfig_read_kb(void)` and `void eeconfig_update_kb(uint32_t val)`
|
||||||
|
* Keymap: `void eeconfig_init_user(void)`, `uint32_t eeconfig_read_user(void)` and `void eeconfig_update_user(uint32_t val)`
|
||||||
|
|
||||||
|
The `val` is the value of the data that you want to write to EEPROM. And the `eeconfig_read_*` function return a 32 bit (DWORD) value from the EEPROM.
|
||||||
|
|
||||||
|
### Deferred Execution :id=deferred-execution
|
||||||
|
|
||||||
|
QMK has the ability to execute a callback after a specified period of time, rather than having to manually manage timers. To enable this functionality, set `DEFERRED_EXEC_ENABLE = yes` in rules.mk.
|
||||||
|
|
||||||
|
#### Deferred executor callbacks
|
||||||
|
|
||||||
|
All _deferred executor callbacks_ have a common function signature and look like:
|
||||||
|
|
||||||
|
```c
|
||||||
|
uint32_t my_callback(uint32_t trigger_time, void *cb_arg) {
|
||||||
|
/* do something */
|
||||||
|
bool repeat = my_deferred_functionality();
|
||||||
|
return repeat ? 500 : 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The first argument `trigger_time` is the intended time of execution. If other delays prevent executing at the exact trigger time, this allows for "catch-up" or even skipping intervals, depending on the required behaviour.
|
||||||
|
|
||||||
|
The second argument `cb_arg` is the same argument passed into `defer_exec()` below, and can be used to access state information from the original call context.
|
||||||
|
|
||||||
|
The return value is the number of milliseconds to use if the function should be repeated -- if the callback returns `0` then it's automatically unregistered. In the example above, a hypothetical `my_deferred_functionality()` is invoked to determine if the callback needs to be repeated -- if it does, it reschedules for a `500` millisecond delay, otherwise it informs the deferred execution background task that it's done, by returning `0`.
|
||||||
|
|
||||||
|
?> Note that the returned delay will be applied to the intended trigger time, not the time of callback invocation. This allows for generally consistent timing even in the face of occasional late execution.
|
||||||
|
|
||||||
|
#### Deferred executor registration
|
||||||
|
|
||||||
|
Once a callback has been defined, it can be scheduled using the following API:
|
||||||
|
|
||||||
|
```c
|
||||||
|
deferred_token my_token = defer_exec(1500, my_callback, NULL);
|
||||||
|
```
|
||||||
|
|
||||||
|
The first argument is the number of milliseconds to wait until executing `my_callback` -- in the case above, `1500` milliseconds, or 1.5 seconds.
|
||||||
|
|
||||||
|
The third parameter is the `cb_arg` that gets passed to the callback at the point of execution. This value needs to be valid at the time the callback is invoked -- a local function value will be destroyed before the callback is executed and should not be used. If this is not required, `NULL` should be used.
|
||||||
|
|
||||||
|
The return value is a `deferred_token` that can consequently be used to cancel the deferred executor callback before it's invoked. If a failure occurs, the returned value will be `INVALID_DEFERRED_TOKEN`. Usually this will be as a result of supplying `0` to the delay, or a `NULL` for the callback. The other failure case is if there are too many deferred executions "in flight" -- this can be increased by changing the limit, described below.
|
||||||
|
|
||||||
|
#### Extending a deferred execution
|
||||||
|
|
||||||
|
The `deferred_token` returned by `defer_exec()` can be used to extend a the duration a pending execution waits before it gets invoked:
|
||||||
|
```c
|
||||||
|
// This will re-delay my_token's future execution such that it is invoked 800ms after the current time
|
||||||
|
extend_deferred_exec(my_token, 800);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Cancelling a deferred execution
|
||||||
|
|
||||||
|
The `deferred_token` returned by `defer_exec()` can be used to cancel a pending execution before it gets invoked:
|
||||||
|
```c
|
||||||
|
// This will cancel my_token's future execution
|
||||||
|
cancel_deferred_exec(my_token);
|
||||||
|
```
|
||||||
|
|
||||||
|
Once a token has been canceled, it should be considered invalid. Reusing the same token is not supported.
|
||||||
|
|
||||||
|
#### Deferred callback limits
|
||||||
|
|
||||||
|
There are a maximum number of deferred callbacks that can be scheduled, controlled by the value of the define `MAX_DEFERRED_EXECUTORS`.
|
||||||
|
|
||||||
|
If registrations fail, then you can increase this value in your keyboard or keymap `config.h` file, for example to 16 instead of the default 8:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define MAX_DEFERRED_EXECUTORS 16
|
||||||
|
```
|
|
@ -1,375 +0,0 @@
|
||||||
{
|
|
||||||
"aliases": {
|
|
||||||
/*
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ ² │ & │ é │ " │ ' │ ( │ § │ è │ ! │ ç │ à │ ) │ - │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ A │ Z │ E │ R │ T │ Y │ U │ I │ O │ P │ ^ │ $ │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ Q │ S │ D │ F │ G │ H │ J │ K │ L │ M │ ù │ µ │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
|
|
||||||
* │ │ < │ W │ X │ C │ V │ B │ N │ , │ ; │ : │ = │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"KC_GRV": {
|
|
||||||
"key": "BE_SUP2",
|
|
||||||
"label": "²",
|
|
||||||
}
|
|
||||||
"KC_1": {
|
|
||||||
"key": "BE_AMPR",
|
|
||||||
"label": "&",
|
|
||||||
}
|
|
||||||
"KC_2": {
|
|
||||||
"key": "BE_EACU",
|
|
||||||
"label": "é",
|
|
||||||
}
|
|
||||||
"KC_3": {
|
|
||||||
"key": "BE_DQUO",
|
|
||||||
"label": "\"",
|
|
||||||
}
|
|
||||||
"KC_4": {
|
|
||||||
"key": "BE_QUOT",
|
|
||||||
"label": "'",
|
|
||||||
}
|
|
||||||
"KC_5": {
|
|
||||||
"key": "BE_LPRN",
|
|
||||||
"label": "(",
|
|
||||||
}
|
|
||||||
"KC_6": {
|
|
||||||
"key": "BE_SECT",
|
|
||||||
"label": "§",
|
|
||||||
}
|
|
||||||
"KC_7": {
|
|
||||||
"key": "BE_EGRV",
|
|
||||||
"label": "è",
|
|
||||||
}
|
|
||||||
"KC_8": {
|
|
||||||
"key": "BE_EXLM",
|
|
||||||
"label": "!",
|
|
||||||
}
|
|
||||||
"KC_9": {
|
|
||||||
"key": "BE_CCED",
|
|
||||||
"label": "ç",
|
|
||||||
}
|
|
||||||
"KC_0": {
|
|
||||||
"key": "BE_AGRV",
|
|
||||||
"label": "à",
|
|
||||||
}
|
|
||||||
"KC_MINS": {
|
|
||||||
"key": "BE_RPRN",
|
|
||||||
"label": ")",
|
|
||||||
}
|
|
||||||
"KC_EQL": {
|
|
||||||
"key": "BE_MINS",
|
|
||||||
"label": "-",
|
|
||||||
}
|
|
||||||
"KC_Q": {
|
|
||||||
"key": "BE_A",
|
|
||||||
"label": "A",
|
|
||||||
}
|
|
||||||
"KC_W": {
|
|
||||||
"key": "BE_Z",
|
|
||||||
"label": "Z",
|
|
||||||
}
|
|
||||||
"KC_E": {
|
|
||||||
"key": "BE_E",
|
|
||||||
"label": "E",
|
|
||||||
}
|
|
||||||
"KC_R": {
|
|
||||||
"key": "BE_R",
|
|
||||||
"label": "R",
|
|
||||||
}
|
|
||||||
"KC_T": {
|
|
||||||
"key": "BE_T",
|
|
||||||
"label": "T",
|
|
||||||
}
|
|
||||||
"KC_Y": {
|
|
||||||
"key": "BE_Y",
|
|
||||||
"label": "Y",
|
|
||||||
}
|
|
||||||
"KC_U": {
|
|
||||||
"key": "BE_U",
|
|
||||||
"label": "U",
|
|
||||||
}
|
|
||||||
"KC_I": {
|
|
||||||
"key": "BE_I",
|
|
||||||
"label": "I",
|
|
||||||
}
|
|
||||||
"KC_O": {
|
|
||||||
"key": "BE_O",
|
|
||||||
"label": "O",
|
|
||||||
}
|
|
||||||
"KC_P": {
|
|
||||||
"key": "BE_P",
|
|
||||||
"label": "P",
|
|
||||||
}
|
|
||||||
"KC_LBRC": {
|
|
||||||
"key": "BE_DCIR",
|
|
||||||
"label": "^ (dead)",
|
|
||||||
}
|
|
||||||
"KC_RBRC": {
|
|
||||||
"key": "BE_DLR",
|
|
||||||
"label": "$",
|
|
||||||
}
|
|
||||||
"KC_A": {
|
|
||||||
"key": "BE_Q",
|
|
||||||
"label": "Q",
|
|
||||||
}
|
|
||||||
"KC_S": {
|
|
||||||
"key": "BE_S",
|
|
||||||
"label": "S",
|
|
||||||
}
|
|
||||||
"KC_D": {
|
|
||||||
"key": "BE_D",
|
|
||||||
"label": "D",
|
|
||||||
}
|
|
||||||
"KC_F": {
|
|
||||||
"key": "BE_F",
|
|
||||||
"label": "F",
|
|
||||||
}
|
|
||||||
"KC_G": {
|
|
||||||
"key": "BE_G",
|
|
||||||
"label": "G",
|
|
||||||
}
|
|
||||||
"KC_H": {
|
|
||||||
"key": "BE_H",
|
|
||||||
"label": "H",
|
|
||||||
}
|
|
||||||
"KC_J": {
|
|
||||||
"key": "BE_J",
|
|
||||||
"label": "J",
|
|
||||||
}
|
|
||||||
"KC_K": {
|
|
||||||
"key": "BE_K",
|
|
||||||
"label": "K",
|
|
||||||
}
|
|
||||||
"KC_L": {
|
|
||||||
"key": "BE_L",
|
|
||||||
"label": "L",
|
|
||||||
}
|
|
||||||
"KC_SCLN": {
|
|
||||||
"key": "BE_M",
|
|
||||||
"label": "M",
|
|
||||||
}
|
|
||||||
"KC_QUOT": {
|
|
||||||
"key": "BE_UGRV",
|
|
||||||
"label": "ù",
|
|
||||||
}
|
|
||||||
"KC_NUHS": {
|
|
||||||
"key": "BE_MICR",
|
|
||||||
"label": "µ",
|
|
||||||
}
|
|
||||||
"KC_NUBS": {
|
|
||||||
"key": "BE_LABK",
|
|
||||||
"label": "<",
|
|
||||||
}
|
|
||||||
"KC_Z": {
|
|
||||||
"key": "BE_W",
|
|
||||||
"label": "W",
|
|
||||||
}
|
|
||||||
"KC_X": {
|
|
||||||
"key": "BE_X",
|
|
||||||
"label": "X",
|
|
||||||
}
|
|
||||||
"KC_C": {
|
|
||||||
"key": "BE_C",
|
|
||||||
"label": "C",
|
|
||||||
}
|
|
||||||
"KC_V": {
|
|
||||||
"key": "BE_V",
|
|
||||||
"label": "V",
|
|
||||||
}
|
|
||||||
"KC_B": {
|
|
||||||
"key": "BE_B",
|
|
||||||
"label": "B",
|
|
||||||
}
|
|
||||||
"KC_N": {
|
|
||||||
"key": "BE_N",
|
|
||||||
"label": "N",
|
|
||||||
}
|
|
||||||
"KC_M": {
|
|
||||||
"key": "BE_COMM",
|
|
||||||
"label": ",",
|
|
||||||
}
|
|
||||||
"KC_COMM": {
|
|
||||||
"key": "BE_SCLN",
|
|
||||||
"label": ";",
|
|
||||||
}
|
|
||||||
"KC_DOT": {
|
|
||||||
"key": "BE_COLN",
|
|
||||||
"label": ":",
|
|
||||||
}
|
|
||||||
"KC_SLSH": {
|
|
||||||
"key": "BE_EQL",
|
|
||||||
"label": "=",
|
|
||||||
}
|
|
||||||
/* Shifted symbols
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ ³ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ° │ _ │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ │ │ ¨ │ * │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ │ │ % │ £ │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
|
|
||||||
* │ │ > │ │ │ │ │ │ │ ? │ . │ / │ + │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"S(BE_SUP2)": {
|
|
||||||
"key": "BE_SUP3",
|
|
||||||
"label": "³",
|
|
||||||
}
|
|
||||||
"S(BE_AMPR)": {
|
|
||||||
"key": "BE_1",
|
|
||||||
"label": "1",
|
|
||||||
}
|
|
||||||
"S(BE_EACU)": {
|
|
||||||
"key": "BE_2",
|
|
||||||
"label": "2",
|
|
||||||
}
|
|
||||||
"S(BE_DQUO)": {
|
|
||||||
"key": "BE_3",
|
|
||||||
"label": "3",
|
|
||||||
}
|
|
||||||
"S(BE_QUOT)": {
|
|
||||||
"key": "BE_4",
|
|
||||||
"label": "4",
|
|
||||||
}
|
|
||||||
"S(BE_LPRN)": {
|
|
||||||
"key": "BE_5",
|
|
||||||
"label": "5",
|
|
||||||
}
|
|
||||||
"S(BE_SECT)": {
|
|
||||||
"key": "BE_6",
|
|
||||||
"label": "6",
|
|
||||||
}
|
|
||||||
"S(BE_EGRV)": {
|
|
||||||
"key": "BE_7",
|
|
||||||
"label": "7",
|
|
||||||
}
|
|
||||||
"S(BE_EXLM)": {
|
|
||||||
"key": "BE_8",
|
|
||||||
"label": "8",
|
|
||||||
}
|
|
||||||
"S(BE_CCED)": {
|
|
||||||
"key": "BE_9",
|
|
||||||
"label": "9",
|
|
||||||
}
|
|
||||||
"S(BE_AGRV)": {
|
|
||||||
"key": "BE_0",
|
|
||||||
"label": "0",
|
|
||||||
}
|
|
||||||
"S(BE_RPRN)": {
|
|
||||||
"key": "BE_DEG",
|
|
||||||
"label": "°",
|
|
||||||
}
|
|
||||||
"S(BE_MINS)": {
|
|
||||||
"key": "BE_UNDS",
|
|
||||||
"label": "_",
|
|
||||||
}
|
|
||||||
"S(BE_DCIR)": {
|
|
||||||
"key": "BE_DIAE",
|
|
||||||
"label": "¨ (dead)",
|
|
||||||
}
|
|
||||||
"S(BE_DLR)": {
|
|
||||||
"key": "BE_ASTR",
|
|
||||||
"label": "*",
|
|
||||||
}
|
|
||||||
"S(BE_UGRV)": {
|
|
||||||
"key": "BE_PERC",
|
|
||||||
"label": "%",
|
|
||||||
}
|
|
||||||
"S(BE_MICR)": {
|
|
||||||
"key": "BE_PND",
|
|
||||||
"label": "£",
|
|
||||||
}
|
|
||||||
"S(BE_LABK)": {
|
|
||||||
"key": "BE_RABK",
|
|
||||||
"label": ">",
|
|
||||||
}
|
|
||||||
"S(BE_COMM)": {
|
|
||||||
"key": "BE_QUES",
|
|
||||||
"label": "?",
|
|
||||||
}
|
|
||||||
"S(BE_SCLN)": {
|
|
||||||
"key": "BE_DOT",
|
|
||||||
"label": ".",
|
|
||||||
}
|
|
||||||
"S(BE_COLN)": {
|
|
||||||
"key": "BE_SLSH",
|
|
||||||
"label": "/",
|
|
||||||
}
|
|
||||||
"S(BE_EQL)": {
|
|
||||||
"key": "BE_PLUS",
|
|
||||||
"label": "+",
|
|
||||||
}
|
|
||||||
/* AltGr symbols
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ │ | │ @ │ # │ │ │ ^ │ │ │ { │ } │ │ │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ │ │ € │ │ │ │ │ │ │ │ [ │ ] │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ │ │ ´ │ ` │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
|
|
||||||
* │ │ \ │ │ │ │ │ │ │ │ │ │ ~ │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"ALGR(BE_AMPR)": {
|
|
||||||
"key": "BE_PIPE",
|
|
||||||
"label": "|",
|
|
||||||
}
|
|
||||||
"ALGR(BE_EACU)": {
|
|
||||||
"key": "BE_AT",
|
|
||||||
"label": "@",
|
|
||||||
}
|
|
||||||
"ALGR(BE_DQUO)": {
|
|
||||||
"key": "BE_HASH",
|
|
||||||
"label": "#",
|
|
||||||
}
|
|
||||||
"ALGR(BE_SECT)": {
|
|
||||||
"key": "BE_CIRC",
|
|
||||||
"label": "^",
|
|
||||||
}
|
|
||||||
"ALGR(BE_CCED)": {
|
|
||||||
"key": "BE_LCBR",
|
|
||||||
"label": "{",
|
|
||||||
}
|
|
||||||
"ALGR(BE_AGRV)": {
|
|
||||||
"key": "BE_RCBR",
|
|
||||||
"label": "}",
|
|
||||||
}
|
|
||||||
"ALGR(BE_E)": {
|
|
||||||
"key": "BE_EURO",
|
|
||||||
"label": "€",
|
|
||||||
}
|
|
||||||
"ALGR(BE_DCIR)": {
|
|
||||||
"key": "BE_LBRC",
|
|
||||||
"label": "[",
|
|
||||||
}
|
|
||||||
"ALGR(BE_DLR)": {
|
|
||||||
"key": "BE_RBRC",
|
|
||||||
"label": "]",
|
|
||||||
}
|
|
||||||
"ALGR(BE_UGRV)": {
|
|
||||||
"key": "BE_ACUT",
|
|
||||||
"label": "´ (dead)",
|
|
||||||
}
|
|
||||||
"ALGR(BE_MICR)": {
|
|
||||||
"key": "BE_GRV",
|
|
||||||
"label": "` (dead)",
|
|
||||||
}
|
|
||||||
"ALGR(BE_LABK)": {
|
|
||||||
"key": "BE_BSLS",
|
|
||||||
"label": "\\",
|
|
||||||
}
|
|
||||||
"ALGR(BE_EQL)": {
|
|
||||||
"key": "BE_TILD",
|
|
||||||
"label": "~",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,632 +0,0 @@
|
||||||
{
|
|
||||||
"aliases": {
|
|
||||||
/*
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ $ │ " │ « │ » │ ( │ ) │ @ │ + │ - │ / │ * │ = │ % │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ B │ É │ P │ O │ È │ ^ │ V │ D │ L │ J │ Z │ W │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ A │ U │ I │ E │ , │ C │ T │ S │ R │ N │ M │ Ç │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
|
|
||||||
* │ │ Ê │ À │ Y │ X │ . │ K │ ' │ Q │ G │ H │ F │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"KC_GRV": {
|
|
||||||
"key": "BP_DLR",
|
|
||||||
"label": "$",
|
|
||||||
}
|
|
||||||
"KC_1": {
|
|
||||||
"key": "BP_DQUO",
|
|
||||||
"label": "\"",
|
|
||||||
}
|
|
||||||
"KC_2": {
|
|
||||||
"key": "BP_LDAQ",
|
|
||||||
"label": "«",
|
|
||||||
}
|
|
||||||
"KC_3": {
|
|
||||||
"key": "BP_RDAQ",
|
|
||||||
"label": "»",
|
|
||||||
}
|
|
||||||
"KC_4": {
|
|
||||||
"key": "BP_LPRN",
|
|
||||||
"label": "(",
|
|
||||||
}
|
|
||||||
"KC_5": {
|
|
||||||
"key": "BP_RPRN",
|
|
||||||
"label": ")",
|
|
||||||
}
|
|
||||||
"KC_6": {
|
|
||||||
"key": "BP_AT",
|
|
||||||
"label": "@",
|
|
||||||
}
|
|
||||||
"KC_7": {
|
|
||||||
"key": "BP_PLUS",
|
|
||||||
"label": "+",
|
|
||||||
}
|
|
||||||
"KC_8": {
|
|
||||||
"key": "BP_MINS",
|
|
||||||
"label": "-",
|
|
||||||
}
|
|
||||||
"KC_9": {
|
|
||||||
"key": "BP_SLSH",
|
|
||||||
"label": "/",
|
|
||||||
}
|
|
||||||
"KC_0": {
|
|
||||||
"key": "BP_ASTR",
|
|
||||||
"label": "*",
|
|
||||||
}
|
|
||||||
"KC_MINS": {
|
|
||||||
"key": "BP_EQL",
|
|
||||||
"label": "=",
|
|
||||||
}
|
|
||||||
"KC_EQL": {
|
|
||||||
"key": "BP_PERC",
|
|
||||||
"label": "%",
|
|
||||||
}
|
|
||||||
"KC_Q": {
|
|
||||||
"key": "BP_B",
|
|
||||||
"label": "B",
|
|
||||||
}
|
|
||||||
"KC_W": {
|
|
||||||
"key": "BP_EACU",
|
|
||||||
"label": "É",
|
|
||||||
}
|
|
||||||
"KC_E": {
|
|
||||||
"key": "BP_P",
|
|
||||||
"label": "P",
|
|
||||||
}
|
|
||||||
"KC_R": {
|
|
||||||
"key": "BP_O",
|
|
||||||
"label": "O",
|
|
||||||
}
|
|
||||||
"KC_T": {
|
|
||||||
"key": "BP_EGRV",
|
|
||||||
"label": "È",
|
|
||||||
}
|
|
||||||
"KC_Y": {
|
|
||||||
"key": "BP_DCIR",
|
|
||||||
"label": "^ (dead)",
|
|
||||||
}
|
|
||||||
"KC_U": {
|
|
||||||
"key": "BP_V",
|
|
||||||
"label": "V",
|
|
||||||
}
|
|
||||||
"KC_I": {
|
|
||||||
"key": "BP_D",
|
|
||||||
"label": "D",
|
|
||||||
}
|
|
||||||
"KC_O": {
|
|
||||||
"key": "BP_L",
|
|
||||||
"label": "L",
|
|
||||||
}
|
|
||||||
"KC_P": {
|
|
||||||
"key": "BP_J",
|
|
||||||
"label": "J",
|
|
||||||
}
|
|
||||||
"KC_LBRC": {
|
|
||||||
"key": "BP_Z",
|
|
||||||
"label": "Z",
|
|
||||||
}
|
|
||||||
"KC_RBRC": {
|
|
||||||
"key": "BP_W",
|
|
||||||
"label": "W",
|
|
||||||
}
|
|
||||||
"KC_A": {
|
|
||||||
"key": "BP_A",
|
|
||||||
"label": "A",
|
|
||||||
}
|
|
||||||
"KC_S": {
|
|
||||||
"key": "BP_U",
|
|
||||||
"label": "U",
|
|
||||||
}
|
|
||||||
"KC_D": {
|
|
||||||
"key": "BP_I",
|
|
||||||
"label": "I",
|
|
||||||
}
|
|
||||||
"KC_F": {
|
|
||||||
"key": "BP_E",
|
|
||||||
"label": "E",
|
|
||||||
}
|
|
||||||
"KC_G": {
|
|
||||||
"key": "BP_COMM",
|
|
||||||
"label": ",",
|
|
||||||
}
|
|
||||||
"KC_H": {
|
|
||||||
"key": "BP_C",
|
|
||||||
"label": "C",
|
|
||||||
}
|
|
||||||
"KC_J": {
|
|
||||||
"key": "BP_T",
|
|
||||||
"label": "T",
|
|
||||||
}
|
|
||||||
"KC_K": {
|
|
||||||
"key": "BP_S",
|
|
||||||
"label": "S",
|
|
||||||
}
|
|
||||||
"KC_L": {
|
|
||||||
"key": "BP_R",
|
|
||||||
"label": "R",
|
|
||||||
}
|
|
||||||
"KC_SCLN": {
|
|
||||||
"key": "BP_N",
|
|
||||||
"label": "N",
|
|
||||||
}
|
|
||||||
"KC_QUOT": {
|
|
||||||
"key": "BP_M",
|
|
||||||
"label": "M",
|
|
||||||
}
|
|
||||||
"KC_BSLS": {
|
|
||||||
"key": "BP_CCED",
|
|
||||||
"label": "Ç",
|
|
||||||
}
|
|
||||||
"KC_NUBS": {
|
|
||||||
"key": "BP_ECIR",
|
|
||||||
"label": "Ê",
|
|
||||||
}
|
|
||||||
"KC_Z": {
|
|
||||||
"key": "BP_AGRV",
|
|
||||||
"label": "À",
|
|
||||||
}
|
|
||||||
"KC_X": {
|
|
||||||
"key": "BP_Y",
|
|
||||||
"label": "Y",
|
|
||||||
}
|
|
||||||
"KC_C": {
|
|
||||||
"key": "BP_X",
|
|
||||||
"label": "X",
|
|
||||||
}
|
|
||||||
"KC_V": {
|
|
||||||
"key": "BP_DOT",
|
|
||||||
"label": ".",
|
|
||||||
}
|
|
||||||
"KC_B": {
|
|
||||||
"key": "BP_K",
|
|
||||||
"label": "K",
|
|
||||||
}
|
|
||||||
"KC_N": {
|
|
||||||
"key": "BP_QUOT",
|
|
||||||
"label": "'",
|
|
||||||
}
|
|
||||||
"KC_M": {
|
|
||||||
"key": "BP_Q",
|
|
||||||
"label": "Q",
|
|
||||||
}
|
|
||||||
"KC_COMM": {
|
|
||||||
"key": "BP_G",
|
|
||||||
"label": "G",
|
|
||||||
}
|
|
||||||
"KC_DOT": {
|
|
||||||
"key": "BP_H",
|
|
||||||
"label": "H",
|
|
||||||
}
|
|
||||||
"KC_SLSH": {
|
|
||||||
"key": "BP_F",
|
|
||||||
"label": "F",
|
|
||||||
}
|
|
||||||
/* Shifted symbols
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ # │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ° │ ` │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ │ │ │ │ │ ! │ │ │ │ │ │ │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ │ │ │ │ ; │ │ │ │ │ │ │ │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
|
|
||||||
* │ │ │ │ │ │ : │ │ ? │ │ │ │ │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"S(BP_DLR)": {
|
|
||||||
"key": "BP_HASH",
|
|
||||||
"label": "#",
|
|
||||||
}
|
|
||||||
"S(BP_DQUO)": {
|
|
||||||
"key": "BP_1",
|
|
||||||
"label": "1",
|
|
||||||
}
|
|
||||||
"S(BP_LDAQ)": {
|
|
||||||
"key": "BP_2",
|
|
||||||
"label": "2",
|
|
||||||
}
|
|
||||||
"S(BP_RDAQ)": {
|
|
||||||
"key": "BP_3",
|
|
||||||
"label": "3",
|
|
||||||
}
|
|
||||||
"S(BP_LPRN)": {
|
|
||||||
"key": "BP_4",
|
|
||||||
"label": "4",
|
|
||||||
}
|
|
||||||
"S(BP_RPRN)": {
|
|
||||||
"key": "BP_5",
|
|
||||||
"label": "5",
|
|
||||||
}
|
|
||||||
"S(BP_AT)": {
|
|
||||||
"key": "BP_6",
|
|
||||||
"label": "6",
|
|
||||||
}
|
|
||||||
"S(BP_PLUS)": {
|
|
||||||
"key": "BP_7",
|
|
||||||
"label": "7",
|
|
||||||
}
|
|
||||||
"S(BP_MINS)": {
|
|
||||||
"key": "BP_8",
|
|
||||||
"label": "8",
|
|
||||||
}
|
|
||||||
"S(BP_SLSH)": {
|
|
||||||
"key": "BP_9",
|
|
||||||
"label": "9",
|
|
||||||
}
|
|
||||||
"S(BP_ASTR)": {
|
|
||||||
"key": "BP_0",
|
|
||||||
"label": "0",
|
|
||||||
}
|
|
||||||
"S(BP_EQL)": {
|
|
||||||
"key": "BP_DEG",
|
|
||||||
"label": "°",
|
|
||||||
}
|
|
||||||
"S(BP_PERC)": {
|
|
||||||
"key": "BP_GRV",
|
|
||||||
"label": "`",
|
|
||||||
}
|
|
||||||
"S(BP_DCIR)": {
|
|
||||||
"key": "BP_EXLM",
|
|
||||||
"label": "!",
|
|
||||||
}
|
|
||||||
"S(BP_COMM)": {
|
|
||||||
"key": "BP_SCLN",
|
|
||||||
"label": ";",
|
|
||||||
}
|
|
||||||
"S(BP_DOT)": {
|
|
||||||
"key": "BP_COLN",
|
|
||||||
"label": ":",
|
|
||||||
}
|
|
||||||
"S(BP_QUOT)": {
|
|
||||||
"key": "BP_QUES",
|
|
||||||
"label": "?",
|
|
||||||
}
|
|
||||||
"S(KC_SPC)": {
|
|
||||||
"key": "BP_NBSP",
|
|
||||||
"label": "(non-breaking space)",
|
|
||||||
}
|
|
||||||
/* AltGr symbols
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ – │ — │ < │ > │ [ │ ] │ ^ │ ± │ − │ ÷ │ × │ ≠ │ ‰ │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ | │ ´ │ & │ Œ │ ` │ ¡ │ ˇ │ Ð │ / │ IJ │ Ə │ ˘ │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ Æ │ Ù │ ¨ │ € │ │ © │ Þ │ ẞ │ ® │ ~ │ ¯ │ ¸ │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
|
|
||||||
* │ │ │ \ │ { │ } │ … │ ~ │ ¿ │ ° │ │ † │ ˛ │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ _ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"ALGR(BP_DLR)": {
|
|
||||||
"key": "BP_NDSH",
|
|
||||||
"label": "–",
|
|
||||||
}
|
|
||||||
"ALGR(BP_DQUO)": {
|
|
||||||
"key": "BP_MDSH",
|
|
||||||
"label": "—",
|
|
||||||
}
|
|
||||||
"ALGR(BP_LDAQ)": {
|
|
||||||
"key": "BP_LABK",
|
|
||||||
"label": "<",
|
|
||||||
}
|
|
||||||
"ALGR(BP_RDAQ)": {
|
|
||||||
"key": "BP_RABK",
|
|
||||||
"label": ">",
|
|
||||||
}
|
|
||||||
"ALGR(BP_LPRN)": {
|
|
||||||
"key": "BP_LBRC",
|
|
||||||
"label": "[",
|
|
||||||
}
|
|
||||||
"ALGR(BP_RPRN)": {
|
|
||||||
"key": "BP_RBRC",
|
|
||||||
"label": "]",
|
|
||||||
}
|
|
||||||
"ALGR(BP_AT)": {
|
|
||||||
"key": "BP_CIRC",
|
|
||||||
"label": "^",
|
|
||||||
}
|
|
||||||
"ALGR(BP_PLUS)": {
|
|
||||||
"key": "BP_PLMN",
|
|
||||||
"label": "±",
|
|
||||||
}
|
|
||||||
"ALGR(BP_MINS)": {
|
|
||||||
"key": "BP_MMNS",
|
|
||||||
"label": "−",
|
|
||||||
}
|
|
||||||
"ALGR(BP_SLSH)": {
|
|
||||||
"key": "BP_DIV",
|
|
||||||
"label": "÷",
|
|
||||||
}
|
|
||||||
"ALGR(BP_ASTR)": {
|
|
||||||
"key": "BP_MUL",
|
|
||||||
"label": "×",
|
|
||||||
}
|
|
||||||
"ALGR(BP_EQL)": {
|
|
||||||
"key": "BP_NEQL",
|
|
||||||
"label": "≠",
|
|
||||||
}
|
|
||||||
"ALGR(BP_PERC)": {
|
|
||||||
"key": "BP_PERM",
|
|
||||||
"label": "‰",
|
|
||||||
}
|
|
||||||
"ALGR(BP_B)": {
|
|
||||||
"key": "BP_PIPE",
|
|
||||||
"label": "|",
|
|
||||||
}
|
|
||||||
"ALGR(BP_EACU)": {
|
|
||||||
"key": "BP_ACUT",
|
|
||||||
"label": "´ (dead)",
|
|
||||||
}
|
|
||||||
"ALGR(BP_P)": {
|
|
||||||
"key": "BP_AMPR",
|
|
||||||
"label": "&",
|
|
||||||
}
|
|
||||||
"ALGR(BP_O)": {
|
|
||||||
"key": "BP_OE",
|
|
||||||
"label": "Œ",
|
|
||||||
}
|
|
||||||
"ALGR(BP_EGRV)": {
|
|
||||||
"key": "BP_DGRV",
|
|
||||||
"label": "` (dead)",
|
|
||||||
}
|
|
||||||
"ALGR(BP_DCIR)": {
|
|
||||||
"key": "BP_IEXL",
|
|
||||||
"label": "¡",
|
|
||||||
}
|
|
||||||
"ALGR(BP_V)": {
|
|
||||||
"key": "BP_CARN",
|
|
||||||
"label": "ˇ (dead)",
|
|
||||||
}
|
|
||||||
"ALGR(BP_D)": {
|
|
||||||
"key": "BP_ETH",
|
|
||||||
"label": "Ð",
|
|
||||||
}
|
|
||||||
"ALGR(BP_L)": {
|
|
||||||
"key": "BP_DSLS",
|
|
||||||
"label": "/ (dead)",
|
|
||||||
}
|
|
||||||
"ALGR(BP_J)": {
|
|
||||||
"key": "BP_IJ",
|
|
||||||
"label": "IJ",
|
|
||||||
}
|
|
||||||
"ALGR(BP_Z)": {
|
|
||||||
"key": "BP_SCHW",
|
|
||||||
"label": "Ə",
|
|
||||||
}
|
|
||||||
"ALGR(BP_W)": {
|
|
||||||
"key": "BP_BREV",
|
|
||||||
"label": "˘ (dead)",
|
|
||||||
}
|
|
||||||
"ALGR(BP_A)": {
|
|
||||||
"key": "BP_AE",
|
|
||||||
"label": "Æ",
|
|
||||||
}
|
|
||||||
"ALGR(BP_U)": {
|
|
||||||
"key": "BP_UGRV",
|
|
||||||
"label": "Ù",
|
|
||||||
}
|
|
||||||
"ALGR(BP_I)": {
|
|
||||||
"key": "BP_DIAE",
|
|
||||||
"label": "¨ (dead)",
|
|
||||||
}
|
|
||||||
"ALGR(BP_E)": {
|
|
||||||
"key": "BP_EURO",
|
|
||||||
"label": "€",
|
|
||||||
}
|
|
||||||
"ALGR(BP_C)": {
|
|
||||||
"key": "BP_COPY",
|
|
||||||
"label": "©",
|
|
||||||
}
|
|
||||||
"ALGR(BP_T)": {
|
|
||||||
"key": "BP_THRN",
|
|
||||||
"label": "Þ",
|
|
||||||
}
|
|
||||||
"ALGR(BP_S)": {
|
|
||||||
"key": "BP_SS",
|
|
||||||
"label": "ẞ",
|
|
||||||
}
|
|
||||||
"ALGR(BP_R)": {
|
|
||||||
"key": "BP_REGD",
|
|
||||||
"label": "®",
|
|
||||||
}
|
|
||||||
"ALGR(BP_N)": {
|
|
||||||
"key": "BP_DTIL",
|
|
||||||
"label": "~ (dead)",
|
|
||||||
}
|
|
||||||
"ALGR(BP_M)": {
|
|
||||||
"key": "BP_MACR",
|
|
||||||
"label": "¯ (dead)",
|
|
||||||
}
|
|
||||||
"ALGR(BP_CCED)": {
|
|
||||||
"key": "BP_CEDL",
|
|
||||||
"label": "¸ (dead)",
|
|
||||||
}
|
|
||||||
"ALGR(BP_AGRV)": {
|
|
||||||
"key": "BP_BSLS",
|
|
||||||
"label": "\\",
|
|
||||||
}
|
|
||||||
"ALGR(BP_Y)": {
|
|
||||||
"key": "BP_LCBR",
|
|
||||||
"label": "{",
|
|
||||||
}
|
|
||||||
"ALGR(BP_X)": {
|
|
||||||
"key": "BP_RCBR",
|
|
||||||
"label": "}",
|
|
||||||
}
|
|
||||||
"ALGR(BP_DOT)": {
|
|
||||||
"key": "BP_ELLP",
|
|
||||||
"label": "…",
|
|
||||||
}
|
|
||||||
"ALGR(BP_K)": {
|
|
||||||
"key": "BP_TILD",
|
|
||||||
"label": "~",
|
|
||||||
}
|
|
||||||
"ALGR(BP_QUES)": {
|
|
||||||
"key": "BP_IQUE",
|
|
||||||
"label": "¿",
|
|
||||||
}
|
|
||||||
"ALGR(BP_Q)": {
|
|
||||||
"key": "BP_RNGA",
|
|
||||||
"label": "° (dead)",
|
|
||||||
}
|
|
||||||
"ALGR(BP_G)": {
|
|
||||||
"key": "BP_DGRK",
|
|
||||||
"label": "µ (dead Greek key)",
|
|
||||||
}
|
|
||||||
"ALGR(BP_H)": {
|
|
||||||
"key": "BP_DAGG",
|
|
||||||
"label": "†",
|
|
||||||
}
|
|
||||||
"ALGR(BP_F)": {
|
|
||||||
"key": "BP_OGON",
|
|
||||||
"label": "˛ (dead)",
|
|
||||||
}
|
|
||||||
"ALGR(KC_SPC)": {
|
|
||||||
"key": "BP_UNDS",
|
|
||||||
"label": "_",
|
|
||||||
}
|
|
||||||
/* Shift+AltGr symbols
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ ¶ │ „ │ “ │ ” │ ≤ │ ≥ │ │ ¬ │ ¼ │ ½ │ ¾ │ ′ │ ″ │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ ¦ │ ˝ │ § │ │ │ │ │ │ │ │ │ │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ │ │ ˙ │ ¤ │ ̛ │ ſ │ │ │ ™ │ │ º │ , │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
|
|
||||||
* │ │ │ │ ‘ │ ’ │ · │ ⌨ │ ̉ │ ̣ │ │ ‡ │ ª │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"S(ALGR(BP_DLR))": {
|
|
||||||
"key": "BP_PARA",
|
|
||||||
"label": "¶",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_DQUO))": {
|
|
||||||
"key": "BP_DLQU",
|
|
||||||
"label": "„",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_LDAQ))": {
|
|
||||||
"key": "BP_LDQU",
|
|
||||||
"label": "“",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_RDAQ))": {
|
|
||||||
"key": "BP_RDQU",
|
|
||||||
"label": "”",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_LPRN))": {
|
|
||||||
"key": "BP_LEQL",
|
|
||||||
"label": "≤",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_RPRN))": {
|
|
||||||
"key": "BP_GEQL",
|
|
||||||
"label": "≥",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_PLUS))": {
|
|
||||||
"key": "BP_NOT",
|
|
||||||
"label": "¬",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_MINS))": {
|
|
||||||
"key": "BP_QRTR",
|
|
||||||
"label": "¼",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_SLSH))": {
|
|
||||||
"key": "BP_HALF",
|
|
||||||
"label": "½",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_ASTR))": {
|
|
||||||
"key": "BP_TQTR",
|
|
||||||
"label": "¾",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_EQL))": {
|
|
||||||
"key": "BP_PRIM",
|
|
||||||
"label": "′",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_PERC))": {
|
|
||||||
"key": "BP_DPRM",
|
|
||||||
"label": "″",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_B))": {
|
|
||||||
"key": "BP_BRKP",
|
|
||||||
"label": "¦",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_EACU))": {
|
|
||||||
"key": "BP_DACU",
|
|
||||||
"label": "˝ (dead)",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_P))": {
|
|
||||||
"key": "BP_SECT",
|
|
||||||
"label": "§",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_I))": {
|
|
||||||
"key": "BP_DOTA",
|
|
||||||
"label": "˙ (dead)",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_E))": {
|
|
||||||
"key": "BP_CURR",
|
|
||||||
"label": "¤ (dead)",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_COMM))": {
|
|
||||||
"key": "BP_HORN",
|
|
||||||
"label": "̛ (dead)",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_C))": {
|
|
||||||
"key": "BP_LNGS",
|
|
||||||
"label": "ſ",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_R))": {
|
|
||||||
"key": "BP_TM",
|
|
||||||
"label": "™",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_M))": {
|
|
||||||
"key": "BP_MORD",
|
|
||||||
"label": "º",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_CCED))": {
|
|
||||||
"key": "BP_DCMM",
|
|
||||||
"label": ", (dead)",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_Y))": {
|
|
||||||
"key": "BP_LSQU",
|
|
||||||
"label": "‘",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_X))": {
|
|
||||||
"key": "BP_RSQU",
|
|
||||||
"label": "’",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_DOT))": {
|
|
||||||
"key": "BP_MDDT",
|
|
||||||
"label": "·",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_K))": {
|
|
||||||
"key": "BP_KEYB",
|
|
||||||
"label": "⌨",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_QUOT))": {
|
|
||||||
"key": "BP_HOKA",
|
|
||||||
"label": "̉ (dead)",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_Q))": {
|
|
||||||
"key": "BP_DOTB",
|
|
||||||
"label": "̣ (dead)",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_H))": {
|
|
||||||
"key": "BP_DDAG",
|
|
||||||
"label": "‡",
|
|
||||||
}
|
|
||||||
"S(ALGR(BP_F))": {
|
|
||||||
"key": "BP_FORD",
|
|
||||||
"label": "ª",
|
|
||||||
}
|
|
||||||
"S(ALGR(KC_SPC))": {
|
|
||||||
"key": "BP_NNBS",
|
|
||||||
"label": "(narrow non-breaking space)",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,379 +0,0 @@
|
||||||
{
|
|
||||||
"aliases": {
|
|
||||||
/*
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ ' │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ ´ │ [ │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ç │ ~ │ ] │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┤
|
|
||||||
* │ │ \ │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ ; │ / │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬──┴─┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"KC_GRV": {
|
|
||||||
"key": "BR_QUOT",
|
|
||||||
"label": "'",
|
|
||||||
}
|
|
||||||
"KC_1": {
|
|
||||||
"key": "BR_1",
|
|
||||||
"label": "1",
|
|
||||||
}
|
|
||||||
"KC_2": {
|
|
||||||
"key": "BR_2",
|
|
||||||
"label": "2",
|
|
||||||
}
|
|
||||||
"KC_3": {
|
|
||||||
"key": "BR_3",
|
|
||||||
"label": "3",
|
|
||||||
}
|
|
||||||
"KC_4": {
|
|
||||||
"key": "BR_4",
|
|
||||||
"label": "4",
|
|
||||||
}
|
|
||||||
"KC_5": {
|
|
||||||
"key": "BR_5",
|
|
||||||
"label": "5",
|
|
||||||
}
|
|
||||||
"KC_6": {
|
|
||||||
"key": "BR_6",
|
|
||||||
"label": "6",
|
|
||||||
}
|
|
||||||
"KC_7": {
|
|
||||||
"key": "BR_7",
|
|
||||||
"label": "7",
|
|
||||||
}
|
|
||||||
"KC_8": {
|
|
||||||
"key": "BR_8",
|
|
||||||
"label": "8",
|
|
||||||
}
|
|
||||||
"KC_9": {
|
|
||||||
"key": "BR_9",
|
|
||||||
"label": "9",
|
|
||||||
}
|
|
||||||
"KC_0": {
|
|
||||||
"key": "BR_0",
|
|
||||||
"label": "0",
|
|
||||||
}
|
|
||||||
"KC_MINS": {
|
|
||||||
"key": "BR_MINS",
|
|
||||||
"label": "-",
|
|
||||||
}
|
|
||||||
"KC_EQL": {
|
|
||||||
"key": "BR_EQL",
|
|
||||||
"label": "=",
|
|
||||||
}
|
|
||||||
"KC_Q": {
|
|
||||||
"key": "BR_Q",
|
|
||||||
"label": "Q",
|
|
||||||
}
|
|
||||||
"KC_W": {
|
|
||||||
"key": "BR_W",
|
|
||||||
"label": "W",
|
|
||||||
}
|
|
||||||
"KC_E": {
|
|
||||||
"key": "BR_E",
|
|
||||||
"label": "E",
|
|
||||||
}
|
|
||||||
"KC_R": {
|
|
||||||
"key": "BR_R",
|
|
||||||
"label": "R",
|
|
||||||
}
|
|
||||||
"KC_T": {
|
|
||||||
"key": "BR_T",
|
|
||||||
"label": "T",
|
|
||||||
}
|
|
||||||
"KC_Y": {
|
|
||||||
"key": "BR_Y",
|
|
||||||
"label": "Y",
|
|
||||||
}
|
|
||||||
"KC_U": {
|
|
||||||
"key": "BR_U",
|
|
||||||
"label": "U",
|
|
||||||
}
|
|
||||||
"KC_I": {
|
|
||||||
"key": "BR_I",
|
|
||||||
"label": "I",
|
|
||||||
}
|
|
||||||
"KC_O": {
|
|
||||||
"key": "BR_O",
|
|
||||||
"label": "O",
|
|
||||||
}
|
|
||||||
"KC_P": {
|
|
||||||
"key": "BR_P",
|
|
||||||
"label": "P",
|
|
||||||
}
|
|
||||||
"KC_LBRC": {
|
|
||||||
"key": "BR_ACUT",
|
|
||||||
"label": "´ (dead)",
|
|
||||||
}
|
|
||||||
"KC_RBRC": {
|
|
||||||
"key": "BR_LBRC",
|
|
||||||
"label": "[",
|
|
||||||
}
|
|
||||||
"KC_A": {
|
|
||||||
"key": "BR_A",
|
|
||||||
"label": "A",
|
|
||||||
}
|
|
||||||
"KC_S": {
|
|
||||||
"key": "BR_S",
|
|
||||||
"label": "S",
|
|
||||||
}
|
|
||||||
"KC_D": {
|
|
||||||
"key": "BR_D",
|
|
||||||
"label": "D",
|
|
||||||
}
|
|
||||||
"KC_F": {
|
|
||||||
"key": "BR_F",
|
|
||||||
"label": "F",
|
|
||||||
}
|
|
||||||
"KC_G": {
|
|
||||||
"key": "BR_G",
|
|
||||||
"label": "G",
|
|
||||||
}
|
|
||||||
"KC_H": {
|
|
||||||
"key": "BR_H",
|
|
||||||
"label": "H",
|
|
||||||
}
|
|
||||||
"KC_J": {
|
|
||||||
"key": "BR_J",
|
|
||||||
"label": "J",
|
|
||||||
}
|
|
||||||
"KC_K": {
|
|
||||||
"key": "BR_K",
|
|
||||||
"label": "K",
|
|
||||||
}
|
|
||||||
"KC_L": {
|
|
||||||
"key": "BR_L",
|
|
||||||
"label": "L",
|
|
||||||
}
|
|
||||||
"KC_SCLN": {
|
|
||||||
"key": "BR_CCED",
|
|
||||||
"label": "Ç",
|
|
||||||
}
|
|
||||||
"KC_QUOT": {
|
|
||||||
"key": "BR_TILD",
|
|
||||||
"label": "~ (dead)",
|
|
||||||
}
|
|
||||||
"KC_BSLS": {
|
|
||||||
"key": "BR_RBRC",
|
|
||||||
"label": "]",
|
|
||||||
}
|
|
||||||
"KC_NUBS": {
|
|
||||||
"key": "BR_BSLS",
|
|
||||||
"label": "\\",
|
|
||||||
}
|
|
||||||
"KC_Z": {
|
|
||||||
"key": "BR_Z",
|
|
||||||
"label": "Z",
|
|
||||||
}
|
|
||||||
"KC_X": {
|
|
||||||
"key": "BR_X",
|
|
||||||
"label": "X",
|
|
||||||
}
|
|
||||||
"KC_C": {
|
|
||||||
"key": "BR_C",
|
|
||||||
"label": "C",
|
|
||||||
}
|
|
||||||
"KC_V": {
|
|
||||||
"key": "BR_V",
|
|
||||||
"label": "V",
|
|
||||||
}
|
|
||||||
"KC_B": {
|
|
||||||
"key": "BR_B",
|
|
||||||
"label": "B",
|
|
||||||
}
|
|
||||||
"KC_N": {
|
|
||||||
"key": "BR_N",
|
|
||||||
"label": "N",
|
|
||||||
}
|
|
||||||
"KC_M": {
|
|
||||||
"key": "BR_M",
|
|
||||||
"label": "M",
|
|
||||||
}
|
|
||||||
"KC_COMM": {
|
|
||||||
"key": "BR_COMM",
|
|
||||||
"label": ",",
|
|
||||||
}
|
|
||||||
"KC_DOT": {
|
|
||||||
"key": "BR_DOT",
|
|
||||||
"label": ".",
|
|
||||||
}
|
|
||||||
"KC_SLSH": {
|
|
||||||
"key": "BR_SCLN",
|
|
||||||
"label": ";",
|
|
||||||
}
|
|
||||||
"KC_INT1": {
|
|
||||||
"key": "BR_SLSH",
|
|
||||||
"label": "/",
|
|
||||||
}
|
|
||||||
"KC_PCMM": {
|
|
||||||
"key": "BR_PDOT",
|
|
||||||
"label": ".",
|
|
||||||
}
|
|
||||||
"KC_PDOT": {
|
|
||||||
"key": "BR_PCMM",
|
|
||||||
"label": ",",
|
|
||||||
}
|
|
||||||
/* Shifted symbols
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ " │ ! │ @ │ # │ $ │ % │ ¨ │ & │ * │ ( │ ) │ _ │ + │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ │ │ ` │ { │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ │ │ ^ │ } │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┤
|
|
||||||
* │ │ | │ │ │ │ │ │ │ │ < │ > │ : │ ? │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬──┴─┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"S(BR_QUOT)": {
|
|
||||||
"key": "BR_DQUO",
|
|
||||||
"label": "\"",
|
|
||||||
}
|
|
||||||
"S(BR_1)": {
|
|
||||||
"key": "BR_EXLM",
|
|
||||||
"label": "!",
|
|
||||||
}
|
|
||||||
"S(BR_2)": {
|
|
||||||
"key": "BR_AT",
|
|
||||||
"label": "@",
|
|
||||||
}
|
|
||||||
"S(BR_3)": {
|
|
||||||
"key": "BR_HASH",
|
|
||||||
"label": "#",
|
|
||||||
}
|
|
||||||
"S(BR_4)": {
|
|
||||||
"key": "BR_DLR",
|
|
||||||
"label": "$",
|
|
||||||
}
|
|
||||||
"S(BR_5)": {
|
|
||||||
"key": "BR_PERC",
|
|
||||||
"label": "%",
|
|
||||||
}
|
|
||||||
"S(BR_6)": {
|
|
||||||
"key": "BR_DIAE",
|
|
||||||
"label": "¨ (dead)",
|
|
||||||
}
|
|
||||||
"S(BR_7)": {
|
|
||||||
"key": "BR_AMPR",
|
|
||||||
"label": "&",
|
|
||||||
}
|
|
||||||
"S(BR_8)": {
|
|
||||||
"key": "BR_ASTR",
|
|
||||||
"label": "*",
|
|
||||||
}
|
|
||||||
"S(BR_9)": {
|
|
||||||
"key": "BR_LPRN",
|
|
||||||
"label": "(",
|
|
||||||
}
|
|
||||||
"S(BR_0)": {
|
|
||||||
"key": "BR_RPRN",
|
|
||||||
"label": ")",
|
|
||||||
}
|
|
||||||
"S(BR_MINS)": {
|
|
||||||
"key": "BR_UNDS",
|
|
||||||
"label": "_",
|
|
||||||
}
|
|
||||||
"S(BR_EQL)": {
|
|
||||||
"key": "BR_PLUS",
|
|
||||||
"label": "+",
|
|
||||||
}
|
|
||||||
"S(BR_ACUT)": {
|
|
||||||
"key": "BR_GRV",
|
|
||||||
"label": "` (dead)",
|
|
||||||
}
|
|
||||||
"S(BR_LBRC)": {
|
|
||||||
"key": "BR_LCBR",
|
|
||||||
"label": "{",
|
|
||||||
}
|
|
||||||
"S(BR_TILD)": {
|
|
||||||
"key": "BR_CIRC",
|
|
||||||
"label": "^ (dead)",
|
|
||||||
}
|
|
||||||
"S(BR_RBRC)": {
|
|
||||||
"key": "BR_RCBR",
|
|
||||||
"label": "}",
|
|
||||||
}
|
|
||||||
"S(BR_BSLS)": {
|
|
||||||
"key": "BR_PIPE",
|
|
||||||
"label": "|",
|
|
||||||
}
|
|
||||||
"S(BR_COMM)": {
|
|
||||||
"key": "BR_LABK",
|
|
||||||
"label": "<",
|
|
||||||
}
|
|
||||||
"S(BR_DOT)": {
|
|
||||||
"key": "BR_RABK",
|
|
||||||
"label": ">",
|
|
||||||
}
|
|
||||||
"S(BR_SCLN)": {
|
|
||||||
"key": "BR_COLN",
|
|
||||||
"label": ":",
|
|
||||||
}
|
|
||||||
"S(BR_SLSH)": {
|
|
||||||
"key": "BR_QUES",
|
|
||||||
"label": "?",
|
|
||||||
}
|
|
||||||
/* AltGr symbols
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ │ ¹ │ ² │ ³ │ £ │ ¢ │ ¬ │ │ │ │ │ │ § │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ │ │ ° │ │ │ │ │ │ │ │ │ ª │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ │ │ │ º │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┤
|
|
||||||
* │ │ │ │ │ ₢ │ │ │ │ │ │ │ │ │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬──┴─┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"ALGR(BR_1)": {
|
|
||||||
"key": "BR_SUP1",
|
|
||||||
"label": "¹",
|
|
||||||
}
|
|
||||||
"ALGR(BR_2)": {
|
|
||||||
"key": "BR_SUP2",
|
|
||||||
"label": "²",
|
|
||||||
}
|
|
||||||
"ALGR(BR_3)": {
|
|
||||||
"key": "BR_SUP3",
|
|
||||||
"label": "³",
|
|
||||||
}
|
|
||||||
"ALGR(BR_4)": {
|
|
||||||
"key": "BR_PND",
|
|
||||||
"label": "£",
|
|
||||||
}
|
|
||||||
"ALGR(BR_5)": {
|
|
||||||
"key": "BR_CENT",
|
|
||||||
"label": "¢",
|
|
||||||
}
|
|
||||||
"ALGR(BR_6)": {
|
|
||||||
"key": "BR_NOT",
|
|
||||||
"label": "¬",
|
|
||||||
}
|
|
||||||
"ALGR(BR_EQL)": {
|
|
||||||
"key": "BR_SECT",
|
|
||||||
"label": "§",
|
|
||||||
}
|
|
||||||
"ALGR(BR_E)": {
|
|
||||||
"key": "BR_DEG",
|
|
||||||
"label": "°",
|
|
||||||
}
|
|
||||||
"ALGR(BR_LBRC)": {
|
|
||||||
"key": "BR_FORD",
|
|
||||||
"label": "ª",
|
|
||||||
}
|
|
||||||
"ALGR(BR_RBRC)": {
|
|
||||||
"key": "BR_MORD",
|
|
||||||
"label": "º",
|
|
||||||
}
|
|
||||||
"ALGR(BR_C)": {
|
|
||||||
"key": "BR_CRUZ",
|
|
||||||
"label": "₢",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,407 +0,0 @@
|
||||||
{
|
|
||||||
"aliases": {
|
|
||||||
/*
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ # │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ ^ │ ¸ │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ` │ < │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
|
|
||||||
* │ │ « │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ É │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"KC_GRV": {
|
|
||||||
"key": "FR_HASH",
|
|
||||||
"label": "#",
|
|
||||||
}
|
|
||||||
"KC_1": {
|
|
||||||
"key": "FR_1",
|
|
||||||
"label": "1",
|
|
||||||
}
|
|
||||||
"KC_2": {
|
|
||||||
"key": "FR_2",
|
|
||||||
"label": "2",
|
|
||||||
}
|
|
||||||
"KC_3": {
|
|
||||||
"key": "FR_3",
|
|
||||||
"label": "3",
|
|
||||||
}
|
|
||||||
"KC_4": {
|
|
||||||
"key": "FR_4",
|
|
||||||
"label": "4",
|
|
||||||
}
|
|
||||||
"KC_5": {
|
|
||||||
"key": "FR_5",
|
|
||||||
"label": "5",
|
|
||||||
}
|
|
||||||
"KC_6": {
|
|
||||||
"key": "FR_6",
|
|
||||||
"label": "6",
|
|
||||||
}
|
|
||||||
"KC_7": {
|
|
||||||
"key": "FR_7",
|
|
||||||
"label": "7",
|
|
||||||
}
|
|
||||||
"KC_8": {
|
|
||||||
"key": "FR_8",
|
|
||||||
"label": "8",
|
|
||||||
}
|
|
||||||
"KC_9": {
|
|
||||||
"key": "FR_9",
|
|
||||||
"label": "9",
|
|
||||||
}
|
|
||||||
"KC_0": {
|
|
||||||
"key": "FR_0",
|
|
||||||
"label": "0",
|
|
||||||
}
|
|
||||||
"KC_MINS": {
|
|
||||||
"key": "FR_MINS",
|
|
||||||
"label": "-",
|
|
||||||
}
|
|
||||||
"KC_EQL": {
|
|
||||||
"key": "FR_EQL",
|
|
||||||
"label": "=",
|
|
||||||
}
|
|
||||||
"KC_Q": {
|
|
||||||
"key": "FR_Q",
|
|
||||||
"label": "Q",
|
|
||||||
}
|
|
||||||
"KC_W": {
|
|
||||||
"key": "FR_W",
|
|
||||||
"label": "W",
|
|
||||||
}
|
|
||||||
"KC_E": {
|
|
||||||
"key": "FR_E",
|
|
||||||
"label": "E",
|
|
||||||
}
|
|
||||||
"KC_R": {
|
|
||||||
"key": "FR_R",
|
|
||||||
"label": "R",
|
|
||||||
}
|
|
||||||
"KC_T": {
|
|
||||||
"key": "FR_T",
|
|
||||||
"label": "T",
|
|
||||||
}
|
|
||||||
"KC_Y": {
|
|
||||||
"key": "FR_Y",
|
|
||||||
"label": "Y",
|
|
||||||
}
|
|
||||||
"KC_U": {
|
|
||||||
"key": "FR_U",
|
|
||||||
"label": "U",
|
|
||||||
}
|
|
||||||
"KC_I": {
|
|
||||||
"key": "FR_I",
|
|
||||||
"label": "I",
|
|
||||||
}
|
|
||||||
"KC_O": {
|
|
||||||
"key": "FR_O",
|
|
||||||
"label": "O",
|
|
||||||
}
|
|
||||||
"KC_P": {
|
|
||||||
"key": "FR_P",
|
|
||||||
"label": "P",
|
|
||||||
}
|
|
||||||
"KC_LBRC": {
|
|
||||||
"key": "FR_DCIR",
|
|
||||||
"label": "^ (dead)",
|
|
||||||
}
|
|
||||||
"KC_RBRC": {
|
|
||||||
"key": "FR_CEDL",
|
|
||||||
"label": "¸ (dead)",
|
|
||||||
}
|
|
||||||
"KC_A": {
|
|
||||||
"key": "FR_A",
|
|
||||||
"label": "A",
|
|
||||||
}
|
|
||||||
"KC_S": {
|
|
||||||
"key": "FR_S",
|
|
||||||
"label": "S",
|
|
||||||
}
|
|
||||||
"KC_D": {
|
|
||||||
"key": "FR_D",
|
|
||||||
"label": "D",
|
|
||||||
}
|
|
||||||
"KC_F": {
|
|
||||||
"key": "FR_F",
|
|
||||||
"label": "F",
|
|
||||||
}
|
|
||||||
"KC_G": {
|
|
||||||
"key": "FR_G",
|
|
||||||
"label": "G",
|
|
||||||
}
|
|
||||||
"KC_H": {
|
|
||||||
"key": "FR_H",
|
|
||||||
"label": "H",
|
|
||||||
}
|
|
||||||
"KC_J": {
|
|
||||||
"key": "FR_J",
|
|
||||||
"label": "J",
|
|
||||||
}
|
|
||||||
"KC_K": {
|
|
||||||
"key": "FR_K",
|
|
||||||
"label": "K",
|
|
||||||
}
|
|
||||||
"KC_L": {
|
|
||||||
"key": "FR_L",
|
|
||||||
"label": "L",
|
|
||||||
}
|
|
||||||
"KC_SCLN": {
|
|
||||||
"key": "FR_SCLN",
|
|
||||||
"label": ";",
|
|
||||||
}
|
|
||||||
"KC_QUOT": {
|
|
||||||
"key": "FR_DGRV",
|
|
||||||
"label": "` (dead)",
|
|
||||||
}
|
|
||||||
"KC_NUHS": {
|
|
||||||
"key": "FR_LABK",
|
|
||||||
"label": "<",
|
|
||||||
}
|
|
||||||
"KC_NUBS": {
|
|
||||||
"key": "FR_LDAQ",
|
|
||||||
"label": "«",
|
|
||||||
}
|
|
||||||
"KC_Z": {
|
|
||||||
"key": "FR_Z",
|
|
||||||
"label": "Z",
|
|
||||||
}
|
|
||||||
"KC_X": {
|
|
||||||
"key": "FR_X",
|
|
||||||
"label": "X",
|
|
||||||
}
|
|
||||||
"KC_C": {
|
|
||||||
"key": "FR_C",
|
|
||||||
"label": "C",
|
|
||||||
}
|
|
||||||
"KC_V": {
|
|
||||||
"key": "FR_V",
|
|
||||||
"label": "V",
|
|
||||||
}
|
|
||||||
"KC_B": {
|
|
||||||
"key": "FR_B",
|
|
||||||
"label": "B",
|
|
||||||
}
|
|
||||||
"KC_N": {
|
|
||||||
"key": "FR_N",
|
|
||||||
"label": "N",
|
|
||||||
}
|
|
||||||
"KC_M": {
|
|
||||||
"key": "FR_M",
|
|
||||||
"label": "M",
|
|
||||||
}
|
|
||||||
"KC_COMM": {
|
|
||||||
"key": "FR_COMM",
|
|
||||||
"label": ",",
|
|
||||||
}
|
|
||||||
"KC_DOT": {
|
|
||||||
"key": "FR_DOT",
|
|
||||||
"label": ".",
|
|
||||||
}
|
|
||||||
"KC_SLSH": {
|
|
||||||
"key": "FR_EACU",
|
|
||||||
"label": "É",
|
|
||||||
}
|
|
||||||
/* Shifted symbols
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ | │ ! │ " │ / │ $ │ % │ ? │ & │ * │ ( │ ) │ _ │ + │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ │ │ │ ¨ │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ │ : │ │ > │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
|
|
||||||
* │ │ » │ │ │ │ │ │ │ │ ' │ │ │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"S(FR_HASH)": {
|
|
||||||
"key": "FR_PIPE",
|
|
||||||
"label": "|",
|
|
||||||
}
|
|
||||||
"S(FR_1)": {
|
|
||||||
"key": "FR_EXLM",
|
|
||||||
"label": "!",
|
|
||||||
}
|
|
||||||
"S(FR_2)": {
|
|
||||||
"key": "FR_DQUO",
|
|
||||||
"label": "\"",
|
|
||||||
}
|
|
||||||
"S(FR_3)": {
|
|
||||||
"key": "FR_SLSH",
|
|
||||||
"label": "/",
|
|
||||||
}
|
|
||||||
"S(FR_4)": {
|
|
||||||
"key": "FR_DLR",
|
|
||||||
"label": "$",
|
|
||||||
}
|
|
||||||
"S(FR_5)": {
|
|
||||||
"key": "FR_PERC",
|
|
||||||
"label": "%",
|
|
||||||
}
|
|
||||||
"S(FR_6)": {
|
|
||||||
"key": "FR_QUES",
|
|
||||||
"label": "?",
|
|
||||||
}
|
|
||||||
"S(FR_7)": {
|
|
||||||
"key": "FR_AMPR",
|
|
||||||
"label": "&",
|
|
||||||
}
|
|
||||||
"S(FR_8)": {
|
|
||||||
"key": "FR_ASTR",
|
|
||||||
"label": "*",
|
|
||||||
}
|
|
||||||
"S(FR_9)": {
|
|
||||||
"key": "FR_LPRN",
|
|
||||||
"label": "(",
|
|
||||||
}
|
|
||||||
"S(FR_0)": {
|
|
||||||
"key": "FR_RPRN",
|
|
||||||
"label": ")",
|
|
||||||
}
|
|
||||||
"S(FR_MINS)": {
|
|
||||||
"key": "FR_UNDS",
|
|
||||||
"label": "_",
|
|
||||||
}
|
|
||||||
"S(FR_EQL)": {
|
|
||||||
"key": "FR_PLUS",
|
|
||||||
"label": "+",
|
|
||||||
}
|
|
||||||
"S(FR_CEDL)": {
|
|
||||||
"key": "FR_DIAE",
|
|
||||||
"label": "¨ (dead)",
|
|
||||||
}
|
|
||||||
"S(FR_SCLN)": {
|
|
||||||
"key": "FR_COLN",
|
|
||||||
"label": ":",
|
|
||||||
}
|
|
||||||
"S(FR_LABK)": {
|
|
||||||
"key": "FR_RABK",
|
|
||||||
"label": ">",
|
|
||||||
}
|
|
||||||
"S(FR_LDAQ)": {
|
|
||||||
"key": "FR_RDAQ",
|
|
||||||
"label": "»",
|
|
||||||
}
|
|
||||||
"S(FR_COMM)": {
|
|
||||||
"key": "FR_QUOT",
|
|
||||||
"label": "'",
|
|
||||||
}
|
|
||||||
/* AltGr symbols
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ \ │ ± │ @ │ £ │ ¢ │ ¤ │ ¬ │ ¦ │ ² │ ³ │ ¼ │ ½ │ ¾ │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ § │ ¶ │ [ │ ] │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ │ ~ │ { │ } │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
|
|
||||||
* │ │ ° │ │ │ │ │ │ │ µ │ ¯ │ - │ ´ │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"ALGR(FR_HASH)": {
|
|
||||||
"key": "FR_BSLS",
|
|
||||||
"label": "\\",
|
|
||||||
}
|
|
||||||
"ALGR(FR_1)": {
|
|
||||||
"key": "FR_PLMN",
|
|
||||||
"label": "±",
|
|
||||||
}
|
|
||||||
"ALGR(FR_2)": {
|
|
||||||
"key": "FR_AT",
|
|
||||||
"label": "@",
|
|
||||||
}
|
|
||||||
"ALGR(FR_3)": {
|
|
||||||
"key": "FR_PND",
|
|
||||||
"label": "£",
|
|
||||||
}
|
|
||||||
"ALGR(FR_4)": {
|
|
||||||
"key": "FR_CENT",
|
|
||||||
"label": "¢",
|
|
||||||
}
|
|
||||||
"ALGR(FR_5)": {
|
|
||||||
"key": "FR_CURR",
|
|
||||||
"label": "¤",
|
|
||||||
}
|
|
||||||
"ALGR(FR_6)": {
|
|
||||||
"key": "FR_NOT",
|
|
||||||
"label": "¬",
|
|
||||||
}
|
|
||||||
"ALGR(FR_7)": {
|
|
||||||
"key": "FR_BRKP",
|
|
||||||
"label": "¦",
|
|
||||||
}
|
|
||||||
"ALGR(FR_8)": {
|
|
||||||
"key": "FR_SUP2",
|
|
||||||
"label": "²",
|
|
||||||
}
|
|
||||||
"ALGR(FR_9)": {
|
|
||||||
"key": "FR_SUP3",
|
|
||||||
"label": "³",
|
|
||||||
}
|
|
||||||
"ALGR(FR_0)": {
|
|
||||||
"key": "FR_QRTR",
|
|
||||||
"label": "¼",
|
|
||||||
}
|
|
||||||
"ALGR(FR_MINS)": {
|
|
||||||
"key": "FR_HALF",
|
|
||||||
"label": "½",
|
|
||||||
}
|
|
||||||
"ALGR(FR_EQL)": {
|
|
||||||
"key": "FR_TQTR",
|
|
||||||
"label": "¾",
|
|
||||||
}
|
|
||||||
"ALGR(FR_O)": {
|
|
||||||
"key": "FR_SECT",
|
|
||||||
"label": "§",
|
|
||||||
}
|
|
||||||
"ALGR(FR_P)": {
|
|
||||||
"key": "FR_PARA",
|
|
||||||
"label": "¶",
|
|
||||||
}
|
|
||||||
"ALGR(FR_DCIR)": {
|
|
||||||
"key": "FR_LBRC",
|
|
||||||
"label": "[",
|
|
||||||
}
|
|
||||||
"ALGR(FR_CEDL)": {
|
|
||||||
"key": "FR_RBRC",
|
|
||||||
"label": "]",
|
|
||||||
}
|
|
||||||
"ALGR(FR_SCLN)": {
|
|
||||||
"key": "FR_TILD",
|
|
||||||
"label": "~",
|
|
||||||
}
|
|
||||||
"ALGR(FR_DGRV)": {
|
|
||||||
"key": "FR_LCBR",
|
|
||||||
"label": "{",
|
|
||||||
}
|
|
||||||
"ALGR(FR_LABK)": {
|
|
||||||
"key": "FR_RCBR",
|
|
||||||
"label": "}",
|
|
||||||
}
|
|
||||||
"ALGR(FR_LDAQ)": {
|
|
||||||
"key": "FR_DEG",
|
|
||||||
"label": "°",
|
|
||||||
}
|
|
||||||
"ALGR(FR_M)": {
|
|
||||||
"key": "FR_MICR",
|
|
||||||
"label": "µ",
|
|
||||||
}
|
|
||||||
"ALGR(FR_COMM)": {
|
|
||||||
"key": "FR_MACR",
|
|
||||||
"label": "¯",
|
|
||||||
}
|
|
||||||
"ALGR(FR_DOT)": {
|
|
||||||
"key": "FR_SHYP",
|
|
||||||
"label": " (soft hyphen)",
|
|
||||||
}
|
|
||||||
"ALGR(FR_EACU)": {
|
|
||||||
"key": "FR_ACUT",
|
|
||||||
"label": "´ (dead)",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,641 +0,0 @@
|
||||||
{
|
|
||||||
"aliases": {
|
|
||||||
/*
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ / │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ ^ │ Ç │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ È │ À │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
|
|
||||||
* │ │ Ù │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ É │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"KC_GRV": {
|
|
||||||
"key": "CA_SLSH",
|
|
||||||
"label": "/",
|
|
||||||
}
|
|
||||||
"KC_1": {
|
|
||||||
"key": "CA_1",
|
|
||||||
"label": "1",
|
|
||||||
}
|
|
||||||
"KC_2": {
|
|
||||||
"key": "CA_2",
|
|
||||||
"label": "2",
|
|
||||||
}
|
|
||||||
"KC_3": {
|
|
||||||
"key": "CA_3",
|
|
||||||
"label": "3",
|
|
||||||
}
|
|
||||||
"KC_4": {
|
|
||||||
"key": "CA_4",
|
|
||||||
"label": "4",
|
|
||||||
}
|
|
||||||
"KC_5": {
|
|
||||||
"key": "CA_5",
|
|
||||||
"label": "5",
|
|
||||||
}
|
|
||||||
"KC_6": {
|
|
||||||
"key": "CA_6",
|
|
||||||
"label": "6",
|
|
||||||
}
|
|
||||||
"KC_7": {
|
|
||||||
"key": "CA_7",
|
|
||||||
"label": "7",
|
|
||||||
}
|
|
||||||
"KC_8": {
|
|
||||||
"key": "CA_8",
|
|
||||||
"label": "8",
|
|
||||||
}
|
|
||||||
"KC_9": {
|
|
||||||
"key": "CA_9",
|
|
||||||
"label": "9",
|
|
||||||
}
|
|
||||||
"KC_0": {
|
|
||||||
"key": "CA_0",
|
|
||||||
"label": "0",
|
|
||||||
}
|
|
||||||
"KC_MINS": {
|
|
||||||
"key": "CA_MINS",
|
|
||||||
"label": "-",
|
|
||||||
}
|
|
||||||
"KC_EQL": {
|
|
||||||
"key": "CA_EQL",
|
|
||||||
"label": "=",
|
|
||||||
}
|
|
||||||
"KC_Q": {
|
|
||||||
"key": "CA_Q",
|
|
||||||
"label": "Q",
|
|
||||||
}
|
|
||||||
"KC_W": {
|
|
||||||
"key": "CA_W",
|
|
||||||
"label": "W",
|
|
||||||
}
|
|
||||||
"KC_E": {
|
|
||||||
"key": "CA_E",
|
|
||||||
"label": "E",
|
|
||||||
}
|
|
||||||
"KC_R": {
|
|
||||||
"key": "CA_R",
|
|
||||||
"label": "R",
|
|
||||||
}
|
|
||||||
"KC_T": {
|
|
||||||
"key": "CA_T",
|
|
||||||
"label": "T",
|
|
||||||
}
|
|
||||||
"KC_Y": {
|
|
||||||
"key": "CA_Y",
|
|
||||||
"label": "Y",
|
|
||||||
}
|
|
||||||
"KC_U": {
|
|
||||||
"key": "CA_U",
|
|
||||||
"label": "U",
|
|
||||||
}
|
|
||||||
"KC_I": {
|
|
||||||
"key": "CA_I",
|
|
||||||
"label": "I",
|
|
||||||
}
|
|
||||||
"KC_O": {
|
|
||||||
"key": "CA_O",
|
|
||||||
"label": "O",
|
|
||||||
}
|
|
||||||
"KC_P": {
|
|
||||||
"key": "CA_P",
|
|
||||||
"label": "P",
|
|
||||||
}
|
|
||||||
"KC_LBRC": {
|
|
||||||
"key": "CA_CIRC",
|
|
||||||
"label": "^ (dead)",
|
|
||||||
}
|
|
||||||
"KC_RBRC": {
|
|
||||||
"key": "CA_CCED",
|
|
||||||
"label": "Ç",
|
|
||||||
}
|
|
||||||
"KC_A": {
|
|
||||||
"key": "CA_A",
|
|
||||||
"label": "A",
|
|
||||||
}
|
|
||||||
"KC_S": {
|
|
||||||
"key": "CA_S",
|
|
||||||
"label": "S",
|
|
||||||
}
|
|
||||||
"KC_D": {
|
|
||||||
"key": "CA_D",
|
|
||||||
"label": "D",
|
|
||||||
}
|
|
||||||
"KC_F": {
|
|
||||||
"key": "CA_F",
|
|
||||||
"label": "F",
|
|
||||||
}
|
|
||||||
"KC_G": {
|
|
||||||
"key": "CA_G",
|
|
||||||
"label": "G",
|
|
||||||
}
|
|
||||||
"KC_H": {
|
|
||||||
"key": "CA_H",
|
|
||||||
"label": "H",
|
|
||||||
}
|
|
||||||
"KC_J": {
|
|
||||||
"key": "CA_J",
|
|
||||||
"label": "J",
|
|
||||||
}
|
|
||||||
"KC_K": {
|
|
||||||
"key": "CA_K",
|
|
||||||
"label": "K",
|
|
||||||
}
|
|
||||||
"KC_L": {
|
|
||||||
"key": "CA_L",
|
|
||||||
"label": "L",
|
|
||||||
}
|
|
||||||
"KC_SCLN": {
|
|
||||||
"key": "CA_SCLN",
|
|
||||||
"label": ";",
|
|
||||||
}
|
|
||||||
"KC_QUOT": {
|
|
||||||
"key": "CA_EGRV",
|
|
||||||
"label": "É",
|
|
||||||
}
|
|
||||||
"KC_NUHS": {
|
|
||||||
"key": "CA_AGRV",
|
|
||||||
"label": "À",
|
|
||||||
}
|
|
||||||
"KC_NUBS": {
|
|
||||||
"key": "CA_UGRV",
|
|
||||||
"label": "Ù",
|
|
||||||
}
|
|
||||||
"KC_Z": {
|
|
||||||
"key": "CA_Z",
|
|
||||||
"label": "Z",
|
|
||||||
}
|
|
||||||
"KC_X": {
|
|
||||||
"key": "CA_X",
|
|
||||||
"label": "X",
|
|
||||||
}
|
|
||||||
"KC_C": {
|
|
||||||
"key": "CA_C",
|
|
||||||
"label": "C",
|
|
||||||
}
|
|
||||||
"KC_V": {
|
|
||||||
"key": "CA_V",
|
|
||||||
"label": "V",
|
|
||||||
}
|
|
||||||
"KC_B": {
|
|
||||||
"key": "CA_B",
|
|
||||||
"label": "B",
|
|
||||||
}
|
|
||||||
"KC_N": {
|
|
||||||
"key": "CA_N",
|
|
||||||
"label": "N",
|
|
||||||
}
|
|
||||||
"KC_M": {
|
|
||||||
"key": "CA_M",
|
|
||||||
"label": "M",
|
|
||||||
}
|
|
||||||
"KC_COMM": {
|
|
||||||
"key": "CA_COMM",
|
|
||||||
"label": ",",
|
|
||||||
}
|
|
||||||
"KC_DOT": {
|
|
||||||
"key": "CA_DOT",
|
|
||||||
"label": ".",
|
|
||||||
}
|
|
||||||
"KC_SLSH": {
|
|
||||||
"key": "CA_EACU",
|
|
||||||
"label": "É",
|
|
||||||
}
|
|
||||||
/* Shifted symbols
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ \ │ ! │ @ │ # │ $ │ % │ ? │ & │ * │ ( │ ) │ _ │ + │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ │ │ ¨ │ │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ │ : │ │ │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ ' │ " │ │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"S(CA_SLSH)": {
|
|
||||||
"key": "CA_BSLS",
|
|
||||||
"label": "\\",
|
|
||||||
}
|
|
||||||
"S(CA_1)": {
|
|
||||||
"key": "CA_EXLM",
|
|
||||||
"label": "!",
|
|
||||||
}
|
|
||||||
"S(CA_2)": {
|
|
||||||
"key": "CA_AT",
|
|
||||||
"label": "@",
|
|
||||||
}
|
|
||||||
"S(CA_3)": {
|
|
||||||
"key": "CA_HASH",
|
|
||||||
"label": "#",
|
|
||||||
}
|
|
||||||
"S(CA_4)": {
|
|
||||||
"key": "CA_DLR",
|
|
||||||
"label": "$",
|
|
||||||
}
|
|
||||||
"S(CA_5)": {
|
|
||||||
"key": "CA_PERC",
|
|
||||||
"label": "%",
|
|
||||||
}
|
|
||||||
"S(CA_6)": {
|
|
||||||
"key": "CA_QUES",
|
|
||||||
"label": "?",
|
|
||||||
}
|
|
||||||
"S(CA_7)": {
|
|
||||||
"key": "CA_AMPR",
|
|
||||||
"label": "&",
|
|
||||||
}
|
|
||||||
"S(CA_8)": {
|
|
||||||
"key": "CA_ASTR",
|
|
||||||
"label": "*",
|
|
||||||
}
|
|
||||||
"S(CA_9)": {
|
|
||||||
"key": "CA_LPRN",
|
|
||||||
"label": "(",
|
|
||||||
}
|
|
||||||
"S(CA_0)": {
|
|
||||||
"key": "CA_RPRN",
|
|
||||||
"label": ")",
|
|
||||||
}
|
|
||||||
"S(CA_MINS)": {
|
|
||||||
"key": "CA_UNDS",
|
|
||||||
"label": "_",
|
|
||||||
}
|
|
||||||
"S(CA_EQL)": {
|
|
||||||
"key": "CA_PLUS",
|
|
||||||
"label": "+",
|
|
||||||
}
|
|
||||||
"S(CA_CIRC)": {
|
|
||||||
"key": "CA_DIAE",
|
|
||||||
"label": "¨ (dead)",
|
|
||||||
}
|
|
||||||
"S(CA_SCLN)": {
|
|
||||||
"key": "CA_COLN",
|
|
||||||
"label": ":",
|
|
||||||
}
|
|
||||||
"S(CA_COMM)": {
|
|
||||||
"key": "CA_QUOT",
|
|
||||||
"label": "'",
|
|
||||||
}
|
|
||||||
"S(CA_DOT)": {
|
|
||||||
"key": "CA_DQUO",
|
|
||||||
"label": "\"",
|
|
||||||
}
|
|
||||||
/* AltGr symbols
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ | │ │ │ │ ¤ │ │ │ { │ } │ [ │ ] │ │ ¬ │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ │ │ € │ │ │ │ │ │ │ │ ` │ ~ │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ │ ° │ │ │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
|
|
||||||
* │ │ │ « │ » │ │ │ │ │ │ < │ > │ │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"ALGR(CA_SLSH)": {
|
|
||||||
"key": "CA_PIPE",
|
|
||||||
"label": "|",
|
|
||||||
}
|
|
||||||
"ALGR(CA_4)": {
|
|
||||||
"key": "CA_CURR",
|
|
||||||
"label": "¤",
|
|
||||||
}
|
|
||||||
"ALGR(CA_7)": {
|
|
||||||
"key": "CA_LCBR",
|
|
||||||
"label": "{",
|
|
||||||
}
|
|
||||||
"ALGR(CA_8)": {
|
|
||||||
"key": "CA_RCBR",
|
|
||||||
"label": "}",
|
|
||||||
}
|
|
||||||
"ALGR(CA_9)": {
|
|
||||||
"key": "CA_LBRC",
|
|
||||||
"label": "[",
|
|
||||||
}
|
|
||||||
"ALGR(CA_0)": {
|
|
||||||
"key": "CA_RBRC",
|
|
||||||
"label": "]",
|
|
||||||
}
|
|
||||||
"ALGR(CA_EQL)": {
|
|
||||||
"key": "CA_NOT",
|
|
||||||
"label": "¬",
|
|
||||||
}
|
|
||||||
"ALGR(CA_E)": {
|
|
||||||
"key": "CA_EURO",
|
|
||||||
"label": "€",
|
|
||||||
}
|
|
||||||
"ALGR(CA_CIRC)": {
|
|
||||||
"key": "CA_GRV",
|
|
||||||
"label": "` (dead)",
|
|
||||||
}
|
|
||||||
"ALGR(CA_CCED)": {
|
|
||||||
"key": "CA_DTIL",
|
|
||||||
"label": "~ (dead)",
|
|
||||||
}
|
|
||||||
"ALGR(CA_SCLN)": {
|
|
||||||
"key": "CA_DEG",
|
|
||||||
"label": "°",
|
|
||||||
}
|
|
||||||
"ALGR(CA_Z)": {
|
|
||||||
"key": "CA_LDAQ",
|
|
||||||
"label": "«",
|
|
||||||
}
|
|
||||||
"ALGR(CA_X)": {
|
|
||||||
"key": "CA_RDAQ",
|
|
||||||
"label": "»",
|
|
||||||
}
|
|
||||||
"ALGR(CA_COMM)": {
|
|
||||||
"key": "CA_LABK",
|
|
||||||
"label": "<",
|
|
||||||
}
|
|
||||||
"ALGR(CA_DOT)": {
|
|
||||||
"key": "CA_RABK",
|
|
||||||
"label": ">",
|
|
||||||
}
|
|
||||||
/* Right Ctrl symbols
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ │ ¹ │ ² │ ³ │ ¼ │ ½ │ ¾ │ │ │ │ │ │ ¸ │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ Ω │ Ł │ Œ │ ¶ │ Ŧ │ ← │ ↓ │ → │ Ø │ Þ │ │ ~ │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ Æ │ ß │ Ð │ │ Ŋ │ Ħ │ IJ │ ĸ │ Ŀ │ ´ │ │ │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
|
|
||||||
* │ │ │ │ │ ¢ │ “ │ ” │ ʼn │ μ │ ― │ ˙ │ │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"RCTL(CA_1)": {
|
|
||||||
"key": "CA_SUP1",
|
|
||||||
"label": "¹",
|
|
||||||
}
|
|
||||||
"RCTL(CA_2)": {
|
|
||||||
"key": "CA_SUP2",
|
|
||||||
"label": "²",
|
|
||||||
}
|
|
||||||
"RCTL(CA_3)": {
|
|
||||||
"key": "CA_SUP3",
|
|
||||||
"label": "³",
|
|
||||||
}
|
|
||||||
"RCTL(CA_4)": {
|
|
||||||
"key": "CA_QRTR",
|
|
||||||
"label": "¼",
|
|
||||||
}
|
|
||||||
"RCTL(CA_5)": {
|
|
||||||
"key": "CA_HALF",
|
|
||||||
"label": "½",
|
|
||||||
}
|
|
||||||
"RCTL(CA_6)": {
|
|
||||||
"key": "CA_TQTR",
|
|
||||||
"label": "¾",
|
|
||||||
}
|
|
||||||
"RCTL(CA_EQL)": {
|
|
||||||
"key": "CA_CEDL",
|
|
||||||
"label": "¸ (dead)",
|
|
||||||
}
|
|
||||||
"RCTL(CA_Q)": {
|
|
||||||
"key": "CA_OMEG",
|
|
||||||
"label": "Ω",
|
|
||||||
}
|
|
||||||
"RCTL(CA_W)": {
|
|
||||||
"key": "CA_LSTR",
|
|
||||||
"label": "Ł",
|
|
||||||
}
|
|
||||||
"RCTL(CA_E)": {
|
|
||||||
"key": "CA_OE",
|
|
||||||
"label": "Œ",
|
|
||||||
}
|
|
||||||
"RCTL(CA_R)": {
|
|
||||||
"key": "CA_PARA",
|
|
||||||
"label": "¶",
|
|
||||||
}
|
|
||||||
"RCTL(CA_T)": {
|
|
||||||
"key": "CA_TSTR",
|
|
||||||
"label": "Ŧ",
|
|
||||||
}
|
|
||||||
"RCTL(CA_Y)": {
|
|
||||||
"key": "CA_LARR",
|
|
||||||
"label": "←",
|
|
||||||
}
|
|
||||||
"RCTL(CA_U)": {
|
|
||||||
"key": "CA_DARR",
|
|
||||||
"label": "↓",
|
|
||||||
}
|
|
||||||
"RCTL(CA_I)": {
|
|
||||||
"key": "CA_RARR",
|
|
||||||
"label": "→",
|
|
||||||
}
|
|
||||||
"RCTL(CA_O)": {
|
|
||||||
"key": "CA_OSTR",
|
|
||||||
"label": "Ø",
|
|
||||||
}
|
|
||||||
"RCTL(CA_P)": {
|
|
||||||
"key": "CA_THRN",
|
|
||||||
"label": "Þ",
|
|
||||||
}
|
|
||||||
"RCTL(CA_CCED)": {
|
|
||||||
"key": "CA_TILD",
|
|
||||||
"label": "~",
|
|
||||||
}
|
|
||||||
"RCTL(CA_A)": {
|
|
||||||
"key": "CA_AE",
|
|
||||||
"label": "Æ",
|
|
||||||
}
|
|
||||||
"RCTL(CA_S)": {
|
|
||||||
"key": "CA_SS",
|
|
||||||
"label": "ß",
|
|
||||||
}
|
|
||||||
"RCTL(CA_D)": {
|
|
||||||
"key": "CA_ETH",
|
|
||||||
"label": "Ð",
|
|
||||||
}
|
|
||||||
"RCTL(CA_G)": {
|
|
||||||
"key": "CA_ENG",
|
|
||||||
"label": "Ŋ",
|
|
||||||
}
|
|
||||||
"RCTL(CA_H)": {
|
|
||||||
"key": "CA_HSTR",
|
|
||||||
"label": "Ħ",
|
|
||||||
}
|
|
||||||
"RCTL(CA_J)": {
|
|
||||||
"key": "CA_IJ",
|
|
||||||
"label": "IJ",
|
|
||||||
}
|
|
||||||
"RCTL(CA_K)": {
|
|
||||||
"key": "CA_KRA",
|
|
||||||
"label": "ĸ",
|
|
||||||
}
|
|
||||||
"RCTL(CA_L)": {
|
|
||||||
"key": "CA_LMDT",
|
|
||||||
"label": "Ŀ",
|
|
||||||
}
|
|
||||||
"RCTL(CA_SCLN)": {
|
|
||||||
"key": "CA_ACUT",
|
|
||||||
"label": "´ (dead)",
|
|
||||||
}
|
|
||||||
"RCTL(CA_C)": {
|
|
||||||
"key": "CA_CENT",
|
|
||||||
"label": "¢",
|
|
||||||
}
|
|
||||||
"RCTL(CA_V)": {
|
|
||||||
"key": "CA_LDQU",
|
|
||||||
"label": "“",
|
|
||||||
}
|
|
||||||
"RCTL(CA_B)": {
|
|
||||||
"key": "CA_RDQU",
|
|
||||||
"label": "”",
|
|
||||||
}
|
|
||||||
"RCTL(CA_N)": {
|
|
||||||
"key": "CA_APSN",
|
|
||||||
"label": "ʼn",
|
|
||||||
}
|
|
||||||
"RCTL(CA_M)": {
|
|
||||||
"key": "CA_MICR",
|
|
||||||
"label": "μ",
|
|
||||||
}
|
|
||||||
"RCTL(CA_COMM)": {
|
|
||||||
"key": "CA_HRZB",
|
|
||||||
"label": "―",
|
|
||||||
}
|
|
||||||
"RCTL(CA_DOT)": {
|
|
||||||
"key": "CA_DOTA",
|
|
||||||
"label": "˙ (dead)",
|
|
||||||
}
|
|
||||||
/* Shift+Right Ctrl symbols
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ - │ ¡ │ │ £ │ │ ⅜ │ ⅝ │ ⅞ │ ™ │ ± │ │ ¿ │ ˛ │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ │ │ │ ® │ │ ¥ │ ↑ │ ı │ │ │ ° │ ¯ │ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
|
|
||||||
* │ │ │ § │ │ ª │ │ │ │ │ │ ˝ │ ˇ │ ˘ │ │
|
|
||||||
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
|
|
||||||
* │ │ ¦ │ │ │ © │ ‘ │ ’ │ ♪ │ º │ × │ ÷ │ │ │
|
|
||||||
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"RCTL(S(CA_SLSH))": {
|
|
||||||
"key": "CA_SHYP",
|
|
||||||
"label": " (soft hyphen)",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_1))": {
|
|
||||||
"key": "CA_IEXL",
|
|
||||||
"label": "¡",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_3))": {
|
|
||||||
"key": "CA_PND",
|
|
||||||
"label": "£",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_5))": {
|
|
||||||
"key": "CA_TEIG",
|
|
||||||
"label": "⅜",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_6))": {
|
|
||||||
"key": "CA_FEIG",
|
|
||||||
"label": "⅝",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_7))": {
|
|
||||||
"key": "CA_SEIG",
|
|
||||||
"label": "⅞",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_8))": {
|
|
||||||
"key": "CA_TM",
|
|
||||||
"label": "™",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_9))": {
|
|
||||||
"key": "CA_PLMN",
|
|
||||||
"label": "±",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_MINS))": {
|
|
||||||
"key": "CA_IQUE",
|
|
||||||
"label": "¿",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_EQL))": {
|
|
||||||
"key": "CA_OGON",
|
|
||||||
"label": "˛ (dead)",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_R))": {
|
|
||||||
"key": "CA_REGD",
|
|
||||||
"label": "®",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_Y))": {
|
|
||||||
"key": "CA_YEN",
|
|
||||||
"label": "¥",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_U))": {
|
|
||||||
"key": "CA_UARR",
|
|
||||||
"label": "↑",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_I))": {
|
|
||||||
"key": "CA_DLSI",
|
|
||||||
"label": "ı",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_CIRC))": {
|
|
||||||
"key": "CA_RNGA",
|
|
||||||
"label": "° (dead)",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_CCED))": {
|
|
||||||
"key": "CA_MACR",
|
|
||||||
"label": "¯ (dead)",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_S))": {
|
|
||||||
"key": "CA_SECT",
|
|
||||||
"label": "§",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_F))": {
|
|
||||||
"key": "CA_FORD",
|
|
||||||
"label": "ª",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_SCLN))": {
|
|
||||||
"key": "CA_DACU",
|
|
||||||
"label": "˝ (dead)",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_EGRV))": {
|
|
||||||
"key": "CA_CARN",
|
|
||||||
"label": "ˇ (dead)",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_AGRV))": {
|
|
||||||
"key": "CA_BREV",
|
|
||||||
"label": "˘ (dead)",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_UGRV))": {
|
|
||||||
"key": "CA_BRKP",
|
|
||||||
"label": "¦",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_C))": {
|
|
||||||
"key": "CA_COPY",
|
|
||||||
"label": "©",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_V))": {
|
|
||||||
"key": "CA_LSQU",
|
|
||||||
"label": "‘",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_B))": {
|
|
||||||
"key": "CA_RSQU",
|
|
||||||
"label": "’",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_N))": {
|
|
||||||
"key": "CA_ENOT",
|
|
||||||
"label": "♪",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_M))": {
|
|
||||||
"key": "CA_MORD",
|
|
||||||
"label": "º",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_COMM))": {
|
|
||||||
"key": "CA_MUL",
|
|
||||||
"label": "×",
|
|
||||||
}
|
|
||||||
"RCTL(S(CA_DOT))": {
|
|
||||||
"key": "CA_DIV",
|
|
||||||
"label": "÷",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,302 +0,0 @@
|
||||||
{
|
|
||||||
"aliases": {
|
|
||||||
/*
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ Q │ W │ F │ P │ G │ J │ L │ U │ Y │ ; │ [ │ ] │ \ │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤
|
|
||||||
* │ │ A │ R │ S │ T │ D │ H │ N │ E │ I │ O │ ' │ │
|
|
||||||
* ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤
|
|
||||||
* │ │ Z │ X │ C │ V │ B │ K │ M │ , │ . │ / │ │
|
|
||||||
* ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"KC_GRV": {
|
|
||||||
"key": "CM_GRV",
|
|
||||||
"label": "`",
|
|
||||||
}
|
|
||||||
"KC_1": {
|
|
||||||
"key": "CM_1",
|
|
||||||
"label": "1",
|
|
||||||
}
|
|
||||||
"KC_2": {
|
|
||||||
"key": "CM_2",
|
|
||||||
"label": "2",
|
|
||||||
}
|
|
||||||
"KC_3": {
|
|
||||||
"key": "CM_3",
|
|
||||||
"label": "3",
|
|
||||||
}
|
|
||||||
"KC_4": {
|
|
||||||
"key": "CM_4",
|
|
||||||
"label": "4",
|
|
||||||
}
|
|
||||||
"KC_5": {
|
|
||||||
"key": "CM_5",
|
|
||||||
"label": "5",
|
|
||||||
}
|
|
||||||
"KC_6": {
|
|
||||||
"key": "CM_6",
|
|
||||||
"label": "6",
|
|
||||||
}
|
|
||||||
"KC_7": {
|
|
||||||
"key": "CM_7",
|
|
||||||
"label": "7",
|
|
||||||
}
|
|
||||||
"KC_8": {
|
|
||||||
"key": "CM_8",
|
|
||||||
"label": "8",
|
|
||||||
}
|
|
||||||
"KC_9": {
|
|
||||||
"key": "CM_9",
|
|
||||||
"label": "9",
|
|
||||||
}
|
|
||||||
"KC_0": {
|
|
||||||
"key": "CM_0",
|
|
||||||
"label": "0",
|
|
||||||
}
|
|
||||||
"KC_MINS": {
|
|
||||||
"key": "CM_MINS",
|
|
||||||
"label": "-",
|
|
||||||
}
|
|
||||||
"KC_EQL": {
|
|
||||||
"key": "CM_EQL",
|
|
||||||
"label": "=",
|
|
||||||
}
|
|
||||||
"KC_Q": {
|
|
||||||
"key": "CM_Q",
|
|
||||||
"label": "Q",
|
|
||||||
}
|
|
||||||
"KC_W": {
|
|
||||||
"key": "CM_W",
|
|
||||||
"label": "W",
|
|
||||||
}
|
|
||||||
"KC_E": {
|
|
||||||
"key": "CM_F",
|
|
||||||
"label": "F",
|
|
||||||
}
|
|
||||||
"KC_R": {
|
|
||||||
"key": "CM_P",
|
|
||||||
"label": "P",
|
|
||||||
}
|
|
||||||
"KC_T": {
|
|
||||||
"key": "CM_G",
|
|
||||||
"label": "G",
|
|
||||||
}
|
|
||||||
"KC_Y": {
|
|
||||||
"key": "CM_J",
|
|
||||||
"label": "J",
|
|
||||||
}
|
|
||||||
"KC_U": {
|
|
||||||
"key": "CM_L",
|
|
||||||
"label": "L",
|
|
||||||
}
|
|
||||||
"KC_I": {
|
|
||||||
"key": "CM_U",
|
|
||||||
"label": "U",
|
|
||||||
}
|
|
||||||
"KC_O": {
|
|
||||||
"key": "CM_Y",
|
|
||||||
"label": "Y",
|
|
||||||
}
|
|
||||||
"KC_P": {
|
|
||||||
"key": "CM_SCLN",
|
|
||||||
"label": ";",
|
|
||||||
}
|
|
||||||
"KC_LBRC": {
|
|
||||||
"key": "CM_LBRC",
|
|
||||||
"label": "[",
|
|
||||||
}
|
|
||||||
"KC_RBRC": {
|
|
||||||
"key": "CM_RBRC",
|
|
||||||
"label": "]",
|
|
||||||
}
|
|
||||||
"KC_BSLS": {
|
|
||||||
"key": "CM_BSLS",
|
|
||||||
"label": "\\",
|
|
||||||
}
|
|
||||||
"KC_A": {
|
|
||||||
"key": "CM_A",
|
|
||||||
"label": "A",
|
|
||||||
}
|
|
||||||
"KC_S": {
|
|
||||||
"key": "CM_R",
|
|
||||||
"label": "R",
|
|
||||||
}
|
|
||||||
"KC_D": {
|
|
||||||
"key": "CM_S",
|
|
||||||
"label": "S",
|
|
||||||
}
|
|
||||||
"KC_F": {
|
|
||||||
"key": "CM_T",
|
|
||||||
"label": "T",
|
|
||||||
}
|
|
||||||
"KC_G": {
|
|
||||||
"key": "CM_D",
|
|
||||||
"label": "D",
|
|
||||||
}
|
|
||||||
"KC_H": {
|
|
||||||
"key": "CM_H",
|
|
||||||
"label": "H",
|
|
||||||
}
|
|
||||||
"KC_J": {
|
|
||||||
"key": "CM_N",
|
|
||||||
"label": "N",
|
|
||||||
}
|
|
||||||
"KC_K": {
|
|
||||||
"key": "CM_E",
|
|
||||||
"label": "E",
|
|
||||||
}
|
|
||||||
"KC_L": {
|
|
||||||
"key": "CM_I",
|
|
||||||
"label": "I",
|
|
||||||
}
|
|
||||||
"KC_SCLN": {
|
|
||||||
"key": "CM_O",
|
|
||||||
"label": "O",
|
|
||||||
}
|
|
||||||
"KC_QUOT": {
|
|
||||||
"key": "CM_QUOT",
|
|
||||||
"label": "'",
|
|
||||||
}
|
|
||||||
"KC_Z": {
|
|
||||||
"key": "CM_Z",
|
|
||||||
"label": "Z",
|
|
||||||
}
|
|
||||||
"KC_X": {
|
|
||||||
"key": "CM_X",
|
|
||||||
"label": "X",
|
|
||||||
}
|
|
||||||
"KC_C": {
|
|
||||||
"key": "CM_C",
|
|
||||||
"label": "C",
|
|
||||||
}
|
|
||||||
"KC_V": {
|
|
||||||
"key": "CM_V",
|
|
||||||
"label": "V",
|
|
||||||
}
|
|
||||||
"KC_B": {
|
|
||||||
"key": "CM_B",
|
|
||||||
"label": "B",
|
|
||||||
}
|
|
||||||
"KC_N": {
|
|
||||||
"key": "CM_K",
|
|
||||||
"label": "K",
|
|
||||||
}
|
|
||||||
"KC_M": {
|
|
||||||
"key": "CM_M",
|
|
||||||
"label": "M",
|
|
||||||
}
|
|
||||||
"KC_COMM": {
|
|
||||||
"key": "CM_COMM",
|
|
||||||
"label": ",",
|
|
||||||
}
|
|
||||||
"KC_DOT": {
|
|
||||||
"key": "CM_DOT",
|
|
||||||
"label": ".",
|
|
||||||
}
|
|
||||||
"KC_SLSH": {
|
|
||||||
"key": "CM_SLSH",
|
|
||||||
"label": "/",
|
|
||||||
}
|
|
||||||
/* Shifted symbols
|
|
||||||
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
|
|
||||||
* │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ │
|
|
||||||
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ │ : │ { │ } │ | │
|
|
||||||
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │ │ │ │ " │ │
|
|
||||||
* ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │ < │ > │ ? │ │
|
|
||||||
* ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
|
|
||||||
* │ │ │ │ │ │ │ │ │
|
|
||||||
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
|
|
||||||
*/
|
|
||||||
"S(CM_GRV)": {
|
|
||||||
"key": "CM_TILD",
|
|
||||||
"label": "~",
|
|
||||||
}
|
|
||||||
"S(CM_1)": {
|
|
||||||
"key": "CM_EXLM",
|
|
||||||
"label": "!",
|
|
||||||
}
|
|
||||||
"S(CM_2)": {
|
|
||||||
"key": "CM_AT",
|
|
||||||
"label": "@",
|
|
||||||
}
|
|
||||||
"S(CM_3)": {
|
|
||||||
"key": "CM_HASH",
|
|
||||||
"label": "#",
|
|
||||||
}
|
|
||||||
"S(CM_4)": {
|
|
||||||
"key": "CM_DLR",
|
|
||||||
"label": "$",
|
|
||||||
}
|
|
||||||
"S(CM_5)": {
|
|
||||||
"key": "CM_PERC",
|
|
||||||
"label": "%",
|
|
||||||
}
|
|
||||||
"S(CM_6)": {
|
|
||||||
"key": "CM_CIRC",
|
|
||||||
"label": "^",
|
|
||||||
}
|
|
||||||
"S(CM_7)": {
|
|
||||||
"key": "CM_AMPR",
|
|
||||||
"label": "&",
|
|
||||||
}
|
|
||||||
"S(CM_8)": {
|
|
||||||
"key": "CM_ASTR",
|
|
||||||
"label": "*",
|
|
||||||
}
|
|
||||||
"S(CM_9)": {
|
|
||||||
"key": "CM_LPRN",
|
|
||||||
"label": "(",
|
|
||||||
}
|
|
||||||
"S(CM_0)": {
|
|
||||||
"key": "CM_RPRN",
|
|
||||||
"label": ")",
|
|
||||||
}
|
|
||||||
"S(CM_MINS)": {
|
|
||||||
"key": "CM_UNDS",
|
|
||||||
"label": "_",
|
|
||||||
}
|
|
||||||
"S(CM_EQL)": {
|
|
||||||
"key": "CM_PLUS",
|
|
||||||
"label": "+",
|
|
||||||
}
|
|
||||||
"S(CM_SCLN)": {
|
|
||||||
"key": "CM_COLN",
|
|
||||||
"label": ":",
|
|
||||||
}
|
|
||||||
"S(CM_LBRC)": {
|
|
||||||
"key": "CM_LCBR",
|
|
||||||
"label": "{",
|
|
||||||
}
|
|
||||||
"S(CM_RBRC)": {
|
|
||||||
"key": "CM_RCBR",
|
|
||||||
"label": "}",
|
|
||||||
}
|
|
||||||
"S(CM_BSLS)": {
|
|
||||||
"key": "CM_PIPE",
|
|
||||||
"label": "|",
|
|
||||||
}
|
|
||||||
"S(CM_QUOT)": {
|
|
||||||
"key": "CM_DQUO",
|
|
||||||
"label": "\"",
|
|
||||||
}
|
|
||||||
"S(CM_COMM)": {
|
|
||||||
"key": "CM_LABK",
|
|
||||||
"label": "<",
|
|
||||||
}
|
|
||||||
"S(CM_DOT)": {
|
|
||||||
"key": "CM_RABK",
|
|
||||||
"label": ">",
|
|
||||||
}
|
|
||||||
"S(CM_SLSH)": {
|
|
||||||
"key": "CM_QUES",
|
|
||||||
"label": "?",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue