]> git.donarmstrong.com Git - kiibohd-controller.git/commitdiff
Adapting the avr-capsense code to the Kiibohd Controller API
authorJacob Alexander <triplehaata@gmail.com>
Sun, 14 Apr 2013 02:35:59 +0000 (22:35 -0400)
committerJacob Alexander <haata@users.sf.net>
Sun, 17 Nov 2013 00:37:16 +0000 (19:37 -0500)
- 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

CMakeLists.txt
Debug/print/print.h
Keymap/avrcapsense.h [new file with mode: 0644]
Keymap/keymap.h
Scan/avr-capsense/scan_loop.c [changed mode: 0755->0644]
Scan/avr-capsense/scan_loop.h [new file with mode: 0644]
Scan/avr-capsense/setup.cmake [changed mode: 0755->0644]
setup.cmake

index 7ce02108193f337f1439bed69a722b534fd1e0bc..a68fc2fa0142e5e3e11bcb9260a0293f907c4d9c 100644 (file)
@@ -27,8 +27,8 @@ include( AddFileDependencies )
 #| "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}" )
index ee36203cdacb3e84d7a6737eac1132a400074eb5..801cca1fae86599b4eb7cf79017de5fa101aaae8 100644 (file)
@@ -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 @@ void printHex_op( uint16_t in, uint8_t op );
 // 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 );
 
diff --git a/Keymap/avrcapsense.h b/Keymap/avrcapsense.h
new file mode 100644 (file)
index 0000000..9b76996
--- /dev/null
@@ -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
+
index 4f12803c5968dd616aaf3f517b49e0b04ec938c1..5ad706e513b964038c84fd6946a3d77fcaefce60 100644 (file)
@@ -41,6 +41,7 @@
 
 
 // See files for full layout descriptions
+#include "avrcapsense.h"
 #include "betkb.h"
 #include "budkeypad.h"
 #include "epsonqx10.h"
