summary refs log tree commit diff
path: root/protocol
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2013-07-28 17:34:41 +0900
committertmk <nobody@nowhere>2013-07-28 17:34:41 +0900
commitdaa4a4235fd4a88b3b6f64e4a2cf590f28f4b65b (patch)
tree91d6c2de3f98bf11e85868c6cd4802f05a55e60e /protocol
parentc7d309e34bf5d05f245811389bea495d814e2111 (diff)
Add NKRO support for LUFA
Diffstat (limited to 'protocol')
-rw-r--r--protocol/lufa/descriptor.c65
-rw-r--r--protocol/lufa/descriptor.h24
-rw-r--r--protocol/lufa/lufa.c28
-rw-r--r--protocol/pjrc/usb_keyboard.c13
4 files changed, 112 insertions, 18 deletions
diff --git a/protocol/lufa/descriptor.c b/protocol/lufa/descriptor.c
index d34ab1c5aa..a46ba3ec6a 100644
--- a/protocol/lufa/descriptor.c
+++ b/protocol/lufa/descriptor.c
@@ -57,9 +57,11 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
         HID_RI_REPORT_COUNT(8, 0x08),
         HID_RI_REPORT_SIZE(8, 0x01),
         HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+
         HID_RI_REPORT_COUNT(8, 0x01),
         HID_RI_REPORT_SIZE(8, 0x08),
-        HID_RI_INPUT(8, HID_IOF_CONSTANT),
+        HID_RI_INPUT(8, HID_IOF_CONSTANT),  /* reserved */
+
         HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
         HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
         HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
@@ -69,6 +71,7 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
         HID_RI_REPORT_COUNT(8, 0x01),
         HID_RI_REPORT_SIZE(8, 0x03),
         HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
+
         HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
         HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
         HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */
@@ -210,11 +213,13 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM NKROReport[] =
 
         HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
         HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
-        HID_RI_USAGE_MAXIMUM(8, NKRO_SIZE*8-1), /* Keyboard Right GUI */
+        HID_RI_USAGE_MAXIMUM(8, (NKRO_EPSIZE-1)*8-1), /* Keyboard Right GUI */
         HID_RI_LOGICAL_MINIMUM(8, 0x00),
         HID_RI_LOGICAL_MAXIMUM(8, 0x01),
-        HID_RI_REPORT_COUNT(8, NKRO_SIZE*8),
+        HID_RI_REPORT_COUNT(8, (NKRO_EPSIZE-1)*8),
         HID_RI_REPORT_SIZE(8, 0x01),
+        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+    HID_RI_END_COLLECTION(0),
 };
 #endif
 
@@ -439,6 +444,48 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
             .PollingIntervalMS      = 0x01
         },
 #endif
+
+    /*
+     * NKRO
+     */
+#ifdef NKRO_ENABLE
+    .NKRO_Interface =
+        {
+            .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+            .InterfaceNumber        = NKRO_INTERFACE,
+            .AlternateSetting       = 0x00,
+
+            .TotalEndpoints         = 1,
+
+            .Class                  = HID_CSCP_HIDClass,
+            .SubClass               = HID_CSCP_NonBootSubclass,
+            .Protocol               = HID_CSCP_NonBootProtocol,
+
+            .InterfaceStrIndex      = NO_DESCRIPTOR
+        },
+
+    .NKRO_HID =
+        {
+            .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+            .HIDSpec                = VERSION_BCD(01.11),
+            .CountryCode            = 0x00,
+            .TotalReportDescriptors = 1,
+            .HIDReportType          = HID_DTYPE_Report,
+            .HIDReportLength        = sizeof(NKROReport)
+        },
+
+    .NKRO_INEndpoint =
+        {
+            .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+            .EndpointAddress        = (ENDPOINT_DIR_IN | NKRO_IN_EPNUM),
+            .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+            .EndpointSize           = NKRO_EPSIZE,
+            .PollingIntervalMS      = 0x01
+        },
+#endif
 };
 
 
@@ -536,6 +583,12 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
                 Size    = sizeof(USB_HID_Descriptor_HID_t);
                 break;
 #endif
+#ifdef NKRO_ENABLE
+            case NKRO_INTERFACE:
+                Address = &ConfigurationDescriptor.NKRO_HID;
+                Size    = sizeof(USB_HID_Descriptor_HID_t);
+                break;
+#endif
             }
             break;
         case HID_DTYPE_Report:
@@ -562,6 +615,12 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
                 Size    = sizeof(ConsoleReport);
                 break;
 #endif
+#ifdef NKRO_ENABLE
+            case NKRO_INTERFACE:
+                Address = &NKROReport;
+                Size    = sizeof(NKROReport);
+                break;
+#endif
             }
             break;
     }
