forked from mirrors/qmk_userspace
		
	change keyboard report descriptor for NKRO.
It uses 1byte for modifiers and 15bytes(120bits) for keys now.
This commit is contained in:
		
					parent
					
						
							
								51f17f0231
							
						
					
				
			
			
				commit
				
					
						1ed336a064
					
				
			
		
					 4 changed files with 96 additions and 48 deletions
				
			
		
							
								
								
									
										73
									
								
								USB_NKRO.txt
									
										
									
									
									
								
							
							
						
						
									
										73
									
								
								USB_NKRO.txt
									
										
									
									
									
								
							| 
						 | 
					@ -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
									
										
									
									
									
								
							
							
						
						
									
										66
									
								
								usb.c
									
										
									
									
									
								
							| 
						 | 
					@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue