aboutsummaryrefslogtreecommitdiff
path: root/keyboards/wasdat/matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/wasdat/matrix.c')
-rw-r--r--keyboards/wasdat/matrix.c484
1 files changed, 484 insertions, 0 deletions
diff --git a/keyboards/wasdat/matrix.c b/keyboards/wasdat/matrix.c
new file mode 100644
index 000000000..b481e5394
--- /dev/null
+++ b/keyboards/wasdat/matrix.c
@@ -0,0 +1,484 @@
1/*
2Copyright 2012-2018 Jun Wako, Jack Humbert, Yiancar
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include <stdint.h>
18#include <stdbool.h>
19#include "wait.h"
20#include "print.h"
21#include "debug.h"
22#include "util.h"
23#include "matrix.h"
24#include "debounce.h"
25#include "quantum.h"
26
27#if (MATRIX_COLS <= 8)
28# define print_matrix_header() print("\nr/c 01234567\n")
29# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
30# define matrix_bitpop(i) bitpop(matrix[i])
31# define ROW_SHIFTER ((uint8_t)1)
32#elif (MATRIX_COLS <= 16)
33# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
34# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
35# define matrix_bitpop(i) bitpop16(matrix[i])
36# define ROW_SHIFTER ((uint16_t)1)
37#elif (MATRIX_COLS <= 32)
38# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
39# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
40# define matrix_bitpop(i) bitpop32(matrix[i])
41# define ROW_SHIFTER ((uint32_t)1)
42#endif
43
44#ifdef MATRIX_MASKED
45 extern const matrix_row_t matrix_mask[];
46#endif
47
48#ifdef DIRECT_PINS
49static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS;
50#elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW)
51static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
52//static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
53#endif
54
55/* matrix state(1:on, 0:off) */
56static matrix_row_t raw_matrix[MATRIX_ROWS]; //raw values
57static matrix_row_t matrix[MATRIX_ROWS]; //debounced values
58
59__attribute__ ((weak))
60void matrix_init_quantum(void) {
61 matrix_init_kb();
62}
63
64__attribute__ ((weak))
65void matrix_scan_quantum(void) {
66 matrix_scan_kb();
67}
68
69__attribute__ ((weak))
70void matrix_init_kb(void) {
71 matrix_init_user();
72}
73
74__attribute__ ((weak))
75void matrix_scan_kb(void) {
76 matrix_scan_user();
77}
78
79__attribute__ ((weak))
80void matrix_init_user(void) {
81}
82
83__attribute__ ((weak))
84void matrix_scan_user(void) {
85}
86
87inline
88uint8_t matrix_rows(void) {
89 return MATRIX_ROWS;
90}
91
92inline
93uint8_t matrix_cols(void) {
94 return MATRIX_COLS;
95}
96
97//Deprecated.
98bool matrix_is_modified(void)
99{
100 if (debounce_active()) return false;
101 return true;
102}
103
104inline
105bool matrix_is_on(uint8_t row, uint8_t col)
106{
107 return (matrix[row] & ((matrix_row_t)1<<col));
108}
109
110inline
111matrix_row_t matrix_get_row(uint8_t row)
112{
113 // Matrix mask lets you disable switches in the returned matrix data. For example, if you have a
114 // switch blocker installed and the switch is always pressed.
115#ifdef MATRIX_MASKED
116 return matrix[row] & matrix_mask[row];
117#else
118 return matrix[row];
119#endif
120}
121
122void matrix_print(void)
123{
124 print_matrix_header();
125
126 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
127 phex(row); print(": ");
128 print_matrix_row(row);
129 print("\n");
130 }
131}
132
133uint8_t matrix_key_count(void)
134{
135 uint8_t count = 0;
136 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
137 count += matrix_bitpop(i);
138 }
139 return count;
140}
141
142
143#ifdef DIRECT_PINS
144
145static void init_pins(void) {
146 for (int row = 0; row < MATRIX_ROWS; row++) {
147 for (int col = 0; col < MATRIX_COLS; col++) {
148 pin_t pin = direct_pins[row][col];
149 if (pin != NO_PIN) {
150 setPinInputHigh(pin);
151 }
152 }
153 }
154}
155
156static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
157 matrix_row_t last_row_value = current_matrix[current_row];
158 current_matrix[current_row] = 0;
159
160 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
161 pin_t pin = direct_pins[current_row][col_index];
162 if (pin != NO_PIN) {
163 current_matrix[current_row] |= readPin(pin) ? 0 : (ROW_SHIFTER << col_index);
164 }
165 }
166
167 return (last_row_value != current_matrix[current_row]);
168}
169
170#elif (DIODE_DIRECTION == COL2ROW)
171
172static void select_row(uint8_t row)
173{
174 setPinOutput(row_pins[row]);
175 writePinLow(row_pins[row]);
176}
177
178static void unselect_row(uint8_t row)
179{
180 setPinInputHigh(row_pins[row]);
181}
182
183static void unselect_rows(void)
184{
185 for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
186 setPinInput(row_pins[x]);
187 }
188}
189
190static void init_pins(void) {
191 unselect_rows();
192 for (uint8_t x = 0; x < MATRIX_COLS; x++) {
193 setPinInputHigh(col_pins[x]);
194 }
195}
196
197static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
198{
199 // Store last value of row prior to reading
200 matrix_row_t last_row_value = current_matrix[current_row];
201
202 // Clear data in matrix row
203 current_matrix[current_row] = 0;
204
205 // Select row and wait for row selecton to stabilize
206 select_row(current_row);
207 wait_us(30);
208
209 // For each col...
210 for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
211
212 // Select the col pin to read (active low)
213 uint8_t pin_state = readPin(col_pins[col_index]);
214
215 // Populate the matrix row with the state of the col pin
216 current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index);
217 }
218
219 // Unselect row
220 unselect_row(current_row);
221
222 return (last_row_value != current_matrix[current_row]);
223}
224
225#elif (DIODE_DIRECTION == ROW2COL)
226
227/* Cols 0 - 15
228 * col 0: C7
229 * col 1: B6
230 * col 2: C6
231 * col 3: B4
232 * col 4: B5
233 * col 5: D7
234 * These columns use a 74HC237D 3 to 8 bit demultiplexer.
235 * A0 A1 A2
236 * col / pin: PD2 PD1 PD0
237 * 6: 1 1 1
238 * 7: 0 1 1
239 * 8: 1 0 1
240 * 9: 0 0 1
241 * 10: 1 1 0
242 * 11: 0 1 0
243 * 12: 1 0 0
244 * col 13: D3
245 * col 14: B7
246 * col 15: B3
247 */
248static void select_col(uint8_t col)
249{
250 switch (col) {
251 case 0:
252 writePinLow(C7);
253 break;
254 case 1:
255 writePinLow(B6);
256 break;
257 case 2:
258 writePinLow(C6);
259 break;
260 case 3:
261 writePinLow(B4);
262 break;
263 case 4:
264 writePinLow(B5);
265 break;
266 case 5:
267 writePinLow(D7);
268 break;
269 case 6:
270 writePinHigh(D0);
271 writePinHigh(D1);
272 writePinHigh(D2);
273 break;
274 case 7:
275 writePinHigh(D0);
276 writePinHigh(D1);
277 break;
278 case 8:
279 writePinHigh(D0);
280 writePinHigh(D2);
281 break;
282 case 9:
283 writePinHigh(D0);
284 break;
285 case 10:
286 writePinHigh(D1);
287 writePinHigh(D2);
288 break;
289 case 11:
290 writePinHigh(D1);
291 break;
292 case 12:
293 writePinHigh(D2);
294 break;
295 case 13:
296 writePinLow(D3);
297 break;
298 case 14:
299 writePinLow(B7);
300 break;
301 case 15:
302 writePinLow(B3);
303 break;
304 }
305}
306
307static void unselect_col(uint8_t col)
308{
309 switch (col) {
310 case 0:
311 writePinHigh(C7);
312 break;
313 case 1:
314 writePinHigh(B6);
315 break;
316 case 2:
317 writePinHigh(C6);
318 break;
319 case 3:
320 writePinHigh(B4);
321 break;
322 case 4:
323 writePinHigh(B5);
324 break;
325 case 5:
326 writePinHigh(D7);
327 break;
328 case 6:
329 writePinLow(D0);
330 writePinLow(D1);
331 writePinLow(D2);
332 break;
333 case 7:
334 writePinLow(D0);
335 writePinLow(D1);
336 break;
337 case 8:
338 writePinLow(D0);
339 writePinLow(D2);
340 break;
341 case 9:
342 writePinLow(D0);
343 break;
344 case 10:
345 writePinLow(D1);
346 writePinLow(D2);
347 break;
348 case 11:
349 writePinLow(D1);
350 break;
351 case 12:
352 writePinLow(D2);
353 break;
354 case 13:
355 writePinHigh(D3);
356 break;
357 case 14:
358 writePinHigh(B7);
359 break;
360 case 15:
361 writePinHigh(B3);
362 break;
363 }
364}
365
366static void unselect_cols(void)
367{
368 //Native
369 setPinOutput(D3);
370 setPinOutput(D7);
371 writePinHigh(D3);
372 writePinHigh(D7);
373
374 setPinOutput(C6);
375 setPinOutput(C7);
376 writePinHigh(C6);
377 writePinHigh(C7);
378
379 setPinOutput(B3);
380 setPinOutput(B4);
381 setPinOutput(B5);
382 setPinOutput(B6);
383 setPinOutput(B7);
384 writePinHigh(B3);
385 writePinHigh(B4);
386 writePinHigh(B5);
387 writePinHigh(B6);
388 writePinHigh(B7);
389
390 //Demultiplexer
391 setPinOutput(D0);
392 setPinOutput(D1);
393 setPinOutput(D2);
394 writePinLow(D0);
395 writePinLow(D1);
396 writePinLow(D2);
397}
398
399static void init_pins(void) {
400 unselect_cols();
401 for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
402 setPinInputHigh(row_pins[x]);
403 }
404}
405
406static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
407{
408 bool matrix_changed = false;
409
410 // Select col and wait for col selecton to stabilize
411 select_col(current_col);
412 wait_us(30);
413
414 // For each row...
415 for(uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++)
416 {
417
418 // Store last value of row prior to reading
419 matrix_row_t last_row_value = current_matrix[row_index];
420
421 // Check row pin state
422 if (readPin(row_pins[row_index]) == 0)
423 {
424 // Pin LO, set col bit
425 current_matrix[row_index] |= (ROW_SHIFTER << current_col);
426 }
427 else
428 {
429 // Pin HI, clear col bit
430 current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
431 }
432
433 // Determine if the matrix changed state
434 if ((last_row_value != current_matrix[row_index]) && !(matrix_changed))
435 {
436 matrix_changed = true;
437 }
438 }
439
440 // Unselect col
441 unselect_col(current_col);
442
443 return matrix_changed;
444}
445
446#endif
447
448void matrix_init(void) {
449
450 // initialize key pins
451 init_pins();
452
453 // initialize matrix state: all keys off
454 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
455 raw_matrix[i] = 0;
456 matrix[i] = 0;
457 }
458
459 debounce_init(MATRIX_ROWS);
460
461 matrix_init_quantum();
462}
463
464uint8_t matrix_scan(void)
465{
466 bool changed = false;
467
468#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW)
469 // Set row, read cols
470 for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
471 changed |= read_cols_on_row(raw_matrix, current_row);
472 }
473#elif (DIODE_DIRECTION == ROW2COL)
474 // Set col, read rows
475 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
476 changed |= read_rows_on_col(raw_matrix, current_col);
477 }
478#endif
479
480 debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
481
482 matrix_scan_quantum();
483 return 1;
484}