old mode 100755 (executable)
new mode 100644 (file)
index 7ce472e..3d80c76
-/* Keyboard example with debug channel, for Teensy USB Development Board\r
- * http://www.pjrc.com/teensy/usb_keyboard.html\r
- * Copyright (c) 2008 PJRC.COM, LLC\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining a copy\r
- * of this software and associated documentation files (the "Software"), to deal\r
- * in the Software without restriction, including without limitation the rights\r
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- * copies of the Software, and to permit persons to whom the Software is\r
- * furnished to do so, subject to the following conditions:\r
- *\r
- * The above copyright notice and this permission notice shall be included in\r
- * all copies or substantial portions of the Software.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
- * THE SOFTWARE.\r
- */\r
-\r
-#include <avr/io.h>\r
-#include <avr/pgmspace.h>\r
-#include <avr/interrupt.h>\r
-#include <util/delay.h>\r
-#include "usb_keyboard_debug.h"\r
-#include "print.h"\r
-\r
-#define LED_CONFIG     (DDRD |= (1<<6))\r
-#define LED_ON         (PORTD &= ~(1<<6))\r
-#define LED_OFF                (PORTD |= (1<<6))\r
-#define CPU_PRESCALE(n)        (CLKPR = 0x80, CLKPR = (n))\r
-\r
-#define THRESHOLD 0x0a\r
-#define BUMP_THRESHOLD 0x50\r
-//((THRESHOLD) * 3)\r
-#define BUMP_REST_US 1200\r
-\r
-#define HYST 1\r
-#define HYST_T 0x10\r
-\r
-#define TEST_KEY_STROBE (0x05)\r
-#define TEST_KEY_MASK (1 << 0)\r
-\r
-#define ADHSM 7\r
-\r
-/** Whether to use all of D and C, vs using E0, E1 instead of D6, D7,\r
- * or alternately all of D, and E0,E1 and C0,..5 */\r
-//#define ALL_D_C\r
-//#define SHORT_D\r
-#define SHORT_C\r
-\r
-// rough offset voltage: one diode drop, about 50mV = 0x3ff * 50/3560 = 20\r
-//#define OFFSET_VOLTAGE 0x14\r
-#define OFFSET_VOLTAGE 0x28\r
-\r
-volatile uint8_t idle_count=1;\r
-\r
-uint8_t blink=0;\r
-\r
-volatile uint16_t full_av = 0;\r
-\r
-#define RIGHT_JUSTIFY 0\r
-#define LEFT_JUSTIFY (0xff)\r
-\r
-// set left or right justification here:\r
-#define JUSTIFY_ADC RIGHT_JUSTIFY\r
-\r
-#define ADLAR_MASK (1 << ADLAR)\r
-#ifdef JUSTIFY_ADC\r
-#define ADLAR_BITS ((ADLAR_MASK) & (JUSTIFY_ADC))\r
-#else // defaults to right justification.\r
-#define ADLAR_BITS 0\r
-#endif\r
-\r
-\r
-// full muxmask\r
-#define FULL_MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2) | (1 << MUX3) | (1 << MUX4))\r
-\r
-// F0-f7 pins only muxmask.\r
-#define MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2))\r
-\r
-#define SET_MUX(X) ((ADMUX) = (((ADMUX) & ~(MUX_MASK)) | ((X) & (MUX_MASK))))\r
-#define SET_FULL_MUX(X) ((ADMUX) = (((ADMUX) & ~(FULL_MUX_MASK)) | ((X) & (FULL_MUX_MASK))))\r
-\r
-#define MUX_1_1 0x1e\r
-#define MUX_GND 0x1f\r
-\r
-\r
-       // set ADC clock prescale\r
-#define PRESCALE_MASK ((1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2))\r
-#define PRESCALE_SHIFT (ADPS0)\r
-#define PRESCALE 3\r
-\r
-\r
-/**/ uint8_t ze_strober = 0;\r
-\r
-#ifdef EXTENDED_STROBE\r
-\r
-#define STROBE_LINES 18\r
-\r
-#else\r
-\r
-#define STROBE_LINES 16\r
-\r
-#endif\r
-\r
-#define STROBE_LINES_XSHIFT 4\r
-#define STROBE_LINES_MASK 0x0f\r
-#define MUXES_COUNT 8\r
-#define MUXES_COUNT_XSHIFT 3\r
-#define MUXES_MASK 0x7\r
-\r
-#define WARMUP_LOOPS ( 1024 )\r
-\r
-#define RECOVERY_US 6\r
-\r
-#define SAMPLES 10\r
-int16_t samples [SAMPLES];\r
-\r
-//int16_t gsamples [SAMPLES];\r
-\r
-#define SAMPLE_OFFSET ((SAMPLES) - MUXES_COUNT)\r
-//#define SAMPLE_OFFSET 9\r
-#define STROBE_OFFSET 0\r
-\r
-/**/ int16_t adc_mux_averages[MUXES_COUNT];\r
-/**/ int16_t adc_strobe_averages[STROBE_LINES];\r
-\r
-\r
-/**/ uint8_t cur_keymap[STROBE_LINES];\r
-// /**/ int8_t last_keymap[STROBE_LINES];\r
-/**/ uint8_t usb_keymap[STROBE_LINES];\r
-uint8_t dirty;\r
-uint8_t unstable;\r
-uint8_t usb_dirty;\r
-\r
-int16_t threshold = THRESHOLD;\r
-uint16_t tests = 0;\r
-\r
-uint8_t col_a=0;\r
-uint8_t col_b=0;\r
-uint8_t col_c=0;\r
-\r
-uint8_t column=0;\r
-\r
-#define KEY_COUNT ((STROBE_LINES) * (MUXES_COUNT))\r
-\r
-int16_t keys_averages_acc[KEY_COUNT];\r
-uint16_t keys_averages[KEY_COUNT];\r
-\r
-uint8_t full_samples[KEY_COUNT];\r
-\r
-/* viable starting biases for near 0.830V offset. and adc PRESCALE 3\r
-0017 0016 001B 001A 0016 0016 000F 000E 001B 001E 001E 0018 0017 0015 000E 001D\r
-001B 001A 0016 0016 000F 000E 001C 001B 001E 0018 0017 0015 000E 001D 0024 001F\r
-0016 0016 000F 000E 001C 001B 001E 001E 0017 0015 000E 001D 0024 001F 0020 001F\r
-000F 000E 001C 001B 001E 001E 0018 0017 000E 001D 0024 001F 0020 001F 0020 0017\r
-001C 001B 001E 001E 0018 0017 0015 000E 0024 001F 0020 001F 0020 0017 0010 001D\r
-001E 001E 0018 0017 0015 000E 001D 0024 0020 001F 0020 0017 0010 001D 0024 0021\r
-0018 0017 0015 000E 001D 0024 001F 0020 0020 0017 0010 001D 0024 0021 0021 0021\r
-0015 000E 001D 0024 001F 0020 001F 0020 0010 001D 0024 0021 0021 0021 0021 0018\r
-*/\r
-\r
-/*** starting bias relative to fixed offset estimate of 820mV (0x50)\r
- *   77 69 65 5B 50 4E 4C 45   66 53 4D 49 45 3F 3E 35\r
- *   68 54 4F 49 45 40 3F 34   74 66 5F 56 4E 4D 4C 3F\r
- *   6D 5D 53 4C 49 46 45 38   6D 5A 53 4E 49 48 45 3E\r
- *   6F 5D 56 4E 4B 48 48 3A   6D 5C 54 4E 48 48 45 37\r
- *   75 68 5F 57 4F 4D 4C 3F   60 4E 48 41 3C 3C 39 2F\r
- *   65 53 4E 49 41 3F 3E 34   65 54 4E 49 43 3F 3E 34\r
- *   60 51 4A 45 3F 3E 3C 30   57 4C 45 3E 3B 37 37 2E\r
- *   64 4E 48 44 3C 3B 39 2F   5D 4F 48 45 3E 3C 3B 30\r
- */\r
-\r
-/*volatile*/ uint16_t count = 0;\r
-\r
-\r
-\r
-/*volatile*/ uint8_t error = 0;\r
-uint16_t error_data = 0;\r
-\r
-void dump(void);\r
-void dumpkeys(void);\r
-\r
-static const uint8_t PROGMEM matrix122F_to_set3[] = {\r
-0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x84, // (), npenter, np3, (), np+, np9, np*, np-\r
-0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, // np0, np., np2, np5, np6, np8, numlck, np/\r
-0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, //\r
-0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\r
-0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,\r
-0x00, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, // 0x50 vanishes - is test key.\r
-0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, // 0x48 vanishes - else roll back.\r
-0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,\r
-0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,\r
-0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,\r
-0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,\r
-0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,\r
-0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,\r
-0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,\r
-0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,\r
-0x01, 0x83, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 0x02 is replaced with 0x83.\r
-};\r
-\r
-#define LX2FX\r
-\r
-static const uint8_t PROGMEM page3_2_USB[133] = {\r
-0x0,           // 00   00  // no key.\r
-\r
-#ifndef LX2FX\r
-\r
-0xe3,          // 01       Enl   Help -> windows. (e3)\r
-0x0,           // 02           // no key.\r
-0x80,  // 03   A4  ExSel SetUp print, -> paste 7d -> vol up 80\r
-0x46,  // 04   A3  CrSel       Properties -> copy 7c -> mute 7f-> prt-scrn\r
-0x29,  // 05   9A  Attn  SysRq // good place fer escape. (29)\r
-0x47,          // 06   9C  Clear -> kp / 54 -> scroll-lock (47)\r
-0x3a,          // 07   3A  F1\r
-0x68,          // 08   68  F13\r
-0x65,          // 09       Ctrl        // record/pause // -> kb application (65)\r
-0x74,          // 0A       Copy  Test // play/test -> execute 74 -> kp + 57\r
-0x75,          // 0B      // no key. help (75) -> kp - 56\r
-0x48,          // 0C       Pause ErInp erase input. -> cut 7b -> kp * 55 -> pause 48\r
-\r
-#else\r
-\r
-/*\r
-0x42,          // 01       L9\r
-0x0,           // 02           // no key.\r
-0x3e,          // 03           L5\r
-0x3c,          // 04           L3\r
-0x3a,          // 05           L1\r
-0x3b,          // 06           L2\r
-0x3a,          // 07   3A  F1\r
-0x68,          // 08   68  F13\r
-0x43,          // 09           L10\r
-0x41,          // 0A           L8\r
-0x3f,          // 0B           L6\r
-0x3d,          // 0C           L4\r
-*/\r
-0x61,          // 01       L9 -> num 9  0x61\r
-0x0,           // 02           // no key.\r
-0x5d,          // 03           L5 -> num 5  0x5d\r
-0x5b,          // 04           L3 -> num 3  0x5b\r
-0x59,          // 05           L1 -> num 1  0x59\r
-0x5a,          // 06           L2 -> num 2  0x5a\r
-0x3a,          // 07   3A  F1\r
-0x68,          // 08   68  F13\r
-0x62,          // 09           L10 -> num 0 0x62\r
-0x60,          // 0A           L8 -> num 8 0x60\r
-0x5e,          // 0B           L6 -> num 6 0x5e\r
-0x5c,          // 0C           L4 -> num 4 0x5c\r
-#endif\r
-\r
-\r
-0x2b,          // 0D   2B  Tab\r
-0x29,          // 0E   35  ~ ` -> escape 29\r
-0x3b,          // 0F   3B  F2\r
-0x69,          // 10   69  F14\r
-0xe0,          // 11   E0  Ctrl L\r
-0xe1,          // 12   E1  Shift L\r
-0xe1,          // 13   64  left of z. -> l shift e1\r
-0x39,          // 14   39  Caps Lock\r
-0x14,          // 15   14  Q\r
-0x1e,          // 16   1E  ! 1\r
-0x3c,          // 17   3C  F3\r
-0x6a,          // 18   6A  F15\r
-0xe2,          // 19   E2  Alt L\r
-0x1d,          // 1A   1D  Z\r
-0x16,          // 1B   16  S\r
-0x04,          // 1C   04  A\r
-0x1a,          // 1D   1A  W\r
-0x1f,          // 1E   1F  @ 2\r
-0x3d,          // 1F   3D  F4\r
-0x6b,          // 20   6B  F16\r
-0x06,          // 21   06  C\r
-0x1b,          // 22   1B  X\r
-0x07,          // 23   07  D\r
-0x08,          // 24   08  E\r
-0x21,          // 25   21  $ 4\r
-0x20,          // 26   20  # 3\r
-0x3e,          // 27   3E  F5\r
-0x6c,          // 28   6C  F17\r
-0x2c,          // 29   2C  Space\r
-0x19,          // 2A   19  V\r
-0x09,          // 2B   09  F\r
-0x17,          // 2C   17  T\r
-0x15,          // 2D   15  R\r
-0x22,          // 2E   22  % 5\r
-0x3f,          // 2F   3F  F6\r
-0x6d,          // 30   6D  F18\r
-0x11,          // 31   11  N\r
-0x05,          // 32   05  B\r
-0x0b,          // 33   0B  H\r
-0x0a,          // 34   0A  G\r
-0x1c,          // 35   1C  Y\r
-0x23,          // 36   23  ^ 6\r
-0x40,          // 37   40  F7\r
-0x6e,          // 38   6E  F19\r
-0xe6,          // 39   E6  Alt R\r
-0x10,          // 3A   10  M\r
-0x0d,          // 3B   0D  J\r
-0x18,          // 3C   18  U\r
-0x24,          // 3D   24  & 7\r
-0x25,          // 3E   25  * 8\r
-0x41,          // 3F   41  F8\r
-0x6f,          // 40   6F  F20\r
-0x36,          // 41   36  < ,\r
-0x0e,          // 42   0E  K\r
-0x0c,          // 43   0C  I\r
-0x12,          // 44   12  O\r
-0x27,          // 45   27  ) 0\r
-0x26,          // 46   26  ( 9\r
-0x42,          // 47   42  F9\r
-0x70,          // 48   70  F21\r
-0x37,          // 49   37  > .\r
-0x38,          // 4A   38  ? /\r
-0x0f,          // 4B   0F  L\r
-0x33,          // 4C   33  : ;\r
-0x13,          // 4D   13  P\r
-0x2d,          // 4E   2D  _ -\r
-0x43,          // 4F   43  F10\r
-0x71,          // 50   71  F22\r
-0xe5,          // 51   87  likely a shift - e.g. kp shift -> e5\r
-0x34,          // 52   34  " '\r
-0x31,          // 53      (INT 2) -> keypad enter. 58 -> |/\ (31)\r
-0x2f,          // 54   2F  { [\r
-0x2e,          // 55   2E  + =\r
-0x44,          // 56   44  F11\r
-0x72,          // 57   72  F23  -> vol up.\r
-0xe4,          // 58   E4  Ctrl R\r
-0xe5,          // 59   E5  Shift R\r
-0x28,          // 5A   28  Enter\r
-0x30,          // 5B   30  } ]\r
-0x31,          // 5C   31  | '\'\r
-0x35,          // 5D   -> kp = 67 -> ~` 35\r
-0x45,          // 5E   45  F12\r
-0x73,          // 5F   73  F24 -> vol down.\r
-0x51,          // 60   51  Down CP\r
-0x50,          // 61   50  Left CP\r
-0x51, //0x0,// 62       Rule // centre cp.  //62   48  Pause/Bk\r
-0x52,          // 63   52  Up CP\r
-0x4c,          // 64   4C  Del CP\r
-0x4d,          // 65   4D  End CP\r
-0x2a,          // 66   2A  Back Space\r
-0x49,          // 67   49  Ins CP\r
-0x48,          // 68           // under kp0 => kp 0 (62) 48 -> pause (48)\r
-0x59,          // 69   59  1 End KP\r
-0x4f,          // 6A   4F  Right CP\r
-0x5c,          // 6B   5C  4 Left KP\r
-0x5f,          // 6C   5F  7 Home KP\r
-0x4e,          // 6D   4E  PgDn CP\r
-0x4a,          // 6E   4A  Home CP\r
-0x4b,          // 6F   4B  PgUp CP\r
-0x62,          // 70   62  0 Ins KP -> pause (+48) -> kp-0 (62)\r
-0x63,          // 71   63  . Del KP\r
-0x5a,          // 72   5A  2 Down KP\r
-0x5d,          // 73   97  5 KP\r
-0x5e,          // 74   5E  6 Right KP\r
-0x60,          // 75   60  8 Up KP\r
-0x53,          // 76   53  Num Lock\r
-0x54,          // 77   54  / KP\r
-0x47,          // 78       Undo // under enter -> scroll-lock 47\r
-0x58,          // 79   58  Enter KP ->  enter kp\r
-0x5b,          // 7A   5B  3 PgDn KP\r
-0x46,          // 7B       (INT 5) // under + -> print screen (46\r
-0x57,          // 7C   57  + KP\r
-0x61,          // 7D   61  9 PgUp KP\r
-0x55,          // 7E   55  * KP\r
-0x0,           // 7F                   no such key?\r
-0x0,           // 80           no such key\r
-0x0,           // 81              Paste?\r
-0x0,           // 82              Find?\r
-#ifndef LX2FX\r
-0x81,          // 83   Print Ident -> undo 7a -> vol down 81\r
-#else\r
-//0x40,                // 83   L7 (f1) 3a\r
-0x5f,          // 83   L7 (f1) 3a -> num 7 0x5f\r
-#endif\r
-0x56           // 84   56  - KP\r
-};\r
-\r
-void\r
-_delay_loop(uint8_t __count)\r
-{\r
-       __asm__ volatile (\r
-               "1: dec %0" "\n\t"\r
-               "brne 1b"\r
-               : "=r" (__count)\r
-               : "0" (__count)\r
-       );\r
-}\r
-\r
-\r
-void setup_ADC (void) {\r
-       // disable adc digital pins.\r
-       DIDR1 |= (1 << AIN0D) | (1<<AIN1D); // set disable on pins 1,0.\r
-       //DIDR0 = 0xff; // disable all. (port F, usually). - testing w/o disable.\r
-       DDRF = 0x0;\r
-       PORTF = 0x0;\r
-       uint8_t mux = 0 & 0x1f; // 0 == first. // 0x1e = 1.1V ref.\r
-\r
-       // 0 = external aref 1,1 = 2.56V internal ref\r
-       uint8_t aref = ((1 << REFS1) | (1 << REFS0)) & ((1 << REFS1) | (1 << REFS0));\r
-//     uint8_t adlar = 0xff & (1 << ADLAR); // 1 := left justify bits, 0 := right\r
-       uint8_t adate = (1 << ADATE) & (1 << ADATE); // trigger enable\r
-       uint8_t trig = 0 & ((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2)); // 0 = free running\r
-       // ps2, ps1 := /64 ( 2^6 ) ps2 := /16 (2^4), ps1 := 4, ps0 :=2, PS1,PS0 := 8 (2^8)\r
-       uint8_t prescale = ( ((PRESCALE) << PRESCALE_SHIFT) & PRESCALE_MASK ); // 001 == 2^1 == 2\r
-       uint8_t hispeed = (1 << ADHSM);\r
-       uint8_t en_mux = (1 << ACME);\r
-\r
-       //ADCSRA = (ADCSRA & ~PRESCALES) | ((1 << ADPS1) | (1 << ADPS2)); // 2, 1 := /64 ( 2^6 )\r
-       //ADCSRA = (ADCSRA & ~PRESCALES) | ((1 << ADPS0) | (1 << ADPS2)); // 2, 0 := /32 ( 2^5 )\r
-       //ADCSRA = (ADCSRA & ~PRESCALES) | ((1 << ADPS2)); // 2 := /16 ( 2^4 )\r
-\r
-       ADCSRA = (1 << ADEN) | prescale; // ADC enable\r
-\r
-       // select ref.\r
-       //ADMUX |= ((1 << REFS1) | (1 << REFS0)); // 2.56 V internal.\r
-       //ADMUX |= ((1 << REFS0) ); // Vcc with external cap.\r
-       //ADMUX &= ~((1 << REFS1) | (1 << REFS0)); // 0,0 : aref.\r
-       ADMUX = aref | mux | ADLAR_BITS;\r
-\r
-       // enable MUX\r
-       // ADCSRB |= (1 << ACME);       // enable\r
-       // ADCSRB &= ~(1 << ADEN); // ?\r
-\r
-       // select first mux.\r
-       //ADMUX = (ADMUX & ~MUXES); // start at 000 = ADC0\r
-\r
-       // clear adlar to left justify data\r
-       //ADMUX = ~();\r
-\r
-       // set adlar to right justify data\r
-       //ADMUX |= (1 << ADLAR);\r
-\r
-\r
-       // set free-running\r
-       ADCSRA |= adate; // trigger enable\r
-       ADCSRB  = en_mux | hispeed | trig | (ADCSRB & ~((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2))); // trigger select free running\r
-\r
-//     ADCSRA |= (1 << ADATE); // tiggger enable\r
-\r
-       ADCSRA |= (1 << ADEN); // ADC enable\r
-       ADCSRA |= (1 << ADSC); // start conversions q\r
-\r
-}\r
-\r
-\r
-#define RECOVERY_CONTROL 1\r
-\r
-#define RECOVERY_SOURCE 0\r
-#define RECOVERY_SINK 2\r
-#define RECOVERY_MASK 0x03\r
-\r
-void recovery(uint8_t on) {\r
-       DDRB |= (1 << RECOVERY_CONTROL);\r
-\r
-       PORTB &= ~(1 << RECOVERY_SINK);    // SINK always zero\r
-       DDRB &= ~(1 << RECOVERY_SOURCE);  // SOURCE high imp\r
-\r
-       if(on) {\r
-               DDRB |= (1 << RECOVERY_SINK);   // SINK pull\r
-\r
-\r
-               PORTB |= (1 << RECOVERY_CONTROL);\r
-\r
-               PORTB |= (1 << RECOVERY_SOURCE); // SOURCE high\r
-               DDRB |= (1 << RECOVERY_SOURCE);\r
-       } else {\r
-               _delay_loop(10);\r
-               PORTB &= ~(1 << RECOVERY_CONTROL);\r
-\r
-               DDRB &= ~(1 << RECOVERY_SOURCE);\r
-               PORTB &= ~(1 << RECOVERY_SOURCE); // SOURCE low\r
-               DDRB &= ~(1 << RECOVERY_SINK);  // SINK high-imp\r
-\r
-               //DDRB &= ~(1 << RECOVERY_SINK);\r
-       }\r
-}\r
-\r
-void strobe_w(uint8_t strobe_num) {\r
-\r
-#ifdef ALL_D_C\r
-\r
-#define D_MASK (0xff)\r
-#define D_SHIFT 0\r
-\r
-#define E_MASK (0x00)\r
-#define E_SHIFT 0\r
-\r
-#define C_MASK (0xff)\r
-#define C_SHIFT 8\r
-\r
-#else\r
-#if defined(SHORT_D)\r
-\r
-#define D_MASK (0x3f)\r
-#define D_SHIFT 0\r
-\r
-#define E_MASK (0x03)\r
-#define E_SHIFT 6\r
-\r
-#define C_MASK (0xff)\r
-#define C_SHIFT 8\r
-\r
-#else\r
-#if defined(SHORT_C)\r
-\r
-#define D_MASK (0xff)\r
-#define D_SHIFT 0\r
-\r
-#define E_MASK (0x03)\r
-#define E_SHIFT 6\r
-\r
-#define C_MASK (0xff)\r
-#define C_SHIFT 8\r
-#endif\r
-#endif\r
-#endif\r
-\r
-\r
-\r
-#define STROBE_CASE(SC_CASE, SC_REG_A) case (SC_CASE): PORT##SC_REG_A = \\r
-       (( (PORT##SC_REG_A) & ~(1 << (SC_CASE - SC_REG_A##_SHIFT)) ) | (1 << (SC_CASE - SC_REG_A##_SHIFT)))\r
-\r
-       PORTC &= ~(D_MASK);\r
-       PORTD &= ~(D_MASK);\r
-       PORTE &= ~(E_MASK);\r
-\r
-#ifdef SHORT_C\r
-       strobe_num = 15 - strobe_num;\r
-#endif\r
-\r
-       switch(strobe_num) {\r
-\r
-       case 0: PORTD |= (1 << 0); break;\r
-       case 1: PORTD |= (1 << 1); break;\r
-       case 2: PORTD |= (1 << 2); break;\r
-       case 3: PORTD |= (1 << 3); break;\r
-       case 4: PORTD |= (1 << 4); break;\r
-       case 5: PORTD |= (1 << 5); break;\r
-\r
-#ifdef ALL_D\r
-\r
-       case 6: PORTD |= (1 << 6); break;\r
-       case 7: PORTD |= (1 << 7); break;\r
-\r
-       case 8:  PORTC |= (1 << 0); break;\r
-       case 9:  PORTC |= (1 << 1); break;\r
-       case 10: PORTC |= (1 << 2); break;\r
-       case 11: PORTC |= (1 << 3); break;\r
-       case 12: PORTC |= (1 << 4); break;\r
-       case 13: PORTC |= (1 << 5); break;\r
-       case 14: PORTC |= (1 << 6); break;\r
-       case 15: PORTC |= (1 << 7); break;\r
-\r
-       case 16: PORTE |= (1 << 0); break;\r
-       case 17: PORTE |= (1 << 1); break;\r
-\r
-#else\r
-#ifdef SHORT_D\r
-\r
-       case 6: PORTE |= (1 << 0); break;\r
-       case 7: PORTE |= (1 << 1); break;\r
-\r
-       case 8:  PORTC |= (1 << 0); break;\r
-       case 9:  PORTC |= (1 << 1); break;\r
-       case 10: PORTC |= (1 << 2); break;\r
-       case 11: PORTC |= (1 << 3); break;\r
-       case 12: PORTC |= (1 << 4); break;\r
-       case 13: PORTC |= (1 << 5); break;\r
-       case 14: PORTC |= (1 << 6); break;\r
-       case 15: PORTC |= (1 << 7); break;\r
-\r
-#else\r
-#ifdef SHORT_C\r
-\r
-       case 6: PORTD |= (1 << 6); break;\r
-       case 7: PORTD |= (1 << 7); break;\r
-\r
-       case 8: PORTE |= (1 << 0); break;\r
-       case 9: PORTE |= (1 << 1); break;\r
-\r
-       case 10:  PORTC |= (1 << 0); break;\r
-       case 11:  PORTC |= (1 << 1); break;\r
-       case 12: PORTC |= (1 << 2); break;\r
-       case 13: PORTC |= (1 << 3); break;\r
-       case 14: PORTC |= (1 << 4); break;\r
-       case 15: PORTC |= (1 << 5); break;\r
-\r
-       case 16: PORTC |= (1 << 6); break;\r
-       case 17: PORTC |= (1 << 7); break;\r
-\r
-#endif\r
-#endif\r
-#endif\r
-\r
-       default:\r
-               break;\r
-       }\r
-\r
-}\r
-\r
-\r
-int sampleColumn_i(uint8_t column, uint8_t muxes, int16_t * buffer) {\r
-\r
-       // ensure all probe lines are driven low, and chill for recovery delay.\r
-       PORTC &= ~C_MASK;\r
-       PORTD &= ~D_MASK;\r
-       PORTE &= ~E_MASK;\r
-       recovery(1);\r
-       _delay_us(RECOVERY_US);\r
-       recovery(0);\r
-\r
-       uint8_t index = 0;\r
-\r
-       for (uint8_t i=0; i<8; ++i) {\r
-               if(muxes & (1 << i)) {\r
-                       buffer[index++] = i;\r
-               }\r
-       }\r
-\r
-       SET_FULL_MUX(MUX_1_1); // crap sample will use this.\r
-       ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions\r
-       ADCSRA |= (1 << ADIF); // clear int flag by writing 1.\r
-\r
-       uint16_t sample;\r
-\r
-       while (! (ADCSRA & (1 << ADIF))); // wait until ready.\r
-       sample = ADC; // 1st sample, icky.\r
-\r
-       strobe_w(column);\r
-       //recovery(0);\r
-\r
-       /**\r
-        * we are running in continuous mode, so we must setup the next\r
-        * read _before_ the current read completes.\r
-        *\r
-        * setup 0,\r
-        * read garbage,\r
-        * do not store\r
-        *\r
-        * setup 1,\r
-        * read 0,\r
-        * store 0,\r
-        *\r
-        * ...\r
-        *\r
-        * setup junk,\r
-        * read n\r
-        * store n\r
-        *\r
-        * */\r
-\r
-\r
-       ADCSRA |= (1 << ADIF); // clear int flag by writing 1.\r
-       //wait for last read to complete.\r
-       while (! (ADCSRA & (1 << ADIF)));\r
-       sample = ADC; // throw away strobe'd value.\r
-\r
-#if 0\r
-       for (uint8_t i=0; i <= index; ++i) {\r
-\r
-               // setup i'th read.\r
-               SET_FULL_MUX(buffer[i]); // _next_ read will use this.\r
-               // wait for i-1'th read to complete:\r
-               ADCSRA |= (1 << ADIF); // clear int flag by writing 1.\r
-               while (! (ADCSRA & (1 << ADIF)));\r
-\r
-               // retrieve last (i-1'th) read.\r
-               if (i) {\r
-                       buffer[i-1] = ADC - OFFSET_VOLTAGE;\r
-               } /*else {\r
-                       buffer[0] = ADC - OFFSET_VOLTAGE;\r
-               }*/\r
-\r
-               //index++;\r
-       }\r
-#else\r
-       for (uint8_t i=0; i < index; ++i) {\r
-\r
-               // setup i'th read.\r
-               SET_FULL_MUX(buffer[i]); // _next_ read will use this.\r
-\r
-               ADCSRA |= (1 << ADIF); // clear int flag by writing 1.\r
-               while (! (ADCSRA & (1 << ADIF)));\r
-               sample = ADC; // throw away warmup value.\r
-\r
-\r
-\r
-               /*\r
-               ADCSRA |= (1 << ADIF); // clear int flag by writing 1.\r
-               while (! (ADCSRA & (1 << ADIF)));\r
-               sample = ADC; // throw away warmup value.\r
-*/\r
-\r
-               ADCSRA |= (1 << ADIF); // clear int flag by writing 1.\r
-               while (! (ADCSRA & (1 << ADIF)));\r
-\r
-               // retrieve current read.\r
-               buffer[i] = ADC - OFFSET_VOLTAGE;\r
-\r
-\r
-       }\r
-#endif\r
-\r
-\r
-       // turn off adc.\r
-       ADCSRA &= ~(1 << ADEN);\r
-\r
-       // pull all columns' probe-lines low.\r
-       PORTC &= ~C_MASK;\r
-       PORTD &= ~D_MASK;\r
-       PORTE &= ~E_MASK;\r
-\r
-       // test for humps. :/\r
-       /*uint16_t delta = full_av;\r
-       if(buffer[0] > BUMP_THRESHOLD + delta) {\r
-               // ze horror.\r
-               return 1;\r
-       } else {\r
-               return 0; //all good.\r
-       }*/\r
-       return 0;\r
-\r
-}\r
-\r
-int sampleColumn_k(uint8_t column, int16_t * buffer) {\r
-       // ensure all probe lines are driven low, and chill for recovery delay.\r
-       uint16_t sample;\r
-\r
-       ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions\r
-       ADCSRA |= (1 << ADIF); // clear int flag by writing 1.\r
-\r
-       // sync up with adc clock:\r
-       while (! (ADCSRA & (1 << ADIF))); // wait until ready.\r
-       sample = ADC; // throw it away.\r
-\r
-       for(uint8_t mux=0; mux < 8; ++mux) {\r
-\r
-               PORTC &= ~C_MASK;\r
-               PORTD &= ~D_MASK;\r
-               PORTE &= ~E_MASK;\r
-\r
-               SET_FULL_MUX(mux); // our sample will use this\r
-\r
-               for(uint8_t i=0; i < 2; ++i) {\r
-                       ADCSRA |= (1 << ADIF); // clear int flag by writing 1.\r
-                       //wait for last read to complete.\r
-                       while (! (ADCSRA & (1 << ADIF)));\r
-                       sample = ADC; // throw away strobe'd value.\r
-               }\r
-\r
-               recovery(0);\r
-               strobe_w(column);\r
-\r
-               ADCSRA |= (1 << ADIF); // clear int flag by writing 1.\r
-               //wait for last read to complete.\r
-               while (! (ADCSRA & (1 << ADIF)));\r
-               sample = ADC; // throw away strobe'd value.\r
-\r
-               ADCSRA |= (1 << ADIF); // clear int flag by writing 1.\r
-               while (! (ADCSRA & (1 << ADIF)));\r
-\r
-               // retrieve current read.\r
-               buffer[mux] = ADC - OFFSET_VOLTAGE;\r
-               recovery(1);\r
-\r
-       }\r
-\r
-       // turn off adc.\r
-       ADCSRA &= ~(1 << ADEN);\r
-\r
-       // pull all columns' probe-lines low.\r
-       PORTC &= ~C_MASK;\r
-       PORTD &= ~D_MASK;\r
-       PORTE &= ~E_MASK;\r
-//             recovery(1);\r
-\r
-\r
-       return 0;\r
-}\r
-\r
-int sampleColumn(uint8_t column) {\r
-       int rval = 0;\r
-\r
-       /*\r
-       sampleColumn_i(column, 0x0f, samples+SAMPLE_OFFSET);\r
-       sampleColumn_i(column, 0xf0, samples+SAMPLE_OFFSET + 4 );\r
-*/\r
-\r
-       rval = sampleColumn_k(column, samples+SAMPLE_OFFSET);\r
-\r
-       for(uint8_t i=0; i<8; ++i) {\r
-               if(samples[SAMPLE_OFFSET + i] - adc_mux_averages[i] > BUMP_THRESHOLD) {\r
-                       // was a hump\r
-\r
-                       _delay_us(BUMP_REST_US);\r
-                       rval++;\r
-                       error = 0x50;\r
-                       error_data = samples[SAMPLE_OFFSET +i]; //  | ((uint16_t)i << 8);\r
-                       return rval;\r
-               }\r
-       }\r
-\r
-       return rval;\r
-}\r
-\r
-\r
-\r
-uint8_t testColumn(uint8_t strobe) {\r
-    uint8_t column = 0;\r
-    uint8_t bit = 1;\r
-    for (uint8_t i=0; i < MUXES_COUNT; ++i) {\r
-               uint16_t delta = keys_averages[(strobe << MUXES_COUNT_XSHIFT) + i];\r
-               if ((int16_t)samples[SAMPLE_OFFSET + i] > threshold + delta) {\r
-                       column |= bit;\r
-               }\r
-               bit <<= 1;\r
-       }\r
-    return column;\r
-}\r
-\r
-int main(void) {\r
-       // set for 16 MHz clock\r
-       CPU_PRESCALE(0);\r
-\r
-       // Initialize the USB, and then wait for the host to set configuration.\r
-       // If the Teensy is powered without a PC connected to the USB port,\r
-       // this will wait forever.\r
-       usb_init();\r
-       while (!usb_configured()) /* wait */ ;\r
-\r
-       // Wait an extra second for the PC's operating system to load drivers\r
-       // and do whatever it does to actually be ready for input\r
-       _delay_ms(1000);\r
-\r
-       LED_CONFIG;\r
-\r
-       setup_ADC();\r
-\r
-       // Configure timer 0 to generate a timer overflow interrupt every\r
-       // 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock\r
-       // This demonstrates how to use interrupts to implement a simple\r
-       // inactivity timeout.\r
-       //TCCR0A = 0x00;\r
-       //TCCR0B = 0x05;\r
-       //TIMSK0 = (1<<TOIE0);\r
-\r
-       DDRC = C_MASK;\r
-       PORTC = 0;\r
-       DDRD = D_MASK;\r
-       PORTD = 0;\r
-       DDRE = E_MASK;\r
-       PORTE = 0 ;\r
-\r
-       //DDRC |= (1 << 6);\r
-       //PORTC &= ~(1<< 6);\r
-\r
-       //uint16_t strobe = 1;\r
-\r
-\r
-       uint8_t strober = 0;\r
-       uint32_t full_av_acc = 0;\r
-\r
-       for (int i=0; i< STROBE_LINES; ++i) {\r
-               cur_keymap[i] = 0;\r
-               //last_keymap[i] = 0;\r
-               usb_keymap[i] = 0;\r
-       }\r
-\r
-       int16_t mux_averages[MUXES_COUNT];\r
-       for(int i=0; i < MUXES_COUNT; ++i) {\r
-               adc_mux_averages[i] = 0x20; // experimentally determined.\r
-       }\r
-       int16_t strobe_averages[STROBE_LINES];\r
-       for(int i=0; i < STROBE_LINES; ++i) {\r
-               adc_strobe_averages[i] = 0x20; // yup.\r
-       }\r
-\r
-       for(int i=0; i< KEY_COUNT; ++i) {\r
-               keys_averages[i] = 0x40;\r
-               keys_averages_acc[i] = (0x400);\r
-       }\r
-\r
-       /** warm things up a bit before we start collecting data, taking real samples. */\r
-       for(uint8_t i = 0; i< STROBE_LINES; ++i) {\r
-               sampleColumn(i);\r
-       }\r
-\r
-       while(1) {\r
-\r
-               for (strober = 0; strober < STROBE_LINES; ++strober) {\r
-\r
-                       uint8_t tries;\r
-                       tries = 1;\r
-                       while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.\r
-                       column = testColumn(strober);\r
-\r
-                       if( column != cur_keymap[strober] && (count >= WARMUP_LOOPS) ) {\r
-                               tests++;\r
-\r
-                               tries = 1;\r
-                               while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.\r
-                               col_a = testColumn(strober);\r
-\r
-                               tries = 1;\r
-                               while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.\r
-                               col_b = testColumn(strober);\r
-\r
-                               tries = 1;\r
-                               while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.\r
-                               col_c = testColumn(strober);\r
-\r
-                               if( (col_a == col_b) && (col_b == col_c) && (cur_keymap[strober] != col_a) ) {\r
-                                       cur_keymap[strober] = col_a;\r
-                                       usb_dirty = 1;\r
-                               }\r
-                       }\r
-\r
-                       if(error == 0x50) {\r
-                               error_data |= (((uint16_t)strober) << 12);\r
-                       }\r
-\r
-                       for(int i=0; i<MUXES_COUNT; ++i) {\r
-                               full_samples[(strober << MUXES_COUNT_XSHIFT) + i] = samples[SAMPLE_OFFSET + i];\r
-                       }\r
-\r
-                       strobe_averages[strober] = 0;\r
-                       for (uint8_t i = SAMPLE_OFFSET; i < (SAMPLE_OFFSET + MUXES_COUNT); ++i) {\r
-                               //samples[i] -= samples[i-SAMPLE_OFFSET]; // av; // + full_av); // -something.\r
-                               //samples[i] -= OFFSET_VOLTAGE; // moved to sampleColumn.\r
-\r
-                               full_av_acc += (samples[i]);\r
-                               mux_averages[i - SAMPLE_OFFSET] += samples[i];\r
-                               strobe_averages[strober] += samples[i];\r
-                               //samples[i] -= (full_av - HYST_T);\r
-\r
-                               //++count;\r
-                       }\r
-                       adc_strobe_averages[strober] += strobe_averages[strober] >> 3;\r
-                       adc_strobe_averages[strober] >>= 1;\r
-\r
-                       /** test if we went negative. */\r
-                       if ((adc_strobe_averages[strober] & 0xFF00) && (count\r
-                                       >= WARMUP_LOOPS)) {\r
-                               //count = 0; // TODO : constrain properly.\r
-                               error = 0xf; error_data = adc_strobe_averages[strober];\r
-                       }\r
-\r
-                       uint8_t strobe_line = strober << MUXES_COUNT_XSHIFT;\r
-                       for (int i = 0; i < MUXES_COUNT; ++i) {\r
-                               keys_averages_acc[strobe_line + i]\r
-                                               += samples[SAMPLE_OFFSET + i];\r
-                       }\r
-\r
-               } // for strober\r
-\r
-               if (count < WARMUP_LOOPS) {\r
-                       error = 0x0C;\r
-                       error_data = count;\r
-                       count++;\r
-               }\r
-\r
-               // verify test key is not down.\r
-               if((cur_keymap[TEST_KEY_STROBE] & TEST_KEY_MASK) ) {\r
-                       //count=0;\r
-                       error = 0x05;\r
-                       error_data = cur_keymap[TEST_KEY_STROBE] << 8;\r
-                       error_data += full_samples[TEST_KEY_STROBE * 8];\r
-                       //threshold++;\r
-               }\r
-\r
-               // calc mux averages.\r
-               if (count < WARMUP_LOOPS) {\r
-                       full_av += (full_av_acc >> (7));\r
-                       full_av >>= 1;\r
-                       //full_av = full_av_acc / count;\r
-                       full_av_acc = 0;\r
-                       for (int i=0; i < MUXES_COUNT; ++i) {\r
-\r
-// mix in 1/4 of the current average to the running average. -> (@mux_mix = 2)\r
-#define MUX_MIX 2\r
-\r
-                               adc_mux_averages[i] = (adc_mux_averages[i] << MUX_MIX) - adc_mux_averages[i];\r
-                               adc_mux_averages[i] += (mux_averages[i] >> 4);\r
-                               adc_mux_averages[i] >>= MUX_MIX;\r
-\r
-                               mux_averages[i] = 0;\r
-                       }\r
-\r
-               }\r
-\r
-#define IDLE_COUNT_MASK 0xff\r
-#define MAX_ICS 8\r
-\r
-#define IDLE_COUNT_SHIFT 4\r
-#define KEYS_AVERAGES_MIX 2\r
-\r
-               idle_count++;\r
-               idle_count &= IDLE_COUNT_MASK;\r
-\r
-               if (/*usb_dirty &&*/ (count >= WARMUP_LOOPS) ) {\r
-                       for (int i=0; i<STROBE_LINES; ++i) {\r
-                               usb_keymap[i] = cur_keymap[i];\r
-                       }\r
-\r
-                       dumpkeys();\r
-                       usb_dirty=0;\r
-                       _delay_ms(2);\r
-               }\r
-\r
-               if (count < WARMUP_LOOPS) {\r
-                       for (uint8_t i = 0; i < KEY_COUNT; ++i) {\r
-                               uint16_t acc = keys_averages_acc[i];\r
-                               uint32_t av = keys_averages[i];\r
-\r
-                               av = av + av + av + acc;\r
-                               av >>= 2;\r
-\r
-                               keys_averages[i] = av;\r
-                               keys_averages_acc[i] = 0;\r
-                       }\r
-               }\r
-\r
-\r
-               if(!idle_count) {\r
-\r
-                       for (int i=0; i< KEY_COUNT; ++i) {\r
-                               keys_averages_acc[i] = 0;\r
-                       }\r
-\r
-                       sampleColumn(0x0); // to resync us if we dumped a mess 'o text.\r
-               }\r
-       }\r
-}\r
-\r
-\r
-void debug_println() {\r
-       usb_debug_putchar('\r');\r
-       usb_debug_putchar('\n');\r
-}\r
-\r
-\r
-// This interrupt routine is run approx 61 times per second.\r
-// A very simple inactivity timeout is implemented, where we\r
-// will send a space character and print a message to the\r
-// hid_listen debug message window.\r
-ISR(TIMER0_OVF_vect) {\r
-       //idle_count++;\r
-       /*\r
-       if (idle_count > 61) {\r
-               idle_count = 0;\r
-       }*/\r
-\r
-}\r
-\r
-void dumpkeys(void) {\r
-       //print(" \n");\r
-       if(error) {\r
-               for (uint8_t i=0; i < STROBE_LINES; ++i) {\r
-                               phex(usb_keymap[i]);\r
-                               usb_debug_putchar(' ');\r
-\r
-                               //print(" ");\r
-               }\r
-               if (count >= WARMUP_LOOPS && error) {\r
-                       dump();\r
-               }\r
-\r
-               print(" : ");\r
-               phex(error);\r
-               error = 0;\r
-               print(" : ");\r
-               phex16(error_data);\r
-               error_data = 0;\r
-               print(" : ");\r
-               debug_println();\r
-       }\r
-\r
-\r
-       for(uint8_t i = 0; i < 6; ++i) {\r
-               keyboard_keys[i] = 0;\r
-       }\r
-       keyboard_modifier_keys = 0;\r
-       uint8_t usbkeycount = 0;\r
-       for (uint8_t i=0; i < STROBE_LINES; ++i) {\r
-               for(uint8_t j=0; j<MUXES_COUNT; ++j) {\r
-                       if ( usb_keymap[i] & (1 << j) ) {\r
-                               uint8_t key = pgm_read_byte(matrix122F_to_set3 + ( (i << MUXES_COUNT_XSHIFT) + j) );\r
-                               if(usb_dirty) phex( key );\r
-                               if(usbkeycount < 6) {\r
-                                       uint8_t usbkey = pgm_read_byte(page3_2_USB + key);\r
-\r
-                                       if ((usbkey >= 0xe0) && (usbkey <= 0xe7)) { // metas\r
-                                               keyboard_modifier_keys |= (1 << (usbkey & 0x07));\r
-                                       } else {\r
-                                               keyboard_keys[usbkeycount++] =  usbkey;\r
-                                       }\r
-                               }\r
-                               if (usb_dirty) usb_debug_putchar(' ');\r
-                       }\r
-               }\r
-       }\r
-       if(usb_dirty) {\r
-               debug_println();\r
-       }\r
-\r
-       /** shall we send actual keyboard events? */\r
-#if 0\r
-       usb_keyboard_send();\r
-#endif\r
-\r
-}\r
-\r
-// taken from the datasheet.\r
-uint8_t readEE(uint16_t offset) {\r
-       /* Wait for completion of previous write */\r
-       while(EECR & (1<<EEPE))\r
-       ;\r
-       /* Set up address register */\r
-       EEAR = offset;\r
-       /* Start eeprom read by writing EERE */\r
-       EECR |= (1<<EERE);\r
-       /* Return data from Data Register */\r
-       return EEDR;\r
-}\r
-\r
-// taken from the datasheet - note: writing is very slow. >1ms/byte.\r
-void writeEE(uint16_t offset, uint8_t data) {\r
-       /* Wait for completion of previous write */\r
-       while(EECR & (1<<EEPE))\r
-       ;\r
-       /* Set up address and Data Registers */\r
-       EEAR = offset;\r
-       EEDR = data;\r
-       /* Write logical one to EEMPE */\r
-       EECR |= (1<<EEMPE);\r
-       /* Start eeprom write by setting EEPE */\r
-       EECR |= (1<<EEPE);\r
-}\r
-\r
-uint8_t dump_count = 0;\r
-void dump(void) {\r
-\r
-#if 0\r
-       static char once = 0;\r
-       uint8_t eb;\r
-\r
-       if(!once) {\r
-               print("\nwriting ee");\r
-               eb = readEE(0x10);\r
-               eb++;\r
-               writeEE(0x10, eb);\r
-\r
-               once++;\r
-       }\r
-\r
-\r
-       print("\n ee: ");\r
-       for(uint16_t i=0x10; i< 0x18; ++i) {\r
-               phex(readEE(i));\r
-               pchar(0x20);\r
-       }\r
-#endif\r
-\r
-       if(!dump_count) {  // we don't want to debug-out during the measurements.\r
-\r
-               for(int i =0; i< KEY_COUNT; ++i) {\r
-                       if(!(i & 0x0f)) {\r
-                               print("\n");\r
-                       } else if (!(i & 0x07)) {\r
-                               print("  ");\r
-                       }\r
-                       usb_debug_putchar(' ');\r
-                       //phex16 (keys_averages[(i >> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]);\r
-                       phex (keys_averages[i]);\r
-               }\r
-\r
-               print("\n");\r
-\r
-               for(int i =0; i< KEY_COUNT; ++i) {\r
-                       if(!(i & 0x0f)) {\r
-                               print("\n");\r
-                       } else if (!(i & 0x07)) {\r
-                               print("  ");\r
-                       }\r
-                       usb_debug_putchar(' ');\r
-                       //phex16 (keys_averages[(i >> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]);\r
-                       //phex16 (keys_averages_acc[i]);\r
-                       phex(full_samples[i]);\r
-               }\r
-       }\r
-\r
-\r
-       //}\r
-\r
-//     uint8_t cur_strober = 0xe;\r
-       uint8_t cur_strober = ze_strober;\r
-       print("\n");\r
-\r
-       phex(cur_strober);\r
-       //print(":         ");\r
-       print(": ");\r
-#if 1\r
-       print("\n");\r
-       for (uint8_t i=0; i < MUXES_COUNT; ++i) {\r
-               usb_debug_putchar(' ');\r
-               phex16(full_samples[(cur_strober << MUXES_COUNT_XSHIFT) + i]);\r
-       }\r
-\r
-       print("\n");\r
-//     phex(threshold);\r
-//     print(": ");\r
-\r
-       for (uint8_t i=0; i < MUXES_COUNT; ++i) {\r
-               usb_debug_putchar(' ');\r
-               phex16(keys_averages[(cur_strober << MUXES_COUNT_XSHIFT) + i]);\r
-       }\r
-\r
-#endif\r
-       /*\r
-       for (uint8_t i=0; i< SAMPLES; ++i) {\r
-               print(" ");\r
-               phex16(samples[i]);\r
-               //phex16(ADC);\r
-       }*/\r
-       //print(" : ");\r
-       //usb_debug_putchar((was_active)?' ':'*');\r
-\r
-       //phex16(keymap[TEST_KEY_STROBE] & TEST_KEY_MASK);\r
-       /*print(" "); */\r
-       //phex(keymap[TEST_KEY_STROBE]);\r
-\r
-\r
-       //print("\n");\r
-       //print(":");\r
-       //phex(full_av);\r
-       //phex16(count);\r
-       //print(" : ");\r
-       print("\n");\r
-\r
-       for (uint8_t i=0; i < STROBE_LINES; ++i) {\r
-               phex(cur_keymap[i]);\r
-               usb_debug_putchar(' ');\r
-\r
-               //print(" ");\r
-       }\r
-\r
-\r
-       //print(": ");\r
-       //phex(adc_strobe_averages[ze_strober]);\r
-       //usb_debug_putchar(' ');\r
-\r
-\r
-\r
-       for (uint8_t i=0; i < MUXES_COUNT; ++i) {\r
-               usb_debug_putchar(' ');\r
-               //phex16(adc_mux_averages[i] + adc_strobe_averages[ze_strober] - full_av);\r
-               //phex16((adc_mux_averages[i] + adc_strobe_averages[ze_strober]) >> 1);\r
-               //phex16((adc_mux_averages[i] * 3  + adc_strobe_averages[ze_strober]) >> 2);\r
-               //phex16(adc_mux_averages[i] + threshold);\r
-               //phex16(gsamples[i + SAMPLE_OFFSET] - (adc_mux_averages[i] + threshold) + 0x100);\r
-               //phex16(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i] + (uint8_t)threshold);\r
-               phex16(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i]);\r
-       }\r
-\r
-       if(error) {\r
-               usb_debug_putchar(' ');\r
-               phex (error);\r
-               usb_debug_putchar(' ');\r
-               phex16(error_data);\r
-               error = 0;\r
-               error_data = 0;\r
-       }\r
-       //print("\n");\r
-\r
-       ze_strober++;\r
-       ze_strober &= 0xf;\r
-\r
-\r
-       dump_count++;\r
-       dump_count &= 0x0f;\r
-\r
-\r
-\r
-       //ze_strobe = (1 << (ze_strober ) );\r
-\r
-\r
-\r
-       //phex(ADCSRA);\r
-       //print(" ");\r
-                       //print("\n");\r
-       //usb_keyboard_press(KEY_SPACE, 0);\r
-\r
-//             if(blink) {\r
-//                     LED_ON;\r
-//             } else {\r
-//                     LED_OFF;\r
-//             }\r
-//             blink ^= 1;\r
-}\r
-\r
-\r
-/*\r
-int oldmain(void) {\r
-       uint8_t b, d, mask, i, reset_idle;\r
-       uint8_t b_prev=0xFF, d_prev=0xFF;\r
-\r
-       // set for 16 MHz clock\r
-       CPU_PRESCALE(0);\r
-\r
-       // Configure all port B and port D pins as inputs with pullup resistors.\r
-       // See the "Using I/O Pins" page for details.\r
-       // http://www.pjrc.com/teensy/pins.html\r
-       DDRD = 0x00;\r
-       DDRB = 0x00;\r
-       PORTB = 0xFF;\r
-       PORTD = 0xFF;\r
-\r
-       // Initialize the USB, and then wait for the host to set configuration.\r
-       // If the Teensy is powered without a PC connected to the USB port,\r
-       // this will wait forever.\r
-       usb_init();\r
-       while (!usb_configured())  ;\r
-\r
-       // Wait an extra second for the PC's operating system to load drivers\r
-       // and do whatever it does to actually be ready for input\r
-       _delay_ms(1000);\r
-\r
-       // Configure timer 0 to generate a timer overflow interrupt every\r
-       // 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock\r
-       // This demonstrates how to use interrupts to implement a simple\r
-       // inactivity timeout.\r
-       TCCR0A = 0x00;\r
-       TCCR0B = 0x05;\r
-       TIMSK0 = (1<<TOIE0);\r
-\r
-       print("Begin keyboard example program\n");\r
-       print("All Port B or Port D pins are inputs with pullup resistors.\n");\r
-       print("Any connection to ground on Port B or D pins will result in\n");\r
-       print("keystrokes sent to the PC (and debug messages here).\n");\r
-       while (1) {\r
-               // read all port B and port D pins\r
-               b = PINB;\r
-               d = PIND;\r
-               // check if any pins are low, but were high previously\r
-               mask = 1;\r
-               reset_idle = 0;\r
-               for (i=0; i<8; i++) {\r
-                       if (((b & mask) == 0) && (b_prev & mask) != 0) {\r
-                               usb_keyboard_press(KEY_B, KEY_SHIFT);\r
-                               usb_keyboard_press(number_keys[i], 0);\r
-                               print("Port B, bit ");\r
-                               phex(i);\r
-                               print("\n");\r
-                               reset_idle = 1;\r
-                       }\r
-                       if (((d & mask) == 0) && (d_prev & mask) != 0) {\r
-                               usb_keyboard_press(KEY_D, KEY_SHIFT);\r
-                               usb_keyboard_press(number_keys[i], 0);\r
-                               print("Port D, bit ");\r
-                               phex(i);\r
-                               print("\n");\r
-                               reset_idle = 1;\r
-                       }\r
-                       mask = mask << 1;\r
-               }\r
-               // if any keypresses were detected, reset the idle counter\r
-               if (reset_idle) {\r
-                       // variables shared with interrupt routines must be\r
-                       // accessed carefully so the interrupt routine doesn't\r
-                       // try to use the variable in the middle of our access\r
-                       cli();\r
-                       idle_count = 0;\r
-                       sei();\r
-               }\r
-               // now the current pins will be the previous, and\r
-               // wait a short delay so we're not highly sensitive\r
-               // to mechanical "bounce".\r
-               b_prev = b;\r
-               d_prev = d;\r
-               _delay_ms(2);\r
-       }\r
-}\r
-*/\r
-\r
+/* 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");
+}
+
diff --git a/Scan/avr-capsense/scan_loop.h b/Scan/avr-capsense/scan_loop.h
new file mode 100644 (file)
index 0000000..465cf57
--- /dev/null
@@ -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
+
old mode 100755 (executable)
new mode 100644 (file)
index bf516c2..ca7c719
@@ -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
 #
 # 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
 )
 
 
index 84e71a770fba699ecc76b3348bd7b8512e22bd28..c754f920869e1e8caf8a036a9f318bf869c2275f 100644 (file)
@@ -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"  )