changeset 21:c14f9ac8420f

Reorganization for use with the CMake "Modules" - Include option is currently "hacked" and needs to be fixed - Builds on Linux, but Mac and Windows needs to be tested - Loader script generation isn't complete
author Jacob Alexander <triplehaata@gmail.com>
date Wed, 28 Sep 2011 23:25:51 -0700
parents 0bd94a5cac31
children 7e2217378d23
files CMakeLists.txt Debug/basic/print.c Debug/basic/print.h Debug/basic/setup.cmake Keymap/keymap.h Keymap/usb_keys.h LoadFile/load Macro/basic/setup.cmake Scan/matrix/matrix.c Scan/matrix/matrix.h Scan/matrix/scan_loop.c Scan/matrix/scan_loop.h Scan/matrix/setup.cmake USB/pjrc/setup.cmake USB/pjrc/usb_keyboard.c USB/pjrc/usb_keyboard.h USB/pjrc/usb_keyboard_debug.c USB/pjrc/usb_keyboard_debug.h setup.cmake
diffstat 19 files changed, 2910 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Wed Sep 28 20:37:19 2011 -0700
+++ b/CMakeLists.txt	Wed Sep 28 23:25:51 2011 -0700
@@ -33,13 +33,13 @@
 # Source Defines
 #
 
