changeset 96:583a081da5d6

Adding debounce and reorganized code - Added debounce mechanism, currently looks for 5 consecutive scans - Temporarily disabled the test point strobe on the kishsaver (spams debug messages, and not useful anymore; needs to be addressed before strobe detection is implemented though) - Reorganized code to cleanup the main scan loop function
author Jacob Alexander <triplehaata@gmail.com>
date Tue, 19 Nov 2013 03:18:44 -0500
parents 8813a3d64261
children 492a32843639
files Scan/avr-capsense/scan_loop.c
diffstat 1 files changed, 146 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/Scan/avr-capsense/scan_loop.c	Tue Nov 19 02:01:51 2013 -0500
+++ b/Scan/avr-capsense/scan_loop.c	Tue Nov 19 03:18:44 2013 -0500
@@ -79,6 +79,9 @@
 // Strobe lines are detected at startup, extra strobes cause anomalies like phantom keypresses
 #define MAX_STROBES 18
 
+// Number of consecutive samples required to pass debounce
+#define DEBOUNCE_THRESHOLD 5
+
 #define MUXES_COUNT 8
 #define MUXES_COUNT_XSHIFT 3
 
@@ -153,6 +156,7 @@
 
 uint16_t keys_averages_acc[KEY_COUNT];
 uint16_t keys_averages    [KEY_COUNT];
+uint8_t  keys_debounce    [KEY_COUNT];
 
 uint8_t full_samples[KEY_COUNT];
 
@@ -184,6 +188,8 @@
 
 int sampleColumn( uint8_t column );
 
+void capsense_scan( void );
+
 void setup_ADC( void );
 
 void strobe_w( uint8_t strobe_num );
@@ -210,8 +216,8 @@
 	// Hardcoded strobes for debugging
 	// Strobes start at 0 and go to 17 (18), not all Model Fs use all of the available strobes
 	// The single row ribbon connector Model Fs only have a max of 16 strobes
-//#define KISHSAVER_STROBE
-#define TERMINAL_6110668_STROBE
+#define KISHSAVER_STROBE
+//#define TERMINAL_6110668_STROBE
 //#define UNSAVER_STROBE
 #ifdef KISHSAVER_STROBE
 	total_strobes = 10;
@@ -225,7 +231,8 @@
 	strobe_map[6] = 7;
 	strobe_map[7] = 8;
 	strobe_map[8] = 9;
-	strobe_map[9] = 15; // Test point strobe (3 test points, sense 1, 4, 5)
+	// XXX - Disabling for now, not sure how to deal with test points yet (without spamming the debug)
+	//strobe_map[9] = 15; // Test point strobe (3 test points, sense 1, 4, 5)
 #elif defined(TERMINAL_6110668_STROBE)
 	total_strobes = 16;
 
@@ -277,6 +284,9 @@
 	{
 		keys_averages[i] = DEFAULT_KEY_BASE;
 		keys_averages_acc[i] = (DEFAULT_KEY_BASE);
+
+		// Reset debounce table
+		keys_debounce[i] = 0;
 	}
 
 	/** warm things up a bit before we start collecting data, taking real samples. */
@@ -296,6 +306,91 @@
 // This is where the important stuff happens
 inline uint8_t scan_loop()
 {
+	capsense_scan();
+
+	// Error case, should not occur in normal operation
+	if ( error )
+	{
+		erro_msg("Problem detected... ");
+
+		// Keymap scan debug
+		for ( uint8_t i = 0; i < total_strobes; ++i )
+		{
+				printHex(cur_keymap[i]);
+				print(" ");
+		}
+
+		print(" : ");
+		printHex(error);
+		error = 0;
+		print(" : ");
+		printHex(error_data);
+		error_data = 0;
+
+		// Display keymaps and other debug information if warmup completede
+		if ( boot_count >= WARMUP_LOOPS )
+		{
+			dump();
+		}
+	}
+
+
+	// Return non-zero if macro and USB processing should be delayed
+	// Macro processing will always run if returning 0
+	// USB processing only happens once the USB send timer expires, if it has not, scan_loop will be called
+	//  after the macro processing has been completed
+	return 0;
+}
+
+
+// Reset Keyboard
+void scan_resetKeyboard( void )
+{
+	// Empty buffer, now that keyboard has been reset
+	KeyIndex_BufferUsed = 0;
+}
+
+
+// Send data to keyboard
+// NOTE: Only used for converters, since the scan module shouldn't handle sending data in a controller
+uint8_t scan_sendData( uint8_t dataPayload )
+{
+	return 0;
+}
+
+
+// Reset/Hold keyboard
+// NOTE: Only used for converters, not needed for full controllers
+void scan_lockKeyboard( void )
+{
+}
+
+// NOTE: Only used for converters, not needed for full controllers
+void scan_unlockKeyboard( void )
+{
+}
+
+
+// Signal KeyIndex_Buffer that it has been properly read
+// NOTE: Only really required for implementing "tricks" in converters for odd protocols
+void scan_finishedWithBuffer( uint8_t sentKeys )
+{
+	// Convenient place to clear the KeyIndex_Buffer
+	KeyIndex_BufferUsed = 0;
+	return;
+}
+
+
+// Signal KeyIndex_Buffer that it has been properly read and sent out by the USB module
+// NOTE: Only really required for implementing "tricks" in converters for odd protocols
+void scan_finishedWithUSBBuffer( uint8_t sentKeys )
+{
+	return;
+}
+
+
+inline void capsense_scan()
+{
 	// TODO dfj code...needs commenting + cleanup...
 	uint8_t strober = 0;
 	uint32_t full_av_acc = 0;
@@ -420,85 +515,6 @@
 		}
 
 	}
