aboutsummaryrefslogtreecommitdiffstats
path: root/docs/ref_functions.md
blob: 174d9a95a6f432b012e200ce29c60c8f2e015c98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# List of Useful Core Functions To Make Your Keyboard Better

There 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.

## (OLKB) Tri Layers

There are actually separate functions that you can use there, depending on what you're after.

### `update_tri_layer(x, y, z)`

The 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`.

This function is useful if you want to create specific keys that have this functionality, but other layer keycodes won't do this.

#### Example

```c
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  switch (keycode) {
    case LOWER:
      if (record->event.pressed) {
        layer_on(_LOWER);
        update_tri_layer(_LOWER, _RAISE, _ADJUST);
      } else {
        layer_off(_LOWER);
        update_tri_layer(_LOWER, _RAISE, _ADJUST);
      }
      return false;
      break;
    case RAISE:
      if (record->event.pressed) {
        layer_on(_RAISE);
        update_tri_layer(_LOWER, _RAISE, _ADJUST);
      } else {
        layer_off(_RAISE);
        update_tri_layer(_LOWER, _RAISE, _ADJUST);
      }
      return false;
      break;
    }
  return true;
}
```

### `update_tri_layer_state(state, x, y, z)`
The 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.

The 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.

#### Example

```c
uint32_t layer_state_set_user(uint32_t state) {
  return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
}
```

Alternatively, 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.

```c
uint32_t layer_state_set_user(uint32_t state) {
  state = update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
  state = update_tri_layer_state(state, _RAISE, _SYMB, _SPECIAL);
  return state;
}
```

## Setting the Persistent Default Layer

Do 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.

To 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).

This 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.

To configure the default layer sounds, you would want to define this in your `config.h` file, like this:

```c
#define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \
                              SONG(COLEMAK_SOUND), \
                              SONG(DVORAK_SOUND) \
                            }
```


?> 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.

## Reseting the keyboard

There 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.

And to do so, add `reset_keyboard()` to your function or macro, and this will reset to bootloader.

## Wiping the EEPROM (Persistent Storage)

If 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.

To wipe the EEPROM, run `eeconfig_init()` from your function or macro to reset most of the settings to default.

## Tap random key

If 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 `/`).  

?> Needless to say, but this is _not_ a cryptographically secure method of generating random Base64 keys or passwords.

## Software Timers

It's possible to start timers and read values for time-specific events. Here's an example:

```c
static uint16_t key_timer;
key_timer = timer_read();

