changeset 85:0e3157680bd1

Adapting the avr-capsense code to the Kiibohd Controller API - Adding "template" keymap - Removed "stray" functions, variables - Cleaned up warnings - Now builds - Added buffered macro integration (rather than dealing with USB directly) - Updated the print messages to use the Kiibohd print header TODO - Add generic matrix integration (this will require some changes to the matrix code) - Add more comments...lots more - Clean up dead code
author Jacob Alexander <triplehaata@gmail.com>
date Sat, 13 Apr 2013 22:35:59 -0400
parents fcef1286ab60
children 13b705bb165f
files CMakeLists.txt Debug/print/print.h Keymap/avrcapsense.h Keymap/keymap.h Scan/avr-capsense/scan_loop.c Scan/avr-capsense/scan_loop.h Scan/avr-capsense/setup.cmake setup.cmake
diffstat 8 files changed, 1744 insertions(+), 1407 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Sat Apr 13 20:11:40 2013 -0400
+++ b/CMakeLists.txt	Sat Apr 13 22:35:59 2013 -0400
@@ -27,8 +27,8 @@
 #| "avr"       # Teensy++ 1.0
 #| "avr"       # Teensy++ 2.0
 #| "arm"       # Teensy   3.0
-set( COMPILER_FAMILY "arm" )
-#set( COMPILER_FAMILY "avr" )
+#set( COMPILER_FAMILY "arm" )
+set( COMPILER_FAMILY "avr" )
 
 message( STATUS "Compiler Family:" )
 message( "${COMPILER_FAMILY}" )
--- a/Debug/print/print.h	Sat Apr 13 20:11:40 2013 -0400
+++ b/Debug/print/print.h	Sat Apr 13 22:35:59 2013 -0400
@@ -78,6 +78,7 @@
 #define dbug_dPrint(...)  dPrintMsg        ("1;35",   "DEBUG",   __VA_ARGS__) // Debug Msg
 #define dbug_print(str)   printMsg         ("1;35",   "DEBUG",   str)         // Debug Msg
 
+
 // Static String Printing
 #define print(s) _print(PSTR(s))
 
@@ -97,9 +98,9 @@
 // String Functions
 #define hexToStr(hex, out) hexToStr_op(hex, out, 1)
 
-void int8ToStr  ( uint8_t  in,   char*  out );
-void int16ToStr ( uint16_t in,   char*  out );
-void hexToStr_op( uint16_t in,   char*  out, uint8_t op );
+void int8ToStr  ( uint8_t  in, char*  out );
+void int16ToStr ( uint16_t in, char*  out );
+void hexToStr_op( uint16_t in, char*  out, uint8_t op );
 void revsStr    ( char*  in );
 uint16_t lenStr ( char*  in );
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Keymap/avrcapsense.h	Sat Apr 13 22:35:59 2013 -0400
@@ -0,0 +1,538 @@
+/* Copyright (C) 2013 by Jacob Alexander
+ * 
+ * dfj, place whatever license you want here
+ */
+
+#ifndef __AVRCAPSENSE_H
+#define __AVRCAPSENSE_H
+
+// This file contains various key layouts for dfj's AVR Capsense Controller
+
+
+// ----- Variables -----
+
+static uint8_t  avrcapsense_ModifierMask [] = { 0x34, 0x38, 0x3A, 0x40 };
+
+// Default 1-indexed key mappings
+static uint8_t avrcapsense_DefaultMap[] = {
+				0, // 0x00
+				0, // 0x01
+				0, // 0x02
+				0, // 0x03
+				0, // 0x04
+				0, // 0x05
+				0, // 0x06
+				0, // 0x07
+				KEY_BACKSPACE, // 0x08
+				KEY_TAB, // 0x09
+				0, // 0x0A
+				0, // 0x0B
+				0, // 0x0C
+				KEY_ENTER, // 0x0D
+				0, // 0x0E
+				0, // 0x0F
+				0, // 0x10
+				0, // 0x11
+				0, // 0x12
+				0, // 0x13
+				0, // 0x14
+				0, // 0x15
+				0, // 0x16
+				0, // 0x17
+				0, // 0x18
+				0, // 0x19
+				0, // 0x1A
+				KEY_ESC, // 0x1B
+				0, // 0x1C
+				0, // 0x1D
+				0, // 0x1E
+				0, // 0x1F
+				KEY_SPACE, // 0x20
+				0, // 0x21
+				0, // 0x22
+				0, // 0x23
+				0, // 0x24
+				0, // 0x25
+				0, // 0x26
+				KEY_QUOTE, // 0x27
+				0, // 0x28
+				0, // 0x29
+				0, // 0x2A
+				0, // 0x2B
+				KEY_COMMA, // 0x2C
+				KEY_MINUS, // 0x2D
+				KEY_PERIOD, // 0x2E
+				KEY_SLASH, // 0x2F
+				KEY_0, // 0x30
+				KEY_1, // 0x31
+				KEY_2, // 0x32
+				KEY_3, // 0x33
+				KEY_4, // 0x34
+				KEY_5, // 0x35
+				KEY_6, // 0x36
+				KEY_7, // 0x37
+				KEY_8, // 0x38
+				KEY_9, // 0x39
+				0, // 0x3A
+				KEY_SEMICOLON, // 0x3B
+				0, // 0x3C
+				KEY_EQUAL, // 0x3D
+				0, // 0x3E
+				0, // 0x3F
+				0, // 0x40
+				0, // 0x41
+				0, // 0x42
+				0, // 0x43
+				0, // 0x44
+				0, // 0x45
+				0, // 0x46
+				0, // 0x47
+				0, // 0x48
+				0, // 0x49
+				0, // 0x4A
+				0, // 0x4B
+				0, // 0x4C
+				0, // 0x4D
+				0, // 0x4E
+				0, // 0x4F
+				0, // 0x50
+				0, // 0x51
+				0, // 0x52
+				0, // 0x53
+				0, // 0x54
+				0, // 0x55
+				0, // 0x56
+				0, // 0x57
+				0, // 0x58
+				0, // 0x59
+				0, // 0x5A
+				KEY_LEFT_BRACE, // 0x5B
+				KEY_BACKSLASH, // 0x5C
+				KEY_RIGHT_BRACE, // 0x5D
+				0, // 0x5E
+				0, // 0x5F
+				KEY_TILDE, // 0x60
+				KEY_A, // 0x61
+				KEY_B, // 0x62
+				KEY_C, // 0x63
+				KEY_D, // 0x64
+				KEY_E, // 0x65
+				KEY_F, // 0x66
+				KEY_G, // 0x67
+				KEY_H, // 0x68
+				KEY_I, // 0x69
+				KEY_J, // 0x6A
+				KEY_K, // 0x6B
+				KEY_L, // 0x6C
+				KEY_M, // 0x6D
+				KEY_N, // 0x6E
+				KEY_O, // 0x6F
+				KEY_P, // 0x70
+				KEY_Q, // 0x71
+				KEY_R, // 0x72
+				KEY_S, // 0x73
+				KEY_T, // 0x74
+				KEY_U, // 0x75
+				KEY_V, // 0x76
+				KEY_W, // 0x77
+				KEY_X, // 0x78
+				KEY_Y, // 0x79
+				KEY_Z, // 0x7A
+				0, // 0x7B
+				0, // 0x7C
+				0, // 0x7D
+				0, // 0x7E
+				KEY_DELETE, // 0x7F
+				0, // 0x80
+				0, // 0x81
+				0, // 0x82
+				0, // 0x83
+				0, // 0x84
+				0, // 0x85
+				0, // 0x86
+				0, // 0x87
+				0, // 0x88
+				0, // 0x89
+				0, // 0x8A
+				0, // 0x8B
+				0, // 0x8C
+				0, // 0x8D
+				0, // 0x8E
+				0, // 0x8F
+				0, // 0x90
+				0, // 0x91
+				0, // 0x92
+				0, // 0x93
+				0, // 0x94
+				0, // 0x95
+				0, // 0x96
+				0, // 0x97
+				0, // 0x98
+				0, // 0x99
+				0, // 0x9A
+				0, // 0x9B
+				0, // 0x9C
+				0, // 0x9D
+				0, // 0x9E
+				0, // 0x9F
+				0, // 0xA0
+				0, // 0xA1
+				0, // 0xA2
+				0, // 0xA3
+				0, // 0xA4
+				0, // 0xA5
+				0, // 0xA6
+				0, // 0xA7
+				0, // 0xA8
+				0, // 0xA9
+				0, // 0xAA
+				0, // 0xAB
+				0, // 0xAC
+				0, // 0xAD
+				0, // 0xAE
+				0, // 0xAF
+				0, // 0xB0
+				KEYPAD_0, // 0xB1
+				KEYPAD_PERIOD, // 0xB2
+				0, // 0xB3
+				0, // 0xB4
+				0, // 0xB5
+				0, // 0xB6
+				0, // 0xB7
+				0, // 0xB8
+				0, // 0xB9
+				0, // 0xBA
+				0, // 0xBB
+				0, // 0xBC
+				0, // 0xBD
+				0, // 0xBE
+				0, // 0xBF
+				KEYPAD_1, // 0xC0
+				KEYPAD_2, // 0xC1
+				KEYPAD_3, // 0xC2
+				KEYPAD_ENTER, // 0xC3
+				0, // 0xC4
+				0, // 0xC5
+				0, // 0xC6
+				0, // 0xC7
+				0, // 0xC8
+				0, // 0xC9
+				0, // 0xCA
+				0, // 0xCB
+				0, // 0xCC
+				0, // 0xCD
+				0, // 0xCE
+				0, // 0xCF
+				KEYPAD_4, // 0xD0
+				KEYPAD_5, // 0xD1
+				KEYPAD_6, // 0xD2
+				KEYPAD_COMMA, // 0xD3
+				0, // 0xD4
+				0, // 0xD5
+				0, // 0xD6
+				0, // 0xD7
+				0, // 0xD8
+				0, // 0xD9
+				0, // 0xDA
+				0, // 0xDB
+				0, // 0xDC
+				0, // 0xDD
+				0, // 0xDE
+				0, // 0xDF
+				0, // 0xE0
+				KEYPAD_7, // 0xE1
+				KEYPAD_8, // 0xE2
+				KEYPAD_9, // 0xE3
+				KEYPAD_MINUS, // 0xE4
+				0, // 0xE5
+				0, // 0xE6
+				0, // 0xE7
+				0, // 0xE8
+				0, // 0xE9
+				0, // 0xEA
+				0, // 0xEB
+				0, // 0xEC
+				0, // 0xED
+				0, // 0xEE
+				0, // 0xEF
+				0, // 0xF0
+				KEY_UP, // 0xF1
+				KEY_DOWN, // 0xF2
+				KEY_LEFT, // 0xF3
+				KEY_RIGHT, // 0xF4
+				KEY_LEFT_SHIFT, // 0xF5
+				KEY_CTRL, // 0xF6
+				0, // 0xF7
+				0, // 0xF8
+				0, // 0xF9
+				0, // 0xFA
+				0, // 0xFB
+				0, // 0xFC
+				0, // 0xFD
+				0, // 0xFE
+				0, // 0xFF
+};
+
+static uint8_t avrcapsense_ColemakMap[] = {
+				0, // 0x00
+				0, // 0x01
+				0, // 0x02
+				0, // 0x03
+				0, // 0x04
+				0, // 0x05
+				0, // 0x06
+				0, // 0x07
+				KEY_BACKSPACE, // 0x08
+				KEY_TAB, // 0x09
+				0, // 0x0A
+				0, // 0x0B
+				0, // 0x0C
+				KEY_ENTER, // 0x0D
+				0, // 0x0E
+				0, // 0x0F
+				0, // 0x10
+				0, // 0x11
+				0, // 0x12
+				0, // 0x13
+				0, // 0x14
+				0, // 0x15
+				0, // 0x16
+				0, // 0x17
+				0, // 0x18
+				0, // 0x19
+				0, // 0x1A
+				KEY_ESC, // 0x1B
+				0, // 0x1C
+				0, // 0x1D
+				0, // 0x1E
+				0, // 0x1F
+				KEY_SPACE, // 0x20
+				0, // 0x21
+				0, // 0x22
+				0, // 0x23
+				0, // 0x24
+				0, // 0x25
+				0, // 0x26
+				KEY_QUOTE, // 0x27
+				0, // 0x28
+				0, // 0x29
+				0, // 0x2A
+				0, // 0x2B
+				KEY_COMMA, // 0x2C
+				KEY_MINUS, // 0x2D
+				KEY_PERIOD, // 0x2E
+				KEY_SLASH, // 0x2F
+				KEY_0, // 0x30
+				KEY_1, // 0x31
+				KEY_2, // 0x32
+				KEY_3, // 0x33
+				KEY_4, // 0x34
+				KEY_5, // 0x35
+				KEY_6, // 0x36
+				KEY_7, // 0x37
+				KEY_8, // 0x38
+				KEY_9, // 0x39
+				0, // 0x3A
+				KEY_O, // 0x3B
+				0, // 0x3C
+				KEY_EQUAL, // 0x3D
+				0, // 0x3E
+				0, // 0x3F
+				0, // 0x40
+				0, // 0x41
+				0, // 0x42
+				0, // 0x43
+				0, // 0x44
+				0, // 0x45
+				0, // 0x46
+				0, // 0x47
+				0, // 0x48
+				0, // 0x49
+				0, // 0x4A
+				0, // 0x4B
+				0, // 0x4C
+				0, // 0x4D
+				0, // 0x4E
+				0, // 0x4F
+				0, // 0x50
+				0, // 0x51
+				0, // 0x52
+				0, // 0x53
+				0, // 0x54
+				0, // 0x55
+				0, // 0x56
+				0, // 0x57
+				0, // 0x58
+				0, // 0x59
+				0, // 0x5A
+				KEY_LEFT_BRACE, // 0x5B
+				KEY_BACKSLASH, // 0x5C
+				KEY_RIGHT_BRACE, // 0x5D
+				0, // 0x5E
+				0, // 0x5F
+				KEY_TILDE, // 0x60
+				KEY_A, // 0x61
+				KEY_B, // 0x62
+				KEY_C, // 0x63
+				KEY_S, // 0x64
+				KEY_F, // 0x65
+				KEY_T, // 0x66
+				KEY_D, // 0x67
+				KEY_H, // 0x68
+				KEY_U, // 0x69
+				KEY_N, // 0x6A
+				KEY_E, // 0x6B
+				KEY_I, // 0x6C
+				KEY_M, // 0x6D
+				KEY_K, // 0x6E
+				KEY_Y, // 0x6F
+				KEY_SEMICOLON, // 0x70
+				KEY_Q, // 0x71
+				KEY_P, // 0x72
+				KEY_R, // 0x73
+				KEY_G, // 0x74
+				KEY_L, // 0x75
+				KEY_V, // 0x76
+				KEY_W, // 0x77
+				KEY_X, // 0x78
+				KEY_J, // 0x79
+				KEY_Z, // 0x7A
+				0, // 0x7B
+				0, // 0x7C
+				0, // 0x7D
+				0, // 0x7E
+				KEY_DELETE, // 0x7F
+				0, // 0x80
+				0, // 0x81
+				0, // 0x82
+				0, // 0x83
+				0, // 0x84
+				0, // 0x85
+				0, // 0x86
+				0, // 0x87
+				0, // 0x88
+				0, // 0x89
+				0, // 0x8A
+				0, // 0x8B
+				0, // 0x8C
+				0, // 0x8D
+				0, // 0x8E
+				0, // 0x8F
+				0, // 0x90
+				0, // 0x91
+				0, // 0x92
+				0, // 0x93
+				0, // 0x94
+				0, // 0x95
+				0, // 0x96
+				0, // 0x97
+				0, // 0x98
+				0, // 0x99
+				0, // 0x9A
+				0, // 0x9B
+				0, // 0x9C
+				0, // 0x9D
+				0, // 0x9E
+				0, // 0x9F
+				0, // 0xA0
+				0, // 0xA1
+				0, // 0xA2
+				0, // 0xA3
+				0, // 0xA4
+				0, // 0xA5
+				0, // 0xA6
+				0, // 0xA7
+				0, // 0xA8
+				0, // 0xA9
+				0, // 0xAA
+				0, // 0xAB
+				0, // 0xAC
+				0, // 0xAD
+				0, // 0xAE
+				0, // 0xAF
+				0, // 0xB0
+				KEYPAD_0, // 0xB1
+				KEYPAD_PERIOD, // 0xB2
+				0, // 0xB3
+				0, // 0xB4
+				0, // 0xB5
+				0, // 0xB6
+				0, // 0xB7
+				0, // 0xB8
+				0, // 0xB9
+				0, // 0xBA
+				0, // 0xBB
+				0, // 0xBC
+				0, // 0xBD
+				0, // 0xBE
+				0, // 0xBF
+				KEYPAD_1, // 0xC0
+				KEYPAD_2, // 0xC1
+				KEYPAD_3, // 0xC2
+				KEYPAD_ENTER, // 0xC3
+				0, // 0xC4
+				0, // 0xC5
+				0, // 0xC6
+				0, // 0xC7
+				0, // 0xC8
+				0, // 0xC9
+				0, // 0xCA
+				0, // 0xCB
+				0, // 0xCC
+				0, // 0xCD
+				0, // 0xCE
+				0, // 0xCF
+				KEYPAD_4, // 0xD0
+				KEYPAD_5, // 0xD1
+				KEYPAD_6, // 0xD2
+				KEYPAD_COMMA, // 0xD3
+				0, // 0xD4
+				0, // 0xD5
+				0, // 0xD6
+				0, // 0xD7
+				0, // 0xD8
+				0, // 0xD9
+				0, // 0xDA
+				0, // 0xDB
+				0, // 0xDC
+				0, // 0xDD
+				0, // 0xDE
+				0, // 0xDF
+				0, // 0xE0
+				KEYPAD_7, // 0xE1
+				KEYPAD_8, // 0xE2
+				KEYPAD_9, // 0xE3
+				KEYPAD_MINUS, // 0xE4
+				0, // 0xE5
+				0, // 0xE6
+				0, // 0xE7
+				0, // 0xE8
+				0, // 0xE9
+				0, // 0xEA
+				0, // 0xEB
+				0, // 0xEC
+				0, // 0xED
+				0, // 0xEE
+				0, // 0xEF
+				0, // 0xF0
+				KEY_UP, // 0xF1
+				KEY_DOWN, // 0xF2
+				KEY_LEFT, // 0xF3
+				KEY_RIGHT, // 0xF4
+				KEY_LEFT_SHIFT, // 0xF5
+				KEY_CTRL, // 0xF6
+				0, // 0xF7
+				0, // 0xF8
+				0, // 0xF9
+				0, // 0xFA
+				0, // 0xFB
+				0, // 0xFC
+				0, // 0xFD
+				0, // 0xFE
+				0, // 0xFF
+};
+
+
+
+#endif
+
--- a/Keymap/keymap.h	Sat Apr 13 20:11:40 2013 -0400
+++ b/Keymap/keymap.h	Sat Apr 13 22:35:59 2013 -0400
@@ -41,6 +41,7 @@
 
 
 // See files for full layout descriptions
