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
35 #define PRE_DRIVE_SLEEP 50
36 #define POST_DRIVE_SLEEP 50
40 #define DRIVE_reg_1 PORTD
41 #define DRIVE_reg_2 PORTD
42 #define DRIVE_reg_3 PORTD
43 #define DRIVE_reg_4 PORTD
44 #define DRIVE_reg_5 PORTD
45 #define DRIVE_reg_6 PORTD
46 #define DRIVE_reg_7 PORTE
47 #define DRIVE_reg_8 PORTE
48 #define DRIVE_reg_9 PORTE
49 #define DRIVE_reg_10 <blank>
50 #define DRIVE_reg_11 <blank>
51 #define DRIVE_reg_12 <blank>
62 #define DRIVE_pin_10 <blank>
63 #define DRIVE_pin_11 <blank>
64 #define DRIVE_pin_12 <blank>
66 // Detect Pin/Group Defines
67 #define DETECT_group_1 1
68 #define DETECT_group_2 2
69 #define DETECT_group_3 3
70 #define DETECT_group_4 4
71 #define DETECT_group_5 5
72 #define DETECT_group_6 6
73 #define DETECT_group_7 7
74 #define DETECT_group_8 8
75 #define DETECT_group_9 9
76 #define DETECT_group_10 <blank>
77 #define DETECT_group_11 <blank>
78 #define DETECT_group_12 <blank>
80 #define DETECT_group_size_1 7
81 #define DETECT_group_size_2 7
82 #define DETECT_group_size_3 6
83 #define DETECT_group_size_4 8
84 #define DETECT_group_size_5 7
85 #define DETECT_group_size_6 7
86 #define DETECT_group_size_7 8
87 #define DETECT_group_size_8 8
88 #define DETECT_group_size_9 4
89 #define DETECT_group_size_10 <blank>
90 #define DETECT_group_size_11 <blank>
91 #define DETECT_group_size_12 <blank>
94 #define DETECT_group_array_1 {{KEY_ESC,KEY_CTRL,KEY_CAPS_LOCK,KEY_SHIFT},{0,1,0,1}}
95 #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}}
96 #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}}
97 #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}}
98 #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}}
99 #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}}
100 #define DETECT_group_array_7 {{KEY_8,KEY_U,KEY_K,KEY_7,KEY_Y,KEY_COMMA},{0,0,0,0,0,0}}
101 #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}}
102 #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}}
105 #define DETECT_group_array_1 {11,27,43,40,6, 22,55}
106 #define DETECT_group_array_2 {10,26,58,41,7, 23,56}
107 #define DETECT_group_array_3 {9, 25,42,8, 24,57}
108 #define DETECT_group_array_4 {12,28,44,39,5, 21,54,59}
109 #define DETECT_group_array_5 {13,29,45,38,4, 20,53}
110 #define DETECT_group_array_6 {14,30,46,37,3, 19,52}
111 #define DETECT_group_array_7 {15,31,61,63,51,36,18,2}
112 #define DETECT_group_array_8 {16,32,47,35,1, 17,50,62}
113 #define DETECT_group_array_9 {48,34,33,49} // 49/60 are the same line
114 #define DETECT_group_array_10 <blank>
115 #define DETECT_group_array_11 <blank>
116 #define DETECT_group_array_12 <blank>
120 // Drive Macros (Generally don't need to be changed), except for maybe DRIVE_DETECT
121 #define DRIVE_DETECT(reg,pin,group) \
122 reg &= ~(1 << pin); \
125 _delay_ms(POST_DRIVE_SLEEP);
127 #define DD_CASE(number) \
129 DRIVE_DETECT(DRIVE_reg_##number, DRIVE_pin_##number, DETECT_group_##number)
131 #define DD_CASE_ORD(number) \
135 #define DD_CASE_END(number,var) \
141 // Detection Macros (Probably don't need to be changed, but depending the matrix, may have to be)
142 // Determine if key is either normal or a modifier
143 #define DET_GROUP_CHECK(index) \
144 curDetect.keyDetectArray[curDetect.keyDetectCount++] = groupArray[index];
147 // XXX - Detection Groups
148 // Checks each of the specified pins, and then if press detected, determine if the key is normal or a modifier
149 // Inverse logic applies for the PINs
151 // Used for 1 detection group (Special group)
152 #define DET_GROUP_1 \
153 if ( !( PINB & (1 << 7) ) ) \
155 if ( !( PINC & (1 << 0) ) ) \
157 if ( !( PIND & (1 << 0) ) ) \
159 if ( !( PIND & (1 << 1) ) ) \
162 // Used for 4 detection groups (Skips J1 P9)
163 #define DET_GROUP_2 \
164 if ( !( PINE & (1 << 7) ) ) \
166 if ( !( PINB & (1 << 0) ) ) \
168 if ( !( PINB & (1 << 1) ) ) \
170 if ( !( PINB & (1 << 2) ) ) \
172 if ( !( PINB & (1 << 3) ) ) \
174 if ( !( PINB & (1 << 4) ) ) \
176 if ( !( PINB & (1 << 5) ) ) \
179 // Used for 1 detection group (Skips J1 P6 and J1 P9)
180 #define DET_GROUP_3 \
181 if ( !( PINE & (1 << 7) ) ) \
183 if ( !( PINB & (1 << 0) ) ) \
185 if ( !( PINB & (1 << 1) ) ) \
187 if ( !( PINB & (1 << 2) ) ) \
189 if ( !( PINB & (1 << 4) ) ) \
191 if ( !( PINB & (1 << 5) ) ) \
194 // Used for 3 detection groups (No skips, except special group 1)
195 #define DET_GROUP_4 \
196 if ( !( PINE & (1 << 7) ) ) \
198 if ( !( PINB & (1 << 0) ) ) \
200 if ( !( PINB & (1 << 1) ) ) \
202 if ( !( PINB & (1 << 2) ) ) \
204 if ( !( PINB & (1 << 3) ) ) \
206 if ( !( PINB & (1 << 4) ) ) \
208 if ( !( PINB & (1 << 5) ) ) \
210 if ( !( PINB & (1 << 6) ) ) \
213 // Combines the DET_GROUP_Xs above for the given groupArray
214 #define DET_GROUP(group,det_group) \
217 uint8_t groupArray[DETECT_group_size_##group] = DETECT_group_array_##group; \
218 DET_GROUP_##det_group \
223 uint8_t keyDetectCount;
224 uint8_t keyDetectArray[40];
226 } curDetect, prevDetect;
229 // Scan Code Decoder (for debug)
230 void printDecodeScancode( int code )
232 static const uint8_t defaultMap[] = { 0,
295 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." };
296 print_P( decodeArray[ defaultMap[code] ] );
299 void detection( int group )
301 _delay_ms(PRE_DRIVE_SLEEP);
303 // XXX Modify for different detection groups <-> groupArray mappings
319 // XXX This part is configurable
322 // For each pin, 0=input, 1=output
330 // Setting pins to either high or pull-up resistor
341 // set for 16 MHz clock
347 // Initialize the USB, and then wait for the host to set configuration.
348 // If the Teensy is powered without a PC connected to the USB port,
349 // this will wait forever.
351 while ( !usb_configured() ) /* wait */ ;
353 // Wait an extra second for the PC's operating system to load drivers
354 // and do whatever it does to actually be ready for input
357 // Make sure variables are properly initialized
358 curDetect.keyDetectCount = 0;
359 curDetect.modifiers = 0;
361 // Main Detection Loop
362 // XXX Change number of ORDs if number of lines differ
363 for ( int group = 1;;group++ ) {
364 // Determine which keys are being pressed
380 // Print out the current keys pressed
381 if ( curDetect.keyDetectCount > 0 ) {
383 for ( int c = 0; c < curDetect.keyDetectCount; c++ ) {
385 phex( curDetect.keyDetectArray[c] );
387 //printDecodeScancode( curDetect.keyDetectArray[c] );
392 if ( curDetect.modifiers ) {
393 print("Modifiers: ");
394 phex( curDetect.modifiers );
398 // After going through each of the key groups, send the detected keys and modifiers
399 // Currently limited to the USB spec (6 keys + modifiers)
400 // Making sure to pass zeros when there are no keys being pressed
401 for ( int c = 0; c < 6 && c < curDetect.keyDetectCount; c++ )
402 keyboard_keys[c] = c < curDetect.keyDetectCount ? curDetect.keyDetectArray[c] : 0;
405 keyboard_modifier_keys = curDetect.modifiers;
408 //usb_keyboard_send();
411 curDetect.keyDetectCount = 0;
412 curDetect.modifiers = 0;
415 // usb_keyboard_press(KEY_B, KEY_SHIFT);