Index: kbd/pcw2hid/code/Descriptors.c
===================================================================
--- kbd/pcw2hid/code/Descriptors.c	(revision 110c6922461234282a264edb8a3c8349f2c610d7)
+++ kbd/pcw2hid/code/Descriptors.c	(revision 8d96947467062b5e907e9f5b4a19d1f78c349431)
@@ -44,72 +44,10 @@
  *  more details on HID report descriptors.
  */
-const USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] =
-{
-			HID_RI_USAGE_PAGE(8, 0x01),
-			HID_RI_USAGE(8, 0x04),
-			HID_RI_COLLECTION(8, 0x01),
-
-				0x85, 0x01, // Report ID 1
-
-				// 15 constant bytes
-				HID_RI_REPORT_SIZE(8, 15),
-				HID_RI_REPORT_COUNT(8, 0x01),
-				HID_RI_INPUT(8, HID_IOF_CONSTANT),
-
-				HID_RI_USAGE_PAGE(8, 0x09),
-				HID_RI_LOGICAL_MINIMUM(8, 0x00),
-				HID_RI_LOGICAL_MAXIMUM(8, 0x01),
-
-				HID_RI_USAGE_MINIMUM(8, 7),
-				HID_RI_USAGE_MAXIMUM(8, 9),
-				HID_RI_USAGE(8, 4),
-				HID_RI_REPORT_SIZE(8, 0x01),
-				HID_RI_REPORT_COUNT(8, 4),
-				HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
-
-				HID_RI_REPORT_SIZE(8, 1),
-				HID_RI_REPORT_COUNT(8, 0x01),
-				HID_RI_INPUT(8, HID_IOF_CONSTANT),
-
-				HID_RI_USAGE(8, 10),
-				HID_RI_USAGE_MINIMUM(8, 1),
-				HID_RI_USAGE_MAXIMUM(8, 3),
-				HID_RI_REPORT_SIZE(8, 0x01),
-				HID_RI_REPORT_COUNT(8, 4),
-				HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
-
-				HID_RI_REPORT_SIZE(8, 1),
-				HID_RI_REPORT_COUNT(8, 0x01),
-				HID_RI_INPUT(8, HID_IOF_CONSTANT),
-
-				HID_RI_USAGE_MINIMUM(8, 5),
-				HID_RI_USAGE_MAXIMUM(8, 6),
-				HID_RI_REPORT_SIZE(8, 0x01),
-				HID_RI_REPORT_COUNT(8, 2),
-				HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
-
-				HID_RI_USAGE_PAGE(8, 0x01),
-				HID_RI_USAGE(8, 0x01),
-				HID_RI_COLLECTION(8, 0x00),
-					HID_RI_USAGE(8, 0x31),
-					HID_RI_LOGICAL_MINIMUM(8, -2),
-					HID_RI_LOGICAL_MAXIMUM(8, 1),
-					HID_RI_REPORT_COUNT(8, 1),
-					HID_RI_REPORT_SIZE(8, 2),
-					HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
-
-					HID_RI_REPORT_SIZE(8, 1),
-					HID_RI_REPORT_COUNT(8, 0x01),
-					HID_RI_INPUT(8, HID_IOF_CONSTANT),
-
-					HID_RI_USAGE(8, 0x30),
-					HID_RI_LOGICAL_MINIMUM(8, -2),
-					HID_RI_LOGICAL_MAXIMUM(8, 1),
-					HID_RI_REPORT_COUNT(8, 1),
-					HID_RI_REPORT_SIZE(8, 2),
-					HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
-				HID_RI_END_COLLECTION(0),
-
-			HID_RI_END_COLLECTION(0)
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
+{
+	/* Use the HID class driver's standard Keyboard report.
+	 *   Max simultaneous keys: 6
+	 */
+	HID_DESCRIPTOR_KEYBOARD(6)
 };
 
@@ -131,5 +69,5 @@
 
 	.VendorID               = 0x16c0,
-	.ProductID              = 0x27dc,
+	.ProductID              = 0x27db,
 	.ReleaseNumber          = VERSION_BCD(0,0,1),
 
@@ -167,5 +105,5 @@
 			.Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
 
-			.InterfaceNumber        = INTERFACE_ID_Joystick,
+			.InterfaceNumber        = INTERFACE_ID_Keyboard,
 			.AlternateSetting       = 0x00,
 
@@ -173,11 +111,11 @@
 
 			.Class                  = HID_CSCP_HIDClass,
-			.SubClass               = HID_CSCP_NonBootSubclass,
-			.Protocol               = HID_CSCP_NonBootProtocol,
+			.SubClass               = HID_CSCP_BootSubclass,
+			.Protocol               = HID_CSCP_KeyboardBootProtocol,
 
 			.InterfaceStrIndex      = NO_DESCRIPTOR
 		},
 
-	.HID_JoystickHID =
+	.HID_KeyboardHID =
 		{
 			.Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
@@ -187,5 +125,5 @@
 			.TotalReportDescriptors = 1,
 			.HIDReportType          = HID_DTYPE_Report,
-			.HIDReportLength        = sizeof(JoystickReport)
+			.HIDReportLength        = sizeof(KeyboardReport)
 		},
 
@@ -194,7 +132,7 @@
 			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
 
-			.EndpointAddress        = JOYSTICK_EPADDR,
+			.EndpointAddress        = KEYBOARD_EPADDR,
 			.Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
-			.EndpointSize           = JOYSTICK_EPSIZE,
+			.EndpointSize           = KEYBOARD_EPSIZE,
 			.PollingIntervalMS      = 0x05
 		}
@@ -264,10 +202,10 @@
 			break;
 		case HID_DTYPE_HID:
-			Address = &ConfigurationDescriptor.HID_JoystickHID;
+			Address = &ConfigurationDescriptor.HID_KeyboardHID;
 			Size    = sizeof(USB_HID_Descriptor_HID_t);
 			break;
 		case HID_DTYPE_Report:
-			Address = &JoystickReport;
-			Size    = sizeof(JoystickReport);
+			Address = &KeyboardReport;
+			Size    = sizeof(KeyboardReport);
 			break;
 	}
Index: kbd/pcw2hid/code/Descriptors.h
===================================================================
--- kbd/pcw2hid/code/Descriptors.h	(revision 110c6922461234282a264edb8a3c8349f2c610d7)
+++ kbd/pcw2hid/code/Descriptors.h	(revision 8d96947467062b5e907e9f5b4a19d1f78c349431)
@@ -51,8 +51,8 @@
 			USB_Descriptor_Configuration_Header_t Config;
 
-			// Joystick HID Interface
+			// Keyboard HID Interface
 			USB_Descriptor_Interface_t            HID_Interface;
-			USB_HID_Descriptor_HID_t              HID_JoystickHID;
-	        USB_Descriptor_Endpoint_t             HID_ReportINEndpoint;
+			USB_HID_Descriptor_HID_t              HID_KeyboardHID;
+			USB_Descriptor_Endpoint_t             HID_ReportINEndpoint;
 		} USB_Descriptor_Configuration_t;
 
@@ -63,5 +63,5 @@
 		enum InterfaceDescriptors_t
 		{
-			INTERFACE_ID_Joystick = 0, /**< Joystick interface desciptor ID */
+			INTERFACE_ID_Keyboard = 0, /**< Keyboard interface descriptor ID */
 		};
 
@@ -78,9 +78,9 @@
 
 	/* Macros: */
-		/** Endpoint address of the Joystick HID reporting IN endpoint. */
-		#define JOYSTICK_EPADDR              (ENDPOINT_DIR_IN | 1)
+		/** Endpoint address of the Keyboard HID reporting IN endpoint. */
+		#define KEYBOARD_EPADDR              (ENDPOINT_DIR_IN | 1)
 
-		/** Size in bytes of the Joystick HID reporting IN endpoint. */
-		#define JOYSTICK_EPSIZE              16
+		/** Size in bytes of the Keyboard HID reporting IN endpoint. */
+		#define KEYBOARD_EPSIZE              8
 
 	/* Function Prototypes: */
Index: kbd/pcw2hid/code/Keyboard.c
===================================================================
--- kbd/pcw2hid/code/Keyboard.c	(revision 110c6922461234282a264edb8a3c8349f2c610d7)
+++ kbd/pcw2hid/code/Keyboard.c	(revision 8d96947467062b5e907e9f5b4a19d1f78c349431)
@@ -31,5 +31,5 @@
 /** \file
  *
- *  Main source file for the Joystick demo. This file contains the main tasks of
+ *  Main source file for the Keyboard demo. This file contains the main tasks of
  *  the demo and is responsible for the initial application hardware configuration.
  */
