diff options
author | IBNobody <protospherex@gmail.com> | 2016-10-28 14:21:38 -0500 |
---|---|---|
committer | IBNobody <protospherex@gmail.com> | 2016-10-28 14:21:38 -0500 |
commit | 508eddf8ba8548d3f71e1c09a404839beb49f45c (patch) | |
tree | f6791e63d391c82814219b6e9fa255c16d164e08 /quantum/matrix.c | |
parent | a0fdb6b81aa33c493bc4fccab178fcbe02231578 (diff) | |
download | qmk_firmware-508eddf8ba8548d3f71e1c09a404839beb49f45c.tar.gz qmk_firmware-508eddf8ba8548d3f71e1c09a404839beb49f45c.zip |
Fixing Debounce - WIP
Diffstat (limited to 'quantum/matrix.c')
-rw-r--r-- | quantum/matrix.c | 246 |
1 files changed, 163 insertions, 83 deletions
diff --git a/quantum/matrix.c b/quantum/matrix.c index ac81794e5..a7dab0987 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c | |||
@@ -26,6 +26,33 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
26 | #include "util.h" | 26 | #include "util.h" |
27 | #include "matrix.h" | 27 | #include "matrix.h" |
28 | 28 | ||
29 | #if (MATRIX_COLS <= 8) | ||
30 | # define print_matrix_header() print("\nr/c 01234567\n") | ||
31 | # define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row)) | ||
32 | # define matrix_bitpop(i) bitpop(matrix[i]) | ||
33 | # define ROW_SHIFTER ((uint8_t)1) | ||
34 | #elif (MATRIX_COLS <= 16) | ||
35 | # define print_matrix_header() print("\nr/c 0123456789ABCDEF\n") | ||
36 | # define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row)) | ||
37 | # define matrix_bitpop(i) bitpop16(matrix[i]) | ||
38 | # define ROW_SHIFTER ((uint16_t)1) | ||
39 | #elif (MATRIX_COLS <= 32) | ||
40 | # define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n") | ||
41 | # define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row)) | ||
42 | # define matrix_bitpop(i) bitpop32(matrix[i]) | ||
43 | # define ROW_SHIFTER ((uint32_t)1) | ||
44 | #endif | ||
45 | |||
46 | #if (MATRIX_ROWS <= 8) | ||
47 | # define COL_SHIFTER ((uint8_t)1) | ||
48 | #elif (MATRIX_ROWS <= 16) | ||
49 | # define COL_SHIFTER ((uint16_t)1) | ||
50 | #elif (MATRIX_ROWS <= 32) | ||
51 | # define COL_SHIFTER ((uint32_t)1) | ||
52 | #endif | ||
53 | |||
54 | |||
55 | |||
29 | #ifdef MATRIX_MASKED | 56 | #ifdef MATRIX_MASKED |
30 | extern const matrix_row_t matrix_mask[]; | 57 | extern const matrix_row_t matrix_mask[]; |
31 | #endif | 58 | #endif |
@@ -42,24 +69,28 @@ static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; | |||
42 | 69 | ||
43 | /* matrix state(1:on, 0:off) */ | 70 | /* matrix state(1:on, 0:off) */ |
44 | static matrix_row_t matrix[MATRIX_ROWS]; | 71 | static matrix_row_t matrix[MATRIX_ROWS]; |
45 | static matrix_row_t matrix_debouncing[MATRIX_ROWS]; | ||
46 | 72 | ||
47 | #if DIODE_DIRECTION == ROW2COL | 73 | #if DIODE_DIRECTION == COL2ROW |
48 | static matrix_row_t matrix_reversed[MATRIX_COLS]; | 74 | static matrix_row_t matrix_debouncing[MATRIX_ROWS]; |
49 | static matrix_row_t matrix_reversed_debouncing[MATRIX_COLS]; | 75 | #else // ROW2COL |
76 | static matrix_col_t matrix_transposed[MATRIX_COLS]; | ||
77 | static matrix_col_t matrix_transposed_debouncing[MATRIX_COLS]; | ||
50 | #endif | 78 | #endif |
51 | 79 | ||
52 | #if MATRIX_COLS > 16 | 80 | #if (DIODE_DIRECTION == COL2ROW) |
53 | #define SHIFTER 1UL | 81 | static void init_cols(void); |
54 | #else | 82 | static matrix_row_t read_cols(void); |
55 | #define SHIFTER 1 | 83 | static void unselect_rows(void); |
84 | static void select_row(uint8_t row); | ||
85 | static void unselect_row(uint8_t row); | ||
86 | #else // ROW2COL | ||
87 | static void init_rows(void); | ||
88 | static matrix_col_t read_rows(void); | ||
89 | static void unselect_cols(void); | ||
90 | static void unselect_col(uint8_t col); | ||
91 | static void select_col(uint8_t col); | ||
56 | #endif | 92 | #endif |
57 | 93 | ||
58 | static matrix_row_t read_cols(void); | ||
59 | static void init_cols(void); | ||
60 | static void unselect_rows(void); | ||
61 | static void select_row(uint8_t row); | ||
62 | |||
63 | __attribute__ ((weak)) | 94 | __attribute__ ((weak)) |
64 | void matrix_init_quantum(void) { | 95 | void matrix_init_quantum(void) { |
65 | matrix_init_kb(); | 96 | matrix_init_kb(); |
@@ -99,7 +130,7 @@ uint8_t matrix_cols(void) { | |||
99 | } | 130 | } |
100 | 131 | ||
101 | // void matrix_power_up(void) { | 132 | // void matrix_power_up(void) { |
102 | // #if DIODE_DIRECTION == COL2ROW | 133 | // #if (DIODE_DIRECTION == COL2ROW) |
103 | // for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { | 134 | // for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { |
104 | // /* DDRxn */ | 135 | // /* DDRxn */ |
105 | // _SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF); | 136 | // _SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF); |
@@ -123,13 +154,15 @@ uint8_t matrix_cols(void) { | |||
123 | // } | 154 | // } |
124 | 155 | ||
125 | void matrix_init(void) { | 156 | void matrix_init(void) { |
157 | |||
126 | // To use PORTF disable JTAG with writing JTD bit twice within four cycles. | 158 | // To use PORTF disable JTAG with writing JTD bit twice within four cycles. |
127 | #ifdef __AVR_ATmega32U4__ | 159 | #if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega32U4__)) |
128 | MCUCR |= _BV(JTD); | 160 | MCUCR |= _BV(JTD); |
129 | MCUCR |= _BV(JTD); | 161 | MCUCR |= _BV(JTD); |
130 | #endif | 162 | #endif |
131 | 163 | ||
132 | // initialize row and col | 164 | // initialize row and col |
165 | #if (DIODE_DIRECTION == COL2ROW) | ||
133 | unselect_rows(); | 166 | unselect_rows(); |
134 | init_cols(); | 167 | init_cols(); |
135 | 168 | ||
@@ -139,25 +172,43 @@ void matrix_init(void) { | |||
139 | matrix_debouncing[i] = 0; | 172 | matrix_debouncing[i] = 0; |
140 | } | 173 | } |
141 | 174 | ||
175 | #else // ROW2COL | ||
176 | unselect_cols(); | ||
177 | init_rows(); | ||
178 | |||
179 | // initialize matrix state: all keys off | ||
180 | for (uint8_t i=0; i < MATRIX_ROWS; i++) { | ||
181 | matrix[i] = 0; | ||
182 | } | ||
183 | |||
184 | // initialize matrix state: all keys off | ||
185 | for (uint8_t i=0; i < MATRIX_COLS; i++) { | ||
186 | matrix_transposed_debouncing[i] = 0; | ||
187 | } | ||
188 | #endif | ||
189 | |||
142 | matrix_init_quantum(); | 190 | matrix_init_quantum(); |
143 | } | 191 | } |
144 | 192 | ||
145 | uint8_t matrix_scan(void) | 193 | uint8_t matrix_scan(void) |
146 | { | 194 | { |
147 | 195 | ||
148 | #if DIODE_DIRECTION == COL2ROW | 196 | #if (DIODE_DIRECTION == COL2ROW) |
197 | |||
198 | // Set row, read cols | ||
199 | |||
149 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | 200 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { |
150 | select_row(i); | 201 | select_row(i); |
151 | wait_us(30); // without this wait read unstable value. | 202 | wait_us(30); // without this wait read unstable value. |
152 | matrix_row_t cols = read_cols(); | 203 | matrix_row_t current_row = read_cols(); |
153 | if (matrix_debouncing[i] != cols) { | 204 | if (matrix_debouncing[i] != current_row) { |
154 | matrix_debouncing[i] = cols; | 205 | matrix_debouncing[i] = current_row; |
155 | if (debouncing) { | 206 | if (debouncing) { |
156 | debug("bounce!: "); debug_hex(debouncing); debug("\n"); | 207 | debug("bounce!: "); debug_hex(debouncing); debug("\n"); |
157 | } | 208 | } |
158 | debouncing = DEBOUNCING_DELAY; | 209 | debouncing = DEBOUNCING_DELAY; |
159 | } | 210 | } |
160 | unselect_rows(); | 211 | unselect_row(i); |
161 | } | 212 | } |
162 | 213 | ||
163 | if (debouncing) { | 214 | if (debouncing) { |
@@ -169,19 +220,23 @@ uint8_t matrix_scan(void) | |||
169 | } | 220 | } |
170 | } | 221 | } |
171 | } | 222 | } |
172 | #else | 223 | |
224 | #else // ROW2COL | ||
225 | |||
226 | // Set col, read rows | ||
227 | |||
173 | for (uint8_t i = 0; i < MATRIX_COLS; i++) { | 228 | for (uint8_t i = 0; i < MATRIX_COLS; i++) { |
174 | select_row(i); | 229 | select_col(i); |
175 | wait_us(30); // without this wait read unstable value. | 230 | wait_us(30); // without this wait read unstable value. |
176 | matrix_row_t rows = read_cols(); | 231 | matrix_col_t current_col = read_rows(); |
177 | if (matrix_reversed_debouncing[i] != rows) { | 232 | if (matrix_transposed_debouncing[i] != current_col) { |
178 | matrix_reversed_debouncing[i] = rows; | 233 | matrix_transposed_debouncing[i] = current_col; |
179 | if (debouncing) { | 234 | if (debouncing) { |
180 | debug("bounce!: "); debug_hex(debouncing); debug("\n"); | 235 | debug("bounce!: "); debug_hex(debouncing); debug("\n"); |
181 | } | 236 | } |
182 | debouncing = DEBOUNCING_DELAY; | 237 | debouncing = DEBOUNCING_DELAY; |
183 | } | 238 | } |
184 | unselect_rows(); | 239 | unselect_col(i); |
185 | } | 240 | } |
186 | 241 | ||
187 | if (debouncing) { | 242 | if (debouncing) { |
@@ -189,17 +244,20 @@ uint8_t matrix_scan(void) | |||
189 | wait_ms(1); | 244 | wait_ms(1); |
190 | } else { | 245 | } else { |
191 | for (uint8_t i = 0; i < MATRIX_COLS; i++) { | 246 | for (uint8_t i = 0; i < MATRIX_COLS; i++) { |
192 | matrix_reversed[i] = matrix_reversed_debouncing[i]; | 247 | matrix_transposed[i] = matrix_transposed_debouncing[i]; |
193 | } | 248 | } |
194 | } | 249 | } |
195 | } | 250 | } |
251 | |||
252 | // Untranspose matrix | ||
196 | for (uint8_t y = 0; y < MATRIX_ROWS; y++) { | 253 | for (uint8_t y = 0; y < MATRIX_ROWS; y++) { |
197 | matrix_row_t row = 0; | 254 | matrix_row_t row = 0; |
198 | for (uint8_t x = 0; x < MATRIX_COLS; x++) { | 255 | for (uint8_t x = 0; x < MATRIX_COLS; x++) { |
199 | row |= ((matrix_reversed[x] & (1<<y)) >> y) << x; | 256 | row |= ((matrix_transposed[x] & (1<<y)) >> y) << x; |
200 | } | 257 | } |
201 | matrix[y] = row; | 258 | matrix[y] = row; |
202 | } | 259 | } |
260 | |||
203 | #endif | 261 | #endif |
204 | 262 | ||
205 | matrix_scan_quantum(); | 263 | matrix_scan_quantum(); |
@@ -233,23 +291,11 @@ matrix_row_t matrix_get_row(uint8_t row) | |||
233 | 291 | ||
234 | void matrix_print(void) | 292 | void matrix_print(void) |
235 | { | 293 | { |
236 | #if (MATRIX_COLS <= 8) | 294 | print_matrix_header(); |
237 | print("\nr/c 01234567\n"); | ||
238 | #elif (MATRIX_COLS <= 16) | ||
239 | print("\nr/c 0123456789ABCDEF\n"); | ||
240 | #elif (MATRIX_COLS <= 32) | ||
241 | print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n"); | ||
242 | #endif | ||
243 | 295 | ||
244 | for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | 296 | for (uint8_t row = 0; row < MATRIX_ROWS; row++) { |
245 | phex(row); print(": "); | 297 | phex(row); print(": "); |
246 | #if (MATRIX_COLS <= 8) | 298 | print_matrix_row(row); |
247 | print_bin_reverse8(matrix_get_row(row)); | ||
248 | #elif (MATRIX_COLS <= 16) | ||
249 | print_bin_reverse16(matrix_get_row(row)); | ||
250 | #elif (MATRIX_COLS <= 32) | ||
251 | print_bin_reverse32(matrix_get_row(row)); | ||
252 | #endif | ||
253 | print("\n"); | 299 | print("\n"); |
254 | } | 300 | } |
255 | } | 301 | } |
@@ -258,28 +304,21 @@ uint8_t matrix_key_count(void) | |||
258 | { | 304 | { |
259 | uint8_t count = 0; | 305 | uint8_t count = 0; |
260 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | 306 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { |
261 | #if (MATRIX_COLS <= 8) | 307 | count += matrix_bitpop(i); |
262 | count += bitpop(matrix[i]); | ||
263 | #elif (MATRIX_COLS <= 16) | ||
264 | count += bitpop16(matrix[i]); | ||
265 | #elif (MATRIX_COLS <= 32) | ||
266 | count += bitpop32(matrix[i]); | ||
267 | #endif | ||
268 | } | 308 | } |
269 | return count; | 309 | return count; |
270 | } | 310 | } |
271 | 311 | ||
312 | |||
313 | |||
314 | #if (DIODE_DIRECTION == COL2ROW) | ||
315 | |||
272 | static void init_cols(void) | 316 | static void init_cols(void) |
273 | { | 317 | { |
274 | #if DIODE_DIRECTION == COL2ROW | 318 | for(uint8_t x = 0; x < MATRIX_COLS; x++) { |
275 | for(int x = 0; x < MATRIX_COLS; x++) { | 319 | uint8_t pin = col_pins[x]; |
276 | int pin = col_pins[x]; | 320 | _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN |
277 | #else | 321 | _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI |
278 | for(int x = 0; x < MATRIX_ROWS; x++) { | ||
279 | int pin = row_pins[x]; | ||
280 | #endif | ||
281 | _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); | ||
282 | _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); | ||
283 | } | 322 | } |
284 | } | 323 | } |
285 | 324 | ||
@@ -287,40 +326,81 @@ static matrix_row_t read_cols(void) | |||
287 | { | 326 | { |
288 | matrix_row_t result = 0; | 327 | matrix_row_t result = 0; |
289 | 328 | ||
290 | #if DIODE_DIRECTION == COL2ROW | 329 | for(uint8_t x = 0; x < MATRIX_COLS; x++) { |
291 | for(int x = 0; x < MATRIX_COLS; x++) { | 330 | uint8_t pin = col_pins[x]; |
292 | int pin = col_pins[x]; | 331 | result |= (_SFR_IO8(pin >> 4) & _BV(pin & 0xF)) ? 0 : (ROW_SHIFTER << x); |
293 | #else | ||
294 | for(int x = 0; x < MATRIX_ROWS; x++) { | ||
295 | int pin = row_pins[x]; | ||
296 | #endif | ||
297 | result |= (_SFR_IO8(pin >> 4) & _BV(pin & 0xF)) ? 0 : (SHIFTER << x); | ||
298 | } | 332 | } |
333 | |||
299 | return result; | 334 | return result; |
300 | } | 335 | } |
301 | 336 | ||
337 | static void select_row(uint8_t row) | ||
338 | { | ||
339 | uint8_t pin = row_pins[row]; | ||
340 | _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT | ||
341 | _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW | ||
342 | } | ||
343 | |||
344 | static void unselect_row(uint8_t row) | ||
345 | { | ||
346 | uint8_t pin = row_pins[row]; | ||
347 | _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN | ||
348 | _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI | ||
349 | } | ||
350 | |||
302 | static void unselect_rows(void) | 351 | static void unselect_rows(void) |
303 | { | 352 | { |
304 | #if DIODE_DIRECTION == COL2ROW | 353 | for(uint8_t x = 0; x < MATRIX_ROWS; x++) { |
305 | for(int x = 0; x < MATRIX_ROWS; x++) { | 354 | uint8_t pin = row_pins[x]; |
306 | int pin = row_pins[x]; | 355 | _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN |
307 | #else | 356 | _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI |
308 | for(int x = 0; x < MATRIX_COLS; x++) { | ||
309 | int pin = col_pins[x]; | ||
310 | #endif | ||
311 | _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); | ||
312 | _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); | ||
313 | } | 357 | } |
314 | } | 358 | } |
315 | 359 | ||
316 | static void select_row(uint8_t row) | 360 | #else // ROW2COL |
361 | |||
362 | static void init_rows(void) | ||
317 | { | 363 | { |
364 | for(uint8_t x = 0; x < MATRIX_ROWS; x++) { | ||
365 | uint8_t pin = row_pins[x]; | ||
366 | _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN | ||
367 | _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI | ||
368 | } | ||
369 | } | ||
318 | 370 | ||
319 | #if DIODE_DIRECTION == COL2ROW | 371 | static matrix_col_t read_rows(void) |
320 | int pin = row_pins[row]; | 372 | { |
321 | #else | 373 | matrix_col_t result = 0; |
322 | int pin = col_pins[row]; | 374 | |
323 | #endif | 375 | for(uint8_t x = 0; x < MATRIX_ROWS; x++) { |
324 | _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); | 376 | uint8_t pin = row_pins[x]; |
325 | _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); | 377 | result |= (_SFR_IO8(pin >> 4) & _BV(pin & 0xF)) ? 0 : (COL_SHIFTER << x); |
378 | } | ||
379 | |||
380 | return result; | ||
381 | } | ||
382 | |||
383 | static void select_col(uint8_t col) | ||
384 | { | ||
385 | uint8_t pin = col_pins[col]; | ||
386 | _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT | ||
387 | _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW | ||
388 | } | ||
389 | |||
390 | static void unselect_col(uint8_t col) | ||
391 | { | ||
392 | uint8_t pin = col_pins[col]; | ||
393 | _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN | ||
394 | _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI | ||
326 | } | 395 | } |
396 | |||
397 | static void unselect_cols(void) | ||
398 | { | ||
399 | for(uint8_t x = 0; x < MATRIX_COLS; x++) { | ||
400 | uint8_t pin = col_pins[x]; | ||
401 | _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN | ||
402 | _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI | ||
403 | } | ||
404 | } | ||
405 | |||
406 | #endif | ||