+#include "avrcapsense.h"
 #include "betkb.h"
 #include "budkeypad.h"
 #include "epsonqx10.h"
--- a/Scan/avr-capsense/scan_loop.c	Sat Apr 13 20:11:40 2013 -0400
+++ b/Scan/avr-capsense/scan_loop.c	Sat Apr 13 22:35:59 2013 -0400
@@ -1,1391 +1,1123 @@
-/* Keyboard example with debug channel, for Teensy USB Development Board
- * http://www.pjrc.com/teensy/usb_keyboard.html
- * Copyright (c) 2008 PJRC.COM, LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <avr/io.h>
-#include <avr/pgmspace.h>
-#include <avr/interrupt.h>
-#include <util/delay.h>
-#include "usb_keyboard_debug.h"
-#include "print.h"
-
-#define LED_CONFIG	(DDRD |= (1<<6))
-#define LED_ON		(PORTD &= ~(1<<6))
-#define LED_OFF		(PORTD |= (1<<6))
-#define CPU_PRESCALE(n)	(CLKPR = 0x80, CLKPR = (n))
-
-#define THRESHOLD 0x0a
-#define BUMP_THRESHOLD 0x50
-//((THRESHOLD) * 3)
-#define BUMP_REST_US 1200
-
-#define HYST 1
-#define HYST_T 0x10
-
-#define TEST_KEY_STROBE (0x05)
-#define TEST_KEY_MASK (1 << 0)
-
-#define ADHSM 7
-
-/** Whether to use all of D and C, vs using E0, E1 instead of D6, D7,
- * or alternately all of D, and E0,E1 and C0,..5 */
-//#define ALL_D_C
-//#define SHORT_D
-#define SHORT_C
-
-// rough offset voltage: one diode drop, about 50mV = 0x3ff * 50/3560 = 20
-//#define OFFSET_VOLTAGE 0x14
-#define OFFSET_VOLTAGE 0x28
-
-volatile uint8_t idle_count=1;
-
-uint8_t blink=0;
-
-volatile uint16_t full_av = 0;
-
-#define RIGHT_JUSTIFY 0
-#define LEFT_JUSTIFY (0xff)
-
-// set left or right justification here:
-#define JUSTIFY_ADC RIGHT_JUSTIFY
-
-#define ADLAR_MASK (1 << ADLAR)
-#ifdef JUSTIFY_ADC
-#define ADLAR_BITS ((ADLAR_MASK) & (JUSTIFY_ADC))
-#else // defaults to right justification.
-#define ADLAR_BITS 0
-#endif
-
-
-// full muxmask
-#define FULL_MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2) | (1 << MUX3) | (1 << MUX4))
-
-// F0-f7 pins only muxmask.
-#define MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2))
-
-#define SET_MUX(X) ((ADMUX) = (((ADMUX) & ~(MUX_MASK)) | ((X) & (MUX_MASK))))
-#define SET_FULL_MUX(X) ((ADMUX) = (((ADMUX) & ~(FULL_MUX_MASK)) | ((X) & (FULL_MUX_MASK))))
-
-#define MUX_1_1 0x1e
-#define MUX_GND 0x1f
-
-
-	// set ADC clock prescale
-#define PRESCALE_MASK ((1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2))
-#define PRESCALE_SHIFT (ADPS0)
-#define PRESCALE 3
-
-
-/**/ uint8_t ze_strober = 0;
-
-#ifdef EXTENDED_STROBE
-
-#define STROBE_LINES 18
-
-#else
-
-#define STROBE_LINES 16
-
-#endif
-
-#define STROBE_LINES_XSHIFT 4
-#define STROBE_LINES_MASK 0x0f
-#define MUXES_COUNT 8
-#define MUXES_COUNT_XSHIFT 3
-#define MUXES_MASK 0x7
-
-#define WARMUP_LOOPS ( 1024 )
-
-#define RECOVERY_US 6
-
-#define SAMPLES 10
-int16_t samples [SAMPLES];
-
-//int16_t gsamples [SAMPLES];
-
-#define SAMPLE_OFFSET ((SAMPLES) - MUXES_COUNT)
-//#define SAMPLE_OFFSET 9
-#define STROBE_OFFSET 0
-
-/**/ int16_t adc_mux_averages[MUXES_COUNT];
-/**/ int16_t adc_strobe_averages[STROBE_LINES];
-
-
-/**/ uint8_t cur_keymap[STROBE_LINES];
-// /**/ int8_t last_keymap[STROBE_LINES];
-/**/ uint8_t usb_keymap[STROBE_LINES];
-uint8_t dirty;
-uint8_t unstable;
-uint8_t usb_dirty;
-
-int16_t threshold = THRESHOLD;
-uint16_t tests = 0;
-
-uint8_t col_a=0;
-uint8_t col_b=0;
-uint8_t col_c=0;
-
-uint8_t column=0;
-
-#define KEY_COUNT ((STROBE_LINES) * (MUXES_COUNT))
-
-int16_t keys_averages_acc[KEY_COUNT];
-uint16_t keys_averages[KEY_COUNT];
-
-uint8_t full_samples[KEY_COUNT];
-
-/* viable starting biases for near 0.830V offset. and adc PRESCALE 3
-0017 0016 001B 001A 0016 0016 000F 000E 001B 001E 001E 0018 0017 0015 000E 001D
-001B 001A 0016 0016 000F 000E 001C 001B 001E 0018 0017 0015 000E 001D 0024 001F
-0016 0016 000F 000E 001C 001B 001E 001E 0017 0015 000E 001D 0024 001F 0020 001F
-000F 000E 001C 001B 001E 001E 0018 0017 000E 001D 0024 001F 0020 001F 0020 0017
-001C 001B 001E 001E 0018 0017 0015 000E 0024 001F 0020 001F 0020 0017 0010 001D
-001E 001E 0018 0017 0015 000E 001D 0024 0020 001F 0020 0017 0010 001D 0024 0021
-0018 0017 0015 000E 001D 0024 001F 0020 0020 0017 0010 001D 0024 0021 0021 0021
-0015 000E 001D 0024 001F 0020 001F 0020 0010 001D 0024 0021 0021 0021 0021 0018
-*/
-
-/*** starting bias relative to fixed offset estimate of 820mV (0x50)
- *   77 69 65 5B 50 4E 4C 45   66 53 4D 49 45 3F 3E 35
- *   68 54 4F 49 45 40 3F 34   74 66 5F 56 4E 4D 4C 3F
- *   6D 5D 53 4C 49 46 45 38   6D 5A 53 4E 49 48 45 3E
- *   6F 5D 56 4E 4B 48 48 3A   6D 5C 54 4E 48 48 45 37
- *   75 68 5F 57 4F 4D 4C 3F   60 4E 48 41 3C 3C 39 2F
- *   65 53 4E 49 41 3F 3E 34   65 54 4E 49 43 3F 3E 34
- *   60 51 4A 45 3F 3E 3C 30   57 4C 45 3E 3B 37 37 2E
- *   64 4E 48 44 3C 3B 39 2F   5D 4F 48 45 3E 3C 3B 30
- */
-
-/*volatile*/ uint16_t count = 0;
-
-
-
-/*volatile*/ uint8_t error = 0;
-uint16_t error_data = 0;
-
-void dump(void);
-void dumpkeys(void);
-
-static const uint8_t PROGMEM matrix122F_to_set3[] = {
-0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x84, // (), npenter, np3, (), np+, np9, np*, np-
-0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, // np0, np., np2, np5, np6, np8, numlck, np/
-0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, //
-0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
-0x00, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, // 0x50 vanishes - is test key.
-0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, // 0x48 vanishes - else roll back.
-0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
-0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
-0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
-0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
-0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
-0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
-0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
-0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
-0x01, 0x83, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 0x02 is replaced with 0x83.
-};
-
-#define LX2FX
-
-static const uint8_t PROGMEM page3_2_USB[133] = {
-0x0,		// 00   00  // no key.
-
-#ifndef LX2FX
-
-0xe3,		// 01       Enl   Help -> windows. (e3)
-0x0,		// 02		// no key.
-0x80,	// 03   A4  ExSel SetUp print, -> paste 7d -> vol up 80
-0x46,	// 04   A3  CrSel       Properties -> copy 7c -> mute 7f-> prt-scrn
-0x29,	// 05   9A  Attn  SysRq // good place fer escape. (29)
-0x47,		// 06   9C  Clear -> kp / 54 -> scroll-lock (47)
-0x3a,		// 07   3A  F1
-0x68,		// 08   68  F13
-0x65,		// 09       Ctrl	// record/pause // -> kb application (65)
-0x74,		// 0A       Copy  Test // play/test -> execute 74 -> kp + 57
-0x75,		// 0B      // no key. help (75) -> kp - 56
-0x48,		// 0C       Pause ErInp erase input. -> cut 7b -> kp * 55 -> pause 48
-
-#else
-
-/*
-0x42,		// 01       L9
-0x0,		// 02		// no key.
-0x3e,		// 03		L5
-0x3c,		// 04		L3
-0x3a,		// 05      	L1
-0x3b,		// 06      	L2
-0x3a,		// 07   3A  F1
-0x68,		// 08   68  F13
-0x43,		// 09      	L10
-0x41,		// 0A      	L8
-0x3f,		// 0B      	L6
-0x3d,		// 0C      	L4
-*/
-0x61,		// 01       L9 -> num 9  0x61
-0x0,		// 02		// no key.
-0x5d,		// 03		L5 -> num 5  0x5d
-0x5b,		// 04		L3 -> num 3  0x5b
-0x59,		// 05      	L1 -> num 1  0x59
-0x5a,		// 06      	L2 -> num 2  0x5a
-0x3a,		// 07   3A  F1
-0x68,		// 08   68  F13
-0x62,		// 09      	L10 -> num 0 0x62
-0x60,		// 0A      	L8 -> num 8 0x60
-0x5e,		// 0B      	L6 -> num 6 0x5e
-0x5c,		// 0C      	L4 -> num 4 0x5c
-#endif
-
-
-0x2b,		// 0D   2B  Tab
-0x29,		// 0E   35  ~ ` -> escape 29
-0x3b,		// 0F   3B  F2
-0x69,		// 10   69  F14
-0xe0,		// 11   E0  Ctrl L
-0xe1,		// 12   E1  Shift L
-0xe1,		// 13   64  left of z. -> l shift e1
-0x39,		// 14   39  Caps Lock
-0x14,		// 15   14  Q
-0x1e,		// 16   1E  ! 1
-0x3c,		// 17   3C  F3
-0x6a,		// 18   6A  F15
-0xe2,		// 19   E2  Alt L
-0x1d,		// 1A   1D  Z
-0x16,		// 1B   16  S
-0x04,		// 1C   04  A
-0x1a,		// 1D   1A  W
-0x1f,		// 1E   1F  @ 2
-0x3d,		// 1F   3D  F4
-0x6b,		// 20   6B  F16
-0x06,		// 21   06  C
-0x1b,		// 22   1B  X
-0x07,		// 23   07  D
-0x08,		// 24   08  E
-0x21,		// 25   21  $ 4
-0x20,		// 26   20  # 3
-0x3e,		// 27   3E  F5
-0x6c,		// 28   6C  F17
-0x2c,		// 29   2C  Space
-0x19,		// 2A   19  V
-0x09,		// 2B   09  F
-0x17,		// 2C   17  T
-0x15,		// 2D   15  R
-0x22,		// 2E   22  % 5
-0x3f,		// 2F   3F  F6
-0x6d,		// 30   6D  F18
-0x11,		// 31   11  N
-0x05,		// 32   05  B
-0x0b,		// 33   0B  H
-0x0a,		// 34   0A  G
-0x1c,		// 35   1C  Y
-0x23,		// 36   23  ^ 6
-0x40,		// 37   40  F7
-0x6e,		// 38   6E  F19
-0xe6,		// 39   E6  Alt R
-0x10,		// 3A   10  M
-0x0d,		// 3B   0D  J
-0x18,		// 3C   18  U
-0x24,		// 3D   24  & 7
-0x25,		// 3E   25  * 8
-0x41,		// 3F   41  F8
-0x6f,		// 40   6F  F20
-0x36,		// 41   36  < ,
-0x0e,		// 42   0E  K
-0x0c,		// 43   0C  I
-0x12,		// 44   12  O
-0x27,		// 45   27  ) 0
-0x26,		// 46   26  ( 9
-0x42,		// 47   42  F9
-0x70,		// 48   70  F21
-0x37,		// 49   37  > .
-0x38,		// 4A   38  ? /
-0x0f,		// 4B   0F  L
-0x33,		// 4C   33  : ;
-0x13,		// 4D   13  P
-0x2d,		// 4E   2D  _ -
-0x43,		// 4F   43  F10
-0x71,		// 50   71  F22
-0xe5,		// 51   87  likely a shift - e.g. kp shift -> e5
-0x34,		// 52   34  " '
-0x31,		// 53      (INT 2) -> keypad enter. 58 -> |/\ (31)
-0x2f,		// 54   2F  { [
-0x2e,		// 55   2E  + =
-0x44,		// 56   44  F11
-0x72,		// 57   72  F23  -> vol up.
-0xe4,		// 58   E4  Ctrl R
-0xe5,		// 59   E5  Shift R
-0x28,		// 5A   28  Enter
-0x30,		// 5B   30  } ]
-0x31,		// 5C   31  | '\'
-0x35,		// 5D   -> kp = 67 -> ~` 35
-0x45,		// 5E   45  F12
-0x73,		// 5F   73  F24 -> vol down.
-0x51,		// 60   51  Down CP
-0x50,		// 61   50  Left CP
-0x51, //0x0,// 62       Rule // centre cp.  //62   48  Pause/Bk
-0x52,		// 63   52  Up CP
-0x4c,		// 64   4C  Del CP
-0x4d,		// 65   4D  End CP
-0x2a,		// 66   2A  Back Space
-0x49,		// 67   49  Ins CP
-0x48,		// 68		// under kp0 => kp 0 (62) 48 -> pause (48)
-0x59,		// 69   59  1 End KP
-0x4f,		// 6A   4F  Right CP
-0x5c,		// 6B   5C  4 Left KP
-0x5f,		// 6C   5F  7 Home KP
-0x4e,		// 6D   4E  PgDn CP
-0x4a,		// 6E   4A  Home CP
-0x4b,		// 6F   4B  PgUp CP
-0x62,		// 70   62  0 Ins KP -> pause (+48) -> kp-0 (62)
-0x63,		// 71   63  . Del KP
-0x5a,		// 72   5A  2 Down KP
-0x5d,		// 73   97  5 KP
-0x5e,		// 74   5E  6 Right KP
-0x60,		// 75   60  8 Up KP
-0x53,		// 76   53  Num Lock
-0x54,		// 77   54  / KP
-0x47,		// 78       Undo // under enter -> scroll-lock 47
-0x58,		// 79   58  Enter KP ->  enter kp
-0x5b,		// 7A   5B  3 PgDn KP
-0x46,		// 7B       (INT 5) // under + -> print screen (46
-0x57,		// 7C   57  + KP
-0x61,		// 7D   61  9 PgUp KP
-0x55,		// 7E   55  * KP
-0x0,		// 7F			no such key?
-0x0,		// 80           no such key
-0x0,		// 81              Paste?
-0x0,		// 82              Find?
-#ifndef LX2FX
-0x81,		// 83   Print Ident -> undo 7a -> vol down 81
-#else
-//0x40,		// 83   L7 (f1) 3a
-0x5f,		// 83   L7 (f1) 3a -> num 7 0x5f
-#endif
-0x56		// 84   56  - KP
-};
-
-void
-_delay_loop(uint8_t __count)
-{
-	__asm__ volatile (
-		"1: dec %0" "\n\t"
-		"brne 1b"
-		: "=r" (__count)
-		: "0" (__count)
-	);
-}
-
-
-void setup_ADC (void) {
-	// disable adc digital pins.
-	DIDR1 |= (1 << AIN0D) | (1<<AIN1D); // set disable on pins 1,0.
-	//DIDR0 = 0xff; // disable all. (port F, usually). - testing w/o disable.
-	DDRF = 0x0;
-	PORTF = 0x0;
-	uint8_t mux = 0 & 0x1f; // 0 == first. // 0x1e = 1.1V ref.
-
-	// 0 = external aref 1,1 = 2.56V internal ref
-	uint8_t aref = ((1 << REFS1) | (1 << REFS0)) & ((1 << REFS1) | (1 << REFS0));
-//	uint8_t adlar = 0xff & (1 << ADLAR); // 1 := left justify bits, 0 := right
-	uint8_t adate = (1 << ADATE) & (1 << ADATE); // trigger enable
-	uint8_t trig = 0 & ((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2)); // 0 = free running
-	// ps2, ps1 := /64 ( 2^6 ) ps2 := /16 (2^4), ps1 := 4, ps0 :=2, PS1,PS0 := 8 (2^8)
-	uint8_t prescale = ( ((PRESCALE) << PRESCALE_SHIFT) & PRESCALE_MASK ); // 001 == 2^1 == 2
-	uint8_t hispeed = (1 << ADHSM);
-	uint8_t en_mux = (1 << ACME);
-
-	//ADCSRA = (ADCSRA & ~PRESCALES) | ((1 << ADPS1) | (1 << ADPS2)); // 2, 1 := /64 ( 2^6 )
-	//ADCSRA = (ADCSRA & ~PRESCALES) | ((1 << ADPS0) | (1 << ADPS2)); // 2, 0 := /32 ( 2^5 )
-	//ADCSRA = (ADCSRA & ~PRESCALES) | ((1 << ADPS2)); // 2 := /16 ( 2^4 )
-
-	ADCSRA = (1 << ADEN) | prescale; // ADC enable
-
-	// select ref.
-	//ADMUX |= ((1 << REFS1) | (1 << REFS0)); // 2.56 V internal.
-	//ADMUX |= ((1 << REFS0) ); // Vcc with external cap.
-	//ADMUX &= ~((1 << REFS1) | (1 << REFS0)); // 0,0 : aref.
-	ADMUX = aref | mux | ADLAR_BITS;
-
-	// enable MUX
-	// ADCSRB |= (1 << ACME); 	// enable
-	// ADCSRB &= ~(1 << ADEN); // ?
-
-	// select first mux.
-	//ADMUX = (ADMUX & ~MUXES); // start at 000 = ADC0
-
-	// clear adlar to left justify data
-	//ADMUX = ~();
-
-	// set adlar to right justify data
-	//ADMUX |= (1 << ADLAR);
-
-
-	// set free-running
-	ADCSRA |= adate; // trigger enable
-	ADCSRB  = en_mux | hispeed | trig | (ADCSRB & ~((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2))); // trigger select free running
-
-//	ADCSRA |= (1 << ADATE); // tiggger enable
-
-	ADCSRA |= (1 << ADEN); // ADC enable
-	ADCSRA |= (1 << ADSC); // start conversions q
-
-}
-
-
-#define RECOVERY_CONTROL 1
-
-#define RECOVERY_SOURCE 0
-#define RECOVERY_SINK 2
-#define RECOVERY_MASK 0x03
-
-void recovery(uint8_t on) {
-	DDRB |= (1 << RECOVERY_CONTROL);
-
-	PORTB &= ~(1 << RECOVERY_SINK);    // SINK always zero
-	DDRB &= ~(1 << RECOVERY_SOURCE);  // SOURCE high imp
-
-	if(on) {
-		DDRB |= (1 << RECOVERY_SINK);	// SINK pull
-
-
-		PORTB |= (1 << RECOVERY_CONTROL);
-
-		PORTB |= (1 << RECOVERY_SOURCE); // SOURCE high
-		DDRB |= (1 << RECOVERY_SOURCE);
-	} else {
-		_delay_loop(10);
-		PORTB &= ~(1 << RECOVERY_CONTROL);
-
-		DDRB &= ~(1 << RECOVERY_SOURCE);
-		PORTB &= ~(1 << RECOVERY_SOURCE); // SOURCE low
-		DDRB &= ~(1 << RECOVERY_SINK);	// SINK high-imp
-
-		//DDRB &= ~(1 << RECOVERY_SINK);
-	}
-}
-
-void strobe_w(uint8_t strobe_num) {
-
-#ifdef ALL_D_C
-
-#define D_MASK (0xff)
-#define D_SHIFT 0
-
-#define E_MASK (0x00)
-#define E_SHIFT 0
-
-#define C_MASK (0xff)
-#define C_SHIFT 8
-
-#else
-#if defined(SHORT_D)
-
-#define D_MASK (0x3f)
-#define D_SHIFT 0
-
-#define E_MASK (0x03)
-#define E_SHIFT 6
-
-#define C_MASK (0xff)
-#define C_SHIFT 8
-
-#else
-#if defined(SHORT_C)
-
-#define D_MASK (0xff)
-#define D_SHIFT 0
-
-#define E_MASK (0x03)
-#define E_SHIFT 6
-
-#define C_MASK (0xff)
-#define C_SHIFT 8
-#endif
-#endif
-#endif
-
-
-
-#define STROBE_CASE(SC_CASE, SC_REG_A) case (SC_CASE): PORT##SC_REG_A = \
-	(( (PORT##SC_REG_A) & ~(1 << (SC_CASE - SC_REG_A##_SHIFT)) ) | (1 << (SC_CASE - SC_REG_A##_SHIFT)))
-
-	PORTC &= ~(D_MASK);
-	PORTD &= ~(D_MASK);
-	PORTE &= ~(E_MASK);
-
-#ifdef SHORT_C
-	strobe_num = 15 - strobe_num;
-#endif
-
-	switch(strobe_num) {
-
-	case 0: PORTD |= (1 << 0); break;
-	case 1: PORTD |= (1 << 1); break;
-	case 2: PORTD |= (1 << 2); break;
-	case 3: PORTD |= (1 << 3); break;
-	case 4: PORTD |= (1 << 4); break;
-	case 5: PORTD |= (1 << 5); break;
-
-#ifdef ALL_D
-
-	case 6: PORTD |= (1 << 6); break;
-	case 7: PORTD |= (1 << 7); break;
-
-	case 8:  PORTC |= (1 << 0); break;
-	case 9:  PORTC |= (1 << 1); break;
-	case 10: PORTC |= (1 << 2); break;
-	case 11: PORTC |= (1 << 3); break;
-	case 12: PORTC |= (1 << 4); break;
-	case 13: PORTC |= (1 << 5); break;
-	case 14: PORTC |= (1 << 6); break;
-	case 15: PORTC |= (1 << 7); break;
-
-	case 16: PORTE |= (1 << 0); break;
-	case 17: PORTE |= (1 << 1); break;
-
-#else
-#ifdef SHORT_D
-
-	case 6: PORTE |= (1 << 0); break;
-	case 7: PORTE |= (1 << 1); break;
-
-	case 8:  PORTC |= (1 << 0); break;
-	case 9:  PORTC |= (1 << 1); break;
-	case 10: PORTC |= (1 << 2); break;
-	case 11: PORTC |= (1 << 3); break;
-	case 12: PORTC |= (1 << 4); break;
-	case 13: PORTC |= (1 << 5); break;
-	case 14: PORTC |= (1 << 6); break;
-	case 15: PORTC |= (1 << 7); break;
-
-#else
-#ifdef SHORT_C
-
-	case 6: PORTD |= (1 << 6); break;
-	case 7: PORTD |= (1 << 7); break;
-
-	case 8: PORTE |= (1 << 0); break;
-	case 9: PORTE |= (1 << 1); break;
-
-	case 10:  PORTC |= (1 << 0); break;
-	case 11:  PORTC |= (1 << 1); break;
-	case 12: PORTC |= (1 << 2); break;
-	case 13: PORTC |= (1 << 3); break;
-	case 14: PORTC |= (1 << 4); break;
-	case 15: PORTC |= (1 << 5); break;
-
-	case 16: PORTC |= (1 << 6); break;
-	case 17: PORTC |= (1 << 7); break;
-
-#endif
-#endif
-#endif
-
-	default:
-		break;
-	}
-
-}
-
-
-int sampleColumn_i(uint8_t column, uint8_t muxes, int16_t * buffer) {
-
-	// ensure all probe lines are driven low, and chill for recovery delay.
-	PORTC &= ~C_MASK;
-	PORTD &= ~D_MASK;
-	PORTE &= ~E_MASK;
-	recovery(1);
-	_delay_us(RECOVERY_US);
-	recovery(0);
-
-	uint8_t index = 0;
-
-	for (uint8_t i=0; i<8; ++i) {
-		if(muxes & (1 << i)) {
-			buffer[index++] = i;
-		}
-	}
-
-	SET_FULL_MUX(MUX_1_1); // crap sample will use this.
-	ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions
-	ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
-
-	uint16_t sample;
-
-	while (! (ADCSRA & (1 << ADIF))); // wait until ready.
-	sample = ADC; // 1st sample, icky.
-
-	strobe_w(column);
-	//recovery(0);
-
-	/**
-	 * we are running in continuous mode, so we must setup the next
-	 * read _before_ the current read completes.
-	 *
-	 * setup 0,
-	 * read garbage,
-	 * do not store
-	 *
-	 * setup 1,
-	 * read 0,
-	 * store 0,
-	 *
-	 * ...
-	 *
-	 * setup junk,
-	 * read n
-	 * store n
-	 *
-	 * */
-
-
-	ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
-	//wait for last read to complete.
-	while (! (ADCSRA & (1 << ADIF)));
-	sample = ADC; // throw away strobe'd value.
-
-#if 0
-	for (uint8_t i=0; i <= index; ++i) {
-
-		// setup i'th read.
-		SET_FULL_MUX(buffer[i]); // _next_ read will use this.
-		// wait for i-1'th read to complete:
-		ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
-		while (! (ADCSRA & (1 << ADIF)));
-
-		// retrieve last (i-1'th) read.
-		if (i) {
-			buffer[i-1] = ADC - OFFSET_VOLTAGE;
-		} /*else {
-			buffer[0] = ADC - OFFSET_VOLTAGE;
-		}*/
-
-		//index++;
-	}
-#else
-	for (uint8_t i=0; i < index; ++i) {
-
-		// setup i'th read.
-		SET_FULL_MUX(buffer[i]); // _next_ read will use this.
-
-		ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
-		while (! (ADCSRA & (1 << ADIF)));
-		sample = ADC; // throw away warmup value.
-
-
-
-		/*
-		ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
-		while (! (ADCSRA & (1 << ADIF)));
-		sample = ADC; // throw away warmup value.
-*/
-
-		ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
-		while (! (ADCSRA & (1 << ADIF)));
-
-		// retrieve current read.
-		buffer[i] = ADC - OFFSET_VOLTAGE;
-
-
-	}
-#endif
-
-
-	// turn off adc.
-	ADCSRA &= ~(1 << ADEN);
-
-	// pull all columns' probe-lines low.
-	PORTC &= ~C_MASK;
-	PORTD &= ~D_MASK;
-	PORTE &= ~E_MASK;
-
-	// test for humps. :/
-	/*uint16_t delta = full_av;
-	if(buffer[0] > BUMP_THRESHOLD + delta) {
-		// ze horror.
-		return 1;
-	} else {
-		return 0; //all good.
-	}*/
-	return 0;
-
-}
-
-int sampleColumn_k(uint8_t column, int16_t * buffer) {
-	// ensure all probe lines are driven low, and chill for recovery delay.
-	uint16_t sample;
-
-	ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions
-	ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
-
-	// sync up with adc clock:
-	while (! (ADCSRA & (1 << ADIF))); // wait until ready.
-	sample = ADC; // throw it away.
-
-	for(uint8_t mux=0; mux < 8; ++mux) {
-
-		PORTC &= ~C_MASK;
-		PORTD &= ~D_MASK;
-		PORTE &= ~E_MASK;
-
-		SET_FULL_MUX(mux); // our sample will use this
-
-		for(uint8_t i=0; i < 2; ++i) {
-			ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
-			//wait for last read to complete.
-			while (! (ADCSRA & (1 << ADIF)));
-			sample = ADC; // throw away strobe'd value.
-		}
-
-		recovery(0);
-		strobe_w(column);
-
-		ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
-		//wait for last read to complete.
-		while (! (ADCSRA & (1 << ADIF)));
-		sample = ADC; // throw away strobe'd value.
-
-		ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
-		while (! (ADCSRA & (1 << ADIF)));
-
-		// retrieve current read.
-		buffer[mux] = ADC - OFFSET_VOLTAGE;
-		recovery(1);
-
-	}
-
-	// turn off adc.
-	ADCSRA &= ~(1 << ADEN);
-
-	// pull all columns' probe-lines low.
-	PORTC &= ~C_MASK;
-	PORTD &= ~D_MASK;
-	PORTE &= ~E_MASK;
-//		recovery(1);
-
-
-	return 0;
-}
-
-int sampleColumn(uint8_t column) {
-	int rval = 0;
-
-	/*
-	sampleColumn_i(column, 0x0f, samples+SAMPLE_OFFSET);
-	sampleColumn_i(column, 0xf0, samples+SAMPLE_OFFSET + 4 );
-*/
-
-	rval = sampleColumn_k(column, samples+SAMPLE_OFFSET);
-
-	for(uint8_t i=0; i<8; ++i) {
-		if(samples[SAMPLE_OFFSET + i] - adc_mux_averages[i] > BUMP_THRESHOLD) {
-			// was a hump
-
-			_delay_us(BUMP_REST_US);
-			rval++;
-			error = 0x50;
-			error_data = samples[SAMPLE_OFFSET +i]; //  | ((uint16_t)i << 8);
-			return rval;
-		}
-	}
-
-	return rval;
-}
-
-
-
-uint8_t testColumn(uint8_t strobe) {
-    uint8_t column = 0;
-    uint8_t bit = 1;
-    for (uint8_t i=0; i < MUXES_COUNT; ++i) {
-		uint16_t delta = keys_averages[(strobe << MUXES_COUNT_XSHIFT) + i];
-		if ((int16_t)samples[SAMPLE_OFFSET + i] > threshold + delta) {
-			column |= bit;
-		}
-		bit <<= 1;
-	}
-    return column;
-}
-
-int main(void) {
-	// set for 16 MHz clock
-	CPU_PRESCALE(0);
-
-	// Initialize the USB, and then wait for the host to set configuration.
-	// If the Teensy is powered without a PC connected to the USB port,
-	// this will wait forever.
-	usb_init();
-	while (!usb_configured()) /* wait */ ;
-
-	// Wait an extra second for the PC's operating system to load drivers
-	// and do whatever it does to actually be ready for input
-	_delay_ms(1000);
-
-	LED_CONFIG;
-
-	setup_ADC();
-
-	// Configure timer 0 to generate a timer overflow interrupt every
-	// 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock
-	// This demonstrates how to use interrupts to implement a simple
-	// inactivity timeout.
-	//TCCR0A = 0x00;
-	//TCCR0B = 0x05;
-	//TIMSK0 = (1<<TOIE0);
-
-	DDRC = C_MASK;
-	PORTC = 0;
-	DDRD = D_MASK;
-	PORTD = 0;
-	DDRE = E_MASK;
-	PORTE = 0 ;
-
-	//DDRC |= (1 << 6);
-	//PORTC &= ~(1<< 6);
-
-	//uint16_t strobe = 1;
-
-
-	uint8_t strober = 0;
-	uint32_t full_av_acc = 0;
-
-	for (int i=0; i< STROBE_LINES; ++i) {
-		cur_keymap[i] = 0;
-		//last_keymap[i] = 0;
-		usb_keymap[i] = 0;
-	}
-
-	int16_t mux_averages[MUXES_COUNT];
-	for(int i=0; i < MUXES_COUNT; ++i) {
-		adc_mux_averages[i] = 0x20; // experimentally determined.
-	}
-	int16_t strobe_averages[STROBE_LINES];
-	for(int i=0; i < STROBE_LINES; ++i) {
-		adc_strobe_averages[i] = 0x20; // yup.
-	}
-
-	for(int i=0; i< KEY_COUNT; ++i) {
-		keys_averages[i] = 0x40;
-		keys_averages_acc[i] = (0x400);
-	}
-
-	/** warm things up a bit before we start collecting data, taking real samples. */
-	for(uint8_t i = 0; i< STROBE_LINES; ++i) {
-		sampleColumn(i);
-	}
-
-	while(1) {
-
-		for (strober = 0; strober < STROBE_LINES; ++strober) {
-
-			uint8_t tries;
-			tries = 1;
-			while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
-			column = testColumn(strober);
-
-			if( column != cur_keymap[strober] && (count >= WARMUP_LOOPS) ) {
-				tests++;
-
-				tries = 1;
-				while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
-				col_a = testColumn(strober);
-
-				tries = 1;
-				while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
-				col_b = testColumn(strober);
-
-				tries = 1;
-				while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
-				col_c = testColumn(strober);
-
-				if( (col_a == col_b) && (col_b == col_c) && (cur_keymap[strober] != col_a) ) {
-					cur_keymap[strober] = col_a;
-					usb_dirty = 1;
-				}
-			}
-
-			if(error == 0x50) {
-				error_data |= (((uint16_t)strober) << 12);
-			}
-
-			for(int i=0; i<MUXES_COUNT; ++i) {
-				full_samples[(strober << MUXES_COUNT_XSHIFT) + i] = samples[SAMPLE_OFFSET + i];
-			}
-
-			strobe_averages[strober] = 0;
-			for (uint8_t i = SAMPLE_OFFSET; i < (SAMPLE_OFFSET + MUXES_COUNT); ++i) {
-				//samples[i] -= samples[i-SAMPLE_OFFSET]; // av; // + full_av); // -something.
-				//samples[i] -= OFFSET_VOLTAGE; // moved to sampleColumn.
-
-				full_av_acc += (samples[i]);
-				mux_averages[i - SAMPLE_OFFSET] += samples[i];
-				strobe_averages[strober] += samples[i];
-				//samples[i] -= (full_av - HYST_T);
-
-				//++count;
-			}
-			adc_strobe_averages[strober] += strobe_averages[strober] >> 3;
-			adc_strobe_averages[strober] >>= 1;
-
-			/** test if we went negative. */
-			if ((adc_strobe_averages[strober] & 0xFF00) && (count
-					>= WARMUP_LOOPS)) {
-				//count = 0; // TODO : constrain properly.
-				error = 0xf; error_data = adc_strobe_averages[strober];
-			}
-
-			uint8_t strobe_line = strober << MUXES_COUNT_XSHIFT;
-			for (int i = 0; i < MUXES_COUNT; ++i) {
-				keys_averages_acc[strobe_line + i]
-						+= samples[SAMPLE_OFFSET + i];
-			}
-
-		} // for strober
-
-		if (count < WARMUP_LOOPS) {
-			error = 0x0C;
-			error_data = count;
-			count++;
-		}
-
-		// verify test key is not down.
-		if((cur_keymap[TEST_KEY_STROBE] & TEST_KEY_MASK) ) {
-			//count=0;
-			error = 0x05;
-			error_data = cur_keymap[TEST_KEY_STROBE] << 8;
-			error_data += full_samples[TEST_KEY_STROBE * 8];
-			//threshold++;
-		}
-
-		// calc mux averages.
-		if (count < WARMUP_LOOPS) {
-			full_av += (full_av_acc >> (7));
-			full_av >>= 1;
-			//full_av = full_av_acc / count;
-			full_av_acc = 0;
-			for (int i=0; i < MUXES_COUNT; ++i) {
-
-// mix in 1/4 of the current average to the running average. -> (@mux_mix = 2)
-#define MUX_MIX 2
-
-				adc_mux_averages[i] = (adc_mux_averages[i] << MUX_MIX) - adc_mux_averages[i];
-				adc_mux_averages[i] += (mux_averages[i] >> 4);
-				adc_mux_averages[i] >>= MUX_MIX;
-
-				mux_averages[i] = 0;
-			}
-
-		}
-
-#define IDLE_COUNT_MASK 0xff
-#define MAX_ICS 8
-
-#define IDLE_COUNT_SHIFT 4
-#define KEYS_AVERAGES_MIX 2
-
-		idle_count++;
-		idle_count &= IDLE_COUNT_MASK;
-
-		if (/*usb_dirty &&*/ (count >= WARMUP_LOOPS) ) {
-			for (int i=0; i<STROBE_LINES; ++i) {
-				usb_keymap[i] = cur_keymap[i];
-			}
-
-			dumpkeys();
-			usb_dirty=0;
-			_delay_ms(2);
-		}
-
-		if (count < WARMUP_LOOPS) {
-			for (uint8_t i = 0; i < KEY_COUNT; ++i) {
-				uint16_t acc = keys_averages_acc[i];
-				uint32_t av = keys_averages[i];
-
-				av = av + av + av + acc;
-				av >>= 2;
-
-				keys_averages[i] = av;
-				keys_averages_acc[i] = 0;
-			}
-		}
-
-
-		if(!idle_count) {
-
-			for (int i=0; i< KEY_COUNT; ++i) {
-				keys_averages_acc[i] = 0;
-			}
-
-			sampleColumn(0x0); // to resync us if we dumped a mess 'o text.
-		}
-	}
-}
-
-
-void debug_println() {
-	usb_debug_putchar('\r');
-	usb_debug_putchar('\n');
-}
-
-
-// This interrupt routine is run approx 61 times per second.
-// A very simple inactivity timeout is implemented, where we
-// will send a space character and print a message to the
-// hid_listen debug message window.
-ISR(TIMER0_OVF_vect) {
-	//idle_count++;
-	/*
-	if (idle_count > 61) {
-		idle_count = 0;
-	}*/
-
-}
-
-void dumpkeys(void) {
-	//print(" \n");
-	if(error) {
-		for (uint8_t i=0; i < STROBE_LINES; ++i) {
-				phex(usb_keymap[i]);
-				usb_debug_putchar(' ');
-
-				//print(" ");
-		}
-		if (count >= WARMUP_LOOPS && error) {
-			dump();
-		}
-
-		print(" : ");
-		phex(error);
-		error = 0;
-		print(" : ");
-		phex16(error_data);
-		error_data = 0;
-		print(" : ");
-		debug_println();
-	}
-
-
-	for(uint8_t i = 0; i < 6; ++i) {
-		keyboard_keys[i] = 0;
-	}
-	keyboard_modifier_keys = 0;
-	uint8_t usbkeycount = 0;
-	for (uint8_t i=0; i < STROBE_LINES; ++i) {
-		for(uint8_t j=0; j<MUXES_COUNT; ++j) {
-			if ( usb_keymap[i] & (1 << j) ) {
-				uint8_t key = pgm_read_byte(matrix122F_to_set3 + ( (i << MUXES_COUNT_XSHIFT) + j) );
-				if(usb_dirty) phex( key );
-				if(usbkeycount < 6) {
-					uint8_t usbkey = pgm_read_byte(page3_2_USB + key);
-
-					if ((usbkey >= 0xe0) && (usbkey <= 0xe7)) { // metas
-						keyboard_modifier_keys |= (1 << (usbkey & 0x07));
-					} else {
-						keyboard_keys[usbkeycount++] =  usbkey;
-					}
-				}
-				if (usb_dirty) usb_debug_putchar(' ');
-			}
-		}
-	}
-	if(usb_dirty) {
-		debug_println();
-	}
-
-	/** shall we send actual keyboard events? */
-#if 0
-	usb_keyboard_send();
-#endif
-
-}
-
-// taken from the datasheet.
-uint8_t readEE(uint16_t offset) {
-	/* Wait for completion of previous write */
-	while(EECR & (1<<EEPE))
-	;
-	/* Set up address register */
-	EEAR = offset;
-	/* Start eeprom read by writing EERE */
-	EECR |= (1<<EERE);
-	/* Return data from Data Register */
-	return EEDR;
-}
-
-// taken from the datasheet - note: writing is very slow. >1ms/byte.
-void writeEE(uint16_t offset, uint8_t data) {
-	/* Wait for completion of previous write */
-	while(EECR & (1<<EEPE))
-	;
-	/* Set up address and Data Registers */
-	EEAR = offset;
-	EEDR = data;
-	/* Write logical one to EEMPE */
-	EECR |= (1<<EEMPE);
-	/* Start eeprom write by setting EEPE */
-	EECR |= (1<<EEPE);
-}
-
-uint8_t dump_count = 0;
-void dump(void) {
-
-#if 0
-	static char once = 0;
-	uint8_t eb;
-
-	if(!once) {
-		print("\nwriting ee");
-		eb = readEE(0x10);
-		eb++;
-		writeEE(0x10, eb);
-
-		once++;
-	}
-
-
-	print("\n ee: ");
-	for(uint16_t i=0x10; i< 0x18; ++i) {
-		phex(readEE(i));
-		pchar(0x20);
-	}
-#endif
-
-	if(!dump_count) {  // we don't want to debug-out during the measurements.
-
-		for(int i =0; i< KEY_COUNT; ++i) {
-			if(!(i & 0x0f)) {
-				print("\n");
-			} else if (!(i & 0x07)) {
-				print("  ");
-			}
-			usb_debug_putchar(' ');
-			//phex16 (keys_averages[(i >> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]);
-			phex (keys_averages[i]);
-		}
-
-		print("\n");
-
-		for(int i =0; i< KEY_COUNT; ++i) {
-			if(!(i & 0x0f)) {
-				print("\n");
-			} else if (!(i & 0x07)) {
-				print("  ");
-			}
-			usb_debug_putchar(' ');
-			//phex16 (keys_averages[(i >> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]);
-			//phex16 (keys_averages_acc[i]);
-			phex(full_samples[i]);
-		}
-	}
-
-
-	//}
-
-//	uint8_t cur_strober = 0xe;
-	uint8_t cur_strober = ze_strober;
-	print("\n");
-
-	phex(cur_strober);
-	//print(":         ");
-	print(": ");
-#if 1
-	print("\n");
-	for (uint8_t i=0; i < MUXES_COUNT; ++i) {
-		usb_debug_putchar(' ');
-		phex16(full_samples[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
-	}
-
-	print("\n");
-//	phex(threshold);
-//	print(": ");
-
-	for (uint8_t i=0; i < MUXES_COUNT; ++i) {
-		usb_debug_putchar(' ');
-		phex16(keys_averages[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
-	}
-
-#endif
-	/*
-	for (uint8_t i=0; i< SAMPLES; ++i) {
-		print(" ");
-		phex16(samples[i]);
-		//phex16(ADC);
-	}*/
-	//print(" : ");
-	//usb_debug_putchar((was_active)?' ':'*');
-
-	//phex16(keymap[TEST_KEY_STROBE] & TEST_KEY_MASK);
-	/*print(" "); */
-	//phex(keymap[TEST_KEY_STROBE]);
-
-
-	//print("\n");
-	//print(":");
-	//phex(full_av);
-	//phex16(count);
-	//print(" : ");
-	print("\n");
-
-	for (uint8_t i=0; i < STROBE_LINES; ++i) {
-		phex(cur_keymap[i]);
-		usb_debug_putchar(' ');
-
-		//print(" ");
-	}
-
-
-	//print(": ");
-	//phex(adc_strobe_averages[ze_strober]);
-	//usb_debug_putchar(' ');
-
-
-
-	for (uint8_t i=0; i < MUXES_COUNT; ++i) {
-		usb_debug_putchar(' ');
-		//phex16(adc_mux_averages[i] + adc_strobe_averages[ze_strober] - full_av);
-		//phex16((adc_mux_averages[i] + adc_strobe_averages[ze_strober]) >> 1);
-		//phex16((adc_mux_averages[i] * 3  + adc_strobe_averages[ze_strober]) >> 2);
-		//phex16(adc_mux_averages[i] + threshold);
-		//phex16(gsamples[i + SAMPLE_OFFSET] - (adc_mux_averages[i] + threshold) + 0x100);
-		//phex16(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i] + (uint8_t)threshold);
-		phex16(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i]);
-	}
-
-	if(error) {
-		usb_debug_putchar(' ');
-		phex (error);
-		usb_debug_putchar(' ');
-		phex16(error_data);
-		error = 0;
-		error_data = 0;
-	}
-	//print("\n");
-
-	ze_strober++;
-	ze_strober &= 0xf;
-
-
-	dump_count++;
-	dump_count &= 0x0f;
-
-
-
-	//ze_strobe = (1 << (ze_strober ) );
-
-
-
-	//phex(ADCSRA);
-	//print(" ");
-			//print("\n");
-	//usb_keyboard_press(KEY_SPACE, 0);
-
-//		if(blink) {
-//			LED_ON;
-//		} else {
-//			LED_OFF;
-//		}
-//		blink ^= 1;
-}
-
-
-/*
-int oldmain(void) {
-	uint8_t b, d, mask, i, reset_idle;
-	uint8_t b_prev=0xFF, d_prev=0xFF;
-
-	// set for 16 MHz clock
-	CPU_PRESCALE(0);
-
-	// Configure all port B and port D pins as inputs with pullup resistors.
-	// See the "Using I/O Pins" page for details.
-	// http://www.pjrc.com/teensy/pins.html
-	DDRD = 0x00;
-	DDRB = 0x00;
-	PORTB = 0xFF;
-	PORTD = 0xFF;
-
-	// Initialize the USB, and then wait for the host to set configuration.
-	// If the Teensy is powered without a PC connected to the USB port,
-	// this will wait forever.
-	usb_init();
-	while (!usb_configured())  ;
-
-	// Wait an extra second for the PC's operating system to load drivers
-	// and do whatever it does to actually be ready for input
-	_delay_ms(1000);
-
-	// Configure timer 0 to generate a timer overflow interrupt every
-	// 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock
-	// This demonstrates how to use interrupts to implement a simple
-	// inactivity timeout.
-	TCCR0A = 0x00;
-	TCCR0B = 0x05;
-	TIMSK0 = (1<<TOIE0);
-
-	print("Begin keyboard example program\n");
-	print("All Port B or Port D pins are inputs with pullup resistors.\n");
-	print("Any connection to ground on Port B or D pins will result in\n");
-	print("keystrokes sent to the PC (and debug messages here).\n");
-	while (1) {
-		// read all port B and port D pins
-		b = PINB;
-		d = PIND;
-		// check if any pins are low, but were high previously
-		mask = 1;
-		reset_idle = 0;
-		for (i=0; i<8; i++) {
-			if (((b & mask) == 0) && (b_prev & mask) != 0) {
-				usb_keyboard_press(KEY_B, KEY_SHIFT);
-				usb_keyboard_press(number_keys[i], 0);
-				print("Port B, bit ");
-				phex(i);
-				print("\n");
-				reset_idle = 1;
-			}
-			if (((d & mask) == 0) && (d_prev & mask) != 0) {
-				usb_keyboard_press(KEY_D, KEY_SHIFT);
-				usb_keyboard_press(number_keys[i], 0);
-				print("Port D, bit ");
-				phex(i);
-				print("\n");
-				reset_idle = 1;
-			}
-			mask = mask << 1;
-		}
-		// if any keypresses were detected, reset the idle counter
-		if (reset_idle) {
-			// variables shared with interrupt routines must be
-			// accessed carefully so the interrupt routine doesn't
-			// try to use the variable in the middle of our access
-			cli();
-			idle_count = 0;
-			sei();
-		}
-		// now the current pins will be the previous, and
-		// wait a short delay so we're not highly sensitive
-		// to mechanical "bounce".
-		b_prev = b;
-		d_prev = d;
-		_delay_ms(2);
-	}
-}
-*/
-
+/* Copyright (C) 2011-2013 by Joseph Makuch
+ * Additions by Jacob Alexander (2013)
+ *
+ * dfj, put whatever license here you want -HaaTa
+ */
+
+// ----- Includes -----
+
+// Compiler Includes
+#include <Lib/ScanLib.h>
+
+// Project Includes
+#include <led.h>
+#include <print.h>
+
+// Local Includes
+#include "scan_loop.h"
+
+
+
+// ----- Defines -----
+
+// TODO dfj defines...needs cleaning up and commenting...
+#define THRESHOLD 0x0a
+#define BUMP_THRESHOLD 0x50
+//((THRESHOLD) * 3)
+#define BUMP_REST_US 1200
+
+#define HYST 1
+#define HYST_T 0x10
+
+#define TEST_KEY_STROBE (0x05)
+#define TEST_KEY_MASK (1 << 0)
+
+#define ADHSM 7
+
+/** Whether to use all of D and C, vs using E0, E1 instead of D6, D7,
+ * or alternately all of D, and E0,E1 and C0,..5 */
+//#define ALL_D_C
+//#define SHORT_D
+#define SHORT_C
+
+// rough offset voltage: one diode drop, about 50mV = 0x3ff * 50/3560 = 20
+//#define OFFSET_VOLTAGE 0x14
+#define OFFSET_VOLTAGE 0x28
+
+
+#define RIGHT_JUSTIFY 0
+#define LEFT_JUSTIFY (0xff)
+
+// set left or right justification here:
+#define JUSTIFY_ADC RIGHT_JUSTIFY
+
+#define ADLAR_MASK (1 << ADLAR)
+#ifdef JUSTIFY_ADC
+#define ADLAR_BITS ((ADLAR_MASK) & (JUSTIFY_ADC))
+#else // defaults to right justification.
+#define ADLAR_BITS 0
+#endif
+
+
+// full muxmask
+#define FULL_MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2) | (1 << MUX3) | (1 << MUX4))
+
+// F0-f7 pins only muxmask.
+#define MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2))
+
+#define MUX_1_1 0x1e
+#define MUX_GND 0x1f
+
+
+	// set ADC clock prescale
+#define PRESCALE_MASK ((1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2))
+#define PRESCALE_SHIFT (ADPS0)
+#define PRESCALE 3
+
+
+#ifdef EXTENDED_STROBE
+
+#define STROBE_LINES 18
+
+#else
+
+#define STROBE_LINES 16
+
+#endif
+
+#define STROBE_LINES_XSHIFT 4
+#define STROBE_LINES_MASK 0x0f
+#define MUXES_COUNT 8
+#define MUXES_COUNT_XSHIFT 3
+#define MUXES_MASK 0x7
+
+#define WARMUP_LOOPS ( 1024 )
+
+#define RECOVERY_US 6
+
+#define SAMPLES 10
+
+
+#define SAMPLE_OFFSET ((SAMPLES) - MUXES_COUNT)
+//#define SAMPLE_OFFSET 9
+#define STROBE_OFFSET 0
+
+
+#define KEY_COUNT ((STROBE_LINES) * (MUXES_COUNT))
+
+#define LX2FX
+
+
+#define RECOVERY_CONTROL 1
+
+#define RECOVERY_SOURCE 0
+#define RECOVERY_SINK 2
+#define RECOVERY_MASK 0x03
+
+
+// mix in 1/4 of the current average to the running average. -> (@mux_mix = 2)
+#define MUX_MIX 2
+
+
+#define IDLE_COUNT_MASK 0xff
+#define MAX_ICS 8
+
+#define IDLE_COUNT_SHIFT 4
+#define KEYS_AVERAGES_MIX 2
+
+
+#ifdef ALL_D_C
+
+#define D_MASK (0xff)
+#define D_SHIFT 0
+
+#define E_MASK (0x00)
+#define E_SHIFT 0
+
+#define C_MASK (0xff)
+#define C_SHIFT 8
+
+#else
+#if defined(SHORT_D)
+
+#define D_MASK (0x3f)
+#define D_SHIFT 0
+
+#define E_MASK (0x03)
+#define E_SHIFT 6
+
+#define C_MASK (0xff)
+#define C_SHIFT 8
+
+#else
+#if defined(SHORT_C)
+
+#define D_MASK (0xff)
+#define D_SHIFT 0
+
+#define E_MASK (0x03)
+#define E_SHIFT 6
+
+#define C_MASK (0xff)
+#define C_SHIFT 8
+#endif
+#endif
+#endif
+
+
+
+
+
+// ----- Macros -----
+
+// Make sure we haven't overflowed the buffer
+#define bufferAdd(byte) \
+		if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
+			KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte
+
+
+// TODO dfj macros...needs cleaning up and commenting...
+#define STROBE_CASE(SC_CASE, SC_REG_A) case (SC_CASE): PORT##SC_REG_A = \
+	(( (PORT##SC_REG_A) & ~(1 << (SC_CASE - SC_REG_A##_SHIFT)) ) | (1 << (SC_CASE - SC_REG_A##_SHIFT)))
+
+#define SET_MUX(X) ((ADMUX) = (((ADMUX) & ~(MUX_MASK)) | ((X) & (MUX_MASK))))
+#define SET_FULL_MUX(X) ((ADMUX) = (((ADMUX) & ~(FULL_MUX_MASK)) | ((X) & (FULL_MUX_MASK))))
+
+
+
+
+
+// ----- Variables -----
+
+// Buffer used to inform the macro processing module which keys have been detected as pressed
+volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
+volatile uint8_t KeyIndex_BufferUsed;
+
+
+// TODO dfj variables...needs cleaning up and commenting
+         uint8_t  blink = 0;
+volatile uint8_t  idle_count = 1;
+volatile uint16_t full_av = 0;
+
+/**/ uint8_t ze_strober = 0;
+
+int16_t samples [SAMPLES];
+
+//int16_t gsamples [SAMPLES];
+
+/**/ int16_t adc_mux_averages[MUXES_COUNT];
+/**/ int16_t adc_strobe_averages[STROBE_LINES];
+
+
+/**/ uint8_t cur_keymap[STROBE_LINES];
+// /**/ int8_t last_keymap[STROBE_LINES];
+/**/ uint8_t usb_keymap[STROBE_LINES];
+uint8_t dirty;
+uint8_t unstable;
+uint8_t usb_dirty;
+
+int16_t threshold = THRESHOLD;
+uint16_t tests = 0;
+
+uint8_t col_a=0;
+uint8_t col_b=0;
+uint8_t col_c=0;
+
+uint8_t column=0;
+
+
+int16_t keys_averages_acc[KEY_COUNT];
+uint16_t keys_averages[KEY_COUNT];
+
+uint8_t full_samples[KEY_COUNT];
+
+/* viable starting biases for near 0.830V offset. and adc PRESCALE 3
+0017 0016 001B 001A 0016 0016 000F 000E 001B 001E 001E 0018 0017 0015 000E 001D
+001B 001A 0016 0016 000F 000E 001C 001B 001E 0018 0017 0015 000E 001D 0024 001F
+0016 0016 000F 000E 001C 001B 001E 001E 0017 0015 000E 001D 0024 001F 0020 001F
+000F 000E 001C 001B 001E 001E 0018 0017 000E 001D 0024 001F 0020 001F 0020 0017
+001C 001B 001E 001E 0018 0017 0015 000E 0024 001F 0020 001F 0020 0017 0010 001D
+001E 001E 0018 0017 0015 000E 001D 0024 0020 001F 0020 0017 0010 001D 0024 0021
+0018 0017 0015 000E 001D 0024 001F 0020 0020 0017 0010 001D 0024 0021 0021 0021
+0015 000E 001D 0024 001F 0020 001F 0020 0010 001D 0024 0021 0021 0021 0021 0018
+*/
+
+/*** starting bias relative to fixed offset estimate of 820mV (0x50)
+ *   77 69 65 5B 50 4E 4C 45   66 53 4D 49 45 3F 3E 35
+ *   68 54 4F 49 45 40 3F 34   74 66 5F 56 4E 4D 4C 3F
+ *   6D 5D 53 4C 49 46 45 38   6D 5A 53 4E 49 48 45 3E
+ *   6F 5D 56 4E 4B 48 48 3A   6D 5C 54 4E 48 48 45 37
+ *   75 68 5F 57 4F 4D 4C 3F   60 4E 48 41 3C 3C 39 2F
+ *   65 53 4E 49 41 3F 3E 34   65 54 4E 49 43 3F 3E 34
+ *   60 51 4A 45 3F 3E 3C 30   57 4C 45 3E 3B 37 37 2E
+ *   64 4E 48 44 3C 3B 39 2F   5D 4F 48 45 3E 3C 3B 30
+ */
+
+/*volatile*/ uint16_t count = 0;
+
+/*volatile*/ uint8_t error = 0;
+uint16_t error_data = 0;
+
+
+int16_t mux_averages[MUXES_COUNT];
+int16_t strobe_averages[STROBE_LINES];
+
+uint8_t dump_count = 0;
+
+
+
+// ----- Function Declarations -----
+
+void dump    ( void );
+void dumpkeys( void );
+
+void recovery( uint8_t on );
+
+int sampleColumn  ( uint8_t column );
+int sampleColumn_i( uint8_t column, uint8_t muxes, int16_t * buffer); // XXX Not currently used
+int sampleColumn_k( uint8_t column, int16_t *buffer );
+
+void setup_ADC( void );
+
+void strobe_w( uint8_t strobe_num );
+
+uint8_t testColumn( uint8_t strobe );
+
+
+
+// ----- Functions -----
+
+// Initial setup for cap sense controller
+inline void scan_setup()
+{
+	// TODO dfj code...needs cleanup + commenting...
+	setup_ADC();
+
+	// Configure timer 0 to generate a timer overflow interrupt every
+	// 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock
+	// This demonstrates how to use interrupts to implement a simple
+	// inactivity timeout.
+	//TCCR0A = 0x00;
+	//TCCR0B = 0x05;
+	//TIMSK0 = (1<<TOIE0);
+
+	DDRC = C_MASK;
+	PORTC = 0;
+	DDRD = D_MASK;
+	PORTD = 0;
+	DDRE = E_MASK;
+	PORTE = 0 ;
+
+	//DDRC |= (1 << 6);
+	//PORTC &= ~(1<< 6);
+
+	//uint16_t strobe = 1;
+
+
+	// TODO all this code should probably be in scan_resetKeyboard
+	for (int i=0; i< STROBE_LINES; ++i) {
+		cur_keymap[i] = 0;
+		//last_keymap[i] = 0;
+		usb_keymap[i] = 0;
+	}
+
+	for(int i=0; i < MUXES_COUNT; ++i) {
+		adc_mux_averages[i] = 0x20; // experimentally determined.
+	}
+	for(int i=0; i < STROBE_LINES; ++i) {
+		adc_strobe_averages[i] = 0x20; // yup.
+	}
+
+	for(int i=0; i< KEY_COUNT; ++i) {
+		keys_averages[i] = 0x40;
+		keys_averages_acc[i] = (0x400);
+	}
+
+	/** warm things up a bit before we start collecting data, taking real samples. */
+	for(uint8_t i = 0; i< STROBE_LINES; ++i) {
+		sampleColumn(i);
+	}
+
+
+	// Reset the keyboard before scanning, we might be in a wierd state
+	// Also sets the KeyIndex_BufferUsed to 0
+	scan_resetKeyboard();
+}
+
+
+// Main Detection Loop
+// This is where the important stuff happens
+inline uint8_t scan_loop()
+{
+	// TODO dfj code...needs commenting + cleanup...
+	uint8_t strober = 0;
+	uint32_t full_av_acc = 0;
+
+	for (strober = 0; strober < STROBE_LINES; ++strober) {
+
+		uint8_t tries;
+		tries = 1;
+		while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
+		column = testColumn(strober);
+
+		if( column != cur_keymap[strober] && (count >= WARMUP_LOOPS) ) {
+			tests++;
+
+			tries = 1;
+			while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
+			col_a = testColumn(strober);
+
+			tries = 1;
+			while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
+			col_b = testColumn(strober);
+
+			tries = 1;
+			while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
+			col_c = testColumn(strober);
+
+			if( (col_a == col_b) && (col_b == col_c) && (cur_keymap[strober] != col_a) ) {
+				cur_keymap[strober] = col_a;
+				usb_dirty = 1;
+			}
+		}
+
+		if(error == 0x50) {
+			error_data |= (((uint16_t)strober) << 12);
+		}
+
+		for(int i=0; i<MUXES_COUNT; ++i) {
+			full_samples[(strober << MUXES_COUNT_XSHIFT) + i] = samples[SAMPLE_OFFSET + i];
+		}
+
+		strobe_averages[strober] = 0;
+		for (uint8_t i = SAMPLE_OFFSET; i < (SAMPLE_OFFSET + MUXES_COUNT); ++i) {
+			//samples[i] -= samples[i-SAMPLE_OFFSET]; // av; // + full_av); // -something.
+			//samples[i] -= OFFSET_VOLTAGE; // moved to sampleColumn.
+
+			full_av_acc += (samples[i]);
+			mux_averages[i - SAMPLE_OFFSET] += samples[i];
+			strobe_averages[strober] += samples[i];
+			//samples[i] -= (full_av - HYST_T);
+
+			//++count;
+		}
+		adc_strobe_averages[strober] += strobe_averages[strober] >> 3;
+		adc_strobe_averages[strober] >>= 1;
+
+		/** test if we went negative. */
+		if ((adc_strobe_averages[strober] & 0xFF00) && (count
+				>= WARMUP_LOOPS)) {
+			//count = 0; // TODO : constrain properly.
+			error = 0xf; error_data = adc_strobe_averages[strober];
+		}
+
+		uint8_t strobe_line = strober << MUXES_COUNT_XSHIFT;
+		for (int i = 0; i < MUXES_COUNT; ++i) {
+			keys_averages_acc[strobe_line + i]
+					+= samples[SAMPLE_OFFSET + i];
+		}
+
+	} // for strober
+
+	if (count < WARMUP_LOOPS) {
+		error = 0x0C;
+		error_data = count;
+		count++;
+	}
+
+	// verify test key is not down.
+	if((cur_keymap[TEST_KEY_STROBE] & TEST_KEY_MASK) ) {
+		//count=0;
+		error = 0x05;
+		error_data = cur_keymap[TEST_KEY_STROBE] << 8;
+		error_data += full_samples[TEST_KEY_STROBE * 8];
+		//threshold++;
+	}
+
+	// calc mux averages.
+	if (count < WARMUP_LOOPS) {
+		full_av += (full_av_acc >> (7));
+		full_av >>= 1;
+		//full_av = full_av_acc / count;
+		full_av_acc = 0;
+		for (int i=0; i < MUXES_COUNT; ++i) {
+
+			adc_mux_averages[i] = (adc_mux_averages[i] << MUX_MIX) - adc_mux_averages[i];
+			adc_mux_averages[i] += (mux_averages[i] >> 4);
+			adc_mux_averages[i] >>= MUX_MIX;
+
+			mux_averages[i] = 0;
+		}
+
+	}
+
+	idle_count++;
+	idle_count &= IDLE_COUNT_MASK;
+
+	if (/*usb_dirty &&*/ (count >= WARMUP_LOOPS) ) {
+		for (int i=0; i<STROBE_LINES; ++i) {
+			usb_keymap[i] = cur_keymap[i];
+		}
+
+		dumpkeys();
+		usb_dirty=0;
+		_delay_ms(2);
+	}
+
+	if (count < WARMUP_LOOPS) {
+		for (uint8_t i = 0; i < KEY_COUNT; ++i) {
+			uint16_t acc = keys_averages_acc[i];
+			uint32_t av = keys_averages[i];
+
+			av = av + av + av + acc;
+			av >>= 2;
+
+			keys_averages[i] = av;
+			keys_averages_acc[i] = 0;
+		}
+	}
+
+
+	if(!idle_count) {
+
+		for (int i=0; i< KEY_COUNT; ++i) {
+			keys_averages_acc[i] = 0;
+		}
+
+		sampleColumn(0x0); // to resync us if we dumped a mess 'o text.
+	}
+
+
+	// 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;
+}
+
+
+void
+_delay_loop(uint8_t __count)
+{
+	__asm__ volatile (
+		"1: dec %0" "\n\t"
+		"brne 1b"
+		: "=r" (__count)
+		: "0" (__count)
+	);
+}
+
+
+void setup_ADC (void) {
+	// disable adc digital pins.
+	DIDR1 |= (1 << AIN0D) | (1<<AIN1D); // set disable on pins 1,0.
+	//DIDR0 = 0xff; // disable all. (port F, usually). - testing w/o disable.
+	DDRF = 0x0;
+	PORTF = 0x0;
+	uint8_t mux = 0 & 0x1f; // 0 == first. // 0x1e = 1.1V ref.
+
+	// 0 = external aref 1,1 = 2.56V internal ref
+	uint8_t aref = ((1 << REFS1) | (1 << REFS0)) & ((1 << REFS1) | (1 << REFS0));
+//	uint8_t adlar = 0xff & (1 << ADLAR); // 1 := left justify bits, 0 := right
+	uint8_t adate = (1 << ADATE) & (1 << ADATE); // trigger enable
+	uint8_t trig = 0 & ((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2)); // 0 = free running
+	// ps2, ps1 := /64 ( 2^6 ) ps2 := /16 (2^4), ps1 := 4, ps0 :=2, PS1,PS0 := 8 (2^8)
+	uint8_t prescale = ( ((PRESCALE) << PRESCALE_SHIFT) & PRESCALE_MASK ); // 001 == 2^1 == 2
+	uint8_t hispeed = (1 << ADHSM);
+	uint8_t en_mux = (1 << ACME);
+
+	//ADCSRA = (ADCSRA & ~PRESCALES) | ((1 << ADPS1) | (1 << ADPS2)); // 2, 1 := /64 ( 2^6 )
+	//ADCSRA = (ADCSRA & ~PRESCALES) | ((1 << ADPS0) | (1 << ADPS2)); // 2, 0 := /32 ( 2^5 )
+	//ADCSRA = (ADCSRA & ~PRESCALES) | ((1 << ADPS2)); // 2 := /16 ( 2^4 )
+
+	ADCSRA = (1 << ADEN) | prescale; // ADC enable
+
+	// select ref.
+	//ADMUX |= ((1 << REFS1) | (1 << REFS0)); // 2.56 V internal.
+	//ADMUX |= ((1 << REFS0) ); // Vcc with external cap.
+	//ADMUX &= ~((1 << REFS1) | (1 << REFS0)); // 0,0 : aref.
+	ADMUX = aref | mux | ADLAR_BITS;
+
+	// enable MUX
+	// ADCSRB |= (1 << ACME); 	// enable
+	// ADCSRB &= ~(1 << ADEN); // ?
+
+	// select first mux.
+	//ADMUX = (ADMUX & ~MUXES); // start at 000 = ADC0
+
+	// clear adlar to left justify data
+	//ADMUX = ~();
+
+	// set adlar to right justify data
+	//ADMUX |= (1 << ADLAR);
+
+
+	// set free-running
+	ADCSRA |= adate; // trigger enable
+	ADCSRB  = en_mux | hispeed | trig | (ADCSRB & ~((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2))); // trigger select free running
+
+//	ADCSRA |= (1 << ADATE); // tiggger enable
+
+	ADCSRA |= (1 << ADEN); // ADC enable
+	ADCSRA |= (1 << ADSC); // start conversions q
+
+}
+
+
+void recovery(uint8_t on) {
+	DDRB |= (1 << RECOVERY_CONTROL);
+
+	PORTB &= ~(1 << RECOVERY_SINK);    // SINK always zero
+	DDRB &= ~(1 << RECOVERY_SOURCE);  // SOURCE high imp
+
+	if(on) {
+		DDRB |= (1 << RECOVERY_SINK);	// SINK pull
+
+
+		PORTB |= (1 << RECOVERY_CONTROL);
+
+		PORTB |= (1 << RECOVERY_SOURCE); // SOURCE high
+		DDRB |= (1 << RECOVERY_SOURCE);
+	} else {
+		_delay_loop(10);
+		PORTB &= ~(1 << RECOVERY_CONTROL);
+
+		DDRB &= ~(1 << RECOVERY_SOURCE);
+		PORTB &= ~(1 << RECOVERY_SOURCE); // SOURCE low
+		DDRB &= ~(1 << RECOVERY_SINK);	// SINK high-imp
+
+		//DDRB &= ~(1 << RECOVERY_SINK);
+	}
+}
+
+
+void strobe_w(uint8_t strobe_num) {
+
+	PORTC &= ~(D_MASK);
+	PORTD &= ~(D_MASK);
+	PORTE &= ~(E_MASK);
+
+#ifdef SHORT_C
+	strobe_num = 15 - strobe_num;
+#endif
+
+	switch(strobe_num) {
+
+	case 0: PORTD |= (1 << 0); break;
+	case 1: PORTD |= (1 << 1); break;
+	case 2: PORTD |= (1 << 2); break;
+	case 3: PORTD |= (1 << 3); break;
+	case 4: PORTD |= (1 << 4); break;
+	case 5: PORTD |= (1 << 5); break;
+
+#ifdef ALL_D
+
+	case 6: PORTD |= (1 << 6); break;
+	case 7: PORTD |= (1 << 7); break;
+
+	case 8:  PORTC |= (1 << 0); break;
+	case 9:  PORTC |= (1 << 1); break;
+	case 10: PORTC |= (1 << 2); break;
+	case 11: PORTC |= (1 << 3); break;
+	case 12: PORTC |= (1 << 4); break;
+	case 13: PORTC |= (1 << 5); break;
+	case 14: PORTC |= (1 << 6); break;
+	case 15: PORTC |= (1 << 7); break;
+
+	case 16: PORTE |= (1 << 0); break;
+	case 17: PORTE |= (1 << 1); break;
+
+#else
+#ifdef SHORT_D
+
+	case 6: PORTE |= (1 << 0); break;
+	case 7: PORTE |= (1 << 1); break;
+
+	case 8:  PORTC |= (1 << 0); break;
+	case 9:  PORTC |= (1 << 1); break;
+	case 10: PORTC |= (1 << 2); break;
+	case 11: PORTC |= (1 << 3); break;
+	case 12: PORTC |= (1 << 4); break;
+	case 13: PORTC |= (1 << 5); break;
+	case 14: PORTC |= (1 << 6); break;
+	case 15: PORTC |= (1 << 7); break;
+
+#else
+#ifdef SHORT_C
+
+	case 6: PORTD |= (1 << 6); break;
+	case 7: PORTD |= (1 << 7); break;
+
+	case 8: PORTE |= (1 << 0); break;
+	case 9: PORTE |= (1 << 1); break;
+
+	case 10:  PORTC |= (1 << 0); break;
+	case 11:  PORTC |= (1 << 1); break;
+	case 12: PORTC |= (1 << 2); break;
+	case 13: PORTC |= (1 << 3); break;
+	case 14: PORTC |= (1 << 4); break;
+	case 15: PORTC |= (1 << 5); break;
+
+	case 16: PORTC |= (1 << 6); break;
+	case 17: PORTC |= (1 << 7); break;
+
+#endif
+#endif
+#endif
+
+	default:
+		break;
+	}
+
+}
+
+
+int sampleColumn_i(uint8_t column, uint8_t muxes, int16_t * buffer) {
+
+	// ensure all probe lines are driven low, and chill for recovery delay.
+	PORTC &= ~C_MASK;
+	PORTD &= ~D_MASK;
+	PORTE &= ~E_MASK;
+	recovery(1);
+	_delay_us(RECOVERY_US);
+	recovery(0);
+
+	uint8_t index = 0;
+
+	for (uint8_t i=0; i<8; ++i) {
+		if(muxes & (1 << i)) {
+			buffer[index++] = i;
+		}
+	}
+
+	SET_FULL_MUX(MUX_1_1); // crap sample will use this.
+	ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions
+	ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
+
+	//uint16_t sample;
+
+	while (! (ADCSRA & (1 << ADIF))); // wait until ready.
+	//sample = ADC; // 1st sample, icky.
+	ADC; // 1st sample, icky. XXX Not sure if the compiler throws this away, but less compiler warnings -HaaTa
+
+	strobe_w(column);
+	//recovery(0);
+
+	/**
+	 * we are running in continuous mode, so we must setup the next
+	 * read _before_ the current read completes.
+	 *
+	 * setup 0,
+	 * read garbage,
+	 * do not store
+	 *
+	 * setup 1,
+	 * read 0,
+	 * store 0,
+	 *
+	 * ...
+	 *
+	 * setup junk,
+	 * read n
+	 * store n
+	 *
+	 * */
+
+
+	ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
+	//wait for last read to complete.
+	while (! (ADCSRA & (1 << ADIF)));
+	//sample = ADC; // throw away strobe'd value.
+	ADC; // throw away strobe'd value.
+
+#if 0
+	for (uint8_t i=0; i <= index; ++i) {
+
+		// setup i'th read.
+		SET_FULL_MUX(buffer[i]); // _next_ read will use this.
+		// wait for i-1'th read to complete:
+		ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
+		while (! (ADCSRA & (1 << ADIF)));
+
+		// retrieve last (i-1'th) read.
+		if (i) {
+			buffer[i-1] = ADC - OFFSET_VOLTAGE;
+		} /*else {
+			buffer[0] = ADC - OFFSET_VOLTAGE;
+		}*/
+
+		//index++;
+	}
+#else
+	for (uint8_t i=0; i < index; ++i) {
+
+		// setup i'th read.
+		SET_FULL_MUX(buffer[i]); // _next_ read will use this.
+
+		ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
+		while (! (ADCSRA & (1 << ADIF)));
+		//sample = ADC; // throw away warmup value.
+		ADC; // throw away warmup value.
+
+
+
+		/*
+		ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
+		while (! (ADCSRA & (1 << ADIF)));
+		//sample = ADC; // throw away warmup value.
+		ADC; // throw away warmup value.
+*/
+
+		ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
+		while (! (ADCSRA & (1 << ADIF)));
+
+		// retrieve current read.
+		buffer[i] = ADC - OFFSET_VOLTAGE;
+
+
+	}
+#endif
+
+
+	// turn off adc.
+	ADCSRA &= ~(1 << ADEN);
+
+	// pull all columns' probe-lines low.
+	PORTC &= ~C_MASK;
+	PORTD &= ~D_MASK;
+	PORTE &= ~E_MASK;
+
+	// test for humps. :/
+	/*uint16_t delta = full_av;
+	if(buffer[0] > BUMP_THRESHOLD + delta) {
+		// ze horror.
+		return 1;
+	} else {
+		return 0; //all good.
+	}*/
+	return 0;
+
+}
+
+
+int sampleColumn_k(uint8_t column, int16_t * buffer) {
+	// ensure all probe lines are driven low, and chill for recovery delay.
+	//uint16_t sample;
+
+	ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions
+	ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
+
+	// sync up with adc clock:
+	while (! (ADCSRA & (1 << ADIF))); // wait until ready.
+	ADC; // throw it away. // XXX Not sure if the compiler throws this away, but less compiler warnings -HaaTa
+	//sample = ADC; // throw it away.
+
+	for(uint8_t mux=0; mux < 8; ++mux) {
+
+		PORTC &= ~C_MASK;
+		PORTD &= ~D_MASK;
+		PORTE &= ~E_MASK;
+
+		SET_FULL_MUX(mux); // our sample will use this
+
+		for(uint8_t i=0; i < 2; ++i) {
+			ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
+			//wait for last read to complete.
+			while (! (ADCSRA & (1 << ADIF)));
+			//sample = ADC; // throw away strobe'd value.
+			ADC; // throw away strobe'd value.
+		}
+
+		recovery(0);
+		strobe_w(column);
+
+		ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
+		//wait for last read to complete.
+		while (! (ADCSRA & (1 << ADIF)));
+		//sample = ADC; // throw away strobe'd value.
+		ADC; // throw away strobe'd value.
+
+		ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
+		while (! (ADCSRA & (1 << ADIF)));
+
+		// retrieve current read.
+		buffer[mux] = ADC - OFFSET_VOLTAGE;
+		recovery(1);
+
+	}
+
+	// turn off adc.
+	ADCSRA &= ~(1 << ADEN);
+
+	// pull all columns' probe-lines low.
+	PORTC &= ~C_MASK;
+	PORTD &= ~D_MASK;
+	PORTE &= ~E_MASK;
+//		recovery(1);
+
+
+	return 0;
+}
+
+
+int sampleColumn(uint8_t column) {
+	int rval = 0;
+
+	/*
+	sampleColumn_i(column, 0x0f, samples+SAMPLE_OFFSET);
+	sampleColumn_i(column, 0xf0, samples+SAMPLE_OFFSET + 4 );
+*/
+
+	rval = sampleColumn_k(column, samples+SAMPLE_OFFSET);
+
+	for(uint8_t i=0; i<8; ++i) {
+		if(samples[SAMPLE_OFFSET + i] - adc_mux_averages[i] > BUMP_THRESHOLD) {
+			// was a hump
+
+			_delay_us(BUMP_REST_US);
+			rval++;
+			error = 0x50;
+			error_data = samples[SAMPLE_OFFSET +i]; //  | ((uint16_t)i << 8);
+			return rval;
+		}
+	}
+
+	return rval;
+}
+
+
+uint8_t testColumn(uint8_t strobe) {
+    uint8_t column = 0;
+    uint8_t bit = 1;
+    for (uint8_t i=0; i < MUXES_COUNT; ++i) {
+		uint16_t delta = keys_averages[(strobe << MUXES_COUNT_XSHIFT) + i];
+		if ((int16_t)samples[SAMPLE_OFFSET + i] > threshold + delta) {
+			column |= bit;
+		}
+		bit <<= 1;
+	}
+    return column;
+}
+
+
+void dumpkeys(void) {
+	//print(" \n");
+	if(error) {
+		for (uint8_t i=0; i < STROBE_LINES; ++i) {
+				printHex(usb_keymap[i]);
+				print(" ");
+
+				//print(" ");
+		}
+		if (count >= WARMUP_LOOPS && error) {
+			dump();
+		}
+
+		print(" : ");
+		printHex(error);
+		error = 0;
+		print(" : ");
+		printHex(error_data);
+		error_data = 0;
+		print(" : " NL);
+	}
+
+	// XXX Will be cleaned up eventually, but this will do for now :P -HaaTa
+	for (uint8_t i=0; i < STROBE_LINES; ++i) {
+		for(uint8_t j=0; j<MUXES_COUNT; ++j) {
+			if ( usb_keymap[i] & (1 << j) ) {
+				uint8_t key = (i << MUXES_COUNT_XSHIFT) + j;
+
+				// Add to the Macro processing buffer
+				// Automatically handles converting to a USB code and sending off to the PC
+				bufferAdd( key );
+
+				if(usb_dirty) {
+					printHex( key );
+					print(" ");
+				}
+			}
+		}
+	}
+	if(usb_dirty) print("\n");
+	usb_keyboard_send();
+}
+
+
+void dump(void) {
+
+	if(!dump_count) {  // we don't want to debug-out during the measurements.
+
+		for(int i =0; i< KEY_COUNT; ++i) {
+			if(!(i & 0x0f)) {
+				print("\n");
+			} else if (!(i & 0x07)) {
+				print("  ");
+			}
+			print(" ");
+			//printHex (keys_averages[(i >> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]);
+			printHex (keys_averages[i]);
+		}
+
+		print("\n");
+
+		for(int i =0; i< KEY_COUNT; ++i) {
+			if(!(i & 0x0f)) {
+				print("\n");
+			} else if (!(i & 0x07)) {
+				print("  ");
+			}
+			print(" ");
+			//printHex (keys_averages[(i >> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]);
+			//printHex (keys_averages_acc[i]);
+			printHex(full_samples[i]);
+		}
+	}
+
+
+	//}
+
+//	uint8_t cur_strober = 0xe;
+	uint8_t cur_strober = ze_strober;
+	print("\n");
+
+	printHex(cur_strober);
+	//print(":         ");
+	print(": ");
+#if 1
+	print("\n");
+	for (uint8_t i=0; i < MUXES_COUNT; ++i) {
+		print(" ");
+		printHex(full_samples[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
+	}
+
+	print("\n");
+//	printHex(threshold);
+//	print(": ");
+
+	for (uint8_t i=0; i < MUXES_COUNT; ++i) {
+		print(" ");
+		printHex(keys_averages[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
+	}
+
+#endif
+	/*
+	for (uint8_t i=0; i< SAMPLES; ++i) {
+		print(" ");
+		printHex(samples[i]);
+		//printHex(ADC);
+	}*/
+	//print(" : ");
+	//dPrint((was_active)?" ":"*");
+
+	//printHex(keymap[TEST_KEY_STROBE] & TEST_KEY_MASK);
+	/*print(" "); */
+	//printHex(keymap[TEST_KEY_STROBE]);
+
+
+	//print("\n");
+	//print(":");
+	//printHex(full_av);
+	//printHex(count);
+	//print(" : ");
+	print("\n");
+
+	for (uint8_t i=0; i < STROBE_LINES; ++i) {
+		printHex(cur_keymap[i]);
+		print(" ");
+
+		//print(" ");
+	}
+
+
+	//print(": ");
+	//printHex(adc_strobe_averages[ze_strober]);
+	//print(" ");
+
+
+
+	for (uint8_t i=0; i < MUXES_COUNT; ++i) {
+		print(" ");
+		//printHex(adc_mux_averages[i] + adc_strobe_averages[ze_strober] - full_av);
+		//printHex((adc_mux_averages[i] + adc_strobe_averages[ze_strober]) >> 1);
+		//printHex((adc_mux_averages[i] * 3  + adc_strobe_averages[ze_strober]) >> 2);
+		//printHex(adc_mux_averages[i] + threshold);
+		//printHex(gsamples[i + SAMPLE_OFFSET] - (adc_mux_averages[i] + threshold) + 0x100);
+		//printHex(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i] + (uint8_t)threshold);
+		printHex(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i]);
+	}
+
+	if(error) {
+		print(" ");
+		printHex(error);
+		print(" ");
+		printHex(error_data);
+		error = 0;
+		error_data = 0;
+	}
+	//print("\n");
+
+	ze_strober++;
+	ze_strober &= 0xf;
+
+
+	dump_count++;
+	dump_count &= 0x0f;
+
+
+
+	//ze_strobe = (1 << (ze_strober ) );
+
+
+
+	//printHex(ADCSRA);
+	//print(" ");
+			//print("\n");
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Scan/avr-capsense/scan_loop.h	Sat Apr 13 22:35:59 2013 -0400
@@ -0,0 +1,54 @@
+/* Copyright (C) 2013 by Jacob Alexander
+ * 
+ * dfj, put whatever license here you want
+ * This file will probably be removed though.
+ */
+
+#ifndef __SCAN_LOOP_H
+#define __SCAN_LOOP_H
+
+// ----- Includes -----
+
+// Compiler Includes
+#include <stdint.h>
+
+// Local Includes
+
+
+
+// ----- Defines -----
+
+#define KEYBOARD_KEYS 0xFF // TODO Determine max number of keys
+#define KEYBOARD_BUFFER 24 // Max number of key signals to buffer
+                           // This limits the NKRO-ability, so at 24, the keyboard is 24KRO
+                           // The buffer is really only needed for converter modules
+                           // An alternative macro module could be written for matrix modules and still work well
+
+
+
+// ----- Variables -----
+
+extern volatile     uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
+extern volatile     uint8_t KeyIndex_BufferUsed;
+
+
+
+// ----- Functions -----
+
+// Functions used by main.c
+void scan_setup( void );
+uint8_t scan_loop( void );
+
+
+// Functions available to macro.c
+uint8_t scan_sendData( uint8_t dataPayload );
+
+void scan_finishedWithBuffer( uint8_t sentKeys );
+void scan_finishedWithUSBBuffer( uint8_t sentKeys );
+void scan_lockKeyboard( void );
+void scan_unlockKeyboard( void );
+void scan_resetKeyboard( void );
+
+
+#endif // __SCAN_LOOP_H
+
--- a/Scan/avr-capsense/setup.cmake	Sat Apr 13 20:11:40 2013 -0400
+++ b/Scan/avr-capsense/setup.cmake	Sat Apr 13 22:35:59 2013 -0400
@@ -1,6 +1,6 @@
 ###| CMake Kiibohd Controller Scan Module |###
 #
-# Written by Jacob Alexander in 2011 for the Kiibohd Controller
+# Written by Jacob Alexander in 2013 for the Kiibohd Controller
 #
 # Released into the Public Domain
 #
@@ -11,26 +11,37 @@
 # Module C files
 #
 
-#| XXX Requires the ../ due to how the paths are constructed
 set( SCAN_SRCS
-	../matrix/matrix_scan.c
-	../matrix/scan_loop.c
+	scan_loop.c
 )
 
 
 ###
+# Module H files
+#
+set( SCAN_HDRS
+	scan_loop.h
+)
+
+
+###
+# File Dependency Setup
+#
+ADD_FILE_DEPENDENCIES( scan_loop.c ${SCAN_HDRS} )
+#add_file_dependencies( scan_loop.c ${SCAN_HDRS} )
+#add_file_dependencies( macro.c keymap.h avrcapsense.h )
+
+
+###
 # Module Specific Options
 #
 add_definitions( -I${HEAD_DIR}/Keymap )
-add_definitions(
-	-I${HEAD_DIR}/Scan/matrix
-)	
 
 #| Keymap Settings
 add_definitions(
-	-DMODIFIER_MASK=budkeypad_ModifierMask
-	#-DKEYINDEX_MASK=budkeypad_TheProfosistMap
-	-DKEYINDEX_MASK=budkeypad_DefaultMap
+	-DMODIFIER_MASK=avrcapsense_ModifierMask
+	#-DKEYINDEX_MASK=avrcapsense_ColemakMap
+	-DKEYINDEX_MASK=avrcapsense_DefaultMap
 )
 
 
--- a/setup.cmake	Sat Apr 13 20:11:40 2013 -0400
+++ b/setup.cmake	Sat Apr 13 22:35:59 2013 -0400
@@ -20,7 +20,7 @@
 #| Please the {Scan,Macro,USB,Debug}/module.txt for information on the modules and how to create new ones
 
 ##| Deals with acquiring the keypress information and turning it into a key index
-set(  ScanModule  "MBC-55X" )
+set(  ScanModule  "avr-capsense" )
 
 ##| Uses the key index and potentially applies special conditions to it, mapping it to a usb key code
 set( MacroModule  "buffer"  )