@@ -37,9 +37,9 @@
 #include "Keyboard.h"
 
-extern void PCW_Init();
-extern void scanall();
-
-/** Buffer to hold the previously generated HID report, for comparison purposes inside the HID class driver. */
-static uint8_t PrevJoystickHIDReportBuffer[4];
+extern void PCW_Init(void);
+extern uint8_t* scanall(void);
+
+/** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */
+static uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)];
 
 /** LUFA HID Class driver interface configuration and state information. This structure is
@@ -47,17 +47,17 @@
  *  within a device can be differentiated from one another.
  */
-USB_ClassInfo_HID_Device_t Joystick_HID_Interface =
+USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
 	{
 		.Config =
 			{
-				.InterfaceNumber              = INTERFACE_ID_Joystick,
+				.InterfaceNumber              = INTERFACE_ID_Keyboard,
 				.ReportINEndpoint             =
 					{
-						.Address              = JOYSTICK_EPADDR,
-						.Size                 = JOYSTICK_EPSIZE,
+						.Address              = KEYBOARD_EPADDR,
+						.Size                 = KEYBOARD_EPSIZE,
 						.Banks                = 1,
 					},
-				.PrevReportINBuffer           = PrevJoystickHIDReportBuffer,
-				.PrevReportINBufferSize       = sizeof(PrevJoystickHIDReportBuffer),
+				.PrevReportINBuffer           = PrevKeyboardHIDReportBuffer,
+				.PrevReportINBufferSize       = sizeof(PrevKeyboardHIDReportBuffer),
 			},
 	};
@@ -76,5 +76,5 @@
 	for (;;)
 	{
-		HID_Device_USBTask(&Joystick_HID_Interface);
+		HID_Device_USBTask(&Keyboard_HID_Interface);
 		USB_USBTask();
 	}
@@ -127,5 +127,5 @@
 	bool ConfigSuccess = true;
 
-	ConfigSuccess &= HID_Device_ConfigureEndpoints(&Joystick_HID_Interface);
+	ConfigSuccess &= HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface);
 
 	USB_Device_EnableSOFEvents();
@@ -137,5 +137,5 @@
 void EVENT_USB_Device_ControlRequest(void)
 {
-	HID_Device_ProcessControlRequest(&Joystick_HID_Interface);
+	HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
 }
 
@@ -143,5 +143,5 @@
 void EVENT_USB_Device_StartOfFrame(void)
 {
-	HID_Device_MillisecondElapsed(&Joystick_HID_Interface);
+	HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
 }
 
