* fmh.h: add matrix diagram
* info.json: apply friendly formatting
* physically arrange LAYOUT_all macro
Move position `K5D` (right half of Split Backspace) to the end of the top row.
* rename LAYOUT_all to LAYOUT_60_tsangan_hhkb
* add LAYOUT_60_ansi_tsangan
* add LAYOUT_60_hhkb
* add LAYOUT_60_ansi_wkl
* add LAYOUT_60_ansi_wkl_split_bs_rshift
* enable Community Layouts support
* Discourage use of ENCODER_MAP at keyboard level
* Update docs/feature_encoders.md
Co-authored-by: Ryan <fauxpark@gmail.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
* Add an ez_maker directpins for rp2040
This allows all exposed pins on the Raspberry Pi Pico to be used
as up to 26 individual keys. Keys use a common ground arrangement.
The firmware is also expected to work on generic RP2040 boards, check
manufacturer pinout diagrams or use trial and error to find out the GP#s
of the pins.
* Update keyboards/ez_maker/directpins/rp2040/info.json
Co-authored-by: Joel Challis <git@zvecr.com>
* Changes based on review comments
Co-authored-by: Joel Challis <git@zvecr.com>
* shell.nix: Update `tomlkit` to 0.11.4 using a Nixpkgs overlay
The used Nixpkgs snapshot contains `tomlkit` version 0.7.0, which is
affected by https://www.github.com/sdispater/tomlkit/issues/148; that
bug is triggered by `pyproject.toml` from `jsonschema` >= 4.11.0,
preventing the build of that module.
Just adding `tomlkit = "*"` to the `[tool.poetry.dev-dependencies]`
section of `nix/pyproject.toml` does not fix the `jsonschema` build,
because `makeRemoveSpecialDependenciesHook` inside `poetry2nix` is not
affected by `nix/pyproject.toml`. Add a Nixpkgs overlay which updates
the `tomlkit` Python module globally, so that `poetry2nix` would also
use the updated version internally.
* shell.nix: Bump `poetry2nix` to the most recent version
The new `poetry2nix` version includes overrides which are required for
recent versions of some Python packages (in particular, `jsonschema` and
`dotty-dict`).
* shell.nix: Bump QMK CLI to 1.1.1; update other Python deps
Update `pyproject.toml` to match `requirements*.txt`:
- add `pyserial = "*"`
- replace `qmk-dotty-dict = "*"` with `dotty-dict = "*"` (#18117, also
required for compatibility with `qmk` 1.1.1, where this replacement
had already been performed)
Add build dependencies of various Python modules to `pyproject.toml`:
- `hatchling`, `hatch-vcs`, `hatch-fancy-pypi-readme` (required by
`jsonschema` >= 4.11.0)
- `pytest` (a newer version is required to solve the dependency conflict
with the `hatchling` module due to the upper bound on `pluggy`)
- `flit-core` (a more recent version is required to build `tomli`)
- `poetry-core` (required for `dotty-dict` >= 1.3.1, and the version
from Nixpkgs does not build on Darwin due to NixOS/nix#4758)
Update `poetry.lock` to use the most recent versions of Python modules.
The complete list of Python module updates as listed in `poetry.lock`
(note that other modules might be present in the Python environment,
e.g., if they come from Nixpkgs):
- `atomicwrites`: none -> 1.4.1 (but this module is not actually used,
because the corresponding dependency of `pytest` is win32-only)
- `attrs`: 21.4.0 -> 22.1.0
- `colorama`: 0.4.4 -> 0.4.5
- `coverage`: 6.4 -> none
- `dotty-dict`: none -> 1.3.1 (used instead of `qmk-dotty-dict`)
- `editables`: none -> 0.3
- `flake8`: 4.0.1 -> 5.0.4
- `flake8-polyfill`: 1.0.2 -> none
- `flit-core`: none -> 3.7.1
- `hatch-fancy-pypi-readme`: none -> 22.3.0
- `hatch-vcs`: none -> 0.2.0
- `hatchling`: none -> 1.8.0
- `hjson`: 3.0.2 -> 3.1.0
- `importlib-resources`: 5.7.1 -> 5.9.0
- `iniconfig`: none -> 1.1.1
- `jsonschema`: 4.5.1 -> 4.14.0
- `mccabe`: 0.6.1 -> 0.7.0
- `nose2`: 0.11.0 -> 0.12.0
- `packaging`: none -> 21.3
- `pathspec`: none -> 0.9.0
- `pep8-naming`: 0.12.1 -> 0.13.2
- `pillow`: 9.1.1 -> 9.2.0
- `pkgutil-resolve-name`: none -> 1.3.10
- `pluggy`: none -> 1.0.0
- `poetry-core`: none -> 1.0.8
- `py`: none -> 1.11.0
- `pycodestyle`: 2.8.0 -> 2.9.1
- `pyflakes`: 2.4.0 -> 2.5.0
- `pygments`: 2.12.0 -> 2.13.0
- `pyparsing`: none -> 3.0.9
- `pyserial`: none -> 3.5
- `pytest`: none -> 7.1.2
- `qmk`: 1.1.0 -> 1.1.1
- `qmk-dotty-dict`: 1.3.0.post1 -> none (replaced by `dotty-dict`)
- `setuptools-scm`: none -> 7.0.5
- `tomli`: none -> 2.0.1
- `typing-extensions`: none -> 4.3.0
- `zipp`: 3.8.0 -> 3.8.1
break statements are missing from the switch for both registering and unregistering key codes. Neither have a default: case either. The code as exists in the repository right now does not compile. It does with this changes.
* Fix Caps Word to treat mod-taps more consistently.
Previously, holding any mod-tap key while Caps Word is active stops Caps
Word, and this happens regardless of `caps_word_press_user()`. Yet for
regular mod keys, AltGr (KC_RALT) is ignored, Shift keys are passed to
`caps_word_press_user()` to determine whether to continue, and
similarly, a key `RSFT(KC_RALT)` representing Right Shift + Alt is
passed to `caps_word_press_user()` to determine whether to continue.
This commit makes held mod-tap keys consistent with regular mod keys:
* Holding a `RALT_T` mod-tap is ignored.
* When holding a shift mod-tap key, `KC_LSFT` or `KC_RSFT` is passed to
`caps_word_press_user()` to determine whether to continue.
* When holding a Right Shift + Alt (`RSA_T`) mod-tap, `RSFT(KC_RALT)` is
passed to `caps_word_press_user()`.
Particularly, with this fix a user may choose to continue Caps Word when
a shift mod-tap key is held by adding `KC_LSFT` and `KC_RSFT` cases in
`caps_word_press_user()`. For instance as
```
bool caps_word_press_user(uint16_t keycode) {
switch (keycode) {
// Keycodes that continue Caps Word, with shift applied.
case KC_A ... KC_Z:
case KC_MINS:
add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to the next key.
return true;
// Keycodes that continue Caps Word, without shifting.
case KC_1 ... KC_0:
case KC_BSPC:
case KC_DEL:
case KC_UNDS:
case KC_LSFT: // <<< Added here.
case KC_RSFT:
return true;
default:
return false; // Deactivate Caps Word.
}
}
```
* Fix Caps Word to treat mod-taps more consistently.
Previously, holding any mod-tap key while Caps Word is active stops Caps
Word, and this happens regardless of `caps_word_press_user()`. Yet for
regular mod keys, AltGr (KC_RALT) is ignored, Shift keys are passed to
`caps_word_press_user()` to determine whether to continue, and
similarly, a key `RSFT(KC_RALT)` representing Right Shift + Alt is
passed to `caps_word_press_user()` to determine whether to continue.
This commit makes held mod-tap keys consistent with regular mod keys:
* Holding a `RALT_T` mod-tap is ignored.
* When holding a shift mod-tap key, `KC_LSFT` or `KC_RSFT` is passed to
`caps_word_press_user()` to determine whether to continue.
* When holding a Right Shift + Alt (`RSA_T`) mod-tap, `RSFT(KC_RALT)` is
passed to `caps_word_press_user()`.
Particularly, with this fix a user may choose to continue Caps Word when
a shift mod-tap key is held by adding `KC_LSFT` and `KC_RSFT` cases in
`caps_word_press_user()`. For instance as
```
bool caps_word_press_user(uint16_t keycode) {
switch (keycode) {
// Keycodes that continue Caps Word, with shift applied.
case KC_A ... KC_Z:
case KC_MINS:
add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to the next key.
return true;
// Keycodes that continue Caps Word, without shifting.
case KC_1 ... KC_0:
case KC_BSPC:
case KC_DEL:
case KC_UNDS:
case KC_LSFT: // <<< Added here.
case KC_RSFT:
return true;
default:
return false; // Deactivate Caps Word.
}
}
```
* Update quantum/process_keycode/process_caps_word.c
Co-authored-by: Joel Challis <git@zvecr.com>
* [Keymap] adding new user (p4yne) layout with complex lighting features (per layer, per key, per type) and usefull layers DE/US, etc.
Co-authored-by: Drashna Jaelre <drashna@live.com>
* SPLIT_USB_DETECT added.
* lednotg keymap added.
* lednotg missing modification fixed.
* VERSION is available.
* USER00 is used instead of SAFE_RANGE in via/keymap.c
* Working on new dactyl
* Preliminary build and keymap in place for 4x5_5 dactyl manuform
* Removing first attempt to use 4x5
* Updating to match c style guide
* Fixing issues after merge, deletion of dactyl_manuform.h
* Spliting out custom keymap
* Adding license headers
* Fixing EE_HANDS detection on Pro-Micro
The pro-micro was not working when I plugged into the elite-c on the
right hand side of my keyboard. Adding the SPLIT_USB_DIRECT definition
fixed the issue.
* Apply suggestions from code review
Adding Drashna's delete comments
Co-authored-by: Drashna Jaelre <drashna@live.com>
* Removed config.h for keymaps and tweaked keymap
Per Drashna's pr review, I have removed the config.h files for the
keymaps.
Also tweaked my keymap to switch backspace and enter. Added tapping
toggle for RAISE.
* Further tweaking ssedrick keymap for dactyl_manuform 4x5_5
As with most new keyboards, they take some getting used to.
I've rearranged my thumb cluster to hopfully a more long
term solution.
* Adding missing KC_BSLS to ssedrick keymap for 4x5_5
Co-authored-by: Drashna Jaelre <drashna@live.com>
* 46: Copy from 52 and file rename
* 46: File internals refer to 46, not 52
* 46: Board remove row
* 46: Keymap: Lshift becomes ctrl, Rshift a symbol
- ESC and CAPs on upper thumbs
- AltGr and App on upper thumbs
- Page up/down on upper thumbs
- F11, F12 and mods for them on adjust
* 46: Readme update for json script, tweaks
* 46: Board fix LED count
* 46: Keymap: Arrows right, symmetric layer keys
* 46: Readme: Image link with and w/o outer pinkie
* 46: Keymap: link fixed image of nav layer
* 46: Keymap: fix reaching adj layer
Co-authored-by: mmccoyd <mmccoyd@cs.berkley.edu>
* Fixed Left Shift tapdance in general and for gaming mode. (#12)
* update ISO readme
* left shift fixed in general, including for gaming mode
* fixed toggle menu rendering on ISO layouts
* updated readme's and cosmetics
* update readme's
* update readme's again
* readme cosmetics
* consolidate readme's
* more readme cosmetics
* clarification for bootloader mode on ISO
* Autocorrect added with 400 word English dictionary (#13)
* autocorrect added with 400 word dictionary
* update readme's for autocorrect
* Add FN-B as shortcut to bootloader
* Update .gitignore
Co-authored-by: Joel Challis <git@zvecr.com>
* RGB changes to system numlock and ISO extended alphas
- hide system numlock off indicator (primarily for Mac users) by moving it to numpad and FN layers instead
- give users with extended alpha ISO languages a config option to add RGB highlights for extras alphas on capslock
* readme updates
* Fixed [FN]B and [FN]N shortcuts not working on numpad layer
Co-authored-by: Joel Challis <git@zvecr.com>
* 52 Keymap.json: Set for Hillside 52
- Change script rows
* 52 Keymap.c: mirror .json
CAPSWORD, QK_BOOT, readme cleanup, EE_RST
* 52 Keymap.json: Initial files copy from 56
* 52 Keymap.json nav/edit lay, thumb shift, syms
- Del in backspace spot on sym layer
- Thumb shift OSM instead of extra space
- Nav/edit on num/fn: arrows cut copy paste undo redo, page up/down
- Fn keys bottom row to allow nav edit keys
- App and AltGr on lower row, on their layer
- Braces on index, so more common -= on middle ring.
- Adjust has Ctrl/GUI swap
- EE_RST, CAPSWORD, QK_BOOT, SPLIT_DETECT
* 52 Family: readme image and folder link
* 52 Board: initial copy from 56
* 52 Keymap via
* 52 Board: remove keys, cant columns, better ids
- .json: vid: MM, pid: H52
* 52 Keymap.c: initial.c copy from 48
* QK_BOOT EE_CLR, not ANY(), as config.qmk supports
- CAPSWRD instead of ANY, though config.qmk still converts to ANY()
* Cleanup readme
* 52 Keymap: Remove redundant key, cleanup script
* 52 Keymap: Fix template
* 52 Readme: Link lower res image better for readme
Co-authored-by: Drashna Jaelre <drashna@live.com>
* 52 Keymap: Move pretty-print script to GitHub wiki
* 52 Keymap: Link to 1024 res image thumbnails
* 52 Keymap: fix whitespace before image link
* Family: Fix image link to 1024 thumb
Co-authored-by: Drashna Jaelre <drashna@live.com>
* 52: Keymap: Caps word on a layer home row
* 52: Keymap: Arrows on right. Symmetric layer keys.
- Nav:
- Arrows on right so up/down more intuitive. Page up/down on ends
- Cut on home row, as more common
- Sym:
- Layer mods on activate hand, extras symbols on left
- Common digits on lower row
- Base:
- Layer keys symmetric, on most extended, not resting, thumb
- Mute on util key for easy use
- Swap layers 3 and 4 to match swapped thumbs
Co-authored-by: mmccoyd <mmccoyd@cs.berkley.edu>
Co-authored-by: Drashna Jaelre <drashna@live.com>
Unfortunately, the crippled versions of “Bluepill” boards with
STM32F103C6xx chips instead of STM32F103C8xx are now sold all over the
place, sometimes advertised in a confusing way to make the difference
not noticeable until too late. Add minimal support for these MCUs in
the common “Bluepill with stm32duino” configuration, so that it could be
possible to make something useful from those boards (although fitting
QMK into the available 24 KiB of flash may be rather hard).
(In fact, I'm not sure whether the “STM32” part of the chip name is
actually correct for those boards of uncertain origin, so the onekey
board name is `bluepill_f103c6`; another reason for that name is to
match the existing `blackpill_f401` and `blackpill_f411`.)
The EEPROM emulation support is not included on purpose, because
enabling it without having a working firmware size check would be
irresponsible with such flash size (the chance that someone would build
a firmware where the EEPROM backing store ends up overlapping some
firmware code is really high). Other than that, enabling the EEPROM
emulation code is mostly trivial (the `wear_leveling` driver with the
`embedded_flash` backing store even works without any custom
configuration, although its code is significantly larger than the
`vendor` driver, which may also be important for such flash size).
* Initial commit
* testing modes
* working on puckbuddy firmware. This is all working for now but need to clean it up and personalize it.
* needs to be updated from vial build
* prepping for PR
* added rgb mode cycling to fn1 since it isn't on the encoder for these maps
* readme written in preparation for pr
* reverting driver print line
* Removed old reference to OBE in the readme from copypaste error
* applying changes based on review
* applying changes from review
* Update keyboards/mechwild/puckbuddy/puckbuddy.c
* trailing whitespaces removed
* added clear screen condition for switching back to name rendering
* Added uf2 keymap and fixed display glitch for the logo render art.
* Removed extra definition of FEE_PAGE_BASE_ADDRESS
* Removed the uf2 keymap and made it automatic when selecting bootloader instead
* Fixed the bad bootloader check
* moved the uf2 check from rules.mk to post_rules.mk to satisfy lint
* changing it back to stm32-dfu bootloader default
* Fixed RGBLIGHT enable oversight.
* Added persistent dynamic tapping configuration for the cirque touchpad tap term
* new lines at end of files for formatting and diff sanity
* changing default bootloader back to stm32-dfu
* Had to completely redefine the tap keycodes instead of using the DT_UP and DT_DOWN keycodes because I was not able to specify them easily in the via/vial configs and this allows me to keep the original functionality instead of tying it to eeprom like these are.
* Added tap toggling keycodes to quick enable and disable the tapping term
* working out an issue where the tap status keeps turning to off on power cycle
* correcting submodule garbo
* Fixed display issue and rewrote TAP config approach to make it a little easier to control
* removing backup puckbuddy.c code
* Added some comment, removed some commented out old code, removed trailing whitespace
* Changed to handle tinyuf2 by expecting emulated eeprom so that adding other forms of eeprom can be handled for the memory offset separately, and added user oled conditional inside the keyboard oled code block
* Updated default keymaps to have the tap and dpi keys on by default
* Apply suggestions from code review
* Apply suggestions from code review
* Reverted to most usable configuration for RDP usage.
* Added some HSV color definitions without the value portion to allow using the existing value.
* Switched to using HSV and HS color definitions.
* Added media keys to the convenience layer.
* Updated make rules to enable media keys.
* Cleaned up planck make rules.
* boardsource/the_mark: add QMK Configurator layout data
* add keyboard maintainers to info.json
Adds the individual and organization accounts as listed maintainers.
* skergo.h: use ___ for KC_NO
* skergo.h: use 3-character notation
* skergo.h: add matrix diagram
* add LAYOUT_all macro
* update grid alignment of LAYOUT macro and keymaps
* refactor keymaps
Refactor keymaps to use the `LAYOUT_all` macro. Converts tabs to spaces.
This change necessitates the following changes to keymaps:
- The keycodes for Page Up, Page Down, and End each move up one row - all as the last keys on their new rows.
- The keycode for the secondary B key moves up one row, inserted between the primary (left side) B and the N.
* remove LAYOUT macro
* rename LAYOUT_all macro to LAYOUT_split_bs
* add LAYOUT_2u_bs macro
* readme.md: add flashing example
* info.json: correct maintainer value
Update to reference maintainer's GitHub username.
* Fix typo for POINTING_DEVICE_GESTURES_SCROLL_ENABLE
Follow the name written in documentation which follows
POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
* Reword the blurb about POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE in docs
* info.json: apply friendly formatting
* info.json: correct layout data
Fix the size and position of the Backslash key.
* readme.md: touch-up formatting
* readme.md: switch Bootloader and Docs sections
* correct keyboard maintainer
* kbdfans/bounce/75/hotswap: keymap readability fix
Update grid alignment to disambiguate which keycodes correspond in different layers.
----
Layer 0 had 13 and 9 keycodes on the bottom two rows respectively, while Layers 1-3 had 14 and 8.
* kbdfans/bounce/75/soldered: keymap readability fix
Update grid alignment to disambiguate which keycodes correspond in different layers.
----
Layer 0 had 14 and 9 keycodes on the bottom two rows respectively, while Layers 1-3 had 15 and 8.
* kbdfans/bounce/75/soldered: fix layer index in keymaps
Layer indexes were 0,1,2,1 instead of 0,1,2,3.
* Start of dz65v2 map for sbennett13
* No wpm, disable some rgb, ~copyright~
* No more raindrops
* Remove more rgb modes and set default
* Almost orgot this crappy thing
* cannot define startup :(
* Layered esc is kc_grv
* Start of dz65v2 map for sbennett13
* No wpm, disable some rgb, ~copyright~
* No more raindrops
* Remove more rgb modes and set default
* Almost orgot this crappy thing
* cannot define startup :(
* Layered esc is kc_grv
* Add license to config and keymap
From the ChibiOS HAL I2C driver pages:
After a timeout the driver must be stopped and restarted because the bus is in
an uncertain state.
This commit does that stopping explicitly on any error that occurred, not only
timeouts. As all the i2c functions restart the peripheral if necessary it is
safe to do so.
Co-authored-by: Dasky <32983009+daskygit@users.noreply.github.com>
Co-authored-by: Dasky <32983009+daskygit@users.noreply.github.com>
Static x & y should be the same type as touchData.xValue &
touchData.yValue: uint16_t.
Their delta could be larger than int8_t and should be constrained to
mouse_xy_report_t.
* skjoldr.h: use ___ for KC_NO
* skjoldr.h: use K<row><column> notation
Matrix was previously defined using identifiers in the format of K<column><row>.
* skjoldr.h: add matrix diagram
* info.json: apply friendly formatting
- key legends as labels
- correct key sizes and positioning
* refactor keymaps
Refactors the `default` and `via` keymaps.
- use QMK-native keycode aliases
- grid-align keycodes for readability
* rename LAYOUT macro to LAYOUT_60_ansi_arrow
* enable Community Layout support
* info.json: correct maintainer value
Field is meant to reference the maintainer's GitHub username.
* bastardkb: restructure folder hierarchy ahead of supporting other adapters/mcus
Upcoming support for the following (adapter, mcu) pairs will be
submitted in follow-up PRs:
- `v2/elitec`
- `v2/stemcell`
- `blackpill`
This PR contains the following changes:
- Move previous implementation to an inner `v1/elitec` folder
- Move keyboard USB IDs and strings to data driven
- Update headers to update maintainers list
- Run `qmk format-c`
* bastardkb/charybdis: remove broken acceleration implementation
* bastardkb/charybdis: fix debug output
* bastardkb: add support for BastardKb the `v2/elitec` (adapter, mcu) pair
* bastardkb: add Blackpill support
* bastardkb/charybdis/3x5: add `bstiq` keymap
* bastardkb/charybdis: add fake LEDs to the configuration
For the Charybdis 3x5 (respectively 4x6), the LED config now simulates
36 (respectively 58) LEDs instead of the actual 35 (respectively 56) to
prevent confusion when testing LEDs during assembly when handedness is
not set correctly. Those fake LEDs are bound to the physical
bottom-left corner.
* bastardkbk/charybdis/readme.md: update build commands
Merge pull request #5 from Nathancooke7/update_charybdis_readme_v2_shield.
* bastardkb/charybdis: fix Via keymap with blackpill
* bastardkb/charybdis: add 3x6 configuration
* bastardkb/charybdis: remove unnecessary files
* bastardkb/charybdis: remove obsolete code
* bastardkb/charybdis/3x6: add Via keymap
* bastardkb: add support for Splinky (RP2040) board
* bastardkb: initial configuration for the Splinky (SPI not working yet)
* bastardkb/charybdis/3x5/v2/splinky: tentative change to enable trackball
* bastardkb/charybdis/3x5/v2/splinky: fix SCK, MISO, MOSI pins
* bastardkb/charybdis/3x5/v2/splinky: fix SCK, MISO, MOSI pins
* bastardkb/charybdis/4x6/v2/splinky: add SPI configuration and enable trackball
* bastardkb/charybdis/3x6: add splinky config
* bastardkb/*/v2/splinky: update drivers to `vendor`
* bastardkb/dilemma: add new board
* bastardkb/charybdis: fix infinite loop in `layer_state_set_user(…)` in the `via` keymaps
* bastardkb/dilemma: add `bstiq` keymap
* bastardkb: specify blackpill boards
* bastardkb/charybdis: fix blackpill-specific define syntax
* bastardkb: remove `NO_ACTION_MACRO` and `NO_ACTION_FUNCTION` which are no longer valid options
* bastardkb: fix `QK_BOOT` keycodes
* bastardkb/dilemma: fix mouse direction on X axis
* bastardkb/charybdis/3x6: adjust CS
* bastardkb/dilemma: adjust trackpad configuration
* charybdis: fix `PWM33XX_CS_PIN` defines
This is a follow-up of https://github.com/qmk/qmk_firmware/pull/17613.
* bastardkb: remove Vial mentions from `bstiq` keymaps
* Cleanup unnecessary comments
Co-authored-by: Nathan <nathan.cooke@compass.com>
Co-authored-by: Charly Delay <0xcharly@codesink.dev>
* sinanju.h: add matrix diagram
* add LAYOUT_60_ansi_wkl_split_bs_rshift macro
Same matrix as `LAYOUT_all`, but with position K2D (right half of split Backspace) moved to the end of the top row.
* refactor keymaps
- use `LAYOUT_60_ansi_wkl_split_bs_rshift` macro instead of `LAYOUT_all`
- polish four-space indent
- update grid alignment
- replace `RESET` keycode with `QK_BOOT`
* remove now-unused LAYOUT_all macro
* add LAYOUT_60_ansi_wkl macro with keymap
Add a layout with 2u Backspace and 2.75u right Shift.
* info.json: correct maintainer value
* Initial Apollo87H support
* Define RGB animations and default animation
* Add proper per-key RGB support
* Adjust LED positions
* Separate delta-gamma
* Fine-tune LED positions
* fix up GAMMA revision
* fix up tabs indentation to spaces indentation
* Fixed positioning and CS-SW defs for some LEDs
* Fix INS RGB position
* Fine-tune LED positions, fix default RGB
* Update readme's
* Rename LAYOUT_87H to lowercase 87h
* Formatting gamma's rules.mk
* Formatting delta's rules.mk
* Use smaller readme image
* Use smaller README image
* First support for 87H-T-SC and 88H-T-SC
* Update README
* Fix layout naming
* Remove
* Remove EEPROM definitions, fix missing RGB LED mod/alpha definer
* Add suggestions from noroadsleft
* chiffre refactor for new revisions
* updated led matrix config
* updated per suggestions
* add tapdance enable
* revert tapdance (none defined in the default keymaps)
* clean up rules
* add readme for HE
* remove notes in readme
* fix perm
* fix perms
* Fix spacing on readme
* fix perm
* fix perms again?
Python will evaluate first the left and then the right side of the and operator.
The left side would previously return True based on the truthiness logic that treats any non-emptry string as true.
It would not check if the desired keymap exists.
If the left side is true it will evaluate the right side which will check for the existance of a specific keymap.
With this change the check for existance of two keymaps is implemented.
* Added autoclicker, better mouse, vim like FN layer and more.
* Updated docs to comply with guidelines
* Fixed Imgur links
* increased step sizes
* updated readme to reflect step size
* Added second delay array for autoclicker to compensate for RGB animation CPU loads
* better RGB effects and updated docs
* better README.md formatting
* added DEBONCE libinput workaround for Linux
* fixed formatting
* fixed typos and clarified
* fixed layer picture order
* Update keyboards/dztech/dz65rgb/keymaps/yuannan/keymap.c
Co-authored-by: Drashna Jaelre <drashna@live.com>
* Update keyboards/dztech/dz65rgb/keymaps/yuannan/README.md
Co-authored-by: Drashna Jaelre <drashna@live.com>
* Updated Docs and rules
* Updated with the new deferred exec API to ensure more consistant CPS
* renamed README.md to be lower case to comply with fauxpark's request
* Remapped alt to be left instead of right for compatibility reasons
* Update keyboards/dztech/dz65rgb/keymaps/yuannan/config.h
Co-authored-by: Drashna Jaelre <drashna@live.com>
Co-authored-by: Drashna Jaelre <drashna@live.com>
Move Pointing Device Initialization to after Split Post Initialization
If both pointing device and split is enabled, the pointing device init needs to be called after the split post init, otherwise the connection (serial/etc) isn't initialized yet, and any commands that need to send data over (such as calling the set cpi command) never get sent over.
* added files for EVO70
* updated info.json and readme
* ran qmk lint and fixed typo in info.json
* removed defines from config.h in favor of info.json
* removed an unnecssary include
* removed unnecessary code
* updated rules.mk to remove mention of Bluetooth
* corrected edit to rules.mk
* added code for OLED menu display
* removed extraneous comments and spaces
* added bongo cat animation
* Update keyboards/custommk/evo70/rules.mk
* Update keyboards/custommk/evo70/config.h
* Modified Bongocat graphics to match original proportions
* updated info.json device version
* updated OLED splash screen display timing
* improved bongo cat tap detection and added backlight breathing to OLED menu
* various improvements to OLED, saving settings, and VIA keymap fix
* removed extraneous define
* custom encoder assignment retained upon powerup, backlight sleep upon suspend
* corrected bongo cat tap detection
* Changed splash screen and bongo cat encoder rotation to use the custom assignments
* removed _default from LAYOUT naming and changed keyboard image to be hosted from imgur
* Force smaller version of image to be used in readme
The `poetry` package from the used Nixpkgs snapshot triggers the regex
compatibility issue in Nix >= 2.10.0 binaries for `x86_64-darwin`:
https://www.github.com/NixOS/nix/issues/4758
Remove the `poetry` package from the Nix shell environment for now
(it is not really required to compile QMK, only to develop the Nix shell
environment itself).
In addition, all `poetry` version earlier than 1.1.14 became effectively
non-functional after a breaking change of the PyPI JSON API:
https://www.github.com/python-poetry/poetry/pull/5973
Updating the `poetry` package is not trivial (just adding it it to
`pyproject.toml` does not work due to dependency version conflicts with
other modules), therefore removing it seems to be the easiest solution
to restore compatibility with new Nix versions while not creating any
major inconvenience for QMK users.
* allowing the kt60 file to be modified so I can do things while waiting for it to be fixed upstream
* initial commit for mokulua keyboard
* Split the board into mirrored and standard layouts.
* Prepping for PR. Silly keymap added.
* prepped for PR
* Apply suggestions from code review
* Fixing firmware from the refactor that removed the mirrored layout.
* Small tweaks using changes from refactor
* Changed the name of the layouts back to match the original to resolve conflict in info.json
* these files needed to be removed as well, they were added as a part of the refactor
* info.json moveds to be different for each build
* Another file had to be removed and the mirrored.c file changed to call mirrored.h instead of standard.h
* fixing chibios ver
* force deleting to revert
* fixing chibios shit
* Update keyboards/mechwild/mokulua/mirrored/mirrored.c
* Update keyboards/mechwild/mokulua/standard/standard.c
* Removing tabs and replacing with 4 spaces. Small style and formatting changes.
* Adding chocV keyboard
* Fix checklist issues / community layout support
* Remove template cruft from readme
* Fix image url in readme
* Fix image url in readme to raw github content
* Change readme example to use default Keymap
* Remove vestigal config
* More informative keymap readme
* Config.h swapsies
* Remove deprecated features
* Conform / Modernize Rules
* Conform / Modernize Rules
* Clean up spacing
* Update keyboards/chocv/readme.md
Move build docs links to end 👍
* Add correct hand_swap_config matrix for planck_rev6 and planck_rev6_drop
* Make sure indentations are consistent
* Make the rev6 hand_swap_config matrix the default, also correct for ez.
* Move hand_swap_config matrix from planck.c to revision subdirectories
* crkbd:thunderbird2086
* readme
* after code review
* coding format
* minor change
* changed file name
* correct image
* updated readme
* using query to get rgb status
* minor update
* feat(keebwerk): added VIA support keymap for keebwerk nano slider
Added VIA support for keebwerk nano slider, VIA json is keebwerk_nano_via.json
Fixed midi2vol keymap where comma symbol is missing from enum "custom_layers"
* feat(keebwerk): removed VIA json as requested
* Update keyboards/keebwerk/nano_slider/keymaps/via/keymap.c
* Update keyboards/keebwerk/nano_slider/keymaps/via/keymap.c
* Fix(PR): removed file as requested
* solanis.h: add matrix diagram
* refactor keymaps: apply grid alignment
* refactor LAYOUT_all macro
Moves the matrix position identifier for the right half of Split Backspace to the number row.
* added new layout for keebio/iris
* Update keyboards/keebio/iris/keymaps/emp/config.h
* Update keyboards/keebio/iris/keymaps/emp/keymap.c
Replace #defines with enum
* Update keyboards/keebio/iris/keymaps/emp/keymap.c
Made requested changes about formatting and the license.
* Update config.h
Cleaned up formatting
* Update keyboards/keebio/iris/keymaps/emp/keymap.c
Small changes to improve readability:
* changed whitespace in license
* added more whitespace around if/else blocks
* fixed bracket style in places
* [Keyboard] Add Chocofly v1
* PR Feedback
* Small change to keymap.
* Replace KC__VOLUP and KC__VOLDOWN with single underscore version.
* Apply suggestions from code review
* Required for my PC
* Required for my PC
* Nayeon Community Layout support
- macro `LAYOUT_ansi` renamed to `LAYOUT_tkl_f13_ansi_tsangan`
- macro `LAYOUT_iso` renamed to `LAYOUT_tkl_f13_iso_tsangan`
- Community Layout support enabled in `rules.mk`
* add LAYOUT_tkl_f13_ansi_tsangan_split_bs_rshift
* add LAYOUT_tkl_f13_iso_tsangan_split_bs_rshift
* info.json: update maintainer field
Field is meant to reference the GitHub username of the maintainer.
* PMW33XX drivers overhaul
This combines the PMW3389 and PM3360 drivers as they only differ in the
firmware blobs and CPI get and set functions. The following changes have
been made:
* PMW3389 now gets the same multi-sensor feature that is already available on the
PMW3360.
* Introduced a shared pmw33xx_report_t struct is now directly readable via SPI
transactions instead of individual byte-sized reads, saving multiple
copies and bitshift operations.
* pmw33(89/60)_get_report functions had unreachable branches in their motion
detection logic these have been simplied as much as possible.
* The fast firmware upload option has been removed as this becomes obsolete by
the newly introduced polled waiting functions for ChibiOS polled waiting
* PMW33(60/89)_SPI_LSBFIRST and PMW33(60/89)_SPI_MODE config options
have been removed as they don't need to be configurable.
* All PMW3389 and PMW3360 defines have been unified to a PMW33XX prefix
to reduce code duplication and make the defines interchangeable
* Adjust keyboards to PMW33XX naming scheme
* bm80v2_iso.h: convert tabs to spaces
* bm80v2_iso.h: use ___ for KC_NO
* bm80v2_iso.h: use QMK 3-character notation
* refactor macro for tkl_iso Community Layout compatibility
- move the matrix position identifier for Enter to the home row
* info.json: correct layout data
* rules.mk: tidy-up formatting
* readme.md: tidy-up formatting
* update maintainer; re-assign copyright
* assign ISO-appropriate keycodes in keymaps
* allowing the kt60 file to be modified so I can do things while waiting for it to be fixed upstream
* Initial commit
* testing modes
* working on puckbuddy firmware. This is all working for now but need to clean it up and personalize it.
* needs to be updated from vial build
* prepping for PR
* added rgb mode cycling to fn1 since it isn't on the encoder for these maps
* shipping firmware built. Need to clean up readme and info.json layout
* removing puckbuddy files from this branch
* readme done, prepping for PR
* info.json updated prepping for PR
* Restore cirque driver that was modified from puckbuddy testing on this branch
* applying changes from review
* Update keyboards/mechwild/bbs/bbs.c
* Fixed info.json
* Apply suggestions from code review
* info.json: correct JSON syntax error
* info.json: correct key sizes
* update readme files
Moves nearly all of the information about this keyboard to the 1967st version's readme, because this readme is exposed in QMK Configurator.
Also updates the readme to align more closely with QMK's keyboard readme template.
* info.json: update metadata
Updates the keyboard name and maintainer fields.
* Use polled waiting on platforms that support it
Due to context switching overhead waiting a very short amount of time on
a sleeping thread is often not accurate and in fact not usable for timing
critical usage i.e. in a driver. Thus we use polled waiting for ranges
in the us range on platforms that support it instead. The fallback is
the thread sleeping mechanism.
This includes:
* ARM platforms with CYCCNT register (ARMv7, ARMv8) this is
incremented at CPU clock frequency
* GD32VF103 RISC-V port with CSR_MCYCLE register this is incremented at
CPU clock frequency
* RP2040 ARMv6 port which uses the integrated timer peripheral which is
incremented with a fixed 1MHz frequency
* Use wait_us() instead of chSysPolledDelayX
...as it is powered by busy waiting now.
* Add chibios waiting methods test bench
* [Layout/Keymap] kbdfans kbd67 rev2 : add new LAYOUT_65_iso_split_bs and naphaline keymap as a working example
* Update keyboards/kbdfans/kbd67/rev2/keymaps/naphtaline/keymap.c
I do trust the reviewer, here goes the change :)
Co-authored-by: Ryan <fauxpark@gmail.com>
* Remove QMK custom keycodes 1/2
Co-authored-by: Nick Brassel <nick@tzarc.org>
* Remove QMK custom keycodes 2/2
Co-authored-by: Nick Brassel <nick@tzarc.org>
Co-authored-by: Ryan <fauxpark@gmail.com>
Co-authored-by: Nick Brassel <nick@tzarc.org>
* Add missing '(' to print_bin_reverse32 declaration
* Fix insufficient character buffers on satisfaction75
* Remove \0 character in format string and use corrected offset math
instead on rocketboard 16
* Replace snprintf_ with snprintf for djinn
* Explicitly ignore format checks for tracktyl manuform that uses %b
specifier
* Print properly escaped version string in command.c, as PRODUCT or
other defines can contain constructs like 'Vendor keyboard 66%' which
will be interpreted as a format specifier
mpaland printf implementation was abandoned in ~2019 and the fork by
eyalroz is now regarded to be the goto replacement of it. So this commit
incoporates the changes needed to use this fork in QMK.
Note that pointer ptrdiff_t is always supported since commit
51c90f93a97fdaef895783ecbe24569be0db7cb8
* info.json: apply friendly formatting
* info.json: remove dead space from Configurator rendering
* rename LAYOUT_all to LAYOUT_65_ansi_blocker
* rules.mk: enable Community Layout support
* Tentative Teensy 3.5 support
* Set firmware format to .hex for ARM Teensys
* Got to "device descriptor failed" by comparing with Teensy 3.6 code
* Drop down to 96MHz...
* Bump back up to 120MHz
* Disable RESET keycode because of naming conflicts
* Add Pico SDK as submodule
* Add RP2040 build support to QMK
* Adjust USB endpoint structs for RP2040
* Add RP2040 bootloader and double-tap reset routine
* Add generic and pro micro RP2040 boards
* Add RP2040 onekey keyboard
* Add WS2812 PIO DMA enabled driver and documentation
Supports regular and open-drain output configuration. RP2040 GPIOs are
sadly not 5V tolerant, so this is a bit use-less or needs extra hardware
or you take the risk to fry your hardware.
* Adjust SIO Driver for RP2040
* Adjust I2C Driver for RP2040
* Adjust SPI Driver for RP2040
* Add PIO serial driver and documentation
* Add general RP2040 documentation
* Apply suggestions from code review
Co-authored-by: Nick Brassel <nick@tzarc.org>
Co-authored-by: Nick Brassel <nick@tzarc.org>
* Initial import of wear-leveling algorithm.
* Alignment.
* Docs tweaks.
* Lock/unlock.
* Update quantum/wear_leveling/wear_leveling_internal.h
Co-authored-by: Stefan Kerkmann <karlk90@pm.me>
* More tests, fix issue with consolidation when unlocked.
* More tests.
* Review comments.
* Add plumbing for FNV1a.
* Another test checking that checksum mismatch clears the cache.
* Check that the write log still gets played back.
Co-authored-by: Stefan Kerkmann <karlk90@pm.me>
* Refactor steno into STENO_ENABLE_[ALL|GEMINI|BOLT]
* Update stenography documentation
* STENO_ENABLE_TXBOLT → STENO_ENABLE_BOLT
TXBOLT is a better name but BOLT is more consistent with the
pre-existing TX Bolt related constants, which all drop the "TX " prefix
* Comments
* STENO_ENABLE_[GEMINI|BOLT|ALL] → STENO_PROTOCOL = [geminipr|txbolt|all]
* Add note on lacking V-USB support
* Clear chord at the end of the switch(mode){send_steno_chord} block
* Return true if NOEVENT
* update_chord_xxx → add_xxx_key_to_chord
* Enable the defines for all the protocols if STENO_PROTOCOL = all
* Mention how to use `steno_set_mode`
* Set the default steno protocol to "all"
This is done so that existing keymaps invoking `steno_set_mode` don't
all suddenly break
* Add data driver equivalents for stenography feature
* Document format of serial steno packets
(Thanks dnaq)
* Add missing comma
* move ISO Enter position to home row
This commit makes the ISO layout macros compatible with QMK's `65_iso_blocker` and `65_iso_blocker_tsangan` community layouts.
* info.json: apply friendly formatting
- add key labels
- add line breaks between physical rows
* enable Community Layout support
* chaos65.h: add matrix diagram
* avr i2c_master: Fix 1ms timeout
i2c_start() produces a minimum time_slice of 1ms for use as timeout
value.
The timer granularity is 1ms, it is entirely possible for timer_count
to tick up immediately after the last timer read and falsely trigger
timeout with a '>= 1' comparison.
* avr/drivers/i2c_master: Use timer_elapsed()
* Fix RGB heatmap to use XY positions
* lower effect area limit and make configurable
* tidy up macro
* Fix triggering in both directions.
* add docs
* fix bug when decreasing value
* performance tweak
* move USE_I2C and EE_HANDS definitions to keyboard level
Allow this keyboard to be compiled by QMK Configurator.
* remove redundant DEFAULT_FOLDER rule
* [Keyboard] Add labbeminiv1
* Adjust vendor id
The used vendor id was in use
* Remove comment in the rgb keymap
* Update keyboards/labbe/labbeminiv1/rules.mk
Co-authored-by: Ryan <fauxpark@gmail.com>
* Rename rgb matrix keymap folder
Co-authored-by: Ryan <fauxpark@gmail.com>
* Add base FAve 84H firmware
* Update keyboards/linworks/fave84h/readme.md
Thank you, apologies for the oversight
Co-authored-by: Joel Challis <git@zvecr.com>
* Update keyboards/linworks/fave84h/keymaps/via/keymap.c
Co-authored-by: Joel Challis <git@zvecr.com>
* Update keyboards/linworks/fave84h/keymaps/default/keymap.c
Co-authored-by: Joel Challis <git@zvecr.com>
* Move LED config in ifdef
* update read me
* Update Product Name
* Update keyboards/linworks/fave84h/rules.mk
Co-authored-by: Ryan <fauxpark@gmail.com>
* Add Via RGB Matrix Control
* Add base FAve 84H firmware
* Add Via RGB Matrix Control
* fix merge conflict
* reduce max brightness
* remove action macro and action function
Co-authored-by: Joel Challis <git@zvecr.com>
* Remove / update code to work with the build in QMK via hack
* Update Read me
* Add newline at end of rules
Co-authored-by: Wolf Van Herreweghe <wolfvh@getupgamesofficial.com>
Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
* sync oled code over the keymaps
* put different product ids
* put different product ids for the rest
* put different product ids for the rest
* try to reduce code duplication
* make ifdefs nice and correct
* move the leds code out of keymap
* try to reduce code duplication
* move the rgb code outside the keymaps for reuse
* Update keyboards/mlego/m65/m65.c
Co-authored-by: Drashna Jaelre <drashna@live.com>
* Update keyboards/mlego/m65/m65.c
Co-authored-by: Drashna Jaelre <drashna@live.com>
* move more code outside keymaps for reuse
* add few more xps
* add mic mute
* update to new name of macros for reset
* style for matrix
* clean split
* use tinyuf2 as bootloader
* Update keyboards/mlego/m65/rev4/rules.mk
Co-authored-by: Ryan <fauxpark@gmail.com>
* radionalise product id and device version
* add tinyuf2 as default bootloader for stm32f4
* update tinyuf2
* update tinyuf2 and via. f411 remove tinyuf2 since is not really working. make the config more conditional
* sync the keymap with default
* revert via non building with gcc 11
Co-authored-by: Drashna Jaelre <drashna@live.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
* Handle timeout on UART for Redox Wireless receiver-to-keyboard communication.
- This fixes the issue of a keyboard deadlocking on the first matrix
scan with Redox Wireless keyboards
* Remove an explicit cast.
Co-authored-by: Tomasz Janeczko <tomasz.j@hey.com>
* Add files for alt34 keyboard
* Add link to hardware bill of materials for alt34
* Change keyboard image link to imgur
* Remove platform specific defines from rev1.h
* Remove bluetooth and sleep led rules etc
* Add GPL license header to all source code files
* Shorten comment for NKRO_ENABLE
Co-authored-by: Drashna Jaelre <drashna@live.com>
* Simplify option usage comment in rules.mk
Co-authored-by: Drashna Jaelre <drashna@live.com>
* Set imgur link to largest size option
Co-authored-by: Drashna Jaelre <drashna@live.com>
* Move rules.mk into rev1 folder entirely
* Remove .noci file
* Update keyboards/alt34/rev1/rules.mk
Co-authored-by: Ryan <fauxpark@gmail.com>
Co-authored-by: Drashna Jaelre <drashna@live.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
* Move SPLIT_HAND_PIN setup to split_pre_init
* doppelganger should use old behaviour
* Add comment for future
Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: Joel Challis <git@zvecr.com>
* Fix Caps Word and Unicode Map
* Tests for Caps Word + Auto Shift and Unicode Map.
* Fix formatting
* Add additional keyboard report expectation macros
This commit defines five test utilities, EXPECT_REPORT, EXPECT_UNICODE,
EXPECT_EMPTY_REPORT, EXPECT_ANY_REPORT and EXPECT_NO_REPORT for use with
TestDriver.
EXPECT_REPORT sets a gmock expectation that a given keyboard report will
be sent. For instance,
EXPECT_REPORT(driver, (KC_LSFT, KC_A));
is shorthand for
EXPECT_CALL(driver,
send_keyboard_mock(KeyboardReport(KC_LSFT, KC_A)));
EXPECT_UNICODE sets a gmock expectation that a given Unicode code point
will be sent using UC_LNX input mode. For instance for U+2013,
EXPECT_UNICODE(driver, 0x2013);
expects the sequence of keys:
"Ctrl+Shift+U, 2, 0, 1, 3, space".
EXPECT_EMPTY_REPORT sets a gmock expectation that a given keyboard
report will be sent. For instance
EXPECT_EMPTY_REPORT(driver);
expects a single report without keypresses or modifiers.
EXPECT_ANY_REPORT sets a gmock expectation that a arbitrary keyboard
report will be sent, without matching its contents. For instance
EXPECT_ANY_REPORT(driver).Times(1);
expects a single arbitrary keyboard report will be sent.
EXPECT_NO_REPORT sets a gmock expectation that no keyboard report will
be sent at all.
* Add tap_key() and tap_keys() to TestFixture.
This commit adds a `tap_key(key)` method to TestFixture that taps a
given KeymapKey, optionally with a specified delay between press and
release.
Similarly, the method `tap_keys(key_a, key_b, key_c)` taps a sequence of
KeymapKeys.
* Use EXPECT_REPORT, tap_keys, etc. in most tests.
This commit uses EXPECT_REPORT, EXPECT_UNICODE, EXPECT_EMPTY_REPORT,
EXPECT_NO_REPORT, tap_key() and tap_keys() test utilities from the
previous two commits in most tests. Particularly the EXPECT_REPORT
macro is frequently useful and makes a nice reduction in boilerplate
needed to express many tests.
Co-authored-by: David Kosorin <david@kosorin.net>
### Add Raspberry Pi RP2040 support ([#14877](https://github.com/qmk/qmk_firmware/pull/14877), [#17514](https://github.com/qmk/qmk_firmware/pull/17514), [#17516](https://github.com/qmk/qmk_firmware/pull/17516), [#17519](https://github.com/qmk/qmk_firmware/pull/17519), [#17612](https://github.com/qmk/qmk_firmware/pull/17612), [#17512](https://github.com/qmk/qmk_firmware/pull/17512), [#17557](https://github.com/qmk/qmk_firmware/pull/17557), [#17817](https://github.com/qmk/qmk_firmware/pull/17817), [#17839](https://github.com/qmk/qmk_firmware/pull/17839), [#18100](https://github.com/qmk/qmk_firmware/pull/18100)) :id=rp2040-support
QMK _finally_ picked up support for RP2040-based boards, such as the Raspberry Pi Pico, the Sparkfun Pro Micro RP2040, and the Adafruit KB2040. One of QMK's newest collaborators, _@KarlK90_, effectively did `/micdrop` with RP2040, with a massive set of changes to both QMK and the repository QMK uses for the base platform support, ChibiOS[-Contrib]. There has been a flurry of development this breaking changes cycle related to RP2040 from a large number of contributors -- so much so that almost all standard QMK hardware subsystems are supported.
Check the [RP2040 platform development page](platformdev_rp2040.md) for all supported peripherals and other hardware implementation details.
### Allow `qmk flash` to use prebuilt firmware binaries ([#16584](https://github.com/qmk/qmk_firmware/pull/16584)) :id=cli-flash-binaries
A long-requested capability of the QMK CLI has been the ability to flash binaries directly, without needing to build a firmware. QMK provides prebuilt `develop`-based default firmwares on our [CI page](https://qmk.tzarc.io/) -- normally people would need [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases/latest) to flash them. This new functionality written by _@Erovia_ allows `qmk flash` to be provided the prebuilt file instead, simplifying the workflow for people who haven't got Toolbox available.
## Changes Requiring User Action :id=changes-requiring-user-action
### Default layers dropped from 32 to 16 ([#15286](https://github.com/qmk/qmk_firmware/pull/15286))
QMK allows for controlling the maximum number of layers it supports through `LAYER_STATE_(8|16|32)BIT`. Each definition allows for the same number of maximum layers -- `LAYER_STATE_8BIT` => 8 layers. There is also a corresponding firmware size decrease that goes along with smaller numbers -- given the vast majority of users don't use more than 16 layers the default has been swapped to 16. AVR users who were not previously specifying their max layer count may see some space freed up as a result.
Following the last breaking changes cycle, QMK has been migrating usages of `RESET` to `QK_BOOT` due to naming collisions with our upstream board support packages. [#17940](https://github.com/qmk/qmk_firmware/pull/17940) converts user keymaps across to use the new keycode name. `RESET` should also move to `QK_BOOT`.
### Data-driven USB IDs Refactoring ([#18152](https://github.com/qmk/qmk_firmware/pull/18152)) :id=usb-ids-Refactoring
QMK has decided to deprecate the specification of USB IDs inside `config.h` in favour of `info.json`, eventually leaving data-driven as the only method to specify USB information.
A significant number of keyboards have already been changed on `master` in a like-for-like fashion, and [#18152](https://github.com/qmk/qmk_firmware/pull/18152) performs the same transformations for keyboards already on `develop`.
Previously in `config.h`:
```c
#define VENDOR_ID 0x1234
#define PRODUCT_ID 0x5678
#define DEVICE_VER 0x0001
#define MANUFACTURER Me
#define PRODUCT MyKeyboard
```
Replaced by `info.json`:
```json
{
"keyboard_name":"MyKeyboard",
"manufacturer":"Me",
"usb":{
"vid":"0x1234",
"pid":"0x5678",
"device_version":"0.0.1"
},
// ... layouts, etc. ...
}
```
#### Deprecation Schedule
- From 2022 Aug 27, specifying USB information in `config.h` will produce warnings during build but will still function as previously.
- From 2022 Nov 26, specifying USB information in `config.h` will cause compilation to fail.
Historically QMK had a `CONVERT_TO_PROTON_C` directive for `rules.mk` to allow people to replace an AVR-based Pro Micro with a QMK Proton C. Global parts shortages have prompted people to create their own pin-compatible boards -- QMK has made this conversion generic and now allows for drop-in replacements for a lot more boards. see the [Converters Feature](feature_converters.md) documentation for the full list of supported replacement boards -- in this breaking changes cycle we've gone from 1 to 7.
### Add cli command to import keyboard|keymap|kbfirmware ([#16668](https://github.com/qmk/qmk_firmware/pull/16668)) :id=cli-import
To help with importing keyboards and keymaps from other sources, _@zvecr_ added [#16668](https://github.com/qmk/qmk_firmware/pull/16668) which adds a new set of commands to the CLI to automatically import keyboards (`qmk import-keyboard -h`), keymaps (`qmk import-keymap -h`), and kbfirmware definitions (`qmk import-kbfirmware -h`) into QMK.
The now-EOL kbfirmware allowed people who aren't set up with QMK the ability to create keyboard firmwares without requiring a full installation of QMK. Unfortunately, it targets a 7-year-old version of QMK -- adding frustration for users who want the newest features, as well as for QMK maintainers who have to spend time explaining why QMK can't just accept a drive-by code drop from kbfirmware. With any luck, this new command helps both camps!
### Generic wear-leveling for EEPROM emulation ([#16996](https://github.com/qmk/qmk_firmware/pull/16996), [#17376](https://github.com/qmk/qmk_firmware/pull/17376), [#18102](https://github.com/qmk/qmk_firmware/pull/18102)) :id=wear-leveling
QMK has had the ability to write to internal MCU flash in order to emulate EEPROM for some time now, but it was only limited to a small number of MCUs. The base HAL used by QMK for a large number of ARM devices provides a "proper" embedded MCU flash driver, so _@tzarc_ decoupled the wear-leveling algorithm from the old flash writing code, improved it, wrote some tests, and enabled its use for a much larger number of other devices... including RP2040's XIP flash, and external SPI NOR Flash.
See the [EEPROM Driver](eeprom_driver.md) documentation for more information.
Ever since Pointing Device Driver support and Split Pointing Device support were added by _@drashna_ and _@daskygit_, there has been increased interest in the development of the pointing device subsystem and its associated code.
Both the PMW33xx and the Cirque Pinnacle implementations have seen a lot of improvement to their code, as has the mouse code in general. Features like circular/edge scrolling for the Cirque, and Kinetic movement for any sensor with "lift detection" ([#17482](https://github.com/qmk/qmk_firmware/pull/17482)). Additionally, for those that make fast motions with their pointing devices, support for much larger mouse movement reports has been added ([#16371](https://github.com/qmk/qmk_firmware/pull/16371)).
Other related changes:
* Add support for large Mouse Reports ([#16371](https://github.com/qmk/qmk_firmware/pull/16371))
* Adafruit Macropad: Add VIA keymap, fix default km ([#17735](https://github.com/qmk/qmk_firmware/pull/17735))
* Fix compilation issues for Charybdis/Dilemma ([#17791](https://github.com/qmk/qmk_firmware/pull/17791))
* bastardkb: fix info.json changes that got reverted during the last merge from `master` to `develop` ([#17800](https://github.com/qmk/qmk_firmware/pull/17800))
| `AUDIO_DAC_SAMPLE_MAX` | `4095U` | Highest value allowed. Lower value means lower volume. And 4095U is the upper limit, since this is limited to a 12 bit value. Only effects non-pregenerated samples. |
| `AUDIO_DAC_OFF_VALUE` | `AUDIO_DAC_SAMPLE_MAX / 2` | The value of the DAC when notplaying anything. Some setups may require a high (`AUDIO_DAC_SAMPLE_MAX`) or low (`0`) value here. |
| `AUDIO_DAC_OFF_VALUE` | `AUDIO_DAC_SAMPLE_MAX / 2` | The value of the DAC when notplaying anything. Some setups may require a high (`AUDIO_DAC_SAMPLE_MAX`) or low (`0`) value here. |
| `AUDIO_MAX_SIMULTANEOUS_TONES` | __see next table__ | The number of tones that can be played simultaneously. A value that is too high may freeze the controller or glitch out when too many tones are being played. |
| `AUDIO_DAC_SAMPLE_RATE` | __see next table__ | Effective bit rate of the DAC (in hertz), higher limits simultaneous tones, and lower sacrifices quality. |
| `AUDIO_DAC_SAMPLE_RATE` | __see next table__ | Effective bit rate of the DAC (in hertz), higher limits simultaneous tones, and lower sacrifices quality. |
There are a number of predefined quality settings that you can use, with "sane minimum" being the default. You can use custom values by simply defining the sample rate and number of simultaneous tones, instead of using one of the listed presets.
@@ -8,6 +8,7 @@ The breaking change period is when we will merge PR's that change QMK in dangero
## What has been included in past Breaking Changes?
* [2022 Aug 27](ChangeLog/20220827.md)
* [2022 May 28](ChangeLog/20220528.md)
* [2022 Feb 26](ChangeLog/20220226.md)
* [2021 Nov 27](ChangeLog/20211127.md)
@@ -22,17 +23,18 @@ The breaking change period is when we will merge PR's that change QMK in dangero
## When is the next Breaking Change?
The next Breaking Change is scheduled for August 27, 2022.
The next Breaking Change is scheduled for November 26, 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.
* 2022 Aug 27 - `develop` is tagged with a new release version. Each push to `master` is subsequently merged to `develop` by GitHub actions.
* 2022 Oct 29 - `develop` closed to new PR's.
* 2022 Oct 29 - Call for testers.
* 2022 Nov 12 - Last day for merges -- after this point `develop` is locked for testing and accepts only bugfixes
* 2022 Nov 19 - `develop` is locked, only critical bugfix PR's merged.
* 2022 Nov 24 - `master` is locked, no PR's merged.
* 2022 Nov 26 - Merge `develop` to `master`.
* 2022 Nov 26 - `master` is unlocked. PR's can be merged again.
## What changes will be included?
@@ -43,80 +45,132 @@ If you want your breaking change to be included in this round you need to create
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`.
* The PR has a ChangeLog file describing the changes under `<qmk_firmware>/docs/Changelog/20221126`.
* This should be in Markdown format, with a name in the format `PR12345.md`, substituting the digits for your PR's ID.
* One strong recommendation that the ChangeLog document matches the PR description on GitHub, so as to ensure traceability.
# Checklists
## Checklists
This section documents various processes we use when running the Breaking Changes process.
## Creating the `develop` branch
This happens immediately after the previous `develop` branch is merged.
*`qmk_firmware` git commands
* [ ]`git checkout master`
* [ ]`git pull --ff-only`
* [ ]`git checkout -b develop`
* [ ] Edit `readme.md`
* [ ] Add a big notice at the top that this is a testing branch.
* [ ] Include a link to this document
* [ ]`git commit -m 'Branch point for <DATE> Breaking Change'`
* [ ]`git tag breakpoint_<YYYY>_<MM>_<DD>`
* [ ]`git tag <next_version>` # Prevent the breakpoint tag from confusing version incrementing
* [ ]`git push upstream develop`
* [ ]`git push --tags`
## 4 Weeks Before Merge
### 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
* Post call for testers: message `@Breaking Changes Updates` on `#qmk_firmware` in Discord:
* `@Breaking Changes Updates -- Hey folks, last day for functional PRs to be raised against qmk_firmware for this breaking changes cycle is today.`
## 2 Weeks Before Merge
### 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
* Post call for testers: message `@Breaking Changes Updates` on `#qmk_firmware` in Discord.
* `@Breaking Changes Updates -- Hey folks, last day for functional PRs to be merged into qmk_firmware for this breaking changes cycle is today. After that, we're handling bugfixes only.`
## 1 Week Before Merge
### 1 Week Before Merge
*Announce that master will be closed from <2DaysBefore> to <DayofMerge>
* [ ] Discord
* [ ] GitHub PR
* [ ] https://reddit.com/r/olkb
*`develop` is now closed to PR merges, only critical bugfixes may be included
* Announce that master will be closed from <2DaysBefore> to <DayofMerge> -- message `@Breaking Changes Updates` on `#qmk_firmware` in Discord:
* `@Breaking Changes Updates -- Hey folks, last day for functional PRs to be merged into qmk_firmware for this breaking changes cycle is today. After that, we're handling bugfixes only.`
## 2 Days Before Merge
### 2 Days Before Merge
*`master` is now closed to PR merges
* Announce that master is closed for 2 days
* [ ] Discord
* [ ] GitHub PR
* [ ] https://reddit.com/r/olkb
* `@Breaking Changes Updates -- Hey folks, the master branch of qmk_firmware is now locked for the next couple of days while we prepare to merge the newest batch of changes from develop.`
## Day Of Merge
### 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`
*`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
* Create a PR for `develop`
* **Turn off 'Automatically delete head branches' for the repository** -- confirm with @qmk/directors that it is done before continuing
*`qmk_firmware` git commands
* [ ]`git checkout master`
* [ ]`git pull --ff-only`
* [ ]`git merge --no-ff develop`
* [ ]`git push upstream master`
*`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. See previous revisions of the `develop` 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, that repository needs to have its `master` branch updated to match (otherwise Configurator won't work):
*`cd lib/chibios`
*`git fetch --all`
*`git checkout master`
*`git reset --hard <commit hash>`
*`git push origin master --force-with-lease`
* Announce that both `master` and `develop` are now unlocked -- message `@Breaking Changes Updates` on `#qmk_firmware` in Discord:
*`@Breaking Changes Updates -- Hey folks, develop has now been merged into master -- newest batch of changes are now available for everyone to use!`
* (Optional) [update ChibiOS + ChibiOS-Contrib on `develop`](chibios_upgrade_instructions.md)
### Set up Discord events for the next cycle
* Update this file with the new dates: `docs/breaking_changes.md`
* Create Events on the QMK Discord - "Somewhere Else" => "GitHub":
| Topic | Last `develop` functionality PRs to be raised |
| Start Date | ((5 weeks before merge)), 12:00am |
| End Date | ((4 weeks before merge)), 12:00am |
| Description | This is the last window for functional PRs to be raised against `develop` for the current breaking changes cycle. After ((4 weeks before merge)), any new PRs targeting `develop` will be deferred to the next cycle. |
| Topic | Last `develop` functionality PRs to be merged |
| Start Date | ((4 weeks before merge)), 12:00am |
| End Date | ((2 weeks before merge)), 12:00am |
| Description | This is the last window for functional PRs to be merged into `develop` for the current breaking changes cycle. After ((2 weeks before merge)), only bugfix PRs targeting `develop` will be considered for merge. |
| Start Date | ((2 weeks before merge)), 12:00am |
| End Date | ((day of merge)), 12:00am |
| Description | This is the deadline for functionality bugfix PRs to be merged into `develop` for the current breaking changes cycle. After ((1 week before merge)), only critical bugfix PRs targeting `develop` will be considered for merge. |
| Description | At some point, QMK will merge `develop` into `master` and everyone will be able to reap the benefits of the newest batch of functionality. |
Ψ Wrote keymap to /home/you/qmk_firmware/polaris_keymap.json
```
## `qmk import-keyboard`
This command imports a data-driven `info.json` keyboard into the repo.
**Usage**:
```
usage: qmk import-keyboard [-h] filename
```
**Example:**
```
$ qmk import-keyboard ~/Downloads/forever60.json
Ψ Importing forever60.json.
Ψ Imported a new keyboard named forever60.
Ψ To start working on things, `cd` into keyboards/forever60,
Ψ or open the directory in your preferred text editor.
Ψ And build with qmk compile -kb forever60 -km default.
```
## `qmk import-keymap`
This command imports a data-driven `keymap.json` keymap into the repo.
**Usage**:
```
usage: qmk import-keymap [-h] filename
```
**Example:**
```
qmk import-keymap ~/Downloads/asdf2.json
Ψ Importing asdf2.json.
Ψ Imported a new keymap named asdf2.
Ψ To start working on things, `cd` into keyboards/takashicompany/dogtag/keymaps/asdf2,
Ψ or open the directory in your preferred text editor.
Ψ And build with qmk compile -kb takashicompany/dogtag -km asdf2.
```
## `qmk import-kbfirmware`
This command creates a new keyboard based on a [Keyboard Firmware Builder](https://kbfirmware.com/) export.
**Usage**:
```
usage: qmk import-kbfirmware [-h] filename
```
**Example:**
```
$ qmk import-kbfirmware ~/Downloads/gh62.json
Ψ Importing gh62.json.
⚠ Support here is basic - Consider using 'qmk new-keyboard' instead
Ψ Imported a new keyboard named gh62.
Ψ To start working on things, `cd` into keyboards/gh62,
Ψ or open the directory in your preferred text editor.
Ψ And build with qmk compile -kb gh62 -km default.
```
---
# Developer Commands
@@ -527,3 +611,4 @@ This command converts a TTF font to an intermediate format for editing, before c
## `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.
QMK runs on any USB-capable AVR or ARM microcontroller with enough flash space - generally 32kB+ for AVR, and 64kB+ for ARM. With significant disabling of features, QMK may *just* squeeze into 16kB AVR MCUs.
Features within QMK may or may not be compatible with every microcontroller.
## Atmel AVR
The following use [LUFA](https://www.fourwalledcubicle.com/LUFA.php) as the USB stack:
@@ -60,9 +62,17 @@ You can also use any ARM chip with USB that [ChibiOS](https://www.chibios.org) s
For a detailed overview about the RP2040 support by QMK see the [dedicated RP2040 page](platformdev_rp2040.md).
## 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.
@@ -57,8 +57,6 @@ This is a C header file that is one of the first things included, and will persi
* 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`
@@ -107,8 +105,10 @@ This is a C header file that is one of the first things included, and will persi
* 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 USB_SUSPEND_WAKEUP_DELAY 0`
* sets the number of milliseconds to pause after sending a wakeup packet.
Disabled by default, you might want to set this to 200 (or higher) if the
keyboard does not wake up properly after suspending.
*`#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`.
@@ -141,7 +141,7 @@ If you define these options you will enable the associated feature, which may in
## 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
* how long before a key press becomes a hold
*`#define TAPPING_TERM_PER_KEY`
* enables handling for per key `TAPPING_TERM` settings
*`#define RETRO_TAPPING`
@@ -174,19 +174,12 @@ If you define these options you will enable the associated feature, which may in
* 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 MOUSE_EXTENDED_REPORT`
* Enables support for extended reports (-32767 to 32767, instead of -127 to 127), which may allow for smoother reporting, and prevent maxing out of the reports. Applies to both Pointing Device and Mousekeys.
*`#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`
@@ -194,7 +187,7 @@ If you define these options you will enable the associated feature, which may in
*`#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.
* 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`
@@ -214,14 +207,12 @@ If you define these options you will enable the associated feature, which may in
*`#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`
*`#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.
@@ -366,8 +357,8 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i
*`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`.
* 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
@@ -420,7 +411,7 @@ Use these to enable or disable building certain features. The more you have enab
* `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.
* 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.
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
typedefunion{
uint32_traw;
struct{
boolrgb_layer_change:1;
};
}user_config_t;
user_config_tuser_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
voidkeyboard_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.
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:
returnfalse;// Skip all further processing of this key
caseKC_ENTER:
// Play a tone when enter is pressed
if(record->event.pressed){
PLAY_SONG(tone_qwerty);
}
returntrue;// Let QMK send the enter press/release events
caseRGB_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
}
}
returnfalse;
caseRGB_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
}
}
returntrue;break;
default:
returntrue;// 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
voideeconfig_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
# 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
## Deferred executor callbacks
All _deferred executor callbacks_ have a common function signature and look like:
@@ -430,7 +251,7 @@ The return value is the number of milliseconds to use if the function should be
?> 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
## Deferred executor registration
Once a callback has been defined, it can be scheduled using the following API:
@@ -444,7 +265,7 @@ The third parameter is the `cb_arg` that gets passed to the callback at the poin
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
## 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
@@ -452,7 +273,7 @@ The `deferred_token` returned by `defer_exec()` can be used to extend a the dura
extend_deferred_exec(my_token,800);
```
#### Cancelling a deferred execution
## Cancelling a deferred execution
The `deferred_token` returned by `defer_exec()` can be used to cancel a pending execution before it gets invoked:
Once a token has been canceled, it should be considered invalid. Reusing the same token is not supported.
#### Deferred callback limits
## 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`.
@@ -471,3 +292,15 @@ If registrations fail, then you can increase this value in your keyboard or keym
```c
#define MAX_DEFERRED_EXECUTORS 16
```
# Advanced topics :id=advanced-topics
This page used to encompass a large set of features. We have moved many sections that used to be part of this page to their own pages. Everything below this point is simply a redirect so that people following old links on the web find what they're looking for.
@@ -8,7 +8,7 @@ We recommend the use of the [Zadig](https://zadig.akeo.ie/) utility. If you have
## Installation
Put your keyboard into bootloader mode, either by hitting the `RESET` keycode (which may be on a different layer), or by pressing the reset switch that's usually located on the underside of the board. If your keyboard has neither, try holding Escape or Space+`B` as you plug it in (see the [Bootmagic Lite](feature_bootmagic.md) docs for more details). Some boards use [Command](feature_command.md) instead of Bootmagic; in this case, you can enter bootloader mode by hitting Left Shift+Right Shift+`B` or Left Shift+Right Shift+Escape at any point while the keyboard is plugged in.
Put your keyboard into bootloader mode, either by hitting the `QK_BOOT` keycode (which may be on a different layer), or by pressing the reset switch that's usually located on the underside of the board. If your keyboard has neither, try holding Escape or Space+`B` as you plug it in (see the [Bootmagic Lite](feature_bootmagic.md) docs for more details). Some boards use [Command](feature_command.md) instead of Bootmagic; in this case, you can enter bootloader mode by hitting Left Shift+Right Shift+`B` or Left Shift+Right Shift+Escape at any point while the keyboard is plugged in.
Some keyboards may have specific instructions for entering the bootloader. For example, the [Bootmagic Lite](feature_bootmagic.md) key (default: Escape) might be on a different key, e.g. Left Control; or the magic combination for Command (default: Left Shift+Right Shift) might require you to hold something else, e.g. Left Control+Right Control. Refer to the board's README file if you are unsure.
To put a device in bootloader mode with USBaspLoader, tap the `RESET` button while holding down the `BOOT` button.
`EEPROM_DRIVER = vendor` (default) | Uses the on-chip driver provided by the chip manufacturer. For AVR, this is provided by avr-libc. This is supported on ARM for a subset of chips -- STM32F3xx, STM32F1xx, and STM32F072xB will be emulated by writing to flash. STM32L0xx and STM32L1xx will use the onboard dedicated true EEPROM. Other chips will generally act as "transient" below.
`EEPROM_DRIVER = i2c` | Supports writing to I2C-based 24xx EEPROM chips. See the driver section below.
`EEPROM_DRIVER = spi` | Supports writing to SPI-based 25xx EEPROM chips. See the driver section below.
`EEPROM_DRIVER = transient` | Fake EEPROM driver -- supports reading/writing to RAM, and will be discarded when power is lost.
`EEPROM_DRIVER = wear_leveling` | Frontend driver for the wear_leveling system, allowing for EEPROM emulation on top of flash -- both in-MCU and external SPI NOR flash.
Currently QMK supports 25xx-series chips over SPI. As such, requires a working spi_master driver configuration. You can override the driver configuration via your config.h:
The wear-leveling driver uses an algorithm to minimise the number of erase cycles on the underlying MCU flash memory.
There is no specific configuration for this driver, but the wear-leveling system used by this driver may need configuration. See the [wear-leveling configuration](#wear_leveling-configuration) section for more information.
`WEAR_LEVELING_DRIVER = embedded_flash` | This driver is used for emulating EEPROM by writing to embedded flash on the MCU.
`WEAR_LEVELING_DRIVER = spi_flash` | This driver is used to address external SPI NOR Flash peripherals.
`WEAR_LEVELING_DRIVER = rp2040_flash` | This driver is used to write to the same storage the RP2040 executes code from.
`WEAR_LEVELING_DRIVER = legacy` | This driver is the "legacy" emulated EEPROM provided in historical revisions of QMK. Currently used for STM32F0xx and STM32F4x1, but slated for deprecation and removal once `embedded_flash` support for those MCU families is complete.
!> All wear-leveling drivers require an amount of RAM equivalent to the selected logical EEPROM size. Increasing the size to 32kB of EEPROM requires 32kB of RAM, which a significant number of MCUs simply do not have.
This driver performs writes to the embedded flash storage embedded in the MCU. In most circumstances, the last few of sectors of flash are used in order to minimise the likelihood of collision with program code.
Configurable options in your keyboard's `config.h`:
`#define WEAR_LEVELING_EFL_FIRST_SECTOR` | _unset_ | The first sector on the MCU to use. By default this is not defined and calculated at runtime based on the MCU. However, different flash sizes on MCUs may require custom configuration.
`#define WEAR_LEVELING_EFL_FLASH_SIZE` | _unset_ | Allows overriding the flash size available for use for wear-leveling. Under normal circumstances this is automatically calculated and should not need to be overridden. Specifying a size larger than the amount actually available in flash will usually prevent the MCU from booting.
`#define WEAR_LEVELING_LOGICAL_SIZE` | `1024` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM.
`#define WEAR_LEVELING_BACKING_SIZE` | `2048` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size.
`#define BACKING_STORE_WRITE_SIZE` | _automatic_ | The byte width of the underlying write used on the MCU, and is usually automatically determined from the selected MCU family. If an error occurs in the auto-detection, you'll need to consult the MCU's datasheet and determine this value, specifying it directly.
!> If your MCU does not boot after swapping to the EFL wear-leveling driver, it's likely that the flash size is incorrectly detected, usually as an MCU with larger flash and may require overriding.
This driver performs writes to an external SPI NOR Flash peripheral. It also requires a working configuration for the SPI NOR Flash peripheral -- see the [flash driver](flash_driver.md) documentation for more information.
Configurable options in your keyboard's `config.h`:
`#define WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_COUNT` | `1` | Number of blocks in the external flash used by the wear-leveling algorithm.
`#define WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_OFFSET` | `0` | The index first block in the external flash used by the wear-leveling algorithm.
`#define WEAR_LEVELING_LOGICAL_SIZE` | `((block_count*block_size)/2)` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM. Result must be <= 64kB.
`#define WEAR_LEVELING_BACKING_SIZE` | `(block_count*block_size)` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size.
`#define BACKING_STORE_WRITE_SIZE` | `8` | The write width used whenever a write is performed on the external flash peripheral.
!> There is currently a limit of 64kB for the EEPROM subsystem within QMK, so using a larger flash is not going to be beneficial as the logical size cannot be increased beyond 65536. The backing size may be increased to a larger value, but erase timing may suffer as a result.
`#define WEAR_LEVELING_RP2040_FLASH_SIZE` | `PICO_FLASH_SIZE_BYTES` | Number of bytes of flash on the board.
`#define WEAR_LEVELING_RP2040_FLASH_BASE` | `(flash_size-sector_size)` | The byte-wise location that the backing storage should be located.
`#define WEAR_LEVELING_LOGICAL_SIZE` | `4096` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM.
`#define WEAR_LEVELING_BACKING_SIZE` | `8192` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size as well as the sector size.
`#define BACKING_STORE_WRITE_SIZE` | `2` | The write width used whenever a write is performed on the external flash peripheral.
This driver performs writes to the embedded flash storage embedded in the MCU much like the normal Embedded Flash Driver, and is only for use with STM32F0xx and STM32F4x1 devices. This flash implementation is still currently provided as the EFL driver is currently non-functional for the previously mentioned families.
By default, `1024` bytes of emulated EEPROM is provided:
MCU | EEPROM Provided | Flash Used
----------|-----------------|--------------
STM32F042 | `1024` bytes | `2048` bytes
STM32F070 | `1024` bytes | `2048` bytes
STM32F072 | `1024` bytes | `2048` bytes
STM32F401 | `1024` bytes | `16384` bytes
STM32F411 | `1024` bytes | `16384` bytes
Under normal circumstances configuration of this driver requires intimate knowledge of the MCU's flash structure -- reconfiguration is at your own risk and will require referring to the code.
@@ -39,7 +39,7 @@ In practice, this means that you can check whether a given modifier is active wi
To check that *only* a specific set of mods is active at a time, AND the modifier state and your desired mod mask as explained above and compare the result to the mod mask itself: `get_mods() & <mod mask> == <mod mask>`.
For example, let's say you want to trigger a piece of custom code if one-shot left control and one-shot left shift are on but every other one-shot mods are off. To do so, you can compose the desired mod mask by combining the mod bits for left control and shift with `(MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT))` and then plug it in: `get_oneshot_mods & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT)) == (MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT))`. Using `MOD_MASK_CS` instead for the mod bitmask would have forced you to press four modifier keys (both versions of control and shift) to fulfill the condition.
For example, let's say you want to trigger a piece of custom code if one-shot left control and one-shot left shift are on but every other one-shot mods are off. To do so, you can compose the desired mod mask by combining the mod bits for left control and shift with `(MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT))` and then plug it in: `get_oneshot_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT)) == (MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT))`. Using `MOD_MASK_CS` instead for the mod bitmask would have forced you to press four modifier keys (both versions of control and shift) to fulfill the condition.
This page used to encompass a large set of features. We have moved many sections that used to be part of this page to their own pages. Everything below this point is simply a redirect so that people following old links on the web find what they're looking for.
If you, for example, use multiple base layers for different key layouts, one for QWERTY, and another one for Colemak, you might want your combos to work from the same key positions on all layers. Defining the same combos again for another layout is redundant and takes more memory. The solution is to just check the keycodes from one layer.
With `#define COMBO_ONLY_FROM_LAYER _LAYER_A` the combos' keys are always checked from layer `_LAYER_A` even though the active layer would be `_LAYER_B`.
With `#define COMBO_ONLY_FROM_LAYER 0` in config.h, the combos' keys are always checked from layer `0`, even if other layers are active.
You can also add the same `CONVERT_TO=<target>` to your keymap's `rules.mk`, which will accomplish the same thing.
?> If you get errors about `PORTB/DDRB`, etc not being defined, you'll need to convert the keyboard's code to use the [GPIO Controls](gpio_control.md) that will work for both ARM and AVR. This shouldn't affect the AVR builds at all.
### Conditional Configuration
Once a converter is enabled, it exposes the `CONVERT_TO_<target_uppercase>` flag that you can use in your code with `#ifdef`s, For example:
```c
#ifdef CONVERT_TO_PROTON_C
// Proton C code
#else
// Pro Micro code
#endif
```
## Pro Micro
If a board currently supported in QMK uses a [Pro Micro](https://www.sparkfun.com/products/12640) (or compatible board), the supported alternative controllers are:
The Proton C only has one on-board LED (C13), and by default, the TXLED (D5) is mapped to it. If you want the RXLED (B0) mapped to it instead, add this line to your `config.h`:
```c
#define CONVERT_TO_PROTON_C_RXLED
```
The following defaults are based on what has been implemented for STM32 boards.
| [Backlight](feature_backlight.md) | Forces [task driven PWM](feature_backlight.md#software-pwm-driver) until ARM can provide automatic configuration |
| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
| [Split keyboards](feature_split_keyboard.md) | Partial - heavily dependent on enabled features |
### Adafruit KB2040 :id=kb2040
The following defaults are based on what has been implemented for [RP2040](platformdev_rp2040.md) boards.
| [RGB Lighting](feature_rgblight.md) | Enabled via `PIO` vendor driver |
| [Backlight](feature_backlight.md) | Forces [task driven PWM](feature_backlight.md#software-pwm-driver) until ARM can provide automatic configuration |
| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
| [Split keyboards](feature_split_keyboard.md) | Partial via `PIO` vendor driver - heavily dependent on enabled features |
### SparkFun Pro Micro - RP2040, Blok, and Bit-C PRO :id=promicro_rp2040
Currently identical to [Adafruit KB2040](#kb2040).
### STeMCell :id=stemcell
Feature set currently identical to [Proton C](#proton_c).
There are two versions of STeMCell available, with different pinouts:
- v1.0.0
- v2.0.0 (pre-release v1.0.1, v1.0.2)
Default official firmware only supports v2.0.0 STeMCell.
STeMCell has support to swap UART and I2C pins, to enable single-wire uart communication in STM chips.
The following additional flags has to be used while compiling, based on the pin used for split communication.
| Split Pin | Compile flags |
|-----------|---------------|
| D3 | -e STMC_US=yes|
| D2 | Not needed |
| D1 | -e STMC_IS=yes|
| D0 | Not needed |
### Bonsai C4 :id=bonsai_c4
The Bonsai C4 only has one on-board LED (B2), and by default, both the Pro Micro TXLED (D5) and RXLED (B0) are mapped to it. If you want only one of them mapped, you can undefine one and redefine it to another pin by adding these line to your `config.h`:
```c
#undef B0
// If Vbus detection is unused, we can send RXLED to the Vbus detect pin instead
#define B0 PAL_LINE(GPIOA, 9)
```
No peripherals are enabled by default at this time, but example code to enable SPI, I2C, PWM, and Serial communications can be found [here](/keyboards/custommk/bonsai_c4_template)
@@ -35,6 +35,7 @@ There are a number of options added that should allow some additional degree of
|`DYNAMIC_MACRO_SIZE` |128 |Sets the amount of memory that Dynamic Macros can use. This is a limited resource, dependent on the controller. |
|`DYNAMIC_MACRO_USER_CALL` |*Not defined* |Defining this falls back to using the user `keymap.c` file to trigger the macro behavior. |
|`DYNAMIC_MACRO_NO_NESTING` |*Not Defined* |Defining this disables the ability to call a macro from another macro (nested macros). |
|`DYNAMIC_MACRO_DELAY` |*Not Defined* |Sets the waiting time (ms unit) when sending each key. |
If the LEDs start blinking during the recording with each keypress, it means there is no more space for the macro in the macro buffer. To fit the macro in, either make the other macro shorter (they share the same buffer) or increase the buffer size by adding the `DYNAMIC_MACRO_SIZE` define in your `config.h` (default value: 128; please read the comments for it in the header).
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
typedefunion{
uint32_traw;
struct{
boolrgb_layer_change:1;
};
}user_config_t;
user_config_tuser_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
voidkeyboard_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.
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:
returnfalse;// Skip all further processing of this key
caseKC_ENTER:
// Play a tone when enter is pressed
if(record->event.pressed){
PLAY_SONG(tone_qwerty);
}
returntrue;// Let QMK send the enter press/release events
caseRGB_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
}
}
returnfalse;
caseRGB_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
}
}
returntrue;break;
default:
returntrue;// 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
voideeconfig_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.
@@ -69,7 +69,7 @@ Additionally, if one side does not have an encoder, you can specify `{}` for the
## Encoder map :id=encoder-map
Encoder mapping may be added to your `keymap.c`, which replicates the normal keyswitch layer handling functionality, but with encoders. Add this to your `rules.mk`:
Encoder mapping may be added to your `keymap.c`, which replicates the normal keyswitch layer handling functionality, but with encoders. Add this to your keymap's `rules.mk`:
One of the most powerful and well used features of QMK Firmware is the ability to use layers. For most people, this amounts to a function key that allows for different keys, much like what you would see on a laptop or tablet keyboard.
One of the most powerful and well used features of QMK Firmware is the ability to use layers. For most people, this amounts to a function key that allows for different keys, much like what you would see on a laptop or tablet keyboard.
For a detailed explanation of how the layer stack works, checkout [Keymap Overview](keymap.md#keymap-and-layers).
@@ -9,7 +9,7 @@ For a detailed explanation of how the layer stack works, checkout [Keymap Overvi
These functions allow you to activate layers in various ways. Note that layers are not generally independent layouts -- multiple layers can be activated at once, and it's typical for layers to use `KC_TRNS` to allow keypresses to pass through to lower layers. When using momentary layer switching with MO(), LM(), TT(), or LT(), make sure to leave the key on the above layers transparent or it may not work as intended.
*`DF(layer)` - switches the default layer. The default layer is the always-active base layer that other layers stack on top of. See below for more about the default layer. This might be used to switch from QWERTY to Dvorak layout. (Note that this is a temporary switch that only persists until the keyboard loses power. To modify the default layer in a persistent way requires deeper customization, such as calling the `set_single_persistent_default_layer` function inside of [process_record_user](custom_quantum_functions.md#programming-the-behavior-of-any-keycode).)
*`MO(layer)` - momentarily activates *layer*. As soon as you let go of the key, the layer is deactivated.
*`MO(layer)` - momentarily activates *layer*. As soon as you let go of the key, the layer is deactivated.
*`LM(layer, mod)` - Momentarily activates *layer* (like `MO`), but with modifier(s) *mod* active. Only supports layers 0-15 and the left modifiers: `MOD_LCTL`, `MOD_LSFT`, `MOD_LALT`, `MOD_LGUI` (note the use of `MOD_` constants instead of `KC_`). These modifiers can be combined using bitwise OR, e.g. `LM(_RAISE, MOD_LCTL | MOD_LALT)`.
*`LT(layer, kc)` - momentarily activates *layer* when held, and sends *kc* when tapped. Only supports layers 0-15.
*`OSL(layer)` - momentarily activates *layer* until the next key is pressed. See [One Shot Keys](one_shot_keys.md) for details and additional functionality.
@@ -31,7 +31,7 @@ Care must be taken when switching layers, it's possible to lock yourself into a
If you are just getting started with QMK you will want to keep everything simple. Follow these guidelines when setting up your layers:
* Setup layer 0 as your default, "base" layer. This is your normal typing layer, and could be whatever layout you want (qwerty, dvorak, colemak, etc.). It's important to set this as the lowest layer since it will typically have most or all of the keyboard's keys defined, so would block other layers from having any effect if it were above them (i.e., had a higher layer number).
* Setup layer 0 as your default, "base" layer. This is your normal typing layer, and could be whatever layout you want (qwerty, dvorak, colemak, etc.). It's important to set this as the lowest layer since it will typically have most or all of the keyboard's keys defined, so would block other layers from having any effect if it were above them (i.e., had a higher layer number).
* Arrange your layers in a "tree" layout, with layer 0 as the root. Do not try to enter the same layer from more than one other layer.
* In a layer's keymap, only reference higher-numbered layers. Because layers are processed from the highest-numbered (topmost) active layer down, modifying the state of lower layers can be tricky and error-prone.
@@ -89,3 +89,46 @@ It is also possible to check the state of a particular layer using the following
| `layer_state_is(layer)` | Checks if the specified `layer` is enabled globally. | `IS_LAYER_ON(layer)`, `IS_LAYER_OFF(layer)` |
| `layer_state_cmp(state, layer)` | Checks `state` to see if the specified `layer` is enabled. Intended for use in layer callbacks. | `IS_LAYER_ON_STATE(state, layer)`, `IS_LAYER_OFF_STATE(state, layer)` |
## 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.
@@ -106,6 +106,8 @@ Only basic keycodes (prefixed by `KC_`) are supported. Do not include the `KC_`
### `SEND_STRING()` & `process_record_user`
See also: [Send String](feature_send_string.md)
Sometimes you want a key to type out words or phrases. For the most common situations, we've provided `SEND_STRING()`, which will type out a string (i.e. a sequence of characters) for you. All ASCII characters that are easily translatable to a keycode are supported (e.g. `qmk 123\n\t`).
Here is an example `keymap.c` for a two-key keyboard:
@@ -347,7 +349,7 @@ If the keycode is `KC_CAPS`, it waits `TAP_HOLD_CAPS_DELAY` milliseconds instead
Like `tap_code(<kc>)`, but with a `delay` parameter for specifying arbitrary intervals before sending the unregister event.
#### `register_code16(<kc>);`, `unregister_code16(<kc>);` and `tap_code16(<kc>);`
#### `register_code16(<kc>);`, `unregister_code16(<kc>);`, `tap_code16(<kc>);` and `tap_code16_delay(<kc>, <delay>);`
These functions work similar to their regular counterparts, but allow you to use modded keycodes (with Shift, Alt, Control, and/or GUI applied to them).
There are two MIDI systems in QMK: basic and advanced. With basic MIDI you will only be able to send Note On and Note Off messages using the note keycodes, meaning that keycodes like `MI_OCTU` and `MI_OCTD` will not work. Advanced MIDI allows you to do things like octave shifts, channel changes, velocity changes, modulation, and more.
### Caveats
MIDI requires 2 USB endpoints and as such may not work on some hardware such as V-USB controllers.
### Basic MIDI
To enable basic MIDI, add the following to your `config.h`:
|`MOUSEKEY_WHEEL_INITIAL_MOVEMENTS` |16 |Initial number of movements of the mouse wheel |
@@ -100,7 +100,7 @@ This is an extension of the accelerated mode. The kinetic mode uses a quadratic
Tips:
* The smoothness of the cursor movement depends on the `MOUSEKEY_INTERVAL` setting. The shorter the interval is set the smoother the movement will be. Setting the value too low makes the cursor unresponsive. Lower settings are possible if the micro processor is fast enough. For example: At an interval of `8` milliseconds, `125` movements per second will be initiated. With a base speed of `1000` each movement will move the cursor by `8` pixels.
* Mouse wheel movements are implemented differently from cursor movements. While it's okay for the cursor to move multiple pixels at once for the mouse wheel this would lead to jerky movements. Instead, the mouse wheel operates at step size `1`. Setting mouse wheel speed is done by adjusting the number of wheel movements per second.
* Mouse wheel movements are implemented differently from cursor movements. While it's okay for the cursor to move multiple pixels at once for the mouse wheel this would lead to jerky movements. Instead, the mouse wheel operates at step size `2`. Setting mouse wheel speed is done by adjusting the number of wheel movements per second.
Hardware configurations using Arm-based microcontrollers or different sizes of OLED modules may be compatible, but are untested.
!> Warning: This OLED driver currently uses the new i2c_master driver from Split Common code. If your split keyboard uses I2C to communicate between sides, this driver could cause an address conflict (serial is fine). Please contact your keyboard vendor and ask them to migrate to the latest Split Common code to fix this. In addition, the display timeout system to reduce OLED burn-in also uses Split Common to detect keypresses, so you will need to implement custom timeout logic for non-Split Common keyboards.
## Usage
To enable the OLED feature, there are two steps. First, when compiling your keyboard, you'll need to add the following to your `rules.mk`:
There are a number of sensors that are supported by default. Note that only one sensor can be enabled by `POINTING_DEVICE_DRIVER` at a time. If you need to enable more than one sensor, then you need to implement it manually.
There are a number of sensors that are supported by default. Note that only one sensor can be enabled by `POINTING_DEVICE_DRIVER` at a time. If you need to enable more than one sensor, then you need to implement it manually, using the `custom` driver.
This supports the Cirque Pinnacle 1CA027 Touch Controller, which is used in the TM040040, TM035035 and the TM023023 trackpads. These are I2C or SPI compatible, and both configurations are supported.
|`CIRQUE_PINNACLE_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `1000000` |
|`CIRQUE_PINNACLE_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
|`CIRQUE_PINNACLE_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `1` |
|`CIRQUE_PINNACLE_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
|`CIRQUE_PINNACLE_SPI_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
**`CIRQUE_PINNACLE_ATTENUATION`** is a measure of how much data is suppressed in regards to sensitivity. The higher the attenuation, the less sensitive the touchpad will be.
Default Scaling/CPI is 1024.
Default attenuation is set to 4X, although if you are using a thicker overlay (such as the curved overlay) you will want a lower attenuation such as 2X. The possible values are:
*`ADC_ATTENUATE_4X`: Least sensitive
*`ADC_ATTENUATE_3X`
*`ADC_ATTENUATE_2X`
*`ADC_ATTENUATE_1X`: Most sensitive
**`CIRQUE_PINNACLE_POSITION_MODE`** can be `CIRQUE_PINNACLE_ABSOLUTE_MODE` or `CIRQUE_PINNACLE_RELATIVE_MODE`. Modes differ in supported features/gestures.
*`CIRQUE_PINNACLE_ABSOLUTE_MODE`: Reports absolute x, y, z (touch pressure) coordinates and up to 5 hw buttons connected to the trackpad
*`CIRQUE_PINNACLE_RELATIVE_MODE`: Reports x/y deltas, scroll and up to 3 buttons (2 of them can be from taps, see gestures) connected to trackpad. Supports taps on secondary side of split. Saves about 2k of flash compared to absolute mode with all features.
| `CIRQUE_PINNACLE_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `1000000` |
| `CIRQUE_PINNACLE_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
| `CIRQUE_PINNACLE_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `1` |
| `CIRQUE_PINNACLE_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
| `CIRQUE_PINNACLE_SPI_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | `POINTING_DEVICE_CS_PIN` |
Default Scaling is 1024. Actual CPI depends on trackpad diameter.
Also see the `POINTING_DEVICE_TASK_THROTTLE_MS`, which defaults to 10ms when using Cirque Pinnacle, which matches the internal update rate of the position registers (in standard configuration). Advanced configuration for pen/stylus usage might require lower values.
| `CIRQUE_PINNACLE_TAP_ENABLE` | (Optional) Enable tap to click. This currently only works on the master side. | _not defined_ |
| `CIRQUE_PINNACLE_TAPPING_TERM` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` |
| `CIRQUE_PINNACLE_TOUCH_DEBOUNCE` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` |
`POINTING_DEVICE_GESTURES_SCROLL_ENABLE` in this mode enables circular scroll. Touch originating in outer ring can trigger scroll by moving along the perimeter. Near side triggers vertical scroll and far side triggers horizontal scroll.
Additionally, `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE` is supported in this mode.
| `CIRQUE_PINNACLE_TAP_ENABLE` | (Optional) Enable tap to "left click". Works on both sides of a split keyboard. | _not defined_ |
| `CIRQUE_PINNACLE_SECONDARY_TAP_ENABLE` | (Optional) Tap in upper right corner (half of the finger needs to be outside of the trackpad) of the trackpad will result in "right click". `CIRQUE_PINNACLE_TAP_ENABLE` must be enabled. | _not defined_ |
Tapping term and debounce are not configurable in this mode since it's handled by trackpad internally.
`POINTING_DEVICE_GESTURES_SCROLL_ENABLE` in this mode enables side scroll. Touch originating on the right side can trigger vertical scroll (IntelliSense trackpad style).
### PAW 3204 Sensor
To use the paw 3204 sensor, add this to your `rules.mk`
```make
POINTING_DEVICE_DRIVER= paw3204
```
The paw 3204 sensor uses a serial type protocol for communication, and requires an additional light source.
|`PIMORONI_TRACKBALL_ADDRESS` | (Required) Sets the I2C Address for the Pimoroni Trackball. | `0x0A` |
|`PIMORONI_TRACKBALL_TIMEOUT` | (Optional) The timeout for i2c communication with the trackball in milliseconds. | `100` |
|`PIMORONI_TRACKBALL_SCALE` | (Optional) The multiplier used to generate reports from the sensor. | `5` |
|`PIMORONI_TRACKBALL_DEBOUNCE_CYCLES` | (Optional) The number of scan cycles used for debouncing on the ball press. | `20` |
|`PIMORONI_TRACKBALL_ERROR_COUNT` | (Optional) Specifies the number of read/write errors until the sensor is disabled. | `10` |
### PMW 3360 Sensor
### PMW 3360 and PMW 3389 Sensor
This drivers supports multiple sensors_per_ controller, so 2 can be attached at the same side for split keyboards (or unsplit keyboards).
To use the PMW 3360 sensor, add this to your `rules.mk`
This drivers supports both the PMW 3360 and PMW 3389 sensor as well as multiple sensors of the same type_per_ controller, so 2 can be attached at the same side for split keyboards (or unsplit keyboards).
To use the **PMW 3360** sensor, add this to your `rules.mk`
```make
POINTING_DEVICE_DRIVER= pmw3360
```
The PMW 3360 is an SPI driven optical sensor, that uses a built in IR LED for surface tracking.
|`PMW3360_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
|`PMW3360_CS_PINS` | (Alternative) Sets the Cable Select pins connected to multiple sensors. | _not defined_ |
|`PMW3360_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` |
|`PMW3360_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
|`PMW3360_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` |
|`PMW3360_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
|`PMW3360_LIFTOFF_DISTANCE` | (Optional) Sets the lift off distance at run time | `0x02` |
|`ROTATIONAL_TRANSFORM_ANGLE` | (Optional) Allows for the sensor data to be rotated +/- 127 degrees directly in the sensor.| `0` |
|`PMW3360_FIRMWARE_UPLOAD_FAST` | (Optional) Skips the 15us wait between firmware blocks. | _not defined_ |
The CPI range is 100-12000, in increments of 100. Defaults to 1600 CPI.
To use multiple sensors, instead of setting `PMW3360_CS_PIN` you need to set `PMW3360_CS_PINS` and also handle and merge the read from this sensor in user code.
To use the **PMW3389** sensor, add this to your `rules.mk`
```make
POINTING_DEVICE_DRIVER= pmw3389
```
The CPI range is 50-16000, in increments of 50. Defaults to 2000 CPI.
Both PMW 3360 and PMW 3389 are SPI driven optical sensors, that use a built in IR LED for surface tracking.
| `PMW33XX_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | `POINTING_DEVICE_CS_PIN` |
| `PMW33XX_CS_PINS` | (Alternative) Sets the Cable Select pins connected to multiple sensors. | _not defined_ |
| `PMW33XX_CPI` | (Optional) Sets counts per inch sensitivity of the sensor. | _varies_ |
| `PMW33XX_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` |
| `PMW33XX_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
| `PMW33XX_LIFTOFF_DISTANCE` | (Optional) Sets the lift off distance at run time | `0x02` |
| `ROTATIONAL_TRANSFORM_ANGLE` | (Optional) Allows for the sensor data to be rotated +/- 127 degrees directly in the sensor. | `0` |
To use multiple sensors, instead of setting `PMW33XX_CS_PIN` you need to set `PMW33XX_CS_PINS` and also handle and merge the read from this sensor in user code.
Note that different (per sensor) values of CPI, speed liftoff, rotational angle or flipping of X/Y is not currently supported.
```c
// in config.h:
#define PMW3360_CS_PINS { B5, B6 }
#define PMW33XX_CS_PINS { B5, B6 }
// in keyboard.c:
#ifdef POINTING_DEVICE_ENABLE
voidpointing_device_init_kb(void){
pmw3360_init(1);// index 1 is the second device.
pointing_device_set_cpi(800);// applies to both sensors
pmw33xx_init(1);// index 1 is the second device.
pmw33xx_set_cpi(0,800);// applies to first sensor
pmw33xx_set_cpi(1,800);// applies to second sensor
pointing_device_init_user();
}
// Contains report from sensor #0 already, need to merge in from sensor #1
|`MOUSE_EXTENDED_REPORT` | (Optional) Enables support for extended mouse reports. (-32767 to 32767, instead of just -127 to 127). | _not defined_ |
|`POINTING_DEVICE_ROTATION_90` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ |
|`POINTING_DEVICE_ROTATION_180` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
|`POINTING_DEVICE_ROTATION_270` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
|`POINTING_DEVICE_INVERT_X` | (Optional) Inverts the X axis report. | _not defined_ |
|`POINTING_DEVICE_INVERT_Y` | (Optional) Inverts the Y axis report. | _not defined_ |
|`POINTING_DEVICE_MOTION_PIN` | (Optional) If supported, will only read from sensor if pin is active. | _not defined_ |
| `POINTING_DEVICE_TASK_THROTTLE_MS` | (Optional) Limits the frequency that the sensor is polled for motion. | _not defined_ |
| `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE` | (Optional) Enable inertial cursor. Cursor continues moving after a flick gesture and slows down by kinetic friction. | _not defined_ |
| `POINTING_DEVICE_GESTURES_SCROLL_ENABLE` | (Optional) Enable scroll gesture. The gesture that activates the scroll is device dependent. | _not defined_ |
| `POINTING_DEVICE_CS_PIN` | (Optional) Provides a default CS pin, useful for supporting multiple sensor configs. | _not defined_ |
| `POINTING_DEVICE_SDIO_PIN` | (Optional) Provides a default SDIO pin, useful for supporting multiple sensor configs. | _not defined_ |
| `POINTING_DEVICE_SCLK_PIN` | (Optional) Provides a default SCLK pin, useful for supporting multiple sensor configs. | _not defined_ |
!> When using `SPLIT_POINTING_ENABLE` the `POINTING_DEVICE_MOTION_PIN` functionality is not supported and `POINTING_DEVICE_TASK_THROTTLE_MS` will default to `1`. Increasing this value will increase transport performance at the cost of possible mouse responsiveness.
The `POINTING_DEVICE_CS_PIN`, `POINTING_DEVICE_SDIO_PIN`, and `POINTING_DEVICE_SCLK_PIN` provide a convenient way to define a single pin that can be used for an interchangeable sensor config. This allows you to have a single config, without defining each device. Each sensor allows for this to be overridden with their own defines.
!> Any pointing device with a lift/contact status can integrate inertial cursor feature into its driver, controlled by `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE`. e.g. PMW3360 can use Lift_Stat from Motion register. Note that `POINTING_DEVICE_MOTION_PIN` cannot be used with this feature; continuous polling of `get_report()` is needed to generate glide reports.
## Split Keyboard Configuration
The following configuration options are only available when using `SPLIT_POINTING_ENABLE` see [data sync options](feature_split_keyboard.md?id=data-sync-options). The rotation and invert `*_RIGHT` options are only used with `POINTING_DEVICE_COMBINED`. If using `POINTING_DEVICE_LEFT` or `POINTING_DEVICE_RIGHT` use the common configuration above to configure your pointing device.
|`POINTING_DEVICE_LEFT` | Pointing device on the left side (Required - pick one only) | _not defined_ |
|`POINTING_DEVICE_RIGHT` | Pointing device on the right side (Required - pick one only) | _not defined_ |
|`POINTING_DEVICE_COMBINED` | Pointing device on both sides (Required - pick one only) | _not defined_ |
|`POINTING_DEVICE_ROTATION_90_RIGHT` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ |
|`POINTING_DEVICE_ROTATION_180_RIGHT` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
|`POINTING_DEVICE_ROTATION_270_RIGHT` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
|`POINTING_DEVICE_INVERT_X_RIGHT` | (Optional) Inverts the X axis report. | _not defined_ |
|`POINTING_DEVICE_INVERT_Y_RIGHT` | (Optional) Inverts the Y axis report. | _not defined_ |
!> If there is a `_RIGHT` configuration option or callback, the [common configuration](feature_pointing_device.md?id=common-configuration) option will work for the left. For correct left/right detection you should setup a [handedness option](feature_split_keyboard?id=setting-handedness), `EE_HANDS` is usually a good option for an existing board that doesn't do handedness by hardware.
| `pointing_device_init_kb(void)` | Callback to allow for keyboard level initialization. Useful for additional hardware sensors. |
| `pointing_device_init_user(void)` | Callback to allow for user level initialization. Useful for additional hardware sensors. |
| `pointing_device_task_kb(mouse_report)` | Callback that sends sensor data, so keyboard code can intercept and modify the data. Returns a mouse report. |
@@ -274,11 +331,11 @@ The following configuration options are only available when using `SPLIT_POINTIN
| `pointing_device_handle_buttons(buttons, pressed, button)` | Callback to handle hardware button presses. Returns a `uint8_t`. |
| `pointing_device_get_cpi(void)` | Gets the current CPI/DPI setting from the sensor, if supported. |
| `pointing_device_set_cpi(uint16_t)` | Sets the CPI/DPI, if supported. |
| `pointing_device_get_report(void)` | Returns the current mouse report (as a `mouse_report_t` data structure). |
| `pointing_device_set_report(mouse_report)` | Sets the mouse report to the assigned `mouse_report_t` data structured passed to the function. |
| `pointing_device_send(void)` | Sends the current mouse report to the host system. Function can be replaced. |
| `pointing_device_get_report(void)` | Returns the current mouse report (as a `mouse_report_t` data structure). |
| `pointing_device_set_report(mouse_report)` | Sets the mouse report to the assigned `mouse_report_t` data structured passed to the function. |
| `pointing_device_send(void)` | Sends the current mouse report to the host system. Function can be replaced. |
| `has_mouse_report_changed(new_report, old_report)` | Compares the old and new `mouse_report_t` data and returns true only if it has changed. |
| `pointing_device_adjust_by_defines(mouse_report)` | Applies rotations and invert configurations to a raw mouse report. |
| `pointing_device_adjust_by_defines(mouse_report)` | Applies rotations and invert configurations to a raw mouse report. |
## Split Keyboard Callbacks and Functions
@@ -286,7 +343,7 @@ The following configuration options are only available when using `SPLIT_POINTIN
The combined functions below are only available when using `SPLIT_POINTING_ENABLE` and `POINTING_DEVICE_COMBINED`. The 2 callbacks `pointing_device_task_combined_*` replace the single sided equivalents above. See the [combined pointing devices example](feature_pointing_device.md?id=combined-pointing-devices)
| `pointing_device_set_shared_report(mouse_report)` | Sets the shared mouse report to the assigned `mouse_report_t` data structured passed to the function. |
| `pointing_device_set_cpi_on_side(bool, uint16_t)` | Sets the CPI/DPI of one side, if supported. Passing `true` will set the left and `false` the right` |
| `pointing_device_combine_reports(left_report, right_report)` | Returns a combined mouse_report of left_report and right_report (as a `mouse_report_t` data structure) |
@@ -430,4 +487,3 @@ report_mouse_t pointing_device_task_combined_user(report_mouse_t left_report, re
@@ -86,6 +86,7 @@ You can use between 1 and 4 IS31FL3733 IC's. Do not specify `DRIVER_ADDR_<N>` de
| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
| `ISSI_PWM_FREQUENCY` | (Optional) PWM Frequency Setting - IS31FL3733B only | 0 |
| `ISSI_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF |
| `ISSI_SWPULLUP` | (Optional) Set the value of the SWx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
| `ISSI_CSPULLUP` | (Optional) Set the value of the CSx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | |
@@ -172,6 +173,7 @@ Configure the hardware via your `config.h`:
| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
| `ISSI_PWM_FREQUENCY` | (Optional) PWM Frequency Setting - IS31FL3737B only | 0 |
| `ISSI_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF |
| `ISSI_SWPULLUP` | (Optional) Set the value of the SWx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
| `ISSI_CSPULLUP` | (Optional) Set the value of the CSx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | |
@@ -409,6 +411,7 @@ You can use up to 2 AW20216 IC's. Do not specify `DRIVER_<N>_xxx` defines for IC
| `DRIVER_LED_TOTAL` | (Required) How many RGB lights are present across all drivers | |
| `AW_SCALING_MAX` | (Optional) LED current scaling value (0-255, higher values mean LED is brighter at full PWM) | 150 |
| `AW_GLOBAL_CURRENT_MAX` | (Optional) Driver global current limit (0-255, higher values means the driver may consume more power) | 150 |
| `AW_SPI_MODE` | (Optional) Mode for SPI communication (0-3, defines polarity and phase of the clock) | 3 |
| `AW_SPI_DIVISOR` | (Optional) Clock divisor for SPI communication (powers of 2, smaller numbers means faster communication, should not be less than 4) | 4 |
Here is an example using 2 drivers.
@@ -665,11 +668,36 @@ In order to change the delay of temperature decrease define `RGB_MATRIX_TYPING_H
Heatmap effect may not light up the correct adjacent LEDs for certain key matrix layout such as split keyboards. The following define will limit the effect to pressed keys only:
As heatmap uses the physical position of the leds set in the g_led_config, you may need to tweak the following options to get the best effect for your keyboard. Note the size of this grid is `224x64`.
Limit the distance the effect spreads to surrounding keys.
```c
#define RGB_MATRIX_TYPING_HEATMAP_SPREAD 40
```
Limit how hot surrounding keys get from each press.
Solid reactive effects will pulse RGB light on key presses with user configurable hues. To enable gradient mode that will automatically change reactive color, add the following define:
```c
#define RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE
```
Gradient mode will loop through the color wheel hues over time and its duration can be controlled with the effect speed keycodes (`RGB_SPI`/`RGB_SPD`).
By setting `RGB_MATRIX_CUSTOM_USER = yes` in `rules.mk`, new effects can be defined directly from your keymap or userspace, without having to edit any QMK core files. To declare new effects, create a `rgb_matrix_user.inc` file in the user keymap directory or userspace folder.
@@ -777,6 +805,7 @@ These are defined in [`color.h`](https://github.com/qmk/qmk_firmware/blob/master
#define RGB_MATRIX_DISABLE_KEYCODES // disables control of rgb matrix by keycodes (must use code functions to control the feature)
#define RGB_MATRIX_SPLIT { X, Y } // (Optional) For split keyboards, the number of LEDs connected on each half. X = left, Y = Right.
// If RGB_MATRIX_KEYPRESSES or RGB_MATRIX_KEYRELEASES is enabled, you also will want to enable SPLIT_TRANSPORT_MIRROR
#define RGB_TRIGGER_ON_KEYDOWN // Triggers RGB keypress events on key down. This makes RGB control feel more responsive. This may cause RGB to not function properly on some boards
@@ -125,13 +125,14 @@ Check out [this video](https://youtube.com/watch?v=VKrpPAHlisY) for a demonstrat
Note: For versions older than 0.6.117, The mode numbers were written directly. In `quantum/rgblight/rgblight.h` there is a contrast table between the old mode number and the current symbol.
### Effect and Animation Toggles
Use these defines to add or remove animations from the firmware. When you are running low on flash space, it can be helpful to disable animations you are not using.
The secure feature aims to prevent unwanted interaction without user intervention.
?> Secure does **not** currently implement encryption/decryption/etc and should not be a replacement where a strong hardware/software based solution is required.
### Unlock sequence
To unlock, the user must perform a set of actions. This can optionally be configured to be multiple keys.
* While unlocking all keyboard input is ignored
* Incorrect attempts will revert back to the previously locked state
### Automatic Locking
Once unlocked, the keyboard will revert back to a locked state after the configured timeout.
The timeout can be refreshed by using the `secure_activity_event` function, for example from one of the various [hooks](custom_quantum_functions.md).
The Send String API is part of QMK's macro system. It allows for sequences of keystrokes to be sent automatically.
The full ASCII character set is supported, along with all of the keycodes in the Basic Keycode range (as these are the only ones that will actually be sent to the host).
?> Unicode characters are **not** supported with this API -- see the [Unicode](feature_unicode.md) feature instead.
## Usage
Send String is enabled by default, so there is usually no need for any special setup. However, if it is disabled, add the following to your `rules.mk`:
|`SENDSTRING_BELL`|*Not defined* |If the [Audio](feature_audio.md) feature is enabled, the `\a` character (ASCII `BEL`) will beep the speaker.|
|`BELL_SOUND` |`TERMINAL_SOUND`|The song to play when the `\a` character is encountered. By default, this is an eighth note of C5. |
## Keycodes
The Send String functions accept C string literals, but specific keycodes can be injected with the below macros. All of the keycodes in the [Basic Keycode range](keycodes_basic.md) are supported (as these are the only ones that will actually be sent to the host), but with an `X_` prefix instead of `KC_`.
|`SS_TAP(x)` |Send a keydown, then keyup, event for the given Send String keycode|
|`SS_DOWN(x)` |Send a keydown event for the given Send String keycode |
|`SS_UP(x)` |Send a keyup event for the given Send String keycode |
|`SS_DELAY(ms)`|Wait for `ms` milliseconds |
The following characters are also mapped to their respective keycodes for convenience:
|Character|Hex |ASCII|Keycode |
|---------|------|-----|--------------|
|`\b` |`\x08`|`BS` |`KC_BACKSPACE`|
|`\e` |`\x09`|`ESC`|`KC_ESCAPE` |
|`\n` |`\x0A`|`LF` |`KC_ENTER` |
|`\t` |`\x1B`|`TAB`|`KC_TAB` |
| |`\x7F`|`DEL`|`KC_DELETE` |
### Language Support
By default, Send String assumes your OS keyboard layout is set to US ANSI. If you are using a different keyboard layout, you can [override the lookup tables used to convert ASCII characters to keystrokes](reference_keymap_extras.md#sendstring-support).
## Examples
### Hello World
A simple custom keycode which types out "Hello, world!" and the Enter key when pressed.
@@ -10,6 +10,8 @@ For this, we will mostly be talking about the generic implementation used by the
!> ARM split supports most QMK subsystems when using the 'serial' and 'serial_usart' drivers. I2C slave is currently unsupported.
!> Both sides must use the same MCU family, for eg two Pro Micro-compatible controllers or two Blackpills. Currently, mixing AVR and ARM is not possible as ARM vs AVR uses different method for serial communication, and are not compatible. Moreover Blackpill's uses 3.3v logic, and atmega32u4 uses 5v logic.
## Compatibility Overview
| Transport | AVR | ARM |
@@ -141,6 +143,9 @@ Next, you will have to flash the EEPROM files once for the correct hand to the c
* ARM controllers with a DFU compatible bootloader (e.g. Proton-C):
*`:dfu-util-split-left`
*`:dfu-util-split-right`
* ARM controllers with a UF2 compatible bootloader:
*`:uf2-split-left`
*`:uf2-split-right`
Example:
@@ -365,7 +370,7 @@ There are some settings that you may need to configure, based on how the hardwar
#define MATRIX_COL_PINS_RIGHT { <col pins> }
```
This allows you to specify a different set of pins for the matrix on the right side. This is useful if you have a board with differently-shaped halves that requires a different configuration (such as Keebio's Quefrency).
This allows you to specify a different set of pins for the matrix on the right side. This is useful if you have a board with differently-shaped halves that requires a different configuration (such as Keebio's Quefrency). The number of pins in the right and left matrices must be the same, if you have a board with a different number of rows or columns on one side, pad out the extra spaces with `NO_PIN` and make sure you add the unused rows or columns to your matrix.
@@ -8,46 +8,107 @@ The [Open Steno Project](https://www.openstenoproject.org/) has built an open-so
Plover can work with any standard QWERTY keyboard, although it is more efficient if the keyboard supports NKRO (n-key rollover) to allow Plover to see all the pressed keys at once. An example keymap for Plover can be found in `planck/keymaps/default`. Switching to the `PLOVER` layer adjusts the position of the keyboard to support the number bar.
To use Plover with QMK just enable NKRO and optionally adjust your layout if you have anything other than a standard layout. You may also want to purchase some steno-friendly keycaps to make it easier to hit multiple keys.
To enable NKRO, add `NKRO_ENABLE = yes` in your `rules.mk` and make sure to press `NK_ON` to turn it on because `NKRO_ENABLE = yes` merely adds the possibility of switching to NKRO mode but it doesn't automatically switch to it. If you want to automatically switch, add `#define FORCE_NKRO` in your `config.h`.
You may also need to adjust your layout, either in QMK or in Plover, if you have anything other than a standard layout. You may also want to purchase some steno-friendly keycaps to make it easier to hit multiple keys.
## Plover with Steno Protocol :id=plover-with-steno-protocol
Plover also understands the language of several steno machines. QMK can speak a couple of these languages, TX Bolt and GeminiPR. An example layout can be found in `planck/keymaps/steno`.
Plover also understands the language of several steno machines. QMK can speak a couple of these languages: TX Bolt and GeminiPR. An example layout can be found in `planck/keymaps/steno`.
When QMK speaks to Plover over a steno protocol Plover will not use the keyboard as input. This means that you can switch back and forth between a standard keyboard and your steno keyboard, or even switch layers from Plover to standard and back without needing to activate/deactivate Plover.
When QMK speaks to Plover over a steno protocol, Plover will not use the keyboard as input. This means that you can switch back and forth between a standard keyboard and your steno keyboard, or even switch layers from Plover to standard and back without needing to activate/deactivate Plover.
In this mode Plover expects to speak with a steno machine over a serial port so QMK will present itself to the operating system as a virtual serial port in addition to a keyboard. By default QMK will speak the TX Bolt protocol but can be switched to GeminiPR; the last protocol used is stored in non-volatile memory so QMK will use the same protocol on restart.
In this mode, Plover expects to speak with a steno machine over a serial port so QMK will present itself to the operating system as a virtual serial port in addition to a keyboard.
> Note: Due to hardware limitations you may not be able to run both a virtual serial port and mouse emulation at the same time.
> Note: Due to hardware limitations, you might not be able to run both a virtual serial port and mouse emulation at the same time.
!> Serial stenography protocols are not supported on [V-USB keyboards](compatible_microcontrollers#atmel-avr).
To enable stenography protocols, add the following lines to your `rules.mk`:
```mk
STENO_ENABLE= yes
```
### TX Bolt :id=tx-bolt
TX Bolt communicates the status of 24 keys over a very simple protocol in variable-sized (1-5 byte) packets.
TX Bolt communicates the status of 24 keys over a simple protocol in variable-sized (1–4 bytes) packets.
To select TX Bolt, add the following lines to your `rules.mk`:
```mk
STENO_ENABLE= yes
STENO_PROTOCOL= txbolt
```
Each byte of the packet represents a different group of steno keys. Determining the group of a certain byte of the packet is done by checking the first two bits, the remaining bits are set if the corresponding steno key was pressed for the stroke. The last set of keys (as indicated by leading `11`) needs to keep track of less keys than there are bits so one of the bits is constantly 0.
The start of a new packet can be detected by comparing the group “ID” (the two MSBs) of the current byte to that of the previously received byte. If the group “ID” of the current byte is smaller or equal to that of the previous byte, it means that the current byte is the beginning of a new packet.
The format of TX Bolt packets is shown below.
```
00HWPKTS 01UE*OAR 10GLBPRF 110#ZDST
```
Examples of steno strokes and the associated packet:
GeminiPR encodes 42 keys into a 6-byte packet. While TX Bolt contains everything that is necessary for standard stenography, GeminiPR opens up many more options, including supporting non-English theories.
GeminiPR encodes 42 keys into a 6-byte packet. While TX Bolt contains everything that is necessary for standard stenography, GeminiPR opens up many more options, including differentiating between top and bottom `S-`, and supporting non-English theories.
To select GeminiPR, add the following lines to your `rules.mk`:
```mk
STENO_ENABLE= yes
STENO_PROTOCOL= geminipr
```
All packets in the GeminiPR protocol consist of exactly six bytes, used as bit-arrays for different groups of keys. The beginning of a packet is indicated by setting the most significant bit (MSB) to 1 while setting the MSB of the remaining five bytes to 0.
The format of GeminiPR packets is shown below.
```
1 Fn #1 #2 #3 #4 #5 #6
0 S1- S2- T- K- P- W- H-
0 R- A- O- *1 *2 res1 res2
0 pwr *3 *4 -E -U -F -R
0 -P -B -L -G -T -S -D
0 #7 #8 #9 #A #B #C -Z
```
Examples of steno strokes and the associated packet:
### Switching protocols on the fly :id=switching-protocols-on-the-fly
If you wish to switch the serial protocol used to transfer the steno chords without having to recompile your keyboard firmware every time, you can press the `QK_STENO_BOLT` and `QK_STENO_GEMINI` keycodes in order to switch protocols on the fly.
To enable these special keycodes, add the following lines to your `rules.mk`:
```mk
STENO_ENABLE= yes
STENO_PROTOCOL= all
```
If you want to switch protocols programatically, as part of a custom macro for example, don't use `tap_code(QK_STENO_*)`, as `tap_code` only supports [basic keycodes](keycodes_basic). Instead, you should use `steno_set_mode(STENO_MODE_*)`, whose valid arguments are `STENO_MODE_BOLT` and `STENO_MODE_GEMINI`.
The default protocol is Gemini PR but the last protocol used is stored in non-volatile memory so QMK will remember your choice between reboots of your keyboard — assuming that your keyboard features (emulated) EEPROM.
Naturally, this option takes the most amount of firmware space as it needs to compile the code for all the available stenography protocols. In most cases, compiling a single stenography protocol is sufficient.
The default value for `STENO_PROTOCOL` is `all`.
## Configuring QMK for Steno :id=configuring-qmk-for-steno
Firstly, enable steno in your keymap's Makefile. You may also need disable mousekeys, extra keys, or another USB endpoint to prevent conflicts. The builtin USB stack for some processors only supports a certain number of USB endpoints and the virtual serial port needed for steno fills 3 of them.
After enabling stenography and optionally selecting a protocol, you may also need disable mousekeys, extra keys, or another USB endpoint to prevent conflicts. The builtin USB stack for some processors only supports a certain number of USB endpoints and the virtual serial port needed for steno fills 3 of them.
```make
STENO_ENABLE= yes
MOUSEKEY_ENABLE= no
```
!> If you had *explicitly* set `VIRSTER_ENABLE = no`, none of the serial stenography protocols (GeminiPR, TX Bolt) will work properly. You are expected to either set it to `yes`, remove the line from your `rules.mk` or send the steno chords yourself in an alternative way using the [provided interceptable hooks](#interfacing-with-the-code).
In your keymap create a new layer for Plover. You will need to include `keymap_steno.h`. See `planck/keymaps/steno/keymap.c` for an example. Remember to create a key to switch to the layer as well as a key for exiting the layer. If you would like to switch modes on the fly you can use the keycodes `QK_STENO_BOLT` and `QK_STENO_GEMINI`. If you only want to use one of the protocols you may set it up in your initialization function:
In your keymap, create a new layer for Plover, that you can fill in with the [steno keycodes](#keycode-reference) (you will need to include `keymap_steno.h`, see `planck/keymaps/steno/keymap.c` for an example). Remember to create a key to switch to the layer as well as a key for exiting the layer.
```c
voideeconfig_init_user(){
steno_set_mode(STENO_MODE_GEMINI);// or STENO_MODE_BOLT
}
```
Once you have your keyboard flashed, launch Plover. Click the 'Configure...' button. In the 'Machine' tab, select the Stenotype Machine that corresponds to your desired protocol. Click the 'Configure...' button on this tab and enter the serial port or click 'Scan'. Baud rate is fine at 9600 (although you should be able to set as high as 115200 with no issues). Use the default settings for everything else (Data Bits: 8, Stop Bits: 1, Parity: N, no flow control).
Once you have your keyboard flashed launch Plover. Click the 'Configure...' button. In the 'Machine' tab select the Stenotype Machine that corresponds to your desired protocol. Click the 'Configure...' button on this tab and enter the serial port or click 'Scan'. Baud rate is fine at 9600 (although you should be able to set as high as 115200 with no issues). Use the default settings for everything else (Data Bits: 8, Stop Bits: 1, Parity: N, no flow control).
On the display tab click 'Open stroke display'. With Plover disabled you should be able to hit keys on your keyboard and see them show up in the stroke display window. Use this to make sure you have set up your keymap correctly. You are now ready to steno!
To test your keymap, you can chord keys on your keyboard and either look at the output of the 'paper tape' (Tools > Paper Tape) or that of the 'layout display' (Tools > Layout Display). If your strokes correctly show up, you are now ready to steno!
## Learning Stenography :id=learning-stenography
@@ -60,7 +121,7 @@ On the display tab click 'Open stroke display'. With Plover disabled you should
The steno code has three interceptable hooks. If you define these functions, they will be called at certain points in processing; if they return true, processing continues, otherwise it's assumed you handled things.
This function is called when a chord is about to be sent. Mode will be one of `STENO_MODE_BOLT` or `STENO_MODE_GEMINI`. This represents the actual chord that would be sent via whichever protocol. You can modify the chord provided to alter what gets sent. Remember to return true if you want the regular sending process to happen.
This function is called when a keypress has come in, before it is processed. The keycode should be one of `QK_STENO_BOLT`, `QK_STENO_GEMINI`, or one of the `STN_*` key values.
This function is called after a key has been processed, but before any decision about whether or not to send a chord. If `IS_PRESSED(record->event)` is false, and `pressed` is 0 or 1, the chord will be sent shortly, but has not yet been sent. This is where to put hooks for things like, say, live displays of steno chords or keys.
This function is called after a key has been processed, but before any decision about whether or not to send a chord. This is where to put hooks for things like, say, live displays of steno chords or keys.
If `IS_PRESSED(record->event)` is false, and `n_pressed_keys` is 0 or 1, the chord will be sent shortly, but has not yet been sent. This relieves you of the need of keeping track of where a packet ends and another begins.
The `chord` argument contains the packet of the current chord as specified by the protocol in use. This is *NOT* simply a list of chorded steno keys of the form `[STN_E, STN_U, STN_BR, STN_GR]`. Refer to the appropriate protocol section of this document to learn more about the format of the packets in your steno protocol/mode of choice.
The `n_pressed_keys` argument is the number of physical keys actually being held down.
This is not always equal to the number of bits set to 1 (aka the [Hamming weight](https://en.wikipedia.org/wiki/Hamming_weight)) in `chord` because it is possible to simultaneously press down four keys, then release three of those four keys and then press yet another key while the fourth finger is still holding down its key.
At the end of this scenario given as an example, `chord` would have five bits set to 1 but
`n_pressed_keys` would be set to 2 because there are only two keys currently being pressed down.
## Keycode Reference :id=keycode-reference
As defined in `keymap_steno.h`.
You must include `keymap_steno.h` to your `keymap.c` with `#include "keymap_steno.h"` before you can use these keycodes
> Note: TX Bolt does not support the full set of keys. The TX Bolt implementation in QMK will map the GeminiPR keys to the nearest TX Bolt key so that one key map will work for both.
@@ -124,10 +193,10 @@ As defined in `keymap_steno.h`.
|`STN_SR`|`STN_SR`| `-S`|
|`STN_DR`|`STN_DR`| `-D`|
|`STN_ZR`|`STN_ZR`| `-Z`|
|`STN_FN`|| (GeminiPR only)|
|`STN_RES1`||(GeminiPR only)|
|`STN_RES2`||(GeminiPR only)|
|`STN_PWR`||(GeminiPR only)|
|`STN_FN`|| (Function)|
|`STN_RES1`||(Reset 1)|
|`STN_RES2`||(Reset 2)|
|`STN_PWR`||(Power)|
If you do not want to hit two keys with one finger combined keycodes can be used. These are also defined in `keymap_steno.h`, and causes both keys to be reported as pressed or released. To use these keycodes define `STENO_COMBINEDMAP` in your `config.h` file.
@@ -14,55 +14,48 @@ Optionally, you might want to set a custom `TAPPING_TERM` time by adding somethi
```c
#define TAPPING_TERM 175
#define TAPPING_TERM_PER_KEY
```
The `TAPPING_TERM` time is the maximum time allowed between taps of your Tap Dance key, and is measured in milliseconds. For example, if you used the above `#define` statement and set up a Tap Dance key that sends `Space` on single-tap and `Enter` on double-tap, then this key will send `ENT` only if you tap this key twice in less than 175ms. If you tap the key, wait more than 175ms, and tap the key again you'll end up sending `SPC SPC` instead.
The `TAPPING_TERM` time is the maximum time allowed between taps of your Tap Dance key, and is measured in milliseconds. For example, if you used the above `#define` statement and set up a Tap Dance key that sends `Space` on single-tap and `Enter` on double-tap, then this key will send `ENT` only if you tap this key twice in less than 175ms. If you tap the key, wait more than 175ms, and tap the key again you'll end up sending `SPC SPC` instead. The `TAPPING_TERM_PER_KEY` definition is only needed if you control the tapping term through a [custom `get_tapping_term` function](tap_hold.md#tapping_term), which may be needed because `TAPPING_TERM` affects not just tap-dance keys.
Next, you will want to define some tap-dance keys, which is easiest to do with the `TD()` macro, that takes a number which will later be used as an index into the `tap_dance_actions` array.
Next, you will want to define some tap-dance keys, which is easiest to do with the `TD()` macro. That macro takes a number which will later be used as an index into the `tap_dance_actions` array and turns it into a tap-dance keycode.
After this, you'll want to use the `tap_dance_actions` array to specify what actions shall be taken when a tap-dance key is in action. Currently, there are five possible options:
*`ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: Sends the `kc1` keycode when tapped once, `kc2` otherwise. When the key is held, the appropriate keycode is registered: `kc1` when pressed and held, `kc2` when tapped once, then pressed and held.
*`ACTION_TAP_DANCE_LAYER_MOVE(kc, layer)`: Sends the `kc` keycode when tapped once, or moves to `layer`. (this functions like the `TO` layer keycode).
* This is the same as `ACTION_TAP_DANCE_DUAL_ROLE`, but renamed to something that is clearer about its functionality. Both names will work.
*`ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer)`: Sends the `kc` keycode when tapped once, or toggles the state of `layer`. (this functions like the `TG` layer keycode).
*`ACTION_TAP_DANCE_FN(fn)`: Calls the specified function - defined in the user keymap - with the final tap count of the tap dance action.
*`ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: Calls the first specified function - defined in the user keymap - on every tap, the second function when the dance action finishes (like the previous option), and the last function when the tap dance action resets.
* ~~`ACTION_TAP_DANCE_FN_ADVANCED_TIME(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn, tap_specific_tapping_term)`~~: This functions identically to the `ACTION_TAP_DANCE_FN_ADVANCED` function, but uses a custom tapping term for it, instead of the predefined `TAPPING_TERM`.
* This is deprecated in favor of the Per Key Tapping Term functionality, as outlined [here](tap_hold.md#tapping-term). You'd want to check for the specific `TD()` macro that you want to use (such as `TD(TD_ESC_CAPS)`) instead of using this specific Tap Dance function.
The first option is enough for a lot of cases, that just want dual roles. For example, `ACTION_TAP_DANCE_DOUBLE(KC_SPC, KC_ENT)` will result in `Space` being sent on single-tap, `Enter` otherwise.
!> Keep in mind that only [basic keycodes](keycodes_basic.md) are supported here. Custom keycodes are not supported.
Similar to the first option, the second option is good for simple layer-switching cases.
Similar to the first option, the second and third option are good for simple layer-switching cases.
For more complicated cases, use the third or fourth options (examples of each are listed below).
Finally, the fifth option is particularly useful if your non-Tap-Dance keys start behaving weirdly after adding the code for your Tap Dance keys. The likely problem is that you changed the `TAPPING_TERM` time to make your Tap Dance keys easier for you to use, and that this has changed the way your other keys handle interrupts.
For more complicated cases, like blink the LEDs, fiddle with the backlighting, and so on, use the fourth or fifth option. Examples of each are listed below.
## Implementation Details :id=implementation
Well, that's the bulk of it! You should now be able to work through the examples below, and to develop your own Tap Dance functionality. But if you want a deeper understanding of what's going on behind the scenes, then read on for the explanation of how it all works!
The main entry point is`process_tap_dance()`, called from `process_record_quantum()`, which is run for every keypress, and our handler gets to run early. This function checks whether the key pressed is a tap-dance key. If it is not, and a tap-dance was in action, we handle that first, and enqueue the newly pressed key. If it is a tap-dance key, then we check if it is the same as the already active one (if there's one active, that is). If it is not, we fire off the old one first, then register the new one. If it was the same, we increment the counter and reset the timer.
Let's go over the three functions mentioned in`ACTION_TAP_DANCE_FN_ADVANCED` in a little more detail. They all receive the same too arguments: a pointer to a structure that holds all dance related state information, and a pointer to a use case specific state variable. The three functions differ in when they are called. The first, `on_each_tap_fn()`, is called every time the tapdance key is *pressed*. Before it is called, the counter is incremented and the timer is reset. The second function, `on_dance_finished_fn()`, is called when the tapdance is interrupted or ends because `TAPPING_TERM` milliseconds have passed since the last tap. When the `finished` field of the dance state structure is set to `true`, the `on_dance_finished_fn()` is skipped. After `on_dance_finished_fn()` was called or would have been called, but no sooner than when the tap dance key is *released*, `on_dance_reset_fn()` is called. It is possible to end a tap dance immediately, skipping `on_dance_finished_fn()`, but not `on_dance_reset_fn`, by calling `reset_tap_dance(state)`.
To accomplish this logic, the tap dance mechanics use three entry points. The main entry point is `process_tap_dance()`, called from `process_record_quantum()`*after*`process_record_kb()` and `process_record_user()`. This function is responsible for calling `on_each_tap_fn()` and `on_dance_reset_fn()`. In order to handle interruptions of a tap dance, another entry point, `preprocess_tap_dance()` is run right at the beginning of `process_record_quantum()`. This function checks whether the key pressed is a tap-dance key. If it is not, and a tap-dance was in action, we handle that first, and enqueue the newly pressed key. If it is a tap-dance key, then we check if it is the same as the already active one (if there's one active, that is). If it is not, we fire off the old one first, then register the new one. Finally, `tap_dance_task()` periodically checks whether `TAPPING_TERM` has passed since the last key press and finishes a tap dance if that is the case.
This means that you have `TAPPING_TERM` time to tap the key again; you do not have to input all the taps within a single `TAPPING_TERM` timeframe. This allows for longer tap counts, with minimal impact on responsiveness.
Our next stop is `tap_dance_task()`. This handles the timeout of tap-dance keys.
For the sake of flexibility, tap-dance actions can be either a pair of keycodes, or a user function. The latter allows one to handle higher tap counts, or do extra things, like blink the LEDs, fiddle with the backlighting, and so on. This is accomplished by using an union, and some clever macros.
## Examples :id=examples
### Simple Example :id=simple-example
### Simple Example: Send `ESC` on Single Tap, `CAPS_LOCK` on Double Tap :id=simple-example
Here's a simple example for a single definition:
1. In your `rules.mk`, add `TAP_DANCE_ENABLE = yes`
2. In your `config.h` (which you can copy from `qmk_firmware/keyboards/planck/config.h` to your keymap directory), add `#define TAPPING_TERM 200`
3. In your `keymap.c` file, define the variables and definitions, then add to your keymap:
2. In your `keymap.c` file, define the variables and definitions, then add to your keymap:
```c
// Tap Dance declarations
@@ -92,40 +85,15 @@ All the enums used in the examples are declared like this:
```c
// Enums defined for all examples:
enum{
CT_SE,
CT_CLN,
TD_ESC_CAPS,
CT_EGG,
CT_FLSH,
X_TAP_DANCE
CT_CLN,
X_CTL,
};
```
#### Example 1: Send `:` on Single Tap, `;` on Double Tap :id=example-1
#### Example 3: Send `:` on Tap, `;` on Hold :id=example-3
With a little effort, powerful tap-hold configurations can be implemented as tap dances. To emit taps as early as possible, we need to act on releases of the tap dance key. There is no callback for this in the tap dance framework, so we use `process_record_user()`.
@@ -329,7 +358,7 @@ And then simply use `TD(X_CTL)` anywhere in your keymap.
If you want to implement this in your userspace, then you may want to check out how [DanielGGordon](https://github.com/qmk/qmk_firmware/tree/master/users/gordon) has implemented this in their userspace.
> In this configuration "hold" takes place **after** tap dance timeout (see `ACTION_TAP_DANCE_FN_ADVANCED_TIME`). To achieve instant hold, remove `state->interrupted` checks in conditions. As a result you may use comfortable longer tapping periods to have more time for taps and not to wait too long for holds (try starting with doubled `TAPPING_TERM`).
> In this configuration "hold" takes place **after** tap dance timeout. To achieve instant hold, remove `state->interrupted` checks in conditions. As a result you may use comfortable longer tapping periods to have more time for taps and not to wait too long for holds (try starting with doubled `TAPPING_TERM`).
#### Example 5: Using tap dance for advanced mod-tap and layer-tap keys :id=example-5
The above code is similar to that used in previous examples. The one point to note is that we need to be able to check which layers are active at any time so we can toggle them if needed. To do this we use the `layer_state_is(layer)` function which returns `true` if the given `layer` is active.
@@ -521,6 +560,6 @@ The use of `cur_dance()` and `ql_tap_state` mirrors the above examples.
The `case: TD_SINGLE_TAP` in `ql_finished` is similar to the above examples. The `TD_SINGLE_HOLD` case works in conjunction with `ql_reset()` to switch to `_MY_LAYER` while the tap dance key is held, and to switch away from `_MY_LAYER` when the key is released. This mirrors the use of `MO(_MY_LAYER)`. The `TD_DOUBLE_TAP` case works by checking whether `_MY_LAYER` is the active layer, and toggling it on or off accordingly. This mirrors the use of `TG(_MY_LAYER)`.
`tap_dance_actions[]` works similar to the above examples. Note that I used `ACTION_TAP_DANCE_FN_ADVANCED_TIME()` instead of `ACTION_TAP_DANCE_FN_ADVANCED()`. This is because I like my `TAPPING_TERM` to be short (\~175ms) for my non-tap-dance keys but find that this is too quick for me to reliably complete tap dance actions - thus the increased time of 275ms here.
`tap_dance_actions[]` works similar to the above examples. Note that, additionally, I set a longer tapping term for the tap dance keys. This is because I like my `TAPPING_TERM` to be short (\~175ms) for my non-tap-dance keys but find that this is too quick for me to reliably complete tap dance actions - thus the increased time of 275ms here. In order for the per-key tapping terms to take effect, `TAPPING_TERM_PER_KEY` must be defined in your `config.h`.
Finally, to get this tap dance key working, be sure to include `TD(QUOT_LAYR)` in your `keymaps[]`.
> This feature is currently *huge*, and should probably only be put on boards with a lot of memory, or for fun.
The terminal feature is a command-line-like interface designed to communicate through a text editor with keystrokes. It's beneficial to turn off auto-indent features in your editor.
To enable, stick this in your `rules.mk` or `Makefile`:
TERMINAL_ENABLE = yes
And use the `TERM_ON` and `TERM_OFF` keycodes to turn it on or off.
When enabled, a `> ` prompt will appear, where you'll be able to type, backspace (a bell will ding if you reach the beginning and audio is enabled), and hit enter to send the command. Arrow keys are currently disabled so it doesn't get confused. Moving your cursor around with the mouse is discouraged.
`#define TERMINAL_HELP` enables some other output helpers that aren't really needed with this page.
Pressing "up" and "down" will allow you to cycle through the past 5 commands entered.
## Future Ideas
* Keyboard/user-extensible commands
* Smaller footprint
* Arrow key support
* Command history - Done
* SD card support
* LCD support for buffer display
* Keycode -> name string LUT
* Layer status
* *Analog/digital port read/write*
* RGB mode stuff
* Macro definitions
* EEPROM read/write
* Audio control
## Current Commands
### `about`
Prints out the current version of QMK with a build date:
```
> about
QMK Firmware
v0.5.115-7-g80ed73-dirty
Built: 2017-08-29-20:24:44
```
### `print-buffer`
Outputs the last 5 commands entered
```
> print-buffer
0. print-buffer
1. help
2. about
3. keymap 0
4. help
5. flush-buffer
```
### `flush-buffer`
Clears command buffer
```
> flush-buffer
Buffer cleared!
```
### `help`
Prints out the available commands:
```
> help
commands available:
about help keycode keymap exit print-buffer flush-buffer
```
### `keycode <layer> <row> <col>`
Prints out the keycode value of a certain layer, row, and column:
@@ -127,7 +127,7 @@ The following input modes are available:
By default, this mode uses Ctrl+Shift+U (`LCTL(LSFT(KC_U))`) to start Unicode input, but this can be changed by defining [`UNICODE_KEY_LNX`](#input-key-configuration) with a different keycode. This might be required for IBus versions ≥1.5.15, where Ctrl+Shift+U behavior is consolidated into Ctrl+Shift+E.
Users who wish support in non-GTK apps without IBus may need to resort to a more indirect method, such as creating a custom keyboard layout ([more on this method](#custom-linux-layout)).
* **`UC_WIN`**: _(not recommended)_ Windows built-in hex numpad Unicode input. Supports code points up to `0xFFFF`.
To enable, create a registry key under `HKEY_CURRENT_USER\Control Panel\Input Method` of type `REG_SZ` called `EnableHexNumpad` and set its value to `1`. This can be done from the Command Prompt by running `reg add "HKCU\Control Panel\Input Method" -v EnableHexNumpad -t REG_SZ -d 1` with administrator privileges. Reboot afterwards.
@@ -172,6 +172,7 @@ You can switch the input mode at any time by using the following keycodes. Addin
|`UNICODE_MODE_WIN` |`UC_M_WI`|`UC_WIN` |Switch to Windows input |
|`UNICODE_MODE_BSD` |`UC_M_BS`|`UC_BSD` |Switch to BSD input _(not implemented)_ |
|`UNICODE_MODE_WINC` |`UC_M_WC`|`UC_WINC` |Switch to Windows input using WinCompose |
|`UNICODE_MODE_EMACS` |`UC_M_EM`|`UC_EMACS` |Switch to emacs (`C-x-8 RET`) |
You can also switch the input mode by calling `set_unicode_input_mode(x)` in your code, where _x_ is one of the above input mode constants (e.g. `UC_LNX`).
1. Enter the bootloader using any of the following methods:
* Press the `RESET` keycode
* Press the `QK_BOOT` keycode
* Press the `RESET` button on the PCB if available
* Short RST to GND quickly
2. Wait for the OS to detect the device
@@ -87,7 +87,7 @@ Compatible flashers:
Flashing sequence:
1. Enter the bootloader using any of the following methods (you only have 7 seconds to flash once it enters; some variants may require you to reset twice within 750 milliseconds):
* Press the `RESET` keycode
* Press the `QK_BOOT` keycode
* Press the `RESET` button on the PCB if available
* Short RST to GND quickly
2. Wait for the OS to detect the device
@@ -123,7 +123,7 @@ Compatible flashers:
Flashing sequence:
1. Enter the bootloader using any of the following methods (you only have 7 seconds to flash once it enters):
* Press the `RESET` keycode
* Press the `QK_BOOT` keycode
* Press the `RESET` button on the Teensy or PCB if available
* short RST to GND quickly
2. Wait for the OS to detect the device
@@ -153,7 +153,7 @@ Compatible flashers:
Flashing sequence:
1. Enter the bootloader using any of the following methods:
* Press the `RESET` keycode
* Press the `QK_BOOT` keycode
* Keep the `BOOT` button held while quickly tapping the `RESET` button on the PCB
2. Wait for the OS to detect the device
3. Flash a .hex file
@@ -182,7 +182,7 @@ Compatible flashers:
Flashing sequence:
1. Enter the bootloader using any of the following methods:
* Tap the `RESET` keycode
* Tap the `QK_BOOT` keycode
* Hold the salt key while plugging the keyboard in - for PS2AVRGB boards, this is usually the key connected to MCU pins A0 and B0, otherwise it will be documented in your keyboard's readme
2. Wait for the OS to detect the device
3. Flash a .hex file
@@ -223,7 +223,7 @@ Compatible flashers:
Flashing sequence:
1. Enter the bootloader using any of the following methods:
* Press the `RESET` keycode
* Press the `QK_BOOT` keycode
* Press the `RESET` button on the PCB if available
* short RST to GND quickly
2. Wait for the OS to detect the device
@@ -256,7 +256,7 @@ Compatible flashers:
Flashing sequence:
1. Enter the bootloader using any of the following methods:
* Tap the `RESET` keycode (may not work on STM32F042 devices)
* Tap the `QK_BOOT` keycode (may not work on STM32F042 devices)
* If a reset circuit is present, tap the `RESET` button on the PCB; some boards may also have a toggle switch that must be flipped
* Otherwise, you need to bridge `BOOT0` to VCC (via `BOOT0` button or jumper), short `RESET` to GND (via `RESET` button or jumper), and then let go of the `BOOT0` bridge
2. Wait for the OS to detect the device
@@ -266,7 +266,7 @@ Flashing sequence:
### `make` Targets
* `:dfu-util`: Waits until an STM32 bootloader device is available, and then flashes the firmware.
* `:dfu-util-split-left` and `:dfu-util-split-right`: Flashes the firmware as with `:avrdude`, but also sets the handedness setting in EEPROM. This is ideal for Proton-C-based split keyboards.
* `:dfu-util-split-left` and `:dfu-util-split-right`: Flashes the firmware as with `:dfu-util`, but also sets the handedness setting in EEPROM. This is ideal for Proton-C-based split keyboards.
* `:st-link-cli`: Allows you to flash the firmware via the ST-Link CLI utility, rather than dfu-util. Requires an ST-Link dongle.
* `:st-flash`: Allows you to flash the firmware via the `st-flash` utility from [STLink Tools](https://github.com/stlink-org/stlink), rather than dfu-util. Requires an ST-Link dongle.
@@ -292,7 +292,7 @@ Compatible flashers:
Flashing sequence:
1. Enter the bootloader using any of the following methods:
* Tap the `RESET` keycode
* Tap the `QK_BOOT` keycode
* If a reset circuit is present, tap the `RESET` button on the PCB
* Otherwise, you need to bridge `BOOT0` to VCC (via `BOOT0` button or jumper), short `RESET` to GND (via `RESET` button or jumper), and then let go of the `BOOT0` bridge
2. Wait for the OS to detect the device
@@ -316,7 +316,7 @@ Compatible flashers:
Flashing sequence:
1. Enter the bootloader using any of the following methods:
* Tap the `RESET` keycode
* Tap the `QK_BOOT` keycode
* Press the `RESET` button on the PCB
2. Wait for the OS to detect the device
3. Flash a .bin file
@@ -342,7 +342,7 @@ Compatible flashers:
Flashing sequence:
1. Enter the bootloader using any of the following methods:
* Tap the `RESET` keycode
* Tap the `QK_BOOT` keycode
* Double-tap the `nRST` button on the PCB.
2. Wait for the OS to detect the device
3. Copy the .uf2 file to the new USB disk
@@ -353,8 +353,51 @@ or
CLI Flashing sequence:
1. Enter the bootloader using any of the following methods:
* `:uf2-split-left` and `:uf2-split-right`: Flashes the firmware but also sets the handedness setting in EEPROM by generating a side specific firmware.
## Raspberry Pi RP2040 UF2
The `rules.mk` setting for this bootloader is `rp2040`, and can be specified at the keymap or user level.
To ensure compatibility with the rp2040 bootloader, make sure this block is present in your `rules.mk`:
```make
# Bootloader selection
BOOTLOADER = rp2040
```
Compatible flashers:
* Any application able to copy a file from one place to another, such as _macOS Finder_ or _Windows Explorer_.
Flashing sequence:
1. Enter the bootloader using any of the following methods:
* Tap the `QK_BOOT` keycode
* Hold the `BOOTSEL` button on the PCB while plugin in the usb cable.
* Double-tap the `RESET` button on the PCB<sup>1</sup>.
2. Wait for the OS to detect the device
3. Copy the .uf2 file to the new USB disk
4. Wait for the keyboard to become available
or
CLI Flashing sequence:
1. Enter the bootloader using any of the following methods:
* Tap the `QK_BOOT` keycode
* Hold the `BOOTSEL` button on the PCB while plugin in the usb cable.
* Double-tap the `RESET` button on the PCB<sup>1</sup>.
@@ -177,20 +177,25 @@ From here, you should have a working keyboard once you program a firmware.
Simple firmware can be created easily using the [Keyboard Firmware Builder](https://kbfirmware.com/) website. Recreate your layout using [Keyboard Layout Editor](https://www.keyboard-layout-editor.com), import it and recreate the matrix (if not already done as part of [planning the matrix](#planning-the-matrix).
Go through the rest of the tabs, assigning keys until you get to the last one where you can compile and download your firmware. The .hex file can be flashed straight onto your keyboard, and the .zip of source files can be modified for advanced functionality and compiled locally using the method described in [Building Your First Firmware](newbs_building_firmware?id=build-your-firmware).
Go through the rest of the tabs, assigning keys until you get to the last one where you can compile and download your firmware. The .hex file can be flashed straight onto your keyboard, or for advanced functionality, compiled locally after [Setting up Your Environment](newbs_getting_started.md).
The source given by Keyboard Firmware Builder is QMK, but is based on a version of QMK from early 2017. To compile the code from your .zip file in a modern version of QMK Firmware, you'll need to open the .zip and follow these instructions:
The source given by Keyboard Firmware Builder is QMK, but is based on a version of QMK from early 2017. To compile the firmware in a modern version of QMK Firmware, you'll need to export via the `Save Configuration` button, then run:
qmk import-kbfirmware /path/to/export.json
For example:
```
$ qmk import-kbfirmware ~/Downloads/gh62.json
Ψ Importing gh62.json.
⚠ Support here is basic - Consider using 'qmk new-keyboard' instead
Ψ Imported a new keyboard named gh62.
Ψ To start working on things, `cd` into keyboards/gh62,
Ψ or open the directory in your preferred text editor.
Ψ And build with qmk compile -kb gh62 -km default.
```
1. Extract the `kb` folder to `qmk_firmware/keyboards/handwired/`.
2. Open the extracted `kb` folder, then proceed to the `keymaps/default/` folder, and open `keymap.c`.
3. Locate and delete the `action_get_macro` code block:
The *scancode* is mapped to a *keycode* dependent on the keyboard [60-keyboard.hwdb at Master](https://github.com/systemd/systemd/blob/master/hwdb.d/60-keyboard.hwdb). Without this mapping, the operating system will not receive a valid keycode and will be unable to do anything useful with that key press.
The *scancode* is mapped to a *keycode* dependent on the keyboard [60-keyboard.hwdb at Main](https://github.com/systemd/systemd/blob/main/hwdb.d/60-keyboard.hwdb). Without this mapping, the operating system will not receive a valid keycode and will be unable to do anything useful with that key press.
|`QK_BOOTLOADER` |`QK_BOOT`|Put the keyboard into bootloader mode for flashing |
|`QK_DEBUG_TOGGLE`|`DB_TOGG`|Toggle debug mode |
|`QK_CLEAR_EEPROM`|`EE_CLR` |Reinitializes the keyboard's EEPROM (persistent memory) |
|`QK_MAKE` | |Sends `qmk compile -kb (keyboard) -km (keymap)`, or `qmk flash` if shift is held. Puts keyboard into bootloader mode if shift & control are held |
|`QK_REBOOT` |`QK_RBT` |Resets the keyboard. Does not load the bootloader |
## Audio Keys :id=audio-keys
@@ -337,6 +337,9 @@ See also: [Magic Keycodes](keycodes_magic.md)
|`MAGIC_SWAP_CONTROL_CAPSLOCK` |`CL_SWAP`|Swap Caps Lock and Left Control |
|`MAGIC_UNSWAP_CONTROL_CAPSLOCK` |`CL_NORM`|Unswap Caps Lock and Left Control |
|`MAGIC_TOGGLE_CONTROL_CAPSLOCK` |`CL_TOGG`|Toggle Caps Lock and Left Control swap |
|`MAGIC_SWAP_ESCAPE_CAPSLOCK` |`EC_SWAP`|Swap Caps Lock and Escape |
|`MAGIC_UNSWAP_ESCAPE_CAPSLOCK` |`EC_NORM`|Unswap Caps Lock and Escape |
|`MAGIC_TOGGLE_ESCAPE_CAPSLOCK` |`EC_TOGG`|Toggle Caps Lock and Escape swap |
|`MAGIC_CAPSLOCK_TO_CONTROL` |`CL_CTRL`|Treat Caps Lock as Control |
|`MAGIC_UNCAPSLOCK_TO_CONTROL` |`CL_CAPS`|Stop treating Caps Lock as Control |
|`MAGIC_SWAP_LCTL_LGUI` |`LCG_SWP`|Swap Left Control and GUI |
This is an intermediate QMK tutorial to setup an out-of-tree build environment with a personal GitHub repository. It avoids using a fork of the QMK firmware to store and build your keymap within its source tree. Keymap files will instead be stored in your own personal GitHub repository, in [Userspace](https://docs.qmk.fm/#/feature_userspace) format, and built with an action workflow. Unlike the [default tutorial](https://docs.qmk.fm/#/newbs), this guide requires some familiarity with using Git.
?> **Is This Guide For Me?**<br>
This is a lean setup to avoid space-consuming local build environment in your computer. Troubleshooting compile-time errors will be slower with commit uploads to GitHub for the compiler workflow.
## Prerequisites
The following are required to get started:
* [GitHub Account](https://github.com/new)
* A working account is required to setup and host your repository for GitHub Actions to build QMK firmware.
* You’ll need a program that can edit and save plain text files. The default editor that comes with many OS's does not save plain text files, so you'll need to make sure that whatever editor you chose does.
* [Toolbox](https://github.com/qmk/qmk_toolbox)
* A graphical program for Windows and macOS that allows you to both program and debug your custom keyboard.
## Environment Setup
?> If you are familiar with using [github.dev](https://docs.github.com/en/codespaces/the-githubdev-web-based-editor), you can skip to [step 2](#_2-create-github-repository) and commit the code files that follows directly on GitHub using the web-based VSCode editor.
### 1. Install Git
A working Git client is required for your local operating system to commit and push changes to GitHub.
<!-- tabs:start -->
### ** Windows **
QMK maintains a bundle of MSYS2, the CLI and all necessary dependencies including Git. Install [QMK MSYS](https://msys.qmk.fm/) with the latest release [here](https://github.com/qmk/qmk_distro_msys/releases/latest). Git will be part of the bundle.
### ** macOS **
Install Homebrew following the instructions on https://brew.sh. Git will be part of the bundle.
### ** Linux/WSL **
It's very likely that you already have Git installed. If not, use one of the following commands:
If your GitHub account is not configured for [authenticated Git operations](https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/), you will need to setup at least one of the following:
* [Connecting with SSH](https://docs.github.com/en/authentication/connecting-to-github-with-ssh)
### 3. Create a repository
You will need a personal GitHub repository to host your QMK code. Follow [this guide](https://docs.github.com/en/get-started/quickstart/create-a-repo#create-a-repository) to create one named `qmk_keymap`. Do not proceed to commit any files just yet.
## Initial Code Commit
### Create template files
Run the following commands in your computer to create a folder with a few template files:
?> For Windows user running MSYS, those commands will create the folder `qmk_keymap/` and its content in the `C:\Users\<windows_username>\qmk_keymap\` path location.
### Add a JSON keymap
Visit the [QMK Configurator](https://config.qmk.fm/#/) to create a keymap file:
1. Select your keyboard from the drop-down list (and choose a layout if required).
2. Use your GitHub username for the **Keymap Name** field.
3. Customise the key layout according to your preference.
4. Select download next to **KEYMAP.JSON** and save the JSON file into the `~/qmk_keymap/` folder.
### Add a GitHub Action workflow
Open the file `~/qmk_keymap/.github/workflows/build.yml` with your favorite [text editor](newbs_learn_more_resources.md#text-editor-resources), paste the following workflow content, and save it:
?> Use your GitHub personal access token at the password prompt. If you have setup SSH access, replace `https://github.com/gh-username/qmk_keymap.git` with `git@github.com:gh-username/qmk_keymap.git` in the remote origin command above.
### Review workflow output
Files committed to GitHub in the previous step will automatically trigger the workflow to build the JSON file listed in `build.yml`. To review its output:
1. Visit your "**qmk_keymap**" repository page on [GitHub](https://github.com/).
2. Select **Actions** tab to display the "**Build QMK Firmware**" workflow.
3. Select that workflow to display its run from the last commit.
4. Successfully compiled firmware will be under the "**Artifacts**" section.
5. If there are build errors, review the job log for details.
Download and flash the firmware file into your keyboard using [QMK Toolbox](https://docs.qmk.fm/#/newbs_flashing?id=flashing-your-keyboard-with-qmk-toolbox).
## Customising your keymap
This setup and workflow relies on the QMK [Userspace](https://docs.qmk.fm/#/feature_userspace) feature. The build process will copy the QMK source codes and clone your repository into its `users/` folder in a container. You must adhere to the following guidelines when customising your keymaps:
* Keymap layout files must be retained in JSON format and cannot be converted to `keymap.c`.
* User callback and functions (e.g. `process_record_user()`) can be placed in the `source.c` file.
* Multiple keymap JSON files can be built in the same workflow. List them under `matrix.file:`, e.g.:
```yml
file:
- planck.json
- crkbd.json
```
* Code changes will require Git commit into GitHub to trigger the build workflow.
?> See [GitHub Actions guide](https://docs.github.com/en/actions/learn-github-actions) to learn more about development workflow.
@@ -108,6 +108,8 @@ However, this does rely on the bootloader being set by the keyboard. If this inf
In this case, you'll have to fall back on specifying the bootloader. See the [Flashing Firmware](flashing.md) Guide for more details.
!> If your bootloader is not detected by `qmk flash`, try running `qmk doctor` for suggestions on how to fix common problems.
## Test It Out!
Congrats! Your custom firmware has been programmed to your keyboard and you're ready to test it out!
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.