aboutsummaryrefslogtreecommitdiff
path: root/quantum/split_common/matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/split_common/matrix.c')
-rw-r--r--quantum/split_common/matrix.c83
1 files changed, 38 insertions, 45 deletions
diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c
index 039e7d977..56d91b07f 100644
--- a/quantum/split_common/matrix.c
+++ b/quantum/split_common/matrix.c
@@ -16,23 +16,30 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17#include <stdint.h> 17#include <stdint.h>
18#include <stdbool.h> 18#include <stdbool.h>
19#include <string.h>
19#include "util.h" 20#include "util.h"
20#include "matrix.h" 21#include "matrix.h"
21#include "debounce.h" 22#include "debounce.h"
22#include "quantum.h" 23#include "quantum.h"
23#include "split_util.h" 24#include "split_util.h"
24#include "config.h" 25#include "config.h"
25#include "transport.h" 26#include "transactions.h"
26 27
27#define ERROR_DISCONNECT_COUNT 5 28#ifndef ERROR_DISCONNECT_COUNT
29# define ERROR_DISCONNECT_COUNT 5
30#endif // ERROR_DISCONNECT_COUNT
28 31
29#define ROWS_PER_HAND (MATRIX_ROWS / 2) 32#define ROWS_PER_HAND (MATRIX_ROWS / 2)
30 33
31#ifdef DIRECT_PINS 34#ifdef DIRECT_PINS
32static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS; 35static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS;
33#elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW) 36#elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW)
37# ifdef MATRIX_ROW_PINS
34static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 38static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
39# endif // MATRIX_ROW_PINS
40# ifdef MATRIX_COL_PINS
35static pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; 41static pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
42# endif // MATRIX_COL_PINS
36#endif 43#endif
37 44
38/* matrix state(1:on, 0:off) */ 45/* matrix state(1:on, 0:off) */
@@ -45,6 +52,9 @@ uint8_t thisHand, thatHand;
45// user-defined overridable functions 52// user-defined overridable functions
46__attribute__((weak)) void matrix_slave_scan_kb(void) { matrix_slave_scan_user(); } 53__attribute__((weak)) void matrix_slave_scan_kb(void) { matrix_slave_scan_user(); }
47__attribute__((weak)) void matrix_slave_scan_user(void) {} 54__attribute__((weak)) void matrix_slave_scan_user(void) {}
55__attribute__((weak)) void matrix_init_pins(void);
56__attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row);
57__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col);
48 58
49static inline void setPinOutput_writeLow(pin_t pin) { 59static inline void setPinOutput_writeLow(pin_t pin) {
50 ATOMIC_BLOCK_FORCEON { 60 ATOMIC_BLOCK_FORCEON {
@@ -61,7 +71,7 @@ static inline void setPinInputHigh_atomic(pin_t pin) {
61 71
62#ifdef DIRECT_PINS 72#ifdef DIRECT_PINS
63 73
64static void init_pins(void) { 74__attribute__((weak)) void matrix_init_pins(void) {
65 for (int row = 0; row < MATRIX_ROWS; row++) { 75 for (int row = 0; row < MATRIX_ROWS; row++) {
66 for (int col = 0; col < MATRIX_COLS; col++) { 76 for (int col = 0; col < MATRIX_COLS; col++) {
67 pin_t pin = direct_pins[row][col]; 77 pin_t pin = direct_pins[row][col];
@@ -72,7 +82,7 @@ static void init_pins(void) {
72 } 82 }
73} 83}
74 84
75static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { 85__attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
76 // Start with a clear matrix row 86 // Start with a clear matrix row
77 matrix_row_t current_row_value = 0; 87 matrix_row_t current_row_value = 0;
78 88
@@ -83,16 +93,13 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
83 } 93 }
84 } 94 }
85 95
86 // If the row has changed, store the row and return the changed flag. 96 // Update the matrix
87 if (current_matrix[current_row] != current_row_value) { 97 current_matrix[current_row] = current_row_value;
88 current_matrix[current_row] = current_row_value;
89 return true;
90 }
91 return false;
92} 98}
93 99
94#elif defined(DIODE_DIRECTION) 100#elif defined(DIODE_DIRECTION)
95# if (DIODE_DIRECTION == COL2ROW) 101# if defined(MATRIX_ROW_PINS) && defined(MATRIX_COL_PINS)
102# if (DIODE_DIRECTION == COL2ROW)
96 103
97static void select_row(uint8_t row) { setPinOutput_writeLow(row_pins[row]); } 104static void select_row(uint8_t row) { setPinOutput_writeLow(row_pins[row]); }
98 105
@@ -104,14 +111,14 @@ static void unselect_rows(void) {
104 } 111 }
105} 112}
106 113
107static void init_pins(void) { 114__attribute__((weak)) void matrix_init_pins(void) {
108 unselect_rows(); 115 unselect_rows();
109 for (uint8_t x = 0; x < MATRIX_COLS; x++) { 116 for (uint8_t x = 0; x < MATRIX_COLS; x++) {
110 setPinInputHigh_atomic(col_pins[x]); 117 setPinInputHigh_atomic(col_pins[x]);
111 } 118 }
112} 119}
113 120
114static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { 121__attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
115 // Start with a clear matrix row 122 // Start with a clear matrix row
116 matrix_row_t current_row_value = 0; 123 matrix_row_t current_row_value = 0;
117 124
@@ -132,15 +139,11 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
132 unselect_row(current_row); 139 unselect_row(current_row);
133 matrix_output_unselect_delay(); // wait for all Col signals to go HIGH 140 matrix_output_unselect_delay(); // wait for all Col signals to go HIGH
134 141
135 // If the row has changed, store the row and return the changed flag. 142 // Update the matrix
136 if (current_matrix[current_row] != current_row_value) { 143 current_matrix[current_row] = current_row_value;
137 current_matrix[current_row] = current_row_value;
138 return true;
139 }
140 return false;
141} 144}
142 145
143# elif (DIODE_DIRECTION == ROW2COL) 146# elif (DIODE_DIRECTION == ROW2COL)
144 147
145static void select_col(uint8_t col) { setPinOutput_writeLow(col_pins[col]); } 148static void select_col(uint8_t col) { setPinOutput_writeLow(col_pins[col]); }
146 149
@@ -152,52 +155,39 @@ static void unselect_cols(void) {
152 } 155 }
153} 156}
154 157
155static void init_pins(void) { 158__attribute__((weak)) void matrix_init_pins(void) {
156 unselect_cols(); 159 unselect_cols();
157 for (uint8_t x = 0; x < ROWS_PER_HAND; x++) { 160 for (uint8_t x = 0; x < ROWS_PER_HAND; x++) {
158 setPinInputHigh_atomic(row_pins[x]); 161 setPinInputHigh_atomic(row_pins[x]);
159 } 162 }
160} 163}
161 164
162static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { 165__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
163 bool matrix_changed = false;
164
165 // Select col 166 // Select col
166 select_col(current_col); 167 select_col(current_col);
167 matrix_output_select_delay(); 168 matrix_output_select_delay();
168 169
169 // For each row... 170 // For each row...
170 for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) { 171 for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) {
171 // Store last value of row prior to reading
172 matrix_row_t last_row_value = current_matrix[row_index];
173 matrix_row_t current_row_value = last_row_value;
174
175 // Check row pin state 172 // Check row pin state
176 if (readPin(row_pins[row_index]) == 0) { 173 if (readPin(row_pins[row_index]) == 0) {
177 // Pin LO, set col bit 174 // Pin LO, set col bit
178 current_row_value |= (MATRIX_ROW_SHIFTER << current_col); 175 current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col);
179 } else { 176 } else {
180 // Pin HI, clear col bit 177 // Pin HI, clear col bit
181 current_row_value &= ~(MATRIX_ROW_SHIFTER << current_col); 178 current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col);
182 }
183
184 // Determine if the matrix changed state
185 if ((last_row_value != current_row_value)) {
186 matrix_changed |= true;
187 current_matrix[row_index] = current_row_value;
188 } 179 }
189 } 180 }
190 181
191 // Unselect col 182 // Unselect col
192 unselect_col(current_col); 183 unselect_col(current_col);
193 matrix_output_unselect_delay(); // wait for all Row signals to go HIGH 184 matrix_output_unselect_delay(); // wait for all Row signals to go HIGH
194
195 return matrix_changed;
196} 185}
197 186
198# else 187# else
199# error DIODE_DIRECTION must be one of COL2ROW or ROW2COL! 188# error DIODE_DIRECTION must be one of COL2ROW or ROW2COL!
200# endif 189# endif
190# endif // defined(MATRIX_ROW_PINS) && defined(MATRIX_COL_PINS)
201#else 191#else
202# error DIODE_DIRECTION is not defined! 192# error DIODE_DIRECTION is not defined!
203#endif 193#endif
@@ -233,7 +223,7 @@ void matrix_init(void) {
233 thatHand = ROWS_PER_HAND - thisHand; 223 thatHand = ROWS_PER_HAND - thisHand;
234 224
235 // initialize key pins 225 // initialize key pins
236 init_pins(); 226 matrix_init_pins();
237 227
238 // initialize matrix state: all keys off 228 // initialize matrix state: all keys off
239 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 229 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
@@ -288,20 +278,23 @@ bool matrix_post_scan(void) {
288} 278}
289 279
290uint8_t matrix_scan(void) { 280uint8_t matrix_scan(void) {
291 bool local_changed = false; 281 matrix_row_t curr_matrix[MATRIX_ROWS] = {0};
292 282
293#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW) 283#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW)
294 // Set row, read cols 284 // Set row, read cols
295 for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) { 285 for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) {
296 local_changed |= read_cols_on_row(raw_matrix, current_row); 286 matrix_read_cols_on_row(curr_matrix, current_row);
297 } 287 }
298#elif (DIODE_DIRECTION == ROW2COL) 288#elif (DIODE_DIRECTION == ROW2COL)
299 // Set col, read rows 289 // Set col, read rows
300 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { 290 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
301 local_changed |= read_rows_on_col(raw_matrix, current_col); 291 matrix_read_rows_on_col(curr_matrix, current_col);
302 } 292 }
303#endif 293#endif
304 294
295 bool local_changed = memcmp(raw_matrix, curr_matrix, sizeof(curr_matrix)) != 0;
296 if (local_changed) memcpy(raw_matrix, curr_matrix, sizeof(curr_matrix));
297
305 debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, local_changed); 298 debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, local_changed);
306 299
307 bool remote_changed = matrix_post_scan(); 300 bool remote_changed = matrix_post_scan();