commit
3996250d81
@ -0,0 +1,42 @@ |
||||
core: |
||||
- quantum/**/* |
||||
- tmk_core/**/* |
||||
- drivers/**/* |
||||
- tests/**/* |
||||
- util/**/* |
||||
- platforms/**/* |
||||
- Makefile |
||||
- '*.mk' |
||||
dependencies: |
||||
- any: |
||||
- 'lib/**/*' |
||||
- '!lib/python/**/*' |
||||
keyboard: |
||||
- any: |
||||
- 'keyboards/**/*' |
||||
- '!keyboards/**/keymaps/**/*' |
||||
keymap: |
||||
- users/**/* |
||||
- layouts/**/* |
||||
- keyboards/**/keymaps/**/* |
||||
via: |
||||
- keyboards/**/keymaps/via/* |
||||
cli: |
||||
- bin/qmk |
||||
- 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/**/* |
@ -0,0 +1,42 @@ |
||||
name: Update API Data |
||||
|
||||
on: |
||||
push: |
||||
branches: |
||||
- master |
||||
paths: |
||||
- 'keyboards/**' |
||||
- 'layouts/community/**' |
||||
|
||||
jobs: |
||||
api_data: |
||||
runs-on: ubuntu-latest |
||||
container: qmkfm/base_container |
||||
|
||||
# protect against those who develop with their fork on master |
||||
if: github.repository == 'qmk/qmk_firmware' |
||||
|
||||
steps: |
||||
- uses: actions/checkout@v2 |
||||
with: |
||||
fetch-depth: 1 |
||||
persist-credentials: false |
||||
|
||||
- name: Generate API Data |
||||
run: qmk generate-api |
||||
|
||||
- name: Install rsync |
||||
run: | |
||||
apt-get update && apt-get install -y rsync |
||||
|
||||
- name: Upload API Data |
||||
uses: JamesIves/github-pages-deploy-action@3.7.1 |
||||
with: |
||||
ACCESS_TOKEN: ${{ secrets.API_TOKEN_GITHUB }} |
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
||||
BRANCH: main |
||||
FOLDER: api_data/v1 |
||||
CLEAN: true |
||||
GIT_CONFIG_EMAIL: hello@qmk.fm |
||||
REPOSITORY_NAME: qmk/qmk_keyboards |
||||
TARGET_FOLDER: v1 |
@ -0,0 +1,33 @@ |
||||
name: Essential files modified |
||||
|
||||
on: |
||||
push: |
||||
branches: |
||||
- master |
||||
paths: |
||||
- quantum/**/* |
||||
- tmk_core/**/* |
||||
- drivers/**/* |
||||
- tests/**/* |
||||
- util/**/* |
||||
- platforms/**/* |
||||
- 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@v2 |
||||
with: |
||||
fetch-depth: 0 |
||||
|
||||
- name: Bump version and push tag |
||||
uses: anothrNick/github-tag-action@1.26.0 |
||||
env: |
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
||||
DEFAULT_BUMP: 'patch' |
@ -0,0 +1,42 @@ |
||||
name: Update Develop API Data |
||||
|
||||
on: |
||||
push: |
||||
branches: |
||||
- develop |
||||
paths: |
||||
- 'keyboards/**' |
||||
- 'layouts/community/**' |
||||
|
||||
jobs: |
||||
api_data: |
||||
runs-on: ubuntu-latest |
||||
container: qmkfm/base_container |
||||
|
||||
# protect against those who work in their fork on develop |
||||
if: github.repository == 'qmk/qmk_firmware' |
||||
|
||||
steps: |
||||
- uses: actions/checkout@v2 |
||||
with: |
||||
fetch-depth: 1 |
||||
persist-credentials: false |
||||
|
||||
- name: Generate API Data |
||||
run: qmk generate-api |
||||
|
||||
- name: Install rsync |
||||
run: | |
||||
apt-get update && apt-get install -y rsync |
||||
|
||||
- name: Upload API Data |
||||
uses: JamesIves/github-pages-deploy-action@3.7.1 |
||||
with: |
||||
ACCESS_TOKEN: ${{ secrets.API_TOKEN_GITHUB }} |
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
||||
BRANCH: main |
||||
FOLDER: api_data/v1 |
||||
CLEAN: true |
||||
GIT_CONFIG_EMAIL: hello@qmk.fm |
||||
REPOSITORY_NAME: qmk/qmk_keyboards_devel |
||||
TARGET_FOLDER: v1 |
@ -0,0 +1,37 @@ |
||||
name: Update develop after master merge |
||||
|
||||
on: |
||||
push: |
||||
branches: |
||||
- master |
||||
|
||||
|
||||
jobs: |
||||
develop_update: |
||||
runs-on: ubuntu-latest |
||||
|
||||
if: github.repository == 'qmk/qmk_firmware' |
||||
|
||||
steps: |
||||
- uses: actions/checkout@v2 |
||||
with: |
||||
fetch-depth: 0 |
||||
|
||||
- name: Checkout develop |
||||
run: | |
||||
git fetch origin master develop |
||||
git checkout develop |
||||
|
||||
- name: Check if branch locked |
||||
id: check_locked |
||||
uses: andstor/file-existence-action@v1 |
||||
with: |
||||
files: ".locked" |
||||
|
||||
- name: Update develop from master |
||||
if: steps.check_locked.outputs.files_exists == 'false' |
||||
run: | |
||||
git config --global user.name "QMK Bot" |
||||
git config --global user.email "hello@qmk.fm" |
||||
git merge origin/master |
||||
git push origin develop |
@ -0,0 +1,43 @@ |
||||
name: Generate Docs |
||||
|
||||
on: |
||||
push: |
||||
branches: |
||||
- master |
||||
paths: |
||||
- 'tmk_core/**' |
||||
- 'quantum/**' |
||||
- 'platforms/**' |
||||
- 'docs/**' |
||||
- '.github/workflows/docs.yml' |
||||
|
||||
jobs: |
||||
generate: |
||||
runs-on: ubuntu-latest |
||||
container: qmkfm/base_container |
||||
|
||||
# protect against those who develop with their fork on master |
||||
if: github.repository == 'qmk/qmk_firmware' |
||||
|
||||
steps: |
||||
- uses: actions/checkout@v2 |
||||
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@3.7.1 |
||||
with: |
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
||||
BASE_BRANCH: master |
||||
BRANCH: gh-pages |
||||
FOLDER: .build/docs |
||||
GIT_CONFIG_EMAIL: hello@qmk.fm |
@ -0,0 +1,43 @@ |
||||
name: Format Codebase |
||||
|
||||
on: |
||||
push: |
||||
branches: |
||||
- master |
||||
|
||||
jobs: |
||||
format: |
||||
runs-on: ubuntu-latest |
||||
container: qmkfm/base_container |
||||
|
||||
# protect against those who develop with their fork on master |
||||
if: github.repository == 'qmk/qmk_firmware' |
||||
|
||||
steps: |
||||
- uses: actions/checkout@v2 |
||||
with: |
||||
token: ${{ secrets.API_TOKEN_GITHUB }} |
||||
|
||||
- name: Install dependencies |
||||
run: | |
||||
apt-get update && apt-get install -y dos2unix |
||||
|
||||
- name: Format files |
||||
run: | |
||||
bin/qmk cformat -a |
||||
bin/qmk pyformat |
||||
bin/qmk fileformat |
||||
|
||||
- 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@v3 |
||||
with: |
||||
delete-branch: true |
||||
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' |
@ -0,0 +1,14 @@ |
||||
name: "Pull Request Labeler" |
||||
|
||||
on: |
||||
pull_request_target: |
||||
types: [opened, synchronize, reopened, ready_for_review, locked] |
||||
|
||||
jobs: |
||||
triage: |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- uses: actions/labeler@main |
||||
with: |
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}" |
||||
configuration-path: '.github/labeler.yml' |
@ -0,0 +1,55 @@ |
||||
name: PR Lint keyboards |
||||
|
||||
on: |
||||
pull_request: |
||||
paths: |
||||
- 'keyboards/**' |
||||
|
||||
jobs: |
||||
lint: |
||||
runs-on: ubuntu-latest |
||||
|
||||
container: qmkfm/base_container |
||||
|
||||
steps: |
||||
- uses: actions/checkout@v2 |
||||
with: |
||||
fetch-depth: 0 |
||||
|
||||
- uses: trilom/file-changes-action@v1.2.4 |
||||
id: file_changes |
||||
with: |
||||
output: '\n' |
||||
|
||||
- name: Print info |
||||
run: | |
||||
git rev-parse --short HEAD |
||||
echo ${{ github.event.pull_request.base.sha }} |
||||
echo '${{ steps.file_changes.outputs.files}}' |
||||
|
||||
- name: Run qmk lint |
||||
shell: 'bash {0}' |
||||
run: | |
||||
QMK_CHANGES=$(echo -e '${{ steps.file_changes.outputs.files}}') |
||||
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 |
||||
if [[ $exit_code -gt 255 ]]; then |
||||
exit 255 |
||||
fi |
||||
exit $exit_code |
@ -0,0 +1 @@ |
||||
theme: jekyll-theme-cayman |
@ -0,0 +1,5 @@ |
||||
# QMK Keyboard Metadata |
||||
|
||||
This directory contains machine parsable data about keyboards supported by QMK. The latest version is always available online at <https://keyboards.qmk.fm>. |
||||
|
||||
Do not edit anything here by hand. It is generated with the `qmk generate-api` command. |
@ -0,0 +1,31 @@ |
||||
# Unconditionally disable features that a keyboard advertises it doesn't support
|
||||
|
||||
FEATURE_NAMES :=
|
||||
FEATURE_NAMES += ADAFRUIT_BLE
|
||||
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 += PRINTING
|
||||
FEATURE_NAMES += PS2_MOUSE
|
||||
FEATURE_NAMES += RGBLIGHT
|
||||
FEATURE_NAMES += RGB_MATRIX
|
||||
FEATURE_NAMES += SLEEP_LED
|
||||
FEATURE_NAMES += SERIAL_LINK
|
||||
FEATURE_NAMES += STENO
|
||||
FEATURE_NAMES += SWAP_HANDS
|
||||
FEATURE_NAMES += VISUALIZER
|
||||
FEATURE_NAMES += WATCHDOG
|
||||
FEATURE_NAMES += XT
|
||||
|
||||
$(foreach AFEATURE,$(FEATURE_NAMES),\
|
||||
$(if $(filter $($(AFEATURE)_SUPPORTED),no),$(eval $(AFEATURE)_ENABLE=no)))
|
@ -0,0 +1,239 @@ |
||||
# QMK Breaking Change - 2020 May 30 Changelog |
||||
|
||||
Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps. |
||||
|
||||
The list of changes follows. |
||||
|
||||
|
||||
## Core Changes |
||||
|
||||
### Converting V-USB usbdrv to a submodule |
||||
|
||||
[#8321](https://github.com/qmk/qmk_firmware/pull/8321) and [qmk_compiler#62](https://github.com/qmk/qmk_compiler/pull/62). |
||||
|
||||
These PRs move the V-USB driver code out of the qmk_firmware repository and into a submodule pointed at https://github.com/obdev/v-usb. This will make it easier to update the codebase if needed, while applying any potential QMK-specific modifications by forking it to the QMK GitHub organization. |
||||
|
||||
### Unify Tap Hold functions and documentation |
||||
|
||||
[#8348](https://github.com/qmk/qmk_firmware/pull/8348) |
||||
|
||||
Updates all of the per key tap-hold functions to pass the `keyrecord_t` structure, and include documentation changes. |
||||
|
||||
Any remaining versions or code outside of the main repo will need to be converted: |
||||
| Old function | New Function | |
||||
|------------------------------------------------------|---------------------------------------------------------------------------| |
||||
|`uint16_t get_tapping_term(uint16_t keycode)` |`uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record)` | |
||||
|`bool get_ignore_mod_tap_interrupt(uint16_t keycode)` |`bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record)` | |
||||
|
||||
### Python Required In The Build Process |
||||
|
||||
[#9000](https://github.com/qmk/qmk_firmware/pull/9000) |
||||
|
||||
This is the last release of QMK that will work without having Python 3.6 (or later) installed. If your environment is not fully setup you will get a warning instructing you to set it up. |
||||
|
||||
After the next breaking change you will not be able to build if `bin/qmk hello` does not work. |
||||
|
||||
### Upgrade from tinyprintf to mpaland/printf |
||||
|
||||
[#8269](https://github.com/qmk/qmk_firmware/pull/8269) |
||||
|
||||
- Provides debug functionality on ChibiOS/ARM that is more compliant than previous integrations. |
||||
- Less maintenence, fewer QMK customisations, and allows QMK to sidestep previous compile and runtime issues. |
||||
- A `make git-submodule` may be required after pulling the latest QMK Firmware code to update to the new dependency. |
||||
|
||||
### Fixed RGB_DISABLE_AFTER_TIMEOUT to be seconds based & small internals cleanup |
||||
|
||||
[#6480](https://github.com/qmk/qmk_firmware/pull/6480) |
||||
|
||||
- Changes `RGB_DISABLE_AFTER_TIMEOUT` to be based on milliseconds instead of ticks. |
||||
- Includes a code cleanup, resulting in a savings of 100 bytes, depending on features used. |
||||
- Fixed issues with timeouts / suspending at the wrong time not turning off all LEDs in some cases. |
||||
|
||||
The `RGB_DISABLE_AFTER_TIMEOUT` definition is now deprecated, and has been superseded by `RGB_DISABLE_TIMEOUT`. To use the new definition, rename `RGB_DISABLE_AFTER_TIMEOUT` to `RGB_DISABLE_TIMEOUT` in your `config.h` file, and multiply the value set by 1200. |
||||
|
||||
Before: `#define RGB_DISABLE_AFTER_TIMEOUT 100` |
||||
After: `#define RGB_DISABLE_TIMEOUT 120000` |
||||
|
||||
### Switch to qmk forks for everything |
||||
|
||||
[#9019](https://github.com/qmk/qmk_firmware/pull/9019) |
||||
|
||||
Fork all QMK submodules to protect against upstream repositories disappearing. |
||||
|
||||
### code cleanup regarding deprecated macro PLAY_NOTE_ARRAY by replacing it with PLAY_SONG |
||||
|
||||
[#8484](https://github.com/qmk/qmk_firmware/pull/8484) |
||||
|
||||
Removes the deprecated `PLAY_NOTE_ARRAY` macro. References to it are replaced with `PLAY_SONG`, which references the same function. |
||||
|
||||
### fixing wrong configuration of AUDIO feature |
||||
|
||||
[#8903](https://github.com/qmk/qmk_firmware/pull/8903) and [#8974](https://github.com/qmk/qmk_firmware/pull/8974) |
||||
|
||||
`audio_avr.c` does not default to any pin; there has to be a #define XX_AUDIO in config.h at some level for Audio to actually work. Otherwise, the Audio code ends up cluttering the firmware, possibly breaking builds because the maximum allowed firmware size is exceeded. |
||||
|
||||
These changes fix this by disabling Audio on keyboards that have the feature misconfigured, and therefore non-functional. |
||||
|
||||
Also, add a compile-time error to alert the user to a missing pin-configuration (on AVR boards) when `AUDIO_ENABLE = yes` is set. |
||||
|
||||
|
||||
## Keyboard Refactors |
||||
|
||||
### Migrating Lily58 to use split_common |
||||
|
||||
[#6260](https://github.com/qmk/qmk_firmware/pull/6260) |
||||
|
||||
Modifies the default firmware for Lily58 to use the `split_common` library, instead of including and depending on its own set of libraries for the following functionality: |
||||
|
||||
- SSD1306 display |
||||
- i2c for OLED |
||||
- Serial Communication |
||||
|
||||
This allows current lily58 firmware to advance with updates to the `split_common` library, which is shared with many other split keyboards. |
||||
|
||||
#### To migrate existing Lily58 firmware: |
||||
|
||||
[Changes to `config.h`](https://github.com/qmk/qmk_firmware/pull/6260/files#diff-445ac369c8717dcd6fc6fc3630836fc1): |
||||
- Remove `#define SSD1306OLED` from config.h |
||||
|
||||
|
||||
[Changes to `keymap.c`](https://github.com/qmk/qmk_firmware/pull/6260/files#diff-20943ea59856e9bdf3d99ecb2eee40b7): |
||||
- Find/Replace each instance of `#ifdef SSD1306OLED` with `#ifdef OLED_DRIVER_ENABLE` |
||||
- The following changes are for compatibility with the OLED driver. If you don't use the OLED driver you may safely delete [this section](https://github.com/qmk/qmk_firmware/blob/e6b9980bd45c186f7360df68c24b6e05a80c10dc/keyboards/lily58/keymaps/default/keymap.c#L144-L190) |
||||
- Alternatively, if you did not change the OLED code from that in `default`, you may find it easier to simply copy the [relevant section](https://github.com/qmk/qmk_firmware/blob/4ac310668501ae6786c711ecc8f01f62ddaa1c0b/keyboards/lily58/keymaps/default/keymap.c#L138-L172). Otherwise, the changes you need to make are as follows (sample change [here](https://github.com/qmk/qmk_firmware/pull/6260/files#diff-20943ea59856e9bdf3d99ecb2eee40b7R138-R173)) |
||||
- [Remove](https://github.com/qmk/qmk_firmware/pull/6260/files#diff-20943ea59856e9bdf3d99ecb2eee40b7L138-L141) the block |
||||
```c |
||||
#ifdef SSD1306OLED |
||||
iota_gfx_init(!has_usb()); // turns on the display |
||||
#endif |
||||
``` |
||||
- Within the block bounded by `#ifdef OLED_DRIVER_ENABLE` and `#endif // OLED_DRIVER_ENABLE`, add the following block to ensure that your two OLEDs are rotated correctly across the left and right sides: |
||||
```c |
||||
oled_rotation_t oled_init_user(oled_rotation_t rotation) { |
||||
if (!is_keyboard_master()) |
||||
return OLED_ROTATION_180; // flips the display 180 degrees if offhand |
||||
return rotation; |
||||
} |
||||
``` |
||||
- Remove the functions `matrix_scan_user`, `matrix_update` and `iota_gfx_task_user` |
||||
- Find/Replace `matrix_render_user(struct CharacterMatrix *matrix)` with `iota_gfx_task_user(void)` |
||||
- Find/Replace `is_master` with `is_keyboard_master()` |
||||
- For each instance of `matrix_write_ln(matrix, display_fn())`, rewrite it as `oled_write_ln(read_layer_state(), false);` |
||||
- For each instance of `matrix_write(matrix, read_logo());`, replace with `oled_write(read_logo(), false);` |
||||
|
||||
### Refactor zinc to use split_common |
||||
|
||||
[#7114](https://github.com/qmk/qmk_firmware/pull/7114) and [#9171](https://github.com/qmk/qmk_firmware/pull/9171) |
||||
|
||||
* Refactor to use split_common and remove split codes under the zinc/revx/ |
||||
* Add - backlight RGB LED and/or underglow RGB LED option |
||||
* Add - continuous RGB animations feature (between L and R halves) |
||||
* Fix - keymap files to adapt to changes |
||||
* all authors of keymaps confirmed this PR |
||||
* Update - documents and rules.mk |
||||
|
||||
### Refactor of TKC1800 to use common OLED code |
||||
|
||||
[#8472](https://github.com/qmk/qmk_firmware/pull/8472) |
||||
|
||||
Modifies the default firmware for TKC1800 to use the in-built I2C and OLED drivers, instead of including and depending on its own set of libraries for the following functionality: |
||||
|
||||
- SSD1306 display |
||||
- i2c for OLED |
||||
|
||||
This allows current TKC1800 firmware to advance with updates to those drivers, which are shared with other keyboards. |
||||
|
||||
#### To migrate existing TKC1800 firmware: |
||||
|
||||
[Changes to `config.h`](https://github.com/qmk/qmk_firmware/pull/8472/files#diff-d10b26e676b4a55cbb00d71955116526): |
||||
- Remove `#define SSD1306OLED` from config.h |
||||
|
||||
[Changes to `tkc1800.c`](https://github.com/qmk/qmk_firmware/pull/8472/files#diff-3b35bd30abe89c8110717c6972cd2cc5): |
||||
- Add the following to avoid debug errors on HID_listen if the screen is not present |
||||
```c |
||||
void keyboard_pre_init_kb(void) { |
||||
setPinInputHigh(D0); |
||||
setPinInputHigh(D1); |
||||
|
||||
keyboard_pre_init_user(); |
||||
} |
||||
``` |
||||
|
||||
[Changes to `keymap.c`](https://github.com/qmk/qmk_firmware/pull/8472/files#diff-05a2a344ce27e4d045fe68520ccd4771): |
||||
- Find/Replace each instance of `#ifdef SSD1306OLED` with `#ifdef OLED_DRIVER_ENABLE` |
||||
- The following changes are for compatibility with the OLED driver. If you don't use the OLED driver you may safely delete [this section](https://github.com/qmk/qmk_firmware/blob/e6b9980bd45c186f7360df68c24b6e05a80c10dc/keyboards/lily58/keymaps/default/keymap.c#L144-L190) |
||||
- [Remove](https://github.com/qmk/qmk_firmware/pull/6260/files#diff-20943ea59856e9bdf3d99ecb2eee40b7L91-L158) the block |
||||
```c |
||||
#ifdef SSD1306OLED |
||||
iota_gfx_init(!has_usb()); // turns on the display |
||||
#endif |
||||
``` |
||||
- Within the block bounded by `#ifdef OLED_DRIVER_ENABLE` and `#endif // OLED_DRIVER_ENABLE`, add the following block to ensure that your two OLEDs are rotated correctly across the left and right sides: |
||||
```c |
||||
oled_rotation_t oled_init_user(oled_rotation_t rotation) { |
||||
if (!is_keyboard_master()) |
||||
return OLED_ROTATION_180; // flips the display 180 degrees if offhand |
||||
return rotation; |
||||
} |
||||
``` |
||||
- Remove the function `iota_gfx_task_user` |
||||
|
||||
### Split HHKB to ANSI and JP layouts and Add VIA support for each |
||||
|
||||
[#8582](https://github.com/qmk/qmk_firmware/pull/8582) |
||||
|
||||
- Splits the HHKB codebase into two separate folders `keyboards/hhkb/ansi` and `keyboards/hhkb/jp`. |
||||
- Adds VIA Configurator support for both versions. |
||||
|
||||
#### Migrating existing HHKB keymaps |
||||
|
||||
- Remove any checks for the `HHKB_JP` definition |
||||
- All checks for this definition have been removed, and each version uses the source that is appropriate to that version. |
||||
- Move the directory for your keymap into the appropriate `keymaps` directory |
||||
- `keyboards/hhkb/ansi/keymaps/` for ANSI HHKBs |
||||
- `keyboards/hhkb/jp/keymaps/` for HHKB JPs |
||||
- Compile with the new keyboard names |
||||
- This PR changes the compilation instructions for the HHKB Alternate Controller. To compile firmware for this controller moving forward, use: |
||||
- `make hhkb/ansi` for ANSI-layout HHKBs |
||||
- `make hhkb/jp` for HHKB JP keyboards |
||||
|
||||
|
||||
## Keyboard Moves |
||||
|
||||
- [#8412](https://github.com/qmk/qmk_firmware/pull/8412 "Changing board names to prevent confusion") by blindassassin111 |
||||
- [#8499](https://github.com/qmk/qmk_firmware/pull/8499 "Move the Keyboardio Model01 to a keyboardio/ subdir") by algernon |
||||
- [#8830](https://github.com/qmk/qmk_firmware/pull/8830 "Move spaceman keyboards") by Spaceman (formerly known as Rionlion100) |
||||
- [#8537](https://github.com/qmk/qmk_firmware/pull/8537 "Organizing my keyboards (plaid, tartan, ergoinu)") by hsgw |
||||
|
||||
Keyboards by Keyboardio, Spaceman, and hsgw move to vendor folders, while PCBs designed by blindassassin111 are renamed. |
||||
|
||||
Old Name | New Name |
||||
:----------------- | :----------------- |
||||
2_milk | spaceman/2_milk |
||||
at101_blackheart | at101_bh |
||||
ergoinu | dm9records/ergoinu |
||||
model01 | keyboardio/model01 |
||||
omnikey_blackheart | omnikey_bh |
||||
pancake | spaceman/pancake |
||||
plaid | dm9records/plaid |
||||
tartan | dm9records/tartan |
||||
z150_blackheart | z150_bh |
||||
|
||||
If you own one of these PCBs, please use the new names to compile your firmware moving forward. |
||||
|
||||
|
||||
## Keycode Migration PRs |
||||
|
||||
[#8954](https://github.com/qmk/qmk_firmware/pull/8954 "Migrate `ACTION_LAYER_TOGGLE` to `TG()`"), [#8957](https://github.com/qmk/qmk_firmware/pull/8957 "Migrate `ACTION_MODS_ONESHOT` to `OSM()`"), [#8958](https://github.com/qmk/qmk_firmware/pull/8958 "Migrate `ACTION_DEFAULT_LAYER_SET` to `DF()`"), [#8959](https://github.com/qmk/qmk_firmware/pull/8959 "Migrate `ACTION_LAYER_MODS` to `LM()`"), [#8968](https://github.com/qmk/qmk_firmware/pull/8968 "Migrate `ACTION_MODS_TAP_KEY` to `MT()`"), [#8977](https://github.com/qmk/qmk_firmware/pull/8977 "Migrate miscellaneous `fn_actions` entries"), and [#8979](https://github.com/qmk/qmk_firmware/pull/8979 "Migrate `ACTION_MODS_KEY` to chained mod keycodes") |
||||
|
||||
Authored by fauxpark, these pull requests remove references to deprecated TMK macros that have been superseded by native QMK keycodes. |
||||
|
||||
Old `fn_actions` action | New QMK keycode |
||||
:---------------------- | :-------------- |
||||
`ACTION_DEFAULT_LAYER_SET(layer)` | `DF(layer)` |
||||
`ACTION_LAYER_MODS(layer, mod)` | `LM(layer, mod)` |
||||
`ACTION_LAYER_ONESHOT(mod)` | `OSL(mod)` |
||||
`ACTION_LAYER_TOGGLE(layer)` | `TG(layer)` |
||||
`ACTION_MODS_ONESHOT(mod)` | `OSM(mod)` |
||||
`ACTION_MODS_TAP_KEY(mod, kc)` | `MT(mod, kc)` |
||||
`ACTION_MODS_KEY(mod, kc)`<br>e.g. `ACTION_MODS_KEY(MOD_LCTL, KC_0)` | `MOD(kc)`<br>e.g. `LCTL(KC_0)` |
@ -0,0 +1,148 @@ |
||||
# QMK Breaking Change - 2020 Aug 29 Changelog |
||||
|
||||
Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps. |
||||
|
||||
|
||||
## Changes Requiring User Action :id=changes-requiring-user-action |
||||
|
||||
### Relocated Keyboards :id-relocated-keyboards |
||||
|
||||
#### The Key Company project consolidation ([#9547](https://github.com/qmk/qmk_firmware/pull/9547)) |
||||
#### relocating boards by flehrad to flehrad/ folder ([#9635](https://github.com/qmk/qmk_firmware/pull/9635)) |
||||
|
||||
Keyboards released by The Key Company and keyboards designed by flehrad have moved to vendor folders. If you own any of the keyboards listed below, please use the new names to compile your firmware moving forward. |
||||
|
||||
Old Name | New Name |
||||
:--------------------- | :------------------ |
||||
candybar/lefty | tkc/candybar/lefty |
||||
candybar/righty | tkc/candybar/righty |
||||
m0lly | tkc/m0lly |
||||
tkc1800 | tkc/tkc1800 |
||||
bigswitch | flehrad/bigswitch |
||||
handwired/downbubble | flehrad/downbubble |
||||
handwired/numbrero | flehrad/numbrero |
||||
snagpad | flehrad/snagpad |
||||
handwired/tradestation | flehrad/tradestation |
||||
|
||||
### Updated Keyboard Codebases :id=keyboard-updates |
||||
|
||||
#### Keebio RGB wiring update ([#7754](https://github.com/qmk/qmk_firmware/pull/7754)) |
||||
|
||||
This pull request changes the configuration for Keebio split boards to use the same RGB strip wiring for each half, which provides the following improvements: |
||||
|
||||
* Easier wiring due to one fewer wire needed (the wire between left DOut to extra data pin) and the fact that wiring is the same for both halves. |
||||
* RGB LEDs can be controlled by each half now instead of just master half. |
||||
* Extra data line is freed up to allow for I2C usage instead of serial. |
||||
|
||||
If you have customized the value of `RGBLED_SPLIT` for your keymap, you will need to undefine it using `#undef RGBLED_SPLIT` before defining it to your customized value. |
||||
|
||||
This change affects: |
||||
|
||||
* BFO-9000 |
||||
* Fourier |
||||
* Iris rev2 |
||||
* Levinson, revs. 1 and 2 |
||||
* Nyquist, revs. 1 and 2 |
||||
* Quefrency rev1 |
||||
* Viterbi, revs. 1 and 2 |
||||
|
||||
### Changes to Core Functionality :id=core-updates |
||||
|
||||
* Bigger Combo index ([#9318](https://github.com/qmk/qmk_firmware/pull/9318)) |
||||
|
||||
Allows the Combo feature to support more than 256 combos. |
||||
|
||||
Any fork that uses `process_combo_event` needs to update the function's first argument to `uint16_t`: |
||||
|
||||
* Old function: `void process_combo_event(uint8_t combo_index, bool pressed)` |
||||
* New function: `void process_combo_event(uint16_t combo_index, bool pressed)` |
||||
|
||||
|
||||
## Core Changes :id=core-changes |
||||
|
||||
### Fixes :id=core-fixes |
||||
|
||||
* Mousekeys: scrolling acceleration is no longer coupled to mouse movement acceleration ([#9174](https://github.com/qmk/qmk_firmware/pull/9174)) |
||||
* Keymap Extras: correctly assign Question Mark in Czech layout ([#9987](https://github.com/qmk/qmk_firmware/pull/9987)) |
||||
|
||||
### Additions and Enhancements :id=core-additions |
||||
|
||||
* allow for WS2812 PWM to work on DMAMUX-capable devices ([#9471](https://github.com/qmk/qmk_firmware/pull/9471)) |
||||
* Newer STM32 MCUs have a DMAMUX peripheral, which allows mapping of DMAs to different DMA streams, rather than hard-defining the target streams in silicon. |
||||
* Affects STM32L4+ devices, as well as the soon-to-be-supported-by-QMK STM32G4/H7 families. |
||||
* Tested on F303/Proton C (ChibiOS v19, non-DMAMUX), G474 (ChibiOS v20, with DMAMUX). |
||||
* dual-bank STM32 bootloader support ([#8778](https://github.com/qmk/qmk_firmware/pull/8778) and [#9738](https://github.com/qmk/qmk_firmware/pull/9738)) |
||||
* Adds support for STM32 dual-bank flash bootloaders, by toggling a GPIO during early init in order to charge an RC circuit attached to `BOOT0`. |
||||
* The main rationale behind this is that dual-bank STM32 devices unconditionally execute user-mode code, regardless of whether or not the user-mode code jumps to the bootloader. If either flash bank is valid (and `BOOT0` is low), then the built-in bootloader will skip any sort of DFU. |
||||
* This PR allows for the initialisation sequencing to charge the RC circuit based on the example circuit posted on Discord, effectively pulling `BOOT0` high before issuing the system reset. As the RC circuit takes a while to discharge, the system reset executes the ROM bootloader which subsequently sees `BOOT0` high, and starts executing the DFU routines. |
||||
* Tested with STM32L082 (with current QMK+current ChibiOS), and STM32G474 (against ChibiOS 20.x). |
||||
* update Space Cadet and Tap Dance features to use Custom Tapping Term when appropriate ([#6259](https://github.com/qmk/qmk_firmware/pull/6259)) |
||||
* For the Tap Dance feature, this completely removes the need for the `ACTION_TAP_DANCE_FN_ADVANCED_TIME` dance. |
||||
* HID Joystick Interface ([#4226](https://github.com/qmk/qmk_firmware/pull/4226) and [#9949](https://github.com/qmk/qmk_firmware/pull/9949 "Fix Joystick Compile Issues")) |
||||
* This implements a joystick feature, including a joystick_task function called from TMK, specific keycodes for joystick buttons and a USB HID interface. |
||||
* Tested on V-USB backend and Proton C; compiles but untested on LUFA. |
||||
* In order to test, you have to add `JOYSTICK_ENABLE = yes` to your `rules.mk` and |
||||
```c |
||||
#define JOYSTICK_BUTTON_COUNT 8 |
||||
#define JOYSTICK_AXES_COUNT 2 |
||||
``` |
||||
in your config.h. |
||||
* Christmas RGB Underglow animation now fades between green and red ([#7648](https://github.com/qmk/qmk_firmware/pull/7648)) |
||||
* `RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL` has been greatly decreased; please check your animation if you have customized this value. |
||||
* layer state now initializes on startup ([#8318](https://github.com/qmk/qmk_firmware/pull/8318)) |
||||
* This should produce more consistent behavior between the two functions and layer masks. |
||||
* added support for HSV->RGB conversion without using CIE curve ([#9856](https://github.com/qmk/qmk_firmware/pull/9856)) |
||||
* added NOEEPROM functions for RGB Matrix ([#9487](https://github.com/qmk/qmk_firmware/pull/9487)) |
||||
* Added eeprom_helpers for toggle, mode, sethsv, speed, similar to rgblight versions. |
||||
* Added set_speed function. |
||||
* Added helper functions, similar to those in rgblight, in order to add NOEEPROM versions of toggle, step, hue, sat, val, and speed. |
||||
* Minor: spelling correction for EEPROM in a debug message. |
||||
* flashing firmware using `st-flash` utility from [STLink Tools](https://github.com/stlink-org/stlink) is now supported ([#9964](https://github.com/qmk/qmk_firmware/pull/9964)) |
||||
* add ability to dump all makefile variables for the specified target ([#8256](https://github.com/qmk/qmk_firmware/pull/8256)) |
||||
* Adds a new subtarget to builds, `dump_vars`, which allows for printing out all the variables that make knows about, after all substitutions occur. |
||||
* Example: `make handwired/onekey/proton_c:default:dump_vars` |
||||
* add ability to change the Auto Shift timeout in real time ([#8441](https://github.com/qmk/qmk_firmware/pull/8441)) |
||||
* added a timer implementation for backlight on ChibiOS ([#8291](https://github.com/qmk/qmk_firmware/pull/8291)) |
||||
* added a third endpoint to V-USB keyboards ([#9020](https://github.com/qmk/qmk_firmware/pull/9020)) |
||||
* added a method to read the OLED display buffer from user space ([#8777](https://github.com/qmk/qmk_firmware/pull/8777)) |
||||
* K-Type refactor ([#9864](https://github.com/qmk/qmk_firmware/pull/9864)) |
||||
* The K-Type has been refactored to use QMK's native matrix scanning routine, and now has partial support for the RGB Matrix feature. |
||||
* Joysticks can now be used without defining analog pins ([#10169](https://github.com/qmk/qmk_firmware/pull/10169)) |
||||
|
||||
### Clean-ups and Optimizations :id=core-optimizations |
||||
|
||||
* iWRAP protocol removed ([#9284](https://github.com/qmk/qmk_firmware/pull/9284)) |
||||
* work begun for consolidation of ChibiOS platform files ([#8327](https://github.com/qmk/qmk_firmware/pull/8327) and [#9315](https://github.com/qmk/qmk_firmware/pull/9315)) |
||||
* Start of the consolidation work to move the ChibiOS board definitions as well as the default set of configuration files for existing board definitions used by keyboards. |
||||
* Uses `/platforms/chibios` as previously discussed on discord. |
||||
* Consolidates the Proton C configs into the generic F303 definitions. |
||||
* Allows for defining a default set of `chconf.h`, `halconf.h`, and `mcuconf.h` files within the platform definition, which is able to be overridden by the keyboard directly, though include path ordering. |
||||
* Adds template `chconf.h`, `halconf.h`, `mcuconf.h`, and `board.h` that can be dropped into a keyboard directory, in order to override rather than replace the entire contents of the respective files. |
||||
* Removed Proton C QMK board definitions, falling back to ChibiOS board definitions with QMK overrides. |
||||
* Various tidy-ups for USB descriptor code ([#9005](https://github.com/qmk/qmk_firmware/pull/9005)) |
||||
* Renamed `keyboard_led_stats` in lufa.c and ChibiOS usb_main.c to `keyboard_led_state`, as well as `vusb_keyboard_leds`, for consistency |
||||
* Formatted CDC and MIDI descriptors better |
||||
* Removed `ENDPOINT_CONFIG` macro, it seems pointless and removes the need for endpoint address defines in the middle of the endpoint numbering enum |
||||
* Fixed (possibly?) V-USB `GET_REPORT` request handling. Not sure about this one, but the existing code appears to always return an empty report - now `send_keyboard` sets this variable to the current report, matching what the LUFA code does. |
||||
* converted `CONSUMER2BLUEFRUIT()` and `CONSUMER2RN42()` macros to static inline functions ([#9055](https://github.com/qmk/qmk_firmware/pull/9055)) |
||||
* Additional cleanups for V-USB code ([#9310](https://github.com/qmk/qmk_firmware/pull/9310)) |
||||
* Removing the UART stuff entirely, now that we have Console support. Also fixing up various other things; switching some `debug()` calls to `dprintf()`, moved `raw_hid_report` out of the way so that we can implement the shared endpoint stuff. |
||||
* removed inclusion of `adafruit_ble.h` from `ssd1306.c` ([#9355](https://github.com/qmk/qmk_firmware/pull/9355)) |
||||
* `outputselect.c` is no longer compiled if Bluetooth is disabled ([#9356](https://github.com/qmk/qmk_firmware/pull/9356)) |
||||
* `analogRead()` deprecated in favor of `analogReadPin()` ([#9023](https://github.com/qmk/qmk_firmware/pull/9023)) |
||||
* forcibly disable NKRO on V-USB controllers ([#9054](https://github.com/qmk/qmk_firmware/pull/9054)) |
||||
* removed warning if running backlight on STM32F072 ([#10040](https://github.com/qmk/qmk_firmware/pull/10040)) |
||||
* removed unused CORTEX_VTOR_INIT rules.mk option ([#10053](https://github.com/qmk/qmk_firmware/pull/10053)) |
||||
* improved handling for enabling Link Time Optimization ([#9832](https://github.com/qmk/qmk_firmware/pull/9832)) |
||||
* streamline rules for supporting Kiibohd bootloader ([#10129](https://github.com/qmk/qmk_firmware/pull/10129)) |
||||
* Define `STM32_DMA_REQUIRED` when using DMA-based WS2812 driver on STM32 ([#10127](https://github.com/qmk/qmk_firmware/pull/10127)) |
||||
* fix DMA stream ID calculation in ws2812_pwm ([#10008](https://github.com/qmk/qmk_firmware/pull/10008)) |
||||
* remove support for Adafruit EZ Key Bluetooth controller ([#10103](https://github.com/qmk/qmk_firmware/pull/10103)) |
||||
|
||||
|
||||
## QMK Infrastructure and Internals :id=qmk-internals |
||||
|
||||
* Attempt to fix CI for non-master branches. ([#9308](https://github.com/qmk/qmk_firmware/pull/9308)) |
||||
* Actually fetch the branch we're attempting to compare against. |
||||
* Run `qmk cformat` on `develop` branch ([#9501](https://github.com/qmk/qmk_firmware/pull/9501)) |
||||
* minor refactor of Bluetooth API ([#9905](https://github.com/qmk/qmk_firmware/pull/9905)) |
@ -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: |
||||
|
||||
```shell |
||||
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`: |
||||
|
||||
```shell |
||||
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_SLCK, 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_SLCK", "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). |
@ -0,0 +1,117 @@ |
||||
# Miscellaneous FAQ |
||||
|
||||
## How do I test my keyboard? :id=testing |
||||
|
||||
Testing your keyboard is usually pretty straightforward. Press every single key and make sure it sends the keys you expect. You can use [QMK Configurator](https://config.qmk.fm/#/test/)'s test mode to check your keyboard, even if it doesn't run QMK. |
||||
|
||||
## Safety Considerations |
||||
|
||||
You probably don't want to "brick" your keyboard, making it impossible |
||||
to rewrite firmware onto it. Here are some of the parameters to show |
||||
what things are (and likely aren't) too risky. |
||||
|
||||
- If your keyboard map does not include RESET, then, to get into DFU |
||||
mode, you will need to press the reset button on the PCB, which |
||||
requires unscrewing the bottom. |
||||
- Messing with tmk_core / common files might make the keyboard |
||||
inoperable |
||||
- Too large a .hex file is trouble; `make dfu` will erase the block, |
||||
test the size (oops, wrong order!), which errors out, failing to |
||||
flash the keyboard, leaving it in DFU mode. |
||||
- To this end, note that the maximum .hex file size on e.g. Planck |
||||
is 7000h (28672 decimal) |
||||
|
||||
``` |
||||
Linking: .build/planck_rev4_cbbrowne.elf [OK] |
||||
Creating load file for Flash: .build/planck_rev4_cbbrowne.hex [OK] |
||||
|
||||
Size after: |
||||
text data bss dec hex filename |
||||
0 22396 0 22396 577c planck_rev4_cbbrowne.hex |
||||
``` |
||||
|
||||
- The above file is of size 22396/577ch, which is less than |
||||
28672/7000h |
||||
- As long as you have a suitable alternative .hex file around, you |
||||
can retry, loading that one |
||||
- Some of the options you might specify in your keyboard's Makefile |
||||
consume extra memory; watch out for BOOTMAGIC_ENABLE, |
||||
MOUSEKEY_ENABLE, EXTRAKEY_ENABLE, CONSOLE_ENABLE, API_SYSEX_ENABLE |
||||
- DFU tools do /not/ allow you to write into the bootloader (unless |
||||
you throw in an extra fruit salad of options), so there is little risk |
||||
there. |
||||
- EEPROM has around a 100000 (100k) write cycle. You shouldn't rewrite |
||||
the firmware repeatedly and continually; that'll burn the EEPROM |
||||
eventually. |
||||
|
||||
## NKRO Doesn't work |
||||
First you have to compile firmware with the build option `NKRO_ENABLE` in **Makefile**. |
||||
|
||||
Try `Magic` **N** command(`LShift+RShift+N` by default) when **NKRO** still doesn't work. You can use this command to toggle between **NKRO** and **6KRO** mode temporarily. In some situations **NKRO** doesn't work and you will need to switch to **6KRO** mode, in particular when you are in BIOS. |
||||
|
||||
If your firmware was built with `BOOTMAGIC_ENABLE` you need to turn its switch on by `BootMagic` **N** command(`Space+N` by default). This setting is stored in EEPROM and kept over power cycles. |
||||
|
||||
https://github.com/tmk/tmk_keyboard#boot-magic-configuration---virtual-dip-switch |
||||
|
||||
|
||||
## TrackPoint Needs Reset Circuit (PS/2 Mouse Support) |
||||
Without reset circuit you will have inconsistent result due to improper initialization of the hardware. See circuit schematic of TPM754: |
||||
|
||||
- https://geekhack.org/index.php?topic=50176.msg1127447#msg1127447 |
||||
- https://www.mikrocontroller.net/attachment/52583/tpm754.pdf |
||||
|
||||
|
||||
## Can't Read Column of Matrix Beyond 16 |
||||
Use `1UL<<16` instead of `1<<16` in `read_cols()` in [matrix.h] when your columns goes beyond 16. |
||||
|
||||
In C `1` means one of [int] type which is [16 bit] in case of AVR, so you can't shift left more than 15. Thus, calculating `1<<16` will unexpectedly equal zero. To work around this, you have to use [unsigned long] type with `1UL`. |
||||
|
||||
https://deskthority.net/workshop-f7/rebuilding-and-redesigning-a-classic-thinkpad-keyboard-t6181-60.html#p146279 |
||||
|
||||
## Special Extra Key Doesn't Work (System, Audio Control Keys) |
||||
You need to define `EXTRAKEY_ENABLE` in `rules.mk` to use them in QMK. |
||||
|
||||
``` |
||||
EXTRAKEY_ENABLE = yes # Audio control and System control |
||||
``` |
||||
|
||||
## Wake from Sleep Doesn't Work |
||||
|
||||
In Windows check `Allow this device to wake the computer` setting in **Power Management** property tab of **Device Manager**. Also check your BIOS settings. Pressing any key during sleep should wake host. |
||||
|
||||
## Using Arduino? |
||||
|
||||
**Note that Arduino pin naming is different from actual chip.** For example, Arduino pin `D0` is not `PD0`. Check circuit with its schematics yourself. |
||||
|
||||
- https://arduino.cc/en/uploads/Main/arduino-leonardo-schematic_3b.pdf |
||||
- https://arduino.cc/en/uploads/Main/arduino-micro-schematic.pdf |
||||
|
||||
Arduino Leonardo and micro have **ATMega32U4** and can be used for TMK, though Arduino bootloader may be a problem. |
||||
|
||||
## Enabling JTAG |
||||
|
||||
By default, the JTAG debugging interface is disabled as soon as the keyboard starts up. JTAG-capable MCUs come from the factory with the `JTAGEN` fuse set, and it takes over certain pins of the MCU that the board may be using for the switch matrix, LEDs, etc. |
||||
|
||||
If you would like to keep JTAG enabled, just add the following to your `config.h`: |
||||
|
||||
```c |
||||
#define NO_JTAG_DISABLE |
||||
``` |
||||
|
||||
## USB 3 Compatibility |
||||
Some problems can be fixed by switching from a USB 3.x port to a USB 2.0 port. |
||||
|
||||
|
||||
## Mac Compatibility |
||||
### OS X 10.11 and Hub |
||||
See here: https://geekhack.org/index.php?topic=14290.msg1884034#msg1884034 |
||||
|
||||
|
||||
## Problem in BIOS (UEFI) Setup/Resume (Sleep & Wake)/Power Cycles |
||||
Some people reported their keyboard stops working in BIOS and/or after resume(power cycles). |
||||
|
||||
As of now the root cause is not clear, but some build options seem to be related. In Makefile, try to disable options like `CONSOLE_ENABLE`, `NKRO_ENABLE`, `SLEEP_LED_ENABLE` and/or others. |
||||
|
||||
More info: |
||||
- https://github.com/tmk/tmk_keyboard/issues/266 |
||||
- https://geekhack.org/index.php?topic=41989.msg1967778#msg1967778 |
@ -1,43 +1,150 @@ |
||||
# Debounce algorithm |
||||
# Contact bounce / contact chatter |
||||
|
||||
QMK supports multiple debounce algorithms through its debounce API. |
||||
Mechanical switches often don't have a clean single transition between pressed and unpressed states. |
||||
|
||||
In an ideal world, when you press a switch, you would expect the digital pin to see something like this: |
||||
(X axis showing time |
||||
``` |
||||
voltage +---------------------- |
||||
^ | |
||||
| | |
||||
| ------------------+ |
||||
----> time |
||||
``` |
||||
|
||||
However in the real world you will actually see contact bounce, which will look like multiple 1->0 and 0->1 transitions, |
||||
until the value finally settles. |
||||
``` |
||||
+-+ +--+ +------------- |
||||
| | | | | |
||||
| | | | | |
||||
+-----------------+ +-+ +-+ |
||||
``` |
||||
The time it takes for the switch to settle might vary with switch type, age, and even pressing technique. |
||||
|
||||
If the device chooses not to mitigate contact bounce, then often actions that happen when the switch is pressed are repeated |
||||
multiple times. |
||||
|
||||
The logic for which debounce method called is below. It checks various defines that you have set in rules.mk |
||||
There are many ways to handle contact bounce ("Debouncing"). Some include employing additional hardware, for example an RC filter, |
||||
while there are various ways to do debouncing in software too, often called debounce algorithms. This page discusses software |
||||
debouncing methods available in QMK. |
||||
|
||||
While technically not considered contact bounce/contact chatter, some switch technologies are susceptible to noise, meaning, |
||||
while the key is not changing state, sometimes short random 0->1 or 1->0 transitions might be read by the digital circuit, for example: |
||||
``` |
||||
+-+ |
||||
| | |
||||
| | |
||||
+-----------------+ +-------------------- |
||||
``` |
||||
|
||||
Many debounce methods (but not all) will also make the device resistant to noise. If you are working with a technology that is |
||||
susceptible to noise, you must choose a debounce method that will also mitigate noise for you. |
||||
|
||||
## Types of debounce algorithms |
||||
|
||||
1) Unit of time: Timestamp (milliseconds) vs Cycles (scans) |
||||
* Debounce algorithms often have a 'debounce time' parameter, that specifies the maximum settling time of the switch contacts. |
||||
This time might be measured in various units: |
||||
* Cycles-based debouncing waits n cycles (scans), decreasing count by one each matrix_scan |
||||
* Timestamp-based debouncing stores the millisecond timestamp a change occurred, and does substraction to figure out time elapsed. |
||||
* Timestamp-based debouncing is usually superior, especially in the case of noise-resistant devices because settling times of physical |
||||
switches is specified in units of time, and should not depend on the matrix scan-rate of the keyboard. |
||||
* Cycles-based debouncing is sometimes considered inferior, because the settling time that it is able to compensate for depends on the |
||||
performance of the matrix scanning code. If you use cycles-based debouncing, and you significantly improve the performance of your scanning |
||||
code, you might end up with less effective debouncing. A situation in which cycles-based debouncing might be preferable is when |
||||
noise is present, and the scanning algorithm is slow, or variable speed. Even if your debounce algorithm is fundamentally noise-resistant, |
||||
if the scanning is slow, and you are using a timestamp-based algorithm, you might end up making a debouncing decision based on only two |
||||
sampled values, which will limit the noise-resistance of the algorithm. |
||||
* Currently all built-in debounce algorithms support timestamp-based debouncing only. In the future we might |
||||
implement cycles-based debouncing, and it will be selectable via a ```config.h``` macro. |
||||
|
||||
2) Symmetric vs Asymmetric |
||||
* Symmetric - apply the same debouncing algorithm, to both key-up and key-down events. |
||||
* Recommended naming convention: ```sym_*``` |
||||
* Asymmetric - apply different debouncing algorithms to key-down and key-up events. E.g. Eager key-down, Defer key-up. |
||||
* Recommended naming convention: ```asym_*``` followed by details of the type of algorithm in use, in order, for key-down and then key-up |
||||
|
||||
3) Eager vs Defer |
||||
* Eager - any key change is reported immediately. All further inputs for DEBOUNCE ms are ignored. |
||||
* Eager algorithms are not noise-resistant. |
||||
* Recommended naming conventions: |
||||
* ```sym_eager_*``` |
||||
* ```asym_eager_*_*```: key-down is using eager algorithm |
||||
* ```asym_*_eager_*```: key-up is using eager algorithm |
||||
* Defer - wait for no changes for DEBOUNCE ms before reporting change. |
||||
* Defer algorithms are noise-resistant |
||||
* Recommended naming conventions: |
||||
* ```sym_defer_*``` |
||||
* ```asym_defer_*_*```: key-down is using defer algorithm |
||||
* ```asym_*_defer_*```: key-up is using defer algorithm |
||||
|
||||
4) Global vs Per-Key vs Per-Row |
||||
* Global - one timer for all keys. Any key change state affects global timer |
||||
* Recommended naming convention: ```*_g``` |
||||
* Per-key - one timer per key |
||||
* Recommended naming convention: ```*_pk``` |
||||
* Per-row - one timer per row |
||||
* Recommended naming convention: ```*_pr``` |
||||
* Per-key and per-row algorithms consume more resources (in terms of performance, |
||||
and ram usage), but fast typists might prefer them over global. |
||||
|
||||
## Debounce algorithms supported by QMK |
||||
|
||||
QMK supports multiple debounce algorithms through its debounce API. |
||||
The logic for which debounce method called is below. It checks various defines that you have set in ```rules.mk``` |
||||
|
||||
``` |
||||
DEBOUNCE_DIR:= $(QUANTUM_DIR)/debounce |
||||
DEBOUNCE_TYPE?= sym_g |
||||
DEBOUNCE_TYPE?= sym_defer_g |
||||
ifneq ($(strip $(DEBOUNCE_TYPE)), custom) |
||||
QUANTUM_SRC += $(DEBOUNCE_DIR)/$(strip $(DEBOUNCE_TYPE)).c |
||||
endif |
||||
``` |
||||
|
||||
# Debounce selection |
||||
### Debounce selection |
||||
|
||||
| DEBOUNCE_TYPE | Description | What else is needed | |
||||
| ------------- | --------------------------------------------------- | ----------------------------- | |
||||
| Not defined | Use the default algorithm, currently sym_g | Nothing | |
||||
| Not defined | Use the default algorithm, currently sym_defer_g | Nothing | |
||||
| custom | Use your own debounce code | ```SRC += debounce.c``` add your own debounce.c and implement necessary functions | |
||||
| anything_else | Use another algorithm from quantum/debounce/* | Nothing | |
||||
| Anything Else | Use another algorithm from quantum/debounce/* | Nothing | |
||||
|
||||
**Regarding split keyboards**: |
||||
The debounce code is compatible with split keyboards. |
||||
|
||||
# Use your own debouncing code |
||||
* Set ```DEBOUNCE_TYPE = custom```. |
||||
* Add ```SRC += debounce.c``` |
||||
### Selecting an included debouncing method |
||||
Keyboards may select one of the already implemented debounce methods, by adding to ```rules.mk``` the following line: |
||||
``` |
||||
DEBOUNCE_TYPE = <name of algorithm> |
||||
``` |
||||
Where name of algorithm is one of: |
||||
* ```sym_defer_g``` - debouncing per keyboard. On any state change, a global timer is set. When ```DEBOUNCE``` milliseconds of no changes has occurred, all input changes are pushed. |
||||
* This is the current default algorithm. This is the highest performance algorithm with lowest memory usage, and it's also noise-resistant. |
||||
* ```sym_eager_pr``` - debouncing per row. On any state change, response is immediate, followed by locking the row ```DEBOUNCE``` milliseconds of no further input for that row. |
||||
For use in keyboards where refreshing ```NUM_KEYS``` 8-bit counters is computationally expensive / low scan rate, and fingers usually only hit one row at a time. This could be |
||||
appropriate for the ErgoDox models; the matrix is rotated 90°, and hence its "rows" are really columns, and each finger only hits a single "row" at a time in normal use. |
||||
* ```sym_eager_pk``` - debouncing per key. On any state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key |
||||
* ```sym_defer_pk``` - debouncing per key. On any state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that key, the key status change is pushed. |
||||
|
||||
### A couple algorithms that could be implemented in the future: |
||||
* ```sym_defer_pr``` |
||||
* ```sym_eager_g``` |
||||
* ```asym_eager_defer_pk``` |
||||
|
||||
### Use your own debouncing code |
||||
You have the option to implement you own debouncing algorithm. To do this: |
||||
* Set ```DEBOUNCE_TYPE = custom``` in ```rules.mk```. |
||||
* Add ```SRC += debounce.c``` in ```rules.mk``` |
||||
* Add your own ```debounce.c```. Look at current implementations in ```quantum/debounce``` for examples. |
||||
* Debouncing occurs after every raw matrix scan. |
||||
* Use num_rows rather than MATRIX_ROWS, so that split keyboards are supported correctly. |
||||
* If the algorithm might be applicable to other keyboards, please consider adding it to ```quantum/debounce``` |
||||
|
||||
# Changing between included debouncing methods |
||||
You can either use your own code, by including your own debounce.c, or switch to another included one. |
||||
Included debounce methods are: |
||||
* eager_pr - debouncing per row. On any state change, response is immediate, followed by locking the row ```DEBOUNCE``` milliseconds of no further input for that row. |
||||
For use in keyboards where refreshing ```NUM_KEYS``` 8-bit counters is computationally expensive / low scan rate, and fingers usually only hit one row at a time. This could be |
||||
appropriate for the ErgoDox models; the matrix is rotated 90°, and hence its "rows" are really columns, and each finger only hits a single "row" at a time in normal use. |
||||
* eager_pk - debouncing per key. On any state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key |
||||
* sym_g - debouncing per keyboard. On any state change, a global timer is set. When ```DEBOUNCE``` milliseconds of no changes has occured, all input changes are pushed. |
||||
* sym_pk - debouncing per key. On any state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occured on that key, the key status change is pushed. |
||||
|
||||
### Old names |
||||
The following old names for existing algorithms will continue to be supported, however it is recommended to use the new names instead. |
||||
|
||||
* sym_g - old name for sym_defer_g |
||||
* eager_pk - old name for sym_eager_pk |
||||
* sym_pk - old name for sym_defer_pk |
||||
* eager_pr - old name for sym_eager_pr |
||||
|
@ -0,0 +1,116 @@ |
||||
# LED Indicators |
||||
|
||||
QMK provides methods to read 5 of the LEDs defined in the HID spec: |
||||
|
||||
* Num Lock |
||||
* Caps Lock |
||||
* Scroll Lock |
||||
* Compose |
||||
* Kana |
||||
|
||||
There are three ways to get the lock LED state: |
||||
* by specifying configuration options within `config.h` |
||||
* by implementing `bool led_update_kb(led_t led_state)` or `_user(led_t led_state)`; or |
||||
* by calling `led_t host_keyboard_led_state()` |
||||
|
||||
!> `host_keyboard_led_state()` may already reflect a new value before `led_update_user()` is called. |
||||
|
||||
Two more deprecated functions exist that provide the LED state as a `uint8_t`: |
||||
|
||||
* `uint8_t led_set_kb(uint8_t usb_led)` and `_user(uint8_t usb_led)` |
||||
* `uint8_t host_keyboard_leds()` |
||||
|
||||
## Configuration Options |
||||
|
||||
To configure the indicators, `#define` these in your `config.h`: |
||||
|
||||
|Define |Default |Description | |
||||
|---------------------|-------------|-------------------------------------------| |
||||
|`LED_NUM_LOCK_PIN` |*Not defined*|The pin that controls the `Num Lock` LED | |
||||
|`LED_CAPS_LOCK_PIN` |*Not defined*|The pin that controls the `Caps Lock` LED | |
||||
|`LED_SCROLL_LOCK_PIN`|*Not defined*|The pin that controls the `Scroll Lock` LED| |
||||
|`LED_COMPOSE_PIN` |*Not defined*|The pin that controls the `Compose` LED | |
||||
|`LED_KANA_PIN` |*Not defined*|The pin that controls the `Kana` LED | |
||||
|`LED_PIN_ON_STATE` |`1` |The state of the indicator pins when the LED is "on" - `1` for high, `0` for low| |
||||
|
||||
Unless you are designing your own keyboard, you generally should not need to change the above config options. |
||||
|
||||
## `led_update_*()` |
||||
|
||||
When the configuration options do not provide enough flexibility, the API hooks provided allow custom control of the LED behavior. These functions will be called when the state of one of those 5 LEDs changes. It receives the LED state as a struct parameter. |
||||
|
||||
By convention, return `true` from `led_update_user()` to get the `led_update_kb()` hook to run its code, and |
||||
return `false` when you would prefer not to run the code in `led_update_kb()`. |
||||
|
||||
Some examples include: |
||||
|
||||
- overriding the LEDs to use them for something else like layer indication |
||||
- return `false` because you do not want the `_kb()` function to run, as it would override your layer behavior. |
||||
- play a sound when an LED turns on or off. |
||||
- return `true` because you want the `_kb` function to run, and this is in addition to the default LED behavior. |
||||
|
||||
?> Because the `led_set_*` functions return `void` instead of `bool`, they do not allow for overriding the keyboard LED control, and thus it's recommended to use `led_update_*` instead. |
||||
|
||||
### Example `led_update_kb()` Implementation |
||||
|
||||
```c |
||||
bool led_update_kb(led_t led_state) { |
||||
bool res = led_update_user(led_state); |
||||
if(res) { |
||||
// writePin sets the pin high for 1 and low for 0. |
||||
// In this example the pins are inverted, setting |
||||
// it low/0 turns it on, and high/1 turns the LED off. |
||||
// This behavior depends on whether the LED is between the pin |
||||
// and VCC or the pin and GND. |
||||
writePin(B0, !led_state.num_lock); |
||||
writePin(B1, !led_state.caps_lock); |
||||
writePin(B2, !led_state.scroll_lock); |
||||
writePin(B3, !led_state.compose); |
||||
writePin(B4, !led_state.kana); |
||||
} |
||||
return res; |
||||
} |
||||
``` |
||||
|
||||
### Example `led_update_user()` Implementation |
||||
|
||||
This incomplete example would play a sound if Caps Lock is turned on or off. It returns `true`, because you also want the LEDs to maintain their state. |
||||
|
||||
```c |
||||
#ifdef AUDIO_ENABLE |
||||
float caps_on[][2] = SONG(CAPS_LOCK_ON_SOUND); |
||||
float caps_off[][2] = SONG(CAPS_LOCK_OFF_SOUND); |
||||
#endif |
||||
|
||||
bool led_update_user(led_t led_state) { |
||||
#ifdef AUDIO_ENABLE |
||||
static uint8_t caps_state = 0; |
||||
if (caps_state != led_state.caps_lock) { |
||||
led_state.caps_lock ? PLAY_SONG(caps_on) : PLAY_SONG(caps_off); |
||||
caps_state = led_state.caps_lock; |
||||
} |
||||
#endif |
||||
return true; |
||||
} |
||||
``` |
||||
|
||||
### `led_update_*` Function Documentation |
||||
|
||||
* Keyboard/Revision: `bool led_update_kb(led_t led_state)` |
||||
* Keymap: `bool led_update_user(led_t led_state)` |
||||
|
||||
## `host_keyboard_led_state()` |
||||
|
||||
Call this function to get the last received LED state as a `led_t`. This is useful for reading the LED state outside `led_update_*`, e.g. in [`matrix_scan_user()`](#matrix-scanning-code). |
||||
|
||||
## Setting Physical LED State |
||||
|
||||
Some keyboard implementations provide convenience methods for setting the state of the physical LEDs. |
||||
|
||||
### Ergodox Boards |
||||
|
||||
The Ergodox implementations provide `ergodox_right_led_1`/`2`/`3_on`/`off()` to turn individual LEDs on or off, as well as `ergodox_right_led_on`/`off(uint8_t led)` to turn them on or off by their index. |
||||
|
||||
In addition, it is possible to specify the brightness level of all LEDs with `ergodox_led_all_set(uint8_t n)`; of individual LEDs with `ergodox_right_led_1`/`2`/`3_set(uint8_t n)`; or by index with `ergodox_right_led_set(uint8_t led, uint8_t n)`. |
||||
|
||||
Ergodox boards also define `LED_BRIGHTNESS_LO` for the lowest brightness and `LED_BRIGHTNESS_HI` for the highest brightness (which is the default). |
@ -0,0 +1,87 @@ |
||||
# Sequencer |
||||
|
||||
Since QMK has experimental support for MIDI, you can now turn your keyboard into a [step sequencer](https://en.wikipedia.org/wiki/Music_sequencer#Step_sequencers)! |
||||
|
||||
!> **IMPORTANT:** This feature is highly experimental, it has only been tested on a Planck EZ so far. Also, the scope will be limited to support the drum machine use-case to start with. |
||||
|
||||
## Enable the step sequencer |
||||
|
||||
Add the following line to your `rules.mk`: |
||||
|
||||
```make |
||||
SEQUENCER_ENABLE = yes |
||||
``` |
||||
|
||||
By default the sequencer has 16 steps, but you can override this setting in your `config.h`: |
||||
|
||||
```c |
||||
#define SEQUENCER_STEPS 32 |
||||
``` |
||||
|
||||
## Tracks |
||||
|
||||
You can program up to 8 independent tracks with the step sequencer. Select the tracks you want to edit, enable or disable some steps, and start the sequence! |
||||
|
||||
## Resolutions |
||||
|
||||
While the tempo defines the absolute speed at which the sequencer goes through the steps, the resolution defines the granularity of these steps (from coarser to finer). |
||||
|
||||
|Resolution |Description | |
||||
|---------- |----------- | |
||||
|`SQ_RES_2` |Every other beat | |
||||
|`SQ_RES_2T` |Every 1.5 beats | |
||||
|`SQ_RES_4` |Every beat | |
||||
|`SQ_RES_4T` |Three times per 2 beats| |
||||
|`SQ_RES_8` |Twice per beat | |
||||
|`SQ_RES_8T` |Three times per beat | |
||||
|`SQ_RES_16` |Four times per beat | |
||||
|`SQ_RES_16T` |Six times per beat | |
||||
|`SQ_RES_32` |Eight times per beat | |
||||
|
||||
## Keycodes |
||||
|
||||
|Keycode |Description | |
||||
|------- |----------- | |
||||
|`SQ_ON` |Start the step sequencer | |
||||
|`SQ_OFF` |Stop the step sequencer | |
||||
|`SQ_TOG` |Toggle the step sequencer playback | |
||||
|`SQ_SALL`|Enable all the steps | |
||||
|`SQ_SCLR`|Disable all the steps | |
||||
|`SQ_S(n)`|Toggle the step `n` | |
||||
|`SQ_TMPD`|Decrease the tempo | |
||||
|`SQ_TMPU`|Increase the tempo | |
||||
|`SQ_R(n)`|Set the resolution to n | |
||||
|`SQ_RESD`|Change to the slower resolution | |
||||
|`SQ_RESU`|Change to the faster resolution | |
||||
|`SQ_T(n)`|Set `n` as the only active track or deactivate all | |
||||
|
||||
## Functions |
||||
|
||||
|Function |Description | |
||||
|-------- |----------- | |
||||
|`bool is_sequencer_on(void);` |Return whether the sequencer is playing | |
||||
|`void sequencer_toggle(void);` |Toggle the step sequencer playback | |
||||
|`void sequencer_on(void);` |Start the step sequencer | |
||||
|`void sequencer_off(void);` |Stop the step sequencer | |
||||
|`bool is_sequencer_step_on(uint8_t step);` |Return whether the step is currently enabled | |
||||
|`void sequencer_set_step(uint8_t step, bool value);` |Enable or disable the step | |
||||
|`void sequencer_set_step_on();` |Enable the step | |
||||
|`void sequencer_set_step_off();` |Disable the step | |
||||
|`void sequencer_toggle_step(uint8_t step);` |Toggle the step | |
||||
|`void sequencer_set_all_steps(bool value);` |Enable or disable all the steps | |
||||
|`void sequencer_set_all_steps_on();` |Enable all the steps | |
||||
|`void sequencer_set_all_steps_off();` |Disable all the steps | |
||||
|`uint8_t sequencer_get_tempo(void);` |Return the current tempo | |
||||
|`void sequencer_set_tempo(uint8_t tempo);` |Set the tempo to `tempo` (between 1 and 255) | |
||||
|`void sequencer_increase_tempo(void);` |Increase the tempo | |
||||
|`void sequencer_decrease_tempo(void);` |Decrease the tempo | |
||||
|`sequencer_resolution_t sequencer_get_resolution(void);` |Return the current resolution | |
||||
|`void sequencer_set_resolution(sequencer_resolution_t resolution);` |Set the resolution to `resolution` | |
||||
|`void sequencer_increase_resolution(void);` |Change to the faster resolution | |
||||
|`void sequencer_decrease_resolution(void);` |Change to the slower resolution | |
||||
|`bool is_sequencer_track_active(uint8_t track);` |Return whether the track is active | |
||||
|`void sequencer_set_track_activation(uint8_t track, bool value);` |Activate or deactivate the `track` | |
||||
|`void sequencer_toggle_track_activation(uint8_t track);` |Toggle the `track` | |
||||
|`void sequencer_activate_track(uint8_t track);` |Activate the `track` | |
||||
|`void sequencer_deactivate_track(uint8_t track);` |Deactivate the `track` | |
||||
|`void sequencer_toggle_single_active_track(uint8_t track);` |Set `track` as the only active track or deactivate all | |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue