]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/avr-capsense/scan_loop.c
3d80c76492302545550c58a66525e80e3b71d5b4
[kiibohd-controller.git] / Scan / avr-capsense / scan_loop.c
1 /* Copyright (C) 2011-2013 by Joseph Makuch
2  * Additions by Jacob Alexander (2013)
3  *
4  * dfj, put whatever license here you want -HaaTa
5  */
6
7 // ----- Includes -----
8
9 // Compiler Includes
10 #include <Lib/ScanLib.h>
11
12 // Project Includes
13 #include <led.h>
14 #include <print.h>
15
16 // Local Includes
17 #include "scan_loop.h"
18
19
20
21 // ----- Defines -----
22
23 // TODO dfj defines...needs cleaning up and commenting...
24 #define THRESHOLD 0x0a
25 #define BUMP_THRESHOLD 0x50
26 //((THRESHOLD) * 3)
27 #define BUMP_REST_US 1200
28
29 #define HYST 1
30 #define HYST_T 0x10
31
32 #define TEST_KEY_STROBE (0x05)
33 #define TEST_KEY_MASK (1 << 0)
34
35 #define ADHSM 7
36
37 /** Whether to use all of D and C, vs using E0, E1 instead of D6, D7,
38  * or alternately all of D, and E0,E1 and C0,..5 */
39 //#define ALL_D_C
40 //#define SHORT_D
41 #define SHORT_C
42
43 // rough offset voltage: one diode drop, about 50mV = 0x3ff * 50/3560 = 20
44 //#define OFFSET_VOLTAGE 0x14
45 #define OFFSET_VOLTAGE 0x28
46
47
48 #define RIGHT_JUSTIFY 0
49 #define LEFT_JUSTIFY (0xff)
50
51 // set left or right justification here:
52 #define JUSTIFY_ADC RIGHT_JUSTIFY
53
54 #define ADLAR_MASK (1 << ADLAR)
55 #ifdef JUSTIFY_ADC
56 #define ADLAR_BITS ((ADLAR_MASK) & (JUSTIFY_ADC))
57 #else // defaults to right justification.
58 #define ADLAR_BITS 0
59 #endif
60
61
62 // full muxmask
63 #define FULL_MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2) | (1 << MUX3) | (1 << MUX4))
64
65 // F0-f7 pins only muxmask.
66 #define MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2))
67
68 #define MUX_1_1 0x1e
69 #define MUX_GND 0x1f
70
71
72         // set ADC clock prescale
73 #define PRESCALE_MASK ((1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2))
74 #define PRESCALE_SHIFT (ADPS0)
75 #define PRESCALE 3
76
77
78 #ifdef EXTENDED_STROBE
79
80 #define STROBE_LINES 18
81
82 #else
83
84 #define STROBE_LINES 16
85
86 #endif
87
88 #define STROBE_LINES_XSHIFT 4
89 #define STROBE_LINES_MASK 0x0f
90 #define MUXES_COUNT 8
91 #define MUXES_COUNT_XSHIFT 3
92 #define MUXES_MASK 0x7
93
94 #define WARMUP_LOOPS ( 1024 )
95
96 #define RECOVERY_US 6
97
98 #define SAMPLES 10
99
100
101 #define SAMPLE_OFFSET ((SAMPLES) - MUXES_COUNT)
102 //#define SAMPLE_OFFSET 9
103 #define STROBE_OFFSET 0
104
105
106 #define KEY_COUNT ((STROBE_LINES) * (MUXES_COUNT))
107
108 #define LX2FX
109
110
111 #define RECOVERY_CONTROL 1
112
113 #define RECOVERY_SOURCE 0
114 #define RECOVERY_SINK 2
115 #define RECOVERY_MASK 0x03
116
117
118 // mix in 1/4 of the current average to the running average. -> (@mux_mix = 2)
119 #define MUX_MIX 2
120
121
122 #define IDLE_COUNT_MASK 0xff
123 #define MAX_ICS 8
124
125 #define IDLE_COUNT_SHIFT 4
126 #define KEYS_AVERAGES_MIX 2
127
128
129 #ifdef ALL_D_C
130
131 #define D_MASK (0xff)
132 #define D_SHIFT 0
133
134 #define E_MASK (0x00)
135 #define E_SHIFT 0
136
137 #define C_MASK (0xff)
138 #define C_SHIFT 8
139
140 #else
141 #if defined(SHORT_D)
142
143 #define D_MASK (0x3f)
144 #define D_SHIFT 0
145
146 #define E_MASK (0x03)
147 #define E_SHIFT 6
148
149 #define C_MASK (0xff)
150 #define C_SHIFT 8
151
152 #else
153 #if defined(SHORT_C)
154
155 #define D_MASK (0xff)
156 #define D_SHIFT 0
157
158 #define E_MASK (0x03)
159 #define E_SHIFT 6
160
161 #define C_MASK (0xff)
162 #define C_SHIFT 8
163 #endif
164 #endif
165 #endif
166
167
168
169
170
171 // ----- Macros -----
172
173 // Make sure we haven't overflowed the buffer
174 #define bufferAdd(byte) \
175                 if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
176                         KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte
177
178
179 // TODO dfj macros...needs cleaning up and commenting...
180 #define STROBE_CASE(SC_CASE, SC_REG_A) case (SC_CASE): PORT##SC_REG_A = \
181         (( (PORT##SC_REG_A) & ~(1 << (SC_CASE - SC_REG_A##_SHIFT)) ) | (1 << (SC_CASE - SC_REG_A##_SHIFT)))
182
183 #define SET_MUX(X) ((ADMUX) = (((ADMUX) & ~(MUX_MASK)) | ((X) & (MUX_MASK))))
184 #define SET_FULL_MUX(X) ((ADMUX) = (((ADMUX) & ~(FULL_MUX_MASK)) | ((X) & (FULL_MUX_MASK))))
185
186
187
188
189
190 // ----- Variables -----
191
192 // Buffer used to inform the macro processing module which keys have been detected as pressed
193 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
194 volatile uint8_t KeyIndex_BufferUsed;
195
196
197 // TODO dfj variables...needs cleaning up and commenting
198          uint8_t  blink = 0;
199 volatile uint8_t  idle_count = 1;
200 volatile uint16_t full_av = 0;
201
202 /**/ uint8_t ze_strober = 0;
203
204 int16_t samples [SAMPLES];
205
206 //int16_t gsamples [SAMPLES];
207
208 /**/ int16_t adc_mux_averages[MUXES_COUNT];
209 /**/ int16_t adc_strobe_averages[STROBE_LINES];
210
211
212 /**/ uint8_t cur_keymap[STROBE_LINES];
213 // /**/ int8_t last_keymap[STROBE_LINES];
214 /**/ uint8_t usb_keymap[STROBE_LINES];
215 uint8_t dirty;
216 uint8_t unstable;
217 uint8_t usb_dirty;
218
219 int16_t threshold = THRESHOLD;
220 uint16_t tests = 0;
221
222 uint8_t col_a=0;
223 uint8_t col_b=0;
224 uint8_t col_c=0;
225
226 uint8_t column=0;
227
228
229 int16_t keys_averages_acc[KEY_COUNT];
230 uint16_t keys_averages[KEY_COUNT];
231
232 uint8_t full_samples[KEY_COUNT];
233
234 /* viable starting biases for near 0.830V offset. and adc PRESCALE 3
235 0017 0016 001B 001A 0016 0016 000F 000E 001B 001E 001E 0018 0017 0015 000E 001D
236 001B 001A 0016 0016 000F 000E 001C 001B 001E 0018 0017 0015 000E 001D 0024 001F
237 0016 0016 000F 000E 001C 001B 001E 001E 0017 0015 000E 001D 0024 001F 0020 001F
238 000F 000E 001C 001B 001E 001E 0018 0017 000E 001D 0024 001F 0020 001F 0020 0017
239 001C 001B 001E 001E 0018 0017 0015 000E 0024 001F 0020 001F 0020 0017 0010 001D
240 001E 001E 0018 0017 0015 000E 001D 0024 0020 001F 0020 0017 0010 001D 0024 0021
241 0018 0017 0015 000E 001D 0024 001F 0020 0020 0017 0010 001D 0024 0021 0021 0021
242 0015 000E 001D 0024 001F 0020 001F 0020 0010 001D 0024 0021 0021 0021 0021 0018
243 */
244
245 /*** starting bias relative to fixed offset estimate of 820mV (0x50)
246  *   77 69 65 5B 50 4E 4C 45   66 53 4D 49 45 3F 3E 35
247  *   68 54 4F 49 45 40 3F 34   74 66 5F 56 4E 4D 4C 3F
248  *   6D 5D 53 4C 49 46 45 38   6D 5A 53 4E 49 48 45 3E
249  *   6F 5D 56 4E 4B 48 48 3A   6D 5C 54 4E 48 48 45 37
250  *   75 68 5F 57 4F 4D 4C 3F   60 4E 48 41 3C 3C 39 2F
251  *   65 53 4E 49 41 3F 3E 34   65 54 4E 49 43 3F 3E 34
252  *   60 51 4A 45 3F 3E 3C 30   57 4C 45 3E 3B 37 37 2E
253  *   64 4E 48 44 3C 3B 39 2F   5D 4F 48 45 3E 3C 3B 30
254  */
255
256 /*volatile*/ uint16_t count = 0;
257
258 /*volatile*/ uint8_t error = 0;
259 uint16_t error_data = 0;
260
261
262 int16_t mux_averages[MUXES_COUNT];
263 int16_t strobe_averages[STROBE_LINES];
264
265 uint8_t dump_count = 0;
266
267
268
269 // ----- Function Declarations -----
270
271 void dump    ( void );
272 void dumpkeys( void );
273
274 void recovery( uint8_t on );
275
276 int sampleColumn  ( uint8_t column );
277 int sampleColumn_i( uint8_t column, uint8_t muxes, int16_t * buffer); // XXX Not currently used
278 int sampleColumn_k( uint8_t column, int16_t *buffer );
279
280 void setup_ADC( void );
281
282 void strobe_w( uint8_t strobe_num );
283
284 uint8_t testColumn( uint8_t strobe );
285
286
287
288 // ----- Functions -----
289
290 // Initial setup for cap sense controller
291 inline void scan_setup()
292 {
293         // TODO dfj code...needs cleanup + commenting...
294         setup_ADC();
295
296         // Configure timer 0 to generate a timer overflow interrupt every
297         // 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock
298         // This demonstrates how to use interrupts to implement a simple
299         // inactivity timeout.
300         //TCCR0A = 0x00;
301         //TCCR0B = 0x05;
302         //TIMSK0 = (1<<TOIE0);
303
304         DDRC = C_MASK;
305         PORTC = 0;
306         DDRD = D_MASK;
307         PORTD = 0;
308         DDRE = E_MASK;
309         PORTE = 0 ;
310
311         //DDRC |= (1 << 6);
312         //PORTC &= ~(1<< 6);
313
314         //uint16_t strobe = 1;
315
316
317         // TODO all this code should probably be in scan_resetKeyboard
318         for (int i=0; i< STROBE_LINES; ++i) {
319                 cur_keymap[i] = 0;
320                 //last_keymap[i] = 0;
321                 usb_keymap[i] = 0;
322         }
323
324         for(int i=0; i < MUXES_COUNT; ++i) {
325                 adc_mux_averages[i] = 0x20; // experimentally determined.
326         }
327         for(int i=0; i < STROBE_LINES; ++i) {
328                 adc_strobe_averages[i] = 0x20; // yup.
329         }
330
331         for(int i=0; i< KEY_COUNT; ++i) {
332                 keys_averages[i] = 0x40;
333                 keys_averages_acc[i] = (0x400);
334         }
335
336         /** warm things up a bit before we start collecting data, taking real samples. */
337         for(uint8_t i = 0; i< STROBE_LINES; ++i) {
338                 sampleColumn(i);
339         }
340
341
342         // Reset the keyboard before scanning, we might be in a wierd state
343         // Also sets the KeyIndex_BufferUsed to 0
344         scan_resetKeyboard();
345 }
346
347
348 // Main Detection Loop
349 // This is where the important stuff happens
350 inline uint8_t scan_loop()
351 {
352         // TODO dfj code...needs commenting + cleanup...
353         uint8_t strober = 0;
354         uint32_t full_av_acc = 0;
355
356         for (strober = 0; strober < STROBE_LINES; ++strober) {
357
358                 uint8_t tries;
359                 tries = 1;
360                 while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
361                 column = testColumn(strober);
362
363                 if( column != cur_keymap[strober] && (count >= WARMUP_LOOPS) ) {
364                         tests++;
365
366                         tries = 1;
367                         while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
368                         col_a = testColumn(strober);
369
370                         tries = 1;
371                         while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
372                         col_b = testColumn(strober);
373
374                         tries = 1;
375                         while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
376                         col_c = testColumn(strober);
377
378                         if( (col_a == col_b) && (col_b == col_c) && (cur_keymap[strober] != col_a) ) {
379                                 cur_keymap[strober] = col_a;
380                                 usb_dirty = 1;
381                         }
382                 }
383
384                 if(error == 0x50) {
385                         error_data |= (((uint16_t)strober) << 12);
386                 }
387
388                 for(int i=0; i<MUXES_COUNT; ++i) {
389                         full_samples[(strober << MUXES_COUNT_XSHIFT) + i] = samples[SAMPLE_OFFSET + i];
390                 }
391
392                 strobe_averages[strober] = 0;
393                 for (uint8_t i = SAMPLE_OFFSET; i < (SAMPLE_OFFSET + MUXES_COUNT); ++i) {
394                         //samples[i] -= samples[i-SAMPLE_OFFSET]; // av; // + full_av); // -something.
395                         //samples[i] -= OFFSET_VOLTAGE; // moved to sampleColumn.
396
397                         full_av_acc += (samples[i]);
398                         mux_averages[i - SAMPLE_OFFSET] += samples[i];
399                         strobe_averages[strober] += samples[i];
400                         //samples[i] -= (full_av - HYST_T);
401
402                         //++count;
403                 }
404                 adc_strobe_averages[strober] += strobe_averages[strober] >> 3;
405                 adc_strobe_averages[strober] >>= 1;
406
407                 /** test if we went negative. */
408                 if ((adc_strobe_averages[strober] & 0xFF00) && (count
409                                 >= WARMUP_LOOPS)) {
410                         //count = 0; // TODO : constrain properly.
411                         error = 0xf; error_data = adc_strobe_averages[strober];
412                 }
413
414                 uint8_t strobe_line = strober << MUXES_COUNT_XSHIFT;
415                 for (int i = 0; i < MUXES_COUNT; ++i) {
416                         keys_averages_acc[strobe_line + i]
417                                         += samples[SAMPLE_OFFSET + i];
418                 }
419
420         } // for strober
421
422         if (count < WARMUP_LOOPS) {
423                 error = 0x0C;
424                 error_data = count;
425                 count++;
426         }
427
428         // verify test key is not down.
429         if((cur_keymap[TEST_KEY_STROBE] & TEST_KEY_MASK) ) {
430                 //count=0;
431                 error = 0x05;
432                 error_data = cur_keymap[TEST_KEY_STROBE] << 8;
433                 error_data += full_samples[TEST_KEY_STROBE * 8];
434                 //threshold++;
435         }
436
437         // calc mux averages.
438         if (count < WARMUP_LOOPS) {
439                 full_av += (full_av_acc >> (7));
440                 full_av >>= 1;
441                 //full_av = full_av_acc / count;
442                 full_av_acc = 0;
443                 for (int i=0; i < MUXES_COUNT; ++i) {
444
445                         adc_mux_averages[i] = (adc_mux_averages[i] << MUX_MIX) - adc_mux_averages[i];
446                         adc_mux_averages[i] += (mux_averages[i] >> 4);
447                         adc_mux_averages[i] >>= MUX_MIX;
448
449                         mux_averages[i] = 0;
450                 }
451
452         }
453
454         idle_count++;
455         idle_count &= IDLE_COUNT_MASK;
456
457         if (/*usb_dirty &&*/ (count >= WARMUP_LOOPS) ) {
458                 for (int i=0; i<STROBE_LINES; ++i) {
459                         usb_keymap[i] = cur_keymap[i];
460                 }
461
462                 dumpkeys();
463                 usb_dirty=0;
464                 _delay_ms(2);
465         }
466
467         if (count < WARMUP_LOOPS) {
468                 for (uint8_t i = 0; i < KEY_COUNT; ++i) {
469                         uint16_t acc = keys_averages_acc[i];
470                         uint32_t av = keys_averages[i];
471
472                         av = av + av + av + acc;
473                         av >>= 2;
474
475                         keys_averages[i] = av;
476                         keys_averages_acc[i] = 0;
477                 }
478         }
479
480
481         if(!idle_count) {
482
483                 for (int i=0; i< KEY_COUNT; ++i) {
484                         keys_averages_acc[i] = 0;
485                 }
486
487                 sampleColumn(0x0); // to resync us if we dumped a mess 'o text.
488         }
489
490
491         // Return non-zero if macro and USB processing should be delayed
492         // Macro processing will always run if returning 0
493         // USB processing only happens once the USB send timer expires, if it has not, scan_loop will be called
494         //  after the macro processing has been completed
495         return 0;
496 }
497
498
499 // Reset Keyboard
500 void scan_resetKeyboard( void )
501 {
502         // Empty buffer, now that keyboard has been reset
503         KeyIndex_BufferUsed = 0;
504 }
505
506
507 // Send data to keyboard
508 // NOTE: Only used for converters, since the scan module shouldn't handle sending data in a controller
509 uint8_t scan_sendData( uint8_t dataPayload )
510 {
511         return 0;
512 }
513
514
515 // Reset/Hold keyboard
516 // NOTE: Only used for converters, not needed for full controllers
517 void scan_lockKeyboard( void )
518 {
519 }
520
521 // NOTE: Only used for converters, not needed for full controllers
522 void scan_unlockKeyboard( void )
523 {
524 }
525
526
527 // Signal KeyIndex_Buffer that it has been properly read
528 // NOTE: Only really required for implementing "tricks" in converters for odd protocols
529 void scan_finishedWithBuffer( uint8_t sentKeys )
530 {
531         // Convenient place to clear the KeyIndex_Buffer
532         KeyIndex_BufferUsed = 0;
533         return;
534 }
535
536
537 // Signal KeyIndex_Buffer that it has been properly read and sent out by the USB module
538 // NOTE: Only really required for implementing "tricks" in converters for odd protocols
539 void scan_finishedWithUSBBuffer( uint8_t sentKeys )
540 {
541         return;
542 }
543
544
545 void
546 _delay_loop(uint8_t __count)
547 {
548         __asm__ volatile (
549                 "1: dec %0" "\n\t"
550                 "brne 1b"
551                 : "=r" (__count)
552                 : "0" (__count)
553         );
554 }
555
556
557 void setup_ADC (void) {
558         // disable adc digital pins.
559         DIDR1 |= (1 << AIN0D) | (1<<AIN1D); // set disable on pins 1,0.
560         //DIDR0 = 0xff; // disable all. (port F, usually). - testing w/o disable.
561         DDRF = 0x0;
562         PORTF = 0x0;
563         uint8_t mux = 0 & 0x1f; // 0 == first. // 0x1e = 1.1V ref.
564
565         // 0 = external aref 1,1 = 2.56V internal ref
566         uint8_t aref = ((1 << REFS1) | (1 << REFS0)) & ((1 << REFS1) | (1 << REFS0));
567 //      uint8_t adlar = 0xff & (1 << ADLAR); // 1 := left justify bits, 0 := right
568         uint8_t adate = (1 << ADATE) & (1 << ADATE); // trigger enable
569         uint8_t trig = 0 & ((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2)); // 0 = free running
570         // ps2, ps1 := /64 ( 2^6 ) ps2 := /16 (2^4), ps1 := 4, ps0 :=2, PS1,PS0 := 8 (2^8)
571         uint8_t prescale = ( ((PRESCALE) << PRESCALE_SHIFT) & PRESCALE_MASK ); // 001 == 2^1 == 2
572         uint8_t hispeed = (1 << ADHSM);
573         uint8_t en_mux = (1 << ACME);
574
575         //ADCSRA = (ADCSRA & ~PRESCALES) | ((1 << ADPS1) | (1 << ADPS2)); // 2, 1 := /64 ( 2^6 )
576         //ADCSRA = (ADCSRA & ~PRESCALES) | ((1 << ADPS0) | (1 << ADPS2)); // 2, 0 := /32 ( 2^5 )
577         //ADCSRA = (ADCSRA & ~PRESCALES) | ((1 << ADPS2)); // 2 := /16 ( 2^4 )
578
579         ADCSRA = (1 << ADEN) | prescale; // ADC enable
580
581         // select ref.
582         //ADMUX |= ((1 << REFS1) | (1 << REFS0)); // 2.56 V internal.
583         //ADMUX |= ((1 << REFS0) ); // Vcc with external cap.
584         //ADMUX &= ~((1 << REFS1) | (1 << REFS0)); // 0,0 : aref.
585         ADMUX = aref | mux | ADLAR_BITS;
586
587         // enable MUX
588         // ADCSRB |= (1 << ACME);       // enable
589         // ADCSRB &= ~(1 << ADEN); // ?
590
591         // select first mux.
592         //ADMUX = (ADMUX & ~MUXES); // start at 000 = ADC0
593
594         // clear adlar to left justify data
595         //ADMUX = ~();
596
597         // set adlar to right justify data
598         //ADMUX |= (1 << ADLAR);
599
600
601         // set free-running
602         ADCSRA |= adate; // trigger enable
603         ADCSRB  = en_mux | hispeed | trig | (ADCSRB & ~((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2))); // trigger select free running
604
605 //      ADCSRA |= (1 << ADATE); // tiggger enable
606
607         ADCSRA |= (1 << ADEN); // ADC enable
608         ADCSRA |= (1 << ADSC); // start conversions q
609
610 }
611
612
613 void recovery(uint8_t on) {
614         DDRB |= (1 << RECOVERY_CONTROL);
615
616         PORTB &= ~(1 << RECOVERY_SINK);    // SINK always zero
617         DDRB &= ~(1 << RECOVERY_SOURCE);  // SOURCE high imp
618
619         if(on) {
620                 DDRB |= (1 << RECOVERY_SINK);   // SINK pull
621
622
623                 PORTB |= (1 << RECOVERY_CONTROL);
624
625                 PORTB |= (1 << RECOVERY_SOURCE); // SOURCE high
626                 DDRB |= (1 << RECOVERY_SOURCE);
627         } else {
628                 _delay_loop(10);
629                 PORTB &= ~(1 << RECOVERY_CONTROL);
630
631                 DDRB &= ~(1 << RECOVERY_SOURCE);
632                 PORTB &= ~(1 << RECOVERY_SOURCE); // SOURCE low
633                 DDRB &= ~(1 << RECOVERY_SINK);  // SINK high-imp
634
635                 //DDRB &= ~(1 << RECOVERY_SINK);
636         }
637 }
638
639
640 void strobe_w(uint8_t strobe_num) {
641
642         PORTC &= ~(D_MASK);
643         PORTD &= ~(D_MASK);
644         PORTE &= ~(E_MASK);
645
646 #ifdef SHORT_C
647         strobe_num = 15 - strobe_num;
648 #endif
649
650         switch(strobe_num) {
651
652         case 0: PORTD |= (1 << 0); break;
653         case 1: PORTD |= (1 << 1); break;
654         case 2: PORTD |= (1 << 2); break;
655         case 3: PORTD |= (1 << 3); break;
656         case 4: PORTD |= (1 << 4); break;
657         case 5: PORTD |= (1 << 5); break;
658
659 #ifdef ALL_D
660
661         case 6: PORTD |= (1 << 6); break;
662         case 7: PORTD |= (1 << 7); break;
663
664         case 8:  PORTC |= (1 << 0); break;
665         case 9:  PORTC |= (1 << 1); break;
666         case 10: PORTC |= (1 << 2); break;
667         case 11: PORTC |= (1 << 3); break;
668         case 12: PORTC |= (1 << 4); break;
669         case 13: PORTC |= (1 << 5); break;
670         case 14: PORTC |= (1 << 6); break;
671         case 15: PORTC |= (1 << 7); break;
672
673         case 16: PORTE |= (1 << 0); break;
674         case 17: PORTE |= (1 << 1); break;
675
676 #else
677 #ifdef SHORT_D
678
679         case 6: PORTE |= (1 << 0); break;
680         case 7: PORTE |= (1 << 1); break;
681
682         case 8:  PORTC |= (1 << 0); break;
683         case 9:  PORTC |= (1 << 1); break;
684         case 10: PORTC |= (1 << 2); break;
685         case 11: PORTC |= (1 << 3); break;
686         case 12: PORTC |= (1 << 4); break;
687         case 13: PORTC |= (1 << 5); break;
688         case 14: PORTC |= (1 << 6); break;
689         case 15: PORTC |= (1 << 7); break;
690
691 #else
692 #ifdef SHORT_C
693
694         case 6: PORTD |= (1 << 6); break;
695         case 7: PORTD |= (1 << 7); break;
696
697         case 8: PORTE |= (1 << 0); break;
698         case 9: PORTE |= (1 << 1); break;
699
700         case 10:  PORTC |= (1 << 0); break;
701         case 11:  PORTC |= (1 << 1); break;
702         case 12: PORTC |= (1 << 2); break;
703         case 13: PORTC |= (1 << 3); break;
704         case 14: PORTC |= (1 << 4); break;
705         case 15: PORTC |= (1 << 5); break;
706
707         case 16: PORTC |= (1 << 6); break;
708         case 17: PORTC |= (1 << 7); break;
709
710 #endif
711 #endif
712 #endif
713
714         default:
715                 break;
716         }
717
718 }
719
720
721 int sampleColumn_i(uint8_t column, uint8_t muxes, int16_t * buffer) {
722
723         // ensure all probe lines are driven low, and chill for recovery delay.
724         PORTC &= ~C_MASK;
725         PORTD &= ~D_MASK;
726         PORTE &= ~E_MASK;
727         recovery(1);
728         _delay_us(RECOVERY_US);
729         recovery(0);
730
731         uint8_t index = 0;
732
733         for (uint8_t i=0; i<8; ++i) {
734                 if(muxes & (1 << i)) {
735                         buffer[index++] = i;
736                 }
737         }
738
739         SET_FULL_MUX(MUX_1_1); // crap sample will use this.
740         ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions
741         ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
742
743         //uint16_t sample;
744
745         while (! (ADCSRA & (1 << ADIF))); // wait until ready.
746         //sample = ADC; // 1st sample, icky.
747         ADC; // 1st sample, icky. XXX Not sure if the compiler throws this away, but less compiler warnings -HaaTa
748
749         strobe_w(column);
750         //recovery(0);
751
752         /**
753          * we are running in continuous mode, so we must setup the next
754          * read _before_ the current read completes.
755          *
756          * setup 0,
757          * read garbage,
758          * do not store
759          *
760          * setup 1,
761          * read 0,
762          * store 0,
763          *
764          * ...
765          *
766          * setup junk,
767          * read n
768          * store n
769          *
770          * */
771
772
773         ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
774         //wait for last read to complete.
775         while (! (ADCSRA & (1 << ADIF)));
776         //sample = ADC; // throw away strobe'd value.
777         ADC; // throw away strobe'd value.
778
779 #if 0
780         for (uint8_t i=0; i <= index; ++i) {
781
782                 // setup i'th read.
783                 SET_FULL_MUX(buffer[i]); // _next_ read will use this.
784                 // wait for i-1'th read to complete:
785                 ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
786                 while (! (ADCSRA & (1 << ADIF)));
787
788                 // retrieve last (i-1'th) read.
789                 if (i) {
790                         buffer[i-1] = ADC - OFFSET_VOLTAGE;
791                 } /*else {
792                         buffer[0] = ADC - OFFSET_VOLTAGE;
793                 }*/
794
795                 //index++;
796         }
797 #else
798         for (uint8_t i=0; i < index; ++i) {
799
800                 // setup i'th read.
801                 SET_FULL_MUX(buffer[i]); // _next_ read will use this.
802
803                 ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
804                 while (! (ADCSRA & (1 << ADIF)));
805                 //sample = ADC; // throw away warmup value.
806                 ADC; // throw away warmup value.
807
808
809
810                 /*
811                 ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
812                 while (! (ADCSRA & (1 << ADIF)));
813                 //sample = ADC; // throw away warmup value.
814                 ADC; // throw away warmup value.
815 */
816
817                 ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
818                 while (! (ADCSRA & (1 << ADIF)));
819
820                 // retrieve current read.
821                 buffer[i] = ADC - OFFSET_VOLTAGE;
822
823
824         }
825 #endif
826
827
828         // turn off adc.
829         ADCSRA &= ~(1 << ADEN);
830
831         // pull all columns' probe-lines low.
832         PORTC &= ~C_MASK;
833         PORTD &= ~D_MASK;
834         PORTE &= ~E_MASK;
835
836         // test for humps. :/
837         /*uint16_t delta = full_av;
838         if(buffer[0] > BUMP_THRESHOLD + delta) {
839                 // ze horror.
840                 return 1;
841         } else {
842                 return 0; //all good.
843         }*/
844         return 0;
845
846 }
847
848
849 int sampleColumn_k(uint8_t column, int16_t * buffer) {
850         // ensure all probe lines are driven low, and chill for recovery delay.
851         //uint16_t sample;
852
853         ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions
854         ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
855
856         // sync up with adc clock:
857         while (! (ADCSRA & (1 << ADIF))); // wait until ready.
858         ADC; // throw it away. // XXX Not sure if the compiler throws this away, but less compiler warnings -HaaTa
859         //sample = ADC; // throw it away.
860
861         for(uint8_t mux=0; mux < 8; ++mux) {
862
863                 PORTC &= ~C_MASK;
864                 PORTD &= ~D_MASK;
865                 PORTE &= ~E_MASK;
866
867                 SET_FULL_MUX(mux); // our sample will use this
868
869                 for(uint8_t i=0; i < 2; ++i) {
870                         ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
871                         //wait for last read to complete.
872                         while (! (ADCSRA & (1 << ADIF)));
873                         //sample = ADC; // throw away strobe'd value.
874                         ADC; // throw away strobe'd value.
875                 }
876
877                 recovery(0);
878                 strobe_w(column);
879
880                 ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
881                 //wait for last read to complete.
882                 while (! (ADCSRA & (1 << ADIF)));
883                 //sample = ADC; // throw away strobe'd value.
884                 ADC; // throw away strobe'd value.
885
886                 ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
887                 while (! (ADCSRA & (1 << ADIF)));
888
889                 // retrieve current read.
890                 buffer[mux] = ADC - OFFSET_VOLTAGE;
891                 recovery(1);
892
893         }
894
895         // turn off adc.
896         ADCSRA &= ~(1 << ADEN);
897
898         // pull all columns' probe-lines low.
899         PORTC &= ~C_MASK;
900         PORTD &= ~D_MASK;
901         PORTE &= ~E_MASK;
902 //              recovery(1);
903
904
905         return 0;
906 }
907
908
909 int sampleColumn(uint8_t column) {
910         int rval = 0;
911
912         /*
913         sampleColumn_i(column, 0x0f, samples+SAMPLE_OFFSET);
914         sampleColumn_i(column, 0xf0, samples+SAMPLE_OFFSET + 4 );
915 */
916
917         rval = sampleColumn_k(column, samples+SAMPLE_OFFSET);
918
919         for(uint8_t i=0; i<8; ++i) {
920                 if(samples[SAMPLE_OFFSET + i] - adc_mux_averages[i] > BUMP_THRESHOLD) {
921                         // was a hump
922
923                         _delay_us(BUMP_REST_US);
924                         rval++;
925                         error = 0x50;
926                         error_data = samples[SAMPLE_OFFSET +i]; //  | ((uint16_t)i << 8);
927                         return rval;
928                 }
929         }
930
931         return rval;
932 }
933
934
935 uint8_t testColumn(uint8_t strobe) {
936     uint8_t column = 0;
937     uint8_t bit = 1;
938     for (uint8_t i=0; i < MUXES_COUNT; ++i) {
939                 uint16_t delta = keys_averages[(strobe << MUXES_COUNT_XSHIFT) + i];
940                 if ((int16_t)samples[SAMPLE_OFFSET + i] > threshold + delta) {
941                         column |= bit;
942                 }
943                 bit <<= 1;
944         }
945     return column;
946 }
947
948
949 void dumpkeys(void) {
950         //print(" \n");
951         if(error) {
952                 for (uint8_t i=0; i < STROBE_LINES; ++i) {
953                                 printHex(usb_keymap[i]);
954                                 print(" ");
955
956                                 //print(" ");
957                 }
958                 if (count >= WARMUP_LOOPS && error) {
959                         dump();
960                 }
961
962                 print(" : ");
963                 printHex(error);
964                 error = 0;
965                 print(" : ");
966                 printHex(error_data);
967                 error_data = 0;
968                 print(" : " NL);
969         }
970
971         // XXX Will be cleaned up eventually, but this will do for now :P -HaaTa
972         for (uint8_t i=0; i < STROBE_LINES; ++i) {
973                 for(uint8_t j=0; j<MUXES_COUNT; ++j) {
974                         if ( usb_keymap[i] & (1 << j) ) {
975                                 uint8_t key = (i << MUXES_COUNT_XSHIFT) + j;
976
977                                 // Add to the Macro processing buffer
978                                 // Automatically handles converting to a USB code and sending off to the PC
979                                 bufferAdd( key );
980
981                                 if(usb_dirty) {
982                                         printHex( key );
983                                         print(" ");
984                                 }
985                         }
986                 }
987         }
988         if(usb_dirty) print("\n");
989         usb_keyboard_send();
990 }
991
992
993 void dump(void) {
994
995         if(!dump_count) {  // we don't want to debug-out during the measurements.
996
997                 for(int i =0; i< KEY_COUNT; ++i) {
998                         if(!(i & 0x0f)) {
999                                 print("\n");
1000                         } else if (!(i & 0x07)) {
1001                                 print("  ");
1002                         }
1003                         print(" ");
1004                         //printHex (keys_averages[(i >> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]);
1005                         printHex (keys_averages[i]);
1006                 }
1007
1008                 print("\n");
1009
1010                 for(int i =0; i< KEY_COUNT; ++i) {
1011                         if(!(i & 0x0f)) {
1012                                 print("\n");
1013                         } else if (!(i & 0x07)) {
1014                                 print("  ");
1015                         }
1016                         print(" ");
1017                         //printHex (keys_averages[(i >> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]);
1018                         //printHex (keys_averages_acc[i]);
1019                         printHex(full_samples[i]);
1020                 }
1021         }
1022
1023
1024         //}
1025
1026 //      uint8_t cur_strober = 0xe;
1027         uint8_t cur_strober = ze_strober;
1028         print("\n");
1029
1030         printHex(cur_strober);
1031         //print(":         ");
1032         print(": ");
1033 #if 1
1034         print("\n");
1035         for (uint8_t i=0; i < MUXES_COUNT; ++i) {
1036                 print(" ");
1037                 printHex(full_samples[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
1038         }
1039
1040         print("\n");
1041 //      printHex(threshold);
1042 //      print(": ");
1043
1044         for (uint8_t i=0; i < MUXES_COUNT; ++i) {
1045                 print(" ");
1046                 printHex(keys_averages[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
1047         }
1048
1049 #endif
1050         /*
1051         for (uint8_t i=0; i< SAMPLES; ++i) {
1052                 print(" ");
1053                 printHex(samples[i]);
1054                 //printHex(ADC);
1055         }*/
1056         //print(" : ");
1057         //dPrint((was_active)?" ":"*");
1058
1059         //printHex(keymap[TEST_KEY_STROBE] & TEST_KEY_MASK);
1060         /*print(" "); */
1061         //printHex(keymap[TEST_KEY_STROBE]);
1062
1063
1064         //print("\n");
1065         //print(":");
1066         //printHex(full_av);
1067         //printHex(count);
1068         //print(" : ");
1069         print("\n");
1070
1071         for (uint8_t i=0; i < STROBE_LINES; ++i) {
1072                 printHex(cur_keymap[i]);
1073                 print(" ");
1074
1075                 //print(" ");
1076         }
1077
1078
1079         //print(": ");
1080         //printHex(adc_strobe_averages[ze_strober]);
1081         //print(" ");
1082
1083
1084
1085         for (uint8_t i=0; i < MUXES_COUNT; ++i) {
1086                 print(" ");
1087                 //printHex(adc_mux_averages[i] + adc_strobe_averages[ze_strober] - full_av);
1088                 //printHex((adc_mux_averages[i] + adc_strobe_averages[ze_strober]) >> 1);
1089                 //printHex((adc_mux_averages[i] * 3  + adc_strobe_averages[ze_strober]) >> 2);
1090                 //printHex(adc_mux_averages[i] + threshold);
1091                 //printHex(gsamples[i + SAMPLE_OFFSET] - (adc_mux_averages[i] + threshold) + 0x100);
1092                 //printHex(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i] + (uint8_t)threshold);
1093                 printHex(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i]);
1094         }
1095
1096         if(error) {
1097                 print(" ");
1098                 printHex(error);
1099                 print(" ");
1100                 printHex(error_data);
1101                 error = 0;
1102                 error_data = 0;
1103         }
1104         //print("\n");
1105
1106         ze_strober++;
1107         ze_strober &= 0xf;
1108
1109
1110         dump_count++;
1111         dump_count &= 0x0f;
1112
1113
1114
1115         //ze_strobe = (1 << (ze_strober ) );
1116
1117
1118
1119         //printHex(ADCSRA);
1120         //print(" ");
1121                         //print("\n");
1122 }
1123