--- /dev/null
+/* 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