Drop bs4 dependency, update docs, minor improvements
[jackhill/qmk/firmware.git] / docs / ref_functions.md
CommitLineData
eb19fb5b
DJ
1# List of Useful Core Functions To Make Your Keyboard Better
2
7e1b57ad 3There are a lot of hidden functions in QMK that are incredible useful, or may add a bit of functionality that you've been wanting. Functions that are specific to certain features are not included here, as those will be on their respective feature page.
eb19fb5b
DJ
4
5## (OLKB) Tri Layers
6
7e1b57ad 7There are actually separate functions that you can use there, depending on what you're after.
eb19fb5b 8
7e1b57ad 9### `update_tri_layer(x, y, z)`
eb19fb5b 10
7e1b57ad 11The first is the `update_tri_layer(x, y, z)` function. This function check to see if layers `x` and `y` are both on. If they are both on, then it runs on layer `z`. Otherwise, if both `x` and `y` are not both on (either only one is, or neither is), then it runs off layer `z`.
eb19fb5b 12
7e1b57ad 13This function is useful if you want to create specific keys that have this functionality, but other layer keycodes won't do this.
eb19fb5b 14
7e1b57ad
DJ
15#### Example
16
17```c
18bool process_record_user(uint16_t keycode, keyrecord_t *record) {
19 switch (keycode) {
20 case LOWER:
21 if (record->event.pressed) {
22 layer_on(_LOWER);
23 update_tri_layer(_LOWER, _RAISE, _ADJUST);
24 } else {
25 layer_off(_LOWER);
26 update_tri_layer(_LOWER, _RAISE, _ADJUST);
27 }
28 return false;
29 break;
30 case RAISE:
31 if (record->event.pressed) {
32 layer_on(_RAISE);
33 update_tri_layer(_LOWER, _RAISE, _ADJUST);
34 } else {
35 layer_off(_RAISE);
36 update_tri_layer(_LOWER, _RAISE, _ADJUST);
37 }
38 return false;
39 break;
40 }
41 return true;
42}
43```
44
45### `update_tri_layer_state(state, x, y, z)`
46The other function is `update_tri_layer_state(state, x, y, z)`. This function is meant to be called from they [`layer_state_set_*` functions](custom_quantum_functions.md#layer-change-code). This means that any time that you use a keycode to change the layer, this will be checked. So you could use `LT(layer, kc)` to change the layer and it will trigger the same layer check.
47
48The caveat to this method is that you cannot access the `z` layer without having `x` and `y` layers on, since if you try to activate just layer `z`, it will run this code and turn off layer `z` before you could use it.
49
50#### Example
51
52```c
b62e160a 53layer_state_t layer_state_set_user(layer_state_t state) {
7e1b57ad
DJ
54 return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
55}
56```
57
58Alternatively, you don't have to immediately "return" the value. This is useful if you want to add multiple tri layers, or if you want to add additional effects.
59
60```c
b62e160a 61layer_state_t layer_state_set_user(layer_state_t state) {
7e1b57ad
DJ
62 state = update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
63 state = update_tri_layer_state(state, _RAISE, _SYMB, _SPECIAL);
64 return state;
65}
66```
eb19fb5b
DJ
67
68## Setting the Persistent Default Layer
69
7e1b57ad 70Do you want to set the default layer, so that it's retained even after you unplug the board? If so, this is the function for you.
eb19fb5b 71
7e1b57ad 72To use this, you would use `set_single_persistent_default_layer(layer)`. If you have a name defined for your layer, you can use that instead (such as _QWERTY, _DVORAK or _COLEMAK).
eb19fb5b 73
7e1b57ad 74This will set the default layer, update the persistent settings, and play a tune if you have [Audio](feature_audio.md) enabled on your board, and the default layer sounds set.
eb19fb5b 75
7e1b57ad 76To configure the default layer sounds, you would want to define this in your `config.h` file, like this:
eb19fb5b
DJ
77
78```c
79#define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \
80 SONG(COLEMAK_SOUND), \
81 SONG(DVORAK_SOUND) \
82 }
83```
84
85
86?> There are a large number of predefined songs in [quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) that you can use.
87
88## Reseting the keyboard
89
7e1b57ad 90There is the `RESET` quantum keycode that you can use. But if you want to reset the board as part of a macro, rather than hitting a key separately, you can do that.
eb19fb5b
DJ
91
92And to do so, add `reset_keyboard()` to your function or macro, and this will reset to bootloader.
93
94## Wiping the EEPROM (Persistent Storage)
95
7e1b57ad 96If you're having issues with Audio, RGB Underglow, backlighting or keys acting weird, then you can reset the EEPROM (persistent setting storage). Bootmagic is one way to do this, but if that isn't enabled, then you can use a custom macro to do so.
eb19fb5b 97
7e1b57ad 98To wipe the EEPROM, run `eeconfig_init()` from your function or macro to reset most of the settings to default.
75a51659
DJ
99
100## Tap random key
101
102If you want to send a random character to the host computer, you can use the `tap_random_base64()` function. This [pseudorandomly](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) selects a number between 0 and 63, and then sends a key press based on that selection. (0–25 is `A`–`Z`, 26–51 is `a`–`z`, 52–61 is `0`–`9`, 62 is `+` and 63 is `/`).
103
104?> Needless to say, but this is _not_ a cryptographically secure method of generating random Base64 keys or passwords.
105
106## Software Timers
107
108It's possible to start timers and read values for time-specific events. Here's an example:
109
110```c
111static uint16_t key_timer;
112key_timer = timer_read();
113
114if (timer_elapsed(key_timer) < 100) {
115 // do something if less than 100ms have passed
116} else {
117 // do something if 100ms or more have passed
118}
119```