]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/DPH/scan_loop.c
Major code cleanup and preparation for PartialMap Macro Module
[kiibohd-controller.git] / Scan / DPH / scan_loop.c
1 /* Copyright (C) 2011-2013 by Joseph Makuch
2  * Additions by Jacob Alexander (2013-2014)
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 450 // As measured from the Teensy ADC pin
36 #define THRESHOLD_MV (MAX_PRESS_DELTA_MV >> 1)
37 //(2560 / (0x3ff/2)) ~= 5
38 #define MV_PER_ADC 5
39 #define THRESHOLD (THRESHOLD_MV / MV_PER_ADC)
40
41 #define STROBE_SETTLE 1
42
43 #define TEST_KEY_STROBE (0x05)
44 #define TEST_KEY_MASK (1 << 0)
45
46 #define ADHSM 7
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 #define ADLAR_MASK (1 << ADLAR)
54
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 // full muxmask
62 #define FULL_MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2) | (1 << MUX3) | (1 << MUX4))
63
64 // F0-f7 pins only muxmask.
65 #define MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2))
66
67 // Strobe Masks
68 #define D_MASK (0xff)
69 #define E_MASK (0x03)
70 #define C_MASK (0xff)
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 // Max number of strobes supported by the hardware
78 // Strobe lines are detected at startup, extra strobes cause anomalies like phantom keypresses
79 #define MAX_STROBES 18
80
81 // Number of consecutive samples required to pass debounce
82 #define DEBOUNCE_THRESHOLD 5
83
84 #define MUXES_COUNT 8
85 #define MUXES_COUNT_XSHIFT 3
86
87 #define WARMUP_LOOPS ( 1024 )
88 #define WARMUP_STOP (WARMUP_LOOPS - 1)
89
90 #define SAMPLE_CONTROL 3
91
92 #define KEY_COUNT ((MAX_STROBES) * (MUXES_COUNT))
93
94 #define RECOVERY_CONTROL 1
95 #define RECOVERY_SOURCE  0
96 #define RECOVERY_SINK    2
97
98 #define ON  1
99 #define OFF 0
100
101 // mix in 1/4 of the current average to the running average. -> (@mux_mix = 2)
102 #define MUX_MIX 2
103
104 #define IDLE_COUNT_MASK 0xff
105 #define IDLE_COUNT_SHIFT 8
106
107 // av = (av << shift) - av + sample; av >>= shift
108 // e.g. 1 -> (av + sample) / 2 simple average of new and old
109 //      2 -> (3 * av + sample) / 4 i.e. 3:1 mix of old to new.
110 //      3 -> (7 * av + sample) / 8 i.e. 7:1 mix of old to new.
111 #define KEYS_AVERAGES_MIX_SHIFT 3
112
113
114
115 // ----- Macros -----
116
117 // Select mux
118 #define SET_FULL_MUX(X) ((ADMUX) = (((ADMUX) & ~(FULL_MUX_MASK)) | ((X) & (FULL_MUX_MASK))))
119
120
121
122 // ----- Variables -----
123
124 // Buffer used to inform the macro processing module which keys have been detected as pressed
125 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
126 volatile uint8_t KeyIndex_BufferUsed;
127
128
129 // TODO dfj variables...needs cleaning up and commenting
130
131 // Variables used to calculate the starting sense value (averaging)
132 uint32_t full_avg = 0;
133 uint32_t high_avg = 0;
134 uint32_t  low_avg = 0;
135
136 uint8_t  high_count = 0;
137 uint8_t   low_count = 0;
138
139
140 uint8_t ze_strober = 0;
141
142 uint16_t samples[MUXES_COUNT];
143
144 uint8_t cur_keymap[MAX_STROBES];
145
146 uint8_t keymap_change;
147
148 uint16_t threshold = THRESHOLD;
149
150 uint8_t column = 0;
151
152 uint16_t keys_averages_acc[KEY_COUNT];
153 uint16_t keys_averages    [KEY_COUNT];
154 uint8_t  keys_debounce    [KEY_COUNT]; // Contains debounce statistics
155 uint8_t  keys_problem     [KEY_COUNT]; // Marks keys that should be ignored (determined by averaging at startup)
156
157 uint8_t full_samples[KEY_COUNT];
158
159 // TODO: change this to 'booting', then count down.
160 uint16_t boot_count = 0;
161
162 uint16_t idle_count = 0;
163 uint8_t idle = 1;
164
165 uint8_t error = 0;
166 uint16_t error_data = 0;
167
168 uint8_t total_strobes = MAX_STROBES;
169 uint8_t strobe_map[MAX_STROBES];
170
171 uint8_t dump_count = 0;
172
173
174
175 // ----- Function Declarations -----
176
177 void dump( void );
178
179 void recovery( uint8_t on );
180
181 int sampleColumn( uint8_t column );
182
183 void capsense_scan( void );
184
185 void setup_ADC( void );
186
187 void strobe_w( uint8_t strobe_num );
188
189 uint8_t testColumn( uint8_t strobe );
190
191
192
193 // ----- Functions -----
194
195 // Initial setup for cap sense controller
196 inline void Scan_setup()
197 {
198         // TODO dfj code...needs cleanup + commenting...
199         setup_ADC();
200
201         DDRC  = C_MASK;
202         PORTC = 0;
203         DDRD  = D_MASK;
204         PORTD = 0;
205         DDRE  = E_MASK;
206         PORTE = 0 ;
207
208         // Hardcoded strobes for debugging
209         // Strobes start at 0 and go to 17 (18), not all Model Fs use all of the available strobes
210         // The single row ribbon connector Model Fs only have a max of 16 strobes
211 #define KISHSAVER_STROBE
212 //#define KISHSAVER_OLD_STROBE
213 //#define TERMINAL_6110668_OLD_STROBE
214 //#define UNSAVER_OLD_STROBE
215 #ifdef KISHSAVER_OLD_STROBE
216         total_strobes = 9;
217
218         strobe_map[0] = 2; // Kishsaver doesn't use strobe 0 and 1
219         strobe_map[1] = 3;
220         strobe_map[2] = 4;
221         strobe_map[3] = 5;
222         strobe_map[4] = 6;
223         strobe_map[5] = 7;
224         strobe_map[6] = 8;
225         strobe_map[7] = 9;
226         strobe_map[8] = 15; // Test point strobe (3 test points, sense 1, 4, 5)
227 #elif defined(KISHSAVER_STROBE)
228         total_strobes = 9;
229
230         strobe_map[0] = 15; // Kishsaver doesn't use strobe 0 and 1
231         strobe_map[1] = 14;
232         strobe_map[2] = 13;
233         strobe_map[3] = 12;
234         strobe_map[4] = 11;
235         strobe_map[5] = 10;
236         strobe_map[6] = 9;
237         strobe_map[7] = 8;
238         strobe_map[8] = 2; // Test point strobe (3 test points, sense 1, 4, 5)
239 #elif defined(TERMINAL_6110668_OLD_STROBE)
240         total_strobes = 16;
241
242         strobe_map[0] = 0;
243         strobe_map[1] = 1;
244         strobe_map[2] = 2;
245         strobe_map[3] = 3;
246         strobe_map[4] = 4;
247         strobe_map[5] = 5;
248         strobe_map[6] = 6;
249         strobe_map[7] = 7;
250         strobe_map[8] = 8;
251         strobe_map[9] = 9;
252         strobe_map[10] = 10;
253         strobe_map[11] = 11;
254         strobe_map[12] = 12;
255         strobe_map[13] = 13;
256         strobe_map[14] = 14;
257         strobe_map[15] = 15;
258 #elif defined(UNSAVER_OLD_STROBE)
259         total_strobes = 14;
260
261         strobe_map[0] = 0;
262         strobe_map[1] = 1;
263         strobe_map[2] = 2;
264         strobe_map[3] = 3;
265         strobe_map[4] = 4;
266         strobe_map[5] = 5;
267         strobe_map[6] = 6;
268         strobe_map[7] = 7;
269         strobe_map[8] = 8;
270         strobe_map[9] = 9;
271         strobe_map[10] = 10;
272         strobe_map[11] = 11;
273         strobe_map[12] = 12;
274         strobe_map[13] = 13;
275 #else
276         // Strobe detection
277         // TODO
278 #endif
279
280         // TODO all this code should probably be in Scan_resetKeyboard
281         for ( int i = 0; i < total_strobes; ++i)
282         {
283                 cur_keymap[i] = 0;
284         }
285
286         // Reset debounce table
287         for ( int i = 0; i < KEY_COUNT; ++i )
288         {
289                 keys_debounce[i] = 0;
290         }
291
292         // Warm things up a bit before we start collecting data, taking real samples.
293         for ( uint8_t i = 0; i < total_strobes; ++i )
294         {
295                 sampleColumn( strobe_map[i] );
296         }
297
298
299         // Reset the keyboard before scanning, we might be in a wierd state
300         // Also sets the KeyIndex_BufferUsed to 0
301         scan_resetKeyboard();
302 }
303
304
305 // Main Detection Loop
306 // This is where the important stuff happens
307 inline uint8_t Scan_loop()
308 {
309         capsense_scan();
310
311         // Error case, should not occur in normal operation
312         if ( error )
313         {
314                 erro_msg("Problem detected... ");
315
316                 // Keymap scan debug
317                 for ( uint8_t i = 0; i < total_strobes; ++i )
318                 {
319                         printHex(cur_keymap[strobe_map[i]]);
320                         print(" ");
321                 }
322
323                 print(" : ");
324                 printHex(error);
325                 error = 0;
326                 print(" : ");
327                 printHex(error_data);
328                 error_data = 0;
329
330                 // Display keymaps and other debug information if warmup completede
331                 if ( boot_count >= WARMUP_LOOPS )
332                 {
333                         dump();
334                 }
335         }
336
337
338         // Return non-zero if macro and USB processing should be delayed
339         // Macro processing will always run if returning 0
340         // USB processing only happens once the USB send timer expires, if it has not, Scan_loop will be called
341         //  after the macro processing has been completed
342         return 0;
343 }
344
345
346 // Signal KeyIndex_Buffer that it has been properly read
347 // NOTE: Only really required for implementing "tricks" in converters for odd protocols
348 void Scan_finishedWithBuffer( uint8_t sentKeys )
349 {
350         // Convenient place to clear the KeyIndex_Buffer
351         KeyIndex_BufferUsed = 0;
352         return;
353 }
354
355
356 // Signal KeyIndex_Buffer that it has been properly read and sent out by the USB module
357 // NOTE: Only really required for implementing "tricks" in converters for odd protocols
358 void Scan_finishedWithUSBBuffer( uint8_t sentKeys )
359 {
360         return;
361 }
362
363
364 inline void capsense_scan()
365 {
366         // Accumulated average used for the next scan
367         uint32_t cur_full_avg = 0;
368         uint32_t cur_high_avg = 0;
369
370         // Reset average counters
371         low_avg = 0;
372         low_count = 0;
373
374         high_count = 0;
375
376         // Scan each of the mapped strobes in the matrix
377         for ( uint8_t strober = 0; strober < total_strobes; ++strober )
378         {
379                 uint8_t map_strobe = strobe_map[strober];
380
381                 uint8_t tries = 1;
382                 while ( tries++ && sampleColumn( map_strobe ) ) { tries &= 0x7; } // don't waste this one just because the last one was poop.
383
384                 // Only process sense data if warmup is finished
385                 if ( boot_count >= WARMUP_LOOPS )
386                 {
387                         column = testColumn( map_strobe );
388
389                         idle |= column; // if column has any pressed keys, then we are not idle.
390
391                         // TODO Is this needed anymore? Really only helps debug -HaaTa
392                         if( column != cur_keymap[map_strobe] && ( boot_count >= WARMUP_LOOPS ) )
393                         {
394                                 cur_keymap[map_strobe] = column;
395                                 keymap_change = 1;
396                         }
397
398                         idle |= keymap_change; // if any keys have changed inc. released, then we are not idle.
399                 }
400
401                 if ( error == 0x50 )
402                 {
403                         error_data |= (((uint16_t)map_strobe) << 12);
404                 }
405
406                 uint8_t strobe_line = map_strobe << MUXES_COUNT_XSHIFT;
407                 for ( int i = 0; i < MUXES_COUNT; ++i )
408                 {
409                         // discard sketchy low bit, and meaningless high bits.
410                         uint8_t sample = samples[i] >> 1;
411                         full_samples[strobe_line + i] = sample;
412                         keys_averages_acc[strobe_line + i] += sample;
413                 }
414
415                 // Accumulate 3 total averages (used for determining starting average during warmup)
416                 //     full_avg - Average of all sampled lines on the previous scan set
417                 // cur_full_avg - Average of all sampled lines for this scan set
418                 //     high_avg - Average of all sampled lines above full_avg on the previous scan set
419                 // cur_high_avg - Average of all sampled lines above full_avg
420                 //      low_avg - Average of all sampled lines below or equal to full_avg
421                 if ( boot_count < WARMUP_LOOPS )
422                 {
423                         for ( uint8_t i = 0; i < MUXES_COUNT; ++i )
424                         {
425                                 uint8_t sample = samples[i] >> 1;
426
427                                 // Sample is high, add it to high avg
428                                 if ( sample > full_avg )
429                                 {
430                                         high_count++;
431                                         cur_high_avg += sample;
432                                 }
433                                 // Sample is low, add it to low avg
434                                 else
435                                 {
436                                         low_count++;
437                                         low_avg += sample;
438                                 }
439
440                                 // If sample is higher than previous high_avg, then mark as "problem key"
441                                 keys_problem[strobe_line + i] = sample > high_avg ? sample : 0;
442
443                                 // Prepare for next average
444                                 cur_full_avg += sample;
445                         }
446                 }
447         } // for strober
448
449         // Update total sense average (only during warm-up)
450         if ( boot_count < WARMUP_LOOPS )
451         {
452                 full_avg = cur_full_avg / (total_strobes * MUXES_COUNT);
453                 high_avg = cur_high_avg / high_count;
454                 low_avg /= low_count;
455
456                 // Update the base average value using the low_avg (best chance of not ignoring a keypress)
457                 for ( int i = 0; i < KEY_COUNT; ++i )
458                 {
459                         keys_averages[i] = low_avg;
460                         keys_averages_acc[i] = low_avg;
461                 }
462         }
463
464 #ifdef VERIFY_TEST_PAD
465         // verify test key is not down.
466         if ( ( cur_keymap[TEST_KEY_STROBE] & TEST_KEY_MASK ) )
467         {
468                 error = 0x05;
469                 error_data = cur_keymap[TEST_KEY_STROBE] << 8;
470                 error_data += full_samples[TEST_KEY_STROBE * 8];
471         }
472 #endif
473
474         /** aggregate if booting, or if idle;
475          * else, if not booting, check for dirty USB.
476          * */
477
478         idle_count++;
479         idle_count &= IDLE_COUNT_MASK;
480
481         // Warm up voltage references
482         if ( boot_count < WARMUP_LOOPS )
483         {
484                 boot_count++;
485
486                 switch ( boot_count )
487                 {
488                 // First loop
489                 case 1:
490                         // Show msg at first iteration only
491                         info_msg("Warming up the voltage references");
492                         break;
493                 // Middle iterations
494                 case 300:
495                 case 600:
496                 case 900:
497                 case 1200:
498                         print(".");
499                         break;
500                 // Last loop
501                 case WARMUP_STOP:
502                         print("\n");
503                         info_msg("Warmup finished using ");
504                         printInt16( WARMUP_LOOPS );
505                         print(" iterations\n");
506
507                         // Display the final calculated averages of all the sensed strobes
508                         info_msg("Full average (");
509                         printInt8( total_strobes * MUXES_COUNT );
510                         print("): ");
511                         printHex( full_avg );
512
513                         print("  High average (");
514                         printInt8( high_count );
515                         print("): ");
516                         printHex( high_avg );
517
518                         print("  Low average (");
519                         printInt8( low_count );
520                         print("): ");
521                         printHex( low_avg );
522                         print("\n");
523
524                         // Display problem keys, and the sense value at the time
525                         for ( uint8_t key = 0; key < KEY_COUNT; key++ )
526                         {
527                                 if ( keys_problem[key] )
528                                 {
529                                         warn_msg("Problem key detected: ");
530                                         printHex( key );
531                                         print(" (");
532                                         printHex( keys_problem[key] );
533                                         print(")\n");
534                                 }
535                         }
536
537                         info_print("If problem keys were detected, and were being held down, they will be reset as soon as let go");
538                         break;
539                 }
540         }
541         else
542         {
543                 // Reset accumulators and idle flag/counter
544                 if ( keymap_change )
545                 {
546                         for ( uint8_t c = 0; c < KEY_COUNT; ++c ) { keys_averages_acc[c] = 0; }
547                         idle_count = 0;
548                         idle = 0;
549
550                         keymap_change = 0;
551                 }
552
553                 if ( !idle_count )
554                 {
555                         if( idle )
556                         {
557                                 // aggregate
558                                 for ( uint8_t i = 0; i < KEY_COUNT; ++i )
559                                 {
560                                         uint16_t acc = keys_averages_acc[i] >> IDLE_COUNT_SHIFT;
561                                         uint32_t av = keys_averages[i];
562
563                                         av = (av << KEYS_AVERAGES_MIX_SHIFT) - av + acc;
564                                         av >>= KEYS_AVERAGES_MIX_SHIFT;
565
566                                         keys_averages[i] = av;
567                                         keys_averages_acc[i] = 0;
568                                 }
569                         }
570
571                         if ( boot_count >= WARMUP_LOOPS )
572                         {
573                                 dump();
574                         }
575                 }
576
577         }
578 }
579
580
581 void setup_ADC()
582 {
583         // disable adc digital pins.
584         DIDR1 |= (1 << AIN0D) | (1<<AIN1D); // set disable on pins 1,0.
585         DDRF = 0x0;
586         PORTF = 0x0;
587         uint8_t mux = 0 & 0x1f; // 0 == first. // 0x1e = 1.1V ref.
588
589         // 0 = external aref 1,1 = 2.56V internal ref
590         uint8_t aref = ((1 << REFS1) | (1 << REFS0)) & ((1 << REFS1) | (1 << REFS0));
591         uint8_t adate = (1 << ADATE) & (1 << ADATE); // trigger enable
592         uint8_t trig = 0 & ((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2)); // 0 = free running
593         // ps2, ps1 := /64 ( 2^6 ) ps2 := /16 (2^4), ps1 := 4, ps0 :=2, PS1,PS0 := 8 (2^8)
594         uint8_t prescale = ( ((PRESCALE) << PRESCALE_SHIFT) & PRESCALE_MASK ); // 001 == 2^1 == 2
595         uint8_t hispeed = (1 << ADHSM);
596         uint8_t en_mux = (1 << ACME);
597
598         ADCSRA = (1 << ADEN) | prescale; // ADC enable
599
600         // select ref.
601         //ADMUX |= ((1 << REFS1) | (1 << REFS0)); // 2.56 V internal.
602         //ADMUX |= ((1 << REFS0) ); // Vcc with external cap.
603         //ADMUX &= ~((1 << REFS1) | (1 << REFS0)); // 0,0 : aref.
604         ADMUX = aref | mux | ADLAR_BITS;
605
606         // set free-running
607         ADCSRA |= adate; // trigger enable
608         ADCSRB  = en_mux | hispeed | trig | (ADCSRB & ~((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2))); // trigger select free running
609
610         ADCSRA |= (1 << ADEN); // ADC enable
611         ADCSRA |= (1 << ADSC); // start conversions q
612 }
613
614
615 void recovery( uint8_t on )
616 {
617         DDRB  |=  (1 << RECOVERY_CONTROL);
618         PORTB &= ~(1 << RECOVERY_SINK);   // SINK always zero
619         DDRB  &= ~(1 << RECOVERY_SOURCE); // SOURCE high imp
620
621         if ( on )
622         {
623                 // set strobes to sink to gnd.
624                 DDRC |= C_MASK;
625                 DDRD |= D_MASK;
626                 DDRE |= E_MASK;
627
628                 PORTC &= ~C_MASK;
629                 PORTD &= ~D_MASK;
630                 PORTE &= ~E_MASK;
631
632                 DDRB  |= (1 << RECOVERY_SINK);   // SINK pull
633                 PORTB |= (1 << RECOVERY_CONTROL);
634                 PORTB |= (1 << RECOVERY_SOURCE); // SOURCE high
635                 DDRB  |= (1 << RECOVERY_SOURCE);
636         }
637         else
638         {
639                 PORTB &= ~(1 << RECOVERY_CONTROL);
640                 DDRB  &= ~(1 << RECOVERY_SOURCE);
641                 PORTB &= ~(1 << RECOVERY_SOURCE); // SOURCE low
642                 DDRB  &= ~(1 << RECOVERY_SINK);   // SINK high-imp
643         }
644 }
645
646
647 void hold_sample( uint8_t on )
648 {
649         if ( !on )
650         {
651                 PORTB |= (1 << SAMPLE_CONTROL);
652                 DDRB  |= (1 << SAMPLE_CONTROL);
653         }
654         else
655         {
656                 DDRB  |=  (1 << SAMPLE_CONTROL);
657                 PORTB &= ~(1 << SAMPLE_CONTROL);
658         }
659 }
660
661
662 void strobe_w( uint8_t strobe_num )
663 {
664         PORTC &= ~(C_MASK);
665         PORTD &= ~(D_MASK);
666         PORTE &= ~(E_MASK);
667
668         // Strobe table
669         // Not all strobes are used depending on which are detected
670         switch ( strobe_num )
671         {
672
673         case 0:  PORTD |= (1 << 0); break;
674         case 1:  PORTD |= (1 << 1); break;
675         case 2:  PORTD |= (1 << 2); break;
676         case 3:  PORTD |= (1 << 3); break;
677         case 4:  PORTD |= (1 << 4); break;
678         case 5:  PORTD |= (1 << 5); break;
679         case 6:  PORTD |= (1 << 6); break;
680         case 7:  PORTD |= (1 << 7); break;
681
682         case 8:  PORTE |= (1 << 0); break;
683         case 9:  PORTE |= (1 << 1); break;
684
685         case 10: PORTC |= (1 << 0); break;
686         case 11: PORTC |= (1 << 1); break;
687         case 12: PORTC |= (1 << 2); break;
688         case 13: PORTC |= (1 << 3); break;
689         case 14: PORTC |= (1 << 4); break;
690         case 15: PORTC |= (1 << 5); break;
691         case 16: PORTC |= (1 << 6); break;
692         case 17: PORTC |= (1 << 7); break;
693
694         default:
695                 break;
696         }
697 }
698
699
700 inline uint16_t getADC(void)
701 {
702         ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
703
704         //wait for last read to complete.
705         while ( !( ADCSRA & (1 << ADIF) ) );
706
707         return ADC; // return sample
708 }
709
710
711 int sampleColumn_8x( uint8_t column, uint16_t * buffer )
712 {
713         // ensure all probe lines are driven low, and chill for recovery delay.
714         ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions
715
716         PORTC &= ~C_MASK;
717         PORTD &= ~D_MASK;
718         PORTE &= ~E_MASK;
719
720         PORTF = 0;
721         DDRF  = 0;
722
723         recovery( OFF );
724         strobe_w( column );
725
726         hold_sample( OFF );
727         SET_FULL_MUX( 0 );
728
729         // Allow strobes to settle
730         for ( uint8_t i = 0; i < STROBE_SETTLE; ++i ) { getADC(); }
731
732         hold_sample( ON );
733
734         uint8_t mux = 0;
735         SET_FULL_MUX( mux );
736         getADC(); // throw away; unknown mux.
737         do {
738                 SET_FULL_MUX( mux + 1 ); // our *next* sample will use this
739
740                 // retrieve current read.
741                 buffer[mux] = getADC();
742                 mux++;
743
744         } while ( mux < 8 );
745
746         hold_sample( OFF );
747         recovery( ON );
748
749         // turn off adc.
750         ADCSRA &= ~(1 << ADEN);
751
752         // pull all columns' strobe-lines low.
753         DDRC |= C_MASK;
754         DDRD |= D_MASK;
755         DDRE |= E_MASK;
756
757         PORTC &= ~C_MASK;
758         PORTD &= ~D_MASK;
759         PORTE &= ~E_MASK;
760
761         return 0;
762 }
763
764
765 int sampleColumn( uint8_t column )
766 {
767         int rval = 0;
768
769         rval = sampleColumn_8x( column, samples );
770
771         return rval;
772 }
773
774
775 uint8_t testColumn( uint8_t strobe )
776 {
777         uint16_t db_delta = 0;
778         uint8_t  db_sample = 0;
779         uint16_t db_threshold = 0;
780
781         uint8_t column = 0;
782         uint8_t bit = 1;
783
784         for ( uint8_t mux = 0; mux < MUXES_COUNT; ++mux )
785         {
786                 uint16_t delta = keys_averages[(strobe << MUXES_COUNT_XSHIFT) + mux];
787
788                 uint8_t key = (strobe << MUXES_COUNT_XSHIFT) + mux;
789
790                 // Check if this is a bad key (e.g. test point, or non-existent key)
791                 if ( keys_problem[key] )
792                 {
793                         // If the sample value of the problem key goes below full_avg (overall initial average)
794                         //  re-enable the key
795                         if ( (db_sample = samples[mux] >> 1) < full_avg )
796                         {
797                                 info_msg("Re-enabling problem key: ");
798                                 printHex( key );
799                                 print("\n");
800
801                                 keys_problem[key] = 0;
802                         }
803                         // Otherwise, don't waste any more cycles processing the problem key
804                         else
805                         {
806                                 continue;
807                         }
808                 }
809
810                 // Keypress detected
811                 //  db_sample (uint8_t), discard meaningless high bit, and garbage low bit
812                 if ( (db_sample = samples[mux] >> 1) > (db_threshold = threshold) + (db_delta = delta) )
813                 {
814                         column |= bit;
815
816                         // Only register keypresses once the warmup is complete, or not enough debounce info
817                         if ( keys_debounce[key] <= DEBOUNCE_THRESHOLD )
818                         {
819                                 // Add to the Macro processing buffer if debounce criteria met
820                                 // Automatically handles converting to a USB code and sending off to the PC
821                                 if ( keys_debounce[key] == DEBOUNCE_THRESHOLD )
822                                 {
823 //#define KEYSCAN_DEBOUNCE_DEBUG
824 #ifdef KEYSCAN_DEBOUNCE_DEBUG
825                                         // Debug message
826                                         print("0x");
827                                         printHex_op( key, 2 );
828                                         print(" ");
829 #endif
830
831                                         // Only add the key to the buffer once
832                                         // NOTE: Buffer can easily handle multiple adds, just more efficient
833                                         //        and nicer debug messages :P
834                                         //Macro_bufferAdd( key );
835                                 }
836
837                                 keys_debounce[key]++;
838
839 #define KEYSCAN_THRESHOLD_DEBUG
840 #ifdef KEYSCAN_THRESHOLD_DEBUG
841                                 // Debug message
842                                 // <key> [<strobe>:<mux>] : <sense val> : <delta + threshold> : <margin>
843                                 dbug_msg("0x");
844                                 printHex_op( key, 2 );
845                                 print(" [");
846                                 printInt8( strobe );
847                                 print(":");
848                                 printInt8( mux );
849                                 print("] : ");
850                                 printHex( db_sample ); // Sense
851                                 print(" : ");
852                                 printHex( db_threshold );
853                                 print("+");
854                                 printHex( db_delta );
855                                 print("=");
856                                 printHex( db_threshold + db_delta ); // Sense compare
857                                 print(" : ");
858                                 printHex( db_sample - ( db_threshold + db_delta ) ); // Margin
859                                 print("\n");
860 #endif
861                         }
862                 }
863                 // Clear debounce entry if no keypress detected
864                 else
865                 {
866                         // If the key was previously pressed, remove from the buffer
867                         for ( uint8_t c = 0; c < KeyIndex_BufferUsed; c++ )
868                         {
869                                 // Key to release found
870                                 if ( KeyIndex_Buffer[c] == key )
871                                 {
872                                         // Shift keys from c position
873                                         for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
874                                                 KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
875
876                                         // Decrement Buffer
877                                         KeyIndex_BufferUsed--;
878
879                                         break;
880                                 }
881                         }
882
883
884                         // Clear debounce entry
885                         keys_debounce[key] = 0;
886                 }
887
888                 bit <<= 1;
889         }
890         return column;
891 }
892
893
894 void dump(void) {
895
896 #ifdef DEBUG_FULL_SAMPLES_AVERAGES
897         // we don't want to debug-out during the measurements.
898         if ( !dump_count )
899         {
900                 // Averages currently set per key
901                 for ( int i = 0; i < KEY_COUNT; ++i )
902                 {
903                         if ( !(i & 0x0f) )
904                         {
905                                 print("\n");
906                         }
907                         else if ( !(i & 0x07) )
908                         {
909                                 print("  ");
910                         }
911
912                         print(" ");
913                         printHex( keys_averages[i] );
914                 }
915
916                 print("\n");
917
918                 // Previously read full ADC scans?
919                 for ( int i = 0; i< KEY_COUNT; ++i)
920                 {
921                         if ( !(i & 0x0f) )
922                         {
923                                 print("\n");
924                         }
925                         else if ( !(i & 0x07) )
926                         {
927                                 print("  ");
928                         }
929
930                         print(" ");
931                         printHex(full_samples[i]);
932                 }
933         }
934 #endif
935
936 #ifdef DEBUG_STROBE_SAMPLES_AVERAGES
937         // Per strobe information
938         uint8_t cur_strober = ze_strober;
939         print("\n");
940
941         printHex(cur_strober);
942
943         // Previously read ADC scans on current strobe
944         print(" :");
945         for ( uint8_t i = 0; i < MUXES_COUNT; ++i )
946         {
947                 print(" ");
948                 printHex(full_samples[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
949         }
950
951         // Averages current set on current strobe
952         print(" :");
953
954         for ( uint8_t i = 0; i < MUXES_COUNT; ++i )
955         {
956                 print(" ");
957                 printHex(keys_averages[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
958         }
959
960 #endif
961
962 #ifdef DEBUG_USB_KEYMAP
963         print("\n      ");
964
965         // Current keymap values
966         for ( uint8_t i = 0; i < total_strobes; ++i )
967         {
968                 printHex(cur_keymap[i]);
969                 print(" ");
970         }
971 #endif
972
973         ze_strober++;
974         ze_strober &= 0xf;
975
976         dump_count++;
977         dump_count &= 0x0f;
978 }
979