@@ -162,12 +162,122 @@
                                          uint16_t* const ReportSize)
 {
+	USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
+
 	uint8_t* matrix = scanall();
-	*ReportID = 1;
-
-	*ReportSize = 16;
-	for (int i = 0; i < 16; i++) {
-		ReportData[i] = matrix[i];
-	}
-	return true;
+
+	uint8_t UsedKeyCodes = 0;
+
+#define MAP(i, j, k) \
+	if (matrix[i] & (1 << j)) \
+		KeyboardReport->KeyCode[UsedKeyCodes++] = k; \
+	if (UsedKeyCodes == 6) \
+		goto full;
+
+#define MODIFIER(i, j, k) \
+	if (matrix[i] & (1 << j)) \
+		KeyboardReport->Modifier |= k;
+
+	MAP(0, 7, HID_KEYBOARD_SC_KEYPAD_2_AND_DOWN_ARROW);
+	MAP(0, 6, HID_KEYBOARD_SC_KEYPAD_3_AND_PAGE_DOWN);
+	MAP(0, 5, HID_KEYBOARD_SC_KEYPAD_6_AND_RIGHT_ARROW);
+	MAP(0, 4, HID_KEYBOARD_SC_KEYPAD_9_AND_PAGE_UP);
+	MAP(0, 3, HID_KEYBOARD_SC_PASTE);
+	MAP(0, 2, HID_KEYBOARD_SC_F1);
+	MAP(0, 1, HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT);
+	MAP(0, 0, HID_KEYBOARD_SC_F3);
+
+	MAP(1, 7, HID_KEYBOARD_SC_KEYPAD_1_AND_END);
+	MAP(1, 6, HID_KEYBOARD_SC_KEYPAD_5);
+	MAP(1, 5, HID_KEYBOARD_SC_KEYPAD_4_AND_LEFT_ARROW);
+	MAP(1, 4, HID_KEYBOARD_SC_KEYPAD_8_AND_UP_ARROW);
+	MAP(1, 3, HID_KEYBOARD_SC_COPY);
+	MAP(1, 2, HID_KEYBOARD_SC_CUT);
+	MAP(1, 1, HID_KEYBOARD_SC_F2);
+	MAP(1, 0, HID_KEYBOARD_SC_F4);
+
+	MAP(2, 7, HID_KEYBOARD_SC_KEYPAD_PLUS);
+	MAP(2, 6, HID_KEYBOARD_SC_NON_US_HASHMARK_AND_TILDE);
+	MODIFIER(2, 5, HID_KEYBOARD_MODIFIER_LEFTSHIFT | HID_KEYBOARD_MODIFIER_RIGHTSHIFT);
+	MAP(2, 4, HID_KEYBOARD_SC_KEYPAD_7_AND_HOME);
+	MAP(2, 3, HID_KEYBOARD_SC_BACKSLASH_AND_PIPE);
+	MAP(2, 2, HID_KEYBOARD_SC_ENTER);
+	MAP(2, 1, HID_KEYBOARD_SC_CLOSING_BRACKET_AND_CLOSING_BRACE);
+	MAP(2, 0, HID_KEYBOARD_SC_DELETE);
+
+	MAP(3, 7, HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN);
+	MAP(3, 6, HID_KEYBOARD_SC_SLASH_AND_QUESTION_MARK);
+	MAP(3, 5, HID_KEYBOARD_SC_SEMICOLON_AND_COLON);
+	MAP(3, 4, HID_KEYBOARD_SC_APOSTROPHE_AND_QUOTE);
+	MAP(3, 3, HID_KEYBOARD_SC_P);
+	MAP(3, 2, HID_KEYBOARD_SC_OPENING_BRACKET_AND_OPENING_BRACE);
+	MAP(3, 1, HID_KEYBOARD_SC_MINUS_AND_UNDERSCORE);
+	MAP(3, 0, HID_KEYBOARD_SC_EQUAL_AND_PLUS);
+
+	MAP(4, 7, HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN);
+	MAP(4, 6, HID_KEYBOARD_SC_M);
+	MAP(4, 5, HID_KEYBOARD_SC_K);
+	MAP(4, 4, HID_KEYBOARD_SC_L);
+	MAP(4, 3, HID_KEYBOARD_SC_I);
+	MAP(4, 2, HID_KEYBOARD_SC_O);
+	MAP(4, 1, HID_KEYBOARD_SC_9_AND_OPENING_PARENTHESIS);
+	MAP(4, 0, HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS);
+
+	MAP(5, 7, HID_KEYBOARD_SC_SPACE);
+	MAP(5, 6, HID_KEYBOARD_SC_N);
+	MAP(5, 5, HID_KEYBOARD_SC_J);
+	MAP(5, 4, HID_KEYBOARD_SC_H);
+	MAP(5, 3, HID_KEYBOARD_SC_Y);
+	MAP(5, 2, HID_KEYBOARD_SC_U);
+	MAP(5, 1, HID_KEYBOARD_SC_7_AND_AMPERSAND);
+	MAP(5, 0, HID_KEYBOARD_SC_8_AND_ASTERISK);
+
+	MAP(6, 7, HID_KEYBOARD_SC_V);
+	MAP(6, 6, HID_KEYBOARD_SC_B);
+	MAP(6, 5, HID_KEYBOARD_SC_F);
+	MAP(6, 4, HID_KEYBOARD_SC_G);
+	MAP(6, 3, HID_KEYBOARD_SC_T);
+	MAP(6, 2, HID_KEYBOARD_SC_R);
+	MAP(6, 1, HID_KEYBOARD_SC_S);
+	MAP(6, 0, HID_KEYBOARD_SC_6_AND_CARET);
+
+	MAP(7, 7, HID_KEYBOARD_SC_X);
+	MAP(7, 6, HID_KEYBOARD_SC_C);
+	MAP(7, 5, HID_KEYBOARD_SC_D);
+	MAP(7, 4, HID_KEYBOARD_SC_S);
+	MAP(7, 3, HID_KEYBOARD_SC_W);
+	MAP(7, 2, HID_KEYBOARD_SC_E);
+	MAP(7, 1, HID_KEYBOARD_SC_3_AND_HASHMARK);
+	MAP(7, 0, HID_KEYBOARD_SC_4_AND_DOLLAR);
+
+	MAP(8, 7, HID_KEYBOARD_SC_Z);
+	MAP(8, 6, HID_KEYBOARD_SC_CAPS_LOCK);
+	MAP(8, 5, HID_KEYBOARD_SC_A);
+	MAP(8, 4, HID_KEYBOARD_SC_TAB);
+	MAP(8, 3, HID_KEYBOARD_SC_Q);
+	MAP(8, 2, HID_KEYBOARD_SC_STOP);
+	MAP(8, 1, HID_KEYBOARD_SC_2_AND_AT);
+	MAP(8, 0, HID_KEYBOARD_SC_1_AND_EXCLAMATION);
+
+	MAP(9, 7, HID_KEYBOARD_SC_BACKSPACE);
+	//MAP(9, 6, HID_KEYBOARD_SC_CAPS_LOCK);
+	MAP(9, 5, HID_KEYBOARD_SC_F6);
+	MAP(9, 4, HID_KEYBOARD_SC_F8);
+	MAP(9, 3, HID_KEYBOARD_SC_RIGHT_ARROW);
+	MAP(9, 2, HID_KEYBOARD_SC_LEFT_ARROW);
+	MAP(9, 1, HID_KEYBOARD_SC_DOWN_ARROW);
+	MAP(9, 0, HID_KEYBOARD_SC_UP_ARROW);
+
+	MODIFIER(10, 7, HID_KEYBOARD_MODIFIER_LEFTALT | HID_KEYBOARD_MODIFIER_RIGHTALT);
+	MAP(10, 6, HID_KEYBOARD_SC_KEYPAD_DOT_AND_DELETE);
+	MAP(10, 5, HID_KEYBOARD_SC_KEYPAD_ENTER);
+	MAP(10, 4, HID_KEYBOARD_SC_F7);
+	MAP(10, 3, HID_KEYBOARD_SC_KEYPAD_MINUS);
+	MAP(10, 2, HID_KEYBOARD_SC_CANCEL);
+	MAP(10, 1, HID_KEYBOARD_SC_HOME);
+	MAP(10, 0, HID_KEYBOARD_SC_F5);
+
+full:
+	*ReportSize = sizeof(USB_KeyboardReport_Data_t);
+	return false;
 }
 
