diff options
author | DidierLoiseau <didierloiseau+github@gmail.com> | 2019-01-18 02:28:33 +0100 |
---|---|---|
committer | Drashna Jaelre <drashna@live.com> | 2019-01-17 17:28:33 -0800 |
commit | 94ba2e5a9f9c01b015b447554bfee99f5bcee032 (patch) | |
tree | e43aaab00774e4d69e9c440eba1e4d2b4e523639 | |
parent | 77399bfe515f4dde5cb6c08dbc466ac1aa77cda3 (diff) | |
download | qmk_firmware-94ba2e5a9f9c01b015b447554bfee99f5bcee032.tar.gz qmk_firmware-94ba2e5a9f9c01b015b447554bfee99f5bcee032.zip |
Defined IS_(HOST_)LED_ON/OFF() and improved LED documentation (#4853)
* Defined IS_(HOST_)LED_ON/OFF() and improved LED documentation
* Update docs/custom_quantum_functions.md
Co-Authored-By: DidierLoiseau <didierloiseau+github@gmail.com>
* Update docs/custom_quantum_functions.md
Co-Authored-By: DidierLoiseau <didierloiseau+github@gmail.com>
* Integrated @drashna and @fauxpark's PR comments
- changed all plurals of "LED" to "LEDs" in the file
- rewording of the note about host_keyboard_leds() vs. led_set_user()
* Update docs/custom_quantum_functions.md
Co-Authored-By: DidierLoiseau <didierloiseau+github@gmail.com>
-rw-r--r-- | docs/custom_quantum_functions.md | 54 | ||||
-rw-r--r-- | tmk_core/common/host.h | 6 |
2 files changed, 52 insertions, 8 deletions
diff --git a/docs/custom_quantum_functions.md b/docs/custom_quantum_functions.md index 5b95450f2..3397bf2d4 100644 --- a/docs/custom_quantum_functions.md +++ b/docs/custom_quantum_functions.md | |||
@@ -90,7 +90,7 @@ keyrecord_t record { | |||
90 | 90 | ||
91 | # LED Control | 91 | # LED Control |
92 | 92 | ||
93 | This allows you to control the 5 LED's defined as part of the USB Keyboard spec. It will be called when the state of one of those 5 LEDs changes. | 93 | QMK provides methods to read the 5 LEDs defined as part of the HID spec: |
94 | 94 | ||
95 | * `USB_LED_NUM_LOCK` | 95 | * `USB_LED_NUM_LOCK` |
96 | * `USB_LED_CAPS_LOCK` | 96 | * `USB_LED_CAPS_LOCK` |
@@ -98,31 +98,46 @@ This allows you to control the 5 LED's defined as part of the USB Keyboard spec. | |||
98 | * `USB_LED_COMPOSE` | 98 | * `USB_LED_COMPOSE` |
99 | * `USB_LED_KANA` | 99 | * `USB_LED_KANA` |
100 | 100 | ||
101 | These five constants correspond to the positional bits of the host LED state. | ||
102 | There are two ways to get the host LED state: | ||
103 | |||
104 | * by implementing `led_set_user()` | ||
105 | * by calling `host_keyboard_leds()` | ||
106 | |||
107 | ## `led_set_user()` | ||
108 | |||
109 | This function will be called when the state of one of those 5 LEDs changes. | ||
110 | It receives the LED state as parameter. | ||
111 | Use the `IS_LED_ON(USB_LED, LED_NAME)` and `IS_LED_OFF(USB_LED, LED_NAME)` | ||
112 | macros to check the LED status. | ||
113 | |||
114 | !> `host_keyboard_leds()` may already reflect a new value before `led_set_user()` is called. | ||
115 | |||
101 | ### Example `led_set_user()` Implementation | 116 | ### Example `led_set_user()` Implementation |
102 | 117 | ||
103 | ```c | 118 | ```c |
104 | void led_set_user(uint8_t usb_led) { | 119 | void led_set_user(uint8_t usb_led) { |
105 | if (usb_led & (1<<USB_LED_NUM_LOCK)) { | 120 | if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) { |
106 | PORTB |= (1<<0); | 121 | PORTB |= (1<<0); |
107 | } else { | 122 | } else { |
108 | PORTB &= ~(1<<0); | 123 | PORTB &= ~(1<<0); |
109 | } | 124 | } |
110 | if (usb_led & (1<<USB_LED_CAPS_LOCK)) { | 125 | if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) { |
111 | PORTB |= (1<<1); | 126 | PORTB |= (1<<1); |
112 | } else { | 127 | } else { |
113 | PORTB &= ~(1<<1); | 128 | PORTB &= ~(1<<1); |
114 | } | 129 | } |
115 | if (usb_led & (1<<USB_LED_SCROLL_LOCK)) { | 130 | if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) { |
116 | PORTB |= (1<<2); | 131 | PORTB |= (1<<2); |
117 | } else { | 132 | } else { |
118 | PORTB &= ~(1<<2); | 133 | PORTB &= ~(1<<2); |
119 | } | 134 | } |
120 | if (usb_led & (1<<USB_LED_COMPOSE)) { | 135 | if (IS_LED_ON(usb_led, USB_LED_COMPOSE)) { |
121 | PORTB |= (1<<3); | 136 | PORTB |= (1<<3); |
122 | } else { | 137 | } else { |
123 | PORTB &= ~(1<<3); | 138 | PORTB &= ~(1<<3); |
124 | } | 139 | } |
125 | if (usb_led & (1<<USB_LED_KANA)) { | 140 | if (IS_LED_ON(usb_led, USB_LED_KANA)) { |
126 | PORTB |= (1<<4); | 141 | PORTB |= (1<<4); |
127 | } else { | 142 | } else { |
128 | PORTB &= ~(1<<4); | 143 | PORTB &= ~(1<<4); |
@@ -135,10 +150,33 @@ void led_set_user(uint8_t usb_led) { | |||
135 | * Keyboard/Revision: `void led_set_kb(uint8_t usb_led)` | 150 | * Keyboard/Revision: `void led_set_kb(uint8_t usb_led)` |
136 | * Keymap: `void led_set_user(uint8_t usb_led)` | 151 | * Keymap: `void led_set_user(uint8_t usb_led)` |
137 | 152 | ||
153 | ## `host_keyboard_leds()` | ||
154 | |||
155 | Call this function to get the last received LED state. | ||
156 | This is useful for reading the LED state outside `led_set_*`, e.g. in [`matrix_scan_user()`](#matrix-scanning-code). | ||
157 | |||
158 | For convenience, you can use the `IS_HOST_LED_ON(LED_NAME)` and `IS_HOST_LED_OFF(LED_NAME)` macros instead of calling `host_keyboard_leds()` directly. | ||
159 | |||
160 | ## Setting physical LED state | ||
161 | |||
162 | Some keyboard implementations provide convenience methods for setting the state of the physical LEDs. | ||
163 | |||
164 | ### Ergodox and Ergodox EZ | ||
165 | |||
166 | The Ergodox EZ implementation provides `ergodox_right_led_``1`/`2`/`3_on`/`off()` | ||
167 | to turn individual LEDs on and off, as well as | ||
168 | `ergodox_right_led_on`/`off(uint8_t led)` | ||
169 | to turn them on and off by their number. | ||
170 | |||
171 | In addition, it is possible to specify the brightness level with `ergodox_led_all_set(uint8_t n)`, | ||
172 | for individual LEDs with `ergodox_right_led_1`/`2`/`3_set(uint8_t n)` | ||
173 | or by their number using `ergodox_right_led_set(uint8_t led, uint8_t n)`. | ||
174 | |||
175 | It defines `LED_BRIGHTNESS_LO` for the lowest brightness and `LED_BRIGHTNESS_HI` for the highest brightness, which is also the default. | ||
138 | 176 | ||
139 | # Matrix Initialization Code | 177 | # Matrix Initialization Code |
140 | 178 | ||
141 | Before a keyboard can be used the hardware must be initialized. QMK handles initialization of the keyboard matrix itself, but if you have other hardware like LED's or i²c controllers you will need to set up that hardware before it can be used. | 179 | Before a keyboard can be used the hardware must be initialized. QMK handles initialization of the keyboard matrix itself, but if you have other hardware like LEDs or i²c controllers you will need to set up that hardware before it can be used. |
142 | 180 | ||
143 | 181 | ||
144 | ### Example `matrix_init_user()` Implementation | 182 | ### Example `matrix_init_user()` Implementation |
@@ -176,7 +214,7 @@ This example has been deliberately omitted. You should understand enough about Q | |||
176 | 214 | ||
177 | This function gets called at every matrix scan, which is basically as often as the MCU can handle. Be careful what you put here, as it will get run a lot. | 215 | This function gets called at every matrix scan, which is basically as often as the MCU can handle. Be careful what you put here, as it will get run a lot. |
178 | 216 | ||
179 | You should use this function if you need custom matrix scanning code. It can also be used for custom status output (such as LED's or a display) or other functionality that you want to trigger regularly even when the user isn't typing. | 217 | You should use this function if you need custom matrix scanning code. It can also be used for custom status output (such as LEDs or a display) or other functionality that you want to trigger regularly even when the user isn't typing. |
180 | 218 | ||
181 | 219 | ||
182 | # Keyboard Idling/Wake Code | 220 | # Keyboard Idling/Wake Code |
diff --git a/tmk_core/common/host.h b/tmk_core/common/host.h index aeabba710..e70bb6853 100644 --- a/tmk_core/common/host.h +++ b/tmk_core/common/host.h | |||
@@ -46,6 +46,12 @@ void host_consumer_send(uint16_t data); | |||
46 | uint16_t host_last_system_report(void); | 46 | uint16_t host_last_system_report(void); |
47 | uint16_t host_last_consumer_report(void); | 47 | uint16_t host_last_consumer_report(void); |
48 | 48 | ||
49 | #define IS_LED_ON(USB_LED, LED_NAME) ((USB_LED) & (1 << (LED_NAME))) | ||
50 | #define IS_LED_OFF(USB_LED, LED_NAME) (~(USB_LED) & (1 << (LED_NAME))) | ||
51 | |||
52 | #define IS_HOST_LED_ON(LED_NAME) IS_LED_ON(host_keyboard_leds(), (LED_NAME)) | ||
53 | #define IS_HOST_LED_OFF(LED_NAME) IS_LED_OFF(host_keyboard_leds(), (LED_NAME)) | ||
54 | |||
49 | #ifdef __cplusplus | 55 | #ifdef __cplusplus |
50 | } | 56 | } |
51 | #endif | 57 | #endif |