]> git.donarmstrong.com Git - kiibohd-controller.git/blobdiff - Scan/MatrixARM/matrix_scan.c
Adding basic remote capabilities + UART Rx DMA buffers
[kiibohd-controller.git] / Scan / MatrixARM / matrix_scan.c
index e3b5429dd4139298d13ee5a27a2a1d4c412d574a..a9018df9494a5d47ba5f3faee7347a207f5840c6 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014 by Jacob Alexander
+/* Copyright (C) 2014-2015 by Jacob Alexander
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -26,6 +26,7 @@
 
 // Project Includes
 #include <cli.h>
+#include <kll_defs.h>
 #include <led.h>
 #include <print.h>
 #include <macro.h>
 
 
 
+// ----- Defines -----
+
+#if ( DebounceThrottleDiv_define > 0 )
+nat_ptr_t Matrix_divCounter = 0;
+#endif
+
+
+
 // ----- Function Declarations -----
 
 // CLI Functions
@@ -49,10 +58,12 @@ void cliFunc_matrixState( char* args );
 // ----- Variables -----
 
 // Scan Module command dictionary
-char*       matrixCLIDictName = "Matrix Module Commands";
-CLIDictItem matrixCLIDict[] = {
-       { "matrixDebug",  "Enables matrix debug mode, prints out each scan code." NL "\t\tIf argument \033[35mT\033[0m is given, prints out each scan code state transition.", cliFunc_matrixDebug },
-       { "matrixState",  "Prints out the current scan table N times." NL "\t\t \033[1mO\033[0m - Off, \033[1;33mP\033[0m - Press, \033[1;32mH\033[0m - Hold, \033[1;35mR\033[0m - Release, \033[1;31mI\033[0m - Invalid", cliFunc_matrixState },
+CLIDict_Entry( matrixDebug,  "Enables matrix debug mode, prints out each scan code." NL "\t\tIf argument \033[35mT\033[0m is given, prints out each scan code state transition." );
+CLIDict_Entry( matrixState,  "Prints out the current scan table N times." NL "\t\t \033[1mO\033[0m - Off, \033[1;33mP\033[0m - Press, \033[1;32mH\033[0m - Hold, \033[1;35mR\033[0m - Release, \033[1;31mI\033[0m - Invalid" );
+
+CLIDict_Def( matrixCLIDict, "Matrix Module Commands" ) = {
+       CLIDict_Item( matrixDebug ),
+       CLIDict_Item( matrixState ),
        { 0, 0, 0 } // Null entry for dictionary end
 };
 
@@ -71,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 -----
@@ -182,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 = 0xFFFF; // 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
@@ -230,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 )
@@ -242,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++ )
        {
@@ -273,23 +301,28 @@ void Matrix_scan( uint16_t scanNum )
                        if ( Matrix_pin( Matrix_rows[ sense ], Type_Sense ) )
                        {
                                // Only update if not going to wrap around
-                               if ( state->activeCount < 0xFFFF ) state->activeCount += 1;
+                               if ( state->activeCount < DebounceDivThreshold_define ) state->activeCount += 1;
                                state->inactiveCount >>= 1;
                        }
                        // Signal Not Detected
                        else
                        {
                                // Only update if not going to wrap around
-                               if ( state->inactiveCount < 0xFFFF ) state->inactiveCount += 1;
+                               if ( state->inactiveCount < DebounceDivThreshold_define ) state->inactiveCount += 1;
                                state->activeCount >>= 1;
                        }
 
                        // 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:
@@ -300,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;
@@ -308,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
@@ -322,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 );
 
@@ -444,7 +498,7 @@ void cliFunc_matrixState ( char* args )
 
        if ( arg1Ptr[0] != '\0' )
        {
-               matrixDebugStateCounter = (uint16_t)decToInt( arg1Ptr );
+               matrixDebugStateCounter = (uint16_t)numToInt( arg1Ptr );
        }
 }