]> git.donarmstrong.com Git - kiibohd-controller.git/blob - main.c
Working keypad switch code detection.
[kiibohd-controller.git] / main.c
1 /* Copyright (C) 2011 by Jacob Alexander
2  * 
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to deal
5  * in the Software without restriction, including without limitation the rights
6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  * copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  * 
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  * 
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19  * THE SOFTWARE.
20  */
21
22 #include <avr/io.h>
23 #include <avr/pgmspace.h>
24 #include <avr/interrupt.h>
25 #include <util/delay.h>
26 //#include "usb_keyboard.h"
27
28 // TEMP INCLUDES
29 #include "usb_keyboard_debug.h"
30 #include <print.h>
31
32 #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
33
34 // Sleep defined in milliseconds
35
36
37 // Number of keys
38 #define KEYBOARD_SIZE 63
39 #define KEYPAD_SIZE 16
40
41
42 // Debouncing Defines
43 #define SAMPLE_THRESHOLD 100
44 #define MAX_SAMPLES 127 // Max is 127, reaching 128 is very bad
45
46
47 // Verified Keypress Defines
48 #define USB_TRANSFER_DIVIDER 10 // 1024 == 1 Send of keypresses per second, 1 == 1 Send of keypresses per ~1 millisecond
49
50
51 // Drive Pin Defines
52 #define DRIVE_reg_1 PORTD
53 #define DRIVE_reg_2 PORTD
54 #define DRIVE_reg_3 PORTD
55 #define DRIVE_reg_4 PORTD
56 #define DRIVE_reg_5 PORTD
57 #define DRIVE_reg_6 PORTD
58 #define DRIVE_reg_7 PORTE
59 #define DRIVE_reg_8 PORTE
60 #define DRIVE_reg_9 PORTE
61 #define DRIVE_reg_10 <blank>
62 #define DRIVE_reg_11 <blank>
63 #define DRIVE_reg_12 <blank>
64
65 #define DRIVE_pin_1 2
66 #define DRIVE_pin_2 3
67 #define DRIVE_pin_3 4
68 #define DRIVE_pin_4 5
69 #define DRIVE_pin_5 6
70 #define DRIVE_pin_6 7
71 #define DRIVE_pin_7 0
72 #define DRIVE_pin_8 1
73 #define DRIVE_pin_9 6
74 #define DRIVE_pin_10 <blank>
75 #define DRIVE_pin_11 <blank>
76 #define DRIVE_pin_12 <blank>
77
78 // Detect Pin/Group Defines
79 #define DETECT_group_1 1
80 #define DETECT_group_2 2
81 #define DETECT_group_3 3
82 #define DETECT_group_4 4
83 #define DETECT_group_5 5
84 #define DETECT_group_6 6
85 #define DETECT_group_7 7
86 #define DETECT_group_8 8
87 #define DETECT_group_9 9
88 #define DETECT_group_10 <blank>
89 #define DETECT_group_11 <blank>
90 #define DETECT_group_12 <blank>
91
92 #define DETECT_group_size_1 7
93 #define DETECT_group_size_2 7
94 #define DETECT_group_size_3 6
95 #define DETECT_group_size_4 8
96 #define DETECT_group_size_5 7
97 #define DETECT_group_size_6 7
98 #define DETECT_group_size_7 8
99 #define DETECT_group_size_8 8
100 #define DETECT_group_size_9 4
101 #define DETECT_group_size_10 <blank>
102 #define DETECT_group_size_11 <blank>
103 #define DETECT_group_size_12 <blank>
104
105 // Switch Codes
106 #define DETECT_group_array_1 {55,22,6 ,40,43,27,11}
107 #define DETECT_group_array_2 {56,23,7 ,41,58,26,10}
108 #define DETECT_group_array_3 {57,24,8 ,42,25,9}
109 #define DETECT_group_array_4 {54,21,5 ,39,44,28,12,59}
110 #define DETECT_group_array_5 {53,20,4 ,38,45,29,13}
111 #define DETECT_group_array_6 {52,19,3 ,37,46,30,14}
112 #define DETECT_group_array_7 {51,18,2 ,36,61,31,15,63}
113 #define DETECT_group_array_8 {50,17,1 ,35,47,32,16,62}
114 #define DETECT_group_array_9 {48,49,33,34} // 49/60 are the same line
115 #define DETECT_group_array_10 <blank>
116 #define DETECT_group_array_11 <blank>
117 #define DETECT_group_array_12 <blank>
118
119
120
121 // Drive Macros (Generally don't need to be changed), except for maybe DRIVE_DETECT
122 #define DRIVE_DETECT(reg,pin,group) \
123                         reg &= ~(1 << pin); \
124                         detection(group); \
125                         reg |= (1 << pin);
126
127 #define DD_CASE(number) \
128                         case number:\
129                                 DRIVE_DETECT(DRIVE_reg_##number, DRIVE_pin_##number, DETECT_group_##number)
130
131 #define DD_CASE_ORD(number) \
132                         DD_CASE(number) \
133                         break;
134
135 #define DD_CASE_END(number,var) \
136                         DD_CASE(number) \
137                         var = -1; \
138                         break;
139
140
141 // Updates the current detection sample and last sample bit
142 // Detection Macros (Probably don't need to be changed, but depending the matrix, may have to be)
143 // Determine if key is either normal or a modifier
144 #define DET_GROUP_CHECK(index,test) \
145                         if ( test ) { \
146                                 keyDetectArray[groupArray[index]]++; \
147                         }
148
149
150 // XXX - Detection Groups
151 // Checks each of the specified pins, and then if press detected, determine if the key is normal or a modifier
152 // Inverse logic applies for the PINs
153
154 // Used for 1 detection group (Special group)
155 #define DET_GROUP_1 \
156                         DET_GROUP_CHECK(0,!( PINB & (1 << 7) )) \
157                         DET_GROUP_CHECK(1,!( PINC & (1 << 0) )) \
158                         DET_GROUP_CHECK(2,!( PIND & (1 << 0) )) \
159                         DET_GROUP_CHECK(3,!( PIND & (1 << 1) )) \
160
161 // Used for 4 detection groups (Skips J1 P9)
162 #define DET_GROUP_2 \
163                         DET_GROUP_CHECK(0,!( PINE & (1 << 7) )) \
164                         DET_GROUP_CHECK(1,!( PINB & (1 << 0) )) \
165                         DET_GROUP_CHECK(2,!( PINB & (1 << 1) )) \
166                         DET_GROUP_CHECK(3,!( PINB & (1 << 2) )) \
167                         DET_GROUP_CHECK(4,!( PINB & (1 << 3) )) \
168                         DET_GROUP_CHECK(5,!( PINB & (1 << 4) )) \
169                         DET_GROUP_CHECK(6,!( PINB & (1 << 5) )) \
170
171 // Used for 1 detection group (Skips J1 P6 and J1 P9)
172 #define DET_GROUP_3 \
173                         DET_GROUP_CHECK(0,!( PINE & (1 << 7) )) \
174                         DET_GROUP_CHECK(1,!( PINB & (1 << 0) )) \
175                         DET_GROUP_CHECK(2,!( PINB & (1 << 1) )) \
176                         DET_GROUP_CHECK(3,!( PINB & (1 << 2) )) \
177                         DET_GROUP_CHECK(4,!( PINB & (1 << 4) )) \
178                         DET_GROUP_CHECK(5,!( PINB & (1 << 5) )) \
179
180 // Used for 3 detection groups (No skips, except special group 1)
181 #define DET_GROUP_4 \
182                         DET_GROUP_CHECK(0,!( PINE & (1 << 7) )) \
183                         DET_GROUP_CHECK(1,!( PINB & (1 << 0) )) \
184                         DET_GROUP_CHECK(2,!( PINB & (1 << 1) )) \
185                         DET_GROUP_CHECK(3,!( PINB & (1 << 2) )) \
186                         DET_GROUP_CHECK(4,!( PINB & (1 << 3) )) \
187                         DET_GROUP_CHECK(5,!( PINB & (1 << 4) )) \
188                         DET_GROUP_CHECK(6,!( PINB & (1 << 5) )) \
189                         DET_GROUP_CHECK(7,!( PINB & (1 << 6) )) \
190
191 // Combines the DET_GROUP_Xs above for the given groupArray
192 #define DET_GROUP(group,det_group) \
193                         case group: \
194                                 { \
195                                         uint8_t groupArray[DETECT_group_size_##group] = DETECT_group_array_##group; \
196                                         _delay_us(1); \
197                                         DET_GROUP_##det_group \
198                                 } \
199                                 break;
200
201
202 // Loop over all of the sampled keys of the given array
203 // If the number of samples is higher than the sample threshold, flag the high bit, clear otherwise
204 // This should be resetting VERY quickly, cutting off a potentially valid keypress is not an issue
205 #define DEBOUNCE_ASSESS(table,size) \
206                         for ( uint8_t key = 1; key < size + 1; key++ ) {\
207                                 table[key] = ( table[key] & ~(1 << 7) ) > SAMPLE_THRESHOLD ? (1 << 7) : 0x00; \
208                         } \
209
210
211 // Keypad detection
212 // Each switch has it's own detection line, inverse logic
213 #define KEYPAD_DETECT(test,switch_code) \
214                         if ( !(test) ) { \
215                                 keypadDetectArray[switch_code]++; \
216                         } \
217
218
219 // NOTE: Highest Bit: Valid keypress (0x80 is valid keypress)
220 //        Other Bits: Pressed state sample counter
221 uint8_t keyDetectArray[KEYBOARD_SIZE + 1];
222 uint8_t keypadDetectArray[KEYPAD_SIZE + 1];
223
224 uint16_t sendKeypressCounter = 0;
225 volatile uint8_t sendKeypresses = 0;
226
227 static const uint8_t defaultMap[] = { 0,
228                                 KEY_INSERT,
229                                 KEY_1,
230                                 KEY_2,
231                                 KEY_3,
232                                 KEY_4,
233                                 KEY_5,
234                                 KEY_6,
235                                 KEY_7,
236                                 KEY_8,
237                                 KEY_9,
238                                 KEY_0,
239                                 KEY_MINUS,
240                                 KEY_EQUAL,
241                                 KEY_BACKSLASH,
242                                 KEY_ALT,
243                                 KEY_TAB,
244                                 KEY_Q,
245                                 KEY_W,
246                                 KEY_E,
247                                 KEY_R,
248                                 KEY_T,
249                                 KEY_Y,
250                                 KEY_U,
251                                 KEY_I,
252                                 KEY_O,
253                                 KEY_P,
254                                 KEY_LEFT_BRACE,
255                                 KEY_RIGHT_BRACE,
256                                 KEY_DELETE,
257                                 KEY_UP,
258                                 KEY_CTRL,
259                                 KEY_CAPS_LOCK,
260                                 KEY_A,
261                                 KEY_S,
262                                 KEY_D,
263                                 KEY_F,
264                                 KEY_G,
265                                 KEY_H,
266                                 KEY_J,
267                                 KEY_K,
268                                 KEY_L,
269                                 KEY_SEMICOLON,
270                                 KEY_QUOTE,
271                                 KEY_ENTER,
272                                 KEY_DOWN,
273                                 KEY_ESC,
274                                 KEY_LEFT_SHIFT,
275                                 KEY_Z,
276                                 KEY_X,
277                                 KEY_C,
278                                 KEY_V,
279                                 KEY_B,
280                                 KEY_N,
281                                 KEY_M,
282                                 KEY_COMMA,
283                                 KEY_PERIOD,
284                                 KEY_SLASH,
285                                 KEY_RIGHT_SHIFT,
286                                 KEY_LEFT,
287                                 KEY_RIGHT,
288                                 KEY_SPACE };
289
290 // Scan Code Decoder (for debug)
291 void printDecodeScancode( int code )
292 {
293
294         static const char* decodeArray[] = { "", "", "", "", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "Enter", "Esc", "Backspace", "Tab", "Space", "-_", "=+", "[{", "]}", "\\", "#", ";:", "'\"", "`~", ",<", ".>", "/?", "Caps Lock", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "Print Screen", "Scroll Lock", "Pause", "Insert", "Home", "Page Up", "Delete", "End", "Page Down", "Right", "Left", "Down", "Up", "Num Lock", "K1", "K2", "K3", "K4", "K5", "K6", "K7", "K8", "K9", "K0", "K." };
295         print_P( decodeArray[ defaultMap[code] ] );
296 }
297
298 void detection( int group )
299 {
300         // XXX Modify for different detection groups <-> groupArray mappings
301         switch ( group ) {
302                 DET_GROUP(1,2)
303                 DET_GROUP(2,2)
304                 DET_GROUP(3,3)
305                 DET_GROUP(4,4)
306                 DET_GROUP(5,2)
307                 DET_GROUP(6,2)
308                 DET_GROUP(7,4)
309                 DET_GROUP(8,4)
310                 DET_GROUP(9,1)
311         }
312 }
313
314
315
316 // XXX This part is configurable
317 inline void pinSetup(void)
318 {
319         // For each pin, 0=input, 1=output
320         DDRA = 0x00;
321         DDRB = 0x00;
322         DDRC = 0x00;
323         DDRD = 0xFC;
324         DDRE = 0x43;
325         DDRF = 0x00;
326
327
328         // Setting pins to either high or pull-up resistor
329         PORTA = 0xFF;
330         PORTB = 0xFF;
331         PORTC = 0x01;
332         PORTD = 0xFF;
333         PORTE = 0xC3;
334         PORTF = 0xFF;
335 }
336
337 void keyPressDetection( uint8_t *keys, uint8_t *validKeys) {
338         for ( uint8_t key = 0; key < KEYBOARD_SIZE + 1; key++ ) {
339                 if ( keys[key] & (1 << 7) ) {
340                         pint8( key );
341                         print(" ");
342
343                         // Too many keys
344                         if ( *validKeys == 6 )
345                                 break;
346                         keyboard_keys[*validKeys++] = defaultMap[key];
347                 }
348         }
349 }
350
351 int main( void )
352 {
353         // Setup with 16 MHz clock
354         CPU_PRESCALE( 0 );
355
356         // Configuring Pins
357         pinSetup();
358
359         // Initialize the USB, and then wait for the host to set configuration.
360         // If the Teensy is powered without a PC connected to the USB port,
361         // this will wait forever.
362         usb_init();
363         while ( !usb_configured() ) /* wait */ ;
364
365         // Wait an extra second for the PC's operating system to load drivers
366         // and do whatever it does to actually be ready for input
367         _delay_ms(1000);
368
369         // Setup ISR Timer for flagging a kepress send to USB
370         // Set to 256 * 1024 (8 bit timer with Clock/1024 prescalar) timer
371         TCCR0A = 0x00;
372         TCCR0B = 0x03;
373         TIMSK0 = (1 << TOIE0);
374
375         // Main Detection Loop
376         int8_t group = 1;
377         uint8_t count = 0;
378         for ( ;;group++ ) {
379                 // XXX Change number of ORDs if number of lines (RowsxColumns) differ
380                 // Determine which keys are being pressed
381                 switch ( group ) {
382                         DD_CASE_ORD(1)
383                         DD_CASE_ORD(2)
384                         DD_CASE_ORD(3)
385                         DD_CASE_ORD(4)
386                         DD_CASE_ORD(5)
387                         DD_CASE_ORD(6)
388                         DD_CASE_ORD(7)
389                         DD_CASE_ORD(8)
390                         DD_CASE_END(9,group)
391                 }
392
393                 // Check all Keyboard keys first
394                 if ( group != -1 )
395                         continue;
396
397                 // Check Keypad keys
398                 KEYPAD_DETECT(PINA & (1 << 0),11)
399                 KEYPAD_DETECT(PINA & (1 << 1),3)
400                 KEYPAD_DETECT(PINA & (1 << 2),7)
401                 KEYPAD_DETECT(PINA & (1 << 3),4)
402                 KEYPAD_DETECT(PINA & (1 << 4),15)
403                 KEYPAD_DETECT(PINA & (1 << 5),6)
404                 KEYPAD_DETECT(PINA & (1 << 6),2)
405                 KEYPAD_DETECT(PINA & (1 << 7),10)
406                 KEYPAD_DETECT(PINF & (1 << 0),8)
407                 KEYPAD_DETECT(PINF & (1 << 1),12)
408                 KEYPAD_DETECT(PINF & (1 << 2),16)
409                 KEYPAD_DETECT(PINF & (1 << 3),13)
410                 KEYPAD_DETECT(PINF & (1 << 4),1)
411                 KEYPAD_DETECT(PINF & (1 << 5),5)
412                 KEYPAD_DETECT(PINF & (1 << 6),9)
413                 KEYPAD_DETECT(PINF & (1 << 7),14)
414
415                 // Check count to see if the sample threshold may have been reached, otherwise collect more data
416                 count++;
417                 if ( count < MAX_SAMPLES )
418                         continue;
419
420                 // Reset Sample Counter
421                 count = 0;
422
423                 // Assess debouncing sample table
424                 DEBOUNCE_ASSESS(keyDetectArray,KEYBOARD_SIZE)
425                 DEBOUNCE_ASSESS(keypadDetectArray,KEYPAD_SIZE)
426
427                 // Send keypresses over USB if the ISR has signalled that it's time
428                 if ( !sendKeypresses )
429                         continue;
430
431
432                 // Detect Valid Keypresses - TODO
433                 uint8_t validKeys = 0;
434                 keyPressDetection( keyDetectArray, &validKeys );
435                 keyPressDetection( keypadDetectArray, &validKeys );
436                 print(":\n");
437
438                 // TODO undo potentially old keys
439                 for ( uint8_t c = validKeys; c < 6; c++ )
440                         keyboard_keys[c] = 0;
441
442
443                 // Print out the current keys pressed
444                 /*
445                 if ( keyDetectCount > 0 ) {
446                         print("Switch: ");
447                         for ( int c = 0; c < keyDetectCount; c++ ) {
448                                 print("0x");
449                                 phex( keyDetectArray[c] );
450                                 print("|");
451                                 //printDecodeScancode( keyDetectArray[c] );
452                                 print(" ");
453
454                         }
455                         print("\n");
456                 }
457                 if ( modifiers ) {
458                         print("Modifiers: ");
459                         phex( modifiers );
460                         print("\n");
461                 }
462                 */
463
464                 // After going through each of the key groups, send the detected keys and modifiers
465                 // Currently limited to the USB spec (6 keys + modifiers)
466                 // Making sure to pass zeros when there are no keys being pressed
467                 /*
468                 for ( int c = 0; c < 6 && c < keyDetectCount; c++ )
469                         keyboard_keys[c] = c < keyDetectCount ? keyDetectArray[c] : 0;
470
471                 // Modifiers
472                 keyboard_modifier_keys = modifiers;
473                 */
474
475                 // Send keypresses
476                 usb_keyboard_send();
477
478                 // Clear sendKeypresses Flag
479                 sendKeypresses = 0;
480         }
481
482         // usb_keyboard_press(KEY_B, KEY_SHIFT);
483         return 0;
484 }
485
486 ISR( TIMER0_OVF_vect )
487 {
488         sendKeypressCounter++;
489         if ( sendKeypressCounter > USB_TRANSFER_DIVIDER ) {
490                 sendKeypressCounter = 0;
491                 sendKeypresses = 1;
492         }
493 }
494