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