# HG changeset patch # User Jacob Alexander # Date 1434703856 25200 # Node ID e464aaa4730fdc76d4644113be14a091e2e4cfc1 # Parent b29c291ad130f89d1bbbddb25f09e611e6b2bc68 Adding timing based debounce code - Uses expiry timer to decide on when to allow a state change - Initial state transitions are unaffected - Use MinDebounceTime define in kll to configure - ms granularity diff -r b29c291ad130 -r e464aaa4730f Scan/MatrixARM/capabilities.kll --- a/Scan/MatrixARM/capabilities.kll Sun Jun 14 14:32:42 2015 -0700 +++ b/Scan/MatrixARM/capabilities.kll Fri Jun 19 01:50:56 2015 -0700 @@ -32,3 +32,10 @@ DebounceThrottleDiv = 0; # Default #DebounceThrottleDiv = 2; # /4 divider +# This defines the minimum amount of time after a transition until allowing another transition +# Generally switches require a minimum 5 ms debounce period +# Since a decision can usually be made quite quickly, there is little latency on each press +# However, this defines the latency at which the switch state can change +MinDebounceTime => MinDebounceTime_define; +MinDebounceTime = 5; # 5 ms + diff -r b29c291ad130 -r e464aaa4730f Scan/MatrixARM/matrix_scan.c --- a/Scan/MatrixARM/matrix_scan.c Sun Jun 14 14:32:42 2015 -0700 +++ b/Scan/MatrixARM/matrix_scan.c Fri Jun 19 01:50:56 2015 -0700 @@ -82,6 +82,9 @@ uint16_t matrixCurScans = 0; uint16_t matrixPrevScans = 0; +// System Timer used for delaying debounce decisions +extern volatile uint32_t systick_millis_count; + // ----- Functions ----- @@ -197,10 +200,11 @@ // 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 @@ -262,6 +266,9 @@ 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++ ) { @@ -305,11 +312,16 @@ } // 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: @@ -320,6 +332,15 @@ } 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; @@ -328,6 +349,15 @@ 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 @@ -342,6 +372,9 @@ break; } + // Update decision time + state->prevDecisionTime = currentTime; + // Send keystate to macro module Macro_keyState( key, state->curState ); diff -r b29c291ad130 -r e464aaa4730f Scan/MatrixARM/matrix_scan.h --- a/Scan/MatrixARM/matrix_scan.h Sun Jun 14 14:32:42 2015 -0700 +++ b/Scan/MatrixARM/matrix_scan.h Fri Jun 19 01:50:56 2015 -0700 @@ -40,6 +40,12 @@ #error "Debounce threshold is too high... 32 bit max. Check .kll defines." #endif +#if ( MinDebounceTime_define > 0xFF ) +#error "MinDebounceTime is a maximum of 255 ms" +#elif ( MinDebounceTime_define < 0x00 ) +#error "MinDebounceTime is a minimum 0 ms" +#endif + // ----- Enums ----- @@ -126,11 +132,12 @@ // Debounce Element typedef struct KeyState { + DebounceCounter activeCount; + DebounceCounter inactiveCount; KeyPosition prevState; KeyPosition curState; - DebounceCounter activeCount; - DebounceCounter inactiveCount; -} KeyState; + uint8_t prevDecisionTime; +} __attribute__((packed)) KeyState;