X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=Scan%2FMatrixARM%2Fmatrix_scan.c;h=a9018df9494a5d47ba5f3faee7347a207f5840c6;hb=7e68e81f4757ffff2261ab4a887d4114318aa5b6;hp=11ecba3511cac7d24dea9469c6d6612f09442904;hpb=eabb1c546a15111221a4f45f50265729ae5197be;p=kiibohd-controller.git diff --git a/Scan/MatrixARM/matrix_scan.c b/Scan/MatrixARM/matrix_scan.c index 11ecba3..a9018df 100644 --- a/Scan/MatrixARM/matrix_scan.c +++ b/Scan/MatrixARM/matrix_scan.c @@ -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 +#include #include #include #include @@ -38,6 +39,14 @@ +// ----- 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 -const char matrixCLIDictName[] = "Matrix Module Commands"; -const 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 ); } }