-
-	// Error case, should not occur in normal operation
-	if ( error )
-	{
-		erro_msg("Problem detected... ");
-
-		// Keymap scan debug
-		for ( uint8_t i = 0; i < total_strobes; ++i )
-		{
-				printHex(cur_keymap[i]);
-				print(" ");
-		}
-
-		print(" : ");
-		printHex(error);
-		error = 0;
-		print(" : ");
-		printHex(error_data);
-		error_data = 0;
-
-		// Display keymaps and other debug information if warmup completede
-		if ( boot_count >= WARMUP_LOOPS )
-		{
-			dump();
-		}
-	}
-
-
-	// Return non-zero if macro and USB processing should be delayed
-	// Macro processing will always run if returning 0
-	// USB processing only happens once the USB send timer expires, if it has not, scan_loop will be called
-	//  after the macro processing has been completed
-	return 0;
-}
-
-
-// Reset Keyboard
-void scan_resetKeyboard( void )
-{
-	// Empty buffer, now that keyboard has been reset
-	KeyIndex_BufferUsed = 0;
-}
-
-
-// Send data to keyboard
-// NOTE: Only used for converters, since the scan module shouldn't handle sending data in a controller
-uint8_t scan_sendData( uint8_t dataPayload )
-{
-	return 0;
-}
-
-
-// Reset/Hold keyboard
-// NOTE: Only used for converters, not needed for full controllers
-void scan_lockKeyboard( void )
-{
-}
-
-// NOTE: Only used for converters, not needed for full controllers
-void scan_unlockKeyboard( void )
-{
-}
-
-
-// Signal KeyIndex_Buffer that it has been properly read
-// NOTE: Only really required for implementing "tricks" in converters for odd protocols
-void scan_finishedWithBuffer( uint8_t sentKeys )
-{
-	// Convenient place to clear the KeyIndex_Buffer
-	KeyIndex_BufferUsed = 0;
-	return;
-}
-
-
-// Signal KeyIndex_Buffer that it has been properly read and sent out by the USB module
-// NOTE: Only really required for implementing "tricks" in converters for odd protocols
-void scan_finishedWithUSBBuffer( uint8_t sentKeys )
-{
-	return;
 }
 
 
@@ -718,22 +734,38 @@
 	{
 		uint16_t delta = keys_averages[(strobe << MUXES_COUNT_XSHIFT) + mux];
 
+		uint8_t key = (strobe << MUXES_COUNT_XSHIFT) + mux;
+
 		// Keypress detected
 		if ( (db_sample = samples[SAMPLE_OFFSET + mux] >> 1) > (db_threshold = threshold) + (db_delta = delta) )
 		{
 			column |= bit;
 
-			// Only register keypresses once the warmup is complete
-			if ( boot_count >= WARMUP_LOOPS )
+			// Only register keypresses once the warmup is complete, or not enough debounce info
+			if ( boot_count >= WARMUP_LOOPS && keys_debounce[key] <= DEBOUNCE_THRESHOLD )
 			{
-				uint8_t key = (strobe << MUXES_COUNT_XSHIFT) + mux;
+				// Add to the Macro processing buffer if debounce criteria met
+				// Automatically handles converting to a USB code and sending off to the PC
+				if ( keys_debounce[key] == DEBOUNCE_THRESHOLD )
+				{
+#define KEYSCAN_DEBOUNCE_DEBUG
+#ifdef KEYSCAN_DEBOUNCE_DEBUG
+					// Debug message
+					// <key> [<strobe>:<mux>] : <sense val> : <delta + threshold> : <margin>
+					print("0x");
+					printHex_op( key, 2 );
+					print(" ");
+#endif
 
-				// TODO Add debounce first
-				// Add to the Macro processing buffer
-				// Automatically handles converting to a USB code and sending off to the PC
-				//bufferAdd( key );
+					// Only add the key to the buffer once
+					// NOTE: Buffer can easily handle multiple adds, just more efficient
+					//        and nicer debug messages :P
+					//bufferAdd( key );
+				}
 
-#define KEYSCAN_THRESHOLD_DEBUG
+				keys_debounce[key]++;
+
+//#define KEYSCAN_THRESHOLD_DEBUG
 #ifdef KEYSCAN_THRESHOLD_DEBUG
 				// Debug message
 				// <key> [<strobe>:<mux>] : <sense val> : <delta + threshold> : <margin>
@@ -757,6 +789,30 @@
 #endif
 			}
 		}
+		// Clear debounce entry if no keypress detected
+		else
+		{
+			// If the key was previously pressed, remove from the buffer
+			for ( uint8_t c = 0; c < KeyIndex_BufferUsed; c++ )
+                        {
+                                // Key to release found
+                                if ( KeyIndex_Buffer[c] == key )
+                                {
+                                        // Shift keys from c position
+                                        for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
+                                                KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
+
+                                        // Decrement Buffer
+                                        KeyIndex_BufferUsed--;
+
+                                        break;
+                                }
+                        }
+
+
+			// Clear debounce entry
+			keys_debounce[key] = 0;
+		}
 
 		bit <<= 1;
 	}