]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/avr-capsense/scan_loop.c
Removed a keyscan layer and added more debug information
[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  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 3.0 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 // ----- Includes -----
19
20 // Compiler Includes
21 #include <Lib/ScanLib.h>
22
23 // Project Includes
24 #include <led.h>
25 #include <print.h>
26
27 // Local Includes
28 #include "scan_loop.h"
29
30
31
32 // ----- Defines -----
33
34 // TODO dfj defines...needs commenting and maybe some cleaning...
35 #define MAX_PRESS_DELTA_MV 470
36 #define THRESHOLD_MV (MAX_PRESS_DELTA_MV >> 1)
37 //(2560 / (0x3ff/2)) ~= 5
38 #define MV_PER_ADC 5
39 // 5
40
41 #define THRESHOLD (THRESHOLD_MV / MV_PER_ADC)
42
43 #define BUMP_DETECTION 0
44 #define BUMP_THRESHOLD 0x50
45 #define BUMP_REST_US 1200
46
47 #define STROBE_SETTLE 1
48 #define MUX_SETTLE 1
49
50 #define TEST_KEY_STROBE (0x05)
51 #define TEST_KEY_MASK (1 << 0)
52
53 #define ADHSM 7
54
55 #define RIGHT_JUSTIFY 0
56 #define LEFT_JUSTIFY (0xff)
57
58 // set left or right justification here:
59 #define JUSTIFY_ADC RIGHT_JUSTIFY
60 #define ADLAR_MASK (1 << ADLAR)
61
62 #ifdef JUSTIFY_ADC
63 #define ADLAR_BITS ((ADLAR_MASK) & (JUSTIFY_ADC))
64 #else // defaults to right justification.
65 #define ADLAR_BITS 0
66 #endif
67
68 // full muxmask
69 #define FULL_MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2) | (1 << MUX3) | (1 << MUX4))
70
71 // F0-f7 pins only muxmask.
72 #define MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2))
73
74 // Strobe Masks
75 #define D_MASK (0xff)
76 #define E_MASK (0x03)
77 #define C_MASK (0xff)
78
79 // set ADC clock prescale
80 #define PRESCALE_MASK ((1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2))
81 #define PRESCALE_SHIFT (ADPS0)
82 #define PRESCALE 3
83
84 // TODO Remove this define when unnecessary -HaaTa
85 #define STROBE_LINES 16
86
87 #define MUXES_COUNT 8
88 #define MUXES_COUNT_XSHIFT 3
89
90 #define WARMUP_LOOPS ( 1024 )
91 #define WARMUP_STOP (WARMUP_LOOPS - 1)
92
93 #define SAMPLES 10
94 #define SAMPLE_OFFSET ((SAMPLES) - MUXES_COUNT)
95 #define SAMPLE_CONTROL 3
96
97 // TODO Figure out calculation or best way to determine at startup -HaaTa
98 //#define DEFAULT_KEY_BASE 0xc8
99 #define DEFAULT_KEY_BASE 0x95
100
101 #define KEY_COUNT ((STROBE_LINES) * (MUXES_COUNT))
102
103 #define RECOVERY_CONTROL 1
104 #define RECOVERY_SOURCE  0
105 #define RECOVERY_SINK    2
106
107 #define ON  1
108 #define OFF 0
109
110 // mix in 1/4 of the current average to the running average. -> (@mux_mix = 2)
111 #define MUX_MIX 2
112
113 #define IDLE_COUNT_MASK 0xff
114 #define IDLE_COUNT_SHIFT 8
115
116 // av = (av << shift) - av + sample; av >>= shift
117 // e.g. 1 -> (av + sample) / 2 simple average of new and old
118 //      2 -> (3 * av + sample) / 4 i.e. 3:1 mix of old to new.
119 //      3 -> (7 * av + sample) / 8 i.e. 7:1 mix of old to new.
120 #define KEYS_AVERAGES_MIX_SHIFT 3
121
122
123
124 // ----- Macros -----
125
126 // Make sure we haven't overflowed the buffer
127 #define bufferAdd(byte) \
128                 if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
129                         KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte
130
131 // Select mux
132 #define SET_FULL_MUX(X) ((ADMUX) = (((ADMUX) & ~(FULL_MUX_MASK)) | ((X) & (FULL_MUX_MASK))))
133
134
135
136 // ----- Variables -----
137
138 // Buffer used to inform the macro processing module which keys have been detected as pressed
139 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
140 volatile uint8_t KeyIndex_BufferUsed;
141
142
143 // TODO dfj variables...needs cleaning up and commenting
144 volatile uint16_t full_av = 0;
145
146 uint8_t ze_strober = 0;
147
148 uint16_t samples [SAMPLES];
149
150 uint16_t adc_mux_averages   [MUXES_COUNT];
151 uint16_t adc_strobe_averages[STROBE_LINES];
152
153 uint8_t cur_keymap[STROBE_LINES];
154
155 uint8_t keymap_change;
156
157 uint16_t threshold = 0x25; // HaaTa Hack -TODO
158 //uint16_t threshold = 0x16; // HaaTa Hack -TODO
159 //uint16_t threshold = THRESHOLD;
160
161 uint8_t column = 0;
162
163 uint16_t keys_averages_acc[KEY_COUNT];
164 uint16_t keys_averages[KEY_COUNT];
165
166 uint8_t full_samples[KEY_COUNT];
167
168 // TODO: change this to 'booting', then count down.
169 uint16_t boot_count = 0;
170
171 uint16_t idle_count = 0;
172 uint8_t idle = 1;
173
174 uint8_t error = 0;
175 uint16_t error_data = 0;
176
177 uint16_t mux_averages[MUXES_COUNT];
178 uint16_t strobe_averages[STROBE_LINES];
179
180 uint8_t dump_count = 0;
181
182 uint16_t db_delta = 0;
183 uint8_t  db_sample = 0;
184 uint16_t db_threshold = 0;
185
186
187
188 // ----- Function Declarations -----
189
190 void dump( void );
191
192 void recovery( uint8_t on );
193
194 int sampleColumn( uint8_t column );
195
196 void setup_ADC( void );
197
198 void strobe_w( uint8_t strobe_num );
199
200 uint8_t testColumn( uint8_t strobe );
201
202
203
204 // ----- Functions -----
205
206 // Initial setup for cap sense controller
207 inline void scan_setup()
208 {
209         // TODO dfj code...needs cleanup + commenting...
210         setup_ADC();
211
212         DDRC  = C_MASK;
213         PORTC = 0;
214         DDRD  = D_MASK;
215         PORTD = 0;
216         DDRE  = E_MASK;
217         PORTE = 0 ;
218
219
220         // TODO all this code should probably be in scan_resetKeyboard
221         for (int i=0; i < STROBE_LINES; ++i) {
222                 cur_keymap[i] = 0;
223         }
224
225         for(int i=0; i < MUXES_COUNT; ++i) {
226                 adc_mux_averages[i] = 0x20; // experimentally determined.
227         }
228         for(int i=0; i < STROBE_LINES; ++i) {
229                 adc_strobe_averages[i] = 0x20; // yup.
230         }
231
232         for(int i=0; i < KEY_COUNT; ++i) {
233                 keys_averages[i] = DEFAULT_KEY_BASE;
234                 keys_averages_acc[i] = (DEFAULT_KEY_BASE);
235         }
236
237         /** warm things up a bit before we start collecting data, taking real samples. */
238         for(uint8_t i = 0; i < STROBE_LINES; ++i) {
239                 sampleColumn(i);
240         }
241
242
243         // Reset the keyboard before scanning, we might be in a wierd state
244         // Also sets the KeyIndex_BufferUsed to 0
245         scan_resetKeyboard();
246 }
247
248
249 // Main Detection Loop
250 // This is where the important stuff happens
251 inline uint8_t scan_loop()
252 {
253         // TODO dfj code...needs commenting + cleanup...
254         uint8_t strober = 0;
255         uint32_t full_av_acc = 0;
256
257         for (strober = 0; strober < STROBE_LINES; ++strober)
258         {
259
260                 uint8_t tries = 1;
261                 while ( tries++ && sampleColumn( strober ) ) { tries &= 0x7; } // don't waste this one just because the last one was poop.
262                 column = testColumn(strober);
263
264                 idle |= column; // if column has any pressed keys, then we are not idle.
265
266                 if( column != cur_keymap[strober] && ( boot_count >= WARMUP_LOOPS ) )
267                 {
268                         cur_keymap[strober] = column;
269                         keymap_change = 1;
270
271                         // The keypresses on this strobe are now know, send them right away
272                         for ( uint8_t mux = 0; mux < MUXES_COUNT; ++mux )
273                         {
274                                 if ( column & (1 << mux) )
275                                 {
276                                         uint8_t key = (strober << MUXES_COUNT_XSHIFT) + mux;
277
278                                         // Add to the Macro processing buffer
279                                         // Automatically handles converting to a USB code and sending off to the PC
280                                         //bufferAdd( key );
281
282                                         printHex( key );
283                                         print("\n");
284                                 }
285                         }
286                 }
287
288                 idle |= keymap_change; // if any keys have changed inc. released, then we are not idle.
289
290                 if ( error == 0x50 )
291                 {
292                         error_data |= (((uint16_t)strober) << 12);
293                 }
294
295                 uint8_t strobe_line = strober << MUXES_COUNT_XSHIFT;
296                 for ( int i = 0; i < MUXES_COUNT; ++i )
297                 {
298                         // discard sketchy low bit, and meaningless high bits.
299                         uint8_t sample = samples[SAMPLE_OFFSET + i] >> 1;
300                         full_samples[strobe_line + i] = sample;
301                         keys_averages_acc[strobe_line + i] += sample;
302                 }
303
304                 strobe_averages[strober] = 0;
305                 for ( uint8_t i = SAMPLE_OFFSET; i < ( SAMPLE_OFFSET + MUXES_COUNT ); ++i )
306                 {
307                         full_av_acc += (samples[i]);
308 #ifdef COLLECT_STROBE_AVERAGES
309                         mux_averages[i - SAMPLE_OFFSET] += samples[i];
310                         strobe_averages[strober] += samples[i];
311 #endif
312                 }
313
314 #ifdef COLLECT_STROBE_AVERAGES
315                 adc_strobe_averages[strober] += strobe_averages[strober] >> 3;
316                 adc_strobe_averages[strober] >>= 1;
317
318                 /** test if we went negative. */
319                 if ( ( adc_strobe_averages[strober] & 0xFF00 ) && ( boot_count >= WARMUP_LOOPS ) )
320                 {
321                         error = 0xf; error_data = adc_strobe_averages[strober];
322                 }
323 #endif
324         } // for strober
325
326 #ifdef VERIFY_TEST_PAD
327         // verify test key is not down.
328         if ( ( cur_keymap[TEST_KEY_STROBE] & TEST_KEY_MASK ) )
329         {
330                 error = 0x05;
331                 error_data = cur_keymap[TEST_KEY_STROBE] << 8;
332                 error_data += full_samples[TEST_KEY_STROBE * 8];
333                 //threshold++;
334         }
335 #endif
336
337 #ifdef COLLECT_STROBE_AVERAGES
338         // calc mux averages.
339         if ( boot_count < WARMUP_LOOPS )
340         {
341                 full_av += (full_av_acc >> (7));
342                 full_av >>= 1;
343                 full_av_acc = 0;
344
345                 for ( int i = 0; i < MUXES_COUNT; ++i )
346                 {
347                         adc_mux_averages[i] = (adc_mux_averages[i] << MUX_MIX) - adc_mux_averages[i];
348                         adc_mux_averages[i] += (mux_averages[i] >> 4);
349                         adc_mux_averages[i] >>= MUX_MIX;
350
351                         mux_averages[i] = 0;
352                 }
353         }
354 #endif
355
356         /** aggregate if booting, or if idle;
357          * else, if not booting, check for dirty USB.
358          * */
359
360         idle_count++;
361         idle_count &= IDLE_COUNT_MASK;
362
363         // Warm up voltage references
364         if ( boot_count < WARMUP_LOOPS )
365         {
366                 boot_count++;
367
368                 switch ( boot_count )
369                 {
370                 // First loop
371                 case 1:
372                         // Show msg at first iteration only
373                         info_msg("Warming up the voltage references");
374                         break;
375                 // Middle iterations
376                 case 300:
377                 case 600:
378                 case 900:
379                 case 1200:
380                         print(".");
381                         break;
382                 // Last loop
383                 case WARMUP_STOP:
384                         print("\n");
385                         info_msg("Warmup finished using ");
386                         printInt16( WARMUP_LOOPS );
387                         print(" iterations\n");
388                         break;
389                 }
390         }
391         else
392         {
393                 // Reset accumulators and idle flag/counter
394                 if ( keymap_change )
395                 {
396                         for ( uint8_t c = 0; c < KEY_COUNT; ++c ) { keys_averages_acc[c] = 0; }
397                         idle_count = 0;
398                         idle = 0;
399
400                         keymap_change = 0;
401                 }
402
403                 if ( !idle_count )
404                 {
405                         if( idle )
406                         {
407                                 // aggregate
408                                 for ( uint8_t i = 0; i < KEY_COUNT; ++i )
409                                 {
410                                         uint16_t acc = keys_averages_acc[i] >> IDLE_COUNT_SHIFT;
411                                         uint32_t av = keys_averages[i];
412
413                                         av = (av << KEYS_AVERAGES_MIX_SHIFT) - av + acc;
414                                         av >>= KEYS_AVERAGES_MIX_SHIFT;
415
416                                         keys_averages[i] = av;
417                                         keys_averages_acc[i] = 0;
418                                 }
419                         }
420
421                         if ( boot_count >= WARMUP_LOOPS )
422                         {
423                                 dump();
424                         }
425
426                         sampleColumn(0x0); // to resync us if we dumped a mess 'o text.
427                 }
428
429         }
430
431         // Error case, should not occur in normal operation
432         if ( error )
433         {
434                 erro_msg("Problem detected... ");
435
436                 // Keymap scan debug
437                 for ( uint8_t i = 0; i < STROBE_LINES; ++i )
438                 {
439                                 printHex(cur_keymap[i]);
440                                 print(" ");
441                 }
442
443                 print(" : ");
444                 printHex(error);
445                 error = 0;
446                 print(" : ");
447                 printHex(error_data);
448                 error_data = 0;
449
450                 // Display keymaps and other debug information if warmup completede
451                 if ( boot_count >= WARMUP_LOOPS )
452                 {
453                         dump();
454                 }
455         }
456
457
458         // Return non-zero if macro and USB processing should be delayed
459         // Macro processing will always run if returning 0
460         // USB processing only happens once the USB send timer expires, if it has not, scan_loop will be called
461         //  after the macro processing has been completed
462         return 0;
463 }
464
465
466 // Reset Keyboard
467 void scan_resetKeyboard( void )
468 {
469         // Empty buffer, now that keyboard has been reset
470         KeyIndex_BufferUsed = 0;
471 }
472
473
474 // Send data to keyboard
475 // NOTE: Only used for converters, since the scan module shouldn't handle sending data in a controller
476 uint8_t scan_sendData( uint8_t dataPayload )
477 {
478         return 0;
479 }
480
481
482 // Reset/Hold keyboard
483 // NOTE: Only used for converters, not needed for full controllers
484 void scan_lockKeyboard( void )
485 {
486 }
487
488 // NOTE: Only used for converters, not needed for full controllers
489 void scan_unlockKeyboard( void )
490 {
491 }
492
493
494 // Signal KeyIndex_Buffer that it has been properly read
495 // NOTE: Only really required for implementing "tricks" in converters for odd protocols
496 void scan_finishedWithBuffer( uint8_t sentKeys )
497 {
498         // Convenient place to clear the KeyIndex_Buffer
499         KeyIndex_BufferUsed = 0;
500         return;
501 }
502
503
504 // Signal KeyIndex_Buffer that it has been properly read and sent out by the USB module
505 // NOTE: Only really required for implementing "tricks" in converters for odd protocols
506 void scan_finishedWithUSBBuffer( uint8_t sentKeys )
507 {
508         return;
509 }
510
511
512 void _delay_loop( uint8_t __count )
513 {
514         __asm__ volatile (
515                 "1: dec %0" "\n\t"
516                 "brne 1b"
517                 : "=r" (__count)
518                 : "0" (__count)
519         );
520 }
521
522
523 void setup_ADC()
524 {
525         // disable adc digital pins.
526         DIDR1 |= (1 << AIN0D) | (1<<AIN1D); // set disable on pins 1,0.
527         DDRF = 0x0;
528         PORTF = 0x0;
529         uint8_t mux = 0 & 0x1f; // 0 == first. // 0x1e = 1.1V ref.
530
531         // 0 = external aref 1,1 = 2.56V internal ref
532         uint8_t aref = ((1 << REFS1) | (1 << REFS0)) & ((1 << REFS1) | (1 << REFS0));
533         uint8_t adate = (1 << ADATE) & (1 << ADATE); // trigger enable
534         uint8_t trig = 0 & ((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2)); // 0 = free running
535         // ps2, ps1 := /64 ( 2^6 ) ps2 := /16 (2^4), ps1 := 4, ps0 :=2, PS1,PS0 := 8 (2^8)
536         uint8_t prescale = ( ((PRESCALE) << PRESCALE_SHIFT) & PRESCALE_MASK ); // 001 == 2^1 == 2
537         uint8_t hispeed = (1 << ADHSM);
538         uint8_t en_mux = (1 << ACME);
539
540         ADCSRA = (1 << ADEN) | prescale; // ADC enable
541
542         // select ref.
543         //ADMUX |= ((1 << REFS1) | (1 << REFS0)); // 2.56 V internal.
544         //ADMUX |= ((1 << REFS0) ); // Vcc with external cap.
545         //ADMUX &= ~((1 << REFS1) | (1 << REFS0)); // 0,0 : aref.
546         ADMUX = aref | mux | ADLAR_BITS;
547
548         // set free-running
549         ADCSRA |= adate; // trigger enable
550         ADCSRB  = en_mux | hispeed | trig | (ADCSRB & ~((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2))); // trigger select free running
551
552         ADCSRA |= (1 << ADEN); // ADC enable
553         ADCSRA |= (1 << ADSC); // start conversions q
554 }
555
556
557 void recovery( uint8_t on )
558 {
559         DDRB  |=  (1 << RECOVERY_CONTROL);
560         PORTB &= ~(1 << RECOVERY_SINK);   // SINK always zero
561         DDRB  &= ~(1 << RECOVERY_SOURCE); // SOURCE high imp
562
563         if ( on )
564         {
565                 // set strobes to sink to gnd.
566                 DDRC |= C_MASK;
567                 DDRD |= D_MASK;
568                 DDRE |= E_MASK;
569
570                 PORTC &= ~C_MASK;
571                 PORTD &= ~D_MASK;
572                 PORTE &= ~E_MASK;
573
574                 DDRB  |= (1 << RECOVERY_SINK);   // SINK pull
575                 PORTB |= (1 << RECOVERY_CONTROL);
576                 PORTB |= (1 << RECOVERY_SOURCE); // SOURCE high
577                 DDRB  |= (1 << RECOVERY_SOURCE);
578         }
579         else
580         {
581                 PORTB &= ~(1 << RECOVERY_CONTROL);
582                 DDRB  &= ~(1 << RECOVERY_SOURCE);
583                 PORTB &= ~(1 << RECOVERY_SOURCE); // SOURCE low
584                 DDRB  &= ~(1 << RECOVERY_SINK);   // SINK high-imp
585         }
586 }
587
588
589 void hold_sample( uint8_t on )
590 {
591         if ( !on )
592         {
593                 PORTB |= (1 << SAMPLE_CONTROL);
594                 DDRB  |= (1 << SAMPLE_CONTROL);
595         }
596         else
597         {
598                 DDRB  |=  (1 << SAMPLE_CONTROL);
599                 PORTB &= ~(1 << SAMPLE_CONTROL);
600         }
601 }
602
603
604 void strobe_w( uint8_t strobe_num )
605 {
606         PORTC &= ~(C_MASK);
607         PORTD &= ~(D_MASK);
608         PORTE &= ~(E_MASK);
609
610 #ifdef SHORT_C
611         //strobe_num = 15 - strobe_num;
612 #endif
613         /*
614         printHex( strobe_num );
615         print(" ");
616         strobe_num = 9 - strobe_num;
617         printHex( strobe_num );
618         print("\n");
619         */
620
621         switch(strobe_num) {
622
623         // XXX Kishsaver strobe (note that D0, D1 are not used)
624         case 0: PORTD |= (1 << 0); break;
625         case 1: PORTD |= (1 << 1); break;
626         case 2: PORTD |= (1 << 2); break;
627         case 3: PORTD |= (1 << 3); break;
628         case 4: PORTD |= (1 << 4); break;
629         case 5: PORTD |= (1 << 5); break;
630
631         // TODO REMOVEME
632         case 6: PORTD |= (1 << 6); break;
633         case 7: PORTD |= (1 << 7); break;
634         case 8: PORTE |= (1 << 0); break;
635         case 9: PORTE |= (1 << 1); break;
636         //case 15: PORTC |= (1 << 5); break; // Test strobe on kishsaver
637
638 #if 0
639         // XXX Kishsaver strobe (note that D0, D1 are not used)
640         case 0: PORTD |= (1 << 2); break;
641         case 1: PORTD |= (1 << 3); break;
642         case 2: PORTD |= (1 << 4); break;
643         case 3: PORTD |= (1 << 5); break;
644
645         // TODO REMOVEME
646         case 4: PORTD |= (1 << 6); break;
647         case 5: PORTD |= (1 << 7); break;
648         case 6: PORTE |= (1 << 0); break;
649         case 7: PORTE |= (1 << 1); break;
650         case 15: PORTC |= (1 << 5); break; // Test strobe on kishsaver
651 #endif
652 /*
653 #ifdef ALL_D
654
655         case 6: PORTD |= (1 << 6); break;
656         case 7: PORTD |= (1 << 7); break;
657
658         case 8:  PORTC |= (1 << 0); break;
659         case 9:  PORTC |= (1 << 1); break;
660         case 10: PORTC |= (1 << 2); break;
661         case 11: PORTC |= (1 << 3); break;
662         case 12: PORTC |= (1 << 4); break;
663         case 13: PORTC |= (1 << 5); break;
664         case 14: PORTC |= (1 << 6); break;
665         case 15: PORTC |= (1 << 7); break;
666
667         case 16: PORTE |= (1 << 0); break;
668         case 17: PORTE |= (1 << 1); break;
669
670 #else
671 #ifdef SHORT_D
672
673         case 6: PORTE |= (1 << 0); break;
674         case 7: PORTE |= (1 << 1); break;
675
676         case 8:  PORTC |= (1 << 0); break;
677         case 9:  PORTC |= (1 << 1); break;
678         case 10: PORTC |= (1 << 2); break;
679         case 11: PORTC |= (1 << 3); break;
680         case 12: PORTC |= (1 << 4); break;
681         case 13: PORTC |= (1 << 5); break;
682         case 14: PORTC |= (1 << 6); break;
683         case 15: PORTC |= (1 << 7); break;
684
685 #else
686 #ifdef SHORT_C
687
688         case 6: PORTD |= (1 << 6); break;
689         case 7: PORTD |= (1 << 7); break;
690
691         case 8: PORTE |= (1 << 0); break;
692         case 9: PORTE |= (1 << 1); break;
693
694         case 10:  PORTC |= (1 << 0); break;
695         case 11:  PORTC |= (1 << 1); break;
696         case 12: PORTC |= (1 << 2); break;
697         case 13: PORTC |= (1 << 3); break;
698         case 14: PORTC |= (1 << 4); break;
699         case 15: PORTC |= (1 << 5); break;
700
701         case 16: PORTC |= (1 << 6); break;
702         case 17: PORTC |= (1 << 7); break;
703
704 #endif
705 #endif
706 #endif
707 */
708
709         default:
710                 break;
711         }
712
713
714 #if 0 // New code from dfj -> still needs redoing for kishsaver and autodetection of strobes
715 #ifdef SHORT_C
716         strobe_num = 15 - strobe_num;
717 #endif
718
719 #ifdef SINGLE_COLUMN_TEST
720         strobe_num = 5;
721 #endif
722
723         switch(strobe_num) {
724
725         case 0: PORTD |= (1 << 0); DDRD &= ~(1 << 0); break;
726         case 1: PORTD |= (1 << 1); DDRD &= ~(1 << 1); break;
727         case 2: PORTD |= (1 << 2); DDRD &= ~(1 << 2); break;
728         case 3: PORTD |= (1 << 3); DDRD &= ~(1 << 3); break;
729         case 4: PORTD |= (1 << 4); DDRD &= ~(1 << 4); break;
730         case 5: PORTD |= (1 << 5); DDRD &= ~(1 << 5); break;
731
732 #ifdef ALL_D
733
734         case 6: PORTD |= (1 << 6); break;
735         case 7: PORTD |= (1 << 7); break;
736
737         case 8:  PORTC |= (1 << 0); break;
738         case 9:  PORTC |= (1 << 1); break;
739         case 10: PORTC |= (1 << 2); break;
740         case 11: PORTC |= (1 << 3); break;
741         case 12: PORTC |= (1 << 4); break;
742         case 13: PORTC |= (1 << 5); break;
743         case 14: PORTC |= (1 << 6); break;
744         case 15: PORTC |= (1 << 7); break;
745
746         case 16: PORTE |= (1 << 0); break;
747         case 17: PORTE |= (1 << 1); break;
748
749 #else
750 #ifdef SHORT_D
751
752         case 6: PORTE |= (1 << 0); break;
753         case 7: PORTE |= (1 << 1); break;
754
755         case 8:  PORTC |= (1 << 0); break;
756         case 9:  PORTC |= (1 << 1); break;
757         case 10: PORTC |= (1 << 2); break;
758         case 11: PORTC |= (1 << 3); break;
759         case 12: PORTC |= (1 << 4); break;
760         case 13: PORTC |= (1 << 5); break;
761         case 14: PORTC |= (1 << 6); break;
762         case 15: PORTC |= (1 << 7); break;
763
764 #else
765 #ifdef SHORT_C
766
767         case 6: PORTD |= (1 << 6); DDRD &= ~(1 << 6); break;
768         case 7: PORTD |= (1 << 7); DDRD &= ~(1 << 7); break;
769
770         case 8: PORTE |= (1 << 0); DDRE &= ~(1 << 0); break;
771         case 9: PORTE |= (1 << 1); DDRE &= ~(1 << 1); break;
772
773         case 10:  PORTC |= (1 << 0); DDRC &= ~(1 << 0); break;
774         case 11:  PORTC |= (1 << 1); DDRC &= ~(1 << 1); break;
775         case 12: PORTC |= (1 << 2); DDRC &= ~(1 << 2); break;
776         case 13: PORTC |= (1 << 3); DDRC &= ~(1 << 3); break;
777         case 14: PORTC |= (1 << 4); DDRC &= ~(1 << 4); break;
778         case 15: PORTC |= (1 << 5); DDRC &= ~(1 << 5); break;
779
780         case 16: PORTC |= (1 << 6); DDRC &= ~(1 << 6); break;
781         case 17: PORTC |= (1 << 7); DDRC &= ~(1 << 7); break;
782
783 #endif
784 #endif
785 #endif
786
787         default:
788                 break;
789         }
790
791 #endif
792
793
794 }
795
796
797 inline uint16_t getADC(void)
798 {
799         ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
800
801         //wait for last read to complete.
802         while ( !( ADCSRA & (1 << ADIF) ) );
803
804         return ADC; // return sample
805 }
806
807
808 int sampleColumn_8x( uint8_t column, uint16_t * buffer )
809 {
810         // ensure all probe lines are driven low, and chill for recovery delay.
811         ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions
812
813         PORTC &= ~C_MASK;
814         PORTD &= ~D_MASK;
815         PORTE &= ~E_MASK;
816
817         PORTF = 0;
818         DDRF  = 0;
819
820         recovery(OFF);
821         strobe_w(column);
822
823         hold_sample(OFF);
824         SET_FULL_MUX(0);
825
826         for ( uint8_t i = 0; i < STROBE_SETTLE; ++i ) { getADC(); }
827
828         hold_sample(ON);
829
830 #undef MUX_SETTLE
831
832 #if (MUX_SETTLE)
833         for ( uint8_t mux = 0; mux < 8; ++mux )
834         {
835                 SET_FULL_MUX(mux); // our sample will use this
836
837                 // wait for mux to settle.
838                 for ( uint8_t i = 0; i < MUX_SETTLE; ++i ) { getADC(); }
839
840                 // retrieve current read.
841                 buffer[mux] = getADC();
842         }
843 #else
844         uint8_t mux = 0;
845         SET_FULL_MUX(mux);
846         getADC(); // throw away; unknown mux.
847         do {
848                 SET_FULL_MUX(mux + 1); // our *next* sample will use this
849
850                 // retrieve current read.
851                 buffer[mux] = getADC();
852                 mux++;
853
854         } while (mux < 8);
855
856 #endif
857         hold_sample(OFF);
858         recovery(ON);
859
860         // turn off adc.
861         ADCSRA &= ~(1 << ADEN);
862
863         // pull all columns' strobe-lines low.
864         DDRC |= C_MASK;
865         DDRD |= D_MASK;
866         DDRE |= E_MASK;
867
868         PORTC &= ~C_MASK;
869         PORTD &= ~D_MASK;
870         PORTE &= ~E_MASK;
871
872         return 0;
873 }
874
875
876 int sampleColumn( uint8_t column )
877 {
878         int rval = 0;
879
880         rval = sampleColumn_8x( column, samples + SAMPLE_OFFSET );
881
882 #if (BUMP_DETECTION)
883         for ( uint8_t i = 0; i < 8; ++i )
884         {
885                 if ( samples[SAMPLE_OFFSET + i] - adc_mux_averages[i] > BUMP_THRESHOLD )
886                 {
887                         // was a hump
888                         _delay_us(BUMP_REST_US);
889                         rval++;
890                         error = 0x50;
891                         error_data = samples[SAMPLE_OFFSET +i]; //  | ((uint16_t)i << 8);
892                         return rval;
893                 }
894         }
895 #endif
896
897         return rval;
898 }
899
900
901 uint8_t testColumn( uint8_t strobe )
902 {
903         uint8_t column = 0;
904         uint8_t bit = 1;
905         for ( uint8_t i = 0; i < MUXES_COUNT; ++i )
906         {
907                 uint16_t delta = keys_averages[(strobe << MUXES_COUNT_XSHIFT) + i];
908
909                 if ( (db_sample = samples[SAMPLE_OFFSET + i] >> 1) > (db_threshold = threshold) + (db_delta = delta) )
910                 {
911                         column |= bit;
912                 }
913
914 #ifdef THRESHOLD_VERIFICATION
915                 if ( db_sample > 0xA0 )
916                 {
917                         printHex( db_sample );
918                         print(" : ");
919                         printHex( db_threshold );
920                         print(" : ");
921                         printHex( db_delta );
922                         print(" :: ");
923                         printHex( column );
924                         print(" : ");
925                         printHex( strobe );
926                         print(NL);
927                 }
928 #endif
929
930                 bit <<= 1;
931         }
932         return column;
933 }
934
935
936 void dump(void) {
937
938 #ifdef DEBUG_FULL_SAMPLES_AVERAGES
939         // we don't want to debug-out during the measurements.
940         if ( !dump_count )
941         {
942                 // Averages currently set per key
943                 for ( int i = 0; i < KEY_COUNT; ++i )
944                 {
945                         if ( !(i & 0x0f) )
946                         {
947                                 print("\n");
948                         }
949                         else if ( !(i & 0x07) )
950                         {
951                                 print("  ");
952                         }
953
954                         print(" ");
955                         printHex( keys_averages[i] );
956                 }
957
958                 print("\n");
959
960                 // Previously read full ADC scans?
961                 for ( int i = 0; i< KEY_COUNT; ++i)
962                 {
963                         if ( !(i & 0x0f) )
964                         {
965                                 print("\n");
966                         }
967                         else if ( !(i & 0x07) )
968                         {
969                                 print("  ");
970                         }
971
972                         print(" ");
973                         printHex(full_samples[i]);
974                 }
975         }
976 #endif
977
978 #ifdef DEBUG_STROBE_SAMPLES_AVERAGES
979         // Per strobe information
980         uint8_t cur_strober = ze_strober;
981         print("\n");
982
983         printHex(cur_strober);
984
985         // Previously read ADC scans on current strobe
986         print(" :");
987         for ( uint8_t i = 0; i < MUXES_COUNT; ++i )
988         {
989                 print(" ");
990                 printHex(full_samples[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
991         }
992
993         // Averages current set on current strobe
994         print(" :");
995
996         for ( uint8_t i = 0; i < MUXES_COUNT; ++i )
997         {
998                 print(" ");
999                 printHex(keys_averages[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
1000         }
1001
1002 #endif
1003
1004 #ifdef DEBUG_DELTA_SAMPLE_THRESHOLD
1005         print("\n");
1006         printHex( db_delta );
1007         print(" ");
1008         printHex( db_sample );
1009         print(" ");
1010         printHex( db_threshold );
1011         print(" ");
1012         printHex( column );
1013 #endif
1014
1015 #ifdef DEBUG_USB_KEYMAP
1016         print("\n      ");
1017
1018         // Current keymap values
1019         for ( uint8_t i = 0; i < STROBE_LINES; ++i )
1020         {
1021                 printHex(cur_keymap[i]);
1022                 print(" ");
1023         }
1024 #endif
1025
1026         ze_strober++;
1027         ze_strober &= 0xf;
1028
1029         dump_count++;
1030         dump_count &= 0x0f;
1031 }
1032