diff --git a/protocol/lufa/descriptor.h b/protocol/lufa/descriptor.h
index 44f20d5a26..9ee1c04d79 100644
--- a/protocol/lufa/descriptor.h
+++ b/protocol/lufa/descriptor.h
@@ -1,5 +1,5 @@
 /* 
- * Copyright 2012 Jun Wako <wakojun@gmail.com>
+ * Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
  * This file is based on:
  *     LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
  *     LUFA-120219/Demos/Device/Lowlevel/GenericHID
@@ -78,6 +78,13 @@ typedef struct
     USB_Descriptor_Endpoint_t             Console_INEndpoint;
     USB_Descriptor_Endpoint_t             Console_OUTEndpoint;
 #endif
+
+#ifdef NKRO_ENABLE
+    // NKRO HID Interface
+    USB_Descriptor_Interface_t            NKRO_Interface;
+    USB_HID_Descriptor_HID_t              NKRO_HID;
+    USB_Descriptor_Endpoint_t             NKRO_INEndpoint;
+#endif
 } USB_Descriptor_Configuration_t;
 
 
@@ -102,9 +109,15 @@ typedef struct
 #   define CONSOLE_INTERFACE        EXTRAKEY_INTERFACE
 #endif
 
+#ifdef NKRO_ENABLE
+#   define NKRO_INTERFACE           (CONSOLE_INTERFACE + 1)
+#else
+#   define NKRO_INTERFACE           CONSOLE_INTERFACE
+#endif
+
 
 /* nubmer of interfaces */
-#define TOTAL_INTERFACES            (CONSOLE_INTERFACE + 1)
+#define TOTAL_INTERFACES            (NKRO_INTERFACE + 1)
 
 
 // Endopoint number and size
@@ -125,6 +138,12 @@ typedef struct
 #ifdef CONSOLE_ENABLE
 #   define CONSOLE_IN_EPNUM         (EXTRAKEY_IN_EPNUM + 1)
 #   define CONSOLE_OUT_EPNUM        (EXTRAKEY_IN_EPNUM + 2)
+#else
+#   define CONSOLE_OUT_EPNUM        EXTRAKEY_IN_EPNUM
+#endif
+
+#ifdef NKRO_ENABLE
+#   define NKRO_IN_EPNUM            (CONSOLE_OUT_EPNUM + 1)
 #endif
 
 
@@ -132,6 +151,7 @@ typedef struct
 #define MOUSE_EPSIZE                8
 #define EXTRAKEY_EPSIZE             8
 #define CONSOLE_EPSIZE              32
+#define NKRO_EPSIZE                 16
 
 
 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c
index a863b8d23c..c1617cd05a 100644
--- a/protocol/lufa/lufa.c
+++ b/protocol/lufa/lufa.c
@@ -220,6 +220,12 @@ void EVENT_USB_Device_ConfigurationChanged(void)
     ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
                                      CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
 #endif
+
+#ifdef NKRO_ENABLE
+    /* Setup NKRO HID Report Endpoints */
+    ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
+                                     NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
+#endif
 }
 
 /*
@@ -350,15 +356,31 @@ static void send_keyboard(report_keyboard_t *report)
     if (USB_DeviceState != DEVICE_STATE_Configured)
         return;
 
-    // TODO: handle NKRO report
     /* Select the Keyboard Report Endpoint */
-    Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
+#ifdef NKRO_ENABLE
+    if (keyboard_nkro) {
+        Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
+    }
+    else
+#endif
+    {
+        Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
+    }
 
     /* Check if Keyboard Endpoint Ready for Read/Write */
     while (--timeout && !Endpoint_IsReadWriteAllowed()) ;
 
     /* Write Keyboard Report Data */
-    Endpoint_Write_Stream_LE(report, sizeof(report_keyboard_t), NULL);
+#ifdef NKRO_ENABLE
+    if (keyboard_nkro) {
+        Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
+    }
+    else
+#endif
+    {
+        /* boot mode */
+        Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
+    }
 
     /* Finalize the stream transfer to send the last packet */
     Endpoint_ClearIN();
diff --git a/protocol/pjrc/usb_keyboard.c b/protocol/pjrc/usb_keyboard.c
index 49b85c179f..de798fcc22 100644
--- a/protocol/pjrc/usb_keyboard.c
+++ b/protocol/pjrc/usb_keyboard.c
@@ -57,12 +57,12 @@ int8_t usb_keyboard_send_report(report_keyboard_t *report)
 
 #ifdef NKRO_ENABLE
     if (keyboard_nkro)
-        result = send_report(report, KBD2_ENDPOINT, 0, KBD2_REPORT_KEYS);
+        result = send_report(report, KBD2_ENDPOINT, 0, KBD2_SIZE);
     else
 #endif
     {
         if (usb_keyboard_protocol)
-            result = send_report(report, KBD_ENDPOINT, 0, KBD_REPORT_KEYS);
+            result = send_report(report, KBD_ENDPOINT, 0, KBD_SIZE);
         else
             result = send_report(report, KBD_ENDPOINT, 0, 6);
     }
@@ -104,15 +104,8 @@ static inline int8_t send_report(report_keyboard_t *report, uint8_t endpoint, ui
             cli();
             UENUM = endpoint;
     }
-    UEDATX = report->mods;
-#ifdef NKRO_ENABLE
-    if (!keyboard_nkro)
-        UEDATX = 0;
-#else
-    UEDATX = 0;
-#endif
     for (uint8_t i = keys_start; i < keys_end; i++) {
-            UEDATX = report->keys[i];
+            UEDATX = report->raw[i];
     }
     UEINTX = 0x3A;
     SREG = intr_state;