qmk_firmware

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

matrix_common.c (4774B)


      1 #include "matrix.h"
      2 #include "debounce.h"
      3 #include "wait.h"
      4 #include "print.h"
      5 #include "debug.h"
      6 
      7 #ifdef SPLIT_KEYBOARD
      8 #    include "split_common/split_util.h"
      9 #    include "split_common/transactions.h"
     10 #    include <string.h>
     11 #endif
     12 
     13 #ifndef MATRIX_IO_DELAY
     14 #    define MATRIX_IO_DELAY 30
     15 #endif
     16 
     17 /* matrix state(1:on, 0:off) */
     18 matrix_row_t raw_matrix[MATRIX_ROWS];
     19 matrix_row_t matrix[MATRIX_ROWS];
     20 
     21 #ifdef SPLIT_KEYBOARD
     22 // row offsets for each hand
     23 uint8_t thisHand, thatHand;
     24 #endif
     25 
     26 #ifdef MATRIX_MASKED
     27 extern const matrix_row_t matrix_mask[];
     28 #endif
     29 
     30 // user-defined overridable functions
     31 
     32 __attribute__((weak)) void matrix_init_kb(void) {
     33     matrix_init_user();
     34 }
     35 
     36 __attribute__((weak)) void matrix_scan_kb(void) {
     37     matrix_scan_user();
     38 }
     39 
     40 __attribute__((weak)) void matrix_init_user(void) {}
     41 
     42 __attribute__((weak)) void matrix_scan_user(void) {}
     43 
     44 // helper functions
     45 
     46 inline uint8_t matrix_rows(void) {
     47     return MATRIX_ROWS;
     48 }
     49 
     50 inline uint8_t matrix_cols(void) {
     51     return MATRIX_COLS;
     52 }
     53 
     54 inline bool matrix_is_on(uint8_t row, uint8_t col) {
     55     return (matrix[row] & ((matrix_row_t)1 << col));
     56 }
     57 
     58 inline matrix_row_t matrix_get_row(uint8_t row) {
     59     // Matrix mask lets you disable switches in the returned matrix data. For example, if you have a
     60     // switch blocker installed and the switch is always pressed.
     61 #ifdef MATRIX_MASKED
     62     return matrix[row] & matrix_mask[row];
     63 #else
     64     return matrix[row];
     65 #endif
     66 }
     67 
     68 #if (MATRIX_COLS <= 8)
     69 #    define print_matrix_header() print("\nr/c 01234567\n")
     70 #    define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
     71 #elif (MATRIX_COLS <= 16)
     72 #    define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
     73 #    define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
     74 #elif (MATRIX_COLS <= 32)
     75 #    define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
     76 #    define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
     77 #endif
     78 
     79 void matrix_print(void) {
     80     print_matrix_header();
     81 
     82     for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
     83         print_hex8(row);
     84         print(": ");
     85         print_matrix_row(row);
     86         print("\n");
     87     }
     88 }
     89 
     90 #ifdef SPLIT_KEYBOARD
     91 bool matrix_post_scan(void) {
     92     bool changed = false;
     93     if (is_keyboard_master()) {
     94         static bool  last_connected                     = false;
     95         matrix_row_t slave_matrix[MATRIX_ROWS_PER_HAND] = {0};
     96         if (transport_master_if_connected(matrix + thisHand, slave_matrix)) {
     97             changed = memcmp(matrix + thatHand, slave_matrix, sizeof(slave_matrix)) != 0;
     98 
     99             last_connected = true;
    100         } else if (last_connected) {
    101             // reset other half when disconnected
    102             memset(slave_matrix, 0, sizeof(slave_matrix));
    103             changed = true;
    104 
    105             last_connected = false;
    106         }
    107 
    108         if (changed) memcpy(matrix + thatHand, slave_matrix, sizeof(slave_matrix));
    109 
    110         matrix_scan_kb();
    111     } else {
    112         transport_slave(matrix + thatHand, matrix + thisHand);
    113 
    114         matrix_slave_scan_kb();
    115     }
    116 
    117     return changed;
    118 }
    119 #endif
    120 
    121 /* `matrix_io_delay ()` exists for backwards compatibility. From now on, use matrix_output_unselect_delay(). */
    122 __attribute__((weak)) void matrix_io_delay(void) {
    123     wait_us(MATRIX_IO_DELAY);
    124 }
    125 __attribute__((weak)) void matrix_output_select_delay(void) {
    126     waitInputPinDelay();
    127 }
    128 __attribute__((weak)) void matrix_output_unselect_delay(uint8_t line, bool key_pressed) {
    129     matrix_io_delay();
    130 }
    131 
    132 // CUSTOM MATRIX 'LITE'
    133 __attribute__((weak)) void matrix_init_custom(void) {}
    134 __attribute__((weak)) bool matrix_scan_custom(matrix_row_t current_matrix[]) {
    135     return true;
    136 }
    137 
    138 #ifdef SPLIT_KEYBOARD
    139 __attribute__((weak)) void matrix_slave_scan_kb(void) {
    140     matrix_slave_scan_user();
    141 }
    142 __attribute__((weak)) void matrix_slave_scan_user(void) {}
    143 #endif
    144 
    145 __attribute__((weak)) void matrix_init(void) {
    146 #ifdef SPLIT_KEYBOARD
    147     thisHand = isLeftHand ? 0 : (MATRIX_ROWS_PER_HAND);
    148     thatHand = MATRIX_ROWS_PER_HAND - thisHand;
    149 #endif
    150 
    151     matrix_init_custom();
    152 
    153     // initialize matrix state: all keys off
    154     for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
    155         raw_matrix[i] = 0;
    156         matrix[i]     = 0;
    157     }
    158 
    159     debounce_init();
    160 
    161     matrix_init_kb();
    162 }
    163 
    164 __attribute__((weak)) uint8_t matrix_scan(void) {
    165     bool changed = matrix_scan_custom(raw_matrix);
    166 
    167 #ifdef SPLIT_KEYBOARD
    168     changed = debounce(raw_matrix, matrix + thisHand, changed) | matrix_post_scan();
    169 #else
    170     changed = debounce(raw_matrix, matrix, changed);
    171     matrix_scan_kb();
    172 #endif
    173 
    174     return changed;
    175 }
    176 
    177 __attribute__((weak)) bool peek_matrix(uint8_t row_index, uint8_t col_index, bool raw) {
    178     return 0 != ((raw ? raw_matrix[row_index] : matrix[row_index]) & (MATRIX_ROW_SHIFTER << col_index));
    179 }