qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

keyboard.c (19276B)


      1 /*
      2 Copyright 2011, 2012, 2013 Jun Wako <wakojun@gmail.com>
      3 
      4 This program is free software: you can redistribute it and/or modify
      5 it under the terms of the GNU General Public License as published by
      6 the Free Software Foundation, either version 2 of the License, or
      7 (at your option) any later version.
      8 
      9 This program is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 GNU General Public License for more details.
     13 
     14 You should have received a copy of the GNU General Public License
     15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17 
     18 #include <stdint.h>
     19 #include "keyboard.h"
     20 #include "keycode_config.h"
     21 #include "matrix.h"
     22 #include "keymap_introspection.h"
     23 #include "host.h"
     24 #include "led.h"
     25 #include "keycode.h"
     26 #include "timer.h"
     27 #include "sync_timer.h"
     28 #include "print.h"
     29 #include "debug.h"
     30 #include "command.h"
     31 #include "util.h"
     32 #include "host.h"
     33 #include "sendchar.h"
     34 #include "eeconfig.h"
     35 #include "action_layer.h"
     36 #include "suspend.h"
     37 #ifdef BOOTMAGIC_ENABLE
     38 #    include "bootmagic.h"
     39 #endif
     40 #ifdef AUDIO_ENABLE
     41 #    include "audio.h"
     42 #endif
     43 #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
     44 #    include "process_music.h"
     45 #endif
     46 #ifdef BACKLIGHT_ENABLE
     47 #    include "backlight.h"
     48 #endif
     49 #ifdef MOUSEKEY_ENABLE
     50 #    include "mousekey.h"
     51 #endif
     52 #ifdef PS2_MOUSE_ENABLE
     53 #    include "ps2_mouse.h"
     54 #endif
     55 #ifdef RGBLIGHT_ENABLE
     56 #    include "rgblight.h"
     57 #endif
     58 #ifdef LED_MATRIX_ENABLE
     59 #    include "led_matrix.h"
     60 #endif
     61 #ifdef RGB_MATRIX_ENABLE
     62 #    include "rgb_matrix.h"
     63 #endif
     64 #ifdef ENCODER_ENABLE
     65 #    include "encoder.h"
     66 #endif
     67 #ifdef HAPTIC_ENABLE
     68 #    include "haptic.h"
     69 #endif
     70 #ifdef AUTO_SHIFT_ENABLE
     71 #    include "process_auto_shift.h"
     72 #endif
     73 #ifdef COMBO_ENABLE
     74 #    include "process_combo.h"
     75 #endif
     76 #ifdef TAP_DANCE_ENABLE
     77 #    include "process_tap_dance.h"
     78 #endif
     79 #ifdef STENO_ENABLE
     80 #    include "process_steno.h"
     81 #endif
     82 #ifdef KEY_OVERRIDE_ENABLE
     83 #    include "process_key_override.h"
     84 #endif
     85 #ifdef SECURE_ENABLE
     86 #    include "secure.h"
     87 #endif
     88 #ifdef POINTING_DEVICE_ENABLE
     89 #    include "pointing_device.h"
     90 #endif
     91 #ifdef MIDI_ENABLE
     92 #    include "process_midi.h"
     93 #endif
     94 #ifdef JOYSTICK_ENABLE
     95 #    include "joystick.h"
     96 #endif
     97 #ifdef HD44780_ENABLE
     98 #    include "hd44780.h"
     99 #endif
    100 #ifdef OLED_ENABLE
    101 #    include "oled_driver.h"
    102 #endif
    103 #ifdef ST7565_ENABLE
    104 #    include "st7565.h"
    105 #endif
    106 #ifdef VIA_ENABLE
    107 #    include "via.h"
    108 #endif
    109 #ifdef DIP_SWITCH_ENABLE
    110 #    include "dip_switch.h"
    111 #endif
    112 #ifdef EEPROM_DRIVER
    113 #    include "eeprom_driver.h"
    114 #endif
    115 #if defined(CRC_ENABLE)
    116 #    include "crc.h"
    117 #endif
    118 #ifdef VIRTSER_ENABLE
    119 #    include "virtser.h"
    120 #endif
    121 #ifdef SLEEP_LED_ENABLE
    122 #    include "sleep_led.h"
    123 #endif
    124 #ifdef SPLIT_KEYBOARD
    125 #    include "split_util.h"
    126 #endif
    127 #ifdef BATTERY_ENABLE
    128 #    include "battery.h"
    129 #endif
    130 #ifdef BLUETOOTH_ENABLE
    131 #    include "bluetooth.h"
    132 #endif
    133 #ifdef CAPS_WORD_ENABLE
    134 #    include "caps_word.h"
    135 #endif
    136 #ifdef LEADER_ENABLE
    137 #    include "leader.h"
    138 #endif
    139 #ifdef UNICODE_COMMON_ENABLE
    140 #    include "unicode.h"
    141 #endif
    142 #ifdef WPM_ENABLE
    143 #    include "wpm.h"
    144 #endif
    145 #ifdef OS_DETECTION_ENABLE
    146 #    include "os_detection.h"
    147 #endif
    148 #ifdef LAYER_LOCK_ENABLE
    149 #    include "layer_lock.h"
    150 #endif
    151 #ifdef CONNECTION_ENABLE
    152 #    include "connection.h"
    153 #endif
    154 
    155 static uint32_t last_input_modification_time = 0;
    156 uint32_t        last_input_activity_time(void) {
    157     return last_input_modification_time;
    158 }
    159 uint32_t last_input_activity_elapsed(void) {
    160     return sync_timer_elapsed32(last_input_modification_time);
    161 }
    162 
    163 static uint32_t last_matrix_modification_time = 0;
    164 uint32_t        last_matrix_activity_time(void) {
    165     return last_matrix_modification_time;
    166 }
    167 uint32_t last_matrix_activity_elapsed(void) {
    168     return sync_timer_elapsed32(last_matrix_modification_time);
    169 }
    170 void last_matrix_activity_trigger(void) {
    171     last_matrix_modification_time = last_input_modification_time = sync_timer_read32();
    172 }
    173 
    174 static uint32_t last_encoder_modification_time = 0;
    175 uint32_t        last_encoder_activity_time(void) {
    176     return last_encoder_modification_time;
    177 }
    178 uint32_t last_encoder_activity_elapsed(void) {
    179     return sync_timer_elapsed32(last_encoder_modification_time);
    180 }
    181 void last_encoder_activity_trigger(void) {
    182     last_encoder_modification_time = last_input_modification_time = sync_timer_read32();
    183 }
    184 
    185 static uint32_t last_pointing_device_modification_time = 0;
    186 uint32_t        last_pointing_device_activity_time(void) {
    187     return last_pointing_device_modification_time;
    188 }
    189 uint32_t last_pointing_device_activity_elapsed(void) {
    190     return sync_timer_elapsed32(last_pointing_device_modification_time);
    191 }
    192 void last_pointing_device_activity_trigger(void) {
    193     last_pointing_device_modification_time = last_input_modification_time = sync_timer_read32();
    194 }
    195 
    196 void set_activity_timestamps(uint32_t matrix_timestamp, uint32_t encoder_timestamp, uint32_t pointing_device_timestamp) {
    197     last_matrix_modification_time          = matrix_timestamp;
    198     last_encoder_modification_time         = encoder_timestamp;
    199     last_pointing_device_modification_time = pointing_device_timestamp;
    200     last_input_modification_time           = MAX(matrix_timestamp, MAX(encoder_timestamp, pointing_device_timestamp));
    201 }
    202 
    203 // Only enable this if console is enabled to print to
    204 #if defined(DEBUG_MATRIX_SCAN_RATE)
    205 static uint32_t matrix_timer           = 0;
    206 static uint32_t matrix_scan_count      = 0;
    207 static uint32_t last_matrix_scan_count = 0;
    208 
    209 void matrix_scan_perf_task(void) {
    210     matrix_scan_count++;
    211 
    212     uint32_t timer_now = timer_read32();
    213     if (TIMER_DIFF_32(timer_now, matrix_timer) >= 1000) {
    214 #    if defined(CONSOLE_ENABLE)
    215         dprintf("matrix scan frequency: %lu\n", matrix_scan_count);
    216 #    endif
    217         last_matrix_scan_count = matrix_scan_count;
    218         matrix_timer           = timer_now;
    219         matrix_scan_count      = 0;
    220     }
    221 }
    222 
    223 uint32_t get_matrix_scan_rate(void) {
    224     return last_matrix_scan_count;
    225 }
    226 #else
    227 #    define matrix_scan_perf_task()
    228 #endif
    229 
    230 #ifdef MATRIX_HAS_GHOST
    231 static matrix_row_t get_real_keys(uint8_t row, matrix_row_t rowdata) {
    232     matrix_row_t out = 0;
    233     for (uint8_t col = 0; col < MATRIX_COLS; col++) {
    234         // read each key in the row data and check if the keymap defines it as a real key
    235         if (keycode_at_keymap_location(0, row, col) && (rowdata & (((matrix_row_t)1) << col))) {
    236             // this creates new row data, if a key is defined in the keymap, it will be set here
    237             out |= ((matrix_row_t)1) << col;
    238         }
    239     }
    240     return out;
    241 }
    242 
    243 static inline bool popcount_more_than_one(matrix_row_t rowdata) {
    244     rowdata &= rowdata - 1; // if there are less than two bits (keys) set, rowdata will become zero
    245     return rowdata;
    246 }
    247 
    248 static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata) {
    249     /* No ghost exists when less than 2 keys are down on the row.
    250     If there are "active" blanks in the matrix, the key can't be pressed by the user,
    251     there is no doubt as to which keys are really being pressed.
    252     The ghosts will be ignored, they are KC_NO.   */
    253     rowdata = get_real_keys(row, rowdata);
    254     if ((popcount_more_than_one(rowdata)) == 0) {
    255         return false;
    256     }
    257     /* Ghost occurs when the row shares a column line with other row,
    258     and two columns are read on each row. Blanks in the matrix don't matter,
    259     so they are filtered out.
    260     If there are two or more real keys pressed and they match columns with
    261     at least two of another row's real keys, the row will be ignored. Keep in mind,
    262     we are checking one row at a time, not all of them at once.
    263     */
    264     for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
    265         if (i != row && popcount_more_than_one(get_real_keys(i, matrix_get_row(i)) & rowdata)) {
    266             return true;
    267         }
    268     }
    269     return false;
    270 }
    271 
    272 #else
    273 
    274 static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata) {
    275     return false;
    276 }
    277 
    278 #endif
    279 
    280 /** \brief matrix_setup
    281  *
    282  * FIXME: needs doc
    283  */
    284 __attribute__((weak)) void matrix_setup(void) {}
    285 
    286 /** \brief keyboard_pre_init_user
    287  *
    288  * FIXME: needs doc
    289  */
    290 __attribute__((weak)) void keyboard_pre_init_user(void) {}
    291 
    292 /** \brief keyboard_pre_init_kb
    293  *
    294  * FIXME: needs doc
    295  */
    296 __attribute__((weak)) void keyboard_pre_init_kb(void) {
    297     keyboard_pre_init_user();
    298 }
    299 
    300 /** \brief keyboard_pre_init_modules
    301  *
    302  * FIXME: needs doc
    303  */
    304 __attribute__((weak)) void keyboard_pre_init_modules(void) {}
    305 
    306 /** \brief keyboard_pre_init_quantum
    307  *
    308  * FIXME: needs doc
    309  */
    310 void keyboard_pre_init_quantum(void) {
    311     keyboard_pre_init_modules();
    312     keyboard_pre_init_kb();
    313 }
    314 
    315 /** \brief keyboard_post_init_user
    316  *
    317  * FIXME: needs doc
    318  */
    319 
    320 __attribute__((weak)) void keyboard_post_init_user(void) {}
    321 
    322 /** \brief keyboard_post_init_kb
    323  *
    324  * FIXME: needs doc
    325  */
    326 
    327 __attribute__((weak)) void keyboard_post_init_kb(void) {
    328     keyboard_post_init_user();
    329 }
    330 
    331 /** \brief keyboard_post_init_modules
    332  *
    333  * FIXME: needs doc
    334  */
    335 
    336 __attribute__((weak)) void keyboard_post_init_modules(void) {}
    337 
    338 /** \brief keyboard_post_init_quantum
    339  *
    340  * FIXME: needs doc
    341  */
    342 
    343 void keyboard_post_init_quantum(void) {
    344     keyboard_post_init_modules();
    345     keyboard_post_init_kb();
    346 }
    347 
    348 /** \brief matrix_can_read
    349  *
    350  * Allows overriding when matrix scanning operations should be executed.
    351  */
    352 __attribute__((weak)) bool matrix_can_read(void) {
    353     return true;
    354 }
    355 
    356 /** \brief keyboard_setup
    357  *
    358  * FIXME: needs doc
    359  */
    360 void keyboard_setup(void) {
    361     print_set_sendchar(sendchar);
    362 #ifdef EEPROM_DRIVER
    363     eeprom_driver_init();
    364 #endif
    365     matrix_setup();
    366     keyboard_pre_init_quantum();
    367 }
    368 
    369 #ifndef SPLIT_KEYBOARD
    370 
    371 /** \brief is_keyboard_master
    372  *
    373  * FIXME: needs doc
    374  */
    375 __attribute__((weak)) bool is_keyboard_master(void) {
    376     return true;
    377 }
    378 
    379 /** \brief is_keyboard_left
    380  *
    381  * FIXME: needs doc
    382  */
    383 __attribute__((weak)) bool is_keyboard_left(void) {
    384     return true;
    385 }
    386 
    387 #endif
    388 
    389 /** \brief should_process_keypress
    390  *
    391  * Override this function if you have a condition where keypresses processing should change:
    392  *   - splits where the slave side needs to process for rgb/oled functionality
    393  */
    394 __attribute__((weak)) bool should_process_keypress(void) {
    395     return is_keyboard_master();
    396 }
    397 
    398 /** \brief housekeeping_task_modules
    399  *
    400  * Codegen will override this if community modules are enabled.
    401  * This is specific to keyboard-level functionality.
    402  */
    403 __attribute__((weak)) void housekeeping_task_modules(void) {}
    404 
    405 /** \brief housekeeping_task_kb
    406  *
    407  * Override this function if you have a need to execute code for every keyboard main loop iteration.
    408  * This is specific to keyboard-level functionality.
    409  */
    410 __attribute__((weak)) void housekeeping_task_kb(void) {}
    411 
    412 /** \brief housekeeping_task_user
    413  *
    414  * Override this function if you have a need to execute code for every keyboard main loop iteration.
    415  * This is specific to user/keymap-level functionality.
    416  */
    417 __attribute__((weak)) void housekeeping_task_user(void) {}
    418 
    419 /** \brief housekeeping_task
    420  *
    421  * Invokes hooks for executing code after QMK is done after each loop iteration.
    422  */
    423 void housekeeping_task(void) {
    424     housekeeping_task_modules();
    425     housekeeping_task_kb();
    426     housekeeping_task_user();
    427 }
    428 
    429 /** \brief quantum_init
    430  *
    431  * Init global state
    432  */
    433 void quantum_init(void) {
    434     /* check signature */
    435     if (!eeconfig_is_enabled()) {
    436         eeconfig_init();
    437     }
    438 
    439     /* init globals */
    440     eeconfig_read_debug(&debug_config);
    441     eeconfig_read_keymap(&keymap_config);
    442 
    443 #ifdef BOOTMAGIC_ENABLE
    444     bootmagic();
    445 #endif
    446 
    447     /* read here just incase bootmagic process changed its value */
    448     layer_state_t default_layer = (layer_state_t)eeconfig_read_default_layer();
    449     default_layer_set(default_layer);
    450 
    451     /* Also initialize layer state to trigger callback functions for layer_state */
    452     layer_state_set_kb((layer_state_t)layer_state);
    453 }
    454 
    455 /** \brief keyboard_init
    456  *
    457  * FIXME: needs doc
    458  */
    459 void keyboard_init(void) {
    460     timer_init();
    461     sync_timer_init();
    462 #ifdef VIA_ENABLE
    463     via_init();
    464 #endif
    465 #ifdef SPLIT_KEYBOARD
    466     split_pre_init();
    467 #endif
    468 #ifdef ENCODER_ENABLE
    469     encoder_init();
    470 #endif
    471     matrix_init();
    472     quantum_init();
    473 #ifdef CONNECTION_ENABLE
    474     connection_init();
    475 #endif
    476     host_init();
    477     led_init_ports();
    478 #ifdef BACKLIGHT_ENABLE
    479     backlight_init_ports();
    480 #endif
    481 #ifdef AUDIO_ENABLE
    482     audio_init();
    483 #endif
    484 #ifdef LED_MATRIX_ENABLE
    485     led_matrix_init();
    486 #endif
    487 #ifdef RGB_MATRIX_ENABLE
    488     rgb_matrix_init();
    489 #endif
    490 #if defined(UNICODE_COMMON_ENABLE)
    491     unicode_input_mode_init();
    492 #endif
    493 #if defined(CRC_ENABLE)
    494     crc_init();
    495 #endif
    496 #ifdef OLED_ENABLE
    497     oled_init(OLED_ROTATION_0);
    498 #endif
    499 #ifdef ST7565_ENABLE
    500     st7565_init(DISPLAY_ROTATION_0);
    501 #endif
    502 #ifdef PS2_MOUSE_ENABLE
    503     ps2_mouse_init();
    504 #endif
    505 #ifdef BACKLIGHT_ENABLE
    506     backlight_init();
    507 #endif
    508 #ifdef RGBLIGHT_ENABLE
    509     rgblight_init();
    510 #endif
    511 #ifdef STENO_ENABLE_ALL
    512     steno_init();
    513 #endif
    514 #if defined(NKRO_ENABLE) && defined(FORCE_NKRO)
    515 #    pragma message "FORCE_NKRO option is now deprecated - Please migrate to NKRO_DEFAULT_ON instead."
    516     keymap_config.nkro = 1;
    517     eeconfig_update_keymap(&keymap_config);
    518 #endif
    519 #ifdef DIP_SWITCH_ENABLE
    520     dip_switch_init();
    521 #endif
    522 #ifdef JOYSTICK_ENABLE
    523     joystick_init();
    524 #endif
    525 #ifdef SLEEP_LED_ENABLE
    526     sleep_led_init();
    527 #endif
    528 #ifdef VIRTSER_ENABLE
    529     virtser_init();
    530 #endif
    531 #ifdef SPLIT_KEYBOARD
    532     split_post_init();
    533 #endif
    534 #ifdef POINTING_DEVICE_ENABLE
    535     // init after split init
    536     pointing_device_init();
    537 #endif
    538 #ifdef BATTERY_ENABLE
    539     battery_init();
    540 #endif
    541 #ifdef BLUETOOTH_ENABLE
    542     bluetooth_init();
    543 #endif
    544 #ifdef HAPTIC_ENABLE
    545     haptic_init();
    546 #endif
    547 
    548 #if defined(DEBUG_MATRIX_SCAN_RATE) && defined(CONSOLE_ENABLE)
    549     debug_enable = true;
    550 #endif
    551 
    552     keyboard_post_init_quantum(); /* Always keep this last */
    553 }
    554 
    555 /** \brief key_event_task
    556  *
    557  * This function is responsible for calling into other systems when they need to respond to electrical switch press events.
    558  * This is differnet than keycode events as no layer processing, or filtering occurs.
    559  */
    560 void switch_events(uint8_t row, uint8_t col, bool pressed) {
    561 #if defined(LED_MATRIX_ENABLE)
    562     led_matrix_handle_key_event(row, col, pressed);
    563 #endif
    564 #if defined(RGB_MATRIX_ENABLE)
    565     rgb_matrix_handle_key_event(row, col, pressed);
    566 #endif
    567     wakeup_matrix_handle_key_event(row, col, pressed);
    568 }
    569 
    570 /**
    571  * @brief Generates a tick event at a maximum rate of 1KHz that drives the
    572  * internal QMK state machine.
    573  */
    574 static inline void generate_tick_event(void) {
    575     static uint16_t last_tick = 0;
    576     const uint16_t  now       = timer_read();
    577     if (TIMER_DIFF_16(now, last_tick) != 0) {
    578         action_exec(MAKE_TICK_EVENT);
    579         last_tick = now;
    580     }
    581 }
    582 
    583 matrix_row_t matrix_previous[MATRIX_ROWS];
    584 
    585 /**
    586  * @brief This task scans the keyboards matrix and processes any key presses
    587  * that occur.
    588  *
    589  * @return true Matrix did change
    590  * @return false Matrix didn't change
    591  */
    592 static bool matrix_task(void) {
    593     if (!matrix_can_read()) {
    594         generate_tick_event();
    595         return false;
    596     }
    597 
    598     matrix_scan();
    599     bool matrix_changed = false;
    600     for (uint8_t row = 0; row < MATRIX_ROWS && !matrix_changed; row++) {
    601         matrix_changed |= matrix_previous[row] ^ matrix_get_row(row);
    602     }
    603 
    604     matrix_scan_perf_task();
    605 
    606     // Short-circuit the complete matrix processing if it is not necessary
    607     if (!matrix_changed) {
    608         generate_tick_event();
    609         return matrix_changed;
    610     }
    611 
    612     if (debug_config.matrix) {
    613         matrix_print();
    614     }
    615 
    616     const bool process_keypress = should_process_keypress();
    617 
    618     for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
    619         const matrix_row_t current_row = matrix_get_row(row);
    620         const matrix_row_t row_changes = current_row ^ matrix_previous[row];
    621 
    622         if (!row_changes || has_ghost_in_row(row, current_row)) {
    623             continue;
    624         }
    625 
    626         matrix_row_t col_mask = 1;
    627         for (uint8_t col = 0; col < MATRIX_COLS; col++, col_mask <<= 1) {
    628             if (row_changes & col_mask) {
    629                 const bool key_pressed = current_row & col_mask;
    630 
    631                 if (process_keypress && !keypress_is_wakeup_key(row, col)) {
    632                     action_exec(MAKE_KEYEVENT(row, col, key_pressed));
    633                 }
    634 
    635                 switch_events(row, col, key_pressed);
    636             }
    637         }
    638 
    639         matrix_previous[row] = current_row;
    640     }
    641 
    642     return matrix_changed;
    643 }
    644 
    645 /** \brief Tasks previously located in matrix_scan_quantum
    646  *
    647  * TODO: rationalise against keyboard_task and current split role
    648  */
    649 void quantum_task(void) {
    650 #ifdef SPLIT_KEYBOARD
    651     // some tasks should only run on master
    652     if (!is_keyboard_master()) return;
    653 #endif
    654 
    655 #ifdef AUDIO_ENABLE
    656     audio_task();
    657 #endif
    658 
    659 #if defined(AUDIO_ENABLE) && !defined(NO_MUSIC_MODE)
    660     music_task();
    661 #endif
    662 
    663 #ifdef KEY_OVERRIDE_ENABLE
    664     key_override_task();
    665 #endif
    666 
    667 #ifdef SEQUENCER_ENABLE
    668     sequencer_task();
    669 #endif
    670 
    671 #ifdef TAP_DANCE_ENABLE
    672     tap_dance_task();
    673 #endif
    674 
    675 #ifdef COMBO_ENABLE
    676     combo_task();
    677 #endif
    678 
    679 #ifdef LEADER_ENABLE
    680     leader_task();
    681 #endif
    682 
    683 #ifdef WPM_ENABLE
    684     decay_wpm();
    685 #endif
    686 
    687 #ifdef DIP_SWITCH_ENABLE
    688     dip_switch_task();
    689 #endif
    690 
    691 #ifdef AUTO_SHIFT_ENABLE
    692     autoshift_matrix_scan();
    693 #endif
    694 
    695 #ifdef CAPS_WORD_ENABLE
    696     caps_word_task();
    697 #endif
    698 
    699 #ifdef SECURE_ENABLE
    700     secure_task();
    701 #endif
    702 
    703 #ifdef LAYER_LOCK_ENABLE
    704     layer_lock_task();
    705 #endif
    706 
    707     host_task();
    708 }
    709 
    710 /** \brief Main task that is repeatedly called as fast as possible. */
    711 void keyboard_task(void) {
    712     __attribute__((unused)) bool activity_has_occurred = false;
    713     if (matrix_task()) {
    714         last_matrix_activity_trigger();
    715         activity_has_occurred = true;
    716     }
    717 
    718     quantum_task();
    719 
    720 #if defined(SPLIT_WATCHDOG_ENABLE)
    721     split_watchdog_task();
    722 #endif
    723 
    724 #if defined(RGBLIGHT_ENABLE)
    725     rgblight_task();
    726 #endif
    727 
    728 #ifdef LED_MATRIX_ENABLE
    729     led_matrix_task();
    730 #endif
    731 #ifdef RGB_MATRIX_ENABLE
    732     rgb_matrix_task();
    733 #endif
    734 
    735 #if defined(BACKLIGHT_ENABLE)
    736 #    if defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS)
    737     backlight_task();
    738 #    endif
    739 #endif
    740 
    741 #ifdef ENCODER_ENABLE
    742     if (encoder_task()) {
    743         last_encoder_activity_trigger();
    744         activity_has_occurred = true;
    745     }
    746 #endif
    747 
    748 #ifdef POINTING_DEVICE_ENABLE
    749     if (pointing_device_task()) {
    750         last_pointing_device_activity_trigger();
    751         activity_has_occurred = true;
    752     }
    753 #endif
    754 
    755 #ifdef OLED_ENABLE
    756     oled_task();
    757 #    if OLED_TIMEOUT > 0
    758     // Wake up oled if user is using those fabulous keys or spinning those encoders!
    759     if (activity_has_occurred) oled_on();
    760 #    endif
    761 #endif
    762 
    763 #ifdef ST7565_ENABLE
    764     st7565_task();
    765 #    if ST7565_TIMEOUT > 0
    766     // Wake up display if user is using those fabulous keys or spinning those encoders!
    767     if (activity_has_occurred) st7565_on();
    768 #    endif
    769 #endif
    770 
    771 #ifdef MOUSEKEY_ENABLE
    772     // mousekey repeat & acceleration
    773     mousekey_task();
    774 #endif
    775 
    776 #ifdef PS2_MOUSE_ENABLE
    777     ps2_mouse_task();
    778 #endif
    779 
    780 #ifdef MIDI_ENABLE
    781     midi_task();
    782 #endif
    783 
    784 #ifdef JOYSTICK_ENABLE
    785     joystick_task();
    786 #endif
    787 
    788 #ifdef BATTERY_ENABLE
    789     battery_task();
    790 #endif
    791 
    792 #ifdef BLUETOOTH_ENABLE
    793     bluetooth_task();
    794 #endif
    795 
    796 #ifdef HAPTIC_ENABLE
    797     haptic_task();
    798 #endif
    799 
    800     led_task();
    801 
    802 #ifdef OS_DETECTION_ENABLE
    803     os_detection_task();
    804 #endif
    805 }