From 11fb8bd77dea03ccda9a977c0ac7938abc938f6c Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Mon, 10 Nov 2014 21:02:25 -0800 Subject: [PATCH] Fixing Linux NKRO Delete bug - Fixed descriptor to not include USB Code 156 (Clear) - This USB Code affects repeating Delete --- Output/pjrcUSB/arm/usb_desc.c | 31 +++++++++++++++++------- Output/pjrcUSB/arm/usb_keyboard.c | 25 ++++++++++++++----- Output/pjrcUSB/avr/usb_keyboard_serial.c | 25 ++++++++++++++----- Output/pjrcUSB/avr/usb_keyboard_serial.h | 31 +++++++++++++++++------- Output/pjrcUSB/output_com.c | 31 +++++++++++++++++------- Output/pjrcUSB/output_com.h | 7 +++--- 6 files changed, 108 insertions(+), 42 deletions(-) diff --git a/Output/pjrcUSB/arm/usb_desc.c b/Output/pjrcUSB/arm/usb_desc.c index d32872b..0b9ea6b 100644 --- a/Output/pjrcUSB/arm/usb_desc.c +++ b/Output/pjrcUSB/arm/usb_desc.c @@ -186,7 +186,8 @@ static uint8_t nkro_keyboard_report_desc[] = { // See http://www.usb.org/developers/hidpage/Hut1_12v2.pdf Chapter 10 // Or Macros/PartialMap/usb_hid.h // - // 50 must be excluded due to a Linux bug with bitmaps (not useful anyways) + // 50 (ISO \ due to \ bug) and 156 (Clear due to Delete bug) must be excluded + // due to a Linux bug with bitmaps (not useful anyways) // 165-175 are reserved/unused as well as 222-223 and 232-65535 // 224-231 are used for modifiers (see above) // @@ -197,10 +198,11 @@ static uint8_t nkro_keyboard_report_desc[] = { // // Packing of bitmaps are as follows: // 4-49 : 6 bytes + 1 Report ID byte (0x04-0x31) ( 46 bits + 2 padding bits for 6 bytes total) - // 51-164 : 20 bytes + 1 Report ID byte (0x33-0xA4) (114 bits + 6 padding bits for 15 bytes total) + // 51-155 : 14 bytes + 1 Report ID byte (0x33-0x9B) (105 bits + 6 padding bits for 15 bytes total) + // 157-164 : 1 byte + 1 Report ID byte (0x9D-0xA4) ( 8 bits) // 176-221 : 6 bytes + 1 Report ID byte (0xB0-0xDD) ( 46 bits + 2 padding bits for 6 bytes total) // - // 4-49 (6 bytes/46 bits) + // 4-49 (6 bytes/46 bits) - MainKeys 0x85, 0x03, // Report ID (3), 0x75, 0x01, // Report Size (1), 0x95, 0x2E, // Report Count (46), @@ -213,22 +215,33 @@ static uint8_t nkro_keyboard_report_desc[] = { // Should pad 2 bits according to the spec, but OSX doesn't like this -HaaTa - // 51-164 (15 bytes/160 bits) + // 51-155 (14 bytes/105 bits) - SecondaryKeys 0x85, 0x04, // Report ID (4), 0x75, 0x01, // Report Size (1), - 0x95, 0xA0, // Report Count (160), + 0x95, 0x69, // Report Count (105), 0x15, 0x00, // Logical Minimum (0), 0x25, 0x01, // Logical Maximum (1), 0x05, 0x07, // Usage Page (Key Codes), 0x19, 0x33, // Usage Minimum (51), - 0x29, 0xA4, // Usage Maximum (164), + 0x29, 0x9B, // Usage Maximum (155), 0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield), // Should pad 6 bits according to the spec, but OSX doesn't like this -HaaTa - // 176-221 (6 bytes/46 bits) + // 157-164 (1 byte/8 bits) - TertiaryKeys 0x85, 0x05, // Report ID (5), 0x75, 0x01, // Report Size (1), + 0x95, 0x08, // Report Count (8), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum (1), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0x9D, // Usage Minimum (157), + 0x29, 0xA4, // Usage Maximum (164), + 0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield), + + // 176-221 (6 bytes/46 bits) - QuartiaryKeys + 0x85, 0x06, // Report ID (6), + 0x75, 0x01, // Report Size (1), 0x95, 0x2D, // Report Count (45), 0x15, 0x00, // Logical Minimum (0), 0x25, 0x01, // Logical Maximum (1), @@ -249,7 +262,7 @@ static uint8_t nkro_keyboard_report_desc[] = { 0x05, 0x01, // Usage Page (Generic Desktop), 0x09, 0x80, // Usage (System Control), 0xA1, 0x01, // Collection (Application), - 0x85, 0x06, // Report ID (6), + 0x85, 0x07, // Report ID (7), 0x75, 0x08, // Report Size (8), 0x95, 0x01, // Report Count (1), 0x16, 0x81, 0x00, // Logical Minimum (129), @@ -267,7 +280,7 @@ static uint8_t nkro_keyboard_report_desc[] = { 0x05, 0x0c, // Usage Page (Consumer), 0x09, 0x01, // Usage (Consumer Control), 0xA1, 0x01, // Collection (Application), - 0x85, 0x07, // Report ID (7), + 0x85, 0x08, // Report ID (8), 0x75, 0x10, // Report Size (16), 0x95, 0x01, // Report Count (1), 0x16, 0x20, 0x00, // Logical Minimum (32), diff --git a/Output/pjrcUSB/arm/usb_keyboard.c b/Output/pjrcUSB/arm/usb_keyboard.c index 7e435cd..722ae8d 100644 --- a/Output/pjrcUSB/arm/usb_keyboard.c +++ b/Output/pjrcUSB/arm/usb_keyboard.c @@ -162,9 +162,9 @@ void usb_keyboard_send() { *tx_buf++ = 0x04; // ID - // 51-164 (Middle 15 bytes) - memcpy( tx_buf, USBKeys_Keys + 6, 15 ); - tx_packet->len = 16; + // 51-155 (Middle 14 bytes) + memcpy( tx_buf, USBKeys_Keys + 6, 14 ); + tx_packet->len = 15; // Send USB Packet usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet ); @@ -175,18 +175,31 @@ void usb_keyboard_send() { *tx_buf++ = 0x05; // ID + // 157-164 (Next byte) + memcpy( tx_buf, USBKeys_Keys + 20, 1 ); + tx_packet->len = 2; + + // Send USB Packet + usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet ); + USBKeys_Changed &= ~USBKeyChangeState_TertiaryKeys; // Mark sent + } + // Check quartiary key section + else if ( USBKeys_Changed & USBKeyChangeState_QuartiaryKeys ) + { + *tx_buf++ = 0x06; // ID + // 176-221 (last 6 bytes) memcpy( tx_buf, USBKeys_Keys + 21, 6 ); tx_packet->len = 7; // Send USB Packet usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet ); - USBKeys_Changed &= ~USBKeyChangeState_TertiaryKeys; // Mark sent + USBKeys_Changed &= ~USBKeyChangeState_QuartiaryKeys; // Mark sent } // Check system control keys else if ( USBKeys_Changed & USBKeyChangeState_System ) { - *tx_buf++ = 0x06; // ID + *tx_buf++ = 0x07; // ID *tx_buf = USBKeys_SysCtrl; tx_packet->len = 2; @@ -197,7 +210,7 @@ void usb_keyboard_send() // Check consumer control keys else if ( USBKeys_Changed & USBKeyChangeState_Consumer ) { - *tx_buf++ = 0x07; // ID + *tx_buf++ = 0x08; // ID *tx_buf++ = (uint8_t)(USBKeys_ConsCtrl & 0x00FF); *tx_buf = (uint8_t)(USBKeys_ConsCtrl >> 8); tx_packet->len = 3; diff --git a/Output/pjrcUSB/avr/usb_keyboard_serial.c b/Output/pjrcUSB/avr/usb_keyboard_serial.c index 260733d..4024eed 100644 --- a/Output/pjrcUSB/avr/usb_keyboard_serial.c +++ b/Output/pjrcUSB/avr/usb_keyboard_serial.c @@ -131,8 +131,8 @@ inline void usb_keyboard_send() { UEDATX = 0x04; // ID - // 51-164 (Middle 15 bytes) - for ( uint8_t byte = 6; byte < 21; byte++ ) + // 51-155 (Middle 14 bytes) + for ( uint8_t byte = 6; byte < 20; byte++ ) UEDATX = USBKeys_Keys[ byte ]; UEINTX = 0; // Finished with ID @@ -144,18 +144,31 @@ inline void usb_keyboard_send() { UEDATX = 0x05; // ID - // 176-221 (last 6 bytes) - for ( uint8_t byte = 21; byte < 27; byte++ ) + // 157-164 (Next byte) + for ( uint8_t byte = 20; byte < 21; byte++ ) UEDATX = USBKeys_Keys[ byte ]; UEINTX = 0; // Finished with ID USBKeys_Changed &= ~USBKeyChangeState_TertiaryKeys; // Mark sent } + // Check quartiary key section + if ( USBKeys_Changed & USBKeyChangeState_TertiaryKeys ) + { + UEDATX = 0x06; // ID + + // 176-221 (last 6 bytes) + for ( uint8_t byte = 21; byte < 27; byte++ ) + UEDATX = USBKeys_Keys[ byte ]; + + UEINTX = 0; // Finished with ID + + USBKeys_Changed &= ~USBKeyChangeState_QuartiaryKeys; // Mark sent + } // Check system control keys if ( USBKeys_Changed & USBKeyChangeState_System ) { - UEDATX = 0x06; // ID + UEDATX = 0x07; // ID UEDATX = USBKeys_SysCtrl; UEINTX = 0; // Finished with ID @@ -164,7 +177,7 @@ inline void usb_keyboard_send() // Check consumer control keys if ( USBKeys_Changed & USBKeyChangeState_Consumer ) { - UEDATX = 0x07; // ID + UEDATX = 0x08; // ID UEDATX = (uint8_t)(USBKeys_ConsCtrl & 0x00FF); UEDATX = (uint8_t)(USBKeys_ConsCtrl >> 8); UEINTX = 0; // Finished with ID diff --git a/Output/pjrcUSB/avr/usb_keyboard_serial.h b/Output/pjrcUSB/avr/usb_keyboard_serial.h index 60b5090..1e20bed 100644 --- a/Output/pjrcUSB/avr/usb_keyboard_serial.h +++ b/Output/pjrcUSB/avr/usb_keyboard_serial.h @@ -370,7 +370,8 @@ static const uint8_t PROGMEM keyboard_nkro_hid_report_desc[] = { // See http://www.usb.org/developers/hidpage/Hut1_12v2.pdf Chapter 10 // Or Macros/PartialMap/usb_hid.h // - // 50 must be excluded due to a Linux bug with bitmaps (not useful anyways) + // 50 (ISO \ due to \ bug) and 156 (Clear due to Delete bug) must be excluded + // due to a Linux bug with bitmaps (not useful anyways) // 165-175 are reserved/unused as well as 222-223 and 232-65535 // 224-231 are used for modifiers (see above) // @@ -381,10 +382,11 @@ static const uint8_t PROGMEM keyboard_nkro_hid_report_desc[] = { // // Packing of bitmaps are as follows: // 4-49 : 6 bytes + 1 Report ID byte (0x04-0x31) ( 46 bits + 2 padding bits for 6 bytes total) - // 51-164 : 20 bytes + 1 Report ID byte (0x33-0xA4) (114 bits + 6 padding bits for 15 bytes total) + // 51-155 : 14 bytes + 1 Report ID byte (0x33-0x9B) (105 bits + 6 padding bits for 15 bytes total) + // 157-164 : 1 byte + 1 Report ID byte (0x9D-0xA4) ( 8 bits) // 176-221 : 6 bytes + 1 Report ID byte (0xB0-0xDD) ( 46 bits + 2 padding bits for 6 bytes total) // - // 4-49 (6 bytes/46 bits) + // 4-49 (6 bytes/46 bits) - MainKeys 0x85, 0x03, // Report ID (3), 0x75, 0x01, // Report Size (1), 0x95, 0x2E, // Report Count (46), @@ -397,22 +399,33 @@ static const uint8_t PROGMEM keyboard_nkro_hid_report_desc[] = { // Should pad 2 bits according to the spec, but OSX doesn't like this -HaaTa - // 51-164 (15 bytes/160 bits) + // 51-155 (14 bytes/105 bits) - SecondaryKeys 0x85, 0x04, // Report ID (4), 0x75, 0x01, // Report Size (1), - 0x95, 0xA0, // Report Count (160), + 0x95, 0x69, // Report Count (105), 0x15, 0x00, // Logical Minimum (0), 0x25, 0x01, // Logical Maximum (1), 0x05, 0x07, // Usage Page (Key Codes), 0x19, 0x33, // Usage Minimum (51), - 0x29, 0xA4, // Usage Maximum (164), + 0x29, 0x9B, // Usage Maximum (155), 0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield), // Should pad 6 bits according to the spec, but OSX doesn't like this -HaaTa - // 176-221 (6 bytes/46 bits) + // 157-164 (1 byte/8 bits) - TertiaryKeys 0x85, 0x05, // Report ID (5), 0x75, 0x01, // Report Size (1), + 0x95, 0x08, // Report Count (8), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum (1), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0x9D, // Usage Minimum (157), + 0x29, 0xA4, // Usage Maximum (164), + 0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield), + + // 176-221 (6 bytes/46 bits) - QuartiaryKeys + 0x85, 0x06, // Report ID (6), + 0x75, 0x01, // Report Size (1), 0x95, 0x2D, // Report Count (45), 0x15, 0x00, // Logical Minimum (0), 0x25, 0x01, // Logical Maximum (1), @@ -433,7 +446,7 @@ static const uint8_t PROGMEM keyboard_nkro_hid_report_desc[] = { 0x05, 0x01, // Usage Page (Generic Desktop), 0x09, 0x80, // Usage (System Control), 0xA1, 0x01, // Collection (Application), - 0x85, 0x06, // Report ID (6), + 0x85, 0x07, // Report ID (7), 0x75, 0x08, // Report Size (8), 0x95, 0x01, // Report Count (1), 0x16, 0x81, 0x00, // Logical Minimum (129), @@ -451,7 +464,7 @@ static const uint8_t PROGMEM keyboard_nkro_hid_report_desc[] = { 0x05, 0x0c, // Usage Page (Consumer), 0x09, 0x01, // Usage (Consumer Control), 0xA1, 0x01, // Collection (Application), - 0x85, 0x07, // Report ID (7), + 0x85, 0x08, // Report ID (8), 0x75, 0x10, // Report Size (16), 0x95, 0x01, // Report Count (1), 0x16, 0x20, 0x00, // Logical Minimum (32), diff --git a/Output/pjrcUSB/output_com.c b/Output/pjrcUSB/output_com.c index a0ce24d..aa5f5b0 100644 --- a/Output/pjrcUSB/output_com.c +++ b/Output/pjrcUSB/output_com.c @@ -342,10 +342,11 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a break; } // First 6 bytes - else if ( key >= 4 && key <= 50 ) + else if ( key >= 4 && key <= 49 ) { // Lookup (otherwise division or multiple checks are needed to do alignment) - uint8_t keyPos = key - (4 - 0); // Starting position in array + // Starting at 0th position, each byte has 8 bits, starting at 4th bit + uint8_t keyPos = key + (0 * 8 - 4); // Starting position in array, Ignoring 4 keys switch ( keyPos ) { byteLookup( 0 ); @@ -358,11 +359,12 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a USBKeys_Changed |= USBKeyChangeState_MainKeys; } - // Next 15 bytes - else if ( key >= 51 && key <= 164 ) + // Next 14 bytes + else if ( key >= 51 && key <= 155 ) { // Lookup (otherwise division or multiple checks are needed to do alignment) - uint8_t keyPos = key - (51 - 48); // Starting position in array + // Starting at 6th byte position, each byte has 8 bits, starting at 51st bit + uint8_t keyPos = key + (6 * 8 - 51); // Starting position in array switch ( keyPos ) { byteLookup( 6 ); @@ -379,16 +381,27 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a byteLookup( 17 ); byteLookup( 18 ); byteLookup( 19 ); - byteLookup( 20 ); } USBKeys_Changed |= USBKeyChangeState_SecondaryKeys; } + // Next byte + else if ( key >= 157 && key <= 164 ) + { + // Lookup (otherwise division or multiple checks are needed to do alignment) + uint8_t keyPos = key + (20 * 8 - 157); // Starting position in array, Ignoring 6 keys + switch ( keyPos ) + { + byteLookup( 20 ); + } + + USBKeys_Changed |= USBKeyChangeState_TertiaryKeys; + } // Last 6 bytes else if ( key >= 176 && key <= 221 ) { // Lookup (otherwise division or multiple checks are needed to do alignment) - uint8_t keyPos = key - (176 - 168); // Starting position in array + uint8_t keyPos = key + (21 * 8 - 176); // Starting position in array switch ( keyPos ) { byteLookup( 21 ); @@ -399,7 +412,7 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a byteLookup( 26 ); } - USBKeys_Changed |= USBKeyChangeState_TertiaryKeys; + USBKeys_Changed |= USBKeyChangeState_QuartiaryKeys; } // Received 0x00 // This is a special USB Code that internally indicates a "break" @@ -415,7 +428,7 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a // Invalid key else { - warn_msg("USB Code not within 4-164 (0x4-0xA4) or 176-221 (0xB0-0xDD) NKRO Mode: "); + warn_msg("USB Code not within 4-49 (0x4-0x31), 51-155 (0x33-0x9B), 157-164 (0x9D-0xA4), 176-221 (0xB0-0xDD) or 224-231 (0xE0-0xE7) NKRO Mode: "); printHex( key ); print( NL ); break; diff --git a/Output/pjrcUSB/output_com.h b/Output/pjrcUSB/output_com.h index 1daaf02..7938040 100644 --- a/Output/pjrcUSB/output_com.h +++ b/Output/pjrcUSB/output_com.h @@ -51,9 +51,10 @@ typedef enum USBKeyChangeState { USBKeyChangeState_MainKeys = 0x02, USBKeyChangeState_SecondaryKeys = 0x04, USBKeyChangeState_TertiaryKeys = 0x08, - USBKeyChangeState_System = 0x10, - USBKeyChangeState_Consumer = 0x20, - USBKeyChangeState_All = 0x3F, + USBKeyChangeState_QuartiaryKeys = 0x10, + USBKeyChangeState_System = 0x20, + USBKeyChangeState_Consumer = 0x40, + USBKeyChangeState_All = 0x7F, } USBKeyChangeState;