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.c639
1 files changed, 207 insertions, 432 deletions
diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c
index 2c37053f8..c3d2857ed 100644
--- a/quantum/split_common/matrix.c
+++ b/quantum/split_common/matrix.c
@@ -25,529 +25,304 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
25#include "matrix.h" 25#include "matrix.h"
26#include "split_util.h" 26#include "split_util.h"
27#include "config.h" 27#include "config.h"
28#include "timer.h"
29#include "split_flags.h" 28#include "split_flags.h"
30#include "quantum.h" 29#include "quantum.h"
31 30#include "debounce.h"
32#ifdef BACKLIGHT_ENABLE 31#include "transport.h"
33# include "backlight.h"
34 extern backlight_config_t backlight_config;
35#endif
36
37#if defined(USE_I2C) || defined(EH)
38# include "i2c.h"
39#else // USE_SERIAL
40# include "serial.h"
41#endif
42
43#ifndef DEBOUNCING_DELAY
44# define DEBOUNCING_DELAY 5
45#endif
46
47#if (DEBOUNCING_DELAY > 0)
48 static uint16_t debouncing_time;
49 static bool debouncing = false;
50#endif
51
52#if defined(USE_I2C) || defined(EH)
53
54#if (MATRIX_COLS <= 8)
55# define print_matrix_header() print("\nr/c 01234567\n")
56# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
57# define matrix_bitpop(i) bitpop(matrix[i])
58# define ROW_SHIFTER ((uint8_t)1)
59#else
60# error "Currently only supports 8 COLS"
61#endif
62
63#else // USE_SERIAL
64 32
65#if (MATRIX_COLS <= 8) 33#if (MATRIX_COLS <= 8)
66# define print_matrix_header() print("\nr/c 01234567\n") 34# define print_matrix_header() print("\nr/c 01234567\n")
67# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row)) 35# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
68# define matrix_bitpop(i) bitpop(matrix[i]) 36# define matrix_bitpop(i) bitpop(matrix[i])
69# define ROW_SHIFTER ((uint8_t)1) 37# define ROW_SHIFTER ((uint8_t)1)
70#elif (MATRIX_COLS <= 16) 38#elif (MATRIX_COLS <= 16)
71# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n") 39# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
72# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row)) 40# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
73# define matrix_bitpop(i) bitpop16(matrix[i]) 41# define matrix_bitpop(i) bitpop16(matrix[i])
74# define ROW_SHIFTER ((uint16_t)1) 42# define ROW_SHIFTER ((uint16_t)1)
75#elif (MATRIX_COLS <= 32) 43#elif (MATRIX_COLS <= 32)
76# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n") 44# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
77# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row)) 45# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
78# define matrix_bitpop(i) bitpop32(matrix[i]) 46# define matrix_bitpop(i) bitpop32(matrix[i])
79# define ROW_SHIFTER ((uint32_t)1) 47# define ROW_SHIFTER ((uint32_t)1)
80#endif
81
82#endif 48#endif
83static matrix_row_t matrix_debouncing[MATRIX_ROWS];
84 49
85#define ERROR_DISCONNECT_COUNT 5 50#define ERROR_DISCONNECT_COUNT 5
86 51
87#define ROWS_PER_HAND (MATRIX_ROWS/2) 52#define ROWS_PER_HAND (MATRIX_ROWS / 2)
88
89static uint8_t error_count = 0;
90 53
54#ifdef DIRECT_PINS
55static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS;
56#else
91static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 57static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
92static pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; 58static pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
59#endif
93 60
94/* matrix state(1:on, 0:off) */ 61/* matrix state(1:on, 0:off) */
95static matrix_row_t matrix[MATRIX_ROWS]; 62static matrix_row_t matrix[MATRIX_ROWS];
96static matrix_row_t matrix_debouncing[MATRIX_ROWS]; 63static matrix_row_t raw_matrix[ROWS_PER_HAND];
97
98#if (DIODE_DIRECTION == COL2ROW)
99 static void init_cols(void);
100 static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row);
101 static void unselect_rows(void);
102 static void select_row(uint8_t row);
103 static void unselect_row(uint8_t row);
104#elif (DIODE_DIRECTION == ROW2COL)
105 static void init_rows(void);
106 static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col);
107 static void unselect_cols(void);
108 static void unselect_col(uint8_t col);
109 static void select_col(uint8_t col);
110#endif
111 64
112__attribute__ ((weak)) 65// row offsets for each hand
113void matrix_init_kb(void) { 66uint8_t thisHand, thatHand;
114 matrix_init_user();
115}
116 67
117__attribute__ ((weak)) 68// user-defined overridable functions
118void matrix_scan_kb(void) {
119 matrix_scan_user();
120}
121 69
122__attribute__ ((weak)) 70__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); }
123void matrix_init_user(void) {
124}
125 71
126__attribute__ ((weak)) 72__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); }
127void matrix_scan_user(void) {
128}
129 73
130__attribute__ ((weak)) 74__attribute__((weak)) void matrix_init_user(void) {}
131void matrix_slave_scan_user(void) {
132}
133 75
134inline 76__attribute__((weak)) void matrix_scan_user(void) {}
135uint8_t matrix_rows(void)
136{
137 return MATRIX_ROWS;
138}
139 77
140inline 78__attribute__((weak)) void matrix_slave_scan_user(void) {}
141uint8_t matrix_cols(void)
142{
143 return MATRIX_COLS;
144}
145 79
146void matrix_init(void) 80// helper functions
147{
148 debug_enable = true;
149 debug_matrix = true;
150 debug_mouse = true;
151 81
152 // Set pinout for right half if pinout for that half is defined 82inline uint8_t matrix_rows(void) { return MATRIX_ROWS; }
153 if (!isLeftHand) {
154#ifdef MATRIX_ROW_PINS_RIGHT
155 const uint8_t row_pins_right[MATRIX_ROWS] = MATRIX_ROW_PINS_RIGHT;
156 for (uint8_t i = 0; i < MATRIX_ROWS; i++)
157 row_pins[i] = row_pins_right[i];
158#endif
159#ifdef MATRIX_COL_PINS_RIGHT
160 const uint8_t col_pins_right[MATRIX_COLS] = MATRIX_COL_PINS_RIGHT;
161 for (uint8_t i = 0; i < MATRIX_COLS; i++)
162 col_pins[i] = col_pins_right[i];
163#endif
164 }
165 83
166 // initialize row and col 84inline uint8_t matrix_cols(void) { return MATRIX_COLS; }
167#if (DIODE_DIRECTION == COL2ROW)
168 unselect_rows();
169 init_cols();
170#elif (DIODE_DIRECTION == ROW2COL)
171 unselect_cols();
172 init_rows();
173#endif
174 85
175 // initialize matrix state: all keys off 86bool matrix_is_modified(void) {
176 for (uint8_t i=0; i < MATRIX_ROWS; i++) { 87 if (debounce_active()) return false;
177 matrix[i] = 0; 88 return true;
178 matrix_debouncing[i] = 0;
179 }
180
181 matrix_init_quantum();
182
183} 89}
184 90
185uint8_t _matrix_scan(void) 91inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); }
186{
187 int offset = isLeftHand ? 0 : (ROWS_PER_HAND);
188#if (DIODE_DIRECTION == COL2ROW)
189 // Set row, read cols
190 for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) {
191# if (DEBOUNCING_DELAY > 0)
192 bool matrix_changed = read_cols_on_row(matrix_debouncing+offset, current_row);
193
194 if (matrix_changed) {
195 debouncing = true;
196 debouncing_time = timer_read();
197 }
198
199# else
200 read_cols_on_row(matrix+offset, current_row);
201# endif
202
203 }
204 92
205#elif (DIODE_DIRECTION == ROW2COL) 93inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; }
206 // Set col, read rows
207 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
208# if (DEBOUNCING_DELAY > 0)
209 bool matrix_changed = read_rows_on_col(matrix_debouncing+offset, current_col);
210 if (matrix_changed) {
211 debouncing = true;
212 debouncing_time = timer_read();
213 }
214# else
215 read_rows_on_col(matrix+offset, current_col);
216# endif
217 94
218 } 95void matrix_print(void) {
219#endif 96 print_matrix_header();
220 97
221# if (DEBOUNCING_DELAY > 0) 98 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
222 if (debouncing && (timer_elapsed(debouncing_time) > DEBOUNCING_DELAY)) { 99 phex(row);
223 for (uint8_t i = 0; i < ROWS_PER_HAND; i++) { 100 print(": ");
224 matrix[i+offset] = matrix_debouncing[i+offset]; 101 print_matrix_row(row);
225 } 102 print("\n");
226 debouncing = false; 103 }
227 } 104}
228# endif
229 105
230 return 1; 106uint8_t matrix_key_count(void) {
107 uint8_t count = 0;
108 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
109 count += matrix_bitpop(i);
110 }
111 return count;
231} 112}
232 113
233#if defined(USE_I2C) || defined(EH) 114// matrix code
234
235// Get rows from other half over i2c
236int i2c_transaction(void) {
237 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
238 int err = 0;
239
240 // write backlight info
241 #ifdef BACKLIGHT_ENABLE
242 if (BACKLIT_DIRTY) {
243 err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
244 if (err) goto i2c_error;
245
246 // Backlight location
247 err = i2c_master_write(I2C_BACKLIT_START);
248 if (err) goto i2c_error;
249
250 // Write backlight
251 i2c_master_write(get_backlight_level());
252
253 BACKLIT_DIRTY = false;
254 }
255 #endif
256 115
257 err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE); 116#ifdef DIRECT_PINS
258 if (err) goto i2c_error;
259 117
260 // start of matrix stored at I2C_KEYMAP_START 118static void init_pins(void) {
261 err = i2c_master_write(I2C_KEYMAP_START); 119 for (int row = 0; row < MATRIX_ROWS; row++) {
262 if (err) goto i2c_error; 120 for (int col = 0; col < MATRIX_COLS; col++) {
121 pin_t pin = direct_pins[row][col];
122 if (pin != NO_PIN) {
123 setPinInputHigh(pin);
124 }
125 }
126 }
127}
263 128
264 // Start read 129static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
265 err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ); 130 matrix_row_t last_row_value = current_matrix[current_row];
266 if (err) goto i2c_error; 131 current_matrix[current_row] = 0;
267 132
268 if (!err) { 133 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
269 int i; 134 pin_t pin = direct_pins[current_row][col_index];
270 for (i = 0; i < ROWS_PER_HAND-1; ++i) { 135 if (pin != NO_PIN) {
271 matrix[slaveOffset+i] = i2c_master_read(I2C_ACK); 136 current_matrix[current_row] |= readPin(pin) ? 0 : (ROW_SHIFTER << col_index);
272 }
273 matrix[slaveOffset+i] = i2c_master_read(I2C_NACK);
274 i2c_master_stop();
275 } else {
276i2c_error: // the cable is disconnceted, or something else went wrong
277 i2c_reset_state();
278 return err;
279 } 137 }
280 138 }
281 #ifdef RGBLIGHT_ENABLE
282 if (RGB_DIRTY) {
283 err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
284 if (err) goto i2c_error;
285
286 // RGB Location
287 err = i2c_master_write(I2C_RGB_START);
288 if (err) goto i2c_error;
289
290 uint32_t dword = eeconfig_read_rgblight();
291
292 // Write RGB
293 err = i2c_master_write_data(&dword, 4);
294 if (err) goto i2c_error;
295
296 RGB_DIRTY = false;
297 i2c_master_stop();
298 }
299 #endif
300 139
301 return 0; 140 return (last_row_value != current_matrix[current_row]);
302} 141}
303 142
304#else // USE_SERIAL 143#elif (DIODE_DIRECTION == COL2ROW)
305
306 144
307typedef struct _Serial_s2m_buffer_t { 145static void select_row(uint8_t row) {
308 // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack 146 writePinLow(row_pins[row]);
309 matrix_row_t smatrix[ROWS_PER_HAND]; 147 setPinOutput(row_pins[row]);
310} Serial_s2m_buffer_t; 148}
311 149
312volatile Serial_s2m_buffer_t serial_s2m_buffer = {}; 150static void unselect_row(uint8_t row) { setPinInputHigh(row_pins[row]); }
313volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
314uint8_t volatile status0 = 0;
315 151
316SSTD_t transactions[] = { 152static void unselect_rows(void) {
317 { (uint8_t *)&status0, 153 for (uint8_t x = 0; x < ROWS_PER_HAND; x++) {
318 sizeof(serial_m2s_buffer), (uint8_t *)&serial_m2s_buffer, 154 setPinInputHigh(row_pins[x]);
319 sizeof(serial_s2m_buffer), (uint8_t *)&serial_s2m_buffer
320 } 155 }
321}; 156}
322 157
323void serial_master_init(void) 158static void init_pins(void) {
324{ soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); } 159 unselect_rows();
160 for (uint8_t x = 0; x < MATRIX_COLS; x++) {
161 setPinInputHigh(col_pins[x]);
162 }
163}
325 164
326void serial_slave_init(void) 165static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
327{ soft_serial_target_init(transactions, TID_LIMIT(transactions)); } 166 // Store last value of row prior to reading
167 matrix_row_t last_row_value = current_matrix[current_row];
328 168
329int serial_transaction(void) { 169 // Clear data in matrix row
330 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; 170 current_matrix[current_row] = 0;
331 171
332 if (soft_serial_transaction()) { 172 // Select row and wait for row selecton to stabilize
333 return 1; 173 select_row(current_row);
334 } 174 wait_us(30);
335 175
336 // TODO: if MATRIX_COLS > 8 change to unpack() 176 // For each col...
337 for (int i = 0; i < ROWS_PER_HAND; ++i) { 177 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
338 matrix[slaveOffset+i] = serial_s2m_buffer.smatrix[i]; 178 // Populate the matrix row with the state of the col pin
339 } 179 current_matrix[current_row] |= readPin(col_pins[col_index]) ? 0 : (ROW_SHIFTER << col_index);
340 180 }
341 #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
342 // Code to send RGB over serial goes here (not implemented yet)
343 #endif
344
345 #ifdef BACKLIGHT_ENABLE
346 // Write backlight level for slave to read
347 serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0;
348 #endif
349
350 return 0;
351}
352#endif
353 181
354uint8_t matrix_scan(void) 182 // Unselect row
355{ 183 unselect_row(current_row);
356 uint8_t ret = _matrix_scan();
357 184
358#if defined(USE_I2C) || defined(EH) 185 return (last_row_value != current_matrix[current_row]);
359 if( i2c_transaction() ) { 186}
360#else // USE_SERIAL
361 if( serial_transaction() ) {
362#endif
363 187
364 error_count++; 188#elif (DIODE_DIRECTION == ROW2COL)
365 189
366 if (error_count > ERROR_DISCONNECT_COUNT) { 190static void select_col(uint8_t col) {
367 // reset other half if disconnected 191 writePinLow(col_pins[col]);
368 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; 192 setPinOutput(col_pins[col]);
369 for (int i = 0; i < ROWS_PER_HAND; ++i) {
370 matrix[slaveOffset+i] = 0;
371 }
372 }
373 } else {
374 error_count = 0;
375 }
376 matrix_scan_quantum();
377 return ret;
378} 193}
379 194
380void matrix_slave_scan(void) { 195static void unselect_col(uint8_t col) { setPinInputHigh(col_pins[col]); }
381 _matrix_scan();
382
383 int offset = (isLeftHand) ? 0 : ROWS_PER_HAND;
384 196
385#if defined(USE_I2C) || defined(EH) 197static void unselect_cols(void) {
386 for (int i = 0; i < ROWS_PER_HAND; ++i) { 198 for (uint8_t x = 0; x < MATRIX_COLS; x++) {
387 i2c_slave_buffer[I2C_KEYMAP_START+i] = matrix[offset+i]; 199 setPinInputHigh(col_pins[x]);
388 } 200 }
389#else // USE_SERIAL
390 // TODO: if MATRIX_COLS > 8 change to pack()
391 for (int i = 0; i < ROWS_PER_HAND; ++i) {
392 serial_s2m_buffer.smatrix[i] = matrix[offset+i];
393 }
394#endif
395 matrix_slave_scan_user();
396} 201}
397 202
398bool matrix_is_modified(void) 203static void init_pins(void) {
399{ 204 unselect_cols();
400 if (debouncing) return false; 205 for (uint8_t x = 0; x < ROWS_PER_HAND; x++) {
401 return true; 206 setPinInputHigh(row_pins[x]);
207 }
402} 208}
403 209
404inline 210static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
405bool matrix_is_on(uint8_t row, uint8_t col) 211 bool matrix_changed = false;
406{
407 return (matrix[row] & ((matrix_row_t)1<<col));
408}
409 212
410inline 213 // Select col and wait for col selecton to stabilize
411matrix_row_t matrix_get_row(uint8_t row) 214 select_col(current_col);
412{ 215 wait_us(30);
413 return matrix[row]; 216
414} 217 // For each row...
218 for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) {
219 // Store last value of row prior to reading
220 matrix_row_t last_row_value = current_matrix[row_index];
415 221
416void matrix_print(void) 222 // Check row pin state
417{ 223 if (readPin(row_pins[row_index])) {
418 print("\nr/c 0123456789ABCDEF\n"); 224 // Pin HI, clear col bit
419 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 225 current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
420 phex(row); print(": "); 226 } else {
421 pbin_reverse16(matrix_get_row(row)); 227 // Pin LO, set col bit
422 print("\n"); 228 current_matrix[row_index] |= (ROW_SHIFTER << current_col);
423 } 229 }
424}
425 230
426uint8_t matrix_key_count(void) 231 // Determine if the matrix changed state
427{ 232 if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) {
428 uint8_t count = 0; 233 matrix_changed = true;
429 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
430 count += bitpop16(matrix[i]);
431 } 234 }
432 return count; 235 }
433}
434 236
435#if (DIODE_DIRECTION == COL2ROW) 237 // Unselect col
238 unselect_col(current_col);
436 239
437static void init_cols(void) 240 return matrix_changed;
438{
439 for(uint8_t x = 0; x < MATRIX_COLS; x++) {
440 setPinInputHigh(col_pins[x]);
441 }
442} 241}
443 242
444static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) 243#endif
445{
446 // Store last value of row prior to reading
447 matrix_row_t last_row_value = current_matrix[current_row];
448
449 // Clear data in matrix row
450 current_matrix[current_row] = 0;
451 244
452 // Select row and wait for row selecton to stabilize 245void matrix_init(void) {
453 select_row(current_row); 246 debug_enable = true;
454 wait_us(30); 247 debug_matrix = true;
248 debug_mouse = true;
455 249
456 // For each col... 250 // Set pinout for right half if pinout for that half is defined
457 for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 251 if (!isLeftHand) {
458 // Populate the matrix row with the state of the col pin 252#ifdef MATRIX_ROW_PINS_RIGHT
459 current_matrix[current_row] |= readPin(col_pins[col_index]) ? 0 : (ROW_SHIFTER << col_index); 253 const uint8_t row_pins_right[MATRIX_ROWS] = MATRIX_ROW_PINS_RIGHT;
254 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
255 row_pins[i] = row_pins_right[i];
460 } 256 }
257#endif
258#ifdef MATRIX_COL_PINS_RIGHT
259 const uint8_t col_pins_right[MATRIX_COLS] = MATRIX_COL_PINS_RIGHT;
260 for (uint8_t i = 0; i < MATRIX_COLS; i++) {
261 col_pins[i] = col_pins_right[i];
262 }
263#endif
264 }
461 265
462 // Unselect row 266 thisHand = isLeftHand ? 0 : (ROWS_PER_HAND);
463 unselect_row(current_row); 267 thatHand = ROWS_PER_HAND - thisHand;
464 268
465 return (last_row_value != current_matrix[current_row]); 269 // initialize key pins
466} 270 init_pins();
467 271
468static void select_row(uint8_t row) 272 // initialize matrix state: all keys off
469{ 273 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
470 writePinLow(row_pins[row]); 274 matrix[i] = 0;
471 setPinOutput(row_pins[row]); 275 }
472}
473 276
474static void unselect_row(uint8_t row) 277 debounce_init(ROWS_PER_HAND);
475{
476 setPinInputHigh(row_pins[row]);
477}
478 278
479static void unselect_rows(void) 279 matrix_init_quantum();
480{
481 for(uint8_t x = 0; x < ROWS_PER_HAND; x++) {
482 setPinInputHigh(row_pins[x]);
483 }
484} 280}
485 281
282uint8_t _matrix_scan(void) {
283 bool changed = false;
284
285#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW)
286 // Set row, read cols
287 for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) {
288 changed |= read_cols_on_row(raw_matrix, current_row);
289 }
486#elif (DIODE_DIRECTION == ROW2COL) 290#elif (DIODE_DIRECTION == ROW2COL)
291 // Set col, read rows
292 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
293 changed |= read_rows_on_col(raw_matrix, current_col);
294 }
295#endif
487 296
488static void init_rows(void) 297 debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed);
489{
490 for(uint8_t x = 0; x < ROWS_PER_HAND; x++) {
491 setPinInputHigh(row_pins[x]);
492 }
493}
494 298
495static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) 299 return 1;
496{ 300}
497 bool matrix_changed = false;
498 301
499 // Select col and wait for col selecton to stabilize 302uint8_t matrix_scan(void) {
500 select_col(current_col); 303 uint8_t ret = _matrix_scan();
501 wait_us(30);
502 304
503 // For each row... 305 if (is_keyboard_master()) {
504 for(uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) 306 static uint8_t error_count;
505 {
506 307
507 // Store last value of row prior to reading 308 if (!transport_master(matrix + thatHand)) {
508 matrix_row_t last_row_value = current_matrix[row_index]; 309 error_count++;
509 310
510 // Check row pin state 311 if (error_count > ERROR_DISCONNECT_COUNT) {
511 if (readPin(row_pins[row_index])) 312 // reset other half if disconnected
512 { 313 for (int i = 0; i < ROWS_PER_HAND; ++i) {
513 // Pin HI, clear col bit 314 matrix[thatHand + i] = 0;
514 current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
515 }
516 else
517 {
518 // Pin LO, set col bit
519 current_matrix[row_index] |= (ROW_SHIFTER << current_col);
520 }
521
522 // Determine if the matrix changed state
523 if ((last_row_value != current_matrix[row_index]) && !(matrix_changed))
524 {
525 matrix_changed = true;
526 } 315 }
316 }
317 } else {
318 error_count = 0;
527 } 319 }
528 320
529 // Unselect col 321 matrix_scan_quantum();
530 unselect_col(current_col); 322 } else {
531 323 transport_slave(matrix + thisHand);
532 return matrix_changed; 324 matrix_slave_scan_user();
533} 325 }
534
535static void select_col(uint8_t col)
536{
537 writePinLow(col_pins[col]);
538 setPinOutput(col_pins[col]);
539}
540
541static void unselect_col(uint8_t col)
542{
543 setPinInputHigh(col_pins[col]);
544}
545 326
546static void unselect_cols(void) 327 return ret;
547{
548 for(uint8_t x = 0; x < MATRIX_COLS; x++) {
549 setPinInputHigh(col_pins[x]);
550 }
551} 328}
552
553#endif