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))
@ -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.
@ -67,7 +67,7 @@ We have a few different types of changes in QMK, each requiring a different leve
* 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.
* 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:
@ -114,16 +114,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.
@ -131,7 +121,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)
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,57 +14,23 @@ 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 |
@ -76,24 +42,88 @@ To configure the backlighting, `#define` these in your `config.h`:
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`:
Most keyboards have only one backlight pin which controls all backlight LEDs (especially if the backlight is connected to a hardware PWM pin).
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 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.
### AVR Driver :id=avr-driver
### PWM Driver :id=pwm-driver
The `pwm` driver is configured by default, however the equivalent setting within `rules.mk` would be:
This is the default backlight driver, which leverages the hardware PWM output capability of the microcontroller.
```make
BACKLIGHT_DRIVER = pwm
```
#### Caveats :id=avr-caveats
### 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 a simple API.
```make
BACKLIGHT_DRIVER = custom
```
```c
void backlight_init_ports(void) {
// Optional - runs on startup
// Usually you want to configure pins here
}
void backlight_set(uint8_t level) {
// Optional - runs on level change
// Usually you want to respond to the new value
}
void backlight_task(void) {
// Optional - runs periodically
// Note that this is called in the main keyboard loop,
// so long running actions here can cause performance issues
}
```
## AVR Configuration :id=avr-configuration
### PWM Driver :id=avr-pwm-driver
On AVR boards, QMK automatically decides which driver to use according to the following table:
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.
@ -108,113 +138,169 @@ On AVR boards, QMK automatically decides which driver to use according to the fo
|`D4` | | | | |Timer 1 | |
|`D5` | | | | |Timer 1 | |
All other pins will use timer-assisted software PWM:
### Timer Driver :id=avr-timer-driver
|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 |
Any GPIO pin can be used with this driver. The following table describes the supported timers:
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.
The following `#define`s apply only to the `timer` driver:
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.
Note that the choice of timer may conflict with the [Audio](feature_audio.md) feature.
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.
### PWM Driver :id=arm-pwm-driver
The breathing effect is the same as in the hardware PWM implementation.
Depending on the ChibiOS board configuration, you may need to enable PWM at the keyboard level. For STM32, this would look like:
### ARM Driver :id=arm-configuration
`halconf.h`:
```c
#define HAL_USE_PWM TRUE
```
`mcuconf.h`:
```c
#undef STM32_PWM_USE_TIM4
#define STM32_PWM_USE_TIM4 TRUE
```
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:
The following `#define`s apply only to the `pwm` 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|
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
```
#### ChibiOS Configuration :id=arm-configuration
The following `#define`s apply only to the `timer` driver:
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|
## Example Schematic
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.
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.
#### Caveats :id=arm-caveats
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 only hardware PWM is supported, not timer assisted, and does not provide automatic configuration.
![Backlight example circuit](https://i.imgur.com/BmAvoUC.png)
### Software PWM Driver :id=software-pwm-driver
## API :id=api
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`:
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.
Turn the backlight on.
To activate multiple backlight pins, add something like this to your `config.h`, instead of `BACKLIGHT_PIN`:
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`:
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.
---
![Backlight example circuit](https://i.imgur.com/BmAvoUC.png)
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`:
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.
#defineDRV2605L_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
#defineDRV2605L_RATED_VOLTAGE 3
#defineDRV2605L_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.
@ -225,3 +225,30 @@ 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 key to then perform some custom action. Key overrides are implemented with much care to behave just like normal keyboard shortcuts would in regards to the order of pressed keys, timing, and interacton with other pressed keys. There are a number of optional settings that can be used to really fine-tune the behavior of each key override as well. Using key overrides also does not delay key input for regular key presses, which inherently happens 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,7 +12,7 @@ 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`:
@ -139,7 +139,7 @@ Currently only 4 drivers are supported, but it would be trivial to support for m
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)
@ -373,7 +367,7 @@ For inspiration and examples, check out the built-in effects under `quantum/led_
#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
@ -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.
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:
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:
// 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.
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 enumerating the 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.
For demonstration purposes, the manufacturer and product strings of the device, along with the request and response, are also printed.
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`.
## API :id=api
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`.
Callback, invoked when a raw HID report has been received from the host.
### Building your host
#### Arguments :id=api-raw-hid-receive-arguments
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:
- `uint8_t *data`
A pointer to the received data. Always 32 bytes in length.
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.
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.
Send an HID 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.
#### Arguments :id=api-raw-hid-send-arguments
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.
- `uint8_t *data`
A pointer to the data to send. Must always be 32 bytes in length.
@ -12,7 +12,7 @@ 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`:
@ -76,7 +76,7 @@ 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`:
@ -162,7 +162,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.
@ -238,7 +238,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.
@ -386,7 +386,7 @@ Currently only 4 drivers are supported, but it would be trivial to support for m
Define these arrays listing all the LEDs in your `<keyboard>.c`:
@ -428,7 +428,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 +450,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`:
@ -470,7 +470,7 @@ There is basic support for addressable RGB matrix lighting with the SPI AW20216
```make
RGB_MATRIX_ENABLE = yes
RGB_MATRIX_DRIVER = AW20216
RGB_MATRIX_DRIVER = aw20216
```
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`:
@ -650,11 +650,8 @@ enum rgb_matrix_effects {
RGB_MATRIX_PIXEL_FRACTAL, // Single hue fractal filled keys pulsing horizontally out to edges
RGB_MATRIX_PIXEL_FLOW, // Pulsing RGB flow along LED wiring with random hues
RGB_MATRIX_PIXEL_RAIN, // Randomly light keys with random hues
#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
RGB_MATRIX_TYPING_HEATMAP, // How hot is your WPM!
RGB_MATRIX_DIGITAL_RAIN, // That famous computer simulation
#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)
@ -887,7 +879,7 @@ These are defined in [`color.h`](https://github.com/qmk/qmk_firmware/blob/master
#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
@ -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.
@ -524,37 +524,6 @@ By defining `RGBLIGHT_LED_MAP` as in the example below, you can specify the LED
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.
@ -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.
|`UNICODE_KEY_MAC` |`KC_LEFT_ALT` |The key to hold when beginning a Unicode sequence with the macOS input mode |
|`UNICODE_KEY_LNX` |`LCTL(LSFT(KC_U))`|The key to tap when beginning a Unicode sequence with the Linux input mode |
|`UNICODE_KEY_WINC` |`KC_RIGHT_ALT` |The key to hold when beginning a Unicode sequence with the WinCompose input mode|
|`UNICODE_SELECTED_MODES`|`-1` |A comma separated list of input modes for cycling through |
|`UNICODE_CYCLE_PERSIST` |`true` |Whether to persist the current Unicode input mode to EEPROM |
|`UNICODE_TYPE_DELAY` |`10` |The amount of time to wait, in milliseconds, between Unicode sequence keystrokes|
### Audio Feedback :id=audio-feedback
<br>
If you have the [Audio](feature_audio.md) feature enabled on your board, you can configure it to play sounds when the input mode is changed.
### 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|
Add the following to your `rules.mk`:
## 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).
<br>
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).
### 1.2. Unicode Map :id=unicode-map
### ** Unicode Map **
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.
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.
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
enum unicode_names {
@ -51,242 +80,373 @@ enum unicode_names {
SNEK
};
const uint32_t unicode_map[] PROGMEM = {
const uint32_t PROGMEM 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 upper case 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 (upper case) character will be inserted; otherwise, the first (lower case) 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
const uint32_t PROGMEM unicode_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:
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).
To set the list of enabled input modes, add the `UNICODE_SELECTED_MODES` define to your keymap's `config.h`, for example:
These modes can then be cycled through using the `UC_NEXT` and `UC_PREV` keycodes. You can also switch to any input mode, even if it is not specified in `UNICODE_SELECTED_MODES`, using their respective keycodes.
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.
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`.
The following input modes are available:
<!-- tabs:start -->
* **`UNICODE_MODE_MACOS`**: macOS built-in Unicode hex input. Supports code points up to `0x10FFFF` (all possible code points).
### ** macOS **
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.
**Mode Name:** `UNICODE_MODE_MAC`
!> Using the _Unicode Hex Input_ input source may disable some Option-based shortcuts, such as Option+Left and Option+Right.
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`.
* **`UNICODE_MODE_LINUX`**: Linux built-in IBus Unicode input. Supports code points up to `0x10FFFF` (all possible code points).
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.
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.
### ** Linux (IBus) **
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)).
**Mode Name:** `UNICODE_MODE_LINUX`
* **`UNICODE_MODE_WINDOWS`**: _(not recommended)_ Windows built-in hex numpad Unicode input. Supports code points up to `0xFFFF`.
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.
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.
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.
* **`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).
### ** Windows (WinCompose) **
* **`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).
**Mode Name:** `UNICODE_MODE_WINCOMPOSE`
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.
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.
## 3. Setting the Input Mode :id=setting-the-input-mode
### ** Windows (HexNumpad) **
To set your desired input mode, add the following define to your `config.h`:
**Mode Name:** `UNICODE_MODE_WINDOWS`
```c
#define UNICODE_SELECTED_MODES UNICODE_MODE_LINUX
```
!> 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 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)).
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.
You can also select multiple input modes, which allows you to easily cycle through them using the `UC_NEXT`/`UC_PREV` keycodes.
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 input mode 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`.
Save the file and run the command `setxkbmap us` to reload the layout.
Send the code point(s) for the given UCIS index.
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.
#### Arguments :id=api-register-ucis-arguments
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.
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.
`public void `[`raw_hid_receive`](#group__raw__hid_1ga6a488515569aeaf57f34773af17ddfd8)`(uint8_t * data,uint8_t length)` | Callback, invoked when a raw HID report has been received from the host.
`public `[`_Static_assert`](#group__unicode_1ga228e8f68206b6c1ee202d512b34cf2cd)`(sizeof(`[`unicode_config_t`](.build/docs/internals/unicode.md#unionunicode__config__t))`,"Unicode EECONFIG out of spec.")` |
`public uint8_t `[`get_unicode_input_mode`](#group__unicode_1ga03d833381368ad20462bffa3b716b1f5)`(void)` | Get the current Unicode input mode.
`public void `[`set_unicode_input_mode`](#group__unicode_1gac4985dee9f40737398b9486217cdb51d)`(uint8_t mode)` | Set the Unicode input mode.
`public void `[`unicode_input_mode_step`](#group__unicode_1gaebd6917bb13f4334bc278ec8b528a736)`(void)` | Change to the next Unicode input mode.
`public void `[`unicode_input_mode_step_reverse`](#group__unicode_1ga1939521bfa03504e4d49f4d96d2f91c3)`(void)` | Change to the previous Unicode input mode.
`public void `[`unicode_input_mode_set_user`](#group__unicode_1ga39925b42094bbfddc2caffb641e54c94)`(uint8_t input_mode)` | User-level callback, invoked when the input mode is changed.
`public void `[`unicode_input_mode_set_kb`](#group__unicode_1ga4cbea45151384f73acfcbf443c81b7f2)`(uint8_t input_mode)` | Keyboard-level callback, invoked when the input mode is changed.
`public void `[`unicode_input_start`](#group__unicode_1ga6d60352abfa290cc3585bbcf6541a900)`(void)` | Begin the Unicode input sequence. The exact behavior depends on the currently selected input mode.
`public void `[`unicode_input_finish`](#group__unicode_1gae14a43125d8d6dcbd7bc5b9e90b0bfe5)`(void)` | Complete the Unicode input sequence. The exact behavior depends on the currently selected input mode.
`public void `[`unicode_input_cancel`](#group__unicode_1ga437fcef7d812226afd59dc1f792b4b23)`(void)` | Cancel the Unicode input sequence. The exact behavior depends on the currently selected input mode.
`public void `[`register_hex`](#group__unicode_1ga8d77f2e7de42368d12863b77df11d3a5)`(uint16_t hex)` | Send a 16-bit hex number.
`public void `[`register_hex32`](#group__unicode_1ga631488849fd1bc67a84604e825b7d48e)`(uint32_t hex)` | Send a 32-bit hex number.
`public void `[`register_unicode`](#group__unicode_1ga0a0deec32fa289a5e4cecf2fa27aa0c0)`(uint32_t code_point)` | Input a single Unicode character. A surrogate pair will be sent if required by the input mode.
#### `public `[`_Static_assert`](#group__unicode_1ga228e8f68206b6c1ee202d512b34cf2cd)`(sizeof(`[`unicode_config_t`](.build/docs/internals/unicode.md#unionunicode__config__t))`,"Unicode EECONFIG out of spec.")`
`public uint8_t `[`unicodemap_index`](#group__unicodemap_1gaf2e331f270db9f276cf7cb3977384712)`(uint16_t keycode)` | Get the index into the `unicode_map` array for the given keycode, respecting shift state for pair keycodes.
`public uint32_t `[`unicodemap_get_code_point`](#group__unicodemap_1gae3d21f90ee76bce7c12336d6e727b73a)`(uint8_t index)` | Get the code point for the given index in the `unicode_map` array.
`public void `[`register_unicodemap`](#group__unicodemap_1gaf76d22d6821316d4e25782ace183e58d)`(uint8_t index)` | Send the code point for the given index in the `unicode_map` array.
@ -11,7 +11,6 @@ If there are any inconsistencies with these recommendations, you're best off [cr
- if submitter _does_ use their own `master` branch, they'll be given a link to the ["how to git"](newbs_git_using_your_master_branch.md) page after merging -- (end of this document will contain the contents of the message)
- PRs should contain the smallest amount of modifications required for a single change to the codebase
- multiple keyboards at the same time is not acceptable
- exception: keymaps for a single user targeting multiple keyboards and/or userspace is acceptable
- **the smaller the PR, the higher likelihood of a quicker review, higher likelihood of quicker merge, and less chance of conflicts**
- newly-added directories and filenames must be lowercase
- the lowercase requirement may be relaxed if upstream sources originally had uppercase characters (e.g. LUFA, ChibiOS, or imported files from other repositories etc.)
@ -40,6 +39,8 @@ If there are any inconsistencies with these recommendations, you're best off [cr
## Keymap PRs
Note that personal keymap submissions will no longer be accepted. This section applies to manufacturer-supported keymaps.
- `#include QMK_KEYBOARD_H` preferred to including specific board files
- prefer layer `enum`s to `#define`s
- custom keycode `enum`s must have first entry `= SAFE_RANGE`
@ -113,7 +113,7 @@ A modifier that acts as if it is held down until another key is released, so you
A low cost AVR development board. Clones of this device are often found on ebay very inexpensively (under $5) but people often struggle with flashing their pro micros.
## Pull Request
A request to submit code to QMK. We encourage all users to submit Pull Requests for their personal keymaps.
A request to submit code to QMK. We encourage all users to submit Pull Requests for bugfixes and new features.
## QWERTY
The standard English keyboard layout, and often a shortcut for other language's standard layouts. Named for the first 6 letters on the keyboard.
The SPI Master drivers used in QMK have a set of common functions to allow portability between MCUs.
## AVR Configuration
## AVR Configuration :id=avr-configuration
No special setup is required - just connect the `SS`, `SCK`, `MOSI` and `MISO` pins of your SPI devices to the matching pins on the MCU:
@ -16,7 +16,7 @@ No special setup is required - just connect the `SS`, `SCK`, `MOSI` and `MISO` p
You may use more than one slave select pin, not just the `SS` pin. This is useful when you have multiple devices connected and need to communicate with them individually.
`SPI_SS_PIN` can be passed to `spi_start()` to refer to `SS`.
You'll need to determine which pins can be used for SPI -- as an example, STM32 parts generally have multiple SPI peripherals, labeled SPI1, SPI2, SPI3 etc.
@ -49,19 +49,19 @@ Configuration-wise, you'll need to set up the peripheral as per your MCU's datas
As per the AVR configuration, you may choose any other standard GPIO as a slave select pin, which should be supplied to `spi_start()`.
## Functions
## API :id=api
### `void spi_init(void)`
### `void spi_init(void)` :id=api-spi-init
Initialize the SPI driver. This function must be called only once, before any of the below functions can be called.
The QMK pin to assert as the slave select pin, eg. `B4`.
@ -80,71 +80,71 @@ Start an SPI transaction.
- `uint16_t divisor`
The SPI clock divisor, will be rounded up to the nearest power of two. This number can be calculated by dividing the MCU's clock speed by the desired SPI clock speed. For example, an MCU running at 8 MHz wanting to talk to an SPI device at 4 MHz would set the divisor to `2`.
#### Return Value
#### Return Value :id=api-spi-start-return
`false` if the supplied parameters are invalid or the SPI peripheral is already in use, or `true`.
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 retro-tapping 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 held mod-tap key. That way, the programs on your computer will no longer interpret the mod suppression induced by retro-tapping 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.
### Retro Shift
[Auto Shift,](feature_auto_shift.md) has its own version of `retro tapping` called `retro shift`. It is extremely similar to `retro tapping`, but holding the key past `AUTO_SHIFT_TIMEOUT` results in the value it sends being shifted. Other configurations also affect it differently; see [here](feature_auto_shift.md#retro-shift) for more information.
You'll need to determine which pins can be used for UART -- as an example, STM32 parts generally have multiple UART peripherals, labeled USART1, USART2, USART3 etc.
@ -47,45 +47,45 @@ Configuration-wise, you'll need to set up the peripheral as per your MCU's datas
|`#define SD1_RTS_PIN` |The pin to use for RTS |`A12` |
|`#define SD1_RTS_PAL_MODE`|The alternate function mode for RTS |`7` |
Initialize the UART driver. This function must be called only once, before any of the below functions can be called.
#### Arguments
#### Arguments :id=api-uart-init-arguments
- `uint32_t baud`
The baud rate to transmit and receive at. This may depend on the device you are communicating with. Common values are 1200, 2400, 4800, 9600, 19200, 38400, 57600, and 115200.