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