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>
master
DidierLoiseau 2019-01-18 02:28:33 +01:00 committed by Drashna Jaelre
parent 77399bfe51
commit 94ba2e5a9f
2 changed files with 52 additions and 8 deletions

View File

@ -90,7 +90,7 @@ keyrecord_t record {
# LED Control # LED Control
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. QMK provides methods to read the 5 LEDs defined as part of the HID spec:
* `USB_LED_NUM_LOCK` * `USB_LED_NUM_LOCK`
* `USB_LED_CAPS_LOCK` * `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.
* `USB_LED_COMPOSE` * `USB_LED_COMPOSE`
* `USB_LED_KANA` * `USB_LED_KANA`
These five constants correspond to the positional bits of the host LED state.
There are two ways to get the host LED state:
* by implementing `led_set_user()`
* by calling `host_keyboard_leds()`
## `led_set_user()`
This function will be called when the state of one of those 5 LEDs changes.
It receives the LED state as parameter.
Use the `IS_LED_ON(USB_LED, LED_NAME)` and `IS_LED_OFF(USB_LED, LED_NAME)`
macros to check the LED status.
!> `host_keyboard_leds()` may already reflect a new value before `led_set_user()` is called.
### Example `led_set_user()` Implementation ### Example `led_set_user()` Implementation
```c ```c
void led_set_user(uint8_t usb_led) { void led_set_user(uint8_t usb_led) {
if (usb_led & (1<<USB_LED_NUM_LOCK)) { if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) {
PORTB |= (1<<0); PORTB |= (1<<0);
} else { } else {
PORTB &= ~(1<<0); PORTB &= ~(1<<0);
} }
if (usb_led & (1<<USB_LED_CAPS_LOCK)) { if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
PORTB |= (1<<1); PORTB |= (1<<1);
} else { } else {
PORTB &= ~(1<<1); PORTB &= ~(1<<1);
} }
if (usb_led & (1<<USB_LED_SCROLL_LOCK)) { if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) {
PORTB |= (1<<2); PORTB |= (1<<2);
} else { } else {
PORTB &= ~(1<<2); PORTB &= ~(1<<2);
} }
if (usb_led & (1<<USB_LED_COMPOSE)) { if (IS_LED_ON(usb_led, USB_LED_COMPOSE)) {
PORTB |= (1<<3); PORTB |= (1<<3);
} else { } else {
PORTB &= ~(1<<3); PORTB &= ~(1<<3);
} }
if (usb_led & (1<<USB_LED_KANA)) { if (IS_LED_ON(usb_led, USB_LED_KANA)) {
PORTB |= (1<<4); PORTB |= (1<<4);
} else { } else {
PORTB &= ~(1<<4); PORTB &= ~(1<<4);
@ -135,10 +150,33 @@ void led_set_user(uint8_t usb_led) {
* Keyboard/Revision: `void led_set_kb(uint8_t usb_led)` * Keyboard/Revision: `void led_set_kb(uint8_t usb_led)`
* Keymap: `void led_set_user(uint8_t usb_led)` * Keymap: `void led_set_user(uint8_t usb_led)`
## `host_keyboard_leds()`
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).
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.
## Setting physical LED state
Some keyboard implementations provide convenience methods for setting the state of the physical LEDs.
### Ergodox and Ergodox EZ
The Ergodox EZ implementation provides `ergodox_right_led_``1`/`2`/`3_on`/`off()`
to turn individual LEDs on and off, as well as
`ergodox_right_led_on`/`off(uint8_t led)`
to turn them on and off by their number.
In addition, it is possible to specify the brightness level with `ergodox_led_all_set(uint8_t n)`,
for individual LEDs with `ergodox_right_led_1`/`2`/`3_set(uint8_t n)`
or by their number using `ergodox_right_led_set(uint8_t led, uint8_t n)`.
It defines `LED_BRIGHTNESS_LO` for the lowest brightness and `LED_BRIGHTNESS_HI` for the highest brightness, which is also the default.
# Matrix Initialization Code # Matrix Initialization Code
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&#xb2;c controllers you will need to set up that hardware before it can be used. 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&#xb2;c controllers you will need to set up that hardware before it can be used.
### Example `matrix_init_user()` Implementation ### Example `matrix_init_user()` Implementation
@ -176,7 +214,7 @@ This example has been deliberately omitted. You should understand enough about Q
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. 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.
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. 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.
# Keyboard Idling/Wake Code # Keyboard Idling/Wake Code

View File

@ -46,6 +46,12 @@ void host_consumer_send(uint16_t data);
uint16_t host_last_system_report(void); uint16_t host_last_system_report(void);
uint16_t host_last_consumer_report(void); uint16_t host_last_consumer_report(void);
#define IS_LED_ON(USB_LED, LED_NAME) ((USB_LED) & (1 << (LED_NAME)))
#define IS_LED_OFF(USB_LED, LED_NAME) (~(USB_LED) & (1 << (LED_NAME)))
#define IS_HOST_LED_ON(LED_NAME) IS_LED_ON(host_keyboard_leds(), (LED_NAME))
#define IS_HOST_LED_OFF(LED_NAME) IS_LED_OFF(host_keyboard_leds(), (LED_NAME))
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif