aboutsummaryrefslogtreecommitdiff
path: root/docs/custom_quantum_functions.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/custom_quantum_functions.md')
-rw-r--r--docs/custom_quantum_functions.md68
1 files changed, 67 insertions, 1 deletions
diff --git a/docs/custom_quantum_functions.md b/docs/custom_quantum_functions.md
index 463366ff7..dd1654bd2 100644
--- a/docs/custom_quantum_functions.md
+++ b/docs/custom_quantum_functions.md
@@ -149,7 +149,7 @@ This is useful for setting up stuff that you may need elsewhere, but isn't hardw
149* GPIO pin initialisation: `void matrix_init_pins(void)` 149* GPIO pin initialisation: `void matrix_init_pins(void)`
150 * This needs to perform the low-level initialisation of all row and column pins. By default this will initialise the input/output state of each of the GPIO pins listed in `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no initialisation of pin state will occur within QMK itself, instead deferring to the keyboard's override. 150 * This needs to perform the low-level initialisation of all row and column pins. By default this will initialise the input/output state of each of the GPIO pins listed in `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no initialisation of pin state will occur within QMK itself, instead deferring to the keyboard's override.
151* `COL2ROW`-based row reads: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)` 151* `COL2ROW`-based row reads: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)`
152* `ROW2COL`-based column reads: `void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)` 152* `ROW2COL`-based column reads: `void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col, matrix_row_t row_shifter)`
153* `DIRECT_PINS`-based reads: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)` 153* `DIRECT_PINS`-based reads: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)`
154 * These three functions need to perform the low-level retrieval of matrix state of relevant input pins, based on the matrix type. Only one of the functions should be implemented, if needed. By default this will iterate through `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, configuring the inputs and outputs based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no manipulation of matrix GPIO pin state will occur within QMK itself, instead deferring to the keyboard's override. 154 * These three functions need to perform the low-level retrieval of matrix state of relevant input pins, based on the matrix type. Only one of the functions should be implemented, if needed. By default this will iterate through `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, configuring the inputs and outputs based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no manipulation of matrix GPIO pin state will occur within QMK itself, instead deferring to the keyboard's override.
155 155
@@ -405,3 +405,69 @@ And you're done. The RGB layer indication will only work if you want it to. And
405* Keymap: `void eeconfig_init_user(void)`, `uint32_t eeconfig_read_user(void)` and `void eeconfig_update_user(uint32_t val)` 405* Keymap: `void eeconfig_init_user(void)`, `uint32_t eeconfig_read_user(void)` and `void eeconfig_update_user(uint32_t val)`
406 406
407The `val` is the value of the data that you want to write to EEPROM. And the `eeconfig_read_*` function return a 32 bit (DWORD) value from the EEPROM. 407The `val` is the value of the data that you want to write to EEPROM. And the `eeconfig_read_*` function return a 32 bit (DWORD) value from the EEPROM.
408
409### Deferred Execution :id=deferred-execution
410
411QMK has the ability to execute a callback after a specified period of time, rather than having to manually manage timers.
412
413#### Deferred executor callbacks
414
415All _deferred executor callbacks_ have a common function signature and look like:
416
417```c
418uint32_t my_callback(uint32_t trigger_time, void *cb_arg) {
419 /* do something */
420 bool repeat = my_deferred_functionality();
421 return repeat ? 500 : 0;
422}
423```
424
425The first argument `trigger_time` is the intended time of execution. If other delays prevent executing at the exact trigger time, this allows for "catch-up" or even skipping intervals, depending on the required behaviour.
426
427The second argument `cb_arg` is the same argument passed into `defer_exec()` below, and can be used to access state information from the original call context.
428
429The return value is the number of milliseconds to use if the function should be repeated -- if the callback returns `0` then it's automatically unregistered. In the example above, a hypothetical `my_deferred_functionality()` is invoked to determine if the callback needs to be repeated -- if it does, it reschedules for a `500` millisecond delay, otherwise it informs the deferred execution background task that it's done, by returning `0`.
430
431?> Note that the returned delay will be applied to the intended trigger time, not the time of callback invocation. This allows for generally consistent timing even in the face of occasional late execution.
432
433#### Deferred executor registration
434
435Once a callback has been defined, it can be scheduled using the following API:
436
437```c
438deferred_token my_token = defer_exec(1500, my_callback, NULL);
439```
440
441The first argument is the number of milliseconds to wait until executing `my_callback` -- in the case above, `1500` milliseconds, or 1.5 seconds.
442
443The third parameter is the `cb_arg` that gets passed to the callback at the point of execution. This value needs to be valid at the time the callback is invoked -- a local function value will be destroyed before the callback is executed and should not be used. If this is not required, `NULL` should be used.
444
445The return value is a `deferred_token` that can consequently be used to cancel the deferred executor callback before it's invoked. If a failure occurs, the returned value will be `INVALID_DEFERRED_TOKEN`. Usually this will be as a result of supplying `0` to the delay, or a `NULL` for the callback. The other failure case is if there are too many deferred executions "in flight" -- this can be increased by changing the limit, described below.
446
447#### Extending a deferred execution
448
449The `deferred_token` returned by `defer_exec()` can be used to extend a the duration a pending execution waits before it gets invoked:
450```c
451// This will re-delay my_token's future execution such that it is invoked 800ms after the current time
452extend_deferred_exec(my_token, 800);
453```
454
455#### Cancelling a deferred execution
456
457The `deferred_token` returned by `defer_exec()` can be used to cancel a pending execution before it gets invoked:
458```c
459// This will cancel my_token's future execution
460cancel_deferred_exec(my_token);
461```
462
463Once a token has been canceled, it should be considered invalid. Reusing the same token is not supported.
464
465#### Deferred callback limits
466
467There are a maximum number of deferred callbacks that can be scheduled, controlled by the value of the define `MAX_DEFERRED_EXECUTORS`.
468
469If registrations fail, then you can increase this value in your keyboard or keymap `config.h` file, for example to 16 instead of the default 8:
470
471```c
472#define MAX_DEFERRED_EXECUTORS 16
473```