It uses 1byte for modifiers and 15bytes(120bits) for keys now.tags/v1.9
@@ -1,6 +1,6 @@ | |||
USB NKRO MEMO | |||
============= | |||
2010/12/07 | |||
2010/12/09 | |||
References | |||
@@ -9,6 +9,9 @@ USB - boot mode, NKRO, compatibility, etc... | |||
http://geekhack.org/showthread.php?t=13162 | |||
NKey Rollover - Overview, Testing Methodology, and Results | |||
http://geekhack.org/showwiki.php?title=NKey+Rollover+-+Overview+Testing+Methodology+and+Results | |||
dfj's NKRO(2010/06) | |||
http://geekhack.org/showpost.php?p=191195&postcount=251 | |||
http://geekhack.org/showthread.php?p=204389#post204389 | |||
Terminogy | |||
@@ -22,18 +25,26 @@ membrane | |||
OS Support Status | |||
----------------- | |||
NKRO is possible at least relatively new OS. | |||
Following OS supports both Extended and Bitmarp report. | |||
USB NKRO is possible *without* a custom driver. | |||
At least following OSes supports. | |||
Windows7 64bit | |||
WindowsXP | |||
Windows2000 SP4 | |||
Ubuntu 10.4(Linux 2.6) | |||
Ubuntu10.4(Linux 2.6) | |||
MacOSX(To be tested) | |||
Custom Driver for USB NKRO | |||
-------------------------- | |||
NOT NEEDED | |||
at least when using fllowing report formats on Windows, Linux or MacOSX. | |||
USB NKRO methods | |||
---------------- | |||
1. Virtual keyboards | |||
Keyboard can increase its KRO by using virtual keyboards with Standard or Extended report. | |||
If the keyboard has 2 virtul keyboard with Standard report(6KRO), it gets 12KRO. | |||
If the keyboard has 2 virtual keyboard with Standard report(6KRO), it gets 12KRO. | |||
Using this method means the keyboard is a composite device. | |||
2. Exteded report | |||
@@ -70,28 +81,64 @@ Extended report is expected to be compatible with boot protocol. | |||
Bitmap report can send at most 128keys by 16bytes and 256keys by 32bytes. | |||
Bitmap report can achieve USB NKRO efficiently in terms of report size. | |||
Bitmap report needs a deliberation for boot protocol implementation. | |||
Compatibility Problem | |||
--------------------- | |||
Some BIOS doesn't send SET_PROTCOL request, a keyboard can't switch to boot protocol mode. | |||
This may cuase a problem on a keyboard which uses other report than Standard. | |||
Bitmap report descriptor sample: | |||
0x05, 0x01, // Usage Page (Generic Desktop), | |||
0x09, 0x06, // Usage (Keyboard), | |||
0xA1, 0x01, // Collection (Application), | |||
// bitmap of modifiers | |||
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 | |||
// LED output report | |||
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), | |||
0x95, 0x01, // Report Count (1), | |||
0x75, 0x03, // Report Size (3), | |||
0x91, 0x03, // Output (Constant), | |||
// bitmap of keys | |||
0x95, (REPORT_BYTES-1)*8, // Report Count (), | |||
0x75, 0x01, // Report Size (1), | |||
0x15, 0x00, // Logical Minimum (0), | |||
0x25, 0x01, // Logical Maximum(1), | |||
0x05, 0x07, // Usage Page (Key Codes), | |||
0x19, 0x00, // Usage Minimum (0), | |||
0x29, (REPORT_BYTES-1)*8-1, // Usage Maximum (), | |||
0x81, 0x02, // Input (Data, Variable, Absolute), | |||
0xc0 // End Collection | |||
where REPORT_BYTES is a report size in bytes. | |||
Considerations | |||
-------------- | |||
Compatibility | |||
boot protocol | |||
minor/old system | |||
Some BIOS doesn't send SET_PROTCOL request, a keyboard can't switch to boot protocol mode. | |||
This may cuase a problem on a keyboard which uses other report than Standard. | |||
Reactivity | |||
USB polling time | |||
OS/Driver processing time | |||
Windows Problem | |||
--------------- | |||
1. Windows accepts only 6keys in case of Standard report. | |||
It should be able to send 6keys plus 8modifiers. | |||
2. Windows accepts only 10keys in case of 16bytes Extended report. | |||
It should be able to send 14keys plus 8modifiers. | |||
3. Windows accepts only 18keys in case of 32bytes Extended report. | |||
It should be able to send 30keys plus 8modifiers. | |||
If keys are pressed in excess of the number, wrong keys are registered on Windows. | |||
This problem will be reportedly fixed soon.(2010/12/05) | |||
http://forums.anandtech.com/showpost.php?p=30873364&postcount=17 | |||
@@ -95,7 +95,7 @@ static const uint8_t PROGMEM endpoint_config_table[] = { | |||
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER, // 3 | |||
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(EXTRA_SIZE) | EXTRA_BUFFER, // 4 | |||
#ifdef NKRO_ENABLE | |||
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KBD2_SIZE) | KBD2_BUFFER, // 5 | |||
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KBD2_SIZE) | KBD2_BUFFER, // 5 | |||
#else | |||
0, // 5 | |||
#endif | |||
@@ -170,38 +170,38 @@ static uint8_t PROGMEM keyboard_hid_report_desc[] = { | |||
}; | |||
#ifdef NKRO_ENABLE | |||
static uint8_t PROGMEM keyboard2_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, KBD2_REPORT_KEYS*8, // Report Count (), | |||
0x75, 0x01, // Report Size (1), | |||
0x15, 0x00, // Logical Minimum (0), | |||
0x25, 0x01, // Logical Maximum(1), | |||
0x05, 0x07, // Usage Page (Key Codes), | |||
0x19, 0x00, // Usage Minimum (0), | |||
0x29, KBD2_REPORT_KEYS*8-1, // Usage Maximum (), | |||
0x81, 0x02, // Input (Data, Variable, Absolute), | |||
0xc0 // End Collection | |||
0x05, 0x01, // Usage Page (Generic Desktop), | |||
0x09, 0x06, // Usage (Keyboard), | |||
0xA1, 0x01, // Collection (Application), | |||
// bitmap of modifiers | |||
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 | |||
// LED output report | |||
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), | |||
0x95, 0x01, // Report Count (1), | |||
0x75, 0x03, // Report Size (3), | |||
0x91, 0x03, // Output (Constant), | |||
// bitmap of keys | |||
0x95, KBD2_REPORT_KEYS*8, // Report Count (), | |||
0x75, 0x01, // Report Size (1), | |||
0x15, 0x00, // Logical Minimum (0), | |||
0x25, 0x01, // Logical Maximum(1), | |||
0x05, 0x07, // Usage Page (Key Codes), | |||
0x19, 0x00, // Usage Minimum (0), | |||
0x29, KBD2_REPORT_KEYS*8-1, // Usage Maximum (), | |||
0x81, 0x02, // Input (Data, Variable, Absolute), | |||
0xc0 // End Collection | |||
}; | |||
#endif | |||
@@ -211,7 +211,8 @@ static inline int8_t _send_report(usb_keyboard_report_t *report, uint8_t endpoin | |||
UENUM = endpoint; | |||
} | |||
UEDATX = report->mods; | |||
UEDATX = 0; | |||
if (!usb_keyboard_nkro) | |||
UEDATX = 0; | |||
for (uint8_t i = keys_start; i < keys_end; i++) { | |||
UEDATX = report->keys[i]; | |||
} |
@@ -18,7 +18,7 @@ | |||
#define KBD2_ENDPOINT 5 | |||
#define KBD2_SIZE 16 | |||
#define KBD2_BUFFER EP_DOUBLE_BUFFER | |||
#define KBD2_REPORT_KEYS (KBD2_SIZE - 2) | |||
#define KBD2_REPORT_KEYS (KBD2_SIZE - 1) | |||
#endif | |||
#if defined(KBD2_REPORT_KEYS) && KBD2_REPORT_KEYS > KBD_REPORT_KEYS |