aboutsummaryrefslogtreecommitdiff
path: root/keyboards/ai03/orbit/matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/ai03/orbit/matrix.c')
-rw-r--r--keyboards/ai03/orbit/matrix.c328
1 files changed, 328 insertions, 0 deletions
diff --git a/keyboards/ai03/orbit/matrix.c b/keyboards/ai03/orbit/matrix.c
new file mode 100644
index 000000000..b8e329668
--- /dev/null
+++ b/keyboards/ai03/orbit/matrix.c
@@ -0,0 +1,328 @@
1/*
2Copyright 2012 Jun Wako <[email protected]>
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
18/*
19 * scan matrix
20 */
21#include <stdint.h>
22#include <stdbool.h>
23#include "wait.h"
24#include "util.h"
25#include "matrix.h"
26#include "split_util.h"
27#include "config.h"
28#include "split_flags.h"
29#include "quantum.h"
30#include "debounce.h"
31#include "transport.h"
32
33#if (MATRIX_COLS <= 8)
34# define print_matrix_header() print("\nr/c 01234567\n")
35# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
36# define matrix_bitpop(i) bitpop(matrix[i])
37# define ROW_SHIFTER ((uint8_t)1)
38#elif (MATRIX_COLS <= 16)
39# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
40# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
41# define matrix_bitpop(i) bitpop16(matrix[i])
42# define ROW_SHIFTER ((uint16_t)1)
43#elif (MATRIX_COLS <= 32)
44# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
45# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
46# define matrix_bitpop(i) bitpop32(matrix[i])
47# define ROW_SHIFTER ((uint32_t)1)
48#endif
49
50#define ERROR_DISCONNECT_COUNT 5
51
52//#define ROWS_PER_HAND (MATRIX_ROWS / 2)
53
54#ifdef DIRECT_PINS
55static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS;
56#else
57static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
58static pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
59#endif
60
61/* matrix state(1:on, 0:off) */
62static matrix_row_t matrix[MATRIX_ROWS];
63static matrix_row_t raw_matrix[ROWS_PER_HAND];
64
65// row offsets for each hand
66uint8_t thisHand, thatHand;
67
68// user-defined overridable functions
69
70__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); }
71
72__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); }
73
74__attribute__((weak)) void matrix_init_user(void) {}
75
76__attribute__((weak)) void matrix_scan_user(void) {}
77
78__attribute__((weak)) void matrix_slave_scan_user(void) {}
79
80// helper functions
81
82inline uint8_t matrix_rows(void) { return MATRIX_ROWS; }
83
84inline uint8_t matrix_cols(void) { return MATRIX_COLS; }
85
86bool matrix_is_modified(void) {
87 if (debounce_active()) return false;
88 return true;
89}
90
91inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); }
92
93inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; }
94
95void matrix_print(void) {
96 print_matrix_header();
97
98 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
99 print_hex8(row);
100 print(": ");
101 print_matrix_row(row);
102 print("\n");
103 }
104}
105
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;
112}
113
114// matrix code
115
116#ifdef DIRECT_PINS
117
118static void init_pins(void) {
119 for (int row = 0; row < MATRIX_ROWS; row++) {
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}
128
129static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
130 matrix_row_t last_row_value = current_matrix[current_row];
131 current_matrix[current_row] = 0;
132
133 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
134 pin_t pin = direct_pins[current_row][col_index];
135 if (pin != NO_PIN) {
136 current_matrix[current_row] |= readPin(pin) ? 0 : (ROW_SHIFTER << col_index);
137 }
138 }
139
140 return (last_row_value != current_matrix[current_row]);
141}
142
143#elif (DIODE_DIRECTION == COL2ROW)
144
145static void select_row(uint8_t row) {
146 setPinOutput(row_pins[row]);
147 writePinLow(row_pins[row]);
148}
149
150static void unselect_row(uint8_t row) { setPinInputHigh(row_pins[row]); }
151
152static void unselect_rows(void) {
153 for (uint8_t x = 0; x < ROWS_PER_HAND; x++) {
154 setPinInputHigh(row_pins[x]);
155 }
156}
157
158static void init_pins(void) {
159 unselect_rows();
160 for (uint8_t x = 0; x < MATRIX_COLS; x++) {
161 setPinInputHigh(col_pins[x]);
162 }
163}
164
165static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
166 // Store last value of row prior to reading
167 matrix_row_t last_row_value = current_matrix[current_row];
168
169 // Clear data in matrix row
170 current_matrix[current_row] = 0;
171
172 // Select row and wait for row selecton to stabilize
173 select_row(current_row);
174 wait_us(30);
175
176 // For each col...
177 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
178 // Populate the matrix row with the state of the col pin
179 current_matrix[current_row] |= readPin(col_pins[col_index]) ? 0 : (ROW_SHIFTER << col_index);
180 }
181
182 // Unselect row
183 unselect_row(current_row);
184
185 return (last_row_value != current_matrix[current_row]);
186}
187
188#elif (DIODE_DIRECTION == ROW2COL)
189
190static void select_col(uint8_t col) {
191 setPinOutput(col_pins[col]);
192 writePinLow(col_pins[col]);
193}
194
195static void unselect_col(uint8_t col) { setPinInputHigh(col_pins[col]); }
196
197static void unselect_cols(void) {
198 for (uint8_t x = 0; x < MATRIX_COLS; x++) {
199 setPinInputHigh(col_pins[x]);
200 }
201}
202
203static void init_pins(void) {
204 unselect_cols();
205 for (uint8_t x = 0; x < ROWS_PER_HAND; x++) {
206 setPinInputHigh(row_pins[x]);
207 }
208}
209
210static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
211 bool matrix_changed = false;
212
213 // Select col and wait for col selecton to stabilize
214 select_col(current_col);
215 wait_us(30);
216
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];
221
222 // Check row pin state
223 if (readPin(row_pins[row_index])) {
224 // Pin HI, clear col bit
225 current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
226 } else {
227 // Pin LO, set col bit
228 current_matrix[row_index] |= (ROW_SHIFTER << current_col);
229 }
230
231 // Determine if the matrix changed state
232 if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) {
233 matrix_changed = true;
234 }
235 }
236
237 // Unselect col
238 unselect_col(current_col);
239
240 return matrix_changed;
241}
242
243#endif
244
245void matrix_init(void) {
246 debug_enable = true;
247 debug_matrix = true;
248 debug_mouse = true;
249
250 // Set pinout for right half if pinout for that half is defined
251 if (!isLeftHand) {
252#ifdef MATRIX_ROW_PINS_RIGHT
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];
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 }
265
266 thisHand = isLeftHand ? 0 : (ROWS_PER_HAND);
267 thatHand = ROWS_PER_HAND - thisHand;
268
269 // initialize key pins
270 init_pins();
271
272 // initialize matrix state: all keys off
273 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
274 matrix[i] = 0;
275 }
276
277 debounce_init(ROWS_PER_HAND);
278
279 matrix_init_quantum();
280}
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 }
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
296
297 debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed);
298
299 return 1;
300}
301
302uint8_t matrix_scan(void) {
303 uint8_t ret = _matrix_scan();
304
305 if (is_keyboard_master()) {
306 static uint8_t error_count;
307
308 if (!transport_master(matrix + thatHand)) {
309 error_count++;
310
311 if (error_count > ERROR_DISCONNECT_COUNT) {
312 // reset other half if disconnected
313 for (int i = 0; i < ROWS_PER_HAND; ++i) {
314 matrix[thatHand + i] = 0;
315 }
316 }
317 } else {
318 error_count = 0;
319 }
320
321 matrix_scan_quantum();
322 } else {
323 transport_slave(matrix + thisHand);
324 matrix_slave_scan_user();
325 }
326
327 return ret;
328}