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.c309
1 files changed, 0 insertions, 309 deletions
diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c
deleted file mode 100644
index 039e7d977..000000000
--- a/quantum/split_common/matrix.c
+++ /dev/null
@@ -1,309 +0,0 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
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 "util.h"
20#include "matrix.h"
21#include "debounce.h"
22#include "quantum.h"
23#include "split_util.h"
24#include "config.h"
25#include "transport.h"
26
27#define ERROR_DISCONNECT_COUNT 5
28
29#define ROWS_PER_HAND (MATRIX_ROWS / 2)
30
31#ifdef DIRECT_PINS
32static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS;
33#elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW)
34static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
35static pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
36#endif
37
38/* matrix state(1:on, 0:off) */
39extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values
40extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values
41
42// row offsets for each hand
43uint8_t thisHand, thatHand;
44
45// user-defined overridable functions
46__attribute__((weak)) void matrix_slave_scan_kb(void) { matrix_slave_scan_user(); }
47__attribute__((weak)) void matrix_slave_scan_user(void) {}
48
49static inline void setPinOutput_writeLow(pin_t pin) {
50 ATOMIC_BLOCK_FORCEON {
51 setPinOutput(pin);
52 writePinLow(pin);
53 }
54}
55
56static inline void setPinInputHigh_atomic(pin_t pin) {
57 ATOMIC_BLOCK_FORCEON { setPinInputHigh(pin); }
58}
59
60// matrix code
61
62#ifdef DIRECT_PINS
63
64static void init_pins(void) {
65 for (int row = 0; row < MATRIX_ROWS; row++) {
66 for (int col = 0; col < MATRIX_COLS; col++) {
67 pin_t pin = direct_pins[row][col];
68 if (pin != NO_PIN) {
69 setPinInputHigh(pin);
70 }
71 }
72 }
73}
74
75static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
76 // Start with a clear matrix row
77 matrix_row_t current_row_value = 0;
78
79 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
80 pin_t pin = direct_pins[current_row][col_index];
81 if (pin != NO_PIN) {
82 current_row_value |= readPin(pin) ? 0 : (MATRIX_ROW_SHIFTER << col_index);
83 }
84 }
85
86 // If the row has changed, store the row and return the changed flag.
87 if (current_matrix[current_row] != current_row_value) {
88 current_matrix[current_row] = current_row_value;
89 return true;
90 }
91 return false;
92}
93
94#elif defined(DIODE_DIRECTION)
95# if (DIODE_DIRECTION == COL2ROW)
96
97static void select_row(uint8_t row) { setPinOutput_writeLow(row_pins[row]); }
98
99static void unselect_row(uint8_t row) { setPinInputHigh_atomic(row_pins[row]); }
100
101static void unselect_rows(void) {
102 for (uint8_t x = 0; x < ROWS_PER_HAND; x++) {
103 setPinInputHigh_atomic(row_pins[x]);
104 }
105}
106
107static void init_pins(void) {
108 unselect_rows();
109 for (uint8_t x = 0; x < MATRIX_COLS; x++) {
110 setPinInputHigh_atomic(col_pins[x]);
111 }
112}
113
114static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
115 // Start with a clear matrix row
116 matrix_row_t current_row_value = 0;
117
118 // Select row
119 select_row(current_row);
120 matrix_output_select_delay();
121
122 // For each col...
123 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
124 // Select the col pin to read (active low)
125 uint8_t pin_state = readPin(col_pins[col_index]);
126
127 // Populate the matrix row with the state of the col pin
128 current_row_value |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index);
129 }
130
131 // Unselect row
132 unselect_row(current_row);
133 matrix_output_unselect_delay(); // wait for all Col signals to go HIGH
134
135 // If the row has changed, store the row and return the changed flag.
136 if (current_matrix[current_row] != current_row_value) {
137 current_matrix[current_row] = current_row_value;
138 return true;
139 }
140 return false;
141}
142
143# elif (DIODE_DIRECTION == ROW2COL)
144
145static void select_col(uint8_t col) { setPinOutput_writeLow(col_pins[col]); }
146
147static void unselect_col(uint8_t col) { setPinInputHigh_atomic(col_pins[col]); }
148
149static void unselect_cols(void) {
150 for (uint8_t x = 0; x < MATRIX_COLS; x++) {
151 setPinInputHigh_atomic(col_pins[x]);
152 }
153}
154
155static void init_pins(void) {
156 unselect_cols();
157 for (uint8_t x = 0; x < ROWS_PER_HAND; x++) {
158 setPinInputHigh_atomic(row_pins[x]);
159 }
160}
161
162static bool 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(current_col);
167 matrix_output_select_delay();
168
169 // For each row...
170 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
176 if (readPin(row_pins[row_index]) == 0) {
177 // Pin LO, set col bit
178 current_row_value |= (MATRIX_ROW_SHIFTER << current_col);
179 } else {
180 // Pin HI, clear col bit
181 current_row_value &= ~(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 }
189 }
190
191 // Unselect col
192 unselect_col(current_col);
193 matrix_output_unselect_delay(); // wait for all Row signals to go HIGH
194
195 return matrix_changed;
196}
197
198# else
199# error DIODE_DIRECTION must be one of COL2ROW or ROW2COL!
200# endif
201#else
202# error DIODE_DIRECTION is not defined!
203#endif
204
205void matrix_init(void) {
206 split_pre_init();
207
208 // Set pinout for right half if pinout for that half is defined
209 if (!isLeftHand) {
210#ifdef DIRECT_PINS_RIGHT
211 const pin_t direct_pins_right[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS_RIGHT;
212 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
213 for (uint8_t j = 0; j < MATRIX_COLS; j++) {
214 direct_pins[i][j] = direct_pins_right[i][j];
215 }
216 }
217#endif
218#ifdef MATRIX_ROW_PINS_RIGHT
219 const pin_t row_pins_right[MATRIX_ROWS] = MATRIX_ROW_PINS_RIGHT;
220 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
221 row_pins[i] = row_pins_right[i];
222 }
223#endif
224#ifdef MATRIX_COL_PINS_RIGHT
225 const pin_t col_pins_right[MATRIX_COLS] = MATRIX_COL_PINS_RIGHT;
226 for (uint8_t i = 0; i < MATRIX_COLS; i++) {
227 col_pins[i] = col_pins_right[i];
228 }
229#endif
230 }
231
232 thisHand = isLeftHand ? 0 : (ROWS_PER_HAND);
233 thatHand = ROWS_PER_HAND - thisHand;
234
235 // initialize key pins
236 init_pins();
237
238 // initialize matrix state: all keys off
239 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
240 raw_matrix[i] = 0;
241 matrix[i] = 0;
242 }
243
244 debounce_init(ROWS_PER_HAND);
245
246 matrix_init_quantum();
247
248 split_post_init();
249}
250
251bool matrix_post_scan(void) {
252 bool changed = false;
253 if (is_keyboard_master()) {
254 static uint8_t error_count;
255
256 matrix_row_t slave_matrix[ROWS_PER_HAND] = {0};
257 if (!transport_master(matrix + thisHand, slave_matrix)) {
258 error_count++;
259
260 if (error_count > ERROR_DISCONNECT_COUNT) {
261 // reset other half if disconnected
262 for (int i = 0; i < ROWS_PER_HAND; ++i) {
263 matrix[thatHand + i] = 0;
264 slave_matrix[i] = 0;
265 }
266
267 changed = true;
268 }
269 } else {
270 error_count = 0;
271
272 for (int i = 0; i < ROWS_PER_HAND; ++i) {
273 if (matrix[thatHand + i] != slave_matrix[i]) {
274 matrix[thatHand + i] = slave_matrix[i];
275 changed = true;
276 }
277 }
278 }
279
280 matrix_scan_quantum();
281 } else {
282 transport_slave(matrix + thatHand, matrix + thisHand);
283
284 matrix_slave_scan_kb();
285 }
286
287 return changed;
288}
289
290uint8_t matrix_scan(void) {
291 bool local_changed = false;
292
293#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW)
294 // Set row, read cols
295 for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) {
296 local_changed |= read_cols_on_row(raw_matrix, current_row);
297 }
298#elif (DIODE_DIRECTION == ROW2COL)
299 // Set col, read rows
300 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
301 local_changed |= read_rows_on_col(raw_matrix, current_col);
302 }
303#endif
304
305 debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, local_changed);
306
307 bool remote_changed = matrix_post_scan();
308 return (uint8_t)(local_changed || remote_changed);
309}