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>
This commit is contained in:
parent
77399bfe51
commit
94ba2e5a9f
2 changed files with 52 additions and 8 deletions
|
@ -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²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²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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue