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 }