diff --git a/docs/custom_quantum_functions.md b/docs/custom_quantum_functions.md index bf3a60377cdd..a23cae5d0fd4 100644 --- a/docs/custom_quantum_functions.md +++ b/docs/custom_quantum_functions.md @@ -287,6 +287,14 @@ This function gets called at every matrix scan, which is basically as often as t 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 housekeeping + +* Keyboard/Revision: `void housekeeping_task_kb(void)` +* Keymap: `void housekeeping_task_user(void)` + +This function gets called at the end of all QMK processing, before starting the next iteration. You can safely assume that QMK has dealt with the last matrix scan at the time that these functions are invoked -- layer states have been updated, USB reports have been sent, LEDs have been updated, and displays have been drawn. + +Similar to `matrix_scan_*`, these are called as often as the MCU can handle. To keep your board responsive, it's suggested to do as little as possible during these function calls, potentially throtting their behaviour if you do indeed require implementing something special. # Keyboard Idling/Wake Code diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index a45af56dfdbb..2c762ae235ca 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c @@ -229,6 +229,20 @@ __attribute__((weak)) bool is_keyboard_master(void) { return true; } */ __attribute__((weak)) bool should_process_keypress(void) { return is_keyboard_master(); } +/** \brief housekeeping_task_kb + * + * Override this function if you have a need to execute code for every keyboard main loop iteration. + * This is specific to keyboard-level functionality. + */ +__attribute__((weak)) void housekeeping_task_kb(void) {} + +/** \brief housekeeping_task_user + * + * Override this function if you have a need to execute code for every keyboard main loop iteration. + * This is specific to user/keymap-level functionality. + */ +__attribute__((weak)) void housekeeping_task_user(void) {} + /** \brief keyboard_init * * FIXME: needs doc @@ -309,6 +323,9 @@ void keyboard_task(void) { uint8_t keys_processed = 0; #endif + housekeeping_task_kb(); + housekeeping_task_user(); + #if defined(OLED_DRIVER_ENABLE) && !defined(OLED_DISABLE_TIMEOUT) uint8_t ret = matrix_scan(); #else diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h index 98ceca49b1a6..1ee69af376ed 100644 --- a/tmk_core/common/keyboard.h +++ b/tmk_core/common/keyboard.h @@ -69,6 +69,9 @@ void keyboard_pre_init_user(void); void keyboard_post_init_kb(void); void keyboard_post_init_user(void); +void housekeeping_task_kb(void); +void housekeeping_task_user(void); + #ifdef __cplusplus } #endif diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c index e4e79d351044..e10be52fb809 100644 --- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c +++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c @@ -305,6 +305,10 @@ int main(void) { // dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired); } #endif // CONSOLE_ENABLE + + // Run housekeeping + housekeeping_task_kb(); + housekeeping_task_user(); } return 1; diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c index 7b25d7ba116e..400c0b8f5308 100644 --- a/tmk_core/protocol/chibios/main.c +++ b/tmk_core/protocol/chibios/main.c @@ -265,5 +265,9 @@ int main(void) { #ifdef RAW_ENABLE raw_hid_task(); #endif + + // Run housekeeping + housekeeping_task_kb(); + housekeeping_task_user(); } } diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index cec00440269a..878be7d3424b 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -1104,6 +1104,10 @@ int main(void) { #if !defined(INTERRUPT_CONTROL_ENDPOINT) USB_USBTask(); #endif + + // Run housekeeping + housekeeping_task_kb(); + housekeeping_task_user(); } } diff --git a/tmk_core/protocol/vusb/main.c b/tmk_core/protocol/vusb/main.c index a57df5ce06a7..0e3447d926d1 100644 --- a/tmk_core/protocol/vusb/main.c +++ b/tmk_core/protocol/vusb/main.c @@ -153,6 +153,10 @@ int main(void) { console_task(); } #endif + + // Run housekeeping + housekeeping_task_kb(); + housekeeping_task_user(); } else if (suspend_wakeup_condition()) { usb_remote_wakeup(); }