if (timer_elapsed(key_timer) < 100) {
  // do something if less than 100ms have passed
} else {
  // do something if 100ms or more have passed
}
```
IN parameters. */ domid_t domain; } dom0_stopdomain_t; #define DOM0_GETDOMAININFO 12 typedef struct dom0_getdomaininfo_st { /* IN variables. */ domid_t domain; /* OUT variables. */ char name[MAX_DOMAIN_NAME]; int processor; int has_cpu; #define DOMSTATE_ACTIVE 0 #define DOMSTATE_STOPPED 1 int state; int hyp_events; unsigned int tot_pages, max_pages; long long cpu_time; unsigned long shared_info_frame; /* MFN of shared_info struct */ full_execution_context_t ctxt; } dom0_getdomaininfo_t; #define DOM0_BUILDDOMAIN 13 typedef struct dom0_builddomain_st { /* IN variables. */ domid_t domain; unsigned int num_vifs; full_execution_context_t ctxt; } dom0_builddomain_t; #define DOM0_IOPL 14 typedef struct dom0_iopl_st { domid_t domain; unsigned int iopl; } dom0_iopl_t; #define DOM0_MSR 15 typedef struct dom0_msr_st { /* IN variables. */ int write, cpu_mask, msr; unsigned int in1, in2; /* OUT variables. */ unsigned int out1, out2; } dom0_msr_t; #define DOM0_DEBUG 16 typedef struct dom0_debug_st { /* IN variables. */ char opcode; domid_t domain; int in1, in2, in3, in4; /* OUT variables. */ unsigned int status; int out1, out2; } dom0_debug_t; /* * Set clock such that it would read <secs,usecs> after 00:00:00 UTC, * 1 January, 1970 if the current system time was <system_time>. */ #define DOM0_SETTIME 17 typedef struct dom0_settime_st { /* IN variables. */ unsigned long secs, usecs; u64 system_time; } dom0_settime_t; #define DOM0_GETPAGEFRAMEINFO 18 typedef struct dom0_getpageframeinfo_st { /* IN variables. */ unsigned long pfn; /* Machine page frame number to query. */ domid_t domain; /* To which domain does the frame belong? */ /* OUT variables. */ /* Is the page PINNED to a type? */ enum { NONE, L1TAB, L2TAB, L3TAB, L4TAB } type; } dom0_getpageframeinfo_t; /* * Read console content from Xen buffer ring. */ #define DOM0_READCONSOLE 19 typedef struct dom0_readconsole_st { unsigned long str; unsigned int count; unsigned int cmd; } dom0_readconsole_t; /* * Pin Domain to a particular CPU (use -1 to unpin) */ #define DOM0_PINCPUDOMAIN 20 typedef struct dom0_pincpudomain_st { /* IN variables. */ domid_t domain; int cpu; /* -1 implies unpin */ } dom0_pincpudomain_t; /* Get trace buffers physical base pointer */ #define DOM0_GETTBUFS 21 typedef struct dom0_gettbufs_st { /* OUT variables */ unsigned long phys_addr; /* location of the trace buffers */ unsigned long size; /* size of each trace buffer, in bytes */ } dom0_gettbufs_t; /* * Get physical information about the host machine */ #define DOM0_PHYSINFO 22 typedef struct dom0_physinfo_st { int ht_per_core; int cores; unsigned long cpu_khz; unsigned long total_pages; unsigned long free_pages; } dom0_physinfo_t; /* * Allow a domain access to a physical PCI device */ #define DOM0_PCIDEV_ACCESS 23 typedef struct dom0_pcidev_access_st { /* IN variables. */ domid_t domain; int bus; int dev; int func; int enable; } dom0_pcidev_access_t; /* * Get the ID of the current scheduler. */ #define DOM0_SCHED_ID 24 typedef struct dom0_sched_id_st { /* OUT variable */ int sched_id; } dom0_sched_id_t; /* * Control shadow pagetables operation */ #define DOM0_SHADOW_CONTROL 25 #define DOM0_SHADOW_CONTROL_OP_OFF 0 #define DOM0_SHADOW_CONTROL_OP_ENABLE_TEST 1 #define DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY 2 #define DOM0_SHADOW_CONTROL_OP_FLUSH 10 #define DOM0_SHADOW_CONTROL_OP_CLEAN 11 typedef struct dom0_shadow_control_st { /* IN variables. */ domid_t domain; int op; } dom0_shadow_control_t; #define DOM0_SETDOMAINNAME 26 typedef struct dom0_setdomainname_st { /* IN variables. */ domid_t domain; char name[MAX_DOMAIN_NAME]; } dom0_setdomainname_t; #define DOM0_SETDOMAININITIALMEM 27 typedef struct dom0_setdomaininitialmem_st { /* IN variables. */ domid_t domain; unsigned int initial_memkb; /* use before domain is built */ } dom0_setdomaininitialmem_t; #define DOM0_SETDOMAINMAXMEM 28 typedef struct dom0_setdomainmaxmem_st { /* IN variables. */ domid_t domain; unsigned int max_memkb; } dom0_setdomainmaxmem_t; typedef struct dom0_op_st { unsigned long cmd; unsigned long interface_version; /* DOM0_INTERFACE_VERSION */ union { dom0_createdomain_t createdomain; dom0_startdomain_t startdomain; dom0_stopdomain_t stopdomain; dom0_destroydomain_t destroydomain; dom0_getmemlist_t getmemlist; dom0_schedctl_t schedctl; dom0_adjustdom_t adjustdom; dom0_builddomain_t builddomain; dom0_getdomaininfo_t getdomaininfo; dom0_getpageframeinfo_t getpageframeinfo; dom0_iopl_t iopl; dom0_msr_t msr; dom0_debug_t debug; dom0_settime_t settime; dom0_readconsole_t readconsole; dom0_pincpudomain_t pincpudomain; dom0_gettbufs_t gettbufs; dom0_physinfo_t physinfo; dom0_pcidev_access_t pcidev_access; dom0_sched_id_t sched_id; dom0_shadow_control_t shadow_control; dom0_setdomainname_t setdomainname; dom0_setdomaininitialmem_t setdomaininitialmem; dom0_setdomainmaxmem_t setdomainmaxmem; } u; } dom0_op_t; #endif /* __DOM0_OPS_H__ */