change keyboard report descriptor for NKRO.

It uses 1byte for modifiers and 15bytes(120bits) for keys now.
This commit is contained in:
tmk 2010-12-11 23:20:49 +09:00
parent 51f17f0231
commit 1ed336a064
4 changed files with 96 additions and 48 deletions

View file

@ -1,6 +1,6 @@
USB NKRO MEMO USB NKRO MEMO
============= =============
2010/12/07 2010/12/09
References References
@ -9,6 +9,9 @@ USB - boot mode, NKRO, compatibility, etc...
http://geekhack.org/showthread.php?t=13162 http://geekhack.org/showthread.php?t=13162
NKey Rollover - Overview, Testing Methodology, and Results NKey Rollover - Overview, Testing Methodology, and Results
http://geekhack.org/showwiki.php?title=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 Terminogy
@ -22,18 +25,26 @@ membrane
OS Support Status OS Support Status
----------------- -----------------
NKRO is possible at least relatively new OS. USB NKRO is possible *without* a custom driver.
Following OS supports both Extended and Bitmarp report. At least following OSes supports.
Windows7 64bit Windows7 64bit
WindowsXP
Windows2000 SP4 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 USB NKRO methods
---------------- ----------------
1. Virtual keyboards 1. Virtual keyboards
Keyboard can increase its KRO by using virtual keyboards with Standard or Extended report. 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. Using this method means the keyboard is a composite device.
2. Exteded report 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 send at most 128keys by 16bytes and 256keys by 32bytes.
Bitmap report can achieve USB NKRO efficiently in terms of report size. Bitmap report can achieve USB NKRO efficiently in terms of report size.
Bitmap report needs a deliberation for boot protocol implementation. Bitmap report needs a deliberation for boot protocol implementation.
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.
Compatibility Problem Considerations
--------------------- --------------
Some BIOS doesn't send SET_PROTCOL request, a keyboard can't switch to boot protocol mode. Compatibility
This may cuase a problem on a keyboard which uses other report than Standard. 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 Windows Problem
--------------- ---------------
1. Windows accepts only 6keys in case of Standard report. 1. Windows accepts only 6keys in case of Standard report.
It should be able to send 6keys plus 8modifiers. It should be able to send 6keys plus 8modifiers.
2. Windows accepts only 10keys in case of 16bytes Extended report. 2. Windows accepts only 10keys in case of 16bytes Extended report.
It should be able to send 14keys plus 8modifiers. It should be able to send 14keys plus 8modifiers.
3. Windows accepts only 18keys in case of 32bytes Extended report. 3. Windows accepts only 18keys in case of 32bytes Extended report.
It should be able to send 30keys plus 8modifiers. It should be able to send 30keys plus 8modifiers.
If keys are pressed in excess of the number, wrong keys are registered on Windows. 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) This problem will be reportedly fixed soon.(2010/12/05)
http://forums.anandtech.com/showpost.php?p=30873364&postcount=17 http://forums.anandtech.com/showpost.php?p=30873364&postcount=17

66
usb.c
View file

