1 /* Copyright (C) 2011 by Jacob Alexander
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:
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
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
23 #include <avr/pgmspace.h>
24 #include <avr/interrupt.h>
25 #include <util/delay.h>
26 //#include "usb_keyboard.h"
29 #include "usb_keyboard_debug.h"
32 #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
34 // Sleep defined in milliseconds
38 #define KEYBOARD_SIZE 63
39 #define KEYPAD_SIZE 16
43 #define SAMPLE_THRESHOLD 100
44 #define MAX_SAMPLES 127 // Max is 127, reaching 128 is very bad
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
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>
74 #define DRIVE_pin_10 <blank>
75 #define DRIVE_pin_11 <blank>
76 #define DRIVE_pin_12 <blank>
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>
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>
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}}
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>
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); \
138 #define DD_CASE(number) \
140 DRIVE_DETECT(DRIVE_reg_##number, DRIVE_pin_##number, DETECT_group_##number)
142 #define DD_CASE_ORD(number) \
146 #define DD_CASE_END(number,var) \
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) \
157 keyDetectArray[groupArray[index]]++; \
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
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) )) \
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) )) \
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) )) \
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) )) \
202 // Combines the DET_GROUP_Xs above for the given groupArray
203 #define DET_GROUP(group,det_group) \
206 uint8_t groupArray[DETECT_group_size_##group] = DETECT_group_array_##group; \
208 DET_GROUP_##det_group \
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; \
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];
227 uint16_t sendKeypressCounter = 0;
228 volatile uint8_t sendKeypresses = 0;
230 static const uint8_t defaultMap[] = { 0,
293 // Scan Code Decoder (for debug)
294 void printDecodeScancode( int code )
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] ] );
301 void detection( int group )
303 // XXX Modify for different detection groups <-> groupArray mappings
319 // XXX This part is configurable
320 inline void pinSetup(void)
322 // For each pin, 0=input, 1=output
331 // Setting pins to either high or pull-up resistor
342 // Setup with 16 MHz clock
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.
352 while ( !usb_configured() ) /* wait */ ;
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
358 // Setup ISR Timer for flagging a kepress send to USB
359 // Set to 256 * 1024 (8 bit timer with Clock/1024 prescalar) timer
363 TIMSK0 = (1 << TOIE0);
365 // Main Detection Loop
369 // XXX Change number of ORDs if number of lines (RowsxColumns) differ
370 // Determine which keys are being pressed
383 // Check all Keyboard keys first
390 // Check count to see if the sample threshold may have been reached, otherwise collect more data
392 if ( count < MAX_SAMPLES )
395 // Reset Sample Counter
398 // Assess debouncing sample table
399 DEBOUNCE_ASSESS(keyDetectArray,KEYBOARD_SIZE)
400 //DEBOUNCE_ASSESS(keypadDetectArray,KEYPAD_SIZE)
402 // Send keypresses over USB if the ISR has signalled that it's time
403 if ( !sendKeypresses )
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]);
412 if ( keyDetectArray[key] & (1 << 7) ) {
419 if ( validKeys == 6 )
421 keyboard_keys[validKeys++] = defaultMap[key];
426 // TODO undo potentially old keys
427 for ( uint8_t c = validKeys; c < 6; c++ )
428 keyboard_keys[c] = 0;
438 // Print out the current keys pressed
440 if ( keyDetectCount > 0 ) {
442 for ( int c = 0; c < keyDetectCount; c++ ) {
444 phex( keyDetectArray[c] );
446 //printDecodeScancode( keyDetectArray[c] );
453 print("Modifiers: ");
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
463 for ( int c = 0; c < 6 && c < keyDetectCount; c++ )
464 keyboard_keys[c] = c < keyDetectCount ? keyDetectArray[c] : 0;
467 keyboard_modifier_keys = modifiers;
473 // Clear sendKeypresses Flag
477 // usb_keyboard_press(KEY_B, KEY_SHIFT);
481 ISR( TIMER0_OVF_vect )
483 sendKeypressCounter++;
484 if ( sendKeypressCounter > USB_TRANSFER_DIVIDER ) {
485 sendKeypressCounter = 0;