X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=Scan%2FMatrixARM%2Fmatrix_scan.c;h=a9018df9494a5d47ba5f3faee7347a207f5840c6;hb=7e68e81f4757ffff2261ab4a887d4114318aa5b6;hp=eaea368f4b01e6a8635879e4f9ba1b25e92ca3dc;hpb=a9c5898ba5fcb06f11ff97c4fe1fbafb836ebd87;p=kiibohd-controller.git diff --git a/Scan/MatrixARM/matrix_scan.c b/Scan/MatrixARM/matrix_scan.c index eaea368..a9018df 100644 --- a/Scan/MatrixARM/matrix_scan.c +++ b/Scan/MatrixARM/matrix_scan.c @@ -26,6 +26,7 @@ // Project Includes #include +#include #include #include #include @@ -38,6 +39,14 @@ +// ----- Defines ----- + +#if ( DebounceThrottleDiv_define > 0 ) +nat_ptr_t Matrix_divCounter = 0; +#endif + + + // ----- Function Declarations ----- // CLI Functions @@ -73,6 +82,9 @@ uint16_t matrixMaxScans = 0; uint16_t matrixCurScans = 0; uint16_t matrixPrevScans = 0; +// System Timer used for delaying debounce decisions +extern volatile uint32_t systick_millis_count; + // ----- Functions ----- @@ -184,14 +196,16 @@ void Matrix_setup() print( NL ); info_msg("Max Keys: "); printHex( Matrix_maxKeys ); + print( NL ); // Clear out Debounce Array for ( uint8_t item = 0; item < Matrix_maxKeys; item++ ) { - Matrix_scanArray[ item ].prevState = KeyState_Off; - Matrix_scanArray[ item ].curState = KeyState_Off; - Matrix_scanArray[ item ].activeCount = 0; - Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state + Matrix_scanArray[ item ].prevState = KeyState_Off; + Matrix_scanArray[ item ].curState = KeyState_Off; + Matrix_scanArray[ item ].activeCount = 0; + Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state + Matrix_scanArray[ item ].prevDecisionTime = 0; } // Clear scan stats counters @@ -232,6 +246,15 @@ void Matrix_keyPositionDebug( KeyPosition pos ) // NOTE: scanNum should be reset to 0 after a USB send (to reset all the counters) void Matrix_scan( uint16_t scanNum ) { +#if ( DebounceThrottleDiv_define > 0 ) + // Scan-rate throttling + // By scanning using a divider, the scan rate slowed down + // DebounceThrottleDiv_define == 1 means -> /2 or half scan rate + // This helps with bouncy switches on fast uCs + if ( !( Matrix_divCounter++ & (1 << ( DebounceThrottleDiv_define - 1 )) ) ) + return; +#endif + // Increment stats counters if ( scanNum > matrixMaxScans ) matrixMaxScans = scanNum; if ( scanNum == 0 ) @@ -244,6 +267,9 @@ void Matrix_scan( uint16_t scanNum ) matrixCurScans++; } + // Read systick for event scheduling + uint8_t currentTime = (uint8_t)systick_millis_count; + // For each strobe, scan each of the sense pins for ( uint8_t strobe = 0; strobe < Matrix_colsNum; strobe++ ) { @@ -287,11 +313,16 @@ void Matrix_scan( uint16_t scanNum ) } // Check for state change if it hasn't been set + // But only if enough time has passed since last state change // Only check if the minimum number of scans has been met // the current state is invalid // and either active or inactive count is over the debounce threshold if ( state->curState == KeyState_Invalid ) { + // Determine time since last decision + uint8_t lastTransition = currentTime - state->prevDecisionTime; + + // Attempt state transition switch ( state->prevState ) { case KeyState_Press: @@ -302,6 +333,15 @@ void Matrix_scan( uint16_t scanNum ) } else { + // If not enough time has passed since Hold + // Keep previous state + if ( lastTransition < MinDebounceTime_define ) + { + //warn_print("FAST Release stopped"); + state->curState = state->prevState; + continue; + } + state->curState = KeyState_Release; } break; @@ -310,6 +350,15 @@ void Matrix_scan( uint16_t scanNum ) case KeyState_Off: if ( state->activeCount > state->inactiveCount ) { + // If not enough time has passed since Hold + // Keep previous state + if ( lastTransition < MinDebounceTime_define ) + { + //warn_print("FAST Press stopped"); + state->curState = state->prevState; + continue; + } + state->curState = KeyState_Press; } else @@ -324,6 +373,9 @@ void Matrix_scan( uint16_t scanNum ) break; } + // Update decision time + state->prevDecisionTime = currentTime; + // Send keystate to macro module Macro_keyState( key, state->curState );