changeset 343:e464aaa4730f

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
author Jacob Alexander <haata@kiibohd.com>
date Fri, 19 Jun 2015 01:50:56 -0700
parents b29c291ad130
children f04450004adf
files Scan/MatrixARM/capabilities.kll Scan/MatrixARM/matrix_scan.c Scan/MatrixARM/matrix_scan.h
diffstat 3 files changed, 54 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- 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
+
--- 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 );
 
--- 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;