* initial commit
* tidy info.json, add readme.md
* correct license headers
* fix some minor typos
* additions to readme
* try and conform to standards
* remove duplicates from config.h
* remove unneccessary line from rules.mk
* further tidying
* some small misses
* some small misses
* repair via keymap
* actually fixed, d'oh
* Update keyboards/keycapsss/3w6_2040/info.json
Co-authored-by: jack <0x6a73@protonmail.com>
* Update keyboards/keycapsss/3w6_2040/info.json
Co-authored-by: jack <0x6a73@protonmail.com>
* Update keyboards/keycapsss/3w6_2040/keymaps/default/keymap.c
Co-authored-by: jack <0x6a73@protonmail.com>
* Update keyboards/keycapsss/3w6_2040/info.json
Co-authored-by: jack <0x6a73@protonmail.com>
* Update keyboards/keycapsss/3w6_2040/keymaps/via/keymap.c
Co-authored-by: jack <0x6a73@protonmail.com>
* Update keyboards/keycapsss/3w6_2040/readme.md
Co-authored-by: jack <0x6a73@protonmail.com>
* remove via config.h
---------
Co-authored-by: jack <0x6a73@protonmail.com>
* Don't print error message when there are no row pins and no col pins
This error message could be triggered for example if MATRIX_IO_DELAY is
configured in config.h, but the matrix is a custom one. The custom matrix
can still call back to existing delay functions that make use of the
MATRIX_IO_DELAY macro. In this case 'matrix_pins' in info_data will be true,
but there will be no 'direct' 'cols' or 'rows' in info_data['matrix_pins'],
and without this commit it would trigger an invalid error.
* Update lib/python/qmk/info.py
Co-authored-by: Nick Brassel <nick@tzarc.org>
---------
Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: Nick Brassel <nick@tzarc.org>
There was an import cycle in the Python modules:
- `qmk.build_targets` imported `qmk.cli.generate.compilation_database`;
- importing `qmk.cli.generate.compilation_database` requires
initializing `qmk.cli` first;
- the initialization of `qmk.cli` imported the modules for all CLI
commands;
- `qmk.cli.compile` imported `qmk.build_targets`.
This cycle did not matter in most cases, because `qmk.cli` was imported
first, and in that case importing `qmk.cli.generate.compilation_database`
did not trigger the initialization of `qmk.cli` again. However, there was
one corner case when `qmk.bulld_targets` was getting imported first:
- The `qmk find` command uses the `multiprocessing` module.
- The `multiprocessing` module uses the `spawn` start method on macOS
and Windows.
- When the `spawn` method is used, the child processes initialize
without any Python modules loaded, and the required modules are loaded
on demand by the `pickle` module when receiving the serialized objects
from the main process.
The result was that the `qmk find` command did not work properly on macOS
(and probably Windows too); it reported exceptions like this:
ImportError: cannot import name 'KeyboardKeymapBuildTarget' from partially initialized module 'qmk.build_targets' (most likely due to a circular import)
Moving the offending `qmk.cli.generate.compilation_database` import into
the method which actually uses it fixes the problem.
When multiple `-f FILTER` options were specified, `qmk find` did not
return anything at all instead of printing the list of entries that
matched all of the specified filters.
The problem was that the statement in `_filter_keymap_targets()` that
filled `targets` had a wrong indent and therefore was executed for every
filter instead of only once after applying all filters, and
`valid_keymaps` was actually an iterator and therefore could be used
only once. Moving the statement outside of the loop fixes the problem.
* [Keyboard] Change default implementation for get_layer_name_user
Will now show the layer number instead of "Unknown", since this is
what will be shown if QMK Configurator is used to compile the
firmware.
* [Keyboard] Update the layout info
This makes it look sort of like a macropad + gamepad rather than an 4x6
ortholinear keyboard.
* [Keyboard] Fix default implementation of get_layer_name_user
Based on feedback from code review the implementation was swapped in
favor of using get_u8_str. This implied a change to the argument type
from int to uint8_t, which cascaded into the existing keymaps. (This
made sense in general, since the return type of get_highest_layer is
also a uint8_t.)
* [Keyboard] Fix bug in set_keylog function
Fixes issue where some keys would not trigger the oled to output the row
and column of a pressed key (would happen with LT(...) for my keymap)
* [Keyboard] Tiny improvement to oled_render_keylog for crkbd
Added improvement suggestion I got for another keyboard
* ChibiOS: USB HID control request as dedicated struct
Instead of accessing the raw USB setup packet and documenting the values
as the corresponding USB HID control request fields we introduce a
struct that allows direct access to the fields. This is safer and self
documenting.
* Rename usb_request.h to usb_types.h
In the future all shared USB data types can live in this file.
* Clean up some keyboard/userspace code
* Rename `KEYBOARD_REPORT_BITS` -> `NKRO_REPORT_BITS`
* Add some missing includes
* Use `PACKED` define for report types
* Fix incorrect function signatures for FlexRAM EEPROM driver
* initialise rpneko65, info.json
* force NKRO
* define WS2812 stuff
and capitalise RPNeko65
* use RGBlight, add ANSI to keymap.c
also remove _ADC suffixes from pins
* basic readme
plus making it so the info.json RGB values are actually recognised as integers
* update repository URL
* fix info.json formatting
* caps lock LED implementation
"borrowed" from waffling60
* put RGBLIGHT_ENABLE in json
also remove "pin" from the rgblight option
* add actually correct keymaps
also reformat info.json
* move to designer folder, add image to README
* move keyboard to separate revision folder
and remove erroneous tag from config.h
* remove brightness/hue/saturation steps
* change device version to 1.0
* move quantum.h include to top
* actually, let's try a new image
I also forgot to save the info.json file beforehand
oops
* Remove comma in info.json
* Community layouts in info.json
* Delete rpneko65/readme.md
* Apply suggested changes to readme
* Suggested code changes
* Suggested imgur link
* rename code file
this was the issue all along
sigh
* Correct layer matching this time
* Move Enter in info.json
* README/info.json change
* Another batch of suggestions
* Add GK61 PRO keyboard
* Update info.json regarding to dunk2k suggestion
* Update keymap files regarding to dunk2k suggestion
* Update keyboards/skyloong/gk61/pro/config.h
OK, thanks for your suggestion.
* Update keyboards/skyloong/gk61/pro/keymaps/default/keymap.c
OK, thanks.
* Update keyboards/skyloong/gk61/pro/keymaps/via/keymap.c
OK, thanks.
* Update keyboards/skyloong/gk61/pro/rules.mk
OK, thank you for your suggestion.
* Update keyboards/skyloong/gk61/pro/info.json
OK,thanks.
* Update keyboards/skyloong/gk61/pro/keymaps/default/keymap.c
OK, thanks.
* Update keyboards/skyloong/gk61/pro/info.json
I see , thanks for your guidance.
* Update keyboards/skyloong/gk61/pro/config.h
OK, thank you.
* Update keyboards/skyloong/gk61/pro/info.json
OK, thank you for your suggestion.
* Update keyboards/skyloong/gk61/pro/info.json
I see, thank you.
* Update keyboards/skyloong/gk61/pro/config.h
OK, thank you for your suggestion.
* Update keyboards/skyloong/gk61/pro/pro.c
I see , thank you.
* Correct PCB feature description in readme.
* Update keyboards/skyloong/gk61/pro/config.h
It doesn't seem to be a problem to compile without defining DRIVER_COUNT. Thank you for your rigor and seriousness.
* Update keyboards/skyloong/gk61/pro/keymaps/default/keymap.c
OK, thank you.
* update config.h to define __flash.
* Update keyboards/skyloong/gk61/pro/config.h
I see, thanks for your suggestion.
* add hardware availabilty international website
* update via/rules.mk for encoder map
* Revert "update via/rules.mk for encoder map"
This reverts commit 66601242af.
* Update keyboards/skyloong/gk61/pro/config.h
OK, thanks.
* Update rules.mk
Enable the encoder map.
* 1.update readme to correct mcu type ; 2. update pro.c to improve indicator function.
* update pro.c and config.h to save power when USB suspend.
* update info.json
* Update RGB animations---delete rainbow_beacon and rainbow_pinwheels
* Update keymap.c and layer indication.
* Enable I2C DMA
* Update keyboards/skyloong/gk61/pro/info.json
OK,Thank you for your suggestion.
* Update keyboards/skyloong/gk61/pro/info.json
OK,Thanks.
* enable encoder map in default keymaps
* Update keyboards/skyloong/gk61/pro/info.json
OK. Thank you for your suggestion.
* Add support for Envious.Design Keyboards
Add various RP2040 keyboards I've designed.
* Fixed missing newlines at EOF.
* Ran CLANG-FORMAT and sorted out any potential issues.
* Gave keyboards all unique product IDs
* Made requested changes.
* removed all VIAL related code
* sorted out license on all *.h or *.h files
* removed outdated RESET Keycode
* missed some VIAL bits
* Made suggested changes
* Made Suggested Changes
* missed one file to change.
* Attempted fix of CI issues
* Update .gitmodules
* Revert "Update .gitmodules"
This reverts commit f4bace5162.
* hopefully fixed all CI and QMK lint issues
* resolve more CI errors and a couple typos
* fixed last remaining issue as of now
* made requested changes
* further more on suggested change
* Delete README.md
* derpy workaround to change case of readme
* finished up 65M firmware
via does not work, I will investigate another time.
* re-did a lot of 65M firmware bits, also fixed via for this board
* corrected mistake in firmware
* made suggested change to info.json for 65m/60F
* finished 65M non via keymap and re-sorted via keymap
* Update keyboards/enviousdesign/tkl/rgb/keymaps/default/keymap.c
* Update keyboards/enviousdesign/tkl/rgb/keymaps/default/keymap.c
* Apply suggestions from code review
Verified updated Info.json works for aforementioned keyboards,
* Follow-up commit with aforementioned suggested changes
* Apply suggestions from code review
correction to a couple typos pointed out.
* follow-up removed some un-needed Readmes and corrected a mistake in 60F via keymap
* Apply suggestions from code review
* Added images of PCB to each Keyboard README
* Apply suggestions from code review
* Update keyboards/enviousdesign/60f/readme.md
* Added missing aspects of info.json and corrected RGB_DI_PIN to WS2812_DI_PIN in RGB keyboard
* made requested changes
* Update config.h
* used QMK migrate to update info.json
* Apply suggestions from code review
* Update keyboards/enviousdesign/65m/info.json
* renamed named keyboards as suggested and added commission keyboard to repo
* renamed file to hopefully please lint
* renamed things to be all lower case since lint doesn't appear to look for upper case
* updated keymap.c and removed unnecessary file
* fixed readme and a couple other bits
* converted various aspects to json information
* attempt fix for lint error
* fix some issues I overlooked
* Apply suggestions from code review
* moved some folders about as suggested
* Made suggested changes
* Apply suggestions from code review
* removed outdated config.h
* fixed errors in 65M and mini1800
* Apply suggestions from code review
* Update keyboards/enviousdesign/delirium/rev1/info.json
* Update keyboards/enviousdesign/65m/info.json
* Apply suggestions from code review
* Added support keyboard Nyx
* Resolved zvarc suggested and lint error
* Delete FORCE_NKRO due to problem with BIOS on mainboard
* Resolved dunk2k suggested and limit more brightness, disable some RGB Effect
* Resolved drashna suggested
* Delete flower blooming effect and move to rev1 folder
from "could not find USB device with" to "cannot find USB device with"
This should fix issue #22234
Co-authored-by: Dominik Loidolt <dominik.loidolt@univie.ac.at>
* Added new handwired, the Split-Cloud
* Minor changes to make clang-format happy
* Alligned files with project standard.
Trimmed midi out of the default layout, modified the readme, and removed unnecessary files.
* Simplified default keymap further, changes to info.json
* Moved image to imgur, simplified, and removed the unneeded rules.mk file
* Update keyboards/handwired/split_cloud/readme.md
Changed image in readme to Huge Thumbnail instead of Original.
* Removed unneeded tri layer custom keycodes
Now using the built-in functionality!
* Update keyboards/handwired/split_cloud/readme.md
Accidentally reverted this when making other changes
* ADD RGB_DEFAULT_DISABLED option and updated documentation
* Formatting
* Add as by fauxpark's suggestion
Co-authored by: fauxpark
* Formatting
* Use boolean values instead of numerical
Co-authored-by: Ryan <fauxpark@gmail.com>
* Edit documentation formatting
Co-authored-by: Ryan <fauxpark@gmail.com>
* Remove comment
Co-authored-by: Ryan <fauxpark@gmail.com>
* Set RGB mode to DEFAULT macro at init
Co-authored-by: Ryan <fauxpark@gmail.com>
---------
Co-authored-by: Ryan <fauxpark@gmail.com>
Co-authored-by: zvecr <git@zvecr.com>
* enable LTO
* change from _user to _kb function
* switch matrix io delay to nops, add opt=3 for higher scan rates
* disable console which was enabled for testing but collides with endpoint used by VIA
* switched from opt=3 to opt=2
* Update keyboards/teleport/native/native.c
Co-authored-by: Joel Challis <git@zvecr.com>
* slightly upped debounce, as some testers had chatter with async + default debounce
---------
Co-authored-by: Joel Challis <git@zvecr.com>
* Refactor `LAYOUT` into `LAYOUT_65_iso_blocker`
Move the Enter key to the end of the home row for Community Layout
compatibility.
[chore] [refactor]
* Enable Community Layout support
[enhancement]
* refactor: move default RGB/LED matrix #defines
Moving the fallback definitions of macros like LED_MATRIX_VAL_STEP and
RGB_MATRIX_MAXIMUM_BRIGHTNESS to header files allows keyboards to
leverage these defaults without requiring #ifdef guards (and often
repeating said fallback definitions).
* style: use if(n)def for consistency
and remove redundant UINT8_MAX checks on maximum brightness
Co-authored-by: Joel Challis <git@zvecr.com>
* refactor: remove INDICATOR_MAX_BRIGHTNESS macro
Co-authored-by: Joel Challis <git@zvecr.com>
---------
Co-authored-by: Joel Challis <git@zvecr.com>
* Refactor `dbroqua` keymap
- use `layer_names` enum
- use QMK-native alias for `KC_TRNS`
- apply four-space indent
- grid-align keycodes
- refactor keymap to use `LAYOUT_all` macro.
- The keycode for position [4, 9] (right half of Split Backspace)
moves to the top row.
- The keycodes for positions [3, 12] and [3, 13] (1.75u/1u Split
RShift) switch positions.
[refactor]
* Refactor `dbroqua_hhkb` keymap
- use `layer_names` enum
- use QMK-native alias for `KC_TRNS`
- apply four-space indent
- grid-align keycodes
- refactor keymap to use `LAYOUT_all` macro.
- The keycode for position [4, 9] (right half of Split Backspace)
moves to the top row.
- The keycodes for positions [3, 12] and [3, 13] (1.75u/1u Split
RShift) switch positions.
[refactor]
* Touch-up `default` keymap
- fix keycode grid alignment
[style]
* Refactor `sgoodwin` keymap
- grid-align keycodes
- apply four-space indent
- refactor keymap to use `LAYOUT_all` macro.
- The keycode for position [4, 9] (right half of Split Backspace)
moves to the top row.
- The keycodes for positions [3, 12] and [3, 13] (1.75u/1u Split
RShift) switch positions.
[refactor]
* Refactor `stanleylai` keymap
- delete `config.h` (use RGB config from keyboard `info.json`)
- fixes non-compilation
- use `layer_names` enum
- use four-space indent
- update keycode grid alignment
- refactor keymap to use `LAYOUT_all` macro.
- The keycode for position [4, 9] (right half of Split Backspace)
moves to the top row.
- The keycodes for positions [3, 12] and [3, 13] (1.75u/1u Split
RShift) switch positions.
[bugfix] [refactor]
* Touch-up `via` keymap
- fix keycode grid alignment
[style]
* Refactor `wigguno` keymap
- use four-space indent
- use QMK-native keycode alias for `KC_DELETE`
- refactor keymap to use `LAYOUT_all` macro.
- The keycode for position [4, 9] (right half of Split Backspace)
moves to the top row.
- The keycodes for positions [3, 12] and [3, 13] (1.75u/1u Split
RShift) switch positions.
[refactor]
* Remove `LAYOUT` macro
Superseded by `LAYOUT_all`.
[chore]
* Add `LAYOUT_60_ansi_split_bs_rshift`
[enhancement]
* Add `LAYOUT_60_tsangan_hhkb`
[enhancement]
* Add `LAYOUT_60_ansi_tsangan`
[enhancement]
* Add `LAYOUT_60_iso_split_bs_rshift`
[enhancement]
* Add `LAYOUT_60_iso`
[enhancement]
* Add `LAYOUT_60_iso_tsangan_split_bs_rshift`
[enhancement]
* Add `LAYOUT_60_iso_tsangan`
[enhancement]
* Add `LAYOUT_60_hhkb`
[enhancement]
* Add `LAYOUT_60_true_hhkb`
[enhancement]
* Add layout/matrix diagram
[docs]
* Add `LAYOUT_60_abnt2`
[enhancement]
* Extend Community Layout support
Add support for community layouts:
- `60_ansi_split_bs_rshift`
- `60_ansi_tsangan`
- `60_tsangan_hhkb`
- `60_hhkb`
- `60_abnt2`
- `60_iso`
- `60_iso_split_bs_rshift`
- `60_iso_tsangan`
[enhancement]
* Fix `LAYOUT_60_abnt2` support
[bugfix]
* Correct layout/matrix diagram
Correct swapped designations for ANSI Backslash and ANSI Enter keys.
[docs]
* Correct matrix data
Correct the matrix data for:
- `LAYOUT_all`
- `LAYOUT_96_ansi`
- `LAYOUT_96_ansi_splitbs`
which all had the matrix positions for ANSI Backslash and ANSI Enter swapped.
[bugfix]
* Implement `LAYOUT_hotswap` directly
Implement `LAYOUT_hotswap` as its own layout, instead of aliasing it to
`LAYOUT_96_ansi`.
[bugfix]
* Specify primary support for Soldered PCBs
Current version of codebase primarily supports Soldered PCBs.
[enhancement] [docs]
* Add layout/matrix diagram
[docs]
* Friendly-format `info.json`
[style]
* Touch-up keymaps
- grid-align keycodes
- use QMK-native keycode aliases
[refactor]
* Fix keymaps
Fix keycodes being assigned out of order with respect to `info.json`.
- move XT function keys to left side
- move keycodes for position [2, 14] from Home Row to Number Row
[bugfix]
* Rename `LAYOUT` to `LAYOUT_65_xt_ansi_blocker_tsangan_wkl_split_bs`
[refactor]
* Add `LAYOUT_65_xt_ansi_blocker_tsangan_wkl`
[enhancement]
* Add layout/matrix diagram
[docs]
* Alias `LAYOUT_all` to `LAYOUT_split_6u`
`LAYOUT_all` and `LAYOUT_split_6u` represent the same matrix positions
and sequence, so implement the former as an alias.
[refactor]
* Touch-up keymaps
- grid-align keycodes
- use QMK-native keycode aliases
[chore]
* Friendly-format `info.json`
[style]
* Correct layout data
Correct key sizes/positioning on the bottom row.
[chore]
* Rename `LAYOUT_2u_6u` to `LAYOUT_65_xt_ansi_blocker`
[refactor]
* Rename `LAYOUT_2u_7u` to `LAYOUT_65_xt_ansi_blocker_tsangan`
[refactor]
* Rename `LAYOUT_split_6u` to `LAYOUT_65_xt_ansi_blocker_split_bs`
[refactor]
* Rename `LAYOUT_split_7u` to `LAYOUT_65_xt_ansi_blocker_tsangan_split_bs`
[refactor]
* Add layout/matrix diagram
[docs]
* Rename `LAYOUT` to `LAYOUT_65_xt_ansi_blocker_split_bs`
[refactor]
* Add `LAYOUT_65_xt_ansi_blocker`
[enhancement]
* Add `LAYOUT_65_xt_ansi_blocker_tsangan`
[enhancement]
* Add `LAYOUT_65_xt_ansi_blocker_tsangan_split_bs`
[enhancement]
* Touch-up keymaps
- grid-align keycodes
- use four-space indent
- use QMK-native keycode aliases
[refactor]
* Update `via` keymap
Update the `via` keymaps to have the same key assignments as the
`default` keymap, which is more fleshed out.
[chore]
* Add layout/matrix diagram
[docs]
* Update layout data
Update layout data to disambiguate the key/joystick/thumbpad functions
in Configurator.
[chore]
* Add `LAYOUT_tkl_ansi_wkl_split_bs_rshift`
[enhancement]
* Add `LAYOUT_tkl_ansi_wkl`
[enhancement]
* Add `LAYOUT_tkl_iso_wkl_split_bs_rshift`
[enhancement]
* Add `LAYOUT_tkl_iso_wkl`
[enhancement]
* Correct layout data
Correct key positioning on the function row.
[enhancement]
* Friendly-format `info.json`
[style]
* Move ISO Enter to Home Row
Corrects the implementation of the ISO Community Layouts.
[bugfix]
* Rename `LAYOUT` to `LAYOUT_all`
[refactor]
* Add layout/matrix diagram
[docs]
* Correct layout data
Reduce the gap between the encoder/macro section and the alphanumeric
section by 0.25u.
[enhancement]
* Add `LAYOUT_ansi_blocker`
[enhancement]
* Add `LAYOUT_iso_blocker`
[enhancement]
* Fix redundant `layout_aliases` keys
per dunk2k
[bugfix]
* Alias `LAYOUT_all` as `LAYOUT_tkl_ansi`
The data for `LAYOUT_all` and `LAYOUT_tkl_ansi` is identical, so alias
the former to the latter to reduce redundancy.
[refactor]
* Rename `LAYOUT_tkl_ansi_tsangan_wkl` to `LAYOUT_tkl_ansi_wkl`
[refactor]
* Enable Community Layout support
[enhancement]
* [Core] Allow customizing PWM frequency
Some frequencies can cause audible noise. Changing the frequency
eliminates that.
Signed-off-by: Daniel Schaefer <dhs@frame.work>
* docs/feature-backlight: Mention PWM frequency
Signed-off-by: Daniel Schaefer <dhs@frame.work>
---------
Signed-off-by: Daniel Schaefer <dhs@frame.work>
When not all SW pins are used, it's useful to disable those that aren't.
Can reduce audible noise.
```
Layout:
D7:D4 D3 D2:D1 D0
SWD LGC OSDE SSD
SWS: SWx Setting. Change how many SW pins are active
LGC: H/L Logic
SSD: Software Shutdown Control
```
Signed-off-by: Daniel Schaefer <dhs@frame.work>
* Rework info.json reference
* Apply suggestions from code review
Co-authored-by: Sergey Vlasov <sigprof@gmail.com>
* Update backlight.pins description
* Add rgblight.driver and lowercase other driver names
* Remove `split.main` and `split.matrix_grid` for now as they are not working yet
---------
Co-authored-by: Sergey Vlasov <sigprof@gmail.com>
* Move RGBLight animations to data driven, 0-9
* Move RGBLight animations to data driven, A
* Move RGBLight animations to data driven, B
* Move RGBLight animations to data driven, C
* Move RGBLight animations to data driven, D
* Move RGBLight animations to data driven, E
* Move RGBLight animations to data driven, F
* Move RGBLight animations to data driven, G
* Move RGBLight animations to data driven, H
* Move RGBLight animations to data driven, handwired
* Move RGBLight animations to data driven, I
* Move RGBLight animations to data driven, J
* Move RGBLight animations to data driven, K
* Move RGBLight animations to data driven, L
* Move RGBLight animations to data driven, M
* Move RGBLight animations to data driven, N
* Move RGBLight animations to data driven, O
* Move RGBLight animations to data driven, P
* Move RGBLight animations to data driven, Q
* Move RGBLight animations to data driven, R
* Move RGBLight animations to data driven, S
* Move RGBLight animations to data driven, T
* Move RGBLight animations to data driven, U
* Move RGBLight animations to data driven, V
* Move RGBLight animations to data driven, W
* Move RGBLight animations to data driven, X
* Move RGBLight animations to data driven, Y
* Move RGBLight animations to data driven, Z
* Fix incorrect placement
* Fix build failures and mismatches
GCC 13 needs the same workaround as GCC 12.
To avoid having to maintain an ever-growing list of broken versions
apply the workaround wherever it can be used.
If at some point a fixed version of GCC is released the workaround can
be disabled for those fixed versions.
See #17064
Although `keychron/c2_pro/ansi/rgb` and `keychron/c2_pro/ansi/white` use
the same custom matrix code, the matrix layouts are slightly different;
in particular, only the `keychron/c2_pro/ansi/white` board actually uses
column 19. However, the handling of column 19 in the custom matrix code
was broken, therefore that column did not work.
Looks like the custom matrix code assumes that `SHIFT_COL_END` refers to
the last column connected to the shift register, and not to the column
past that; so the value of `SHIFT_COL_END` needs to be changed from 19
to 18 (columns 11...18 are connected to the shift register, and column
19 is connected to the C14 pin).
Also the code which was determining `SIZE_T` and `UNSELECT_ALL_COL` had
an off-by-one bug when counting the required number of bits (again due
to the confusion on the `SHIFT_COL_END` meaning); this had been fixed
too (the actual behavior of that part of the code did not change,
because both the old and the new version select the 8 bit variant).
After #21169, rgb_matrix_indicators() was limited to running on the
final render iteration. Since the jellybean_raindrops animation
immediately returns false after updating a single LED, the iteration
count no longer ends up high enough to render non-advanced indicators.
This change also brings jellybean_raindrops more in line with raindrops.
* Respect USB_SUSPEND_WAKEUP_DELAY on wakeup
This delay wasn't honored after removing `restart_usb_driver` from the
suspend and wakeup handling. It is now re-introduced in the appropriate
spot, namely after issuing a remote wakeup to a sleeping host.
* Remove old, unused and commented testing code
Problem:
`mousekey_task` spams empty hid reports with when a mouse key is
pressed, causing resource exhaustion in the USB mouse endpoint.
Cause:
The check whether or not to send a new mouse report would always
evaluate to true if a mouse key is pressed:
1. `mouse_report` has non-zero fields and `tmpmr` is a copy of this
fields.
2. `mouse_report` is set to zero, `tmpmr` has now non-zero fields.
3. `has_mouse_report_changed` compares the two and evaluates to true
4. a mouse report is sent.
Fix:
The check condition of `has_mouse_report_changed` will evaluate any
empty record as unchanged, as mouse report data is relative and doesn't
need to return to zero. An empty report will still be send by
`register_mouse` on release of all mouse buttons.
Keychron Q11 uses `matrix_mask` to mask away the matrix location used
for `SPLIT_HAND_MATRIX_GRID` (otherwise the keyboard will constantly
generate a wakeup request whenever the host enters suspend). However,
the value of `matrix_mask` is actually chosen to mask away all unused
locations, but it was apparently generated for the ANSI board and
therefore masks away the left Shift key on the ISO board, breaking the
functionality of that key.
Fix `matrix_mask` to make the masking work as intended:
- Set the `[4, 1]` bit to 1; this is the matrix location for the ISO
left Shift.
- Set the `[2, 5]` bit to 0; this is actually the matrix location which
corresponds to `#define SPLIT_HAND_MATRIX_GRID A2, A15` on the left
side, which was intended to be masked; apparently the wakeup problem
does not happen due to `SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT`, so the
left half actually has that matrix location open. On the right side
`A2, A15` is `[9, 6]`, which was masked off correctly.
Running the "HID Tests" suite of the USB 3 Command Verifier (USB3CV)
tool resulted in the following error:
(HID: 3.2.61) The report descriptor returned in response to a
GetDescriptor(Report) must be compliant with the HID specification.
Byte Number: 37h ( 55d)
Data Field: 91 02
Mnemonic: Output
Value: (Variable)
Errors: Error: LOGICAL MAX MUST be bounded by Report Size
The error stems from the fact that logical minimum and maximum are
global items, which means that the next item in a report descriptor
inherits the value from the previously set value. In this case the
status leds item inherited the logical minimum (=0) and maximum (=255)
from the keycodes item. As the status leds set a report size of 1 bit,
wich can only hold a boolean, it becomes clear that this range would
never fit.
The fix is straightforward, we just define a appropriate logical maximum
(=1), the mismatch is solved and our keyboard now passes the compliance
tests. Defining the logical minimum is redundant in this case but is
kept to form a logical block.
The code for Helix rev3 boards could not be built with, e.g.,
`CONVERT_TO=rp2040_ce` due to invalid `#include <stdio.h>` in the
keyboard level `config.h` (apparently the AVR version of that file
contains guards against usage in assembly code, which was hiding the
bug). Move `#include <stdio.h>` to the C sources which need it.
Previously, if the user tried to use `#define AUDIO_MAX_SIMULTANEOUS_TONES 1` to conserve CPU time, their firmware would fail to build with this error:
```
platforms/chibios/drivers/audio_dac_additive.c:91:73: error: excess elements in array initializer [-Werror]
91 | static float active_tones_snapshot[AUDIO_MAX_SIMULTANEOUS_TONES] = {0, 0};
| ^
```
This also affected the preset `#define AUDIO_DAC_QUALITY_VERY_HIGH`, which called up only one simultaneous tone at 88200 Hz.
* [style] friendly-format info.json
* [chore] remove key labels from info.json
* [chore] correct layout data
Fix a misleading Configurator implementation, and incorrect key sizes
and positioning on the bottom row.
* [chore] re-add key labels to info.json
* Keychron V4 ANSI: rename LAYOUT_ansi_61 to LAYOUT_60_ansi
* Keychron V4 ANSI: enable Community Layout support
* Keychron V4 ISO: correct layout data
Move position [3, 1] up by 0.25u.
* Keychron V4 ISO: rename LAYOUT_iso_62 to LAYOUT_60_iso
* Keychron V4 ISO: enable Community Layout support
* [chore] correct layout data
* [chore] rename LAYOUT to LAYOUT_65_ansi_blocker
Also adds a layout alias so as to not have to edit the user keymaps.
* [enhancement] enable Community Layout support
* [refactor] rename LAYOUT_tkl_ansi to LAYOUT_tkl_f13_ansi
* [enhancement] enable Community Layout support
* [chore] correct layout data
Correct the position of the spacebar.
* [style] refactor keymaps
- use four-space indent
- grid-align keycodes
- use QMK-native keycode aliases
* [style] friendly-format info.json
* [chore] remove key overlaps in layout data
* [chore] correct key sequence
* [chore] add key labels
Add `label` keys to the JSON layout data to disambiguate which keys each
object is meant to represent.
Based on the original key sizes and positions as submitted by the
maintainer.
* [docs] add layout/matrix diagram
* [refactor] rename LAYOUT to LAYOUT_all
* [enhancement] add LAYOUT_tkl_ansi_split_bs_rshift
* [enhancement] add LAYOUT_tkl_iso_split_bs_rshift
* [enhancement] enable Community Layout support
* [style] friendly-format info.json
- sort JSON keys in layouts object
- remove instances of `w: 1`
* [chore] correct layout data
* [refactor] rename LAYOUT to LAYOUT_60_tsangan_hhkb
* [enhancement] add LAYOUT_60_ansi_tsangan_split_rshift
* [enhancement] enable Community Layout support
* [bugfix] write appropropriate keymaps
Neither the `default` nor `via` keymaps were written appropriately for
this keyboard.
This commit modifies both keymaps to be appropriate for
`60_tsangan_hhkb` layout.
* Update ChibiOS-Contrib for USB suspend fixes
* Remove S3 wakup workaround
ChibiOS OTGv1 driver has a remote wakeup bug that prevents the device to
resume it's operation. 02516cbc24
introduced a hotfix that forcefully restarted the usb driver as a workaround.
This workaround broke multiple boards which do not use this driver /
peripheral. With the update of ChibiOS this hotfix is now obsolete.
* Remove restart_usb_driver overrides
they are no longer necessary as the workaround is not needed anymore
for stm32f4
* Remove unused RP_USB_USE_SOF_INTR defines
The SOF interrupt is enabled dynamically by the RP2040 usb driver
According to the USB 2.0 spec, remote wakeup should be disabled by
default, and should only be enabled if the host explicitly requests
it. The chibios driver code already takes care of storing this
information, and returning it on GET_STATUS requests. However our
application code has been ignoring it so far.
This is a USB compliance issue, but also a bug that causes trouble
in some cases: On RP2040 targets this has been causing problems if
a key is held down while the keyboard is plugged in. The keyboard
would fail to enumerate until all keys are released. With this
change that behavior is fixed.
Note that for LUFA targets this is already done correctly.
* [refactor] rename LAYOUT to LAYOUT_planck_mit
* [style] friendly-format info.json
* [style] refactor keymaps
- grid-align keycodes
- use four-space indent
- remove trailing whitespace
* [chore] tidy-up keyboard data in info.json
- spell-check `manufacturer` value
- use valid `url`
- reference GitHub username for `maintainer`
* [chore] tidy-up readme
- link to maintainer's GitHub account
- add Hardware Availability link
- break-out Hardware Specs into its own section
* [enhancement] enable Community Layout support
* [chore] replace product image in readme
Source repository for previous URL seems to have been deleted.
* [style] friendly-format info.json
* [docs] add layout/matrix diagram
* [style] refactor via keymap
- grid-align keycodes
- remove trailing whitespace
* [refactor] LAYOUT_all macro
Move the JSON object for the Enter key to the end of the home row.
* [style] refactor default keymap
- update keycode grid alignment
- remove trailing whitespace
* [refactor] LAYOUT_tkl_iso macro
Move the JSON object for the Enter key to the end of the home row.
This commit fixes a key sequence error with the `tkl_iso` Community
Layout support.
* [style] refactor default_ansi keymap
- update keycode grid alignment
- remove trailing whitespace
* [bugfix] fix function row matrix assignments for LAYOUT_tkl_iso
Fix incorrect matrix position assignments on the function row keys for
the `LAYOUT_tkl_iso` macro.
* [bugfix] fix function row matrix assignments for LAYOUT_tkl_ansi
Fix incorrect matrix position assignments on the function row keys for
the `LAYOUT_tkl_ansi` macro.
* [enhancement] remove redundant layout data
Remove the redundant layout data from the keyboard-level `info.json`.
* [enhancement] correct JSON syntax in rev1/info.json
* [enhancement] friendly-format rev1/info.json
* [enhancement] correct layout data
* fix non-default keymap compiling, initial matrix state, watchdog options
* fix: allow planck/rev7 to be used with ENCODER_ENABLE = no
* chore: update function name on all cases.
* remove old midi tone option
Co-authored-by: Ryan <fauxpark@gmail.com>
* fixes abhixec's planck keymap
* add audio enable condition to abhixec's planck keymap
* add audio enable condition to all muse includes
* Revert "add audio enable condition to all muse includes"
This reverts commit 9779e90897.
* Revert "add audio enable condition to abhixec's planck keymap"
This reverts commit 24c742a5e8.
* Revert "fixes abhixec's planck keymap"
This reverts commit 4bb085d1ff.
---------
Co-authored-by: Peter.Falken <luis@bitjester.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
* [refactor] update `info.json` for readability
- sort the JSON objects representing the keyboard's keys in the order:
- label, matrix, x, y, w, h
- convert numeric JSON values to integers where appropriate
* [refactor] remove key labels from `info.json`
* [refactor] keymap refactor
- grid-align keycodes
* [bugfix] move Enter key to home row
Moves the JSON object representing the Enter key to the home row.
Fixes an issue that resulted in correct key assignment only if the
keymap being compiled/flashed was based upon the `via` keymap.
* [refactor] friendly-format info.json
* [enhancement] remove key overlap
Fix a key overlap in the Configurator rendering between LCtrl and Fn2.
* [enhancement] replace store links with product links
Replace URLs that point to the vendor's shop with URLs to the vendor's
product listing.
Apparently layouts with 2u keys were not correctly converted into the
`info.json` format (the old C layout macros used the arguments for such
keys multiple times to cover all possible 1u locations; this is not
supported in `info.json`, and the single matrix location for 2u keys was
chosen incorrectly in some cases). Fix the layout definitions to match
the real PCB wiring.
* refactor keymaps
- remove extra blank lines
- convert tabs to spaces
- use four-space indent
- grid-align keycodes
- use QMK-native keycode aliases
* info.json: correct layout data
* add readme.md
* info.json: correct maintainer field
Updates the value to reference the maintainer's GitHub username.
* Fork Rev. 3 to 4
* Update RGB LED positions
* Adjust RGB positions
* Enable more RGB modes
* Update copyrights
* Add license headers to keymaps
* Use same type of license header
Co-authored-by: Joel Challis <git@zvecr.com>
* Fix I2C pins
---------
Co-authored-by: Joel Challis <git@zvecr.com>
* physically arrange layout macro
Arranges the layout macro to QMK standards (left to right, row by row).
This change breaks compatibility with out-of-tree keymaps, because the
order in which the keycode arguments must be passed is changed.
* rename `LAYOUT_alice_all` to `LAYOUT_split_bs`
* add `LAYOUT_2u_bs` macro
* ws2812_update boolean to stop update every single cycle
* lint1
Co-authored-by: Joel Challis <git@zvecr.com>
* lint2
Co-authored-by: Joel Challis <git@zvecr.com>
* Update quantum/rgb_matrix/rgb_matrix_drivers.c
---------
Co-authored-by: Joel Challis <git@zvecr.com>
* Add an emphasis on QMK MSYS terminal
Not using MSYS terminal is a frequent user error. This change
adds an additional statement to guide users to run the first
command in MSYS itself. Edited the same statement for consistency
in the other OSes.
* Update instructions for the other operating systems
The `matrix_need_update` variable needs to be reset to `false` in
`transfer_matrix_values()`, otherwise that function continues to be
invoked for every scanning loop (forever with `sym_eager_pk` and
`sym_eager_pk`, or until some key gets released with
`asym_eager_defer_pk`), and the scanning rate gets much lower because of
all that useless work.
Co-authored-by: Sergey Vlasov <sigprof@gmail.com>
Functions in filters did not work properly except when used in the last
(or only) filter. The problem was caused by the peculiarity of the
`lambda` behavior in Python — any variables from the outer scope are
captured only by reference, therefore any subsequent reassignment of
those variables is propagated to all lambdas created earlier in the same
scope. Together with the laziness of `filter()` (it returns an iterator
which performs filtering on demand) this resulted in all function
filters using the values of the `key` and `value` variables which
correspond to the last filter in the sequence, therefore the result of
filtering was wrong if some filter with a function was not the last one
in the sequence.
Apparently the shortest way to make a Python lambda capture some
variables by value is to add arguments with default values for such
variables (default values are evaluated when the lambda is created, and
any subsequent reassignments in the outer scope no longer changes them).
This makes filters with functions work properly even when such filters
are not at the last position in the sequence.
As per last few breaking changes cycles, there have been _a lot_ of behind-the-scenes changes, mainly around migration of configurables into `info.json` files, cleanup of `info.json` files, additional layout definitions for keyboards, adding support for general community layouts to keyboards, as well as addressing technical debt.
One thing to note for this release -- `qmk/qmk_firmware` is no longer accepting PRs for keymaps other than for manufacturer-supported keymaps. User keymap workflow has been documented [here](https://docs.qmk.fm/#/newbs) for several years. This change is to progressively reduce the maintenance burden on the project, and to allow us to focus on the core features of QMK.
Existing user keymaps and userspace areas will likely be relocated/removed in the future -- non-building keymaps and userspace will be first targets, likely during the new breaking changes cycle. We will provide more information on Discord regarding this initiative as it becomes available.
Most RGB Matrix implementations now check whether or not RGB LED data has changed and skip transmission if it hasn't. This was measured to improve scan frequency in cases of static or infrequently-changing colors.
Some audio code relating to "notes" used `double` datatypes, which are implemented in software floating-point for most ARM microcontrollers. This has been changed to use `float` datatypes instead, which are implemented in hardware floating-point on most ARM microcontrollers. This change increases performance as well as reduces the firmware size by significant number of bytes.
AVR sees minimal (if any) benefit -- `double` was interpreted as `float` on AVR anyway.
## Changes Requiring User Action :id=changes-requiring-user-action
Some keyboards "hacked" encoder support into spare slots in the key matrix in order to interoperate with VIA. This workaround is no longer necessary, and the code has been removed. If you have a keyboard that uses this workaround, you will need to update your keymap to use the new [Encoder Map](feature_encoders.md#encoder-map) API instead.
### Remove old OLED API code ([#21651](https://github.com/qmk/qmk_firmware/pull/21651)) :id=remove-old-oled-api-code
Old OLED code using `ssd1306.c``ssd1306.h`, and `SSD1306OLED` and other similar files have been consolidated to use the standard OLED driver. External user keymaps will need to be updated to use the standard OLED driver accordingly.
In most circumstances this won't affect users -- only keyboard designers with currently-unmerged boards. The only users affected are people who have modified existing keyboards in order to add/modify haptics, lighting, or bluetooth -- and only if the base keyboard did not configure them already. Driver naming has been modified to be lowercase.
RGBLight (`RGBLIGHT_DRIVER` / `rgblight.driver`):
| Old | New |
|--------|--------|
| `WS2812` | `ws2812` |
| `APA102` | `apa102` |
LED Matrix (`LED_MATRIX_DRIVER` / `led_matrix.driver`):
* RGB Matrix limit basic indicators to the last render ([#21169](https://github.com/qmk/qmk_firmware/pull/21169))
* dynamic keymap: Rely on introspection to handle OOB access. ([#21247](https://github.com/qmk/qmk_firmware/pull/21247))
* add VIA support for LED Matrix ([#21281](https://github.com/qmk/qmk_firmware/pull/21281))
* Refactor times inverse of sqrt 2 calculation ([#21293](https://github.com/qmk/qmk_firmware/pull/21293))
* Move protocol makefiles into their respective folders ([#21332](https://github.com/qmk/qmk_firmware/pull/21332))
* Remove use of __flash within LED drivers ([#21343](https://github.com/qmk/qmk_firmware/pull/21343))
* STM32H723 support ([#21352](https://github.com/qmk/qmk_firmware/pull/21352))
* Remove CORTEX_ENABLE_WFI_IDLE from keyboards. ([#21353](https://github.com/qmk/qmk_firmware/pull/21353))
* Get rid of `USB_LED_KANA` and `USB_LED_COMPOSE` ([#21366](https://github.com/qmk/qmk_firmware/pull/21366))
* Minor board clean-up after #19780 ([#21391](https://github.com/qmk/qmk_firmware/pull/21391))
* Get rid of `USB_LED_SCROLL_LOCK` ([#21405](https://github.com/qmk/qmk_firmware/pull/21405))
* Get rid of `USB_LED_NUM_LOCK` ([#21424](https://github.com/qmk/qmk_firmware/pull/21424))
* Simplify audio_duration_to_ms() and audio_ms_to_duration(), reduce firmware size by a few bytes. ([#21427](https://github.com/qmk/qmk_firmware/pull/21427))
* Allow key override to respect weak mods caused by caps word ([#21434](https://github.com/qmk/qmk_firmware/pull/21434))
* Get rid of `USB_LED_CAPS_LOCK` ([#21436](https://github.com/qmk/qmk_firmware/pull/21436))
* tmk_core: remove direct `quantum.h` includes ([#21465](https://github.com/qmk/qmk_firmware/pull/21465))
* bootmagic mods covering the case when swapped mods are pressed at the same time (#21320) ([#21472](https://github.com/qmk/qmk_firmware/pull/21472))
* drivers: remove direct `quantum.h` includes ([#21473](https://github.com/qmk/qmk_firmware/pull/21473))
* debounce: remove direct `quantum.h` includes ([#21480](https://github.com/qmk/qmk_firmware/pull/21480))
* keymap_extras: remove direct `quantum.h` includes ([#21485](https://github.com/qmk/qmk_firmware/pull/21485))
* process_keycode: remove direct `quantum.h` includes ([#21486](https://github.com/qmk/qmk_firmware/pull/21486))
# QMK Breaking Changes - 2023 November 26 Changelog
## Notable Features :id=notable-features
As per last few breaking changes cycles, there have been _a lot_ of behind-the-scenes changes, mainly around consolidation of config into `info.json` files, cleanup of `info.json` files, cleaning up driver naming, as well as addressing technical debt.
As a followup to last cycle's [notable changes](20230827.md#notable-changes), as `qmk/qmk_firmware` is no longer accepting PRs for keymaps we're pleased to announce that storing and building keymaps externally from the normal QMK Firmware repository is now possible. This is done through the new [External Userspace](newbs_external_userspace.md) feature, more details below!
## Changes Requiring User Action :id=changes-requiring-user-action
As mentioned above, the new External Userspace feature allows for keymaps to be stored and built externally from the main QMK Firmware repository. This allows for keymaps to be stored separately -- usually in their own repository -- and for users to be able to maintain and build their keymaps without needing to fork the main QMK Firmware repository.
See the [External Userspace documentation](newbs_external_userspace.md) for more details.
A significant portion of user keymaps have already been removed from `qmk/qmk_firmware` and more will follow in coming weeks. You can still recover your keymap from the tag [user-keymaps-still-present](https://github.com/qmk/qmk_firmware/tree/user-keymaps-still-present) if required -- a perfect time to migrate to the new External Userspace!
!> This feature is still in beta, and we're looking for feedback on it. Please try it out and let us know what you think -- a new `#help-userspace` channel has been set up on Discord.
### Improve and Cleanup Shutdown callbacks ([#21060](https://github.com/qmk/qmk_firmware/pull/20160)) :id=improve-and-cleanup-shutdown-callbacks
Shutdown callbacks at the keyboard level were never present, preventing safe shutdown sequencing for peripherals such as OLEDs, RGB LEDs, and other devices. This PR adds a new `shutdown_kb` function, as well as amending `shutdown_user`, allowing for safe shutdown of peripherals at both keyboard and keymap level.
See the [Keyboard Shutdown/Reboot Code](custom_quantum_functions.md#keyboard-shutdown-reboot-code) documentation for more details.
### OLED Force Flush ([#20953](https://github.com/qmk/qmk_firmware/pull/20953)) :id=oled-force-flush
Along with the new `shutdown_kb` function, a new API `oled_render_dirty(bool)` function has been added. This allows OLED contents to be written deterministically when supplied with `true` -- that is, the OLED will be updated immediately, rather than waiting for the next OLED update cycle. This allows for OLEDs to show things such as "BOOTLOADER MODE" and the like if resetting to bootloader from QMK.
### Switch statement helpers for keycode ranges ([#20059](https://github.com/qmk/qmk_firmware/pull/20059)) :id=switch-statement-helpers-for-keycode-ranges
Predefined ranges usable within switch statements have been added for groups of similar keycodes, where people who wish to handle entire blocks at once can do so. This allows keymaps to be immune to changes in keycode values, and also allows for more efficient code generation.
### Quantum Painter OLED support ([#19997](https://github.com/qmk/qmk_firmware/pull/19997)) :id=quantum-painter-oled-support
Quantum Painter has picked up support for SH1106 displays -- commonly seen as 128x64 OLEDs. Support for both I2C and SPI displays is available.
If you're already using OLED through `OLED_DRIVER_ENABLE = yes` or equivalent in `info.json` and wish to use Quantum Painter instead, you'll need to disable the old OLED system, instead enabling Quantum Painter as well as enabling the appropriate SH1106 driver. See the [Quantum Painter driver documentation](quantum_painter.md#quantum-painter-drivers) for more details. The old OLED driver is still available, and keymaps do not require migrating to Quantum Painter if you don't want to do so.
As you can probably tell by the list of PRs just above, there has been a lot of cleanup and consolidation this cycle when it comes to RGB/LED lighting drivers. The number of changes is too large to list here, but the general theme has been focusing on consistency of naming, both of drivers themselves and their respective implementation and configuration. Most changes only affect keyboard designers -- if you find that your in-development keyboard is no longer building due to naming of defines changing, your best bet is to refer to another board already in the repository which has had the changes applied.
When enabling peripherals such as I2C, SPI, or Analog/ADC, some required manual inclusion of source files in order to provide driver support, and in some cases, when multiple drivers were using the same underlying peripheral, files were being added to the build multiple times.
Most systems requiring other peripherals now mark their respective dependencies as "required", allowing the build system to check whether peripherals are necessary before including them in the build rather than having each location enable them manually.
For a concrete example, users or keyboard designers who previously added `SRC += analog.c` in order to allow for analog readings via an ADC now should specify `ANALOG_DRIVER_REQUIRED = yes` instead. The full list of added options is as follows:
### NKRO on V-USB boards ([#22398](https://github.com/qmk/qmk_firmware/pull/22398)) :id=vusb-nkro
NKRO is now available for ATmega32A and 328P-based keyboards (including PS2AVRGB/Bootmapper boards), thanks to some internal refactoring and cleanup. To enable it, the process is the same as always - add `NKRO_ENABLE = yes` to your `rules.mk`, then assign and press the `NK_TOGG` keycode to switch modes.
## Full changelist :id=full-changelist
Core:
* Compilation warning if both `keymap.json` and `keymap.c` exist ([#19939](https://github.com/qmk/qmk_firmware/pull/19939))
* [QP] Add support for OLED, variable framebuffer bpp ([#19997](https://github.com/qmk/qmk_firmware/pull/19997))
* Generate switch statement helpers for keycode ranges ([#20059](https://github.com/qmk/qmk_firmware/pull/20059))
* Chibios SPI driver: allow some SPI pins to be left unassigned ([#20315](https://github.com/qmk/qmk_firmware/pull/20315))
* Take care of scroll divisor remainders for PS/2 drag scroll ([#20732](https://github.com/qmk/qmk_firmware/pull/20732))
* Optimize the additive DAC code, fixing performance-related hangs ([#21662](https://github.com/qmk/qmk_firmware/pull/21662))
* [Enhancement] Improvements for debounce test coverage + bug fixes for sym_defer_g and sym_eager_pr ([#21667](https://github.com/qmk/qmk_firmware/pull/21667))
* fix: make clicky delay silent ([#21866](https://github.com/qmk/qmk_firmware/pull/21866))
* Add `mousekey.h` include to `quantum.h` ([#21897](https://github.com/qmk/qmk_firmware/pull/21897))
* Fix default layer value in eeconfig_init ([#21909](https://github.com/qmk/qmk_firmware/pull/21909))
* Add RTC IRQ Priority to RP2040 board files ([#21926](https://github.com/qmk/qmk_firmware/pull/21926))
* Update AW20216S LED type ([#22072](https://github.com/qmk/qmk_firmware/pull/22072))
This driver provides support for APA102 addressable RGB LEDs. They are similar to the [WS2812](ws2812_driver.md) LEDs, but have increased data and refresh rates.
## Usage :id=usage
In most cases, the APA102 driver code is automatically included if you are using either the [RGBLight](feature_rgblight.md) or [RGB Matrix](feature_rgb_matrix.md) feature with the `apa102` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add the following to your `rules.mk`:
```make
APA102_DRIVER_REQUIRED= yes
```
You can then call the APA102 API by including `apa102.h` in your code.
The QMK CLI makes building and working with QMK keyboards easier. We have provided a number of commands to simplify and streamline tasks such as obtaining and compiling the QMK firmware, creating keymaps, and more.
The QMK CLI (command line interface) makes building and working with QMK keyboards easier. We have provided a number of commands to simplify and streamline tasks such as obtaining and compiling the QMK firmware, creating keymaps, and more.
### Requirements :id=requirements
QMK requires Python 3.6 or greater. We try to keep the number of requirements small but you will also need to install the packages listed in [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt). These are installed automatically when you install the QMK CLI.
QMK requires Python 3.7 or greater. We try to keep the number of requirements small but you will also need to install the packages listed in [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt). These are installed automatically when you install the QMK CLI.
### Install Using Homebrew (macOS, some Linux) :id=install-using-homebrew
@@ -20,7 +20,7 @@ qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build
### Install Using pip :id=install-using-easy_install-or-pip
If your system is not listed above you can install QMK manually. First ensure that you have Python 3.6 (or later) installed and have installed pip. Then install QMK with this command:
If your system is not listed above you can install QMK manually. First ensure that you have Python 3.7 (or later) installed and have installed pip. Then install QMK with this command:
First we import the `cli` object from `milc`. This is how we interact with the user and control the script's behavior. We use `@cli.argument()` to define a command line flag, `--name`. This also creates a configuration variable named `hello.name` (and the corresponding `user.name`) which the user can set so they don't have to specify the argument. The `cli.subcommand()` decorator designates this function as a subcommand. The name of the subcommand will be taken from the name of the function.
Once inside our function we find a typical "Hello, World!" program. We use `cli.log` to access the underlying [Logger Object](https://docs.python.org/3.6/library/logging.html#logger-objects), whose behavior is user controllable. We also access the value for name supplied by the user as `cli.config.hello.name`. The value for `cli.config.hello.name` will be determined by looking at the `--name` argument supplied by the user, if not provided it will use the value in the `qmk.ini` config file, and if neither of those is provided it will fall back to the default supplied in the `cli.argument()` decorator.
Once inside our function we find a typical "Hello, World!" program. We use `cli.log` to access the underlying [Logger Object](https://docs.python.org/3.7/library/logging.html#logger-objects), whose behavior is user controllable. We also access the value for name supplied by the user as `cli.config.hello.name`. The value for `cli.config.hello.name` will be determined by looking at the `--name` argument supplied by the user, if not provided it will use the value in the `qmk.ini` config file, and if neither of those is provided it will fall back to the default supplied in the `cli.argument()` decorator.
# User Interaction
@@ -56,13 +56,13 @@ There are two main methods for outputting text in a subcommand- `cli.log` and `c
You can use special tokens to colorize your text, to make it easier to understand the output of your program. See [Colorizing Text](#colorizing-text) below.
Both of these methods support built-in string formatting using python's [printf style string format operations](https://docs.python.org/3.6/library/stdtypes.html#old-string-formatting). You can use tokens such as `%s` and `%d` within your text strings then pass the values as arguments. See our Hello, World program above for an example.
Both of these methods support built-in string formatting using python's [printf style string format operations](https://docs.python.org/3.7/library/stdtypes.html#old-string-formatting). You can use tokens such as `%s` and `%d` within your text strings then pass the values as arguments. See our Hello, World program above for an example.
You should never use the format operator (`%`) directly, always pass values as arguments.
### Logging (`cli.log`)
The `cli.log` object gives you access to a [Logger Object](https://docs.python.org/3.6/library/logging.html#logger-objects). We have configured our log output to show the user a nice emoji for each log level (or the log level name if their terminal does not support unicode.) This way the user can tell at a glance which messages are most important when something goes wrong.
The `cli.log` object gives you access to a [Logger Object](https://docs.python.org/3.7/library/logging.html#logger-objects). We have configured our log output to show the user a nice emoji for each log level (or the log level name if their terminal does not support unicode.) This way the user can tell at a glance which messages are most important when something goes wrong.
The default log level is `INFO`. If the user runs `qmk -v <subcommand>` the default log level will be set to `DEBUG`.
@@ -439,7 +439,7 @@ Use these to enable or disable building certain features. The more you have enab
* `UNICODE_ENABLE`
* Unicode
* `BLUETOOTH_ENABLE`
* Current options are BluefruitLE, RN42
* Current options are bluefruit_le, rn42
* `SPLIT_KEYBOARD`
* Enables split keyboard support (dual MCU like the let's split and bakingpy's boards) and includes all necessary files located at quantum/split_common
@@ -36,7 +36,7 @@ If you need help you can [open an issue](https://github.com/qmk/qmk_firmware/iss
Never made an open source contribution before? Wondering how contributions work in QMK? Here's a quick rundown!
0. Sign up for a [GitHub](https://github.com) account.
1. Put together a keymap to contribute, [find an issue](https://github.com/qmk/qmk_firmware/issues) you are interested in addressing, or [a feature](https://github.com/qmk/qmk_firmware/issues?q=is%3Aopen+is%3Aissue+label%3Afeature) you would like to add.
1. [Find an issue](https://github.com/qmk/qmk_firmware/issues) you are interested in addressing, or [a feature](https://github.com/qmk/qmk_firmware/issues?q=is%3Aopen+is%3Aissue+label%3Afeature) you would like to add.
2. Fork the repository associated with the issue to your GitHub account. This means that you will have a copy of the repository under `your-GitHub-username/qmk_firmware`.
3. Clone the repository to your local machine using `git clone https://github.com/github-username/repository-name.git`.
4. If you're working on a new feature consider opening an issue to talk with us about the work you're about to undertake.
@@ -63,12 +63,14 @@ Most of our style is pretty easy to pick up on. If you are familiar with either
We have a few different types of changes in QMK, each requiring a different level of rigor. We'd like you to keep the following guidelines in mind no matter what type of change you're making.
* **Before you contribute:** Please make sure your fork is up to date with the upstream `qmk_firmware` repo. This will help minimize CI failures that may not occur for you when compiling locally.
* Separate PRs into logical units. For example, do not submit one PR covering two separate features, instead submit a separate PR for each feature.
* Check for unnecessary whitespace with `git diff --check` before committing.
* Make sure your code change actually compiles.
* Keymaps: Make sure that `make keyboard:your_new_keymap` does not return any errors.
* Keymaps: Make sure that `make keyboard:keymap` does not return any errors.
* Keyboards: Make sure that `make keyboard:all` does not return any errors.
* Core: Make sure that `make all` does not return any errors.
* Note that user-keymap and userspace contributions are no longer accepted.
* Make sure commit messages are understandable on their own. You should put a short description (no more than 70 characters) on the first line, the second line should be empty, and on the 3rd and later lines you should describe your commit in detail, if required. Example:
```
@@ -79,8 +81,6 @@ The kerpleplork was intermittently failing with error code 23. The root cause wa
Limited experimentation on the devices I have available shows that 7 is high enough to avoid confusing the kerpleplork, but I'd like to get some feedback from people with ARM devices to be sure.
```
!> **IMPORTANT:** If you would like to contribute a bugfix or improvement to user code, such as non-default keymaps, userspace and layouts, be sure to tag the original submitter of the code in your PR. Many users, regardless of skill level with Git and GitHub, may be confused or frustrated at their code being modified without their knowledge.
## Documentation
Documentation is one of the easiest ways to get started contributing to QMK. Finding places where the documentation is wrong or incomplete and fixing those is easy! We also very badly need someone to edit our documentation, so if you have editing skills but aren't sure where or how to jump in please [reach out for help](#where-can-i-go-for-help)!
@@ -113,16 +113,6 @@ or if you only have Python 3 installed:
and navigating to `http://localhost:8936/`.
## Keymaps
Most first-time QMK contributors start with their personal keymaps. We try to keep keymap standards pretty casual (keymaps, after all, reflect the personality of their creators) but we do ask that you follow these guidelines to make it easier for others to discover and learn from your keymap.
* Write a `readme.md` using [the template](documentation_templates.md).
* All Keymap PRs are squashed, so if you care about how your commits are squashed you should do it yourself
* Do not lump features in with keymap PRs. Submit the feature first and then a second PR for the keymap.
* Do not include `Makefile`s in your keymap folder (they're no longer used)
* Update copyrights in file headers (look for `%YOUR_NAME%`)
## Keyboards
Keyboards are the raison d'être for QMK. Some keyboards are community maintained, while others are maintained by the people responsible for making a particular keyboard. The `readme.md` should tell you who maintains a particular keyboard. If you have questions relating to a particular keyboard you can [Open An Issue](https://github.com/qmk/qmk_firmware/issues) and tag the maintainer in your question.
@@ -130,7 +120,7 @@ Keyboards are the raison d'être for QMK. Some keyboards are community maintaine
We also ask that you follow these guidelines:
* Write a `readme.md` using [the template](documentation_templates.md).
*Keep the number of commits reasonable or we will squash your PR
*Include a `default` keymap that provides a clean slate for users to start with when creating their own keymaps.
* Do not lump core features in with new keyboards. Submit the feature first and then submit a separate PR for the keyboard.
* Name `.c`/`.h` file after the immediate parent folder, eg `/keyboards/<kb1>/<kb2>/<kb2>.[ch]`
* Do not include `Makefile`s in your keyboard folder (they're no longer used)
This function gets called whenever the firmware is reset, whether it's a soft reset or reset to the bootloader. This is the spot to use for any sort of cleanup, as this happens right before the actual reset. And it can be useful for turning off different systems (such as RGB, onboard screens, etc).
Additionally, it differentiates between the soft reset (eg, rebooting back into the firmware) or jumping to the bootloader.
Certain tasks are performed during shutdown too. The keyboard is cleared, music and midi is stopped (if enabled), the shutdown chime is triggered (if audio is enabled), and haptic is stopped.
If `jump_to_bootloader` is set to `true`, this indicates that the board will be entering the bootloader for a new firmware flash, whereas `false` indicates that this is happening for a soft reset and will load the firmware agaim immediately (such as when using `QK_REBOOT` or `QK_CLEAR_EEPROM`).
As there is a keyboard and user level function, returning `false` for the user function will disable the keyboard level function, allowing for customization.
?> Bootmagic does not trigger `shutdown_*()` as it happens before most of the initialization process.
### Example `shutdown_kb()` Implementation
```c
boolshutdown_kb(booljump_to_bootloader){
if(!shutdown_user(jump_to_bootloader)){
returnfalse;
}
if(jump_to_bootloader){
// red for bootloader
rgb_matrix_set_color_all(RGB_OFF);
}else{
// off for soft reset
rgb_matrix_set_color_all(RGB_GREEN);
}
// force flushing -- otherwise will never happen
rgb_matrix_update_pwm_buffers();
returntrue;
}
```
### Example `shutdown_user()` Implementation
```c
boolshutdown_user(booljump_to_bootloader){
if(jump_to_bootloader){
// red for bootloader
rgb_matrix_set_color_all(RGB_RED);
}else{
// off for soft reset
rgb_matrix_set_color_all(RGB_OFF);
}
// force flushing -- otherwise will never happen
rgb_matrix_update_pwm_buffers();
// false to not process kb level
returnfalse;
}
```
### Keyboard shutdown/reboot Function Documentation
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.
`#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.
`#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` | `(backing_size/2)` | 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.
@@ -139,7 +147,7 @@ Configurable options in your keyboard's `config.h`:
`#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_LOGICAL_SIZE` | `(backing_size/2)` | 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.
Additionally, `apply_autocorrect(uint8_t backspaces, const char *str)` allows for users to add additional handling to the autocorrection, or replace the functionality entirely. This passes on the number of backspaces needed to replace the words, as well as the replacement string (partial word, not the full word).
Additionally, `apply_autocorrect(uint8_t backspaces, const char *str, char *typo, char *correct)` allows for users to add additional handling to the autocorrection, or replace the functionality entirely. This passes on the number of backspaces needed to replace the words, as well as the replacement string (partial word, not the full word), and the typo and corrected strings (complete words).
?> Due to the way code works (no notion of words, just a stream of letters), the `typo` and `correct` strings are a best bet and could be "wrong". For example you may get `wordtpyo`&`wordtypo` instead of the expected `tpyo`&`typo`.
#### Apply Autocorrect Example
@@ -209,7 +211,7 @@ This following example will play a sound when a typo is autocorrected and execut
?> In this callback function, `return false` will stop the normal processing of autocorrect, which requires manually handling of removing the "bad" characters and typing the new characters.
!> ***IMPORTANT***: `str` is a pointer to `PROGMEM` data for the autocorrection. If you return false, and want to send the string, this needs to use `send_string_P` and not `send_string` or `SEND_STRING`.
!> ***IMPORTANT***: `str` is a pointer to `PROGMEM` data for the autocorrection. If you return false, and want to send the string, this needs to use `send_string_P` and not `send_string`nor `SEND_STRING`.
You can also use `apply_autocorrect` to detect and display the event but allow internal code to execute the autocorrection with `return true`:
Many keyboards support backlit keys by way of individual LEDs placed through or underneath the keyswitches. This feature is distinct from both the [RGB underglow](feature_rgblight.md) and [RGB matrix](feature_rgb_matrix.md) features as it usually allows for only a single colour per switch, though you can obviously install multiple different single coloured LEDs on a keyboard.
Many keyboards support backlit keys by way of individual LEDs placed through or underneath the keyswitches. This feature is distinct from both the [RGB Underglow](feature_rgblight.md) and [RGB Matrix](feature_rgb_matrix.md) features as it usually allows for only a single colour per switch, though you can obviously install multiple different single coloured LEDs on a keyboard.
QMK is able to control the brightness of these LEDs by switching them on and off rapidly in a certain ratio, a technique known as *Pulse Width Modulation*, or PWM. By altering the duty cycle of the PWM signal, it creates the illusion of dimming.
The MCU can only supply so much current to its GPIO pins. Instead of powering the backlight directly from the MCU, the backlight pin is connected to a transistor or MOSFET that switches the power to the LEDs.
## Usage :id=usage
Most keyboards have backlighting enabled by default if they support it, but if it is not working for you, check that your `rules.mk` includes the following:
Most keyboards have backlighting enabled by default if they support it, but if it is not working for you (or you have added support), check that your `rules.mk` includes the following:
```make
BACKLIGHT_ENABLE= yes
@@ -14,186 +14,95 @@ BACKLIGHT_ENABLE = yes
## Keycodes :id=keycodes
Once enabled, the following keycodes below can be used to change the backlight level.
|`BACKLIGHT_PIN` |*Not defined* |The pin that controls the LED(s) |
|`BACKLIGHT_PIN` |*Not defined* |The pin that controls the LEDs |
|`BACKLIGHT_LEVELS` |`3` |The number of brightness levels (maximum 31 excluding off) |
|`BACKLIGHT_CAPS_LOCK` |*Not defined* |Enable Caps Lock indicator using backlight (for keyboards without dedicated LED) |
|`BACKLIGHT_BREATHING` |*Not defined* |Enable backlight breathing, if supported |
|`BREATHING_PERIOD` |`6` |The length of one backlight "breath" in seconds |
|`BACKLIGHT_ON_STATE` |`1` |The state of the backlight pin when the backlight is "on" - `1` for high, `0` for low |
|`BACKLIGHT_LIMIT_VAL` |`255` |The maximum duty cycle of the backlight -- `255` allows for full brightness, any lower will decrease the maximum.|
|`BACKLIGHT_DEFAULT_ON` |`true` |Enable backlight upon clearing the EEPROM |
|`BACKLIGHT_DEFAULT_BREATHING`|`false` |Whether to enable backlight breathing upon clearing the EEPROM |
|`BACKLIGHT_DEFAULT_LEVEL` |`BACKLIGHT_LEVELS`|The default backlight level to use upon clearing the EEPROM |
|`BACKLIGHT_DEFAULT_BREATHING`|*Not defined* |Whether to enable backlight breathing upon clearing the EEPROM |
Unless you are designing your own keyboard, you generally should not need to change the `BACKLIGHT_PIN` or `BACKLIGHT_ON_STATE`.
### Backlight On State :id=backlight-on-state
### "On" State :id=on-state
Most backlight circuits are driven by an N-channel MOSFET or NPN transistor. This means that to turn the transistor *on* and light the LEDs, you must drive the backlight pin, connected to the gate or base, *high*.
Sometimes, however, a P-channel MOSFET, or a PNP transistor is used. In this case, when the transistor is on, the pin is driven *low* instead.
This functionality is configured at the keyboard level with the `BACKLIGHT_ON_STATE` define.
To configure the "on" state of the backlight circuit, add the following to your `config.h`:
### AVR Driver :id=avr-driver
The `pwm` driver is configured by default, however the equivalent setting within `rules.mk` would be:
```make
BACKLIGHT_DRIVER= pwm
```c
#define BACKLIGHT_ON_STATE 0
```
#### Caveats :id=avr-caveats
On AVR boards, QMK automatically decides which driver to use according to the following table:
All other pins will use timer-assisted software PWM:
|Audio Pin|Audio Timer|Software PWM Timer|
|---------|-----------|------------------|
|`C4` |Timer 3 |Timer 1 |
|`C5` |Timer 3 |Timer 1 |
|`C6` |Timer 3 |Timer 1 |
|`B5` |Timer 1 |Timer 3 |
|`B6` |Timer 1 |Timer 3 |
|`B7` |Timer 1 |Timer 3 |
When both timers are in use for Audio, the backlight PWM cannot use a hardware timer, and will instead be triggered during the matrix scan. In this case, breathing is not supported, and the backlight might flicker, because the PWM computation may not be called with enough timing precision.
When using the supported pins for backlighting, QMK will use a hardware timer configured to output a PWM signal. This timer will count up to `ICRx` (by default `0xFFFF`) before resetting to 0.
The desired brightness is calculated and stored in the `OCRxx` register. When the counter reaches this value, the backlight pin will go low, and is pulled high again when the counter resets.
In this way `OCRxx` essentially controls the duty cycle of the LEDs, and thus the brightness, where `0x0000` is completely off and `0xFFFF` is completely on.
The breathing effect is achieved by registering an interrupt handler for `TIMER1_OVF_vect` that is called whenever the counter resets, roughly 244 times per second.
In this handler, the value of an incrementing counter is mapped onto a precomputed brightness curve. To turn off breathing, the interrupt handler is simply disabled, and the brightness reset to the level stored in EEPROM.
When `BACKLIGHT_PIN` is not set to a hardware backlight pin, QMK will use a hardware timer configured to trigger software interrupts. This time will count up to `ICRx` (by default `0xFFFF`) before resetting to 0.
When resetting to 0, the CPU will fire an OVF (overflow) interrupt that will turn the LEDs on, starting the duty cycle.
The desired brightness is calculated and stored in the `OCRxx` register. When the counter reaches this value, the CPU will fire a Compare Output match interrupt, which will turn the LEDs off.
In this way `OCRxx` essentially controls the duty cycle of the LEDs, and thus the brightness, where `0x0000` is completely off and `0xFFFF` is completely on.
The breathing effect is the same as in the hardware PWM implementation.
### ARM Driver :id=arm-configuration
While still in its early stages, ARM backlight support aims to eventually have feature parity with AVR. The `pwm` driver is configured by default, however the equivalent setting within `rules.mk` would be:
```make
BACKLIGHT_DRIVER= pwm
```
#### ChibiOS Configuration :id=arm-configuration
The following `#define`s apply only to ARM-based keyboards:
|`BACKLIGHT_PWM_DRIVER` |`PWMD4`|The PWM driver to use |
|`BACKLIGHT_PWM_CHANNEL`|`3` |The PWM channel to use |
|`BACKLIGHT_PAL_MODE` |`2` |The pin alternative function to use|
See the ST datasheet for your particular MCU to determine these values. Unless you are designing your own keyboard, you generally should not need to change them.
#### Caveats :id=arm-caveats
Currently only hardware PWM is supported, not timer assisted, and does not provide automatic configuration.
### Software PWM Driver :id=software-pwm-driver
In this mode, PWM is "emulated" while running other keyboard tasks. It offers maximum hardware compatibility without extra platform configuration. The tradeoff is the backlight might jitter when the keyboard is busy. To enable, add this to your `rules.mk`:
Most keyboards have only one backlight pin which controls all backlight LEDs (especially if the backlight is connected to a hardware PWM pin).
In software PWM, it is possible to define multiple backlight pins, which will be turned on and off at the same time during the PWM duty cycle.
The `timer` and `software` drivers allow you to define multiple backlight pins, which will be turned on and off at the same time during the PWM duty cycle.
This feature allows to set, for instance, the Caps Lock LED's (or any other controllable LED) brightness at the same level as the other LEDs of the backlight. This is useful if you have mapped Control in place of Caps Lock and you need the Caps Lock LED to be part of the backlight instead of being activated when Caps Lock is on, as it is usually wired to a separate pin from the backlight.
To activate multiple backlight pins, add something like this to your `config.h`, instead of `BACKLIGHT_PIN`:
To configure multiple backlight pins, add something like this to your `config.h`, instead of `BACKLIGHT_PIN`:
```c
#define BACKLIGHT_PINS { F5, B2 }
```
## Driver Configuration :id=driver-configuration
Backlight driver selection is configured in `rules.mk`. Valid drivers are `pwm` (default), `timer`, `software`, or `custom`. See below for information on individual drivers.
### PWM Driver :id=pwm-driver
This is the default backlight driver, which leverages the hardware PWM output capability of the microcontroller.
```make
BACKLIGHT_DRIVER= pwm
```
### Timer Driver :id=timer-driver
This driver is similar to the PWM driver, but instead of directly configuring the pin to output a PWM signal, an interrupt handler is attached to the timer to turn the pin on and off as appropriate.
```make
BACKLIGHT_DRIVER= timer
```
### Software Driver :id=software-driver
In this mode, PWM is "emulated" while running other keyboard tasks. It offers maximum hardware compatibility without extra platform configuration. However, breathing is not supported, and the backlight can flicker when the keyboard is busy.
```make
BACKLIGHT_DRIVER= software
```
### Custom Driver :id=custom-driver
If none of the above drivers apply to your board (for example, you are using a separate IC to control the backlight), you can implement a custom backlight driver using this simple API provided by QMK. To enable, add this to your `rules.mk`:
If none of the above drivers apply to your board (for example, you are using a separate IC to control the backlight), you can implement a custom backlight driver using a simple API.
The following table describes the supported pins for the PWM driver. Only cells marked with a timer number are capable of hardware PWM output; any others must use the `timer` driver.
|`BACKLIGHT_PWM_DRIVER` |`PWMD4` |The PWM driver to use |
|`BACKLIGHT_PWM_CHANNEL`|`3` |The PWM channel to use |
|`BACKLIGHT_PAL_MODE` |`2` |The pin alternative function to use |
|`BACKLIGHT_PWM_PERIOD` |*Not defined*|The PWM period in counter ticks - Default is platform dependent|
Refer to the ST datasheet for your particular MCU to determine these values. For example, these defaults are set up for pin `B8` on a Proton-C (STM32F303) using `TIM4_CH3` on AF2. Unless you are designing your own keyboard, you generally should not need to change them.
### Timer Driver :id=arm-timer-driver
Depending on the ChibiOS board configuration, you may need to enable general-purpose timers at the keyboard level. For STM32, this would look like:
`halconf.h`:
```c
#define HAL_USE_GPT TRUE
```
`mcuconf.h`:
```c
#undef STM32_GPT_USE_TIM15
#define STM32_GPT_USE_TIM15 TRUE
```
The following `#define`s apply only to the `timer` driver:
|`BACKLIGHT_GPT_DRIVER`|`GPTD15`|The timer to use|
## Example Schematic
Since the MCU can only supply so much current to its GPIO pins, instead of powering the backlight directly from the MCU, the backlight pin is connected to a transistor or MOSFET that switches the power to the LEDs.
In this typical example, the backlight LEDs are all connected in parallel towards an N-channel MOSFET. Its gate pin is wired to one of the microcontroller's GPIO pins through a 470Ω resistor to avoid ringing.
A pulldown resistor is also placed between the gate pin and ground to keep it at a defined state when it is not otherwise being driven by the MCU.
The values of these resistors are not critical - see [this Electronics StackExchange question](https://electronics.stackexchange.com/q/68748) for more information.

Currently Bluetooth support is limited to AVR based chips. For Bluetooth 2.1, QMK has support for RN-42 modules. For more recent BLE protocols, currently only the Adafruit Bluefruit SPI Friend is directly supported. BLE is needed to connect to iOS devices. Note iOS does not support mouse input.
|[Bluefruit LE SPI Friend](https://www.adafruit.com/product/2633)|Bluetooth Low Energy|SPI |`BLUETOOTH_DRIVER = bluefruit_le`|nRF51822 |
Not Supported Yet but possible:
* [Bluefruit LE UART Friend](https://www.adafruit.com/product/2479). [Possible tmk implementation found in](https://github.com/tmk/tmk_keyboard/issues/514)
@@ -32,7 +32,7 @@ Add the following to your `rules.mk`:
Since many drop-in replacement controllers now exist, we've done our best to make them easy to use in existing designs.
This page documents the automated process for converting keyboards to use drop-in replacement controllers. This process is designed to be easy to use and can be completed in a few simple steps.
This page documents the handy automated process for converting keyboards.
## Supported Converters
### Supported Converters
Currently the following converters are available:
The following converters are available at this time:
| From | To |
|------------|-------------------|
@@ -28,14 +26,10 @@ Currently the following converters are available:
| `elite_c` | `helios` |
| `elite_c` | `liatris` |
See below for more in depth information on each converter.
## Overview
Each converter category is broken down by its declared `pin compatibility`.
This ensures that only valid combinations are attempted.
You can generate the firmware by appending `-e CONVERT_TO=<target>` to your compile/flash command. For example:
Each converter category is broken down by its declared `pin compatibility`. This ensures that only valid combinations are attempted. You can generate the firmware by appending `-e CONVERT_TO=<target>` to your compile/flash command. For example:
@@ -59,14 +53,12 @@ Once a converter is enabled, it exposes the `CONVERT_TO_<target_uppercase>` flag
### Pin Compatibility
To ensure compatibility, provide validation, and power future workflows, a keyboard should declare its `pin compatibility`. For legacy reasons, this is currently assumed to be `promicro`.
To ensure compatibility, provide validation, and enable future workflows, a keyboard should declare its `pin compatibility`. For legacy reasons, this is currently assumed to be `promicro`. The following pin compatibility interfaces are currently defined:
Currently the following pin compatibility interfaces are defined:
To declare the base for conversions, add this line to your keyboard's `rules.mk`:
@@ -140,7 +132,7 @@ The following defaults are based on what has been implemented for [RP2040](platf
### SparkFun Pro Micro - RP2040, Blok, Bit-C PRO and Michi :id=promicro_rp2040
Currently identical to [Adafruit KB2040](#kb2040).
Feature set is identical to [Adafruit KB2040](#kb2040).
### STeMCell :id=stemcell
@@ -150,9 +142,7 @@ There are two versions of STeMCell available, with different pinouts:
- 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.
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 |
|-----------|---------------|
@@ -173,11 +163,8 @@ The Bonsai C4 only has one on-board LED (B2), and by default, both the Pro Micro
### RP2040 Community Edition - Elite-Pi, Helios, and Liatris :id=rp2040_ce
Feature set currently identical to [Adafruit KB2040](#kb2040).
Feature set is identical to [Adafruit KB2040](#kb2040). VBUS detection is enabled by default for superior split keyboard support. For more information, refer to the [Community Edition pinout](platformdev_rp2040.md#rp2040_ce) docs.
Enables VBUS detection by default for superior split keyboard support.
For more information, refer to the [RP2040 Community Edition](platformdev_rp2040.md#rp2040_ce) docs.
## Elite-C
@@ -202,8 +189,8 @@ Converter summary:
### STeMCell :id=stemcell_elite
Currently identical to [STeMCell](#stemcell) with support for the additional bottom row of pins.
Identical to [Pro Micro - STeMCell](#stemcell) with support for the additional bottom row of pins.
### RP2040 Community Edition :id=rp2040_ce_elite
Currently identical to [RP2040 Community Edition](#rp2040_ce), with support for the additional bottom row of pins.
Identical to [Pro Micro - RP2040 Community Edition](#rp2040_ce) with support for the additional bottom row of pins.
The following options are currently available for haptic feedback in `rules.mk`:
```
```make
HAPTIC_ENABLE= yes
HAPTIC_DRIVER += DRV2605L
HAPTIC_DRIVER += SOLENOID
HAPTIC_DRIVER = drv2605l
# or
HAPTIC_DRIVER= solenoid
```
The following `config.h` settings are available for all types of haptic feedback:
@@ -92,30 +93,30 @@ This driver supports 2 different feedback motors. Set the following in your `con
Eccentric Rotating Mass vibration motors (ERM) is motor with a off-set weight attached so when drive signal is attached, the off-set weight spins and causes a sinusoidal wave that translate into vibrations.
#define DRV2605L_FB_LOOPGAIN 1 /* For Low:0, Medium:1, High:2, Very High:3 */
/* Please refer to your datasheet for the optimal setting for your specific motor. */
#define RATED_VOLTAGE 3
#define V_PEAK 5
#define DRV2605L_RATED_VOLTAGE 3
#define DRV2605L_V_PEAK 5
```
##### LRA
Linear resonant actuators (LRA, also know as a linear vibrator) works different from a ERM. A LRA has a weight and magnet suspended by springs and a voice coil. When the drive signal is applied, the weight would be vibrate on a single axis (side to side or up and down). Since the weight is attached to a spring, there is a resonance effect at a specific frequency. This frequency is where the LRA will operate the most efficiently. Refer to the motor's datasheet for the recommanded range for this frequency.
LCD modules using [HD44780U](https://www.sparkfun.com/datasheets/LCD/HD44780.pdf) IC or equivalent, communicating in 4-bit mode.
@@ -11,7 +11,7 @@ LCD modules using [HD44780U](https://www.sparkfun.com/datasheets/LCD/HD44780.pdf
To run these modules at 3.3V, an additional MAX660 voltage converter IC must be soldered on, along with two 10µF capacitors. See [this page](https://www.codrey.com/electronic-circuits/hack-your-16x2-lcd/) for more details.
## Usage
## Usage :id=usage
Add the following to your `rules.mk`:
@@ -19,7 +19,7 @@ Add the following to your `rules.mk`:
HD44780_ENABLE= yes
```
## Basic Configuration
## Basic Configuration :id=basic-configuration
Add the following to your `config.h`:
@@ -33,9 +33,9 @@ Add the following to your `config.h`:
|`HD44780_DISPLAY_LINES`|`2` |The number of visible lines on the display |
|`HD44780_WRAP_LINES` |*Not defined* |If defined, input characters will wrap to the next line |
Whether to read the current cursor position, or the character at the cursor.
#### Return Value
#### Return Value :id=api-hd44780-read-return
If `isData` is `true`, the returned byte will be the character at the current DDRAM address. Otherwise, it will be the current DDRAM address and the busy flag.
@@ -21,7 +21,7 @@ Then, in your `keymap.c` file, you'll need to define the array `key_overrides`,
The `key_override_t` struct has many options that allow you to precisely tune your overrides. The full reference is shown below. Instead of manually creating a `key_override_t` value, it is recommended to use these dedicated initializers:
#### `ko_make_basic(modifiers, key, replacement)`
Returns a `key_override_t`, which sends `replacement` (can be a key-modifer combination), when `key` and `modifiers` are all pressed down. This override still activates if any additional modifiers not specified in `modifiers` are also pressed down. See `ko_make_with_layers_and_negmods` to customize this behavior.
Returns a `key_override_t`, which sends `replacement` (can be a key-modifier combination), when `key` and `modifiers` are all pressed down. This override still activates if any additional modifiers not specified in `modifiers` are also pressed down. See `ko_make_with_layers_and_negmods` to customize this behavior.
Additionally takes a bitmask `layers` that defines on which layers the override is used.
@@ -224,4 +224,31 @@ The duration of the key repeat delay is controlled with the `KEY_OVERRIDE_REPEAT
## Difference to Combos :id=difference-to-combos
Note that key overrides are very different from [combos](https://docs.qmk.fm/#/feature_combo). Combos require that you press down several keys almost _at the same time_ and can work with any combination of non-modifier keys. Key overrides work like keyboard shortcuts (e.g. `ctrl` + `z`): They take combinations of _multiple_ modifiers and _one_ non-modifier keyto then perform some custom action.Keyoverridesare implemented with much care to behave just like normal keyboard shortcuts would inregardstotheorderof pressed keys,timing,and interacton with other pressed keys.Thereareanumberof optional settings that canbeusedto really fine-tune thebehaviorofeachkeyoverrideaswell.Usingkey overrides also does notdelaykeyinputforregularkey presses, which inherently happens incombosandmaybe undesirable.
Note that key overrides are very different from [combos](https://docs.qmk.fm/#/feature_combo). Combos require that you press down several keys almost _at the same time_ and can work with any combination of non-modifier keys. Key overrides work like keyboard shortcuts (e.g. `ctrl` + `z`): Theytakecombinations of _multiple_modifiers and _one_non-modifier key to thenperformsomecustomaction. Key overrides are implementedwithmuchcare to behavejustlikenormalkeyboardshortcutswould in regards to the order of pressedkeys, timing, and interactionwithotherpressedkeys. There are a number of optionalsettingsthat can be used to reallyfine-tune the behavior of each key override as well. Using key overridesalsodoes not delay key input for regular key presses, whichinherentlyhappens in combos and may be undesirable.
## Solution to the problem of flashing modifiers :id=neutralize-flashing-modifiers
If the programs you use bind an action to taps of modifier keys (e.g. tapping left GUI to bring up the applications menu or tapping left Alt to focus the menu bar), you may find that using key overrides with suppressed mods falsely triggers those actions. To counteract this, you can define a `DUMMY_MOD_NEUTRALIZER_KEYCODE` in `config.h` that will get sent in between the register and unregister events of a suppressed modifier. That way, the programs on your computer will no longer interpret the mod suppression induced by key overrides as a lone tap of a modifier key and will thus not falsely trigger the undesired action.
Naturally, for this technique to be effective, you must choose a `DUMMY_MOD_NEUTRALIZER_KEYCODE` for which no keyboard shortcuts are bound to. Recommended values are: `KC_RIGHT_CTRL` or `KC_F18`.
Please note that `DUMMY_MOD_NEUTRALIZER_KEYCODE` must be a basic, unmodified, HID keycode so values like `KC_NO`, `KC_TRANSPARENT` or `KC_PIPE` aka `S(KC_BACKSLASH)` are not permitted.
By default, only left Alt and left GUI are neutralized. If you want to change the list of applicable modifier masks, use the following in your `config.h`:
!> Do not use `MOD_xxx` constants like `MOD_LSFT` or `MOD_RALT`, since they're 5-bit packed bit-arrays while `MODS_TO_NEUTRALIZE` expects a list of 8-bit packed bit-arrays. Use `MOD_BIT(<kc>)` or `MOD_MASK_xxx` instead.
@@ -12,21 +12,20 @@ There is basic support for addressable LED matrix lighting with the I2C IS31FL37
```make
LED_MATRIX_ENABLE= yes
LED_MATRIX_DRIVER=IS31FL3731
LED_MATRIX_DRIVER=is31fl3731
```
You can use between 1 and 4 IS31FL3731 IC's. Do not specify `LED_DRIVER_ADDR_<N>` defines for IC's that are not present on your keyboard. You can define the following items in `config.h`:
| Variable | Description | Default |
|----------|-------------|---------|
| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
| `LED_DRIVER_COUNT` | (Required) How many LED driver IC's are present | |
| `IS31FL3731_I2C_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
| `IS31FL3731_I2C_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
| `LED_MATRIX_LED_COUNT` | (Required) How many LED lights are present across all drivers | |
| `LED_DRIVER_ADDR_1` | (Required) Address for the first LED driver | |
| `LED_DRIVER_ADDR_2` | (Optional) Address for the second LED driver | |
| `LED_DRIVER_ADDR_3` | (Optional) Address for the third LED driver | |
| `LED_DRIVER_ADDR_4` | (Optional) Address for the fourth LED driver | |
| `IS31FL3731_I2C_ADDRESS_1` | (Required) Address for the first LED driver | |
| `IS31FL3731_I2C_ADDRESS_2` | (Optional) Address for the second LED driver | |
| `IS31FL3731_I2C_ADDRESS_3` | (Optional) Address for the third LED driver | |
| `IS31FL3731_I2C_ADDRESS_4` | (Optional) Address for the fourth LED driver | |
Here is an example using 2 drivers.
@@ -34,14 +33,15 @@ Here is an example using 2 drivers.
// This is a 7-bit address, that gets left-shifted and bit 0
// set to 0 for write, 1 for read (as per I2C protocol)
// The address will vary depending on your wiring:
@@ -49,12 +49,12 @@ Here is an example using 2 drivers.
!> Note the parentheses, this is so when `LED_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL)` will give very different results than `rand() % LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL`.
For split keyboards using `LED_MATRIX_SPLIT` with an LED driver, you can either have the same driver address or different driver addresses. If using different addresses, use `DRIVER_ADDR_1` for one and `DRIVER_ADDR_2` for the other one. Then, in `g_is31_leds`, fill out the correct driver index (0 or 1). If using one address, use `DRIVER_ADDR_1` for both, and use index 0 for `g_is31_leds`.
For split keyboards using `LED_MATRIX_SPLIT` with an LED driver, you can either have the same driver address or different driver addresses. If using different addresses, use `IS31FL3731_I2C_ADDRESS_1` for one and `IS31FL3731_I2C_ADDRESS_2` for the other one. Then, in `g_is31fl3731_leds`, fill out the correct driver index (0 or 1). If using one address, use `IS31FL3731_I2C_ADDRESS_1` for both, and use index 0 for `g_is31fl3731_leds`.
Define these arrays listing all the LEDs in your `<keyboard>.c`:
#define LED_MATRIX_KEYRELEASES // reactive effects respond to keyreleases (instead of keypresses)
#define LED_MATRIX_TIMEOUT 0 // number of milliseconds to wait until led automatically turns off
#define LED_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended
#define LED_MATRIX_LED_PROCESS_LIMIT (LED_MATRIX_LED_COUNT + 4) / 5 // limits the number of LEDs to process in an animation per task run (increases keyboard responsiveness)
#define LED_MATRIX_LED_FLUSH_LIMIT 16 // limits in milliseconds how frequently an animation will update the LEDs. 16 (16ms) is equivalent to limiting to 60fps (increases keyboard responsiveness)
#define LED_MATRIX_MAXIMUM_BRIGHTNESS 255 // limits maximum brightness of LEDs
#define LED_MATRIX_DEFAULT_ON true // Sets the default enabled state, if none has been set
#define LED_MATRIX_DEFAULT_MODE LED_MATRIX_SOLID // Sets the default mode, if none has been set
#define LED_MATRIX_DEFAULT_VAL LED_MATRIX_MAXIMUM_BRIGHTNESS // Sets the default brightness value, if none has been set
#define LED_MATRIX_DEFAULT_SPD 127 // Sets the default animation speed, if none has been set
#define LED_MATRIX_SPLIT { X, Y } // (Optional) For split keyboards, the number of LEDs connected on each half. X = left, Y = Right.
// If LED_MATRIX_KEYPRESSES or LED_MATRIX_KEYRELEASES is enabled, you also will want to enable SPLIT_TRANSPORT_MIRROR
// If reactive effects are enabled, you also will want to enable SPLIT_TRANSPORT_MIRROR
```
## EEPROM storage :id=eeprom-storage
@@ -433,7 +426,7 @@ The EEPROM for it is currently shared with the RGB Matrix system (it's generally
### Indicators :id=indicators
If you want to set custom indicators, such as an LED for Caps Lock, or layer indication, you can use the `led_matrix_indicators_kb` or `led_matrix_indicators_user` function for that:
If you want to set custom indicators, such as an LED for Caps Lock, or layer indication, then you can use the `led_matrix_indicators_kb` function on the keyboard level source file, or `led_matrix_indicators_user` function in the user `keymap.c`.
@@ -67,6 +67,7 @@ This is the default mode. You can adjust the cursor and scrolling acceleration u
|`MOUSEKEY_TIME_TO_MAX` |30 |Time until maximum cursor speed is reached |
|`MOUSEKEY_WHEEL_DELAY` |10 |Delay between pressing a wheel key and wheel movement |
|`MOUSEKEY_WHEEL_INTERVAL` |80 |Time between wheel movements |
|`MOUSEKEY_WHEEL_DELTA` |1 |Wheel movement step size |
|`MOUSEKEY_WHEEL_MAX_SPEED` |8 |Maximum number of scroll steps per scroll action |
|`MOUSEKEY_WHEEL_TIME_TO_MAX`|40 |Time until maximum scroll speed is reached |
@@ -101,7 +102,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 `2`. 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 `1`. Setting mouse wheel speed is done by adjusting the number of wheel movements per second.
|i2c (default)| Uses I2C for communication with the OLED panel |
|spi | Uses SPI for communication with the OLED panel |
|`i2c` (default)| Uses I2C for communication with the OLED panel |
|`spi` | Uses SPI for communication with the OLED panel |
e.g.
```make
@@ -166,6 +167,28 @@ bool oled_task_user(void) {
#endif
```
Render a message before booting into bootloader mode.
```c
voidoled_render_boot(boolbootloader){
oled_clear();
for(inti=0;i<16;i++){
oled_set_cursor(0,i);
if(bootloader){
oled_write_P(PSTR("Awaiting New Firmware "),false);
}else{
oled_write_P(PSTR("Rebooting "),false);
}
}
oled_render_dirty(true);
}
boolshutdown_user(booljump_to_bootloader){
oled_render_boot(jump_to_bootloader);
}
```
## Basic Configuration
These configuration options should be placed in `config.h`. Example:
@@ -190,7 +213,7 @@ These configuration options should be placed in `config.h`. Example:
|`OLED_SCROLL_TIMEOUT_RIGHT`|*Not defined* |Scroll timeout direction is right when defined, left when undefined. |
|`OLED_TIMEOUT` |`60000` |Turns off the OLED screen after 60000ms of screen update inactivity. Helps reduce OLED Burn-in. Set to 0 to disable. |
|`OLED_UPDATE_INTERVAL` |`0` (`50` for split keyboards) |Set the time interval for updating the OLED display in ms. This will improve the matrix scan rate. |
|`OLED_UPDATE_PROCESS_LIMIT'|`1` |Set the number of dirty blocks to render per loop. Increasing may degrade performance. |
|`OLED_UPDATE_PROCESS_LIMIT`|`1` |Set the number of dirty blocks to render per loop. Increasing may degrade performance. |
### I2C Configuration
|Define |Default |Description |
@@ -275,7 +298,7 @@ Rotation on SH1106 and SH1107 is noticeably less efficient than on SSD1306, beca
#### Set different target layer when a particular layer is active:
The below code will change the auto mouse layer target to `_MOUSE_LAYER_2` when `_DEFAULT_LAYER_2` is highest default layer state.
*NOTE: that `auto_mouse_layer_off` is used here instead of `remove_auto_mouse_layer` as `default_layer_state_set_*` stack is separate from the `layer_state_set_*` stack* if something similar was to be done in `layer_state_set_user `state = remove_auto_mouse_layer(state, false)` should be used instead
*ADDITIONAL NOTE: `AUTO_MOUSE_TARGET_LAYER` is checked if already set to avoid deactivating the target layer unless needed*
The below code will change the auto mouse layer target to `_MOUSE_LAYER_2` when `_DEFAULT_LAYER_2` is highest default layer state.
*NOTE: that `auto_mouse_layer_off` is used here instead of `remove_auto_mouse_layer` as `default_layer_state_set_*` stack is separate from the `layer_state_set_*` stack*, if something similar was to be done in `layer_state_set_user`, `state = remove_auto_mouse_layer(state, false)` should be used instead.
*ADDITIONAL NOTE: `AUTO_MOUSE_TARGET_LAYER` is checked if already set to avoid deactivating the target layer unless needed*.
Programmable Buttons are keys that have no predefined meaning. This means they can be processed on the host side by custom software without the operating system trying to interpret them.
The keycodes are emitted according to the HID Telephony Device page (`0x0B`), Programmable Button usage (`0x07`). On Linux (> 5.14) they are handled automatically and translated to `KEY_MACRO#` keycodes (up to `KEY_MACRO30`).
The keycodes are emitted according to the HID Telephony Device page (`0x0B`), Programmable Button usage (`0x09`). On Linux (> 5.14) they are handled automatically and translated to `KEY_MACRO#` keycodes (up to `KEY_MACRO30`).
?> Currently there is no known support in Windows or macOS. It may be possible to write a custom HID driver to receive these usages, but this is out of the scope of the QMK documentation.
The `PIO` subsystem is a Raspberry Pi RP2040 specific implementation, using the integrated PIO peripheral and is therefore only available on this MCU.
There are strict requirements for pin ordering but any pair of GPIO pins can be used. The GPIO used for clock must be directly after data, see the included info.json snippet for an example of correct order.
You may optionally switch the PIO peripheral used with the following define in config.h:
```c
#define PS2_PIO_USE_PIO1 // Force the usage of PIO1 peripheral, by default the PS2 implementation uses the PIO0 peripheral
Raw HID allows for bidirectional communication between QMK and the host computer over an HID interface. This has many potential use cases, such as switching keymaps on the fly or changing RGB LED colors and modes.
The Raw HID feature allows for bidirectional communication between QMK and the host computer over an HID interface. This has many potential use cases, such as switching keymaps on the fly or sending useful metrics like CPU/RAM usage.
There are two main components to getting raw HID working with your keyboard.
In order to communicate with the keyboard using this feature, you will need to write a program that runs on the host. As such, some basic programming skills are required - more if you intend to implement complex behaviour.
## Keyboard firmware
## Usage :id=usage
The implementation is fairly straightforward for the firmware.
In your `rules.mk` add:
Add the following to your `rules.mk`:
```make
RAW_ENABLE= yes
```
In your `keymap.c` include `"raw_hid.h"` and implement the following:
## Basic Configuration :id=basic-configuration
By default, the HID Usage Page and Usage ID for the Raw HID interface are `0xFF60` and `0x61`. However, they can be changed if necessary by adding the following to your `config.h`:
|`RAW_USAGE_PAGE`|`0xFF60`|The usage page of the Raw HID interface|
|`RAW_USAGE_ID` |`0x61` |The usage ID of the Raw HID interface |
## Sending Data to the Keyboard :id=sending-data-to-the-keyboard
To send data to the keyboard, you must first find a library for communicating with HID devices in the programming language of your choice. Here are some examples:
* **Java:** [purejavahidapi](https://github.com/nyholku/purejavahidapi) and [hid4java](https://github.com/gary-rowe/hid4java)
* **Python:** [pyhidapi](https://pypi.org/project/hid/) and [pywinusb](https://pypi.org/project/pywinusb)
Please refer to these libraries' own documentation for instructions on usage. Remember to close the device once you are finished with it!
Next, you will need to know the USB Vendor and Product IDs of the device. These can easily be found by looking at your keyboard's `info.json`, under the `usb` object (alternatively, you can also use Device Manager on Windows, System Information on macOS, or `lsusb` on Linux). For example, the Vendor ID for the Planck Rev 6 is `0x03A8`, and the Product ID is `0xA4F9`.
It's also a good idea to narrow down the list of potential HID devices the library may give you by filtering on the usage page and usage ID, to avoid accidentally opening the interface on the same device for the keyboard, or mouse, or media keys, etc.
Once you are able to open the HID device and send reports to it, it's time to handle them on the keyboard side. Implement the following function in your `keymap.c` and start coding:
```c
voidraw_hid_receive(uint8_t*data,uint8_tlength){
// Your code goes here. data is the packet received from host.
// Your code goes here
// `data` is a pointer to the buffer containing the received HID report
// `length` is the length of the report - always `RAW_EPSIZE`
}
```
The `"raw_hid.h"` header also declares `void raw_hid_send(uint8_t *data, uint8_t length);` which allows sending packets from keyboard to host. As an example, it can also be used for debugging when building your host application by returning all data back to the host.
!> Because the HID specification does not support variable length reports, all reports in both directions must be exactly `RAW_EPSIZE` (currently 32) bytes long, regardless of actual payload length. However, variable length payloads can potentially be implemented on top of this by creating your own data structure that may span multiple reports.
## Receiving Data from the Keyboard :id=receiving-data-from-the-keyboard
If you need the keyboard to send data back to the host, simply call the `raw_hid_send()` function. It requires two arguments - a pointer to a 32-byte buffer containing the data you wish to send, and the length (which should always be `RAW_EPSIZE`).
The received report can then be handled in whichever way your HID library provides.
## Simple Example :id=simple-example
The following example reads the first byte of the received report from the host, and if it is an ASCII "A", responds with "B". `memset()` is used to fill the response buffer (which could still contain the previous response) with null bytes.
```c
voidraw_hid_receive(uint8_t*data,uint8_tlength){
raw_hid_send(data,length);
uint8_tresponse[length];
memset(response,0,length);
response[0]='B';
if(data[0]=='A'){
raw_hid_send(response,length);
}
}
```
These two functions send and receive packets of length`RAW_EPSIZE` bytes to and from the host (32 on LUFA/ChibiOS/V-USB, 64 on ATSAM).
On the host side (here we are using Python and the `pyhidapi` library), the HID device is opened by enumeratingthe interfaces on the USB device, then filtering on the usage page and usage ID. Then, a report containing a single ASCII "A" (hex `0x41`) is constructed and sent.
Make sure to flash raw enabled firmware before proceeding with working on the host side.
For demonstration purposes, the manufacturer and product strings of the device, along with the request and response, are also printed.
## Host (Windows/macOS/Linux)
```python
importsys
importhid
This is the more complicated part as it will require some digging.
vendor_id=0x4335
product_id=0x0002
To connect your host computer to your keyboard with raw HID you need four pieces of information about your keyboard:
The first two can easily be found in your keyboard's `config.h` in the keyboard's main directory under `VENDOR_ID` and `PRODUCT_ID`.
iflen(raw_hid_interfaces)==0:
returnNone
The final two can be overridden in your keyboard's `config.h` in the keyboard's main directory by redefining the values: `#define RAW_USAGE_PAGE 0xFF60` and `#define RAW_USAGE_ID 0x61`.
By default, **Usage Page** is `0xFF60` and **Usage** is `0x61`.
print(f"Manufacturer: {interface.manufacturer}")
print(f"Product: {interface.product}")
### Building your host
returninterface
You can build your host using any language that has an available HID implementation library if you don't wish to make your own. The ones we know of for popular languages are:
This is not an exhaustive cross-platform list but should get you started. There are no special requirements for using raw HID so any HID library should work.
request_data=[0x00]*(report_length+1)# First byte is Report ID
request_data[1:len(data)+1]=data
request_report=bytes(request_data)
Now that you have all four pieces of information required to open HID interface to your keyboard. All you need to do is use your library's available functions to open the device with its ID parameters.
print("Request:")
print(request_report)
Note that Vendor ID and Product ID are not actually required to open the device. They are used only to filter to a specific device out of the many HID devices you have plugged in. Many libraries will give you the option to open the device using Product Name or Manufacturer Name instead, `node-hid` being a prime example. This will create issues for devices with builtin USB Hub or any extra HID interfaces where you will have multiple interfaces with the same name or from the same manufacturer. The Vendor ID together with Product ID create a unique designation to a single interface and will not exhibit this problem. Therefore, even if your library doesn't require you to, it is best to use them to avoid issues.
Unlike Vendor ID and Product ID though, Usage Page and Usage are necessary for successful communication.
try:
interface.write(request_report)
It should go without saying that regardless of the library you're using, you should always make sure to close the interface when finished. Depending on the operating system and your particular environment there may be issues connecting to it again afterwards with another client or another instance of the same client if it's not explicitly closed.
@@ -12,22 +12,21 @@ There is basic support for addressable RGB matrix lighting with the I2C IS31FL37
```make
RGB_MATRIX_ENABLE= yes
RGB_MATRIX_DRIVER=IS31FL3731
RGB_MATRIX_DRIVER=is31fl3731
```
You can use between 1 and 4 IS31FL3731 IC's. Do not specify `DRIVER_ADDR_<N>` defines for IC's that are not present on your keyboard. You can define the following items in `config.h`:
| Variable | Description | Default |
|----------|-------------|---------|
| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
| `ISSI_3731_DEGHOST` | (Optional) Set this define to enable de-ghosting by halving Vcc during blanking time | |
| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | |
| `IS31FL3731_I2C_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
| `IS31FL3731_I2C_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
| `IS31FL3731_DEGHOST` | (Optional) Set this define to enable de-ghosting by halving Vcc during blanking time | |
| `RGB_MATRIX_LED_COUNT` | (Required) How many RGB lights are present across all drivers | |
| `DRIVER_ADDR_1` | (Required) Address for the first RGB driver | |
| `DRIVER_ADDR_2` | (Optional) Address for the second RGB driver | |
| `DRIVER_ADDR_3` | (Optional) Address for the third RGB driver | |
| `DRIVER_ADDR_4` | (Optional) Address for the fourth RGB driver | |
| `IS31FL3731_I2C_ADDRESS_1` | (Required) Address for the first RGB driver | |
| `IS31FL3731_I2C_ADDRESS_2` | (Optional) Address for the second RGB driver | |
| `IS31FL3731_I2C_ADDRESS_3` | (Optional) Address for the third RGB driver | |
| `IS31FL3731_I2C_ADDRESS_4` | (Optional) Address for the fourth RGB driver | |
Here is an example using 2 drivers.
@@ -35,14 +34,15 @@ Here is an example using 2 drivers.
// This is a 7-bit address, that gets left-shifted and bit 0
// set to 0 for write, 1 for read (as per I2C protocol)
// The address will vary depending on your wiring:
@@ -50,12 +50,12 @@ Here is an example using 2 drivers.
!> Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
For split keyboards using `RGB_MATRIX_SPLIT` with an LED driver, you can either have the same driver address or different driver addresses. If using different addresses, use `DRIVER_ADDR_1` for one and `DRIVER_ADDR_2` for the other one. Then, in `g_is31_leds`, fill out the correct driver index (0 or 1). If using one address, use `DRIVER_ADDR_1` for both, and use index 0 for `g_is31_leds`.
For split keyboards using `RGB_MATRIX_SPLIT` with an LED driver, you can either have the same driver address or different driver addresses. If using different addresses, use `IS31FL3731_I2C_ADDRESS_1` for one and `IS31FL3731_I2C_ADDRESS_2` for the other one. Then, in `g_is31fl3731_leds`, fill out the correct driver index (0 or 1). If using one address, use `IS31FL3731_I2C_ADDRESS_1` for both, and use index 0 for `g_is31fl3731_leds`.
Define these arrays listing all the LEDs in your `<keyboard>.c`:
@@ -76,41 +76,40 @@ There is basic support for addressable RGB matrix lighting with the I2C IS31FL37
```make
RGB_MATRIX_ENABLE= yes
RGB_MATRIX_DRIVER=IS31FL3733
RGB_MATRIX_DRIVER=is31fl3733
```
You can use between 1 and 4 IS31FL3733 IC's. Do not specify `DRIVER_ADDR_<N>` defines for IC's that are not present on your keyboard. You can define the following items in `config.h`:
| Variable | Description | Default |
|----------|-------------|---------|
| `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 | |
| `IS31FL3733_I2C_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
| `IS31FL3733_I2C_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
| `IS31FL3733_PWM_FREQUENCY` | (Optional) PWM Frequency Setting - IS31FL3733B only | 0 |
| `IS31FL3733_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF |
| `IS31FL3733_SWPULLUP` | (Optional) Set the value of the SWx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
| `IS31FL3733_CSPULLUP` | (Optional) Set the value of the CSx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
| `RGB_MATRIX_LED_COUNT` | (Required) How many RGB lights are present across all drivers | |
| `DRIVER_ADDR_1` | (Required) Address for the first RGB driver | |
| `DRIVER_ADDR_2` | (Optional) Address for the second RGB driver | |
| `DRIVER_ADDR_3` | (Optional) Address for the third RGB driver | |
| `DRIVER_ADDR_4` | (Optional) Address for the fourth RGB driver | |
| `DRIVER_SYNC_1` | (Optional) Sync configuration for the first RGB driver | 0 |
| `DRIVER_SYNC_2` | (Optional) Sync configuration for the second RGB driver | 0 |
| `DRIVER_SYNC_3` | (Optional) Sync configuration for the third RGB driver | 0 |
| `DRIVER_SYNC_4` | (Optional) Sync configuration for the fourth RGB driver | 0 |
| `IS31FL3733_I2C_ADDRESS_1` | (Required) Address for the first RGB driver | |
| `IS31FL3733_I2C_ADDRESS_2` | (Optional) Address for the second RGB driver | |
| `IS31FL3733_I2C_ADDRESS_3` | (Optional) Address for the third RGB driver | |
| `IS31FL3733_I2C_ADDRESS_4` | (Optional) Address for the fourth RGB driver | |
| `IS31FL3733_SYNC_1` | (Optional) Sync configuration for the first RGB driver | 0 |
| `IS31FL3733_SYNC_2` | (Optional) Sync configuration for the second RGB driver | 0 |
| `IS31FL3733_SYNC_3` | (Optional) Sync configuration for the third RGB driver | 0 |
| `IS31FL3733_SYNC_4` | (Optional) Sync configuration for the fourth RGB driver | 0 |
The IS31FL3733 IC's have on-chip resistors that can be enabled to allow for de-ghosting of the RGB matrix. By default these resistors are not enabled (`ISSI_SWPULLUP`/`ISSI_CSPULLUP` are given the value of`PUR_0R`), the values that can be set to enable de-ghosting are as follows:
The IS31FL3733 IC's have on-chip resistors that can be enabled to allow for de-ghosting of the RGB matrix. By default these resistors are not enabled (`IS31FL3733_SWPULLUP`/`IS31FL3733_CSPULLUP` are given the value of`IS31FL3733_PUR_0R`), the values that can be set to enable de-ghosting are as follows:
@@ -162,7 +160,7 @@ There is basic support for addressable RGB matrix lighting with the I2C IS31FL37
```make
RGB_MATRIX_ENABLE= yes
RGB_MATRIX_DRIVER=IS31FL3736
RGB_MATRIX_DRIVER=is31fl3736
```
You can use between 1 and 4 IS31FL3736 IC's. Do not specify `DRIVER_ADDR_<N>` defines for IC's that are not present on your keyboard.
@@ -170,31 +168,30 @@ Configure the hardware via your `config.h`:
| Variable | Description | Default |
|----------|-------------|---------|
| `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 - IS31FL3736B 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 | |
| `IS31FL3736_I2C_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
| `IS31FL3736_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
| `IS31FL3736_PWM_FREQUENCY` | (Optional) PWM Frequency Setting - IS31FL3736B only | 0 |
| `IS31FL3736_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF |
| `IS31FL3736_SWPULLUP` | (Optional) Set the value of the SWx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
| `IS31FL3736_CSPULLUP` | (Optional) Set the value of the CSx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
| `RGB_MATRIX_LED_COUNT` | (Required) How many RGB lights are present across all drivers | |
| `DRIVER_ADDR_1` | (Required) Address for the first RGB driver | |
| `DRIVER_ADDR_2` | (Optional) Address for the second RGB driver | |
| `DRIVER_ADDR_3` | (Optional) Address for the third RGB driver | |
| `DRIVER_ADDR_4` | (Optional) Address for the fourth RGB driver | |
| `IS31FL3736_I2C_ADDRESS_1` | (Required) Address for the first RGB driver | |
| `IS31FL3736_I2C_ADDRESS_2` | (Optional) Address for the second RGB driver | |
| `IS31FL3736_I2C_ADDRESS_3` | (Optional) Address for the third RGB driver | |
| `IS31FL3736_I2C_ADDRESS_4` | (Optional) Address for the fourth RGB driver | |
The IS31FL3736 IC's have on-chip resistors that can be enabled to allow for de-ghosting of the RGB matrix. By default these resistors are not enabled (`ISSI_SWPULLUP`/`ISSI_CSPULLUP` are given the value of`PUR_0R`), the values that can be set to enable de-ghosting are as follows:
The IS31FL3736 IC's have on-chip resistors that can be enabled to allow for de-ghosting of the RGB matrix. By default these resistors are not enabled (`IS31FL3736_SWPULLUP`/`IS31FL3736_CSPULLUP` are given the value of`IS31FL3736_PUR_0R`), the values that can be set to enable de-ghosting are as follows:
@@ -238,7 +235,7 @@ There is basic support for addressable RGB matrix lighting with the I2C IS31FL37
```make
RGB_MATRIX_ENABLE= yes
RGB_MATRIX_DRIVER=IS31FL3737
RGB_MATRIX_DRIVER=is31fl3737
```
You can use between 1 and 4 IS31FL3737 IC's. Do not specify `DRIVER_ADDR_<N>` defines for IC's that are not present on your keyboard.
@@ -246,31 +243,30 @@ Configure the hardware via your `config.h`:
| Variable | Description | Default |
|----------|-------------|---------|
| `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 | |
| `IS31FL3737_I2C_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
| `IS31FL3737_I2C_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
| `IS31FL3737_PWM_FREQUENCY` | (Optional) PWM Frequency Setting - IS31FL3737B only | 0 |
| `IS31FL3737_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF |
| `IS31FL3737_SWPULLUP` | (Optional) Set the value of the SWx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
| `IS31FL3737_CSPULLUP` | (Optional) Set the value of the CSx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
| `RGB_MATRIX_LED_COUNT` | (Required) How many RGB lights are present across all drivers | |
| `DRIVER_ADDR_1` | (Required) Address for the first RGB driver | |
| `DRIVER_ADDR_2` | (Optional) Address for the second RGB driver | |
| `DRIVER_ADDR_3` | (Optional) Address for the third RGB driver | |
| `DRIVER_ADDR_4` | (Optional) Address for the fourth RGB driver | |
| `IS31FL3737_I2C_ADDRESS_1` | (Required) Address for the first RGB driver | |
| `IS31FL3737_I2C_ADDRESS_2` | (Optional) Address for the second RGB driver | |
| `IS31FL3737_I2C_ADDRESS_3` | (Optional) Address for the third RGB driver | |
| `IS31FL3737_I2C_ADDRESS_4` | (Optional) Address for the fourth RGB driver | |
The IS31FL3737 IC's have on-chip resistors that can be enabled to allow for de-ghosting of the RGB matrix. By default these resistors are not enabled (`ISSI_SWPULLUP`/`ISSI_CSPULLUP` are given the value of`PUR_0R`), the values that can be set to enable de-ghosting are as follows:
The IS31FL3737 IC's have on-chip resistors that can be enabled to allow for de-ghosting of the RGB matrix. By default these resistors are not enabled (`IS31FL3737_SWPULLUP`/`IS31FL3737_CSPULLUP` are given the value of`IS31FL3737_PUR_0R`), the values that can be set to enable de-ghosting are as follows:
@@ -428,7 +421,7 @@ There is basic support for addressable RGB matrix lighting with a WS2811/WS2812{
```make
RGB_MATRIX_ENABLE= yes
RGB_MATRIX_DRIVER=WS2812
RGB_MATRIX_DRIVER=ws2812
```
Configure the hardware via your `config.h`:
@@ -450,7 +443,7 @@ There is basic support for APA102 based addressable LED strands. To enable it, a
```make
RGB_MATRIX_ENABLE= yes
RGB_MATRIX_DRIVER=APA102
RGB_MATRIX_DRIVER=apa102
```
Configure the hardware via your `config.h`:
@@ -465,41 +458,39 @@ Configure the hardware via your `config.h`:
```
---
### AW20216 :id=aw20216
There is basic support for addressable RGB matrix lighting with the SPI AW20216 RGB controller. To enable it, add this to your `rules.mk`:
### AW20216S :id=aw20216s
There is basic support for addressable RGB matrix lighting with the SPI AW20216S RGB controller. To enable it, add this to your `rules.mk`:
```make
RGB_MATRIX_ENABLE= yes
RGB_MATRIX_DRIVER=AW20216
RGB_MATRIX_DRIVER=aw20216s
```
You can use up to 2 AW20216 IC's. Do not specify `DRIVER_<N>_xxx` defines for IC's that are not present on your keyboard. You can define the following items in `config.h`:
You can use up to 2 AW20216S IC's. Do not specify `DRIVER_<N>_xxx` defines for IC's that are not present on your keyboard. You can define the following items in `config.h`:
| Variable | Description | Default |
|----------|-------------|---------|
| `DRIVER_1_CS` | (Required) MCU pin connected to first RGB driver chip select line | B13 |
| `DRIVER_2_CS` | (Optional) MCU pin connected to second RGB driver chip select line | |
| `DRIVER_1_EN` | (Required) MCU pin connected to first RGB driver hardware enable line | C13 |
| `DRIVER_2_EN` | (Optional) MCU pin connected to second RGB driver hardware enable line | |
| `AW20216S_CS_PIN_1` | (Required) MCU pin connected to first RGB driver chip select line | B13 |
| `AW20216S_CS_PIN_2` | (Optional) MCU pin connected to second RGB driver chip select line | |
| `AW20216S_EN_PIN_1` | (Required) MCU pin connected to first RGB driver hardware enable line | C13 |
| `AW20216S_EN_PIN_2` | (Optional) MCU pin connected to second RGB driver hardware enable line | |
| `DRIVER_1_LED_TOTAL` | (Required) How many RGB lights are connected to first RGB driver | |
| `DRIVER_2_LED_TOTAL` | (Optional) How many RGB lights are connected to second RGB driver | |
| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | |
| `RGB_MATRIX_LED_COUNT` | (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 |
| `AW20216S_SCALING_MAX` | (Optional) LED current scaling value (0-255, higher values mean LED is brighter at full PWM) | 150 |
| `AW20216S_GLOBAL_CURRENT_MAX` | (Optional) Driver global current limit (0-255, higher values means the driver may consume more power) | 150 |
| `AW20216S_SPI_MODE` | (Optional) Mode for SPI communication (0-3, defines polarity and phase of the clock) | 3 |
| `AW20216S_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.
```c
#define DRIVER_1_CS B13
#define DRIVER_2_CS B14
#define AW20216S_CS_PIN_1 B13
#define AW20216S_CS_PIN_2 B14
// Hardware enable lines may be connected to the same pin
#define RGB_MATRIX_KEYRELEASES // reactive effects respond to keyreleases (instead of keypresses)
#define RGB_MATRIX_TIMEOUT 0 // number of milliseconds to wait until rgb automatically turns off
#define RGB_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended
#define RGB_MATRIX_LED_PROCESS_LIMIT (RGB_MATRIX_LED_COUNT + 4) / 5 // limits the number of LEDs to process in an animation per task run (increases keyboard responsiveness)
@@ -883,11 +876,12 @@ These are defined in [`color.h`](https://github.com/qmk/qmk_firmware/blob/master
#define RGB_MATRIX_DEFAULT_MODE RGB_MATRIX_CYCLE_LEFT_RIGHT // Sets the default mode, if none has been set
#define RGB_MATRIX_DEFAULT_HUE 0 // Sets the default hue value, if none has been set
#define RGB_MATRIX_DEFAULT_SAT 255 // Sets the default saturation value, if none has been set
#define RGB_MATRIX_DEFAULT_ON true // Sets the default enabled state, if none has been set
#define RGB_MATRIX_DEFAULT_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS // Sets the default brightness value, if none has been set
#define RGB_MATRIX_DEFAULT_SPD 127 // Sets the default animation speed, if none has been set
#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
// If reactive effects are 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
```
@@ -964,7 +958,7 @@ The EEPROM for it is currently shared with the LED Matrix system (it's generally
### Indicators :id=indicators
If you want to set custom indicators, such as an LED for Caps Lock, or layer indication, you can use the `rgb_matrix_indicators_kb` or `rgb_matrix_indicators_user` function for that:
If you want to set custom indicators, such as an LED for Caps Lock, or layer indication, then you can use the `rgb_matrix_indicators_kb` function on the keyboard level source file, or `rgb_matrix_indicators_user` function in the user `keymap.c`.
@@ -28,7 +28,7 @@ For APA102 LEDs, add the following to your `rules.mk`:
```make
RGBLIGHT_ENABLE= yes
RGBLIGHT_DRIVER=APA102
RGBLIGHT_DRIVER=apa102
```
At minimum you must define the data pin your LED strip is connected to, and the number of LEDs in the strip, in your `config.h`. For APA102 LEDs, you must also define the clock pin. If your keyboard has onboard RGB LEDs, and you are simply creating a keymap, you usually won't need to modify these.
@@ -90,7 +90,7 @@ Your RGB lighting can be configured by placing these `#define`s in your `config.
For keyboards that use the RGB LEDs as a backlight for each key, you can also define it as in the example below.
```c
// config.h
#define RGBLED_NUM 30
/* RGB LED Conversion macro from physical array to electric array */
#define LED_LAYOUT( \
L00, L01, L02, L03, L04, L05, \
L10, L11, L12, L13, L14, L15, \
L20, L21, L22, L23, L24, L25, \
L30, L31, L32, L33, L34, L35, \
L40, L41, L42, L43, L44, L45 ) \
{ \
L05, L04, L03, L02, L01, L00, \
L10, L11, L12, L13, L14, L15, \
L25, L24, L23, L22, L21, L20, \
L30, L31, L32, L33, L34, L35, \
L46, L45, L44, L43, L42, L41 \
}
/* RGB LED logical order map */
/* Top->Bottom, Right->Left */
#define RGBLIGHT_LED_MAP LED_LAYOUT( \
25, 20, 15, 10, 5, 0, \
26, 21, 16, 11, 6, 1, \
27, 22, 17, 12, 7, 2, \
28, 23, 18, 13, 8, 3, \
29, 24, 19, 14, 9, 4 )
```
## Clipping Range
Using the `rgblight_set_clipping_range()` function, you can prepare more buffers than the actual number of LEDs, and output some of the buffers to the LEDs. This is useful if you want the split keyboard to treat left and right LEDs as logically contiguous.
@@ -575,11 +544,41 @@ In addition to setting the Clipping Range, you can use `RGBLIGHT_LED_MAP` togeth
If your keyboard lacks onboard underglow LEDs, you may often be able to solder on an RGB LED strip yourself. You will need to find an unused pin to wire to the data pin of your LED strip. Some keyboards may break out unused pins from the MCU to make soldering easier. The other two pins, VCC and GND, must also be connected to the appropriate power pins.
## Velocikey
Velocikey is a feature that lets you control the speed of lighting effects (like the Rainbow Swirl effect) with the speed of your typing. The faster you type, the faster the lights will go!
### Usage
For Velocikey to take effect, there are two steps. First, when compiling your keyboard, you'll need to set `VELOCIKEY_ENABLE=yes` in `rules.mk`, e.g.:
```
MOUSEKEY_ENABLE = no
STENO_ENABLE = no
EXTRAKEY_ENABLE = yes
VELOCIKEY_ENABLE = yes
```
Then, while using your keyboard, you need to also turn it on with the `VK_TOGG` keycode, which toggles the feature on and off.
The following light effects will all be controlled by Velocikey when it is enabled:
- RGB Breathing
- RGB Rainbow Mood
- RGB Rainbow Swirl
- RGB Snake
- RGB Knight
Support for LED breathing effects is planned but not available yet.
As long as Velocikey is enabled, it will control the speed regardless of any other speed setting that your RGB lights are currently on.
### Configuration
Velocikey doesn't currently support any configuration via keyboard settings. If you want to adjust something like the speed increase or decay rate, you would need to edit `velocikey.c` and adjust the values there to achieve the kinds of speeds that you like.
The Send String API is part of QMK's macro system. It allows for sequences of keystrokes to be sent automatically.
@@ -6,7 +6,7 @@ The full ASCII character set is supported, along with all of the keycodes in the
?> Unicode characters are **not** supported with this API -- see the [Unicode](feature_unicode.md) feature instead.
## Usage
## Usage :id=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`:
@@ -14,7 +14,7 @@ Send String is enabled by default, so there is usually no need for any special s
SEND_STRING_ENABLE= yes
```
## Basic Configuration
## Basic Configuration :id=basic-configuration
Add the following to your `config.h`:
@@ -23,7 +23,7 @@ Add the following to your `config.h`:
|`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
## Keycodes :id=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_`.
@@ -44,13 +44,13 @@ The following characters are also mapped to their respective keycodes for conven
|`\t` |`\x1B`|`TAB`|`KC_TAB` |
| |`\x7F`|`DEL`|`KC_DELETE` |
### Language Support
### Language Support :id=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
## Examples :id=examples
### Hello World
### Hello World :id=example-hello-world
A simple custom keycode which types out "Hello, world!" and the Enter key when pressed.
@@ -205,7 +205,7 @@ This sets the pin to be used for serial communication. If you're not using seria
However, if you are using serial and I<sup>2</sup>C on the board, you will need to set this, and to something other than D0 and D1 (as these are used for I<sup>2</sup>C communication).
```c
#define SELECT_SOFT_SERIAL_SPEED {#}`
#define SELECT_SOFT_SERIAL_SPEED {#}
```
If you're having issues with serial communication, you can change this value, as it controls the communication speed for serial. The default is 1, and the possible values are:
@@ -298,7 +298,7 @@ This enables transmitting the pointing device status to the master side of the s
#define SPLIT_HAPTIC_ENABLE
```
This enables triggering of haptic feedback on the slave side of the split keyboard. For DRV2605L this will send the mode, but for solenoids it is expected that the desired mode is already set up on the slave.
This enables the triggering of haptic feedback on the slave side of the split keyboard. This will send information to the slave side such as the mode, dwell, and whether buzz is enabled.
@@ -104,7 +104,7 @@ After enabling stenography and optionally selecting a protocol, you may also nee
!> 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, 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.
In your keymap, create a new layer for Plover, that you can fill in with the [steno keycodes](#keycode-reference). Remember to create a key to switch to the layer as well as a key for exiting the layer.
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).
@@ -149,8 +149,6 @@ At the end of this scenario given as an example, `chord` would have five bits se
## Keycode Reference :id=keycode-reference
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.
|GeminiPR|TX Bolt|Steno Key|
@@ -198,7 +196,7 @@ You must include `keymap_steno.h` to your `keymap.c` with `#include "keymap_sten
|`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.
If you do not want to hit two keys with one finger combined keycodes can be used. These cause both keys to be reported as pressed or released. To use these keycodes define `STENO_COMBINEDMAP` in your `config.h` file.
@@ -28,7 +28,7 @@ After this, you'll want to use the `tap_dance_actions` array to specify what act
*`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_WITH_RELEASE(on_each_tap_fn, on_each_release_fn, on_dance_finished_fn, on_dance_reset_fn)`: This macro is identical to `ACTION_TAP_DANCE_FN_ADVANCED` with the addition of `on_each_release_fn` which is invoked every time the key for the tap dance is released. It is worth noting that `on_each_release_fn` will still be called even when the key is released after the dance finishes (e.g. if the key is released after being pressed and held for longer than the `TAPPING_TERM`).
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.
Unicode characters can be input straight from your keyboard! There are some limitations, however.
With a little help from your OS, practically any Unicode character can be input using your keyboard.
In order to enable Unicode support on your keyboard, you will need to do the following:
## Caveats :id=caveats
1. Choose one of three supported Unicode implementations: [Basic Unicode](#basic-unicode), [Unicode Map](#unicode-map), [UCIS](#ucis).
2. Find which [input mode](#input-modes) is the best match for your operating system and setup.
3. [Set](#setting-the-input-mode) the appropriate input mode (or modes) in your configuration.
4. Add Unicode keycodes to your keymap.
There are some limitations to this feature. Because there is no "standard" method of Unicode input across all operating systems, each of them require their own setup process on both the host *and* in the firmware, which may involve installation of additional software. This also means Unicode input will not "just work" when the keyboard is plugged into another device.
## Usage :id=usage
## 1. Methods :id=methods
The core Unicode API can be used purely programmatically. However, there are also additional subsystems which build on top of it and come with keycodes to make things easier. See below for more details.
QMK supports three different methods for enabling Unicode input and adding Unicode characters to your keymap. Each has its pros and cons in terms of flexibility and ease of use. Choose the one that best fits your use case.
Add the following to your keymap's `rules.mk`:
The Basic method should be enough for most users. However, if you need a wider range of supported characters (including emoji, rare symbols etc.), you should use Unicode Map.
```make
UNICODE_COMMON= yes
```
<br>
## Basic Configuration :id=basic-configuration
### 1.1. Basic Unicode :id=basic-unicode
Add the following to your `config.h`:
The easiest to use method, albeit somewhat limited. It stores Unicode characters as keycodes in the keymap itself, so it only supports code points up to `0x7FFF`. This covers characters for most modern languages (including East Asian), as well as symbols, but it doesn't cover emoji.
|`UNICODE_SONG_MAC` |*n/a* |The song to play when the macOS input mode is selected |
|`UNICODE_SONG_LNX` |*n/a* |The song to play when the Linux input mode is selected |
|`UNICODE_SONG_BSD` |*n/a* |The song to play when the BSD input mode is selected |
|`UNICODE_SONG_WIN` |*n/a* |The song to play when the Windows input mode is selected |
|`UNICODE_SONG_WINC`|*n/a* |The song to play when the WinCompose input mode is selected|
## Input Subsystems :id=input-subsystems
Each of these subsystems have their own pros and cons in terms of flexibility and ease of use. Choose the one that best fits your needs.
<!-- tabs:start -->
### ** Basic **
This is the easiest to use, albeit somewhat limited. It supports code points up to `U+7FFF`, which covers characters for most modern languages (including East Asian), as well as many symbols, but does not include emoji.
To enable Basic Unicode, add the following to your `rules.mk`:
```make
UNICODE_ENABLE= yes
```
Then add `UC(c)` keycodes to your keymap, where _c_ is the code point of the desired character (preferably in hexadecimal, up to 4 digits long). For example, `UC(0x40B)` will output [Ћ](https://unicode-table.com/en/040B/), and `UC(0x30C4)` will output [ツ](https://unicode-table.com/en/30C4).
You can then add `UC(c)` keycodes to your keymap, where *c* is the code point of the desired character (in hexadecimal - the `U+` prefix will not work). For example, `UC(0x40B)` will output [Ћ](https://unicode-table.com/en/040B/), and `UC(0x30C4)` will output [ツ](https://unicode-table.com/en/30C4).
<br>
### ** Unicode Map **
### 1.2. Unicode Map :id=unicode-map
Unicode Map supports all possible code points (up to `U+10FFFF`). Here, the code points are stored in a separate mapping table (which may contain at most 16,384 entries), instead of directly in the keymap.
In addition to standard character ranges, this method also covers emoji, ancient scripts, rare symbols etc. In fact, all possible code points (up to `0x10FFFF`) are supported. Here, Unicode characters are stored in a separate mapping table. You need to maintain a `unicode_map` array in your keymap file, which may contain at most 16384 entries.
Add the following to your `rules.mk`:
To enable Unicode Map, add the following to your `rules.mk`:
```make
UNICODEMAP_ENABLE= yes
```
Then add `X(i)` keycodes to your keymap, where _i_ is the desired character's index in the mapping table. This can be a numeric value, but it's recommended to keep the indices in an enum and access them by name.
Then, you will need to create a mapping table in your `keymap.c`, and (optionally) an enum for naming the array indices, like so:
```c
enumunicode_names{
@@ -51,242 +80,373 @@ enum unicode_names {
SNEK
};
constuint32_tunicode_map[]PROGMEM={
constuint32_tPROGMEM unicode_map[]={
[BANG]=0x203D,// ‽
[IRONY]=0x2E2E,// ⸮
[SNEK]=0x1F40D,// 🐍
};
```
Then you can use `X(BANG)`,`X(SNEK)` etc. in your keymap.
Finally, add `UM(i)` keycodes to your keymap, where *i* is an index into the `unicode_map[]` array. If you defined the enum above, you can use those names instead, for example `UM(BANG)` or`UM(SNEK)`.
#### Lower and Upper Case
#### Lower and Upper Case Pairs :id=unicodemap-pairs
Characters often come in lower and uppercase pairs, such as å and Å. To make inputting these characters easier, you can use `XP(i, j)` in your keymap, where _i_ and _j_ are the mapping table indices of the lower and uppercase character, respectively. If you're holding down Shift or have Caps Lock turned on when you press the key, the second (uppercase) character will be inserted; otherwise, the first (lowercase) version will appear.
Some writing systems have lowercase and uppercase variants of each character, such as å and Å. To make inputting these characters easier, you can use the `UP(i, j)` keycode in your keymap, where *i* and *j* are the mapping table indices of the lowercase and uppercase characters, respectively. If you're holding down Shift or have Caps Lock turned on when you press the key, the uppercase character will be inserted; otherwise, the lowercase character will be inserted.
This is most useful when creating a keymap for an international layout with special characters. Instead of having to put the lower and upper case versions of a character on separate keys, you can have them both on the same key by using `XP()`. This helps blend Unicode keys in with regular alphas.
```c
constuint32_tPROGMEMunicode_map[]={
[AE_LOWER]=0x00E6,// æ
[AE_UPPER]=0x00C6,// Æ
};
```
Due to keycode size constraints, _i_ and _j_ can each only refer to one of the first 128 characters in your `unicode_map`. In other words, 0 ≤ _i_ ≤ 127 and 0 ≤ _j_ ≤ 127. This is enough for most use cases, but if you'd like to customize the index calculation, you can override the [`unicodemap_index()`](https://github.com/qmk/qmk_firmware/blob/71f640d47ee12c862c798e1f56392853c7b1c1a8/quantum/process_keycode/process_unicodemap.c#L36) function. This also allows you to, say, check Ctrl instead of Shift/Caps.
This is most useful when creating a keymap for an international layout with special characters. Instead of having to put the lower and upper case versions of a character on separate keys, you can have them both on the same key. This helps blend Unicode keys in with regular keycodes.
<br>
Due to keycode size constraints, *i* and *j* can each only refer to one of the first 128 characters in your `unicode_map`. In other words, 0 ≤ *i* ≤ 127 and 0 ≤ *j* ≤ 127.
### 1.3. UCIS :id=ucis
### ** UCIS **
This method also supports all possible code points. As with the Unicode Map method, you need to maintain a mapping table in your keymap file. However, there are no built-in keycodes for this feature — you have to create a custom keycode or function that invokes this functionality.
As with Unicode Map, the UCIS method also supports all possible code points, and requires the use of a mapping table. However, it works much differently - Unicode characters are input by replacing a typed mnemonic.
Add the following to your `rules.mk`:
To enable UCIS, add the following to your keymap's `rules.mk`:
```make
UCIS_ENABLE= yes
```
Then define a table like this in your keymap file:
Then, create a mapping table in your `keymap.c`:
```c
constucis_symbol_tucis_symbol_table[]=UCIS_TABLE(
UCIS_SYM("poop",0x1F4A9),// 💩
UCIS_SYM("rofl",0x1F923),// 🤣
UCIS_SYM("cuba",0x1F1E8,0x1F1FA),// 🇨🇺
UCIS_SYM("ukr",0x1F1FA,0x1F1E6),// 🇺🇦
UCIS_SYM("look",0x0CA0,0x005F,0x0CA0)// ಠ_ಠ
);
```
By default, each table entry may be up to 3 code points long. This number can be changed by adding `#define UCIS_MAX_CODE_POINTS n` to your `config.h` file.
By default, each table entry may be up to three code points long. This can be changed by adding `#define UCIS_MAX_CODE_POINTS n` to your keymap's `config.h`.
To use UCIS input, call`ucis_start()`. Then, type the mnemonic for the character (such as "rofl") and hit Space, Enter or Esc. QMK should erase the "rofl" text and insert the laughing emoji.
To invoke UCIS input, the`ucis_start()` function must first be called (for example, in a custom "Unicode" keycode). Then, type the mnemonic for the mapping table entry (such as "rofl"), and hit Space or Enter. The "rofl" text will be backspaced and the emoji inserted.
#### Customization
<!-- tabs:end -->
There are several functions that you can define in your keymap to customize the functionality of this feature.
## Input Modes :id=input-modes
*`void ucis_start_user(void)`– This runs when you call the "start" function, and can be used to provide feedback. By default, it types out a keyboard emoji.
*`void ucis_success(uint8_t symbol_index)`– This runs when the input has matched something and has completed. By default, it doesn't do anything.
*`void ucis_symbol_fallback (void)`– This runs when the input doesn't match anything. By default, it falls back to trying that input as a Unicode code.
Unicode input works by typing a sequence of characters, similar to a macro. However, since this sequence depends on your OS, you will need to prepare both your host machine and QMK to recognise and send the correct Unicode input sequences respectively.
You can find the default implementations of these functions in [`process_ucis.c`](https://github.com/qmk/qmk_firmware/blob/master/quantum/process_keycode/process_ucis.c).
## 2. Input Modes :id=input-modes
Unicode input in QMK works by inputting a sequence of characters to the OS, sort of like a macro. Unfortunately, the way this is done differs for each platform. Specifically, each platform requires a different combination of keys to trigger Unicode input. Therefore, a corresponding input mode has to be set in QMK.
The following input modes are available:
* **`UNICODE_MODE_MACOS`**: macOS built-in Unicode hex input. Supports code points up to `0x10FFFF` (all possible code points).
To enable, go to _System Preferences > Keyboard > Input Sources_, add _Unicode Hex Input_ to the list (it's under _Other_), then activate it from the input dropdown in the Menu Bar.
By default, this mode uses the left Option key (`KC_LALT`) for Unicode input, but this can be changed by defining [`UNICODE_KEY_MAC`](#input-key-configuration) with a different keycode.
!> Using the _Unicode Hex Input_ input source may disable some Option-based shortcuts, such as Option+Left and Option+Right.
* **`UNICODE_MODE_LINUX`**: Linux built-in IBus Unicode input. Supports code points up to `0x10FFFF` (all possible code points).
Enabled by default and works almost anywhere on IBus-enabled distros. Without IBus, this mode works under GTK apps, but rarely anywhere else.
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)).
* **`UNICODE_MODE_WINDOWS`**: _(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.
This mode is not recommended because of reliability and compatibility issues; use the `UNICODE_MODE_WINCOMPOSE` mode instead.
* **`UNICODE_MODE_BSD`**: _(non implemented)_ Unicode input under BSD. Not implemented at this time. If you're a BSD user and want to help add support for it, please [open an issue on GitHub](https://github.com/qmk/qmk_firmware/issues).
* **`UNICODE_MODE_WINCOMPOSE`**: Windows Unicode input using [WinCompose](https://github.com/samhocevar/wincompose). As of v0.9.0, supports code points up to `0x10FFFF` (all possible code points).
To enable, install the [latest release](https://github.com/samhocevar/wincompose/releases/latest). Once installed, WinCompose will automatically run on startup. This mode works reliably under all version of Windows supported by the app.
By default, this mode uses right Alt (`KC_RALT`) as the Compose key, but this can be changed in the WinCompose settings and by defining [`UNICODE_KEY_WINC`](#input-key-configuration) with a different keycode.
## 3. Setting the Input Mode :id=setting-the-input-mode
To set your desired input mode, add the following define to your `config.h`:
To set the list of enabled input modes, add the `UNICODE_SELECTED_MODES` define to your keymap's `config.h`, for example:
This example sets the board's default input mode to `UNICODE_MODE_LINUX`. You can replace this with `UNICODE_MODE_MACOS`, `UNICODE_MODE_WINCOMPOSE`, or any of the other modes listed [above](#input-modes). The board will automatically use the selected mode on startup, unless you manually switch to another mode (see [below](#keycodes)).
These modes can then be cycled through using the`UC_NEXT` and `UC_PREV` keycodes. You can also switch to any inputmode, even if it is not specified in `UNICODE_SELECTED_MODES`, using their respective keycodes.
You can also select multiple input modes, which allows you to easily cycle through them using the `UC_NEXT`/`UC_PREV` keycodes.
If your keyboard has working EEPROM, it will remember the last used input mode and continue using it on the next power up. This can be disabled by defining `UNICODE_CYCLE_PERSIST` to `false`.
macOS has built-in support for Unicode input as its own input source. It supports all possible code points by way of surrogate pairs for code points above `U+FFFF`.
To enable, go to **System Preferences → Keyboard → Input Sources**, then add Unicode Hex Input to the list (under Other), and activate it from the input dropdown in the menu bar. Note that this may disable some Option-based shortcuts such as Option+Left and Option+Right.
### ** Linux (IBus) **
**Mode Name:**`UNICODE_MODE_LINUX`
For Linux distros with IBus, Unicode input is enabled by default, supports all possible code points, and works almost anywhere. Without IBus, it works under GTK apps, but rarely anywhere else.
Users who would like support in non-GTK apps without IBus may need to resort to a more indirect method, such as creating a custom keyboard layout.
### ** Windows (WinCompose) **
**Mode Name:**`UNICODE_MODE_WINCOMPOSE`
This mode requires a third-party tool called [WinCompose](https://github.com/samhocevar/wincompose). It supports all possible code points, and is the recommended input mode for Windows.
To enable, install the [latest release from GitHub](https://github.com/samhocevar/wincompose/releases/latest). Once installed, it will automatically run on startup. This works reliably under all versions of Windows supported by WinCompose.
### ** Windows (HexNumpad) **
**Mode Name:**`UNICODE_MODE_WINDOWS`
!> This input mode is *not* the "Alt code" system. Alt codes are not Unicode; they instead follow [the Windows-1252 character set](https://en.wikipedia.org/wiki/Alt_code).
This is Windows' built-in hex numpad Unicode input mode. It only supports code points up to `U+FFFF`, and is not recommended due to reliability and compatibility issues.
To enable, run the following as an administrator, then reboot:
Note that the values are separated by commas. The board will remember the last used input mode and will continue using it on next power-up. You can disable this and force it to always start with the first mode in the list by adding `#define UNICODE_CYCLE_PERSIST false` to your `config.h`.
### ** Emacs **
#### Keycodes
**Mode Name:**`UNICODE_MODE_EMACS`
You can switch the input mode at any time by using the following keycodes. Adding these to your keymap allows you to quickly switch to a specific input mode, including modes not listed in `UNICODE_SELECTED_MODES`.
Emacs supports code point input with the `insert-char` command.
|`QK_UNICODE_MODE_NEXT` |`UC_NEXT`|Next in list |Cycle through selected modes, reverse direction when Shift is held |
|`QK_UNICODE_MODE_PREVIOUS` |`UC_PREV`|Prev in list |Cycle through selected modes in reverse, forward direction when Shift is held|
|`QK_UNICODE_MODE_MACOS` |`UC_MAC` |`UNICODE_MODE_MACOS` |Switch to macOS input |
|`QK_UNICODE_MODE_LINUX` |`UC_LINX`|`UNICODE_MODE_LINUX` |Switch to Linux input |
|`QK_UNICODE_MODE_WINDOWS` |`UC_WIN` |`UNICODE_MODE_WINDOWS` |Switch to Windows input |
|`QK_UNICODE_MODE_BSD` |`UC_BSD` |`UNICODE_MODE_BSD` |Switch to BSD input _(not implemented)_ |
|`QK_UNICODE_MODE_WINCOMPOSE`|`UC_WINC`|`UNICODE_MODE_WINCOMPOSE`|Switch to Windows input using WinCompose |
|`QK_UNICODE_MODE_EMACS` |`UC_EMAC`|`UNICODE_MODE_EMACS` |Switch to emacs (`C-x-8 RET`) |
### ** BSD **
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.`UNICODE_MODE_LINUX`).
**Mode Name:**`UNICODE_MODE_BSD`
?> Using `UNICODE_SELECTED_MODES` is preferable to calling `set_unicode_input_mode()` in `matrix_init_user()` or similar functions, since it's better integrated into the Unicode system and has the added benefit of avoiding unnecessary writes to EEPROM.
Not currently implemented. If you're a BSD user and want to contribute support for this input mode, please [feel free](contributing.md)!
#### Audio Feedback
<!-- tabs:end -->
If you have the [Audio feature](feature_audio.md) enabled on the board, you can set melodies to be played when you press the above keys. That way you can have some audio feedback when switching input modes.
## Keycodes :id=keycodes
For instance, you can add these definitions to your `config.h` file:
Because Unicode is a large and versatile feature, there are a number of options you can customize to make it work better on your system.
#### Return Value :id=api-get-unicode-input-mode-return-value
### Start and Finish Input Functions
The currently active Unicode input mode.
The functions for starting and finishing Unicode input on your platform can be overridden locally. Possible uses include customizing input mode behavior if you don't use the default keys, or adding extra visual/audio feedback to Unicode input.
---
* `void unicode_input_start(void)`– This sends the initial sequence that tells your platform to enter Unicode input mode. For example, it holds the left Alt key followed by Num+ on Windows, and presses the `UNICODE_KEY_LNX` combination (default: Ctrl+Shift+U) on Linux.
*`void unicode_input_finish(void)`– This is called to exit Unicode input mode, for example by pressing Space or releasing the Alt key.
You can find the default implementations of these functions in [`process_unicode_common.c`](https://github.com/qmk/qmk_firmware/blob/master/quantum/process_keycode/process_unicode_common.c).
You can customize the keys used to trigger Unicode input for macOS, Linux and WinCompose by adding corresponding defines to your `config.h`. The default values match the platforms' default settings, so you shouldn't need to change this unless Unicode input isn't working, or you want to use a different key (e.g. in order to free up left or right Alt).
User-level callback, invoked when the input mode is changed.
This function is much like `send_string()`, but it allows you to input UTF-8 characters directly. It supports all code points, provided the selected inputmode also supports it. Make sure your `keymap.c` file is formatted using UTF-8 encoding.
In `quantum/keymap_extras`, you'll see various language files — these work the same way as the ones for alternative layouts such as Colemak or BÉPO. When you include one of these language headers, you gain access to keycodes specific to that language / national layout. Such keycodes are defined by a 2-letter country/language code, followed by an underscore and a 4-letter abbreviation of the character to which the key corresponds. For example, including `keymap_french.h` and using `FR_UGRV` in your keymap will output `ù` when typed on a system with a native French AZERTY layout.
Keyboard-level callback, invoked when the input mode is changed.
If the primary system layout you use on your machine is different from US ANSI, using these language-specific keycodes can help your QMK keymaps better match what will actually be output on the screen. However, keep in mind that these keycodes are just aliases for the corresponding default US keycodes under the hood, and that the HID protocol used by keyboards is itself inherently based on US ANSI.
The method does not require Unicode support in the keyboard itself but instead depends on [AutoHotkey](https://autohotkey.com) running in the background.
Begin the Unicode input sequence. The exact behavior depends on the currently selected input mode:
First you need to select a modifier combination that is not in use by any of your programs.
Ctrl+Alt+Win is not used very widely and should therefore be perfect for this.
There is a macro defined for a mod-tab combo `LCAG_T`.
Add this mod-tab combo to a key on your keyboard, e.g.: `LCAG_T(KC_TAB)`.
This makes the key behave like a tab key if pressed and released immediately but changes it to the modifier if used with another key.
- **macOS**: Hold `UNICODE_KEY_MAC`
- **Linux**: Tap `UNICODE_KEY_LNX`
- **WinCompose**: Tap `UNICODE_KEY_WINC`, then U
- **HexNumpad**: Hold Left Alt, then tap Numpad +
- **Emacs**: Tap Ctrl+X, then 8, then Enter
In the default script of AutoHotkey you can define custom hotkeys.
This function is weakly defined, and can be overridden in user code.
<^<!<#a::Send, ä
<^<!<#<+a::Send, Ä
---
The hotkeys above are for the combination CtrlAltGui and CtrlAltGuiShift plus the letter a.
AutoHotkey inserts the Text right of `Send, ` when this combination is pressed.
Complete the Unicode input sequence. The exact behavior depends on the currently selected input mode:
If you enable the US International layout on the system, it will use punctuation to accent the characters. For instance, typing "\`a" will result in à.
You can find details on how to enable this [here](https://support.microsoft.com/en-us/help/17424/windows-change-keyboard-layout).
- **macOS**: Release `UNICODE_KEY_MAC`
- **Linux**: Tap Space
- **WinCompose**: Tap Enter
- **HexNumpad**: Release Left Alt
- **Emacs**: Tap Enter
## Software keyboard layout on Linux :id=custom-linux-layout
This function is weakly defined, and can be overridden in user code.
This method does not require Unicode support on the keyboard itself but instead uses a custom keyboard layout for Xorg. This is how special characters are inserted by regular keyboards. This does not require IBus and works in practically all software. Help on creating a custom layout can be found [here](https://www.linux.com/news/creating-custom-keyboard-layouts-x11-using-xkb/), [here](http://karols.github.io/blog/2013/11/18/creating-custom-keyboard-layouts-for-linux/) and [here](https://wiki.archlinux.org/index.php/X_keyboard_extension). An example of how you could edit the `us` layout to gain 🤣 on `RALT(KC_R)`:
---
Edit the keyboard layout file `/usr/share/X11/xkb/symbols/us`.
Cancel the Unicode input sequence. The exact behavior depends on the currently selected input mode:
Find the line defining the R key and add an entry to the list, making it look like this:
```
key <AD04> { [ r, R, U1F923 ] };
```
- **macOS**: Release `UNICODE_KEY_MAC`
- **Linux**: Tap Escape
- **WinCompose**: Tap Escape
- **HexNumpad**: Release Left Alt
- **Emacs**: Tap Ctrl+G
Save the file and run the command `setxkbmap us` to reload the layout.
This function is weakly defined, and can be overridden in user code.
You can define one custom character for key defined in the layout, and another if you populate the fourth layer. Additional layers up to 8th are also possible.
---
This method is specific to the computer on which you set the custom layout. The custom keys will be available only when Xorg is running. To avoid accidents, you should always reload the layout using `setxkbmap`, otherwise an invalid layout could prevent you from logging into your system, locking you out.
!> Please note, userspace submissions to the upstream `qmk/qmk_firmware` repository are no longer being accepted. The userspace feature itself remains functional and can be configured locally.
If you use more than one keyboard with a similar keymap, you might see the benefit in being able to share code between them. Create your own folder in `users/` named the same as your keymap (ideally your GitHub username, `<name>`) with the following structure:
*`/users/<name>/` (added to the path automatically)
Velocikey is a feature that lets you control the speed of lighting effects (like the Rainbow Swirl effect) with the speed of your typing. The faster you type, the faster the lights will go!
## Usage
For Velocikey to take effect, there are two steps. First, when compiling your keyboard, you'll need to set `VELOCIKEY_ENABLE=yes` in `rules.mk`, e.g.:
```
MOUSEKEY_ENABLE = no
STENO_ENABLE = no
EXTRAKEY_ENABLE = yes
VELOCIKEY_ENABLE = yes
```
Then, while using your keyboard, you need to also turn it on with the `VK_TOGG` keycode, which toggles the feature on and off.
The following light effects will all be controlled by Velocikey when it is enabled:
- RGB Breathing
- RGB Rainbow Mood
- RGB Rainbow Swirl
- RGB Snake
- RGB Knight
Support for LED breathing effects is planned but not available yet.
As long as Velocikey is enabled, it will control the speed regardless of any other speed setting that your RGB lights are currently on.
## Configuration
Velocikey doesn't currently support any configuration via keyboard settings. If you want to adjust something like the speed increase or decay rate, you would need to edit `velocikey.c` and adjust the values there to achieve the kinds of speeds that you like.
4. Reset the device into application mode (may be done automatically)
## WB32 DFU
Some keyboards produced for several commercial brands (GMMK, Akko, MonsGeek, Inland) use this bootloader. The `wb32-dfu-updater` utility is bundled with [QMK MSYS](https://msys.qmk.fm/) and [Glorious's build of QMK Toolbox](https://www.gloriousgaming.com/blogs/guides-resources/gmmk-2-qmk-installation-guide). If neither of these flashing methods is available for your OS, you will likely need to [compile the CLI version from source](https://github.com/WestberryTech/wb32-dfu-updater).
The `info.json` setting for this bootloader is `wb32-dfu`.
Compatible flashers:
* [Glorious's build of QMK Toolbox](https://www.gloriousgaming.com/blogs/guides-resources/gmmk-2-qmk-installation-guide) (recommended GUI)
* [wb32-dfu-updater_cli](https://github.com/WestberryTech/wb32-dfu-updater) / `:flash` target in QMK (recommended command line)
@@ -109,7 +109,7 @@ This allows you to send Unicode characters using `UC(<code point>)` in your keym
`UNICODEMAP_ENABLE`
This allows you to send Unicode characters using `X(<map index>)` in your keymap. You will need to maintain a mapping table in your keymap file. All possible code points (up to `0x10FFFF`) are supported.
This allows you to send Unicode characters using `UM(<map index>)` in your keymap. You will need to maintain a mapping table in your keymap file. All possible code points (up to `0x10FFFF`) are supported.
The I2C Master drivers used in QMK have a set of common functions to allow portability between MCUs.
## Usage :id=usage
In most cases, the I2C Master driver code is automatically included if you are using a feature or driver which requires it, such as [OLED](feature_oled_driver.md).
However, if you need to use the driver standalone, add the following to your `rules.mk`:
```make
I2C_DRIVER_REQUIRED= yes
```
You can then call the I2C API by including `i2c_master.h` in your code.
## I2C Addressing :id=note-on-i2c-addresses
All of the addresses expected by this driver should be pushed to the upper 7 bits of the address byte. Setting
@@ -72,7 +84,7 @@ Configuration-wise, you'll need to set up the peripheral as per your MCU's datas
The following configuration values depend on the specific MCU in use.
### I2Cv1 :id=i2cv1
### I2Cv1 :id=arm-configuration-i2cv1
* STM32F1xx
* STM32F2xx
@@ -88,7 +100,7 @@ See [this page](https://www.playembedded.org/blog/stm32-i2c-chibios/#7_I2Cv1_con
|`I2C1_CLOCK_SPEED` |`100000` |
|`I2C1_DUTY_CYCLE` |`STD_DUTY_CYCLE`|
### I2Cv2 :id=i2cv2
### I2Cv2 :id=arm-configuration-i2cv2
* STM32F0xx
* STM32F3xx
@@ -105,9 +117,9 @@ See [this page](https://www.playembedded.org/blog/stm32-i2c-chibios/#8_I2Cv2_I2C
|`I2C1_TIMINGR_SCLH` |`38U` |
|`I2C1_TIMINGR_SCLL` |`129U` |
## Functions :id=functions
## API :id=api
### `void i2c_init(void)`
### `void i2c_init(void)` :id=api-i2c-init
Initialize the I2C driver. This function must be called only once, before any of the below functions can be called.
The [QMK Configurator](https://config.qmk.fm) is an online graphical user interface that generates QMK Firmware `.hex` or `.bin` files.
It should be noted that Configurator cannot produce firmwares for keyboards using a different controller than they were designed for, i.e. an RP2040 controller on a board designed for pro micro. You will have to use the command line [converters](https://docs.qmk.fm/#/feature_converters?id=supported-converters) for this.
Watch the [Video Tutorial](https://www.youtube.com/watch?v=-imgglzDMdY). Many people find that is enough information to start programming their own keyboard.
The QMK Configurator works best with Chrome or Firefox.
@@ -85,6 +85,8 @@ Visit the [QMK Configurator](https://config.qmk.fm/#/) to create a keymap file:
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.
!> **Important:** Make sure that the GitHub username you use in step 2 is correct. If it is not, the build process will fail to locate your files in the right 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:
@@ -141,13 +143,13 @@ Replace `username.json` with the JSON file name that was downloaded from [QMK Co
If you have completed all steps correctly, the folder `qmk_keymap/` will contain the following files:
```
|-- .github
| `-- workflows
| `-- build.yml
|-- rules.mk
|-- config.h
|-- source.c
|-- username.json
├── .github
│ └── workflows
│ └── build.yml
├── rules.mk
├── config.h
├── source.c
└── username.json
```
To commit and push them into GitHub, run the following commands (replacing `gh-username` with your GitHub user name):
QMK Firmware now officially supports storing user keymaps outside of the normal QMK Firmware repository, allowing users to maintain their own keymaps without having to fork, modify, and maintain a copy of QMK Firmware themselves.
External Userspace mirrors the structure of the main QMK Firmware repository, but only contains the keymaps that you wish to build. You can still use `keyboards/<my keyboard>/keymaps/<my keymap>` to store your keymaps, or you can use the `layouts/<my layout>/<my keymap>` system as before -- they're just stored external to QMK Firmware.
The build system will still honor the use of `users/<my keymap>` if you rely on the traditional QMK Firmware [userspace feature](feature_userspace.md) -- it's now supported externally too, using the same location inside the External Userspace directory.
Additionally, there is first-class support for using GitHub Actions to build your keymaps, allowing you to automatically compile your keymaps whenever you push changes to your External Userspace repository.
!> External Userspace is new functionality and may have issues. Tighter integration with the `qmk` command will occur over time.
?> Historical keymap.json and GitHub-based firmware build instructions can be found [here](newbs_building_firmware_workflow.md). This document supersedes those instructions, but they should still function correctly.
## Setting up QMK Locally
If you wish to build on your local machine, you will need to set up QMK locally. This is a one-time process, and is documented in the [newbs setup guide](https://docs.qmk.fm/#/newbs).
!> If you wish to use any QMK CLI commands related to manipulating External Userspace definitions, you will currently need a copy of QMK Firmware as well.
!> Building locally has a much shorter turnaround time than waiting for GitHub Actions to complete.
## External Userspace Repository Setup (forked on GitHub)
A basic skeleton External Userspace repository can be found [here](https://github.com/qmk/qmk_userspace). If you wish to keep your keymaps on GitHub (strongly recommended!), you can fork the repository and use it as a base:
_These instructions assume you have already set up QMK locally, and have a copy of the QMK Firmware repository on your machine._
Keymaps within External Userspace are defined in the same way as they are in the main QMK repository. You can either use the `qmk new-keymap` command to create a new keymap, or manually create a new directory in the `keyboards` directory.
Alternatively, you can use the `layouts` directory to store your keymaps, using the same layout system as the main QMK repository -- if you choose to do so you'll want to use the path `layouts/<layout name>/<keymap name>/keymap.*` to store your keymap files, where `layout name` matches an existing layout in QMK, such as `tkl_ansi`.
After creating your new keymap, building the keymap matches normal QMK usage:
```sh
qmk compile -kb <keyboard> -km <keymap>
```
!> The `qmk config user.overlay_dir=...` command must have been run when cloning the External Userspace repository for this to work correctly.
## Adding the keymap to External Userspace build targets
Once you have created your keymap, if you want to use GitHub Actions to build your firmware, you will need to add it to the External Userspace build targets. This is done using the `qmk userspace-add` command:
This updates the `qmk.json` file in the root of your External Userspace directory. If you're using a git repository to store your keymaps, now is a great time to commit and push to your own fork.
## Compiling External Userspace build targets
Once you have added your keymaps to the External Userspace build targets, you can compile all of them at once using the `qmk userspace-compile` command:
```sh
qmk userspace-compile
```
All firmware builds you've added to the External Userspace build targets will be built, and the resulting firmware files will be placed in the root of your External Userspace directory.
## Using GitHub Actions
GitHub Actions can be used to automatically build your keymaps whenever you push changes to your External Userspace repository. If you have set up your list of build targets, this is as simple as enabling workflows in the GitHub repository settings:

Any push will result in compilation of all configured builds, and once completed a new release containing the newly-minted firmware files will be created on GitHub, which you can subsequently download and flash to your keyboard:
@@ -15,7 +15,7 @@ Different keyboards have different ways to enter this special mode. If your PCB
* Press the physical `RESET` button, usually located on the underside of the PCB
* Locate header pins on the PCB labeled `RESET` and `GND`, and short them together while plugging your PCB in
If you've attempted all of the above to no avail, and the main chip on the board says `STM32` on it, this may be a bit more complicated. Generally your best bet is to ask on [Discord](https://discord.gg/Uq7gcHh) for assistance. It's likely some photos of the board will be asked for -- if you can get them ready beforehand it'll help move things along!
If you've attempted all of the above to no avail, and the main chip on the board says `STM32` or `RP2-B1` on it, this may be a bit more complicated. Generally your best bet is to ask on [Discord](https://discord.gg/Uq7gcHh) for assistance. It's likely some photos of the board will be asked for -- if you can get them ready beforehand it'll help move things along!
Otherwise, you should see a message in yellow, similar to this in QMK Toolbox:
@@ -31,6 +31,8 @@ The simplest way to flash your keyboard will be with the [QMK Toolbox](https://g
However, the Toolbox is currently only available for Windows and macOS. If you're using Linux (or just wish to flash the firmware from the command line), skip to the [Flash your Keyboard from the Command Line](#flash-your-keyboard-from-the-command-line) section.
?> QMK Toolbox is not necessary for flashing [RP2040 devices](https://docs.qmk.fm/#/flashing?id=raspberry-pi-rp2040-uf2).
### Load the File into QMK Toolbox
Begin by opening the QMK Toolbox application. You'll want to locate the firmware file in Finder or Explorer. Your keyboard firmware may be in one of two formats- `.hex` or `.bin`. QMK tries to copy the appropriate one for your keyboard into the root `qmk_firmware` directory.
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.