diff options
Diffstat (limited to 'docs/custom_quantum_functions.md')
| -rw-r--r-- | docs/custom_quantum_functions.md | 96 |
1 files changed, 69 insertions, 27 deletions
diff --git a/docs/custom_quantum_functions.md b/docs/custom_quantum_functions.md index 839d49ca0..2d505b075 100644 --- a/docs/custom_quantum_functions.md +++ b/docs/custom_quantum_functions.md | |||
| @@ -90,68 +90,110 @@ keyrecord_t record { | |||
| 90 | 90 | ||
| 91 | # LED Control | 91 | # LED Control |
| 92 | 92 | ||
| 93 | QMK provides methods to read the 5 LEDs defined as part of the HID spec: | 93 | QMK provides methods to read 5 of the LEDs defined in the HID spec: |
| 94 | 94 | ||
| 95 | * `USB_LED_NUM_LOCK` | 95 | * Num Lock |
| 96 | * `USB_LED_CAPS_LOCK` | 96 | * Caps Lock |
| 97 | * `USB_LED_SCROLL_LOCK` | 97 | * Scroll Lock |
| 98 | * `USB_LED_COMPOSE` | 98 | * Compose |
| 99 | * `USB_LED_KANA` | 99 | * Kana |
| 100 | 100 | ||
| 101 | These five constants correspond to the positional bits of the host LED state. | 101 | There are two ways to get the lock LED state: |
| 102 | There are two ways to get the host LED state: | ||
| 103 | 102 | ||
| 104 | * by implementing `led_set_user()` | 103 | * by implementing `bool led_update_kb(led_t led_state)` or `_user(led_t led_state)`; or |
| 105 | * by calling `host_keyboard_leds()` | 104 | * by calling `led_t host_keyboard_led_state()` |
| 106 | 105 | ||
| 107 | ## `led_set_user()` | 106 | !> `host_keyboard_led_state()` may already reflect a new value before `led_update_user()` is called. |
| 108 | 107 | ||
| 109 | This function will be called when the state of one of those 5 LEDs changes. It receives the LED state as a parameter. | 108 | Two more deprecated functions exist that provide the LED state as a `uint8_t`: |
| 110 | Use the `IS_LED_ON(usb_led, led_name)` and `IS_LED_OFF(usb_led, led_name)` macros to check the LED status. | ||
| 111 | 109 | ||
| 112 | !> `host_keyboard_leds()` may already reflect a new value before `led_set_user()` is called. | 110 | * `uint8_t led_set_kb(uint8_t usb_led)` and `_user(uint8_t usb_led)` |
| 111 | * `uint8_t host_keyboard_leds()` | ||
| 113 | 112 | ||
| 114 | ### Example `led_set_user()` Implementation | 113 | ## `led_update_user()` |
| 114 | |||
| 115 | This function will be called when the state of one of those 5 LEDs changes. It receives the LED state as a struct parameter. | ||
| 116 | |||
| 117 | You must return either `true` or `false` from this function, depending on whether you want to override the keyboard-level implementation. | ||
| 118 | |||
| 119 | ?> Because the `led_set_*` functions return `void` instead of `bool`, they do not allow for overriding the keyboard LED control, and thus it's recommended to use `led_update_*` instead. | ||
| 120 | |||
| 121 | ### Example `led_update_kb()` Implementation | ||
| 122 | |||
| 123 | ```c | ||
| 124 | bool led_update_kb(led_t led_state) { | ||
| 125 | if(led_update_user(led_state)) { | ||
| 126 | if (led_state.num_lock) { | ||
| 127 | writePinLow(B0); | ||
| 128 | } else { | ||
| 129 | writePinHigh(B0); | ||
| 130 | } | ||
| 131 | if (led_state.caps_lock) { | ||
| 132 | writePinLow(B1); | ||
| 133 | } else { | ||
| 134 | writePinHigh(B1); | ||
| 135 | } | ||
| 136 | if (led_state.scroll_lock) { | ||
| 137 | writePinLow(B2); | ||
| 138 | } else { | ||
| 139 | writePinHigh(B2); | ||
| 140 | } | ||
| 141 | if (led_state.compose) { | ||
| 142 | writePinLow(B3); | ||
| 143 | } else { | ||
| 144 | writePinHigh(B3); | ||
| 145 | } | ||
| 146 | if (led_state.kana) { | ||
| 147 | writePinLow(B4); | ||
| 148 | } else { | ||
| 149 | writePinHigh(B4); | ||
| 150 | } | ||
| 151 | return true; | ||
| 152 | } | ||
| 153 | } | ||
| 154 | ``` | ||
| 155 | |||
| 156 | ### Example `led_update_user()` Implementation | ||
| 115 | 157 | ||
| 116 | ```c | 158 | ```c |
| 117 | void led_set_user(uint8_t usb_led) { | 159 | bool led_update_user(led_t led_state) { |
| 118 | if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) { | 160 | if (led_state.num_lock) { |
| 119 | writePinLow(B0); | 161 | writePinLow(B0); |
| 120 | } else { | 162 | } else { |
| 121 | writePinHigh(B0); | 163 | writePinHigh(B0); |
| 122 | } | 164 | } |
| 123 | if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) { | 165 | if (led_state.caps_lock) { |
| 124 | writePinLow(B1); | 166 | writePinLow(B1); |
| 125 | } else { | 167 | } else { |
| 126 | writePinHigh(B1); | 168 | writePinHigh(B1); |
| 127 | } | 169 | } |
| 128 | if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) { | 170 | if (led_state.scroll_lock) { |
| 129 | writePinLow(B2); | 171 | writePinLow(B2); |
| 130 | } else { | 172 | } else { |
| 131 | writePinHigh(B2); | 173 | writePinHigh(B2); |
| 132 | } | 174 | } |
| 133 | if (IS_LED_ON(usb_led, USB_LED_COMPOSE)) { | 175 | if (led_state.compose) { |
| 134 | writePinLow(B3); | 176 | writePinLow(B3); |
| 135 | } else { | 177 | } else { |
| 136 | writePinHigh(B3); | 178 | writePinHigh(B3); |
| 137 | } | 179 | } |
| 138 | if (IS_LED_ON(usb_led, USB_LED_KANA)) { | 180 | if (led_state.kana) { |
| 139 | writePinLow(B4); | 181 | writePinLow(B4); |
| 140 | } else { | 182 | } else { |
| 141 | writePinHigh(B4); | 183 | writePinHigh(B4); |
| 142 | } | 184 | } |
| 185 | return true; | ||
| 143 | } | 186 | } |
| 144 | ``` | 187 | ``` |
| 145 | 188 | ||
| 146 | ### `led_set_*` Function Documentation | 189 | ### `led_update_*` Function Documentation |
| 147 | 190 | ||
| 148 | * Keyboard/Revision: `void led_set_kb(uint8_t usb_led)` | 191 | * Keyboard/Revision: `bool led_update_kb(led_t led_state)` |
| 149 | * Keymap: `void led_set_user(uint8_t usb_led)` | 192 | * Keymap: `bool led_update_user(led_t led_state)` |
| 150 | 193 | ||
| 151 | ## `host_keyboard_leds()` | 194 | ## `host_keyboard_led_state()` |
| 152 | 195 | ||
| 153 | Call this function to get the last received LED state. This is useful for reading the LED state outside `led_set_*`, e.g. in [`matrix_scan_user()`](#matrix-scanning-code). | 196 | Call this function to get the last received LED state as a `led_t`. This is useful for reading the LED state outside `led_update_*`, e.g. in [`matrix_scan_user()`](#matrix-scanning-code). |
| 154 | For convenience, you can use the `IS_HOST_LED_ON(led_name)` and `IS_HOST_LED_OFF(led_name)` macros instead of calling and checking `host_keyboard_leds()` directly. | ||
| 155 | 197 | ||
| 156 | ## Setting Physical LED State | 198 | ## Setting Physical LED State |
| 157 | 199 | ||
