Mercurial > louis > kiibohd-controller
comparison Scan/MatrixARM/matrix_scan.c @ 415:293154e4aafe
Added support for ghosting matrices and code for elimination.
To use define GHOST in matrix.h, see example in Scan/CK3
author | CryHam <cryham@gmail.com> |
---|---|
date | Fri, 19 Feb 2016 18:10:25 +0100 |
parents | fc2c2a1e9615 |
children | 060aa589b307 |
comparison
equal
deleted
inserted
replaced
414:06b8d295518e | 415:293154e4aafe |
---|---|
68 }; | 68 }; |
69 | 69 |
70 // Debounce Array | 70 // Debounce Array |
71 KeyState Matrix_scanArray[ Matrix_colsNum * Matrix_rowsNum ]; | 71 KeyState Matrix_scanArray[ Matrix_colsNum * Matrix_rowsNum ]; |
72 | 72 |
73 // Ghost Arrays | |
74 #ifdef GHOST | |
75 KeyGhost Matrix_ghostArray[ Matrix_colsNum * Matrix_rowsNum ]; | |
76 | |
77 uint8_t col_use[Matrix_colsNum], row_use[Matrix_rowsNum]; // used count | |
78 uint8_t col_ghost[Matrix_colsNum], row_ghost[Matrix_rowsNum]; // marked as having ghost if 1 | |
79 #endif | |
80 | |
81 | |
73 // Matrix debug flag - If set to 1, for each keypress the scan code is displayed in hex | 82 // Matrix debug flag - If set to 1, for each keypress the scan code is displayed in hex |
74 // If set to 2, for each key state change, the scan code is displayed along with the state | 83 // If set to 2, for each key state change, the scan code is displayed along with the state |
75 uint8_t matrixDebugMode = 0; | 84 uint8_t matrixDebugMode = 0; |
76 | 85 |
77 // Matrix State Table Debug Counter - If non-zero display state table after every matrix scan | 86 // Matrix State Table Debug Counter - If non-zero display state table after every matrix scan |
109 // Operation depends on Type | 118 // Operation depends on Type |
110 switch ( type ) | 119 switch ( type ) |
111 { | 120 { |
112 case Type_StrobeOn: | 121 case Type_StrobeOn: |
113 *GPIO_PSOR |= (1 << gpio.pin); | 122 *GPIO_PSOR |= (1 << gpio.pin); |
123 #ifdef GHOST | |
124 *GPIO_PDDR |= (1 << gpio.pin); // output | |
125 #endif | |
114 break; | 126 break; |
115 | 127 |
116 case Type_StrobeOff: | 128 case Type_StrobeOff: |
117 *GPIO_PCOR |= (1 << gpio.pin); | 129 *GPIO_PCOR |= (1 << gpio.pin); |
130 #ifdef GHOST | |
131 // Ghosting martix needs to put not used (off) strobes in high impedance state | |
132 *GPIO_PDDR &= ~(1 << gpio.pin); // input, high Z state | |
133 #endif | |
118 break; | 134 break; |
119 | 135 |
120 case Type_StrobeSetup: | 136 case Type_StrobeSetup: |
121 // Set as output pin | 137 // Set as output pin |
122 *GPIO_PDDR |= (1 << gpio.pin); | 138 *GPIO_PDDR |= (1 << gpio.pin); |
204 Matrix_scanArray[ item ].prevState = KeyState_Off; | 220 Matrix_scanArray[ item ].prevState = KeyState_Off; |
205 Matrix_scanArray[ item ].curState = KeyState_Off; | 221 Matrix_scanArray[ item ].curState = KeyState_Off; |
206 Matrix_scanArray[ item ].activeCount = 0; | 222 Matrix_scanArray[ item ].activeCount = 0; |
207 Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state | 223 Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state |
208 Matrix_scanArray[ item ].prevDecisionTime = 0; | 224 Matrix_scanArray[ item ].prevDecisionTime = 0; |
225 #ifdef GHOST | |
226 Matrix_ghostArray[ item ].prev = KeyState_Off; | |
227 Matrix_ghostArray[ item ].cur = KeyState_Off; | |
228 Matrix_ghostArray[ item ].saved = KeyState_Off; | |
229 #endif | |
209 } | 230 } |
210 | 231 |
211 // Clear scan stats counters | 232 // Clear scan stats counters |
212 matrixMaxScans = 0; | 233 matrixMaxScans = 0; |
213 matrixPrevScans = 0; | 234 matrixPrevScans = 0; |
370 case KeyState_Invalid: | 391 case KeyState_Invalid: |
371 default: | 392 default: |
372 erro_print("Matrix scan bug!! Report me!"); | 393 erro_print("Matrix scan bug!! Report me!"); |
373 break; | 394 break; |
374 } | 395 } |
375 | 396 |
376 // Update decision time | 397 // Update decision time |
377 state->prevDecisionTime = currentTime; | 398 state->prevDecisionTime = currentTime; |
378 | 399 |
379 // Send keystate to macro module | 400 // Send keystate to macro module |
401 #ifndef GHOST | |
380 Macro_keyState( key, state->curState ); | 402 Macro_keyState( key, state->curState ); |
403 #endif | |
381 | 404 |
382 // Matrix Debug, only if there is a state change | 405 // Matrix Debug, only if there is a state change |
383 if ( matrixDebugMode && state->curState != state->prevState ) | 406 if ( matrixDebugMode && state->curState != state->prevState ) |
384 { | 407 { |
385 // Basic debug output | 408 // Basic debug output |
401 | 424 |
402 // Unstrobe Pin | 425 // Unstrobe Pin |
403 Matrix_pin( Matrix_cols[ strobe ], Type_StrobeOff ); | 426 Matrix_pin( Matrix_cols[ strobe ], Type_StrobeOff ); |
404 } | 427 } |
405 | 428 |
429 | |
430 // Matrix ghosting check and elimination | |
431 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . | |
432 #ifdef GHOST | |
433 // strobe = column, sense = row | |
434 | |
435 // Count (rows) use for columns | |
436 //print("C "); | |
437 for ( uint8_t col = 0; col < Matrix_colsNum; col++ ) | |
438 { | |
439 uint8_t used = 0; | |
440 for ( uint8_t row = 0; row < Matrix_rowsNum; row++ ) | |
441 { | |
442 uint8_t key = Matrix_colsNum * row + col; | |
443 KeyState *state = &Matrix_scanArray[ key ]; | |
444 if ( keyOn(state->curState) ) | |
445 used++; | |
446 } | |
447 //printInt8(used); | |
448 col_use[col] = used; | |
449 col_ghost[col] = 0; // clear | |
450 } | |
451 | |
452 // Count (columns) use for rows | |
453 //print(" R "); | |
454 for ( uint8_t row = 0; row < Matrix_rowsNum; row++ ) | |
455 { | |
456 uint8_t used = 0; | |
457 for ( uint8_t col = 0; col < Matrix_colsNum; col++ ) | |
458 { | |
459 uint8_t key = Matrix_colsNum * row + col; | |
460 KeyState *state = &Matrix_scanArray[ key ]; | |
461 if ( keyOn(state->curState) ) | |
462 used++; | |
463 } | |
464 //printInt8(used); | |
465 row_use[row] = used; | |
466 row_ghost[row] = 0; // clear | |
467 } | |
468 | |
469 // Check if matrix has ghost | |
470 // Happens when key is pressed and some other key is pressed in same row and another in same column | |
471 //print(" G "); | |
472 for ( uint8_t col = 0; col < Matrix_colsNum; col++ ) | |
473 { | |
474 for ( uint8_t row = 0; row < Matrix_rowsNum; row++ ) | |
475 { | |
476 uint8_t key = Matrix_colsNum * row + col; | |
477 KeyState *state = &Matrix_scanArray[ key ]; | |
478 if ( keyOn(state->curState) && col_use[col] >= 2 && row_use[row] >= 2 ) | |
479 { | |
480 // mark col and row as having ghost | |
481 col_ghost[col] = 1; | |
482 row_ghost[row] = 1; | |
483 //print(" "); printInt8(col); print(","); printInt8(row); | |
484 } | |
485 } | |
486 } | |
487 //print( NL ); | |
488 | |
489 // Send keys | |
490 for ( uint8_t col = 0; col < Matrix_colsNum; col++ ) | |
491 { | |
492 for ( uint8_t row = 0; row < Matrix_rowsNum; row++ ) | |
493 { | |
494 uint8_t key = Matrix_colsNum * row + col; | |
495 KeyState *state = &Matrix_scanArray[ key ]; | |
496 KeyGhost *st = &Matrix_ghostArray[ key ]; | |
497 | |
498 // col or row is ghosting (crossed) | |
499 uint8_t ghost = (col_ghost[col] > 0 || row_ghost[row] > 0) ? 1 : 0; | |
500 | |
501 st->prev = st->cur; // previous | |
502 // save state if no ghost or outside ghosted area | |
503 if ( ghost == 0 ) | |
504 st->saved = state->curState; // save state if no ghost | |
505 // final | |
506 // use saved state if ghosting, or current if not | |
507 st->cur = ghost > 0 ? st->saved : state->curState; | |
508 | |
509 // Send keystate to macro module | |
510 KeyPosition k = !st->cur | |
511 ? (!st->prev ? KeyState_Off : KeyState_Release) | |
512 : ( st->prev ? KeyState_Hold : KeyState_Press); | |
513 //if (!st->cur && !st->prev) k = KeyState_Off; else | |
514 //if ( st->cur && st->prev) k = KeyState_Hold; else | |
515 //if ( st->cur && !st->prev) k = KeyState_Press; else | |
516 //if (!st->cur && st->prev) k = KeyState_Release; | |
517 Macro_keyState( key, k ); | |
518 } | |
519 } | |
520 #endif | |
521 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . | |
522 | |
523 | |
406 // State Table Output Debug | 524 // State Table Output Debug |
407 if ( matrixDebugStateCounter > 0 ) | 525 if ( matrixDebugStateCounter > 0 ) |
408 { | 526 { |
409 // Decrement counter | 527 // Decrement counter |
410 matrixDebugStateCounter--; | 528 matrixDebugStateCounter--; |