aboutsummaryrefslogtreecommitdiff
path: root/keyboards/thedogkeyboard/matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/thedogkeyboard/matrix.c')
-rw-r--r--keyboards/thedogkeyboard/matrix.c287
1 files changed, 287 insertions, 0 deletions
diff --git a/keyboards/thedogkeyboard/matrix.c b/keyboards/thedogkeyboard/matrix.c
new file mode 100644
index 000000000..e06fc15dc
--- /dev/null
+++ b/keyboards/thedogkeyboard/matrix.c
@@ -0,0 +1,287 @@
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
48static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
49static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
50
51/* matrix state(1:on, 0:off) */
52static matrix_row_t raw_matrix[MATRIX_ROWS]; //raw values
53static matrix_row_t matrix[MATRIX_ROWS]; //debounced values
54
55__attribute__ ((weak))
56void matrix_init_quantum(void) {
57 matrix_init_kb();
58}
59
60__attribute__ ((weak))
61void matrix_scan_quantum(void) {
62 matrix_scan_kb();
63}
64
65__attribute__ ((weak))
66void matrix_init_kb(void) {
67 matrix_init_user();
68}
69
70__attribute__ ((weak))
71void matrix_scan_kb(void) {
72 matrix_scan_user();
73}
74
75__attribute__ ((weak))
76void matrix_init_user(void) {
77}
78
79__attribute__ ((weak))
80void matrix_scan_user(void) {
81}
82
83inline
84uint8_t matrix_rows(void) {
85 return MATRIX_ROWS;
86}
87
88inline
89uint8_t matrix_cols(void) {
90 return MATRIX_COLS;
91}
92
93//Deprecated.
94bool matrix_is_modified(void)
95{
96 if (debounce_active()) return false;
97 return true;
98}
99
100inline
101bool matrix_is_on(uint8_t row, uint8_t col)
102{
103 return (matrix[row] & ((matrix_row_t)1<<col));
104}
105
106inline
107matrix_row_t matrix_get_row(uint8_t row)
108{
109 // Matrix mask lets you disable switches in the returned matrix data. For example, if you have a
110 // switch blocker installed and the switch is always pressed.
111#ifdef MATRIX_MASKED
112 return matrix[row] & matrix_mask[row];
113#else
114 return matrix[row];
115#endif
116}
117
118void matrix_print(void)
119{
120 print_matrix_header();
121
122 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
123 phex(row); print(": ");
124 print_matrix_row(row);
125 print("\n");
126 }
127}
128
129uint8_t matrix_key_count(void)
130{
131 uint8_t count = 0;
132 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
133 count += matrix_bitpop(i);
134 }
135 return count;
136}
137
138static void select_row(uint8_t row)
139{
140 setPinOutput(row_pins[row]);
141 writePinLow(row_pins[row]);
142}
143
144static void unselect_row(uint8_t row)
145{
146 setPinInputHigh(row_pins[row]);
147}
148
149static void unselect_rows(void)
150{
151 for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
152 setPinInputHigh(row_pins[x]);
153 }
154}
155
156static void select_col(uint8_t col)
157{
158 setPinOutput(col_pins[col]);
159 writePinLow(col_pins[col]);
160}
161
162static void unselect_col(uint8_t col)
163{
164 setPinInputHigh(col_pins[col]);
165}
166
167static void unselect_cols(void)
168{
169 for(uint8_t x = 0; x < MATRIX_COLS; x++) {
170 setPinInputHigh(col_pins[x]);
171 }
172}
173
174static void init_pins(void) {
175 unselect_rows();
176 unselect_cols();
177 for (uint8_t x = 0; x < MATRIX_COLS; x++) {
178 setPinInputHigh(col_pins[x]);
179 }
180 for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
181 setPinInputHigh(row_pins[x]);
182 }
183}
184
185static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
186{
187 // Store last value of row prior to reading
188 matrix_row_t last_row_value = current_matrix[current_row];
189
190 // Clear data in matrix row
191 current_matrix[current_row] = 0;
192
193 // Select row and wait for row selecton to stabilize
194 select_row(current_row);
195 wait_us(30);
196
197 // For each col...
198 for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
199
200 // Select the col pin to read (active low)
201 uint8_t pin_state = readPin(col_pins[col_index]);
202
203 // Populate the matrix row with the state of the col pin
204 current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index);
205 }
206
207 // Unselect row
208 unselect_row(current_row);
209
210 return (last_row_value != current_matrix[current_row]);
211}
212
213static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
214{
215 bool matrix_changed = false;
216
217 // Select col and wait for col selecton to stabilize
218 select_col(current_col);
219 wait_us(30);
220
221 // For each row...
222 for(uint8_t row_index = 0; row_index < MATRIX_ROWS/2; row_index++)
223 {
224 uint8_t tmp = row_index + MATRIX_ROWS/2;
225 // Store last value of row prior to reading
226 matrix_row_t last_row_value = current_matrix[tmp];
227
228 // Check row pin state
229 if (readPin(row_pins[row_index]) == 0)
230 {
231 // Pin LO, set col bit
232 current_matrix[tmp] |= (ROW_SHIFTER << current_col);
233 }
234 else
235 {
236 // Pin HI, clear col bit
237 current_matrix[tmp] &= ~(ROW_SHIFTER << current_col);
238 }
239
240 // Determine if the matrix changed state
241 if ((last_row_value != current_matrix[tmp]) && !(matrix_changed))
242 {
243 matrix_changed = true;
244 }
245 }
246
247 // Unselect col
248 unselect_col(current_col);
249
250 return matrix_changed;
251}
252
253void matrix_init(void) {
254
255 // initialize key pins
256 init_pins();
257
258 // initialize matrix state: all keys off
259 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
260 raw_matrix[i] = 0;
261 matrix[i] = 0;
262 }
263
264 debounce_init(MATRIX_ROWS);
265
266 matrix_init_quantum();
267}
268
269uint8_t matrix_scan(void)
270{
271 bool changed = false;
272
273 // Set row, read cols
274 for (uint8_t current_row = 0; current_row < MATRIX_ROWS / 2; current_row++) {
275 changed |= read_cols_on_row(raw_matrix, current_row);
276 }
277 //else
278 // Set col, read rows
279 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
280 changed |= read_rows_on_col(raw_matrix, current_col);
281 }
282
283 debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
284
285 matrix_scan_quantum();
286 return (uint8_t)changed;
287}