# HG changeset patch # User Jo Makuch # Date 1365617170 14400 # Node ID 62069d39b09d1a0993c7bc99f8813ad27bd27230 # Parent 4c267d3734eb3d45d0418fba10756a4bde431fcd rsync'd over the changes diff -r 4c267d3734eb -r 62069d39b09d Scan/avr-capsense/scan_loop.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Scan/avr-capsense/scan_loop.c Wed Apr 10 14:06:10 2013 -0400 @@ -0,0 +1,1391 @@ +/* Keyboard example with debug channel, for Teensy USB Development Board + * http://www.pjrc.com/teensy/usb_keyboard.html + * Copyright (c) 2008 PJRC.COM, LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include +#include +#include "usb_keyboard_debug.h" +#include "print.h" + +#define LED_CONFIG (DDRD |= (1<<6)) +#define LED_ON (PORTD &= ~(1<<6)) +#define LED_OFF (PORTD |= (1<<6)) +#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) + +#define THRESHOLD 0x0a +#define BUMP_THRESHOLD 0x50 +//((THRESHOLD) * 3) +#define BUMP_REST_US 1200 + +#define HYST 1 +#define HYST_T 0x10 + +#define TEST_KEY_STROBE (0x05) +#define TEST_KEY_MASK (1 << 0) + +#define ADHSM 7 + +/** Whether to use all of D and C, vs using E0, E1 instead of D6, D7, + * or alternately all of D, and E0,E1 and C0,..5 */ +//#define ALL_D_C +//#define SHORT_D +#define SHORT_C + +// rough offset voltage: one diode drop, about 50mV = 0x3ff * 50/3560 = 20 +//#define OFFSET_VOLTAGE 0x14 +#define OFFSET_VOLTAGE 0x28 + +volatile uint8_t idle_count=1; + +uint8_t blink=0; + +volatile uint16_t full_av = 0; + +#define RIGHT_JUSTIFY 0 +#define LEFT_JUSTIFY (0xff) + +// set left or right justification here: +#define JUSTIFY_ADC RIGHT_JUSTIFY + +#define ADLAR_MASK (1 << ADLAR) +#ifdef JUSTIFY_ADC +#define ADLAR_BITS ((ADLAR_MASK) & (JUSTIFY_ADC)) +#else // defaults to right justification. +#define ADLAR_BITS 0 +#endif + + +// full muxmask +#define FULL_MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2) | (1 << MUX3) | (1 << MUX4)) + +// F0-f7 pins only muxmask. +#define MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2)) + +#define SET_MUX(X) ((ADMUX) = (((ADMUX) & ~(MUX_MASK)) | ((X) & (MUX_MASK)))) +#define SET_FULL_MUX(X) ((ADMUX) = (((ADMUX) & ~(FULL_MUX_MASK)) | ((X) & (FULL_MUX_MASK)))) + +#define MUX_1_1 0x1e +#define MUX_GND 0x1f + + + // set ADC clock prescale +#define PRESCALE_MASK ((1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2)) +#define PRESCALE_SHIFT (ADPS0) +#define PRESCALE 3 + + +/**/ uint8_t ze_strober = 0; + +#ifdef EXTENDED_STROBE + +#define STROBE_LINES 18 + +#else + +#define STROBE_LINES 16 + +#endif + +#define STROBE_LINES_XSHIFT 4 +#define STROBE_LINES_MASK 0x0f +#define MUXES_COUNT 8 +#define MUXES_COUNT_XSHIFT 3 +#define MUXES_MASK 0x7 + +#define WARMUP_LOOPS ( 1024 ) + +#define RECOVERY_US 6 + +#define SAMPLES 10 +int16_t samples [SAMPLES]; + +//int16_t gsamples [SAMPLES]; + +#define SAMPLE_OFFSET ((SAMPLES) - MUXES_COUNT) +//#define SAMPLE_OFFSET 9 +#define STROBE_OFFSET 0 + +/**/ int16_t adc_mux_averages[MUXES_COUNT]; +/**/ int16_t adc_strobe_averages[STROBE_LINES]; + + +/**/ uint8_t cur_keymap[STROBE_LINES]; +// /**/ int8_t last_keymap[STROBE_LINES]; +/**/ uint8_t usb_keymap[STROBE_LINES]; +uint8_t dirty; +uint8_t unstable; +uint8_t usb_dirty; + +int16_t threshold = THRESHOLD; +uint16_t tests = 0; + +uint8_t col_a=0; +uint8_t col_b=0; +uint8_t col_c=0; + +uint8_t column=0; + +#define KEY_COUNT ((STROBE_LINES) * (MUXES_COUNT)) + +int16_t keys_averages_acc[KEY_COUNT]; +uint16_t keys_averages[KEY_COUNT]; + +uint8_t full_samples[KEY_COUNT]; + +/* viable starting biases for near 0.830V offset. and adc PRESCALE 3 +0017 0016 001B 001A 0016 0016 000F 000E 001B 001E 001E 0018 0017 0015 000E 001D +001B 001A 0016 0016 000F 000E 001C 001B 001E 0018 0017 0015 000E 001D 0024 001F +0016 0016 000F 000E 001C 001B 001E 001E 0017 0015 000E 001D 0024 001F 0020 001F +000F 000E 001C 001B 001E 001E 0018 0017 000E 001D 0024 001F 0020 001F 0020 0017 +001C 001B 001E 001E 0018 0017 0015 000E 0024 001F 0020 001F 0020 0017 0010 001D +001E 001E 0018 0017 0015 000E 001D 0024 0020 001F 0020 0017 0010 001D 0024 0021 +0018 0017 0015 000E 001D 0024 001F 0020 0020 0017 0010 001D 0024 0021 0021 0021 +0015 000E 001D 0024 001F 0020 001F 0020 0010 001D 0024 0021 0021 0021 0021 0018 +*/ + +/*** starting bias relative to fixed offset estimate of 820mV (0x50) + * 77 69 65 5B 50 4E 4C 45 66 53 4D 49 45 3F 3E 35 + * 68 54 4F 49 45 40 3F 34 74 66 5F 56 4E 4D 4C 3F + * 6D 5D 53 4C 49 46 45 38 6D 5A 53 4E 49 48 45 3E + * 6F 5D 56 4E 4B 48 48 3A 6D 5C 54 4E 48 48 45 37 + * 75 68 5F 57 4F 4D 4C 3F 60 4E 48 41 3C 3C 39 2F + * 65 53 4E 49 41 3F 3E 34 65 54 4E 49 43 3F 3E 34 + * 60 51 4A 45 3F 3E 3C 30 57 4C 45 3E 3B 37 37 2E + * 64 4E 48 44 3C 3B 39 2F 5D 4F 48 45 3E 3C 3B 30 + */ + +/*volatile*/ uint16_t count = 0; + + + +/*volatile*/ uint8_t error = 0; +uint16_t error_data = 0; + +void dump(void); +void dumpkeys(void); + +static const uint8_t PROGMEM matrix122F_to_set3[] = { +0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x84, // (), npenter, np3, (), np+, np9, np*, np- +0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, // np0, np., np2, np5, np6, np8, numlck, np/ +0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, // +0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, +0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, +0x00, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, // 0x50 vanishes - is test key. +0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, // 0x48 vanishes - else roll back. +0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, +0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, +0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, +0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, +0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, +0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, +0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, +0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, +0x01, 0x83, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 0x02 is replaced with 0x83. +}; + +#define LX2FX + +static const uint8_t PROGMEM page3_2_USB[133] = { +0x0, // 00 00 // no key. + +#ifndef LX2FX + +0xe3, // 01 Enl Help -> windows. (e3) +0x0, // 02 // no key. +0x80, // 03 A4 ExSel SetUp print, -> paste 7d -> vol up 80 +0x46, // 04 A3 CrSel Properties -> copy 7c -> mute 7f-> prt-scrn +0x29, // 05 9A Attn SysRq // good place fer escape. (29) +0x47, // 06 9C Clear -> kp / 54 -> scroll-lock (47) +0x3a, // 07 3A F1 +0x68, // 08 68 F13 +0x65, // 09 Ctrl // record/pause // -> kb application (65) +0x74, // 0A Copy Test // play/test -> execute 74 -> kp + 57 +0x75, // 0B // no key. help (75) -> kp - 56 +0x48, // 0C Pause ErInp erase input. -> cut 7b -> kp * 55 -> pause 48 + +#else + +/* +0x42, // 01 L9 +0x0, // 02 // no key. +0x3e, // 03 L5 +0x3c, // 04 L3 +0x3a, // 05 L1 +0x3b, // 06 L2 +0x3a, // 07 3A F1 +0x68, // 08 68 F13 +0x43, // 09 L10 +0x41, // 0A L8 +0x3f, // 0B L6 +0x3d, // 0C L4 +*/ +0x61, // 01 L9 -> num 9 0x61 +0x0, // 02 // no key. +0x5d, // 03 L5 -> num 5 0x5d +0x5b, // 04 L3 -> num 3 0x5b +0x59, // 05 L1 -> num 1 0x59 +0x5a, // 06 L2 -> num 2 0x5a +0x3a, // 07 3A F1 +0x68, // 08 68 F13 +0x62, // 09 L10 -> num 0 0x62 +0x60, // 0A L8 -> num 8 0x60 +0x5e, // 0B L6 -> num 6 0x5e +0x5c, // 0C L4 -> num 4 0x5c +#endif + + +0x2b, // 0D 2B Tab +0x29, // 0E 35 ~ ` -> escape 29 +0x3b, // 0F 3B F2 +0x69, // 10 69 F14 +0xe0, // 11 E0 Ctrl L +0xe1, // 12 E1 Shift L +0xe1, // 13 64 left of z. -> l shift e1 +0x39, // 14 39 Caps Lock +0x14, // 15 14 Q +0x1e, // 16 1E ! 1 +0x3c, // 17 3C F3 +0x6a, // 18 6A F15 +0xe2, // 19 E2 Alt L +0x1d, // 1A 1D Z +0x16, // 1B 16 S +0x04, // 1C 04 A +0x1a, // 1D 1A W +0x1f, // 1E 1F @ 2 +0x3d, // 1F 3D F4 +0x6b, // 20 6B F16 +0x06, // 21 06 C +0x1b, // 22 1B X +0x07, // 23 07 D +0x08, // 24 08 E +0x21, // 25 21 $ 4 +0x20, // 26 20 # 3 +0x3e, // 27 3E F5 +0x6c, // 28 6C F17 +0x2c, // 29 2C Space +0x19, // 2A 19 V +0x09, // 2B 09 F +0x17, // 2C 17 T +0x15, // 2D 15 R +0x22, // 2E 22 % 5 +0x3f, // 2F 3F F6 +0x6d, // 30 6D F18 +0x11, // 31 11 N +0x05, // 32 05 B +0x0b, // 33 0B H +0x0a, // 34 0A G +0x1c, // 35 1C Y +0x23, // 36 23 ^ 6 +0x40, // 37 40 F7 +0x6e, // 38 6E F19 +0xe6, // 39 E6 Alt R +0x10, // 3A 10 M +0x0d, // 3B 0D J +0x18, // 3C 18 U +0x24, // 3D 24 & 7 +0x25, // 3E 25 * 8 +0x41, // 3F 41 F8 +0x6f, // 40 6F F20 +0x36, // 41 36 < , +0x0e, // 42 0E K +0x0c, // 43 0C I +0x12, // 44 12 O +0x27, // 45 27 ) 0 +0x26, // 46 26 ( 9 +0x42, // 47 42 F9 +0x70, // 48 70 F21 +0x37, // 49 37 > . +0x38, // 4A 38 ? / +0x0f, // 4B 0F L +0x33, // 4C 33 : ; +0x13, // 4D 13 P +0x2d, // 4E 2D _ - +0x43, // 4F 43 F10 +0x71, // 50 71 F22 +0xe5, // 51 87 likely a shift - e.g. kp shift -> e5 +0x34, // 52 34 " ' +0x31, // 53 (INT 2) -> keypad enter. 58 -> |/\ (31) +0x2f, // 54 2F { [ +0x2e, // 55 2E + = +0x44, // 56 44 F11 +0x72, // 57 72 F23 -> vol up. +0xe4, // 58 E4 Ctrl R +0xe5, // 59 E5 Shift R +0x28, // 5A 28 Enter +0x30, // 5B 30 } ] +0x31, // 5C 31 | '\' +0x35, // 5D -> kp = 67 -> ~` 35 +0x45, // 5E 45 F12 +0x73, // 5F 73 F24 -> vol down. +0x51, // 60 51 Down CP +0x50, // 61 50 Left CP +0x51, //0x0,// 62 Rule // centre cp. //62 48 Pause/Bk +0x52, // 63 52 Up CP +0x4c, // 64 4C Del CP +0x4d, // 65 4D End CP +0x2a, // 66 2A Back Space +0x49, // 67 49 Ins CP +0x48, // 68 // under kp0 => kp 0 (62) 48 -> pause (48) +0x59, // 69 59 1 End KP +0x4f, // 6A 4F Right CP +0x5c, // 6B 5C 4 Left KP +0x5f, // 6C 5F 7 Home KP +0x4e, // 6D 4E PgDn CP +0x4a, // 6E 4A Home CP +0x4b, // 6F 4B PgUp CP +0x62, // 70 62 0 Ins KP -> pause (+48) -> kp-0 (62) +0x63, // 71 63 . Del KP +0x5a, // 72 5A 2 Down KP +0x5d, // 73 97 5 KP +0x5e, // 74 5E 6 Right KP +0x60, // 75 60 8 Up KP +0x53, // 76 53 Num Lock +0x54, // 77 54 / KP +0x47, // 78 Undo // under enter -> scroll-lock 47 +0x58, // 79 58 Enter KP -> enter kp +0x5b, // 7A 5B 3 PgDn KP +0x46, // 7B (INT 5) // under + -> print screen (46 +0x57, // 7C 57 + KP +0x61, // 7D 61 9 PgUp KP +0x55, // 7E 55 * KP +0x0, // 7F no such key? +0x0, // 80 no such key +0x0, // 81 Paste? +0x0, // 82 Find? +#ifndef LX2FX +0x81, // 83 Print Ident -> undo 7a -> vol down 81 +#else +//0x40, // 83 L7 (f1) 3a +0x5f, // 83 L7 (f1) 3a -> num 7 0x5f +#endif +0x56 // 84 56 - KP +}; + +void +_delay_loop(uint8_t __count) +{ + __asm__ volatile ( + "1: dec %0" "\n\t" + "brne 1b" + : "=r" (__count) + : "0" (__count) + ); +} + + +void setup_ADC (void) { + // disable adc digital pins. + DIDR1 |= (1 << AIN0D) | (1< BUMP_THRESHOLD + delta) { + // ze horror. + return 1; + } else { + return 0; //all good. + }*/ + return 0; + +} + +int sampleColumn_k(uint8_t column, int16_t * buffer) { + // ensure all probe lines are driven low, and chill for recovery delay. + uint16_t sample; + + ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions + ADCSRA |= (1 << ADIF); // clear int flag by writing 1. + + // sync up with adc clock: + while (! (ADCSRA & (1 << ADIF))); // wait until ready. + sample = ADC; // throw it away. + + for(uint8_t mux=0; mux < 8; ++mux) { + + PORTC &= ~C_MASK; + PORTD &= ~D_MASK; + PORTE &= ~E_MASK; + + SET_FULL_MUX(mux); // our sample will use this + + for(uint8_t i=0; i < 2; ++i) { + ADCSRA |= (1 << ADIF); // clear int flag by writing 1. + //wait for last read to complete. + while (! (ADCSRA & (1 << ADIF))); + sample = ADC; // throw away strobe'd value. + } + + recovery(0); + strobe_w(column); + + ADCSRA |= (1 << ADIF); // clear int flag by writing 1. + //wait for last read to complete. + while (! (ADCSRA & (1 << ADIF))); + sample = ADC; // throw away strobe'd value. + + ADCSRA |= (1 << ADIF); // clear int flag by writing 1. + while (! (ADCSRA & (1 << ADIF))); + + // retrieve current read. + buffer[mux] = ADC - OFFSET_VOLTAGE; + recovery(1); + + } + + // turn off adc. + ADCSRA &= ~(1 << ADEN); + + // pull all columns' probe-lines low. + PORTC &= ~C_MASK; + PORTD &= ~D_MASK; + PORTE &= ~E_MASK; +// recovery(1); + + + return 0; +} + +int sampleColumn(uint8_t column) { + int rval = 0; + + /* + sampleColumn_i(column, 0x0f, samples+SAMPLE_OFFSET); + sampleColumn_i(column, 0xf0, samples+SAMPLE_OFFSET + 4 ); +*/ + + rval = sampleColumn_k(column, samples+SAMPLE_OFFSET); + + for(uint8_t i=0; i<8; ++i) { + if(samples[SAMPLE_OFFSET + i] - adc_mux_averages[i] > BUMP_THRESHOLD) { + // was a hump + + _delay_us(BUMP_REST_US); + rval++; + error = 0x50; + error_data = samples[SAMPLE_OFFSET +i]; // | ((uint16_t)i << 8); + return rval; + } + } + + return rval; +} + + + +uint8_t testColumn(uint8_t strobe) { + uint8_t column = 0; + uint8_t bit = 1; + for (uint8_t i=0; i < MUXES_COUNT; ++i) { + uint16_t delta = keys_averages[(strobe << MUXES_COUNT_XSHIFT) + i]; + if ((int16_t)samples[SAMPLE_OFFSET + i] > threshold + delta) { + column |= bit; + } + bit <<= 1; + } + return column; +} + +int main(void) { + // set for 16 MHz clock + CPU_PRESCALE(0); + + // Initialize the USB, and then wait for the host to set configuration. + // If the Teensy is powered without a PC connected to the USB port, + // this will wait forever. + usb_init(); + while (!usb_configured()) /* wait */ ; + + // Wait an extra second for the PC's operating system to load drivers + // and do whatever it does to actually be ready for input + _delay_ms(1000); + + LED_CONFIG; + + setup_ADC(); + + // Configure timer 0 to generate a timer overflow interrupt every + // 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock + // This demonstrates how to use interrupts to implement a simple + // inactivity timeout. + //TCCR0A = 0x00; + //TCCR0B = 0x05; + //TIMSK0 = (1<= 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> 3; + adc_strobe_averages[strober] >>= 1; + + /** test if we went negative. */ + if ((adc_strobe_averages[strober] & 0xFF00) && (count + >= WARMUP_LOOPS)) { + //count = 0; // TODO : constrain properly. + error = 0xf; error_data = adc_strobe_averages[strober]; + } + + uint8_t strobe_line = strober << MUXES_COUNT_XSHIFT; + for (int i = 0; i < MUXES_COUNT; ++i) { + keys_averages_acc[strobe_line + i] + += samples[SAMPLE_OFFSET + i]; + } + + } // for strober + + if (count < WARMUP_LOOPS) { + error = 0x0C; + error_data = count; + count++; + } + + // verify test key is not down. + if((cur_keymap[TEST_KEY_STROBE] & TEST_KEY_MASK) ) { + //count=0; + error = 0x05; + error_data = cur_keymap[TEST_KEY_STROBE] << 8; + error_data += full_samples[TEST_KEY_STROBE * 8]; + //threshold++; + } + + // calc mux averages. + if (count < WARMUP_LOOPS) { + full_av += (full_av_acc >> (7)); + full_av >>= 1; + //full_av = full_av_acc / count; + full_av_acc = 0; + for (int i=0; i < MUXES_COUNT; ++i) { + +// mix in 1/4 of the current average to the running average. -> (@mux_mix = 2) +#define MUX_MIX 2 + + adc_mux_averages[i] = (adc_mux_averages[i] << MUX_MIX) - adc_mux_averages[i]; + adc_mux_averages[i] += (mux_averages[i] >> 4); + adc_mux_averages[i] >>= MUX_MIX; + + mux_averages[i] = 0; + } + + } + +#define IDLE_COUNT_MASK 0xff +#define MAX_ICS 8 + +#define IDLE_COUNT_SHIFT 4 +#define KEYS_AVERAGES_MIX 2 + + idle_count++; + idle_count &= IDLE_COUNT_MASK; + + if (/*usb_dirty &&*/ (count >= WARMUP_LOOPS) ) { + for (int i=0; i>= 2; + + keys_averages[i] = av; + keys_averages_acc[i] = 0; + } + } + + + if(!idle_count) { + + for (int i=0; i< KEY_COUNT; ++i) { + keys_averages_acc[i] = 0; + } + + sampleColumn(0x0); // to resync us if we dumped a mess 'o text. + } + } +} + + +void debug_println() { + usb_debug_putchar('\r'); + usb_debug_putchar('\n'); +} + + +// This interrupt routine is run approx 61 times per second. +// A very simple inactivity timeout is implemented, where we +// will send a space character and print a message to the +// hid_listen debug message window. +ISR(TIMER0_OVF_vect) { + //idle_count++; + /* + if (idle_count > 61) { + idle_count = 0; + }*/ + +} + +void dumpkeys(void) { + //print(" \n"); + if(error) { + for (uint8_t i=0; i < STROBE_LINES; ++i) { + phex(usb_keymap[i]); + usb_debug_putchar(' '); + + //print(" "); + } + if (count >= WARMUP_LOOPS && error) { + dump(); + } + + print(" : "); + phex(error); + error = 0; + print(" : "); + phex16(error_data); + error_data = 0; + print(" : "); + debug_println(); + } + + + for(uint8_t i = 0; i < 6; ++i) { + keyboard_keys[i] = 0; + } + keyboard_modifier_keys = 0; + uint8_t usbkeycount = 0; + for (uint8_t i=0; i < STROBE_LINES; ++i) { + for(uint8_t j=0; j= 0xe0) && (usbkey <= 0xe7)) { // metas + keyboard_modifier_keys |= (1 << (usbkey & 0x07)); + } else { + keyboard_keys[usbkeycount++] = usbkey; + } + } + if (usb_dirty) usb_debug_putchar(' '); + } + } + } + if(usb_dirty) { + debug_println(); + } + + /** shall we send actual keyboard events? */ +#if 0 + usb_keyboard_send(); +#endif + +} + +// taken from the datasheet. +uint8_t readEE(uint16_t offset) { + /* Wait for completion of previous write */ + while(EECR & (1<1ms/byte. +void writeEE(uint16_t offset, uint8_t data) { + /* Wait for completion of previous write */ + while(EECR & (1<> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]); + phex (keys_averages[i]); + } + + print("\n"); + + for(int i =0; i< KEY_COUNT; ++i) { + if(!(i & 0x0f)) { + print("\n"); + } else if (!(i & 0x07)) { + print(" "); + } + usb_debug_putchar(' '); + //phex16 (keys_averages[(i >> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]); + //phex16 (keys_averages_acc[i]); + phex(full_samples[i]); + } + } + + + //} + +// uint8_t cur_strober = 0xe; + uint8_t cur_strober = ze_strober; + print("\n"); + + phex(cur_strober); + //print(": "); + print(": "); +#if 1 + print("\n"); + for (uint8_t i=0; i < MUXES_COUNT; ++i) { + usb_debug_putchar(' '); + phex16(full_samples[(cur_strober << MUXES_COUNT_XSHIFT) + i]); + } + + print("\n"); +// phex(threshold); +// print(": "); + + for (uint8_t i=0; i < MUXES_COUNT; ++i) { + usb_debug_putchar(' '); + phex16(keys_averages[(cur_strober << MUXES_COUNT_XSHIFT) + i]); + } + +#endif + /* + for (uint8_t i=0; i< SAMPLES; ++i) { + print(" "); + phex16(samples[i]); + //phex16(ADC); + }*/ + //print(" : "); + //usb_debug_putchar((was_active)?' ':'*'); + + //phex16(keymap[TEST_KEY_STROBE] & TEST_KEY_MASK); + /*print(" "); */ + //phex(keymap[TEST_KEY_STROBE]); + + + //print("\n"); + //print(":"); + //phex(full_av); + //phex16(count); + //print(" : "); + print("\n"); + + for (uint8_t i=0; i < STROBE_LINES; ++i) { + phex(cur_keymap[i]); + usb_debug_putchar(' '); + + //print(" "); + } + + + //print(": "); + //phex(adc_strobe_averages[ze_strober]); + //usb_debug_putchar(' '); + + + + for (uint8_t i=0; i < MUXES_COUNT; ++i) { + usb_debug_putchar(' '); + //phex16(adc_mux_averages[i] + adc_strobe_averages[ze_strober] - full_av); + //phex16((adc_mux_averages[i] + adc_strobe_averages[ze_strober]) >> 1); + //phex16((adc_mux_averages[i] * 3 + adc_strobe_averages[ze_strober]) >> 2); + //phex16(adc_mux_averages[i] + threshold); + //phex16(gsamples[i + SAMPLE_OFFSET] - (adc_mux_averages[i] + threshold) + 0x100); + //phex16(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i] + (uint8_t)threshold); + phex16(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i]); + } + + if(error) { + usb_debug_putchar(' '); + phex (error); + usb_debug_putchar(' '); + phex16(error_data); + error = 0; + error_data = 0; + } + //print("\n"); + + ze_strober++; + ze_strober &= 0xf; + + + dump_count++; + dump_count &= 0x0f; + + + + //ze_strobe = (1 << (ze_strober ) ); + + + + //phex(ADCSRA); + //print(" "); + //print("\n"); + //usb_keyboard_press(KEY_SPACE, 0); + +// if(blink) { +// LED_ON; +// } else { +// LED_OFF; +// } +// blink ^= 1; +} + + +/* +int oldmain(void) { + uint8_t b, d, mask, i, reset_idle; + uint8_t b_prev=0xFF, d_prev=0xFF; + + // set for 16 MHz clock + CPU_PRESCALE(0); + + // Configure all port B and port D pins as inputs with pullup resistors. + // See the "Using I/O Pins" page for details. + // http://www.pjrc.com/teensy/pins.html + DDRD = 0x00; + DDRB = 0x00; + PORTB = 0xFF; + PORTD = 0xFF; + + // Initialize the USB, and then wait for the host to set configuration. + // If the Teensy is powered without a PC connected to the USB port, + // this will wait forever. + usb_init(); + while (!usb_configured()) ; + + // Wait an extra second for the PC's operating system to load drivers + // and do whatever it does to actually be ready for input + _delay_ms(1000); + + // Configure timer 0 to generate a timer overflow interrupt every + // 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock + // This demonstrates how to use interrupts to implement a simple + // inactivity timeout. + TCCR0A = 0x00; + TCCR0B = 0x05; + TIMSK0 = (1<