]> git.donarmstrong.com Git - kiibohd-controller.git/commitdiff
Adding timing based debounce code
authorJacob Alexander <haata@kiibohd.com>
Fri, 19 Jun 2015 08:50:56 +0000 (01:50 -0700)
committerJacob Alexander <haata@kiibohd.com>
Fri, 19 Jun 2015 08:57:16 +0000 (01:57 -0700)
- 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

Scan/MatrixARM/capabilities.kll
Scan/MatrixARM/matrix_scan.c
Scan/MatrixARM/matrix_scan.h

index 8221ec8f2d6e2ad7f11e2f73f8204b457099bd80..fe0192df0c046446c5a4d681326b8dd6163c8a02 100644 (file)
@@ -32,3 +32,10 @@ DebounceThrottleDiv => DebounceThrottleDiv_define;
 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
+
index 85f82050f33cb4ef83ce08086af369d85db0ccc0..a48e28731423ad133bb3eaa26bdac294c5e7778e 100644 (file)
@@ -82,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 -----
@@ -197,10 +200,11 @@ void Matrix_setup()
        // 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 @@ 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++ )
        {
@@ -305,11 +312,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:
@@ -320,6 +332,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;
@@ -328,6 +349,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
@@ -342,6 +372,9 @@ void Matrix_scan( uint16_t scanNum )
                                        break;
                                }
 
+                               // Update decision time
+                               state->prevDecisionTime = currentTime;
+
                                // Send keystate to macro module
                                Macro_keyState( key, state->curState );
 
index 06ae75fbb1b3d5e492f6ee15caf16bbf27e9070a..810e6d9ddee0146a1f8a580ecb21750003aa3fb1 100644 (file)
 #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 @@ typedef struct GPIO_Pin {
 
 // Debounce Element
 typedef struct KeyState {
-       KeyPosition     prevState;
-       KeyPosition     curState;
        DebounceCounter activeCount;
        DebounceCounter inactiveCount;
-} KeyState;
+       KeyPosition     prevState;
+       KeyPosition     curState;
+       uint8_t         prevDecisionTime;
+} __attribute__((packed)) KeyState;