@ -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(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER, // 3
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(EXTRA_SIZE) | EXTRA_BUFFER, // 4 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(EXTRA_SIZE) | EXTRA_BUFFER, // 4
#ifdef NKRO_ENABLE #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 #else
0, // 5 0, // 5
#endif #endif
@ -170,38 +170,38 @@ static uint8_t PROGMEM keyboard_hid_report_desc[] = {
}; };
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
static uint8_t PROGMEM keyboard2_hid_report_desc[] = { static uint8_t PROGMEM keyboard2_hid_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop), 0x05, 0x01, // Usage Page (Generic Desktop),
0x09, 0x06, // Usage (Keyboard), 0x09, 0x06, // Usage (Keyboard),
0xA1, 0x01, // Collection (Application), 0xA1, 0x01, // Collection (Application),
0x75, 0x01, // Report Size (1), // bitmap of modifiers
0x95, 0x08, // Report Count (8), 0x75, 0x01, // Report Size (1),
0x05, 0x07, // Usage Page (Key Codes), 0x95, 0x08, // Report Count (8),
0x19, 0xE0, // Usage Minimum (224), 0x05, 0x07, // Usage Page (Key Codes),
0x29, 0xE7, // Usage Maximum (231), 0x19, 0xE0, // Usage Minimum (224),
0x15, 0x00, // Logical Minimum (0), 0x29, 0xE7, // Usage Maximum (231),
0x25, 0x01, // Logical Maximum (1), 0x15, 0x00, // Logical Minimum (0),
0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte 0x25, 0x01, // Logical Maximum (1),
0x95, 0x01, // Report Count (1), 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
0x75, 0x08, // Report Size (8), // LED output report
0x81, 0x03, // Input (Constant), ;Reserved byte 0x95, 0x05, // Report Count (5),
0x95, 0x05, // Report Count (5), 0x75, 0x01, // Report Size (1),
0x75, 0x01, // Report Size (1), 0x05, 0x08, // Usage Page (LEDs),
0x05, 0x08, // Usage Page (LEDs), 0x19, 0x01, // Usage Minimum (1),
0x19, 0x01, // Usage Minimum (1), 0x29, 0x05, // Usage Maximum (5),
0x29, 0x05, // Usage Maximum (5), 0x91, 0x02, // Output (Data, Variable, Absolute),
0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report 0x95, 0x01, // Report Count (1),
0x95, 0x01, // Report Count (1), 0x75, 0x03, // Report Size (3),
0x75, 0x03, // Report Size (3), 0x91, 0x03, // Output (Constant),
0x91, 0x03, // Output (Constant), ;LED report padding // bitmap of keys
0x95, KBD2_REPORT_KEYS*8, // Report Count (), 0x95, KBD2_REPORT_KEYS*8, // Report Count (),
0x75, 0x01, // Report Size (1), 0x75, 0x01, // Report Size (1),
0x15, 0x00, // Logical Minimum (0), 0x15, 0x00, // Logical Minimum (0),
0x25, 0x01, // Logical Maximum(1), 0x25, 0x01, // Logical Maximum(1),
0x05, 0x07, // Usage Page (Key Codes), 0x05, 0x07, // Usage Page (Key Codes),
0x19, 0x00, // Usage Minimum (0), 0x19, 0x00, // Usage Minimum (0),
0x29, KBD2_REPORT_KEYS*8-1, // Usage Maximum (), 0x29, KBD2_REPORT_KEYS*8-1, // Usage Maximum (),
0x81, 0x02, // Input (Data, Variable, Absolute), 0x81, 0x02, // Input (Data, Variable, Absolute),
0xc0 // End Collection 0xc0 // End Collection
}; };
#endif #endif

View file

@ -211,7 +211,8 @@ static inline int8_t _send_report(usb_keyboard_report_t *report, uint8_t endpoin
UENUM = endpoint; UENUM = endpoint;
} }
UEDATX = report->mods; UEDATX = report->mods;
UEDATX = 0; if (!usb_keyboard_nkro)
UEDATX = 0;
for (uint8_t i = keys_start; i < keys_end; i++) { for (uint8_t i = keys_start; i < keys_end; i++) {
UEDATX = report->keys[i]; UEDATX = report->keys[i];
} }

View file

@ -18,7 +18,7 @@
#define KBD2_ENDPOINT 5 #define KBD2_ENDPOINT 5
#define KBD2_SIZE 16 #define KBD2_SIZE 16
#define KBD2_BUFFER EP_DOUBLE_BUFFER #define KBD2_BUFFER EP_DOUBLE_BUFFER
#define KBD2_REPORT_KEYS (KBD2_SIZE - 2) #define KBD2_REPORT_KEYS (KBD2_SIZE - 1)
#endif #endif
#if defined(KBD2_REPORT_KEYS) && KBD2_REPORT_KEYS > KBD_REPORT_KEYS #if defined(KBD2_REPORT_KEYS) && KBD2_REPORT_KEYS > KBD_REPORT_KEYS