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--;