]> git.donarmstrong.com Git - kiibohd-controller.git/commitdiff
rsync'd over the changes
authorJo Makuch <jmakuch@kvack.org>
Wed, 10 Apr 2013 18:06:10 +0000 (14:06 -0400)
committerJacob Alexander <haata@users.sf.net>
Sun, 17 Nov 2013 00:37:16 +0000 (19:37 -0500)
Scan/avr-capsense/scan_loop.c [new file with mode: 0755]
Scan/avr-capsense/setup.cmake [new file with mode: 0755]
cmake_install.cmake [new file with mode: 0755]
winbuild.sh [new file with mode: 0755]

diff --git a/Scan/avr-capsense/scan_loop.c b/Scan/avr-capsense/scan_loop.c
new file mode 100755 (executable)
index 0000000..7ce472e
--- /dev/null
@@ -0,0 +1,1391 @@
+/* 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
diff --git a/Scan/avr-capsense/setup.cmake b/Scan/avr-capsense/setup.cmake
new file mode 100755 (executable)
index 0000000..bf516c2
--- /dev/null
@@ -0,0 +1,43 @@
+###| CMake Kiibohd Controller Scan Module |###
+#
+# Written by Jacob Alexander in 2011 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
+)
+
+
+###
+# 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
+)
+
+
+###
+# Compiler Family Compatibility
+#
+set( ScanModuleCompatibility
+       avr
+)
+
diff --git a/cmake_install.cmake b/cmake_install.cmake
new file mode 100755 (executable)
index 0000000..433b8f1
--- /dev/null
@@ -0,0 +1,39 @@
+# Install script for directory: L:/haata/kiibohd\r
+\r
+# Set the install prefix\r
+IF(NOT DEFINED CMAKE_INSTALL_PREFIX)\r
+  SET(CMAKE_INSTALL_PREFIX "C:/Program Files (x86)/kiibohd_controller")\r
+ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX)\r
+STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")\r
+\r
+# Set the install configuration name.\r
+IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)\r
+  IF(BUILD_TYPE)\r
+    STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" ""\r
+           CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")\r
+  ELSE(BUILD_TYPE)\r
+    SET(CMAKE_INSTALL_CONFIG_NAME "")\r
+  ENDIF(BUILD_TYPE)\r
+  MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")\r
+ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)\r
+\r
+# Set the component getting installed.\r
+IF(NOT CMAKE_INSTALL_COMPONENT)\r
+  IF(COMPONENT)\r
+    MESSAGE(STATUS "Install component: \"${COMPONENT}\"")\r
+    SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}")\r
+  ELSE(COMPONENT)\r
+    SET(CMAKE_INSTALL_COMPONENT)\r
+  ENDIF(COMPONENT)\r
+ENDIF(NOT CMAKE_INSTALL_COMPONENT)\r
+\r
+IF(CMAKE_INSTALL_COMPONENT)\r
+  SET(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")\r
+ELSE(CMAKE_INSTALL_COMPONENT)\r
+  SET(CMAKE_INSTALL_MANIFEST "install_manifest.txt")\r
+ENDIF(CMAKE_INSTALL_COMPONENT)\r
+\r
+FILE(WRITE "L:/haata/kiibohd/${CMAKE_INSTALL_MANIFEST}" "")\r
+FOREACH(file ${CMAKE_INSTALL_MANIFEST_FILES})\r
+  FILE(APPEND "L:/haata/kiibohd/${CMAKE_INSTALL_MANIFEST}" "${file}\n")\r
+ENDFOREACH(file)\r
diff --git a/winbuild.sh b/winbuild.sh
new file mode 100755 (executable)
index 0000000..d2d260c
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+#temp jo
+#export PATH="/c/WinAVR-20100110/bin:/c/Program Files (x86)/CMake 2.8/bin:${PATH}"
+#echo $PATH
+export PATH="/c/WinAVR-20100110/bin:/c/Program Files (x86)/CMake 2.8/bin:/usr/local/bin:/usr/bin:/bin:/c/Windows/system32"
+echo $PATH
+
+
+which cmake.exe
+which -a cmake.exe
+which avr-gcc
+which make
+#alias cmake="cmake.exe"
+#alias make="avr-nm"
+
+#cd build
+cmake -G "Unix Makefiles" -D \
+CMAKE_C_COMPILER="C:/WinAVR-20100110/bin/avr-gcc.exe" \
+-D CMAKE_CXX_COMPILER="C:/WinAVR-20100110/bin/avr-g++.exe" .
+#cd ..
+make
+#nm
+
+#./buildall.bash