Index: kbd/pcw2hid/code/Keyboard.h
===================================================================
--- kbd/pcw2hid/code/Keyboard.h	(revision 110c6922461234282a264edb8a3c8349f2c610d7)
+++ kbd/pcw2hid/code/Keyboard.h	(revision 8d96947467062b5e907e9f5b4a19d1f78c349431)
@@ -31,9 +31,9 @@
 /** \file
  *
- *  Header file for Joystick.c.
+ *  Header file for Keyboard.c.
  */
 
-#ifndef _JOYSTICK_H_
-#define _JOYSTICK_H_
+#ifndef _KEYBOARD_H_
+#define _KEYBOARD_H_
 
 	/* Includes: */
Index: kbd/pcw2hid/code/protocol.cpp
===================================================================
--- kbd/pcw2hid/code/protocol.cpp	(revision 110c6922461234282a264edb8a3c8349f2c610d7)
+++ kbd/pcw2hid/code/protocol.cpp	(revision 8d96947467062b5e907e9f5b4a19d1f78c349431)
@@ -75,5 +75,7 @@
 	do {
 		address = scanbyte();
-	} while ((address < 15) && (kmatrix[15] & 0x80 != 0));
+	// } while ((address < 15) && ((kmatrix[15] & 0x80) != 0));
+	} while ((address != 10) && ((kmatrix[15] & 0x80) != 0));
+	// nothing interesting past row 10, so stop scanning there.
 
 	return kmatrix;
