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
This commit is contained in:
parent
f708ce720c
commit
98f796d4df
@ -32,3 +32,10 @@ DebounceThrottleDiv => DebounceThrottleDiv_define;
|
|||||||
DebounceThrottleDiv = 0; # Default
|
DebounceThrottleDiv = 0; # Default
|
||||||
#DebounceThrottleDiv = 2; # /4 divider
|
#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
|
||||||
|
|
||||||
|
@ -82,6 +82,9 @@ uint16_t matrixMaxScans = 0;
|
|||||||
uint16_t matrixCurScans = 0;
|
uint16_t matrixCurScans = 0;
|
||||||
uint16_t matrixPrevScans = 0;
|
uint16_t matrixPrevScans = 0;
|
||||||
|
|
||||||
|
// System Timer used for delaying debounce decisions
|
||||||
|
extern volatile uint32_t systick_millis_count;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Functions -----
|
// ----- Functions -----
|
||||||
@ -197,10 +200,11 @@ void Matrix_setup()
|
|||||||
// Clear out Debounce Array
|
// Clear out Debounce Array
|
||||||
for ( uint8_t item = 0; item < Matrix_maxKeys; item++ )
|
for ( uint8_t item = 0; item < Matrix_maxKeys; item++ )
|
||||||
{
|
{
|
||||||
Matrix_scanArray[ item ].prevState = KeyState_Off;
|
Matrix_scanArray[ item ].prevState = KeyState_Off;
|
||||||
Matrix_scanArray[ item ].curState = KeyState_Off;
|
Matrix_scanArray[ item ].curState = KeyState_Off;
|
||||||
Matrix_scanArray[ item ].activeCount = 0;
|
Matrix_scanArray[ item ].activeCount = 0;
|
||||||
Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state
|
Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state
|
||||||
|
Matrix_scanArray[ item ].prevDecisionTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear scan stats counters
|
// Clear scan stats counters
|
||||||
@ -262,6 +266,9 @@ void Matrix_scan( uint16_t scanNum )
|
|||||||
matrixCurScans++;
|
matrixCurScans++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read systick for event scheduling
|
||||||
|
uint8_t currentTime = (uint8_t)systick_millis_count;
|
||||||
|
|
||||||
// For each strobe, scan each of the sense pins
|
// For each strobe, scan each of the sense pins
|
||||||
for ( uint8_t strobe = 0; strobe < Matrix_colsNum; strobe++ )
|
for ( uint8_t strobe = 0; strobe < Matrix_colsNum; strobe++ )
|
||||||
{
|
{
|
||||||
@ -305,11 +312,16 @@ void Matrix_scan( uint16_t scanNum )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for state change if it hasn't been set
|
// 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
|
// Only check if the minimum number of scans has been met
|
||||||
// the current state is invalid
|
// the current state is invalid
|
||||||
// and either active or inactive count is over the debounce threshold
|
// and either active or inactive count is over the debounce threshold
|
||||||
if ( state->curState == KeyState_Invalid )
|
if ( state->curState == KeyState_Invalid )
|
||||||
{
|
{
|
||||||
|
// Determine time since last decision
|
||||||
|
uint8_t lastTransition = currentTime - state->prevDecisionTime;
|
||||||
|
|
||||||
|
// Attempt state transition
|
||||||
switch ( state->prevState )
|
switch ( state->prevState )
|
||||||
{
|
{
|
||||||
case KeyState_Press:
|
case KeyState_Press:
|
||||||
@ -320,6 +332,15 @@ void Matrix_scan( uint16_t scanNum )
|
|||||||
}
|
}
|
||||||
else
|
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;
|
state->curState = KeyState_Release;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -328,6 +349,15 @@ void Matrix_scan( uint16_t scanNum )
|
|||||||
case KeyState_Off:
|
case KeyState_Off:
|
||||||
if ( state->activeCount > state->inactiveCount )
|
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;
|
state->curState = KeyState_Press;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -342,6 +372,9 @@ void Matrix_scan( uint16_t scanNum )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update decision time
|
||||||
|
state->prevDecisionTime = currentTime;
|
||||||
|
|
||||||
// Send keystate to macro module
|
// Send keystate to macro module
|
||||||
Macro_keyState( key, state->curState );
|
Macro_keyState( key, state->curState );
|
||||||
|
|
||||||
|
@ -40,6 +40,12 @@
|
|||||||
#error "Debounce threshold is too high... 32 bit max. Check .kll defines."
|
#error "Debounce threshold is too high... 32 bit max. Check .kll defines."
|
||||||
#endif
|
#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 -----
|
// ----- Enums -----
|
||||||
@ -126,11 +132,12 @@ typedef struct GPIO_Pin {
|
|||||||
|
|
||||||
// Debounce Element
|
// Debounce Element
|
||||||
typedef struct KeyState {
|
typedef struct KeyState {
|
||||||
KeyPosition prevState;
|
|
||||||
KeyPosition curState;
|
|
||||||
DebounceCounter activeCount;
|
DebounceCounter activeCount;
|
||||||
DebounceCounter inactiveCount;
|
DebounceCounter inactiveCount;
|
||||||
} KeyState;
|
KeyPosition prevState;
|
||||||
|
KeyPosition curState;
|
||||||
|
uint8_t prevDecisionTime;
|
||||||
|
} __attribute__((packed)) KeyState;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user