]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/avr-capsense/scan_loop.c
Fixing the strobe count on the Kishsaver
[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 380
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 #define MUX_SETTLE 1
43
44 #define TEST_KEY_STROBE (0x05)
45 #define TEST_KEY_MASK (1 << 0)
46
47 #define ADHSM 7
48
49 #define RIGHT_JUSTIFY 0
50 #define LEFT_JUSTIFY (0xff)
51
52 // set left or right justification here:
53 #define JUSTIFY_ADC RIGHT_JUSTIFY
54 #define ADLAR_MASK (1 << ADLAR)
55
56 #ifdef JUSTIFY_ADC
57 #define ADLAR_BITS ((ADLAR_MASK) & (JUSTIFY_ADC))
58 #else // defaults to right justification.
59 #define ADLAR_BITS 0
60 #endif
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 // Strobe Masks
69 #define D_MASK (0xff)
70 #define E_MASK (0x03)
71 #define C_MASK (0xff)
72
73 // set ADC clock prescale
74 #define PRESCALE_MASK ((1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2))
75 #define PRESCALE_SHIFT (ADPS0)
76 #define PRESCALE 3
77
78 // Max number of strobes supported by the hardware
79 // Strobe lines are detected at startup, extra strobes cause anomalies like phantom keypresses
80 #define MAX_STROBES 18
81
82 // Number of consecutive samples required to pass debounce
83 #define DEBOUNCE_THRESHOLD 5
84
85 #define MUXES_COUNT 8
86 #define MUXES_COUNT_XSHIFT 3
87
88 #define WARMUP_LOOPS ( 1024 )
89 #define WARMUP_STOP (WARMUP_LOOPS - 1)
90
91 #define SAMPLES 10
92 #define SAMPLE_OFFSET ((SAMPLES) - MUXES_COUNT)
93 #define SAMPLE_CONTROL 3
94
95 // Starting average for keys, per key will adjust during runtime
96 // XXX - A better method is needed to choose this value (i.e. not experimental)
97 //       The ideal average is not always found for weak keys if this is set too high...
98 #define DEFAULT_KEY_BASE 0xB0
99
100 #define KEY_COUNT ((MAX_STROBES) * (MUXES_COUNT))
101
102 #define RECOVERY_CONTROL 1
103 #define RECOVERY_SOURCE  0
104 #define RECOVERY_SINK    2
105
106 #define ON  1
107 #define OFF 0
108
109 // mix in 1/4 of the current average to the running average. -> (@mux_mix = 2)
110 #define MUX_MIX 2
111
112 #define IDLE_COUNT_MASK 0xff
113 #define IDLE_COUNT_SHIFT 8
114
115 // av = (av << shift) - av + sample; av >>= shift
116 // e.g. 1 -> (av + sample) / 2 simple average of new and old
117 //      2 -> (3 * av + sample) / 4 i.e. 3:1 mix of old to new.
118 //      3 -> (7 * av + sample) / 8 i.e. 7:1 mix of old to new.
119 #define KEYS_AVERAGES_MIX_SHIFT 3
120
121
122
123 // ----- Macros -----
124
125 // Make sure we haven't overflowed the buffer
126 #define bufferAdd(byte) \
127                 if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
128                         KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte
129
130 // Select mux
131 #define SET_FULL_MUX(X) ((ADMUX) = (((ADMUX) & ~(FULL_MUX_MASK)) | ((X) & (FULL_MUX_MASK))))
132
133
134
135 // ----- Variables -----
136
137 // Buffer used to inform the macro processing module which keys have been detected as pressed
138 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
139 volatile uint8_t KeyIndex_BufferUsed;
140
141
142 // TODO dfj variables...needs cleaning up and commenting
143 volatile uint16_t full_av = 0;
144
145 uint8_t ze_strober = 0;
146
147 uint16_t samples [SAMPLES];
148
149 uint8_t cur_keymap[MAX_STROBES];
150
151 uint8_t keymap_change;
152
153 uint16_t threshold = THRESHOLD;
154
155 uint8_t column = 0;
156
157 uint16_t keys_averages_acc[KEY_COUNT];
158 uint16_t keys_averages    [KEY_COUNT];
159 uint8_t  keys_debounce    [KEY_COUNT];
160
161 uint8_t full_samples[KEY_COUNT];
162
163 // TODO: change this to 'booting', then count down.
164 uint16_t boot_count = 0;
165
166 uint16_t idle_count = 0;
167 uint8_t idle = 1;
168
169 uint8_t error = 0;
170 uint16_t error_data = 0;
171
172 uint8_t total_strobes = MAX_STROBES;
173 uint8_t strobe_map[MAX_STROBES];
174
175 uint8_t dump_count = 0;
176
177 uint16_t db_delta = 0;
178 uint8_t  db_sample = 0;
179 uint16_t db_threshold = 0;
180
181
182
183 // ----- Function Declarations -----
184
185 void dump( void );
186
187 void recovery( uint8_t on );
188
189 int sampleColumn( uint8_t column );
190
191 void capsense_scan( void );
192
193 void setup_ADC( void );
194
195 void strobe_w( uint8_t strobe_num );
196
197 uint8_t testColumn( uint8_t strobe );
198
199
200
201 // ----- Functions -----
202
203 // Initial setup for cap sense controller
204 inline void scan_setup()
205 {
206         // TODO dfj code...needs cleanup + commenting...
207         setup_ADC();
208
209         DDRC  = C_MASK;
210         PORTC = 0;
211         DDRD  = D_MASK;
212         PORTD = 0;
213         DDRE  = E_MASK;
214         PORTE = 0 ;
215
216         // Hardcoded strobes for debugging
217         // Strobes start at 0 and go to 17 (18), not all Model Fs use all of the available strobes
218         // The single row ribbon connector Model Fs only have a max of 16 strobes
219 #define KISHSAVER_STROBE
220 //#define TERMINAL_6110668_STROBE
221 //#define UNSAVER_STROBE
222 #ifdef KISHSAVER_STROBE
223         total_strobes = 8;
224         //total_strobes = 9;
225
226         strobe_map[0] = 2; // Kishsaver doesn't use strobe 0 and 1
227         strobe_map[1] = 3;
228         strobe_map[2] = 4;
229         strobe_map[3] = 5;
230         strobe_map[4] = 6;
231         strobe_map[5] = 7;
232         strobe_map[6] = 8;
233         strobe_map[7] = 9;
234         // XXX - Disabling for now, not sure how to deal with test points yet (without spamming the debug)
235         //strobe_map[9] = 15; // Test point strobe (3 test points, sense 1, 4, 5)
236 #elif defined(TERMINAL_6110668_STROBE)
237         total_strobes = 16;
238
239         strobe_map[0] = 0;
240         strobe_map[1] = 1;
241         strobe_map[2] = 2;
242         strobe_map[3] = 3;
243         strobe_map[4] = 4;
244         strobe_map[5] = 5;
245         strobe_map[6] = 6;
246         strobe_map[7] = 7;
247         strobe_map[8] = 8;
248         strobe_map[9] = 9;
249         strobe_map[10] = 10;
250         strobe_map[11] = 11;
251         strobe_map[12] = 12;
252         strobe_map[13] = 13;
253         strobe_map[14] = 14;
254         strobe_map[15] = 15;
255 #elif defined(UNSAVER_STROBE)
256         total_strobes = 14;
257
258         strobe_map[0] = 0;
259         strobe_map[1] = 1;
260         strobe_map[2] = 2;
261         strobe_map[3] = 3;
262         strobe_map[4] = 4;
263         strobe_map[5] = 5;
264         strobe_map[6] = 6;
265         strobe_map[7] = 7;
266         strobe_map[8] = 8;
267         strobe_map[9] = 9;
268         strobe_map[10] = 10;
269         strobe_map[11] = 11;
270         strobe_map[12] = 12;
271         strobe_map[13] = 13;
272 #else
273         // Strobe detection
274         // TODO
275 #endif
276
277         // TODO all this code should probably be in scan_resetKeyboard
278         for ( int i = 0; i < total_strobes; ++i)
279         {
280                 cur_keymap[i] = 0;
281         }
282
283         for ( int i = 0; i < KEY_COUNT; ++i )
284         {
285                 keys_averages[i] = DEFAULT_KEY_BASE;
286                 keys_averages_acc[i] = (DEFAULT_KEY_BASE);
287
288                 // Reset debounce table
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 // Reset Keyboard
347 void scan_resetKeyboard( void )
348 {
349         // Empty buffer, now that keyboard has been reset
350         KeyIndex_BufferUsed = 0;
351 }
352
353
354 // Send data to keyboard
355 // NOTE: Only used for converters, since the scan module shouldn't handle sending data in a controller
356 uint8_t scan_sendData( uint8_t dataPayload )
357 {
358         return 0;
359 }
360
361
362 // Reset/Hold keyboard
363 // NOTE: Only used for converters, not needed for full controllers
364 void scan_lockKeyboard( void )
365 {
366 }
367
368 // NOTE: Only used for converters, not needed for full controllers
369 void scan_unlockKeyboard( void )
370 {
371 }
372
373
374 // Signal KeyIndex_Buffer that it has been properly read
375 // NOTE: Only really required for implementing "tricks" in converters for odd protocols
376 void scan_finishedWithBuffer( uint8_t sentKeys )
377 {
378         // Convenient place to clear the KeyIndex_Buffer
379         KeyIndex_BufferUsed = 0;
380         return;
381 }
382
383
384 // Signal KeyIndex_Buffer that it has been properly read and sent out by the USB module
385 // NOTE: Only really required for implementing "tricks" in converters for odd protocols
386 void scan_finishedWithUSBBuffer( uint8_t sentKeys )
387 {
388         return;
389 }
390
391
392 inline void capsense_scan()
393 {
394         // TODO dfj code...needs commenting + cleanup...
395         uint32_t full_av_acc = 0;
396
397         for ( uint8_t strober = 0; strober < total_strobes; ++strober )
398         {
399                 uint8_t map_strobe = strobe_map[strober];
400
401                 uint8_t tries = 1;
402                 while ( tries++ && sampleColumn( map_strobe ) ) { tries &= 0x7; } // don't waste this one just because the last one was poop.
403                 column = testColumn( map_strobe );
404
405                 idle |= column; // if column has any pressed keys, then we are not idle.
406
407                 // TODO Is this needed anymore? Really only helps debug -HaaTa
408                 if( column != cur_keymap[map_strobe] && ( boot_count >= WARMUP_LOOPS ) )
409                 {
410                         cur_keymap[map_strobe] = column;
411                         keymap_change = 1;
412                 }
413
414                 idle |= keymap_change; // if any keys have changed inc. released, then we are not idle.
415
416                 if ( error == 0x50 )
417                 {
418                         error_data |= (((uint16_t)map_strobe) << 12);
419                 }
420
421                 uint8_t strobe_line = map_strobe << MUXES_COUNT_XSHIFT;
422                 for ( int i = 0; i < MUXES_COUNT; ++i )
423                 {
424                         // discard sketchy low bit, and meaningless high bits.
425                         uint8_t sample = samples[SAMPLE_OFFSET + i] >> 1;
426                         full_samples[strobe_line + i] = sample;
427                         keys_averages_acc[strobe_line + i] += sample;
428                 }
429
430                 for ( uint8_t i = SAMPLE_OFFSET; i < ( SAMPLE_OFFSET + MUXES_COUNT ); ++i )
431                 {
432                         full_av_acc += (samples[i]);
433                 }
434         } // for strober
435
436 #ifdef VERIFY_TEST_PAD
437         // verify test key is not down.
438         if ( ( cur_keymap[TEST_KEY_STROBE] & TEST_KEY_MASK ) )
439         {
440                 error = 0x05;
441                 error_data = cur_keymap[TEST_KEY_STROBE] << 8;
442                 error_data += full_samples[TEST_KEY_STROBE * 8];
443         }
444 #endif
445
446         /** aggregate if booting, or if idle;
447          * else, if not booting, check for dirty USB.
448          * */
449
450         idle_count++;
451         idle_count &= IDLE_COUNT_MASK;
452
453         // Warm up voltage references
454         if ( boot_count < WARMUP_LOOPS )
455         {
456                 boot_count++;
457
458                 switch ( boot_count )
459                 {
460                 // First loop
461                 case 1:
462                         // Show msg at first iteration only
463                         info_msg("Warming up the voltage references");
464                         break;
465                 // Middle iterations
466                 case 300:
467                 case 600:
468                 case 900:
469                 case 1200:
470                         print(".");
471                         break;
472                 // Last loop
473                 case WARMUP_STOP:
474                         print("\n");
475                         info_msg("Warmup finished using ");
476                         printInt16( WARMUP_LOOPS );
477                         print(" iterations\n");
478                         break;
479                 }
480         }
481         else
482         {
483                 // Reset accumulators and idle flag/counter
484                 if ( keymap_change )
485                 {
486                         for ( uint8_t c = 0; c < KEY_COUNT; ++c ) { keys_averages_acc[c] = 0; }
487                         idle_count = 0;
488                         idle = 0;
489
490                         keymap_change = 0;
491                 }
492
493                 if ( !idle_count )
494                 {
495                         if( idle )
496                         {
497                                 // aggregate
498                                 for ( uint8_t i = 0; i < KEY_COUNT; ++i )
499                                 {
500                                         uint16_t acc = keys_averages_acc[i] >> IDLE_COUNT_SHIFT;
501                                         uint32_t av = keys_averages[i];
502
503                                         av = (av << KEYS_AVERAGES_MIX_SHIFT) - av + acc;
504                                         av >>= KEYS_AVERAGES_MIX_SHIFT;
505
506                                         keys_averages[i] = av;
507                                         keys_averages_acc[i] = 0;
508                                 }
509                         }
510
511                         if ( boot_count >= WARMUP_LOOPS )
512                         {
513                                 dump();
514                         }
515                 }
516
517         }
518 }
519
520
521 void setup_ADC()
522 {
523         // disable adc digital pins.
524         DIDR1 |= (1 << AIN0D) | (1<<AIN1D); // set disable on pins 1,0.
525         DDRF = 0x0;
526         PORTF = 0x0;
527         uint8_t mux = 0 & 0x1f; // 0 == first. // 0x1e = 1.1V ref.
528
529         // 0 = external aref 1,1 = 2.56V internal ref
530         uint8_t aref = ((1 << REFS1) | (1 << REFS0)) & ((1 << REFS1) | (1 << REFS0));
531         uint8_t adate = (1 << ADATE) & (1 << ADATE); // trigger enable
532         uint8_t trig = 0 & ((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2)); // 0 = free running
533         // ps2, ps1 := /64 ( 2^6 ) ps2 := /16 (2^4), ps1 := 4, ps0 :=2, PS1,PS0 := 8 (2^8)
534         uint8_t prescale = ( ((PRESCALE) << PRESCALE_SHIFT) & PRESCALE_MASK ); // 001 == 2^1 == 2
535         uint8_t hispeed = (1 << ADHSM);
536         uint8_t en_mux = (1 << ACME);
537
538         ADCSRA = (1 << ADEN) | prescale; // ADC enable
539
540         // select ref.
541         //ADMUX |= ((1 << REFS1) | (1 << REFS0)); // 2.56 V internal.
542         //ADMUX |= ((1 << REFS0) ); // Vcc with external cap.
543         //ADMUX &= ~((1 << REFS1) | (1 << REFS0)); // 0,0 : aref.
544         ADMUX = aref | mux | ADLAR_BITS;
545
546         // set free-running
547         ADCSRA |= adate; // trigger enable
548         ADCSRB  = en_mux | hispeed | trig | (ADCSRB & ~((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2))); // trigger select free running
549
550         ADCSRA |= (1 << ADEN); // ADC enable
551         ADCSRA |= (1 << ADSC); // start conversions q
552 }
553
554
555 void recovery( uint8_t on )
556 {
557         DDRB  |=  (1 << RECOVERY_CONTROL);
558         PORTB &= ~(1 << RECOVERY_SINK);   // SINK always zero
559         DDRB  &= ~(1 << RECOVERY_SOURCE); // SOURCE high imp
560
561         if ( on )
562         {
563                 // set strobes to sink to gnd.
564                 DDRC |= C_MASK;
565                 DDRD |= D_MASK;
566                 DDRE |= E_MASK;
567
568                 PORTC &= ~C_MASK;
569                 PORTD &= ~D_MASK;
570                 PORTE &= ~E_MASK;
571
572                 DDRB  |= (1 << RECOVERY_SINK);   // SINK pull
573                 PORTB |= (1 << RECOVERY_CONTROL);
574                 PORTB |= (1 << RECOVERY_SOURCE); // SOURCE high
575                 DDRB  |= (1 << RECOVERY_SOURCE);
576         }
577         else
578         {
579                 PORTB &= ~(1 << RECOVERY_CONTROL);
580                 DDRB  &= ~(1 << RECOVERY_SOURCE);
581                 PORTB &= ~(1 << RECOVERY_SOURCE); // SOURCE low
582                 DDRB  &= ~(1 << RECOVERY_SINK);   // SINK high-imp
583         }
584 }
585
586
587 void hold_sample( uint8_t on )
588 {
589         if ( !on )
590         {
591                 PORTB |= (1 << SAMPLE_CONTROL);
592                 DDRB  |= (1 << SAMPLE_CONTROL);
593         }
594         else
595         {
596                 DDRB  |=  (1 << SAMPLE_CONTROL);
597                 PORTB &= ~(1 << SAMPLE_CONTROL);
598         }
599 }
600
601
602 void strobe_w( uint8_t strobe_num )
603 {
604         PORTC &= ~(C_MASK);
605         PORTD &= ~(D_MASK);
606         PORTE &= ~(E_MASK);
607
608         // Strobe table
609         // Not all strobes are used depending on which are detected
610         switch ( strobe_num )
611         {
612
613         case 0:  PORTD |= (1 << 0); break;
614         case 1:  PORTD |= (1 << 1); break;
615         case 2:  PORTD |= (1 << 2); break;
616         case 3:  PORTD |= (1 << 3); break;
617         case 4:  PORTD |= (1 << 4); break;
618         case 5:  PORTD |= (1 << 5); break;
619         case 6:  PORTD |= (1 << 6); break;
620         case 7:  PORTD |= (1 << 7); break;
621
622         case 8:  PORTE |= (1 << 0); break;
623         case 9:  PORTE |= (1 << 1); break;
624
625         case 10: PORTC |= (1 << 0); break;
626         case 11: PORTC |= (1 << 1); break;
627         case 12: PORTC |= (1 << 2); break;
628         case 13: PORTC |= (1 << 3); break;
629         case 14: PORTC |= (1 << 4); break;
630         case 15: PORTC |= (1 << 5); break;
631         case 16: PORTC |= (1 << 6); break;
632         case 17: PORTC |= (1 << 7); break;
633
634         default:
635                 break;
636         }
637 }
638
639
640 inline uint16_t getADC(void)
641 {
642         ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
643
644         //wait for last read to complete.
645         while ( !( ADCSRA & (1 << ADIF) ) );
646
647         return ADC; // return sample
648 }
649
650
651 int sampleColumn_8x( uint8_t column, uint16_t * buffer )
652 {
653         // ensure all probe lines are driven low, and chill for recovery delay.
654         ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions
655
656         PORTC &= ~C_MASK;
657         PORTD &= ~D_MASK;
658         PORTE &= ~E_MASK;
659
660         PORTF = 0;
661         DDRF  = 0;
662
663         recovery(OFF);
664         strobe_w(column);
665
666         hold_sample(OFF);
667         SET_FULL_MUX(0);
668
669         for ( uint8_t i = 0; i < STROBE_SETTLE; ++i ) { getADC(); }
670
671         hold_sample(ON);
672
673 #undef MUX_SETTLE
674
675 #if (MUX_SETTLE)
676         for ( uint8_t mux = 0; mux < 8; ++mux )
677         {
678                 SET_FULL_MUX(mux); // our sample will use this
679
680                 // wait for mux to settle.
681                 for ( uint8_t i = 0; i < MUX_SETTLE; ++i ) { getADC(); }
682
683                 // retrieve current read.
684                 buffer[mux] = getADC();
685         }
686 #else
687         uint8_t mux = 0;
688         SET_FULL_MUX(mux);
689         getADC(); // throw away; unknown mux.
690         do {
691                 SET_FULL_MUX(mux + 1); // our *next* sample will use this
692
693                 // retrieve current read.
694                 buffer[mux] = getADC();
695                 mux++;
696
697         } while (mux < 8);
698 #endif
699
700         hold_sample(OFF);
701         recovery(ON);
702
703         // turn off adc.
704         ADCSRA &= ~(1 << ADEN);
705
706         // pull all columns' strobe-lines low.
707         DDRC |= C_MASK;
708         DDRD |= D_MASK;
709         DDRE |= E_MASK;
710
711         PORTC &= ~C_MASK;
712         PORTD &= ~D_MASK;
713         PORTE &= ~E_MASK;
714
715         return 0;
716 }
717
718
719 int sampleColumn( uint8_t column )
720 {
721         int rval = 0;
722
723         rval = sampleColumn_8x( column, samples + SAMPLE_OFFSET );
724
725         return rval;
726 }
727
728
729 uint8_t testColumn( uint8_t strobe )
730 {
731         uint8_t column = 0;
732         uint8_t bit = 1;
733         for ( uint8_t mux = 0; mux < MUXES_COUNT; ++mux )
734         {
735                 uint16_t delta = keys_averages[(strobe << MUXES_COUNT_XSHIFT) + mux];
736
737                 uint8_t key = (strobe << MUXES_COUNT_XSHIFT) + mux;
738
739                 // Keypress detected
740                 if ( (db_sample = samples[SAMPLE_OFFSET + mux] >> 1) > (db_threshold = threshold) + (db_delta = delta) )
741                 {
742                         column |= bit;
743
744                         // Only register keypresses once the warmup is complete, or not enough debounce info
745                         if ( boot_count >= WARMUP_LOOPS && keys_debounce[key] <= DEBOUNCE_THRESHOLD )
746                         {
747                                 // Add to the Macro processing buffer if debounce criteria met
748                                 // Automatically handles converting to a USB code and sending off to the PC
749                                 if ( keys_debounce[key] == DEBOUNCE_THRESHOLD )
750                                 {
751 #define KEYSCAN_DEBOUNCE_DEBUG
752 #ifdef KEYSCAN_DEBOUNCE_DEBUG
753                                         // Debug message
754                                         print("0x");
755                                         printHex_op( key, 2 );
756                                         print(" ");
757 #endif
758
759                                         // Only add the key to the buffer once
760                                         // NOTE: Buffer can easily handle multiple adds, just more efficient
761                                         //        and nicer debug messages :P
762                                         //bufferAdd( key );
763                                 }
764
765                                 keys_debounce[key]++;
766
767 //#define KEYSCAN_THRESHOLD_DEBUG
768 #ifdef KEYSCAN_THRESHOLD_DEBUG
769                                 // Debug message
770                                 // <key> [<strobe>:<mux>] : <sense val> : <delta + threshold> : <margin>
771                                 dbug_msg("0x");
772                                 printHex_op( key, 2 );
773                                 print(" [");
774                                 printInt8( strobe );
775                                 print(":");
776                                 printInt8( mux );
777                                 print("] : ");
778                                 printHex( db_sample ); // Sense
779                                 print(" : ");
780                                 printHex( db_threshold );
781                                 print("+");
782                                 printHex( db_delta );
783                                 print("=");
784                                 printHex( db_threshold + db_delta ); // Sense compare
785                                 print(" : ");
786                                 printHex( db_sample - ( db_threshold + db_delta ) ); // Margin
787                                 print("\n");
788 #endif
789                         }
790                 }
791                 // Clear debounce entry if no keypress detected
792                 else
793                 {
794                         // If the key was previously pressed, remove from the buffer
795                         for ( uint8_t c = 0; c < KeyIndex_BufferUsed; c++ )
796                         {
797                                 // Key to release found
798                                 if ( KeyIndex_Buffer[c] == key )
799                                 {
800                                         // Shift keys from c position
801                                         for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
802                                                 KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
803
804                                         // Decrement Buffer
805                                         KeyIndex_BufferUsed--;
806
807                                         break;
808                                 }
809                         }
810
811
812                         // Clear debounce entry
813                         keys_debounce[key] = 0;
814                 }
815
816                 bit <<= 1;
817         }
818         return column;
819 }
820
821
822 void dump(void) {
823
824 #ifdef DEBUG_FULL_SAMPLES_AVERAGES
825         // we don't want to debug-out during the measurements.
826         if ( !dump_count )
827         {
828                 // Averages currently set per key
829                 for ( int i = 0; i < KEY_COUNT; ++i )
830                 {
831                         if ( !(i & 0x0f) )
832                         {
833                                 print("\n");
834                         }
835                         else if ( !(i & 0x07) )
836                         {
837                                 print("  ");
838                         }
839
840                         print(" ");
841                         printHex( keys_averages[i] );
842                 }
843
844                 print("\n");
845
846                 // Previously read full ADC scans?
847                 for ( int i = 0; i< KEY_COUNT; ++i)
848                 {
849                         if ( !(i & 0x0f) )
850                         {
851                                 print("\n");
852                         }
853                         else if ( !(i & 0x07) )
854                         {
855                                 print("  ");
856                         }
857
858                         print(" ");
859                         printHex(full_samples[i]);
860                 }
861         }
862 #endif
863
864 #ifdef DEBUG_STROBE_SAMPLES_AVERAGES
865         // Per strobe information
866         uint8_t cur_strober = ze_strober;
867         print("\n");
868
869         printHex(cur_strober);
870
871         // Previously read ADC scans on current strobe
872         print(" :");
873         for ( uint8_t i = 0; i < MUXES_COUNT; ++i )
874         {
875                 print(" ");
876                 printHex(full_samples[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
877         }
878
879         // Averages current set on current strobe
880         print(" :");
881
882         for ( uint8_t i = 0; i < MUXES_COUNT; ++i )
883         {
884                 print(" ");
885                 printHex(keys_averages[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
886         }
887
888 #endif
889
890 #ifdef DEBUG_DELTA_SAMPLE_THRESHOLD
891         print("\n");
892         printHex( db_delta );
893         print(" ");
894         printHex( db_sample );
895         print(" ");
896         printHex( db_threshold );
897         print(" ");
898         printHex( column );
899 #endif
900
901 #ifdef DEBUG_USB_KEYMAP
902         print("\n      ");
903
904         // Current keymap values
905         for ( uint8_t i = 0; i < total_strobes; ++i )
906         {
907                 printHex(cur_keymap[i]);
908                 print(" ");
909         }
910 #endif
911
912         ze_strober++;
913         ze_strober &= 0xf;
914
915         dump_count++;
916         dump_count &= 0x0f;
917 }
918