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