Allow overriding of all functions in wonderland.c (#7198)

* f

* Allow overriding of all functions in wonderland.c

 - needed for custom LED functions in keymap.c

* Example of layer indication via LEDs

optimize

* Use newer led_update_kb and led_update_user hooks

 - these allow overriding without use of __attribute((weak))__

* Update led documentation a bit

 - clarify some of the wording around how  to use led_update_user

* Update led_update_user example

* Update audio example to be complete

* trailing spaces smh

* spaces

* spaces

* smh

* Less code is good

* Update docs/custom_quantum_functions.md

Co-Authored-By: fauxpark <fauxpark@gmail.com>

* Update docs/custom_quantum_functions.md

Co-Authored-By: fauxpark <fauxpark@gmail.com>

* Update docs/custom_quantum_functions.md

Co-Authored-By: fauxpark <fauxpark@gmail.com>

* Update docs/custom_quantum_functions.md

Co-Authored-By: fauxpark <fauxpark@gmail.com>

* Update docs/custom_quantum_functions.md

Co-Authored-By: fauxpark <fauxpark@gmail.com>

* Update docs/custom_quantum_functions.md

Co-Authored-By: fauxpark <fauxpark@gmail.com>
master
Yan-Fa Li 2019-11-22 12:55:45 -08:00 committed by GitHub
parent 0270d4d5a1
commit e62ab7e259
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 52 deletions

View File

@ -114,7 +114,15 @@ Two more deprecated functions exist that provide the LED state as a `uint8_t`:
This function will be called when the state of one of those 5 LEDs changes. It receives the LED state as a struct parameter. This function will be called when the state of one of those 5 LEDs changes. It receives the LED state as a struct parameter.
You must return either `true` or `false` from this function, depending on whether you want to override the keyboard-level implementation. By convention, return `true` from `led_update_user()` to get the `led_update_kb()` hook to run its code, and
return `false` when you would prefer not to run the code in `led_update_kb()`.
Some examples include:
- overriding the LEDs to use them for something else like layer indication
- return `false` because you do not want the `_kb()` function to run, as it would override your layer behavior.
- play a sound when an LED turns on or off.
- return `true` because you want the `_kb` function to run, and this is in addition to the default LED behavior.
?> 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. ?> 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.
@ -122,7 +130,8 @@ You must return either `true` or `false` from this function, depending on whethe
```c ```c
bool led_update_kb(led_t led_state) { bool led_update_kb(led_t led_state) {
if(led_update_user(led_state)) { bool res = led_update_user(led_state);
if(res) {
if (led_state.num_lock) { if (led_state.num_lock) {
writePinLow(B0); writePinLow(B0);
} else { } else {
@ -148,40 +157,29 @@ bool led_update_kb(led_t led_state) {
} else { } else {
writePinHigh(B4); writePinHigh(B4);
} }
return true;
} }
return res;
} }
``` ```
### Example `led_update_user()` Implementation ### Example `led_update_user()` Implementation
This incomplete example would play a sound if Caps Lock is turned on or off. It returns `true`, because you also want the LEDs to maintain their state.
```c ```c
#ifdef AUDIO_ENABLE
float caps_on[][2] = SONG(CAPS_LOCK_ON_SOUND);
float caps_off[][2] = SONG(CAPS_LOCK_OFF_SOUND);
#endif
bool led_update_user(led_t led_state) { bool led_update_user(led_t led_state) {
if (led_state.num_lock) { #ifdef AUDIO_ENABLE
writePinLow(B0); static uint8_t caps_state = 0;
} else { if (caps_state != led_state.caps_lock) {
writePinHigh(B0); led_state.caps_lock ? PLAY_SONG(caps_on) : PLAY_SONG(caps_off);
} caps_state = led_state.caps_lock;
if (led_state.caps_lock) {
writePinLow(B1);
} else {
writePinHigh(B1);
}
if (led_state.scroll_lock) {
writePinLow(B2);
} else {
writePinHigh(B2);
}
if (led_state.compose) {
writePinLow(B3);
} else {
writePinHigh(B3);
}
if (led_state.kana) {
writePinLow(B4);
} else {
writePinHigh(B4);
} }
#endif
return true; return true;
} }
``` ```

View File

@ -22,3 +22,33 @@ RGB_RMOD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
_______, KC_LALT, _______, _______, _______, KC_RALT, _______ \ _______, KC_LALT, _______, _______, _______, KC_RALT, _______ \
) )
}; };
#ifdef USE_LEDS_FOR_LAYERS
// example of how to use LEDs as layer indicators
static uint8_t top = 1;
static uint8_t middle = 0;
static uint8_t bottom = 0;
layer_state_t layer_state_set_user(layer_state_t state) {
top = middle = bottom = 0;
switch (get_highest_layer(state)) {
case _BASE:
top = 1;
break;
case _FUNC:
middle = 1;
break;
default: // for any other layers, or the default layer
break;
}
return state;
}
// override kb level function
bool led_update_user(led_t usb_led) {
writePin(B1, !top);
writePin(B2, !middle);
writePin(B3, !bottom);
return false; // we are using LEDs for something else override kb
}
#endif

View File

@ -1,5 +1,6 @@
#include "wonderland.h" #include "wonderland.h"
__attribute__ ((weak))
void matrix_init_kb(void) { void matrix_init_kb(void) {
// put your keyboard start-up code here // put your keyboard start-up code here
// runs once when the firmware starts up // runs once when the firmware starts up
@ -7,12 +8,14 @@ void matrix_init_kb(void) {
led_init_ports(); led_init_ports();
}; };
__attribute__ ((weak))
void matrix_scan_kb(void) { void matrix_scan_kb(void) {
// put your looping keyboard code here // put your looping keyboard code here
// runs every cycle (a lot) // runs every cycle (a lot)
matrix_scan_user(); matrix_scan_user();
}; };
__attribute__ ((weak))
void led_init_ports(void) { void led_init_ports(void) {
// * Set our LED pins as output // * Set our LED pins as output
setPinOutput(B1); setPinOutput(B1);
@ -20,23 +23,12 @@ void led_init_ports(void) {
setPinOutput(B3); setPinOutput(B3);
} }
void led_set_kb(uint8_t usb_led) { bool led_update_kb(led_t led_state) {
if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) { bool runDefault = led_update_user(led_state);
writePinLow(B1); if (runDefault) {
} else { writePin(B1, !led_state.num_lock);
writePinHigh(B1); writePin(B2, !led_state.caps_lock);
writePin(B3, !led_state.scroll_lock);
} }
return runDefault;
if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
writePinLow(B2);
} else {
writePinHigh(B2);
}
if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) {
writePinLow(B3);
} else {
writePinHigh(B3);
}
led_set_user(usb_led);
} }