|
| 1 | +Hooks |
| 2 | +----- |
| 3 | +Hooks allow you to execute custom code at certain predefined points in the firmware execution. To use them, just define the hook function in your keymap file. |
| 4 | + |
| 5 | +The following hooks are available available: |
| 6 | + |
| 7 | +Hook function | Called in file | Timing |
| 8 | +---|---|--- |
| 9 | +`hook_keyboard_start(void)` | *protocol/\<protocol>.c* | Early in the boot process, before the matrix is initialized and before a connection is made with the host. Thus, this hook has access to very few parameters, but it is a good place to define any custom parameters needed by other early processes. |
| 10 | +`hook_keyboard_init(void)` | *protocol/\<protocol>.c* | Near the end of the boot process, after Boot Magic has run and LEDs have been initialized. |
| 11 | +`hook_bootmagic(void)` | *common/bootmagic.c* | During the Boot Magic window, after EEPROM and Bootloader checks are made, but before any other built-in Boot Magic checks are made. |
| 12 | +`hook_usb_suspend(void)` | *protocol/\<protocol>.c* | When the device enters USB suspend state. *Default action:* enable LED breathing. |
| 13 | +`hook_usb_wakeup(void)` | *protocol/\<protocol>.c* | When the device wakes up from USB suspend state. *Default action:* disable LED breathing. |
| 14 | +`hook_suspend_loop(void)` | *protocol/\<protocol>.c* | Continuously, while the device is in USB suspend state. *Default action:* power down and periodically check the matrix, causing wakeup if needed. |
| 15 | +`hook_keyboard_loop(void)` | *common/keyboard.c* | Continuously, during the main loop, after the matrix is checked. Note that the protocol and interrupt configuration may affect the timing. If you need precise timing, use one of the `hook_interval_*` functions listed below. |
| 16 | +`hook_matrix_change(keyevent_t event)` | *common/action.c* | When a keypress event is detected, before any other actions are processed. |
| 17 | +`hook_layer_state_change(uint32_t layer_state)` | *common/action_layer.c* | When any layer is turned on or off. `layer_state` is a 32-bit integer containing the 0/1 state of all 32 layers, one bit per layer (see [keymap documentation](tmk_core/doc/keymap.md)). |
| 18 | +`hook_default_layer_state_change(uint32_t default_layer_state)` | *common/action_layer.c* | When the default layer is changed. `default_layer_state` is a 32-bit integer with a single bit set to 1 indicating the default layer (see [keymap documentation](tmk_core/doc/keymap.md)). |
| 19 | +`hook_leds_change(uint8_t led_status)` | *common/keyboard.c* | Whenever a change in the LED status is performed. *Default action:* call `keyboard_set_leds(led_status)` |
| 20 | + |
| 21 | +### Hooks Examples |
| 22 | + |
| 23 | +You can try these out by copying the code to your keymap file, or any .c file in the Makefile `SRC`. |
| 24 | + |
| 25 | +#### Activate keymap layer 5 on startup |
| 26 | + |
| 27 | +```C |
| 28 | +#include "action_layer.h" |
| 29 | + |
| 30 | +void hook_keyboard_init(void) |
| 31 | +{ |
| 32 | + layer_on(5); |
| 33 | + print("Layer 5 enabled!"); |
| 34 | +} |
| 35 | +``` |
| 36 | + |
| 37 | +#### Blink the Caps Lock LED every .5 seconds |
| 38 | + |
| 39 | +```C |
| 40 | +#include "timer.h" |
| 41 | +#include "led.h" |
| 42 | + |
| 43 | +bool my_led_status = 0; |
| 44 | +uint16_t my_led_timer; |
| 45 | + |
| 46 | +void hook_keyboard_loop(void) |
| 47 | +{ |
| 48 | + // check if we've reached 500 milliseconds yet... |
| 49 | + if (timer_elapsed(my_led_timer) > 500) |
| 50 | + { |
| 51 | + // we've reached 500 milliseconds! |
| 52 | + // reset the timer |
| 53 | + my_led_timer = timer_read(); |
| 54 | + |
| 55 | + // check the current LED state |
| 56 | + if (my_led_status) |
| 57 | + { |
| 58 | + // LED is on, so let's turn it off |
| 59 | + led_set(host_keyboard_leds() & (0<<USB_LED_CAPS_LOCK)); |
| 60 | + my_led_status = 0; |
| 61 | + } |
| 62 | + else |
| 63 | + { |
| 64 | + // LED is off, so let's turn it on |
| 65 | + led_set(host_keyboard_leds() | (1<<USB_LED_CAPS_LOCK)); |
| 66 | + my_led_status = 1; |
| 67 | + } |
| 68 | + } |
| 69 | +} |
| 70 | +``` |
| 71 | + |
| 72 | +#### Flash the Caps Lock LED for 20ms on every keypress |
| 73 | +```C |
| 74 | +#include "timer.h" |
| 75 | +#include "led.h" |
| 76 | + |
| 77 | +bool my_led_status = 0; |
| 78 | +uint16_t my_led_timer; |
| 79 | + |
| 80 | +void hook_matrix_change(keyevent_t event) |
| 81 | +{ |
| 82 | + // only flash LED for key press events, not key release events. |
| 83 | + if (event.pressed) |
| 84 | + { |
| 85 | + // check the current LED status and reverse it |
| 86 | + if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) |
| 87 | + { |
| 88 | + led_set(host_keyboard_leds() & (0<<USB_LED_CAPS_LOCK)); |
| 89 | + } |
| 90 | + else { |
| 91 | + led_set(host_keyboard_leds() | (1<<USB_LED_CAPS_LOCK)); |
| 92 | + } |
| 93 | + |
| 94 | + my_led_status = 1; |
| 95 | + my_led_timer = timer_read(); |
| 96 | + } |
| 97 | +} |
| 98 | + |
| 99 | +void hook_keyboard_loop(void) |
| 100 | +{ |
| 101 | + if (my_led_status) |
| 102 | + { |
| 103 | + // check if we've reached 20 milliseconds yet... |
| 104 | + if (timer_elapsed(my_led_timer) > 20) |
| 105 | + { |
| 106 | + keyboard_set_leds(host_keyboard_leds()); |
| 107 | + |
| 108 | + my_led_status = 0; |
| 109 | + } |
| 110 | + } |
| 111 | +} |
| 112 | +``` |
0 commit comments