-#| Sources 
-set( SRCS
-	./main.c
-        ./print.c
-	./usb_keyboard_debug.c
-	./scan_loop.c
-)
+#| Sources (see setup.h for configuring in/away code blocks or other complete modules)
+#| XXX Not set here in this project, see setup.cmake
+#set( SRCS ./main.c )
+
+#| Instead, include the module source selector
+include( setup.cmake )
+set( SRCS main.c ${SCAN_SRCS} ${MACRO_SRCS} ${USB_SRCS} ${DEBUG_SRCS} )
 
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Debug/basic/print.c	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,190 @@
+/* Copyright (C) 2011 by Jacob Alexander
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+// Compiler Includes
+#include <stdarg.h>
+
+// AVR Includes
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+
+// Project Includes
+#include "print.h"
+
+// Defines
+
+
+// USB HID String Output
+void usb_debug_putstr( char* s )
+{
+	while ( *s != '\0' )
+		usb_debug_putchar( *s++ );
+}
+
+// Multiple string Output
+void usb_debug_putstrs( char* first, ... )
+{
+	// Initialize the variadic function parameter list
+	va_list ap;
+
+	// Get the first parameter
+	va_start( ap, first );
+	char *cur = first;
+
+	// Loop through the variadic list until "\0\0\0" is found
+	while ( !( cur[0] == '\0' && cur[1] == '\0' && cur[2] == '\0' ) )
+	{
+		// Print out the given string
+		usb_debug_putstr( cur );
+
+		// Get the next argument ready
+		cur = va_arg( ap, char* );
+	}
+
+	va_end( ap ); // Not required, but good practice
+}
+
+// Print a constant string
+void _print(const char *s)
+{
+	char c;
+
+	// Acquire the character from flash, and print it, as long as it's not NULL
+	// Also, if a newline is found, print a carrige return as well
+	while ( ( c = pgm_read_byte(s++) ) != '\0' )
+	{
+		if ( c == '\n' )
+			usb_debug_putchar('\r');
+		usb_debug_putchar(c);
+	}
+}
+
+
+
+
+// String Functions
+void int8ToStr( uint8_t in, char* out )
+{
+	// Position and sign containers
+	uint8_t pos;
+	pos = 0;
+
+	// Evaluate through digits as decimal
+	do
+	{
+		out[pos++] = in % 10 + '0';
+	}
+	while ( (in /= 10) > 0 );
+
+	// Append null
+	out[pos] = '\0';
+
+	// Reverse the string to the correct order
+	revsStr(out);
+}
+
+
+void int16ToStr( uint16_t in, char* out )
+{
+	// Position and sign containers
+	uint16_t pos;
+	pos = 0;
+
+	// Evaluate through digits as decimal
+	do
+	{
+		out[pos++] = in % 10 + '0';
+	}
+	while ( (in /= 10) > 0 );
+
+	// Append null
+	out[pos] = '\0';
+
+	// Reverse the string to the correct order
+	revsStr(out);
+}
+
+
+void hexToStr_op( uint16_t in, char* out, uint8_t op )
+{
+	// Position container
+	uint16_t pos = 0;
+
+	// Evaluate through digits as hex
+	do
+	{
+		uint16_t cur = in % 16;
+		out[pos++] = cur + (( cur < 10 ) ? '0' : 'A' - 10);
+	}
+	while ( (in /= 16) > 0 );
+
+	// Output formatting options
+	switch ( op )
+	{
+	case 1: // Add 0x
+		out[pos++] = 'x';
+		out[pos++] = '0';
+		break;
+	case 2: //  8-bit padding
+	case 4: // 16-bit padding
+		while ( pos < op )
+			out[pos++] = '0';
+		break;
+	}
+
+	// Append null
+	out[pos] = '\0';
+
+	// Reverse the string to the correct order
+	revsStr(out);
+}
+
+
+void revsStr( char* in )
+{
+	// Iterators
+	int i, j;
+
+	// Temp storage
+	char c;
+
+	// Loop through the string, and reverse the order of the characters
+	for ( i = 0, j = lenStr( in ) - 1; i < j; i++, j-- )
+	{
+		c = in[i];
+		in[i] = in[j];
+		in[j] = c;
+	}
+}
+
+
+uint16_t lenStr( char* in )
+{
+	// Iterator
+	char *pos;
+
+	// Loop until null is found
+	for ( pos = in; *pos; pos++ );
+
+	// Return the difference between the pointers of in and pos (which is the string length)
+	return (pos - in);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Debug/basic/print.h	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,87 @@
+/* Copyright (C) 2011 by Jacob Alexander
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef print_h__
+#define print_h__
+
+// AVR Includes
+#include <avr/pgmspace.h>
+
+// Project Includes
+#include "usb_keyboard_debug.h"
+
+// Defines
+#define NL "\r\n"
+
+
+/* XXX
+ * Note that all the variadic functions below, take comma separated string lists, they are purposely not printf style (simplicity)
+ */
+
+// Function Aliases
+#define dPrint(c)         usb_debug_putchar(c)
+#define dPrintStr(c)      usb_debug_putstr (c)
+#define dPrintStrs(...)   usb_debug_putstrs(__VA_ARGS__, "\0\0\0")      // Convenience Variadic Macro
+#define dPrintStrNL(c)    dPrintStrs       (c, NL)                      // Appends New Line Macro
+#define dPrintStrsNL(...) usb_debug_putstrs(__VA_ARGS__, NL, "\0\0\0")  // Appends New Line Macro
+
+// Special Msg Constructs (Uses VT100 tags)
+#define dPrintMsg(colour_code_str,msg,...) \
+                          usb_debug_putstrs("\033[", colour_code_str, "m", msg, "\033[0m - ", __VA_ARGS__, NL, "\0\0\0")
+#define printMsg(colour_code_str,msg,str) \
+                          print("\033[" colour_code_str "m" msg "\033[0m - " str NL)
+
+// Info Messages
+#define info_dPrint(...)  dPrintMsg        ("1;32",   "INFO",    __VA_ARGS__) // Info Msg
+#define info_print(str)   printMsg         ("1;32",   "INFO",    str)         // Info Msg
+
+// Warning Messages
+#define warn_dPrint(...)  dPrintMsg        ("1;33",   "WARNING", __VA_ARGS__) // Warning Msg
+#define warn_print(str)   printMsg         ("1;33",   "WARNING", str)         // Warning Msg
+
+// Error Messages
+#define erro_dPrint(...)  dPrintMsg        ("1;5;31", "ERROR",   __VA_ARGS__) // Error Msg
+#define erro_print(str)   printMsg         ("1;5;31", "ERROR",   str)         // Error Msg
+
+// Debug Messages
+#define dbug_dPrint(...)  dPrintMsg        ("1;35",   "DEBUG",   __VA_ARGS__) // Debug Msg
+#define dbug_print(str)   printMsg         ("1;35",   "DEBUG",   str)         // Debug Msg
+
+// Static String Printing
+#define print(s) _print(PSTR(s))
+
+void _print(const char *s);
+void usb_debug_putstr( char* s );
+void usb_debug_putstrs( char* first, ... );
+
+
+
+// String Functions
+#define hexToStr(hex, out) hexToStr_op(hex, out, 1)
+
+void int8ToStr  ( uint8_t  in,   char*  out );
+void int16ToStr ( uint16_t in,   char*  out );
+void hexToStr_op( uint16_t in,   char*  out, uint8_t op );
+void revsStr    ( char*  in );
+uint16_t lenStr ( char*  in );
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Debug/basic/setup.cmake	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,22 @@
+###| CMake Kiibohd Controller Debug Module |###
+#
+# Written by Jacob Alexander in 2011 for the Kiibohd Controller
+#
+# Released into the Public Domain
+#
+###
+
+
+###
+# Module C files
+#
+
+set( DEBUG_SRCS
+	print.c
+)
+
+
+###
+# Module Specific Options
+#
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Keymap/keymap.h	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,228 @@
+#ifndef __KEYMAP_h
+#define __KEYMAP_h
+
+#include "usb_keys.h"
+
+// Modifier Mask
+#define MODIFIERS_KEYPAD   0
+#define MODIFIERS_KEYBOARD 4
+static uint8_t    keypad_modifierMask[] = {};
+static uint8_t  keyboard_modifierMask[] = { 1, 17, 33, 49 };
+static uint8_t alternate_modifierMask[] = { 1, 17, 33, 49, 62 };
+
+// Default 1-indexed key mappings
+static uint8_t keypadDefaultMap[] = { 0,
+				KEYPAD_7,
+				KEYPAD_8,
+				KEYPAD_9,
+				KEYPAD_SLASH,
+				KEYPAD_4,
+				KEYPAD_5,
+				KEYPAD_6,
+				KEYPAD_ASTERIX,
+				KEYPAD_1,
+				KEYPAD_2,
+				KEYPAD_3,
+				KEYPAD_MINUS,
+				KEYPAD_ENTER,
+				KEYPAD_0,
+				KEYPAD_PERIOD,
+				KEYPAD_PLUS };
+
+static uint8_t defaultMap[] = { 0,
+				KEY_GUI,
+				KEY_1,
+				KEY_2,
+				KEY_3,
+				KEY_4,
+				KEY_5,
+				KEY_6,
+				KEY_7,
+				KEY_8,
+				KEY_9,
+				KEY_0,
+				KEY_MINUS,
+				KEY_EQUAL,
+				KEY_BACKSLASH,
+				KEY_TILDE,
+				KEY_BACKSPACE,
+				KEY_ALT,
+				KEY_TAB,
+				KEY_Q,
+				KEY_W,
+				KEY_E,
+				KEY_R,
+				KEY_T,
+				KEY_Y,
+				KEY_U,
+				KEY_I,
+				KEY_O,
+				KEY_P,
+				KEY_LEFT_BRACE,
+				KEY_RIGHT_BRACE,
+				KEY_DELETE,
+				KEY_UP,
+				KEY_CTRL,
+				KEY_CAPS_LLOCK,
+				KEY_A,
+				KEY_S,
+				KEY_D,
+				KEY_F,
+				KEY_G,
+				KEY_H,
+				KEY_J,
+				KEY_K,
+				KEY_L,
+				KEY_SEMICOLON,
+				KEY_QUOTE,
+				KEY_ENTER,
+				KEY_DOWN,
+				KEY_ESC,
+				KEY_LEFT_SHIFT,
+				KEY_Z,
+				KEY_X,
+				KEY_C,
+				KEY_V,
+				KEY_B,
+				KEY_N,
+				KEY_M,
+				KEY_COMMA,
+				KEY_PERIOD,
+				KEY_SLASH,
+				KEY_RIGHT_SHIFT,
+				KEY_LEFT,
+				KEY_RIGHT,
+				KEY_SPACE };
+
+static uint8_t navigationMap[] = { 0,
+				KEY_GUI,
+				KEY_F1,
+				KEY_F2,
+				KEY_F3,
+				KEY_F4,
+				KEY_F5,
+				KEY_F6,
+				KEY_F7,
+				KEY_F8,
+				KEY_F9,
+				KEY_F10,
+				KEY_F11,
+				KEY_F12,
+				KEY_INSERT,
+				KEY_DELETE,
+				KEY_BACKSPACE,
+				KEY_ALT,
+				KEY_CAPS_LOCK,
+				0,
+				0,
+				0,
+				0,
+				0,
+				0,
+				0,
+				KEY_SYSREQ_ATT,
+				KEY_SCROLL_LOCK,
+				KEY_PAUSE,
+				KEY_UP,
+				0,
+				0,
+				0,
+				KEY_CTRL,
+				KEY_CAPS_LLOCK,
+				0,
+				0,
+				0,
+				0,
+				0,
+				KEYPAD_ASTERIX,
+				KEYPAD_SLASH,
+				KEY_HOME,
+				KEY_PAGE_UP,
+				KEY_LEFT,
+				KEY_RIGHT,
+				KEY_ENTER,
+				0,
+				KEY_ESC,
+				KEY_LEFT_SHIFT,
+				0,
+				0,
+				0,
+				0,
+				0,
+				KEYPAD_PLUS,
+				KEYPAD_MINUS,
+				KEY_END,
+				KEY_PAGE_DOWN,
+				KEY_DOWN,
+				KEY_RIGHT_SHIFT,
+				165,
+				KEY_RIGHT_ALT,
+				KEY_SPACE };
+
+static uint8_t colemakMap[] = { 0,
+				KEY_GUI,
+				KEY_1,
+				KEY_2,
+				KEY_3,
+				KEY_4,
+				KEY_5,
+				KEY_6,
+				KEY_7,
+				KEY_8,
+				KEY_9,
+				KEY_0,
+				KEY_MINUS,
+				KEY_EQUAL,
+				KEY_BACKSLASH,
+				KEY_TILDE,
+				KEY_BACKSPACE,
+				KEY_ALT,
+				KEY_TAB,
+				KEY_Q,
+				KEY_W,
+				KEY_F,
+				KEY_P,
+				KEY_G,
+				KEY_J,
+				KEY_L,
+				KEY_U,
+				KEY_Y,
+				KEY_SEMICOLON,
+				KEY_LEFT_BRACE,
+				KEY_RIGHT_BRACE,
+				KEY_DELETE,
+				KEY_PAGE_UP,
+				KEY_CTRL,
+				KEY_CAPS_LLOCK,
+				KEY_A,
+				KEY_R,
+				KEY_S,
+				KEY_T,
+				KEY_D,
+				KEY_H,
+				KEY_N,
+				KEY_E,
+				KEY_I,
+				KEY_O,
+				KEY_QUOTE,
+				KEY_ENTER,
+				KEY_PAGE_DOWN,
+				KEY_ESC,
+				KEY_LEFT_SHIFT,
+				KEY_Z,
+				KEY_X,
+				KEY_C,
+				KEY_V,
+				KEY_B,
+				KEY_K,
+				KEY_M,
+				KEY_COMMA,
+				KEY_PERIOD,
+				KEY_SLASH,
+				KEY_RIGHT_SHIFT,
+				165,
+				KEY_RIGHT_ALT,
+				KEY_SPACE };
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Keymap/usb_keys.h	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,244 @@
+#ifndef __usb_keys_h
+#define __usb_keys_h
+
+
+// List of Modifiers
+#define KEY_CTRL	0x01
+#define KEY_SHIFT	0x02
+#define KEY_ALT		0x04
+#define KEY_GUI		0x08
+#define KEY_LEFT_CTRL	0x01
+#define KEY_LEFT_SHIFT	0x02
+#define KEY_LEFT_ALT	0x04
+#define KEY_LEFT_GUI	0x08
+#define KEY_RIGHT_CTRL	0x10
+#define KEY_RIGHT_SHIFT	0x20
+#define KEY_RIGHT_ALT	0x40
+#define KEY_RIGHT_GUI	0x80
+
+// List of Keycodes
+#define KEY_A           4
+#define KEY_B           5
+#define KEY_C           6
+#define KEY_D           7
+#define KEY_E           8
+#define KEY_F           9
+#define KEY_G           10
+#define KEY_H           11
+#define KEY_I           12
+#define KEY_J           13
+#define KEY_K           14
+#define KEY_L           15
+#define KEY_M           16
+#define KEY_N           17
+#define KEY_O           18
+#define KEY_P           19
+#define KEY_Q           20
+#define KEY_R           21
+#define KEY_S           22
+#define KEY_T           23
+#define KEY_U           24
+#define KEY_V           25
+#define KEY_W           26
+#define KEY_X           27
+#define KEY_Y           28
+#define KEY_Z           29
+#define KEY_1           30
+#define KEY_2           31
+#define KEY_3           32
+#define KEY_4           33
+#define KEY_5           34
+#define KEY_6           35
+#define KEY_7           36
+#define KEY_8           37
+#define KEY_9           38
+#define KEY_0           39
+#define KEY_ENTER       40
+#define KEY_ESC         41
+#define KEY_BACKSPACE   42
+#define KEY_TAB         43
+#define KEY_SPACE       44
+#define KEY_MINUS       45
+#define KEY_EQUAL       46
+#define KEY_LEFT_BRACE  47
+#define KEY_RIGHT_BRACE 48
+#define KEY_BACKSLASH   49
+#define KEY_NUMBER      50
+#define KEY_SEMICOLON   51
+#define KEY_QUOTE       52
+#define KEY_TILDE       53
+#define KEY_COMMA       54
+#define KEY_PERIOD      55
+#define KEY_SLASH       56
+#define KEY_CAPS_LOCK   57
+#define KEY_F1          58
+#define KEY_F2          59
+#define KEY_F3          60
+#define KEY_F4          61
+#define KEY_F5          62
+#define KEY_F6          63
+#define KEY_F7          64
+#define KEY_F8          65
+#define KEY_F9          66
+#define KEY_F10         67
+#define KEY_F11         68
+#define KEY_F12         69
+#define KEY_PRINTSCREEN 70
+#define KEY_SCROLL_LOCK 71
+#define KEY_PAUSE       72
+#define KEY_INSERT      73
+#define KEY_HOME        74
+#define KEY_PAGE_UP     75
+#define KEY_DELETE      76
+#define KEY_END         77
+#define KEY_PAGE_DOWN   78
+#define KEY_RIGHT       79
+#define KEY_LEFT        80
+#define KEY_DOWN        81
+#define KEY_UP          82
+#define KEY_NUM_LOCK    83
+#define KEYPAD_SLASH    84
+#define KEYPAD_ASTERIX  85
+#define KEYPAD_MINUS    86
+#define KEYPAD_PLUS     87
+#define KEYPAD_ENTER    88
+#define KEYPAD_1        89
+#define KEYPAD_2        90
+#define KEYPAD_3        91
+#define KEYPAD_4        92
+#define KEYPAD_5        93
+#define KEYPAD_6        94
+#define KEYPAD_7        95
+#define KEYPAD_8        96
+#define KEYPAD_9        97
+#define KEYPAD_0        98
+#define KEYPAD_PERIOD   99
+#define KEY_ISO_BACKSLASH 100
+#define KEY_APP         101
+#define KEYBOARD_ERROR  102 // See spec
+#define KEYPAD_EQUAL    103
+#define KEY_F13         104
+#define KEY_F14         105
+#define KEY_F15         106
+#define KEY_F16         107
+#define KEY_F17         108
+#define KEY_F18         109
+#define KEY_F19         110
+#define KEY_F20         111
+#define KEY_F21         112
+#define KEY_F22         113
+#define KEY_F23         114
+#define KEY_F24         115
+#define KEY_EXEC        116
+#define KEY_HELP        117
+#define KEY_MENU        118
+#define KEY_SELECT      119
+#define KEY_STOP        120
+#define KEY_AGAIN       121
+#define KEY_UNDO        122
+#define KEY_CUT         123
+#define KEY_COPY        124
+#define KEY_PASTE       125
+#define KEY_FIND        126
+#define KEY_MUTE        127
+#define KEY_VOL_UP      128
+#define KEY_VOL_DOWN    129
+#define KEY_CAPS_LLOCK  130 // "Locking" Scroll Lock (Old keyboards with Locking Caps Lock)
+#define KEY_NUM_LLOCK   131
+#define KEY_SCROLL_LLOCK 132
+#define KEYPAD_COMMA    133 // Brazillian (See spec)
+#define KEYPAD_EQUAL_AS 134 // AS/400 Keyboard (See spec)
+#define KEY_INTER1      135 // Brazillian and Japanese "Ru"
+#define KEY_INTER2      136 // Japanese Katakana/Hiragana
+#define KEY_INTER3      137 // Japanese Yen
+#define KEY_INTER4      138 // Japanese Henkan
+#define KEY_INTER5      139 // Japanese Muhenkan
+#define KEY_INTER6      140 // PC98 Comma (Ka-m-ma)
+#define KEY_INTER7      141 // Double-Byte/Single-Byte Toggle
+#define KEY_INTER8      142 // Undefined
+#define KEY_INTER9      143 // Undefined
+#define KEY_LANG1       144 // Korean Hangul/English Toggle
+#define KEY_LANG2       145 // Korean Hanja Conversion
+#define KEY_LANG3       146 // Japanese Katakana Key (USB)
+#define KEY_LANG4       147 // Japanese Hiragana Key (USB)
+#define KEY_LANG5       148 // Japanese Zenkaku/Hankaku Key (USB)
+#define KEY_LANG6       149 // Reserved (Application Specific)
+#define KEY_LANG7       150 // Reserved (Application Specific)
+#define KEY_LANG8       151 // Reserved (Application Specific)
+#define KEY_LANG9       152 // Reserved (Application Specific)
+#define KEY_ALT_ERASE   153 // Special Erase (See Spec)
+#define KEY_SYSREQ_ATT  154 // Modifier Type
+#define KEY_CANCEL      155
+#define KEY_CLEAR       156
+#define KEY_PRIOR       157
+#define KEY_RETURN      158
+#define KEY_SEPARATOR   159
+#define KEY_OUT         160
+#define KEY_OPER        161
+#define KEY_CLEAR_AGAIN 162
+#define KEY_CRSEL_PROPS 163
+#define KEY_EXSEL       164
+// 165 - 175 Reserved
+#define KEYPAD_00       176
+#define KEYPAD_000      177
+#define KEY_1000_SEP    178
+#define KEY_DECIMAL_SEP 179
+#define KEY_CURRENCY_MAIN 180
+#define KEY_CURRENCY_SUB 181
+#define KEYPAD_LPAREN   182
+#define KEYPAD_RPAREN   183
+#define KEYPAD_LBRACE   184
+#define KEYPAD_RBRACE   185
+#define KEYPAD_TAB      186
+#define KEYPAD_BACKSPACE 187
+#define KEYPAD_A        188
+#define KEYPAD_B        189
+#define KEYPAD_C        190
+#define KEYPAD_D        191
+#define KEYPAD_E        192
+#define KEYPAD_F        193
+#define KEYPAD_XOR      194
+#define KEYPAD_CHEVRON  195
+#define KEYPAD_PERCENT  196
+#define KEYPAD_LTHAN    197
+#define KEYPAD_GTHAN    198
+#define KEYPAD_AND      199
+#define KEYPAD_AND_AND  200
+#define KEYPAD_OR       201
+#define KEYPAD_OR_OR    202
+#define KEYPAD_COLON    203
+#define KEYPAD_POUND    204
+#define KEYPAD_SPACE    205
+#define KEYPAD_AT       206
+#define KEYPAD_EXCLAIM  207
+#define KEYPAD_MEM_STORE 208
+#define KEYPAD_MEM_RECALL 209
+#define KEYPAD_MEM_CLEAR 210
+#define KEYPAD_MEM_ADD  211
+#define KEYPAD_MEM_SUB  212
+#define KEYPAD_MEM_MULT 213
+#define KEYPAD_MEM_DIV  214
+#define KEYPAD_PLUS_MINUS 215
+#define KEYPAD_CLEAR    216
+#define KEYPAD_CLEAR_ENTRY 217
+#define KEYPAD_BINARY   218
+#define KEYPAD_OCTAL    219
+#define KEYPAD_DECIMAL  220
+#define KEYPAD_HEX      221
+// 222 - 223 Reserved
+#define KEYS_LCTRL      224
+#define KEYS_LSHIFT     225
+#define KEYS_LALT       226
+#define KEYS_LGUI       227
+#define KEYS_RCTRL      228
+#define KEYS_RSHIFT     229
+#define KEYS_RALT       230
+#define KEYS_RGUI       231
+// 232 - 65535 Reserved
+
+
+
+
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LoadFile/load	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+#| Loads the hex file onto the teensy++ 2.0
+
+sudo teensy-loader-cli -mmcu=at90usb1286 -w Build/main.hex
+
+exit 0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Macro/basic/setup.cmake	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,21 @@
+###| CMake Kiibohd Controller Macro Module |###
+#
+# Written by Jacob Alexander in 2011 for the Kiibohd Controller
+#
+# Released into the Public Domain
+#
+###
+
+
+###
+# Module C files
+#
+
+set( MACRO_SRCS
+)
+
+
+###
+# Module Specific Options
+#
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Scan/matrix/matrix.c	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,181 @@
+/* Copyright (C) 2011 by Jacob Alexander
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "matrix.h"
+
+#define REG_SET(reg)	reg |= (1 << ( matrix[row][col] % 10 ) )
+			
+#define PIN_SET_COL(pin) \
+			switch ( scanMode ) { \
+			case scanCol: \
+			case scanCol_powrRow: \
+			case scanDual: \
+				REG_SET(port##pin); break; \
+			case scanRow_powrCol: REG_SET(ddr##pin); REG_SET(port##pin); break; \
+			} \
+			break
+
+#define PIN_SET_ROW(pin) \
+			switch ( scanMode ) { \
+			case scanRow: \
+			case scanRow_powrCol: \
+			case scanDual: \
+				REG_SET(port##pin); break; \
+			case scanCol_powrRow: REG_SET(ddr##pin); REG_SET(port##pin); break; \
+			} \
+			break
+
+#define PIN_CASE(pinLetter) \
+			case pin##pinLetter##0: \
+			case pin##pinLetter##1: \
+			case pin##pinLetter##2: \
+			case pin##pinLetter##3: \
+			case pin##pinLetter##4: \
+			case pin##pinLetter##5: \
+			case pin##pinLetter##6: \
+			case pin##pinLetter##7
+
+#define PIN_TEST_COL(pin) \
+			if ( !( pin & ( 1 << ( matrix[0][col] % 10 ) ) \
+				detectArray[matrix[row][col]]++; \
+			break
+
+
+void matrix_pinSetup( uint8_t *matrix )
+{
+	// Setup the variables
+	uint8_t portA = 0x00;
+	uint8_t portB = 0x00;
+	uint8_t portC = 0x00;
+	uint8_t portD = 0x00;
+	uint8_t portE = 0x00;
+	uint8_t portF = 0x00;
+
+	uint8_t ddrA = 0x00;
+	uint8_t ddrB = 0x00;
+	uint8_t ddrC = 0x00;
+	uint8_t ddrD = 0x00;
+	uint8_t ddrE = 0x00;
+	uint8_t ddrF = 0x00;
+
+	// Loop through all the pin assignments, for the initial pin settings
+	int row, col;
+
+	// Rows
+	for ( row = 1; row < sizeof(matrix); row++ ) {
+		switch ( matrix[row][col] ) {
+		PIN_CASE(A):
+			PIN_SET_ROW(A);
+		PIN_CASE(B):
+			PIN_SET_ROW(B);
+		PIN_CASE(C):
+			PIN_SET_ROW(C);
+		PIN_CASE(D):
+			PIN_SET_ROW(D);
+		PIN_CASE(E):
+			PIN_SET_ROW(E);
+		PIN_CASE(F):
+			PIN_SET_ROW(F);
+
+		default:
+			continue;
+		}
+	}
+
+	// Columns
+	for ( col = 1; col < sizeof(matrix[0]); row++ ) {
+		switch ( matrix[row][col] ) {
+		PIN_CASE(A):
+			PIN_SET_COL(A);
+		PIN_CASE(B):
+			PIN_SET_COL(B);
+		PIN_CASE(C):
+			PIN_SET_COL(C);
+		PIN_CASE(D):
+			PIN_SET_COL(D);
+		PIN_CASE(E):
+			PIN_SET_COL(E);
+		PIN_CASE(F):
+			PIN_SET_COL(F);
+
+		default:
+			continue;
+		}
+	}
+
+	// Setting the pins
+	DDRA = ddrA;
+	DDRB = ddrB;
+	DDRC = ddrC;
+	DDRD = ddrD;
+	DDRE = ddrE;
+	DDRF = ddrF;
+
+	PORTA = portA;
+	PORTB = portB;
+	PORTC = portC;
+	PORTD = portD;
+	PORTE = portE;
+	PORTF = portF;
+}
+
+// TODO Proper matrix scanning
+void matrix_scan( uint8_t *matrix, uint8_t *detectArray )
+{
+	// Column Scan
+#if scanMode == scanCol
+	uint8_t col = 1;
+	uint8_t row = 1;
+	for ( ; col < sizeof(matrix[1]); col++ ) {
+		switch ( matrix[0][col] / 10 ) {
+		case 0: // PINA
+			PIN_TEST_COL(PINA);
+		case 1: // PINB
+			PIN_TEST_COL(PINB);
+		case 2: // PINC
+			PIN_TEST_COL(PINC);
+		case 3: // PIND
+			PIN_TEST_COL(PIND);
+		case 4: // PINE
+			PIN_TEST_COL(PINE);
+		case 5: // PINF
+			PIN_TEST_COL(PINF);
+		}
+	}
+#endif
+
+	// Row Scan
+#if scanMode == scanRow
+#endif
+
+	// Column Scan, Power Row
+#if scanMode == scanCol_powrRow
+#endif
+
+	// Row Scan, Power Column
+#if scanMode == scanRow_powrCol
+#endif
+
+	// Dual Scan
+#if scanMode == scanDual
+#endif
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Scan/matrix/matrix.h	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,151 @@
+/* Copyright (C) 2011 by Jacob Alexander
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef __MATRIX_H
+#define __MATRIX_H
+
+// ----- Quick Map (don't change) -----
+#define pinA0  0
+#define pinA1  1
+#define pinA2  2
+#define pinA3  3
+#define pinA4  4
+#define pinA5  5
+#define pinA6  6
+#define pinA7  7
+
+#define pinB0 10
+#define pinB1 11
+#define pinB2 12
+#define pinB3 13
+#define pinB4 14
+#define pinB5 15
+#define pinB6 16
+#define pinB7 17
+
+#define pinC0 20
+#define pinC1 21
+#define pinC2 22
+#define pinC3 23
+#define pinC4 24
+#define pinC5 25
+#define pinC6 26
+#define pinC7 27
+
+#define pinD0 30
+#define pinD1 31
+#define pinD2 32
+#define pinD3 33
+#define pinD4 34
+#define pinD5 35
+#define pinD6 36
+#define pinD7 37
+
+#define pinE0 40
+#define pinE1 41
+#define pinE2 42
+#define pinE3 43
+#define pinE4 44
+#define pinE5 45
+#define pinE6 46
+#define pinE7 47
+
+#define pinF0 50
+#define pinF1 51
+#define pinF2 52
+#define pinF3 53
+#define pinF4 54
+#define pinF5 55
+#define pinF6 56
+#define pinF7 57
+
+#define pinNULL 128
+
+
+
+// ----- Scan Mode (usually dual-scan) -----
+// Ordered by increasing memory/CPU usage
+#define scanRow         0  // Needed for powered switches (Hall-Effect)
+#define scanCol         1  // Opposite of scanRow
+#define scanRow_powrCol 2  // NKRO supported (simple detection)
+#define scanCol_powrRow 3  // Opposite of scanRow_powrCol
+#define scanDual        4  // Typical ~2KRO matrix
+
+
+
+// ----- Scan Mode Setting -----
+#define scanMode scanCol
+
+
+
+// ----- Key Settings -----
+#define keyboardSize 16  // # of keys
+
+
+
+// ----- Matrix Configuration -----
+static uint8_t matrix_pinout[][] = {
+
+
+
+// Just layout the matrix by rows and columns
+// Usually you'll want to set the scanMode above to scanDual or scanCol_powrRow/scanRow_powrCol
+// The mode allows for optimization in the kind of scanning algorithms that are done
+// 
+// The key numbers are used to translate into the keymap table (array) (and always start from 1, not 0).
+// See the keymap.h file for the various preconfigured arrays.
+
+// Scan Mode | Col 1 | Col 2 | Col 3 | Col 4 | Col 4 | ...
+// -------------------------------------------------------
+//     Row 1 | Key 1   Key 7   Key32    ...
+//     Row 2 | Key 3   Key92    ...
+//     Row 3 | Key23    ...
+//     Row 4 |  ...
+//     Row 5 |
+//      ...  |
+
+
+  { scanMode, pinF4, pinA6, pinA1, pinA3, pinF5, pinA5, pinA2, pinF0, pinF6, pinA7, pinA0, pinF1, pinF3, pinF7, pinA4, pinF2 },
+  { pinNULL,  1,     2,     3,     4,     5,     6,     7,     8,     9,     10,    11,    12,    13,    14,    15,    16    },
+
+
+// Example Rows
+//{ pinE0,    1,     2,     3,     4,     5,     6,     7,     8,     9,     10,    11,    12,    13,    14,    15,    16    },
+//{ pinE1,   21,    22,    23,    24,    25,    26,    27,    28,    29,     30,    31,    32,    33,    34,                 },
+
+
+};
+
+
+// ----- Variables -----
+
+// NOTE: Highest Bit: Valid keypress (0x80 is valid keypress)
+//        Other Bits: Pressed state sample counter
+uint8_t keyboardDetectArray[keyboardSize + 1];
+
+
+
+// ----- Functions -----
+
+
+#endif // __MATRIX_H
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Scan/matrix/scan_loop.c	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,137 @@
+/* Copyright (C) 2011 by Jacob Alexander
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+#include <stdint.h>
+#include <usb_keyboard_debug.h>
+#include <keymap.h>
+// Debouncing Defines
+#define SAMPLE_THRESHOLD 110
+#define MAX_SAMPLES 127 // Max is 127, reaching 128 is very bad
+// Loop over all of the sampled keys of the given array
+// If the number of samples is higher than the sample threshold, flag the high bit, clear otherwise
+// This should be resetting VERY quickly, cutting off a potentially valid keypress is not an issue
+#define DEBOUNCE_ASSESS(table,size) \
+			for ( uint8_t key = 1; key < size + 1; key++ ) {\
+				table[key] = ( table[key] & ~(1 << 7) ) > SAMPLE_THRESHOLD ? (1 << 7) : 0x00; \
+			} \
+
+// NOTE: Highest Bit: Valid keypress (0x80 is valid keypress)
+//        Other Bits: Pressed state sample counter
+#define KEYBOARD_SIZE 23
+uint8_t keyboardDetectArray[KEYBOARD_SIZE + 1];
+
+// Interrupt Variable
+volatile uint8_t sendKeypresses = 0;
+
+// USB Data Send
+void usb_send( uint8_t validKeys )
+{
+		// TODO undo potentially old keys
+		for ( uint8_t c = validKeys; c < 6; c++ )
+			keyboard_keys[c] = 0;
+
+		// Send keypresses
+		usb_keyboard_send();
+
+		// Clear sendKeypresses Flag
+		sendKeypresses = 0;
+
+		// Clear modifiers
+		keyboard_modifier_keys = 0;
+}
+
+
+// Given a sampling array, and the current number of detected keypress
+// Add as many keypresses from the sampling array to the USB key send array as possible.
+void keyPressDetection( uint8_t *keys, uint8_t *validKeys, uint8_t numberOfKeys, uint8_t *modifiers, uint8_t numberOfModifiers, uint8_t *map ) {
+	for ( uint8_t key = 0; key < numberOfKeys + 1; key++ ) {
+		if ( keys[key] & (1 << 7) ) {
+			pint8( key );
+			//print(" ");
+			uint8_t modFound = 0;
+
+			// Determine if the key is a modifier
+			for ( uint8_t mod = 0; mod < numberOfModifiers; mod++ ) {
+				// Modifier found
+				if ( modifiers[mod] == key ) {
+					keyboard_modifier_keys |= map[key];
+					modFound = 1;
+					break;
+				}
+			}
+			if ( modFound )
+				continue;
+
+			// Too many keys
+			if ( *validKeys == 6 )
+				break;
+
+			// Allow ignoring keys with 0's
+			if ( map[key] != 0 )
+				keyboard_keys[(*validKeys)++] = map[key];
+		}
+	}
+}
+
+
+// Main Detection Loop
+void scan_loop( void )
+{
+	//matrix_pinSetup( matrix_pinout );
+	uint8_t count = 0;
+
+	for ( ;; ) {
+		//matrix_scan( matrix_pinout, keyboardDetectArray );
+
+		// Check count to see if the sample threshold may have been reached, otherwise collect more data
+		if ( count++ < MAX_SAMPLES )
+			continue;
+
+		// Reset Sample Counter
+		count = 0;
+
+		// Assess debouncing sample table
+		//DEBOUNCE_ASSESS(keyDetectArray,KEYBOARD_SIZE)
+
+		// Send keypresses over USB if the ISR has signalled that it's time
+		if ( !sendKeypresses )
+			continue;
+
+		// Layout Setup
+		uint8_t validKeys = 0;
+
+		uint8_t *keyboard_MODMASK = keyboard_modifierMask;
+		uint8_t  keyboard_NUMMODS = MODIFIERS_KEYBOARD;
+		uint8_t *keyboard_MAP     = defaultMap;
+
+		// TODO Layout Switching
+
+		// TODO Macro Processing
+
+		// Debounce Sampling Array to USB Data Array
+		keyPressDetection( keyboardDetectArray, &validKeys, KEYBOARD_SIZE, keyboard_MODMASK, keyboard_NUMMODS, keyboard_MAP );
+
+		// Send USB Data
+		usb_send( validKeys );
+	}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Scan/matrix/scan_loop.h	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,31 @@
+/* Copyright (C) 2011 by Jacob Alexander
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef __SCAN_LOOP_H
+#define __SCAN_LOOP_H
+
+//extern uint8_t keyboardDetectArray[KEYBOARDZ
+extern volatile uint8_t sendKeypresses;
+
+void scan_loop( void );
+
+#endif // __SCAN_LOOP_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Scan/matrix/setup.cmake	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,23 @@
+###| CMake Kiibohd Controller Scan Module |###
+#
+# Written by Jacob Alexander in 2011 for the Kiibohd Controller
+#
+# Released into the Public Domain
+#
+###
+
+
+###
+# Module C files
+#
+
+set( SCAN_SRCS
+	scan_loop.c
+)
+
+
+###
+# Module Specific Options TODO Fixme!! (../)
+#
+add_definitions( -I../Keymap )
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USB/pjrc/setup.cmake	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,22 @@
+###| CMake Kiibohd Controller USB Module |###
+#
+# Written by Jacob Alexander in 2011 for the Kiibohd Controller
+#
+# Released into the Public Domain
+#
+###
+
+
+###
+# Module C files
+#
+
+set( USB_SRCS
+	usb_keyboard_debug.c
+)
+
+
+###
+# Module Specific Options
+#
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USB/pjrc/usb_keyboard.c	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,592 @@
+/* USB Keyboard Example for Teensy USB Development Board
+ * http://www.pjrc.com/teensy/usb_keyboard.html
+ * Copyright (c) 2009 PJRC.COM, LLC
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+// Version 1.0: Initial Release
+// Version 1.1: Add support for Teensy 2.0
+
+#define USB_SERIAL_PRIVATE_INCLUDE
+#include "usb_keyboard.h"
+
+/**************************************************************************
+ *
+ *  Configurable Options
+ *
+ **************************************************************************/
+
+// You can change these to give your code its own name.
+#define STR_MANUFACTURER	L"MfgName"
+#define STR_PRODUCT		L"Keyboard"
+
+
+// Mac OS-X and Linux automatically load the correct drivers.  On
+// Windows, even though the driver is supplied by Microsoft, an
+// INF file is needed to load the driver.  These numbers need to
+// match the INF file.
+#define VENDOR_ID		0x16C0
+#define PRODUCT_ID		0x047C
+
+
+// USB devices are supposed to implment a halt feature, which is
+// rarely (if ever) used.  If you comment this line out, the halt
+// code will be removed, saving 102 bytes of space (gcc 4.3.0).
+// This is not strictly USB compliant, but works with all major
+// operating systems.
+#define SUPPORT_ENDPOINT_HALT
+
+
+
+/**************************************************************************
+ *
+ *  Endpoint Buffer Configuration
+ *
+ **************************************************************************/
+
+#define ENDPOINT0_SIZE		32
+
+#define KEYBOARD_INTERFACE	0
+#define KEYBOARD_ENDPOINT	3
+#define KEYBOARD_SIZE		8
+#define KEYBOARD_BUFFER		EP_DOUBLE_BUFFER
+
+static const uint8_t PROGMEM endpoint_config_table[] = {
+	0,
+	0,
+	1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER,
+	0
+};
+
+
+/**************************************************************************
+ *
+ *  Descriptor Data
+ *
+ **************************************************************************/
+
+// Descriptors are the data that your computer reads when it auto-detects
+// this USB device (called "enumeration" in USB lingo).  The most commonly
+// changed items are editable at the top of this file.  Changing things
+// in here should only be done by those who've read chapter 9 of the USB
+// spec and relevant portions of any USB class specifications!
+
+
+static uint8_t PROGMEM device_descriptor[] = {
+	18,					// bLength
+	1,					// bDescriptorType
+	0x00, 0x02,				// bcdUSB
+	0,					// bDeviceClass
+	0,					// bDeviceSubClass
+	0,					// bDeviceProtocol
+	ENDPOINT0_SIZE,				// bMaxPacketSize0
+	LSB(VENDOR_ID), MSB(VENDOR_ID),		// idVendor
+	LSB(PRODUCT_ID), MSB(PRODUCT_ID),	// idProduct
+	0x00, 0x01,				// bcdDevice
+	1,					// iManufacturer
+	2,					// iProduct
+	0,					// iSerialNumber
+	1					// bNumConfigurations
+};
+
+// Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
+static uint8_t PROGMEM keyboard_hid_report_desc[] = {
+        0x05, 0x01,          // Usage Page (Generic Desktop),
+        0x09, 0x06,          // Usage (Keyboard),
+        0xA1, 0x01,          // Collection (Application),
+        0x75, 0x01,          //   Report Size (1),
+        0x95, 0x08,          //   Report Count (8),
+        0x05, 0x07,          //   Usage Page (Key Codes),
+        0x19, 0xE0,          //   Usage Minimum (224),
+        0x29, 0xE7,          //   Usage Maximum (231),
+        0x15, 0x00,          //   Logical Minimum (0),
+        0x25, 0x01,          //   Logical Maximum (1),
+        0x81, 0x02,          //   Input (Data, Variable, Absolute), ;Modifier byte
+        0x95, 0x01,          //   Report Count (1),
+        0x75, 0x08,          //   Report Size (8),
+        0x81, 0x03,          //   Input (Constant),                 ;Reserved byte
+        0x95, 0x05,          //   Report Count (5),
+        0x75, 0x01,          //   Report Size (1),
+        0x05, 0x08,          //   Usage Page (LEDs),
+        0x19, 0x01,          //   Usage Minimum (1),
+        0x29, 0x05,          //   Usage Maximum (5),
+        0x91, 0x02,          //   Output (Data, Variable, Absolute), ;LED report
+        0x95, 0x01,          //   Report Count (1),
+        0x75, 0x03,          //   Report Size (3),
+        0x91, 0x03,          //   Output (Constant),                 ;LED report padding
+        0x95, 0x06,          //   Report Count (6),
+        0x75, 0x08,          //   Report Size (8),
+        0x15, 0x00,          //   Logical Minimum (0),
+        0x25, 0x68,          //   Logical Maximum(104),
+        0x05, 0x07,          //   Usage Page (Key Codes),
+        0x19, 0x00,          //   Usage Minimum (0),
+        0x29, 0x68,          //   Usage Maximum (104),
+        0x81, 0x00,          //   Input (Data, Array),
+        0xc0                 // End Collection
+};
+
+#define CONFIG1_DESC_SIZE        (9+9+9+7)
+#define KEYBOARD_HID_DESC_OFFSET (9+9)
+static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
+	// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
+	9, 					// bLength;
+	2,					// bDescriptorType;
+	LSB(CONFIG1_DESC_SIZE),			// wTotalLength
+	MSB(CONFIG1_DESC_SIZE),
+	1,					// bNumInterfaces
+	1,					// bConfigurationValue
+	0,					// iConfiguration
+	0xC0,					// bmAttributes
+	50,					// bMaxPower
+	// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
+	9,					// bLength
+	4,					// bDescriptorType
+	KEYBOARD_INTERFACE,			// bInterfaceNumber
+	0,					// bAlternateSetting
+	1,					// bNumEndpoints
+	0x03,					// bInterfaceClass (0x03 = HID)
+	0x01,					// bInterfaceSubClass (0x01 = Boot)
+	0x01,					// bInterfaceProtocol (0x01 = Keyboard)
+	0,					// iInterface
+	// HID interface descriptor, HID 1.11 spec, section 6.2.1
+	9,					// bLength
+	0x21,					// bDescriptorType
+	0x11, 0x01,				// bcdHID
+	0,					// bCountryCode
+	1,					// bNumDescriptors
+	0x22,					// bDescriptorType
+	sizeof(keyboard_hid_report_desc),	// wDescriptorLength
+	0,
+	// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+	7,					// bLength
+	5,					// bDescriptorType
+	KEYBOARD_ENDPOINT | 0x80,		// bEndpointAddress
+	0x03,					// bmAttributes (0x03=intr)
+	KEYBOARD_SIZE, 0,			// wMaxPacketSize
+	1					// bInterval
+};
+
+// If you're desperate for a little extra code memory, these strings
+// can be completely removed if iManufacturer, iProduct, iSerialNumber
+// in the device desciptor are changed to zeros.
+struct usb_string_descriptor_struct {
+	uint8_t bLength;
+	uint8_t bDescriptorType;
+	int16_t wString[];
+};
+static struct usb_string_descriptor_struct PROGMEM string0 = {
+	4,
+	3,
+	{0x0409}
+};
+static struct usb_string_descriptor_struct PROGMEM string1 = {
+	sizeof(STR_MANUFACTURER),
+	3,
+	STR_MANUFACTURER
+};
+static struct usb_string_descriptor_struct PROGMEM string2 = {
+	sizeof(STR_PRODUCT),
+	3,
+	STR_PRODUCT
+};
+
+// This table defines which descriptor data is sent for each specific
+// request from the host (in wValue and wIndex).
+static struct descriptor_list_struct {
+	uint16_t	wValue;
+	uint16_t	wIndex;
+	const uint8_t	*addr;
+	uint8_t		length;
+} PROGMEM descriptor_list[] = {
+	{0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
+	{0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
+	{0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
+	{0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9},
+	{0x0300, 0x0000, (const uint8_t *)&string0, 4},
+	{0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
+	{0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}
+};
+#define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
+
+
+/**************************************************************************
+ *
+ *  Variables - these are the only non-stack RAM usage
+ *
+ **************************************************************************/
+
+// zero when we are not configured, non-zero when enumerated
+static volatile uint8_t usb_configuration=0;
+
+// which modifier keys are currently pressed
+// 1=left ctrl,    2=left shift,   4=left alt,    8=left gui
+// 16=right ctrl, 32=right shift, 64=right alt, 128=right gui
+uint8_t keyboard_modifier_keys=0;
+
+// which keys are currently pressed, up to 6 keys may be down at once
+uint8_t keyboard_keys[6]={0,0,0,0,0,0};
+
+// protocol setting from the host.  We use exactly the same report
+// either way, so this variable only stores the setting since we
+// are required to be able to report which setting is in use.
+static uint8_t keyboard_protocol=1;
+
+// the idle configuration, how often we send the report to the
+// host (ms * 4) even when it hasn't changed
+static uint8_t keyboard_idle_config=125;
+
+// count until idle timeout
+static uint8_t keyboard_idle_count=0;
+
+// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
+volatile uint8_t keyboard_leds=0;
+
+
+/**************************************************************************
+ *
+ *  Public Functions - these are the API intended for the user
+ *
+ **************************************************************************/
+
+
+// initialize USB
+void usb_init(void)
+{
+	HW_CONFIG();
+	USB_FREEZE();	// enable USB
+	PLL_CONFIG();				// config PLL
+        while (!(PLLCSR & (1<<PLOCK))) ;	// wait for PLL lock
+        USB_CONFIG();				// start USB clock
+        UDCON = 0;				// enable attach resistor
+	usb_configuration = 0;
+        UDIEN = (1<<EORSTE)|(1<<SOFE);
+	sei();
+}
+
+// return 0 if the USB is not configured, or the configuration
+// number selected by the HOST
+uint8_t usb_configured(void)
+{
+	return usb_configuration;
+}
+
+
+// perform a single keystroke
+int8_t usb_keyboard_press(uint8_t key, uint8_t modifier)
+{
+	int8_t r;
+
+	keyboard_modifier_keys = modifier;
+	keyboard_keys[0] = key;
+	r = usb_keyboard_send();
+	if (r) return r;
+	keyboard_modifier_keys = 0;
+	keyboard_keys[0] = 0;
+	return usb_keyboard_send();
+}
+
+// send the contents of keyboard_keys and keyboard_modifier_keys
+int8_t usb_keyboard_send(void)
+{
+	uint8_t i, intr_state, timeout;
+
+	if (!usb_configuration) return -1;
+	intr_state = SREG;
+	cli();
+	UENUM = KEYBOARD_ENDPOINT;
+	timeout = UDFNUML + 50;
+	while (1) {
+		// are we ready to transmit?
+		if (UEINTX & (1<<RWAL)) break;
+		SREG = intr_state;
+		// has the USB gone offline?
+		if (!usb_configuration) return -1;
+		// have we waited too long?
+		if (UDFNUML == timeout) return -1;
+		// get ready to try checking again
+		intr_state = SREG;
+		cli();
+		UENUM = KEYBOARD_ENDPOINT;
+	}
+	UEDATX = keyboard_modifier_keys;
+	UEDATX = 0;
+	for (i=0; i<6; i++) {
+		UEDATX = keyboard_keys[i];
+	}
+	UEINTX = 0x3A;
+	keyboard_idle_count = 0;
+	SREG = intr_state;
+	return 0;
+}
+
+/**************************************************************************
+ *
+ *  Private Functions - not intended for general user consumption....
+ *
+ **************************************************************************/
+
+
+
+// USB Device Interrupt - handle all device-level events
+// the transmit buffer flushing is triggered by the start of frame
+//
+ISR(USB_GEN_vect)
+{
+	uint8_t intbits, t, i;
+	static uint8_t div4=0;
+
+        intbits = UDINT;
+        UDINT = 0;
+        if (intbits & (1<<EORSTI)) {
+		UENUM = 0;
+		UECONX = 1;
+		UECFG0X = EP_TYPE_CONTROL;
+		UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
+		UEIENX = (1<<RXSTPE);
+		usb_configuration = 0;
+        }
+	if ((intbits & (1<<SOFI)) && usb_configuration) {
+		if (keyboard_idle_config && (++div4 & 3) == 0) {
+			UENUM = KEYBOARD_ENDPOINT;
+			if (UEINTX & (1<<RWAL)) {
+				keyboard_idle_count++;
+				if (keyboard_idle_count == keyboard_idle_config) {
+					keyboard_idle_count = 0;
+					UEDATX = keyboard_modifier_keys;
+					UEDATX = 0;
+					for (i=0; i<6; i++) {
+						UEDATX = keyboard_keys[i];
+					}
+					UEINTX = 0x3A;
+				}
+			}
+		}
+	}
+}
+
+
+
+// Misc functions to wait for ready and send/receive packets
+static inline void usb_wait_in_ready(void)
+{
+	while (!(UEINTX & (1<<TXINI))) ;
+}
+static inline void usb_send_in(void)
+{
+	UEINTX = ~(1<<TXINI);
+}
+static inline void usb_wait_receive_out(void)
+{
+	while (!(UEINTX & (1<<RXOUTI))) ;
+}
+static inline void usb_ack_out(void)
+{
+	UEINTX = ~(1<<RXOUTI);
+}
+
+
+
+// USB Endpoint Interrupt - endpoint 0 is handled here.  The
+// other endpoints are manipulated by the user-callable
+// functions, and the start-of-frame interrupt.
+//
+ISR(USB_COM_vect)
+{
+        uint8_t intbits;
+	const uint8_t *list;
+        const uint8_t *cfg;
+	uint8_t i, n, len, en;
+	uint8_t bmRequestType;
+	uint8_t bRequest;
+	uint16_t wValue;
+	uint16_t wIndex;
+	uint16_t wLength;
+	uint16_t desc_val;
+	const uint8_t *desc_addr;
+	uint8_t	desc_length;
+
+        UENUM = 0;
+	intbits = UEINTX;
+        if (intbits & (1<<RXSTPI)) {
+                bmRequestType = UEDATX;
+                bRequest = UEDATX;
+                wValue = UEDATX;
+                wValue |= (UEDATX << 8);
+                wIndex = UEDATX;
+                wIndex |= (UEDATX << 8);
+                wLength = UEDATX;
+                wLength |= (UEDATX << 8);
+                UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
+                if (bRequest == GET_DESCRIPTOR) {
+			list = (const uint8_t *)descriptor_list;
+			for (i=0; ; i++) {
+				if (i >= NUM_DESC_LIST) {
+					UECONX = (1<<STALLRQ)|(1<<EPEN);  //stall
+					return;
+				}
+				desc_val = pgm_read_word(list);
+				if (desc_val != wValue) {
+					list += sizeof(struct descriptor_list_struct);
+					continue;
+				}
+				list += 2;
+				desc_val = pgm_read_word(list);
+				if (desc_val != wIndex) {
+					list += sizeof(struct descriptor_list_struct)-2;
+					continue;
+				}
+				list += 2;
+				desc_addr = (const uint8_t *)pgm_read_word(list);
+				list += 2;
+				desc_length = pgm_read_byte(list);
+				break;
+			}
+			len = (wLength < 256) ? wLength : 255;
+			if (len > desc_length) len = desc_length;
+			do {
+				// wait for host ready for IN packet
+				do {
+					i = UEINTX;
+				} while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
+				if (i & (1<<RXOUTI)) return;	// abort
+				// send IN packet
+				n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
+				for (i = n; i; i--) {
+					UEDATX = pgm_read_byte(desc_addr++);
+				}
+				len -= n;
+				usb_send_in();
+			} while (len || n == ENDPOINT0_SIZE);
+			return;
+                }
+		if (bRequest == SET_ADDRESS) {
+			usb_send_in();
+			usb_wait_in_ready();
+			UDADDR = wValue | (1<<ADDEN);
+			return;
+		}
+		if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
+			usb_configuration = wValue;
+			usb_send_in();
+			cfg = endpoint_config_table;
+			for (i=1; i<5; i++) {
+				UENUM = i;
+				en = pgm_read_byte(cfg++);
+				UECONX = en;
+				if (en) {
+					UECFG0X = pgm_read_byte(cfg++);
+					UECFG1X = pgm_read_byte(cfg++);
+				}
+			}
+        		UERST = 0x1E;
+        		UERST = 0;
+			return;
+		}
+		if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
+			usb_wait_in_ready();
+			UEDATX = usb_configuration;
+			usb_send_in();
+			return;
+		}
+
+		if (bRequest == GET_STATUS) {
+			usb_wait_in_ready();
+			i = 0;
+			#ifdef SUPPORT_ENDPOINT_HALT
+			if (bmRequestType == 0x82) {
+				UENUM = wIndex;
+				if (UECONX & (1<<STALLRQ)) i = 1;
+				UENUM = 0;
+			}
+			#endif
+			UEDATX = i;
+			UEDATX = 0;
+			usb_send_in();
+			return;
+		}
+		#ifdef SUPPORT_ENDPOINT_HALT
+		if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
+		  && bmRequestType == 0x02 && wValue == 0) {
+			i = wIndex & 0x7F;
+			if (i >= 1 && i <= MAX_ENDPOINT) {
+				usb_send_in();
+				UENUM = i;
+				if (bRequest == SET_FEATURE) {
+					UECONX = (1<<STALLRQ)|(1<<EPEN);
+				} else {
+					UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
+					UERST = (1 << i);
+					UERST = 0;
+				}
+				return;
+			}
+		}
+		#endif
+		if (wIndex == KEYBOARD_INTERFACE) {
+			if (bmRequestType == 0xA1) {
+				if (bRequest == HID_GET_REPORT) {
+					usb_wait_in_ready();
+					UEDATX = keyboard_modifier_keys;
+					UEDATX = 0;
+					for (i=0; i<6; i++) {
+						UEDATX = keyboard_keys[i];
+					}
+					usb_send_in();
+					return;
+				}
+				if (bRequest == HID_GET_IDLE) {
+					usb_wait_in_ready();
+					UEDATX = keyboard_idle_config;
+					usb_send_in();
+					return;
+				}
+				if (bRequest == HID_GET_PROTOCOL) {
+					usb_wait_in_ready();
+					UEDATX = keyboard_protocol;
+					usb_send_in();
+					return;
+				}
+			}
+			if (bmRequestType == 0x21) {
+				if (bRequest == HID_SET_REPORT) {
+					usb_wait_receive_out();
+					keyboard_leds = UEDATX;
+					usb_ack_out();
+					usb_send_in();
+					return;
+				}
+				if (bRequest == HID_SET_IDLE) {
+					keyboard_idle_config = (wValue >> 8);
+					keyboard_idle_count = 0;
+					usb_send_in();
+					return;
+				}
+				if (bRequest == HID_SET_PROTOCOL) {
+					keyboard_protocol = wValue;
+					usb_send_in();
+					return;
+				}
+			}
+		}
+	}
+	UECONX = (1<<STALLRQ) | (1<<EPEN);	// stall
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USB/pjrc/usb_keyboard.h	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,16 @@
+#ifndef usb_serial_h__
+#define usb_serial_h__
+
+#include <stdint.h>
+
+void usb_init(void);			// initialize everything
+uint8_t usb_configured(void);		// is the USB port configured
+
+int8_t usb_keyboard_press(uint8_t key, uint8_t modifier);
+int8_t usb_keyboard_send(void);
+extern uint8_t keyboard_modifier_keys;
+extern uint8_t keyboard_keys[6];
+extern volatile uint8_t keyboard_leds;
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USB/pjrc/usb_keyboard_debug.c	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,750 @@
+/* USB Keyboard Plus Debug Channel Example for Teensy USB Development Board
+ * http://www.pjrc.com/teensy/usb_keyboard.html
+ * Copyright (c) 2009 PJRC.COM, LLC
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+// Version 1.0: Initial Release
+// Version 1.1: Add support for Teensy 2.0
+
+#define USB_SERIAL_PRIVATE_INCLUDE
+#include "usb_keyboard_debug.h"
+
+/**************************************************************************
+ *
+ *  Configurable Options
+ *
+ **************************************************************************/
+
+// You can change these to give your code its own name.
+#define STR_MANUFACTURER	L"MfgName"
+#define STR_PRODUCT		L"Keyboard"
+
+
+// Mac OS-X and Linux automatically load the correct drivers.  On
+// Windows, even though the driver is supplied by Microsoft, an
+// INF file is needed to load the driver.  These numbers need to
+// match the INF file.
+#define VENDOR_ID		0x16C0
+#define PRODUCT_ID		0x047D
+
+
+// USB devices are supposed to implment a halt feature, which is
+// rarely (if ever) used.  If you comment this line out, the halt
+// code will be removed, saving 102 bytes of space (gcc 4.3.0).
+// This is not strictly USB compliant, but works with all major
+// operating systems.
+#define SUPPORT_ENDPOINT_HALT
+
+
+
+/**************************************************************************
+ *
+ *  Endpoint Buffer Configuration
+ *
+ **************************************************************************/
+
+#define ENDPOINT0_SIZE		32
+
+#define KEYBOARD_INTERFACE	0
+#define KEYBOARD_ENDPOINT	3
+#define KEYBOARD_SIZE		8
+#define KEYBOARD_BUFFER		EP_DOUBLE_BUFFER
+
+#define DEBUG_INTERFACE		1
+#define DEBUG_TX_ENDPOINT	4
+#define DEBUG_TX_SIZE		32
+#define DEBUG_TX_BUFFER		EP_DOUBLE_BUFFER
+
+static const uint8_t PROGMEM endpoint_config_table[] = {
+	0,
+	0,
+	1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER,
+	1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER
+};
+
+
+/**************************************************************************
+ *
+ *  Descriptor Data
+ *
+ **************************************************************************/
+
+// Descriptors are the data that your computer reads when it auto-detects
+// this USB device (called "enumeration" in USB lingo).  The most commonly
+// changed items are editable at the top of this file.  Changing things
+// in here should only be done by those who've read chapter 9 of the USB
+// spec and relevant portions of any USB class specifications!
+
+
+static const uint8_t PROGMEM device_descriptor[] = {
+	18,					// bLength
+	1,					// bDescriptorType
+	0x00, 0x02,				// bcdUSB
+	0,					// bDeviceClass
+	0,					// bDeviceSubClass
+	0,					// bDeviceProtocol
+	ENDPOINT0_SIZE,				// bMaxPacketSize0
+	LSB(VENDOR_ID), MSB(VENDOR_ID),		// idVendor
+	LSB(PRODUCT_ID), MSB(PRODUCT_ID),	// idProduct
+	0x00, 0x01,				// bcdDevice
+	1,					// iManufacturer
+	2,					// iProduct
+	0,					// iSerialNumber
+	1					// bNumConfigurations
+};
+
+// Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
+static const uint8_t PROGMEM keyboard_hid_report_desc[] = {
+        0x05, 0x01,          // Usage Page (Generic Desktop),
+        0x09, 0x06,          // Usage (Keyboard),
+        0xA1, 0x01,          // Collection (Application),
+        0x75, 0x01,          //   Report Size (1),
+        0x95, 0x08,          //   Report Count (8),
+        0x05, 0x07,          //   Usage Page (Key Codes),
+        0x19, 0xE0,          //   Usage Minimum (224),
+        0x29, 0xE7,          //   Usage Maximum (231),
+        0x15, 0x00,          //   Logical Minimum (0),
+        0x25, 0x01,          //   Logical Maximum (1),
+        0x81, 0x02,          //   Input (Data, Variable, Absolute), ;Modifier byte
+        0x95, 0x01,          //   Report Count (1),
+        0x75, 0x08,          //   Report Size (8),
+        0x81, 0x03,          //   Input (Constant),                 ;Reserved byte
+        0x95, 0x05,          //   Report Count (5),
+        0x75, 0x01,          //   Report Size (1),
+        0x05, 0x08,          //   Usage Page (LEDs),
+        0x19, 0x01,          //   Usage Minimum (1),
+        0x29, 0x05,          //   Usage Maximum (5),
+        0x91, 0x02,          //   Output (Data, Variable, Absolute), ;LED report
+        0x95, 0x01,          //   Report Count (1),
+        0x75, 0x03,          //   Report Size (3),
+        0x91, 0x03,          //   Output (Constant),                 ;LED report padding
+        0x95, 0x06,          //   Report Count (6),
+        0x75, 0x08,          //   Report Size (8),
+        0x15, 0x00,          //   Logical Minimum (0),
+        0x25, 0x68,          //   Logical Maximum(104),
+        0x05, 0x07,          //   Usage Page (Key Codes),
+        0x19, 0x00,          //   Usage Minimum (0),
+        0x29, 0x68,          //   Usage Maximum (104),
+        0x81, 0x00,          //   Input (Data, Array),
+        0xc0                 // End Collection
+};
+
+static const uint8_t PROGMEM debug_hid_report_desc[] = {
+	0x06, 0x31, 0xFF,			// Usage Page 0xFF31 (vendor defined)
+	0x09, 0x74,				// Usage 0x74
+	0xA1, 0x53,				// Collection 0x53
+	0x75, 0x08,				// report size = 8 bits
+	0x15, 0x00,				// logical minimum = 0
+	0x26, 0xFF, 0x00,			// logical maximum = 255
+	0x95, DEBUG_TX_SIZE,			// report count
+	0x09, 0x75,				// usage
+	0x81, 0x02,				// Input (array)
+	0xC0					// end collection
+};
+
+#define CONFIG1_DESC_SIZE        (9+9+9+7+9+9+7)
+#define KEYBOARD_HID_DESC_OFFSET (9+9)
+#define DEBUG_HID_DESC_OFFSET    (9+9+9+7+9)
+static const uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
+	// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
+	9, 					// bLength;
+	2,					// bDescriptorType;
+	LSB(CONFIG1_DESC_SIZE),			// wTotalLength
+	MSB(CONFIG1_DESC_SIZE),
+	2,					// bNumInterfaces
+	1,					// bConfigurationValue
+	0,					// iConfiguration
+	0xC0,					// bmAttributes
+	50,					// bMaxPower
+	// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
+	9,					// bLength
+	4,					// bDescriptorType
+	KEYBOARD_INTERFACE,			// bInterfaceNumber
+	0,					// bAlternateSetting
+	1,					// bNumEndpoints
+	0x03,					// bInterfaceClass (0x03 = HID)
+	0x01,					// bInterfaceSubClass (0x01 = Boot)
+	0x01,					// bInterfaceProtocol (0x01 = Keyboard)
+	0,					// iInterface
+	// HID interface descriptor, HID 1.11 spec, section 6.2.1
+	9,					// bLength
+	0x21,					// bDescriptorType
+	0x11, 0x01,				// bcdHID
+	0,					// bCountryCode
+	1,					// bNumDescriptors
+	0x22,					// bDescriptorType
+	sizeof(keyboard_hid_report_desc),	// wDescriptorLength
+	0,
+	// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+	7,					// bLength
+	5,					// bDescriptorType
+	KEYBOARD_ENDPOINT | 0x80,		// bEndpointAddress
+	0x03,					// bmAttributes (0x03=intr)
+	KEYBOARD_SIZE, 0,			// wMaxPacketSize
+	1,					// bInterval
+	// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
+	9,					// bLength
+	4,					// bDescriptorType
+	DEBUG_INTERFACE,			// bInterfaceNumber
+	0,					// bAlternateSetting
+	1,					// bNumEndpoints
+	0x03,					// bInterfaceClass (0x03 = HID)
+	0x00,					// bInterfaceSubClass
+	0x00,					// bInterfaceProtocol
+	0,					// iInterface
+	// HID interface descriptor, HID 1.11 spec, section 6.2.1
+	9,					// bLength
+	0x21,					// bDescriptorType
+	0x11, 0x01,				// bcdHID
+	0,					// bCountryCode
+	1,					// bNumDescriptors
+	0x22,					// bDescriptorType
+	sizeof(debug_hid_report_desc),		// wDescriptorLength
+	0,
+	// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+	7,					// bLength
+	5,					// bDescriptorType
+	DEBUG_TX_ENDPOINT | 0x80,		// bEndpointAddress
+	0x03,					// bmAttributes (0x03=intr)
+	DEBUG_TX_SIZE, 0,			// wMaxPacketSize
+	1					// bInterval
+};
+
+// If you're desperate for a little extra code memory, these strings
+// can be completely removed if iManufacturer, iProduct, iSerialNumber
+// in the device desciptor are changed to zeros.
+struct usb_string_descriptor_struct {
+	uint8_t bLength;
+	uint8_t bDescriptorType;
+	int16_t wString[];
+};
+static const struct usb_string_descriptor_struct PROGMEM string0 = {
+	4,
+	3,
+	{0x0409}
+};
+static const struct usb_string_descriptor_struct PROGMEM string1 = {
+	sizeof(STR_MANUFACTURER),
+	3,
+	STR_MANUFACTURER
+};
+static const struct usb_string_descriptor_struct PROGMEM string2 = {
+	sizeof(STR_PRODUCT),
+	3,
+	STR_PRODUCT
+};
+
+// This table defines which descriptor data is sent for each specific
+// request from the host (in wValue and wIndex).
+static const struct descriptor_list_struct {
+	uint16_t	wValue;
+	uint16_t	wIndex;
+	const uint8_t	*addr;
+	uint8_t		length;
+} PROGMEM descriptor_list[] = {
+	{0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
+	{0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
+	{0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
+	{0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9},
+	{0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)},
+	{0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9},
+	{0x0300, 0x0000, (const uint8_t *)&string0, 4},
+	{0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
+	{0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}
+};
+#define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
+
+
+/**************************************************************************
+ *
+ *  Variables - these are the only non-stack RAM usage
+ *
+ **************************************************************************/
+
+// zero when we are not configured, non-zero when enumerated
+static volatile uint8_t usb_configuration=0;
+
+// the time remaining before we transmit any partially full
+// packet, or send a zero length packet.
+static volatile uint8_t debug_flush_timer=0;
+
+// which modifier keys are currently pressed
+// 1=left ctrl,    2=left shift,   4=left alt,    8=left gui
+// 16=right ctrl, 32=right shift, 64=right alt, 128=right gui
+uint8_t keyboard_modifier_keys=0;
+
+// which keys are currently pressed, up to 6 keys may be down at once
+uint8_t keyboard_keys[6]={0,0,0,0,0,0};
+
+// protocol setting from the host.  We use exactly the same report
+// either way, so this variable only stores the setting since we
+// are required to be able to report which setting is in use.
+static uint8_t keyboard_protocol=1;
+
+// the idle configuration, how often we send the report to the
+// host (ms * 4) even when it hasn't changed
+static uint8_t keyboard_idle_config=125;
+
+// count until idle timeout
+static uint8_t keyboard_idle_count=0;
+
+// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
+volatile uint8_t keyboard_leds=0;
+
+
+/**************************************************************************
+ *
+ *  Public Functions - these are the API intended for the user
+ *
+ **************************************************************************/
+
+
+// initialize USB
+void usb_init(void)
+{
+	HW_CONFIG();
+	USB_FREEZE();				// enable USB
+	PLL_CONFIG();				// config PLL
+        while (!(PLLCSR & (1<<PLOCK))) ;	// wait for PLL lock
+        USB_CONFIG();				// start USB clock
+        UDCON = 0;				// enable attach resistor
+	usb_configuration = 0;
+        UDIEN = (1<<EORSTE)|(1<<SOFE);
+	sei();
+}
+
+// return 0 if the USB is not configured, or the configuration
+// number selected by the HOST
+uint8_t usb_configured(void)
+{
+	return usb_configuration;
+}
+
+
+// perform a single keystroke
+int8_t usb_keyboard_press(uint8_t key, uint8_t modifier)
+{
+	int8_t r;
+
+	keyboard_modifier_keys = modifier;
+	keyboard_keys[0] = key;
+	r = usb_keyboard_send();
+	if (r) return r;
+	keyboard_modifier_keys = 0;
+	keyboard_keys[0] = 0;
+	return usb_keyboard_send();
+}
+
+// send the contents of keyboard_keys and keyboard_modifier_keys
+int8_t usb_keyboard_send(void)
+{
+	uint8_t i, intr_state, timeout;
+
+	if (!usb_configuration) return -1;
+	intr_state = SREG;
+	cli();
+	UENUM = KEYBOARD_ENDPOINT;
+	timeout = UDFNUML + 50;
+	while (1) {
+		// are we ready to transmit?
+		if (UEINTX & (1<<RWAL)) break;
+		SREG = intr_state;
+		// has the USB gone offline?
+		if (!usb_configuration) return -1;
+		// have we waited too long?
+		if (UDFNUML == timeout) return -1;
+		// get ready to try checking again
+		intr_state = SREG;
+		cli();
+		UENUM = KEYBOARD_ENDPOINT;
+	}
+	UEDATX = keyboard_modifier_keys;
+	UEDATX = 0;
+	for (i=0; i<6; i++) {
+		UEDATX = keyboard_keys[i];
+	}
+	UEINTX = 0x3A;
+	keyboard_idle_count = 0;
+	SREG = intr_state;
+	return 0;
+}
+
+// transmit a character.  0 returned on success, -1 on error
+int8_t usb_debug_putchar(uint8_t c)
+{
+	static uint8_t previous_timeout=0;
+	uint8_t timeout, intr_state;
+
+	// if we're not online (enumerated and configured), error
+	if (!usb_configuration) return -1;
+	// interrupts are disabled so these functions can be
+	// used from the main program or interrupt context,
+	// even both in the same program!
+	intr_state = SREG;
+	cli();
+	UENUM = DEBUG_TX_ENDPOINT;
+	// if we gave up due to timeout before, don't wait again
+	if (previous_timeout) {
+		if (!(UEINTX & (1<<RWAL))) {
+			SREG = intr_state;
+			return -1;
+		}
+		previous_timeout = 0;
+	}
+	// wait for the FIFO to be ready to accept data
+	timeout = UDFNUML + 4;
+	while (1) {
+		// are we ready to transmit?
+		if (UEINTX & (1<<RWAL)) break;
+		SREG = intr_state;
+		// have we waited too long?
+		if (UDFNUML == timeout) {
+			previous_timeout = 1;
+			return -1;
+		}
+		// has the USB gone offline?
+		if (!usb_configuration) return -1;
+		// get ready to try checking again
+		intr_state = SREG;
+		cli();
+		UENUM = DEBUG_TX_ENDPOINT;
+	}
+	// actually write the byte into the FIFO
+	UEDATX = c;
+	// if this completed a packet, transmit it now!
+	if (!(UEINTX & (1<<RWAL))) {
+		UEINTX = 0x3A;
+		debug_flush_timer = 0;
+	} else {
+		debug_flush_timer = 2;
+	}
+	SREG = intr_state;
+	return 0;
+}
+
+
+// immediately transmit any buffered output.
+void usb_debug_flush_output(void)
+{
+	uint8_t intr_state;
+
+	intr_state = SREG;
+	cli();
+	if (debug_flush_timer) {
+		UENUM = DEBUG_TX_ENDPOINT;
+		while ((UEINTX & (1<<RWAL))) {
+			UEDATX = 0;
+		}
+		UEINTX = 0x3A;
+		debug_flush_timer = 0;
+	}
+	SREG = intr_state;
+}
+
+
+
+/**************************************************************************
+ *
+ *  Private Functions - not intended for general user consumption....
+ *
+ **************************************************************************/
+
+
+
+// USB Device Interrupt - handle all device-level events
+// the transmit buffer flushing is triggered by the start of frame
+//
+ISR(USB_GEN_vect)
+{
+	uint8_t intbits, t, i;
+	static uint8_t div4=0;
+
+        intbits = UDINT;
+        UDINT = 0;
+        if (intbits & (1<<EORSTI)) {
+		UENUM = 0;
+		UECONX = 1;
+		UECFG0X = EP_TYPE_CONTROL;
+		UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
+		UEIENX = (1<<RXSTPE);
+		usb_configuration = 0;
+        }
+	if ((intbits & (1<<SOFI)) && usb_configuration) {
+		t = debug_flush_timer;
+		if (t) {
+			debug_flush_timer = -- t;
+			if (!t) {
+				UENUM = DEBUG_TX_ENDPOINT;
+				while ((UEINTX & (1<<RWAL))) {
+					UEDATX = 0;
+				}
+				UEINTX = 0x3A;
+			}
+		}
+		if (keyboard_idle_config && (++div4 & 3) == 0) {
+			UENUM = KEYBOARD_ENDPOINT;
+			if (UEINTX & (1<<RWAL)) {
+				keyboard_idle_count++;
+				if (keyboard_idle_count == keyboard_idle_config) {
+					keyboard_idle_count = 0;
+					UEDATX = keyboard_modifier_keys;
+					UEDATX = 0;
+					for (i=0; i<6; i++) {
+						UEDATX = keyboard_keys[i];
+					}
+					UEINTX = 0x3A;
+				}
+			}
+		}
+	}
+}
+
+
+
+// Misc functions to wait for ready and send/receive packets
+static inline void usb_wait_in_ready(void)
+{
+	while (!(UEINTX & (1<<TXINI))) ;
+}
+static inline void usb_send_in(void)
+{
+	UEINTX = ~(1<<TXINI);
+}
+static inline void usb_wait_receive_out(void)
+{
+	while (!(UEINTX & (1<<RXOUTI))) ;
+}
+static inline void usb_ack_out(void)
+{
+	UEINTX = ~(1<<RXOUTI);
+}
+
+
+
+// USB Endpoint Interrupt - endpoint 0 is handled here.  The
+// other endpoints are manipulated by the user-callable
+// functions, and the start-of-frame interrupt.
+//
+ISR(USB_COM_vect)
+{
+        uint8_t intbits;
+	const uint8_t *list;
+        const uint8_t *cfg;
+	uint8_t i, n, len, en;
+	uint8_t bmRequestType;
+	uint8_t bRequest;
+	uint16_t wValue;
+	uint16_t wIndex;
+	uint16_t wLength;
+	uint16_t desc_val;
+	const uint8_t *desc_addr;
+	uint8_t	desc_length;
+
+        UENUM = 0;
+	intbits = UEINTX;
+        if (intbits & (1<<RXSTPI)) {
+                bmRequestType = UEDATX;
+                bRequest = UEDATX;
+                wValue = UEDATX;
+                wValue |= (UEDATX << 8);
+                wIndex = UEDATX;
+                wIndex |= (UEDATX << 8);
+                wLength = UEDATX;
+                wLength |= (UEDATX << 8);
+                UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
+                if (bRequest == GET_DESCRIPTOR) {
+			list = (const uint8_t *)descriptor_list;
+			for (i=0; ; i++) {
+				if (i >= NUM_DESC_LIST) {
+					UECONX = (1<<STALLRQ)|(1<<EPEN);  //stall
+					return;
+				}
+				desc_val = pgm_read_word(list);
+				if (desc_val != wValue) {
+					list += sizeof(struct descriptor_list_struct);
+					continue;
+				}
+				list += 2;
+				desc_val = pgm_read_word(list);
+				if (desc_val != wIndex) {
+					list += sizeof(struct descriptor_list_struct)-2;
+					continue;
+				}
+				list += 2;
+				desc_addr = (const uint8_t *)pgm_read_word(list);
+				list += 2;
+				desc_length = pgm_read_byte(list);
+				break;
+			}
+			len = (wLength < 256) ? wLength : 255;
+			if (len > desc_length) len = desc_length;
+			do {
+				// wait for host ready for IN packet
+				do {
+					i = UEINTX;
+				} while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
+				if (i & (1<<RXOUTI)) return;	// abort
+				// send IN packet
+				n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
+				for (i = n; i; i--) {
+					UEDATX = pgm_read_byte(desc_addr++);
+				}
+				len -= n;
+				usb_send_in();
+			} while (len || n == ENDPOINT0_SIZE);
+			return;
+                }
+		if (bRequest == SET_ADDRESS) {
+			usb_send_in();
+			usb_wait_in_ready();
+			UDADDR = wValue | (1<<ADDEN);
+			return;
+		}
+		if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
+			usb_configuration = wValue;
+			usb_send_in();
+			cfg = endpoint_config_table;
+			for (i=1; i<5; i++) {
+				UENUM = i;
+				en = pgm_read_byte(cfg++);
+				UECONX = en;
+				if (en) {
+					UECFG0X = pgm_read_byte(cfg++);
+					UECFG1X = pgm_read_byte(cfg++);
+				}
+			}
+        		UERST = 0x1E;
+        		UERST = 0;
+			return;
+		}
+		if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
+			usb_wait_in_ready();
+			UEDATX = usb_configuration;
+			usb_send_in();
+			return;
+		}
+
+		if (bRequest == GET_STATUS) {
+			usb_wait_in_ready();
+			i = 0;
+			#ifdef SUPPORT_ENDPOINT_HALT
+			if (bmRequestType == 0x82) {
+				UENUM = wIndex;
+				if (UECONX & (1<<STALLRQ)) i = 1;
+				UENUM = 0;
+			}
+			#endif
+			UEDATX = i;
+			UEDATX = 0;
+			usb_send_in();
+			return;
+		}
+		#ifdef SUPPORT_ENDPOINT_HALT
+		if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
+		  && bmRequestType == 0x02 && wValue == 0) {
+			i = wIndex & 0x7F;
+			if (i >= 1 && i <= MAX_ENDPOINT) {
+				usb_send_in();
+				UENUM = i;
+				if (bRequest == SET_FEATURE) {
+					UECONX = (1<<STALLRQ)|(1<<EPEN);
+				} else {
+					UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
+					UERST = (1 << i);
+					UERST = 0;
+				}
+				return;
+			}
+		}
+		#endif
+		if (wIndex == KEYBOARD_INTERFACE) {
+			if (bmRequestType == 0xA1) {
+				if (bRequest == HID_GET_REPORT) {
+					usb_wait_in_ready();
+					UEDATX = keyboard_modifier_keys;
+					UEDATX = 0;
+					for (i=0; i<6; i++) {
+						UEDATX = keyboard_keys[i];
+					}
+					usb_send_in();
+					return;
+				}
+				if (bRequest == HID_GET_IDLE) {
+					usb_wait_in_ready();
+					UEDATX = keyboard_idle_config;
+					usb_send_in();
+					return;
+				}
+				if (bRequest == HID_GET_PROTOCOL) {
+					usb_wait_in_ready();
+					UEDATX = keyboard_protocol;
+					usb_send_in();
+					return;
+				}
+			}
+			if (bmRequestType == 0x21) {
+				if (bRequest == HID_SET_REPORT) {
+					usb_wait_receive_out();
+					keyboard_leds = UEDATX;
+					usb_ack_out();
+					usb_send_in();
+					return;
+				}
+				if (bRequest == HID_SET_IDLE) {
+					keyboard_idle_config = (wValue >> 8);
+					keyboard_idle_count = 0;
+					//usb_wait_in_ready();
+					usb_send_in();
+					return;
+				}
+				if (bRequest == HID_SET_PROTOCOL) {
+					keyboard_protocol = wValue;
+					//usb_wait_in_ready();
+					usb_send_in();
+					return;
+				}
+			}
+		}
+		if (wIndex == DEBUG_INTERFACE) {
+			if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
+				len = wLength;
+				do {
+					// wait for host ready for IN packet
+					do {
+						i = UEINTX;
+					} while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
+					if (i & (1<<RXOUTI)) return;	// abort
+					// send IN packet
+					n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
+					for (i = n; i; i--) {
+						UEDATX = 0;
+					}
+					len -= n;
+					usb_send_in();
+				} while (len || n == ENDPOINT0_SIZE);
+				return;
+			}
+		}
+	}
+	UECONX = (1<<STALLRQ) | (1<<EPEN);	// stall
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USB/pjrc/usb_keyboard_debug.h	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,91 @@
+#ifndef usb_serial_h__
+#define usb_serial_h__
+
+#include <stdint.h>
+
+void usb_init(void);			// initialize everything
+uint8_t usb_configured(void);		// is the USB port configured
+
+int8_t usb_keyboard_press(uint8_t key, uint8_t modifier);
+int8_t usb_keyboard_send(void);
+extern uint8_t keyboard_modifier_keys;
+extern uint8_t keyboard_keys[6];
+extern volatile uint8_t keyboard_leds;
+
+int8_t usb_debug_putchar(uint8_t c);	// transmit a character
+void usb_debug_flush_output(void);	// immediately transmit any buffered output
+#define USB_DEBUG_HID
+
+
+// Everything below this point is only intended for usb_serial.c
+#ifdef USB_SERIAL_PRIVATE_INCLUDE
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
+
+#define EP_TYPE_CONTROL			0x00
+#define EP_TYPE_BULK_IN			0x81
+#define EP_TYPE_BULK_OUT		0x80
+#define EP_TYPE_INTERRUPT_IN		0xC1
+#define EP_TYPE_INTERRUPT_OUT		0xC0
+#define EP_TYPE_ISOCHRONOUS_IN		0x41
+#define EP_TYPE_ISOCHRONOUS_OUT		0x40
+
+#define EP_SINGLE_BUFFER		0x02
+#define EP_DOUBLE_BUFFER		0x06
+
+#define EP_SIZE(s)	((s) == 64 ? 0x30 :	\
+			((s) == 32 ? 0x20 :	\
+			((s) == 16 ? 0x10 :	\
+			             0x00)))
+
+#define MAX_ENDPOINT		4
+
+#define LSB(n) (n & 255)
+#define MSB(n) ((n >> 8) & 255)
+
+#if defined(__AVR_AT90USB162__)
+#define HW_CONFIG() 
+#define PLL_CONFIG() (PLLCSR = ((1<<PLLE)|(1<<PLLP0)))
+#define USB_CONFIG() (USBCON = (1<<USBE))
+#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
+#elif defined(__AVR_ATmega32U4__)
+#define HW_CONFIG() (UHWCON = 0x01)
+#define PLL_CONFIG() (PLLCSR = 0x12)
+#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
+#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
+#elif defined(__AVR_AT90USB646__)
+#define HW_CONFIG() (UHWCON = 0x81)
+#define PLL_CONFIG() (PLLCSR = 0x1A)
+#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
+#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
+#elif defined(__AVR_AT90USB1286__)
+#define HW_CONFIG() (UHWCON = 0x81)
+#define PLL_CONFIG() (PLLCSR = 0x16)
+#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
+#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
+#endif
+
+// standard control endpoint request types
+#define GET_STATUS			0
+#define CLEAR_FEATURE			1
+#define SET_FEATURE			3
+#define SET_ADDRESS			5
+#define GET_DESCRIPTOR			6
+#define GET_CONFIGURATION		8
+#define SET_CONFIGURATION		9
+#define GET_INTERFACE			10
+#define SET_INTERFACE			11
+// HID (human interface device)
+#define HID_GET_REPORT			1
+#define HID_GET_IDLE			2
+#define HID_GET_PROTOCOL		3
+#define HID_SET_REPORT			9
+#define HID_SET_IDLE			10
+#define HID_SET_PROTOCOL		11
+// CDC (communication class device)
+#define CDC_SET_LINE_CODING		0x20
+#define CDC_GET_LINE_CODING		0x21
+#define CDC_SET_CONTROL_LINE_STATE	0x22
+#endif
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/setup.cmake	Wed Sep 28 23:25:51 2011 -0700
@@ -0,0 +1,109 @@
+###| CMAKE Kiibohd Controller Source Configurator |###
+#
+# Written by Jacob Alexander in 2011 for the Kiibohd Controller
+#
+# Released into the Public Domain
+#
+###
+
+
+
+###
+# Project Modules
+#
+
+#| Each module is defined by it's own folder (e.g. Scan/Matrix represents the "Matrix" module)
+#| All of the modules must be specified, as they generate the sources list of files to compile
+#| Any modifications to this file will cause a complete rebuild of the project
+
+#| Please the {Scan,Macro,USB,Debug}/module.txt for information on the modules and how to create new ones
+
+##| Deals with acquiring the keypress information and turning it into a key index
+set(  ScanModule  "matrix" )
+
+##| Uses the key index and potentially applies special conditions to it, mapping it to a usb key code
+set( MacroModule  "basic"  )
+
+##| Sends the current list of usb key codes through USB HID
+set(   USBModule  "pjrc"   )
+
+##| Debugging source to use, each module has it's own set of defines that it sets
+set( DebugModule  "basic"  )
+
+
+
+###
+# Path Setup
+# 
+set(  ScanModulePath  "Scan/${ScanModule}"  )
+set( MacroModulePath "Macro/${MacroModule}" )
+set(   USBModulePath   "USB/${USBModule}"   )
+set( DebugModulePath "Debug/${DebugModule}" )
+
+
+
+
+###
+# Module Configuration
+#
+
+#| Additional options, usually define settings
+add_definitions()
+
+#| Include path for each of the modules TODO Fixme!! (../)
+add_definitions("
+	-I../${ScanModulePath}
+	-I../${MacroModulePath}
+	-I../${USBModulePath}
+	-I../${DebugModulePath}
+")
+
+
+
+###
+# Module Processing
+#
+
+#| Go through lists of sources and append paths
+#| Usage:
+#|  PathPrepend( OutputListOfSources <Prepend Path> <InputListOfSources> )
+macro( PathPrepend Output SourcesPath )
+	unset( tmpSource )
+
+	# Loop through items
+	foreach( item ${ARGN} )
+		set( tmpSource ${tmpSource} "${SourcesPath}/${item}" )
+	endforeach( item )
+
+	# Finalize by writing the new list back over the old one
+	set( ${Output} ${tmpSource} )
+endmacro( PathPrepend )
+
+
+#| Scan Module
+include(  "${ScanModulePath}/setup.cmake" )
+PathPrepend( SCAN_SRCS ${ScanModulePath} ${SCAN_SRCS} )
+
+#| Macro Module
+include( "${MacroModulePath}/setup.cmake" )
+PathPrepend( MACRO_SRCS ${MacroModulePath} ${MACRO_SRCS} )
+
+#| USB Module
+include(   "${USBModulePath}/setup.cmake" )
+PathPrepend( USB_SRCS ${USBModulePath} ${USB_SRCS} )
+
+#| Debugging Module
+include( "${DebugModulePath}/setup.cmake" )
+PathPrepend( DEBUG_SRCS ${DebugModulePath} ${DEBUG_SRCS} )
+
+
+#| Print list of all module sources
+message( STATUS "Detected Scan Module Source Files:
+${SCAN_SRCS}")
+message( STATUS "Detected Macro Module Source Files:
+${MACRO_SRCS}")
+message( STATUS "Detected USB Module Source Files:
+${USB_SRCS}")
+message( STATUS "Detected Debug Module Source Files:
+${DEBUG_SRCS}")
+