Fixing NKRO on Windows 8.1
- Had to re-write descriptor to support Windows 8.1 while still working with Mac OSX - NKRO keyboard is now more bandwidth intensive as all the keys must be updated at the same time (due to 8.1 bug in the HID spec)
This commit is contained in:
parent
774ccc7fe9
commit
c939059c7f
@ -153,19 +153,8 @@ static uint8_t nkro_keyboard_report_desc[] = {
|
|||||||
0x09, 0x06, // Usage (Keyboard),
|
0x09, 0x06, // Usage (Keyboard),
|
||||||
0xA1, 0x01, // Collection (Application) - Keyboard,
|
0xA1, 0x01, // Collection (Application) - Keyboard,
|
||||||
|
|
||||||
// Modifier Byte
|
|
||||||
0x85, 0x01, // Report ID (1),
|
|
||||||
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, 0xE0, // Usage Minimum (224),
|
|
||||||
0x29, 0xE7, // Usage Maximum (231),
|
|
||||||
0x81, 0x02, // Input (Data, Variable, Absolute),
|
|
||||||
|
|
||||||
// LED Report
|
// LED Report
|
||||||
0x85, 0x02, // Report ID (2),
|
0x85, 0x01, // Report ID (1),
|
||||||
0x75, 0x01, // Report Size (1),
|
0x75, 0x01, // Report Size (1),
|
||||||
0x95, 0x05, // Report Count (5),
|
0x95, 0x05, // Report Count (5),
|
||||||
0x05, 0x08, // Usage Page (LEDs),
|
0x05, 0x08, // Usage Page (LEDs),
|
||||||
@ -189,21 +178,34 @@ static uint8_t nkro_keyboard_report_desc[] = {
|
|||||||
// 50 (ISO \ due to \ bug) and 156 (Clear due to Delete bug) must be excluded
|
// 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)
|
// due to a Linux bug with bitmaps (not useful anyways)
|
||||||
// 165-175 are reserved/unused as well as 222-223 and 232-65535
|
// 165-175 are reserved/unused as well as 222-223 and 232-65535
|
||||||
// 224-231 are used for modifiers (see above)
|
|
||||||
//
|
//
|
||||||
// Compatibility Notes:
|
// Compatibility Notes:
|
||||||
// - Using a second endpoint for a boot mode device helps with compatibility
|
// - Using a second endpoint for a boot mode device helps with compatibility
|
||||||
// - DO NOT use Padding in the descriptor for bitfields
|
// - DO NOT use Padding in the descriptor for bitfields
|
||||||
// (Mac OSX silently fails... Windows/Linux work correctly)
|
// (Mac OSX silently fails... Windows/Linux work correctly)
|
||||||
|
// - DO NOT use Report IDs, Windows 8.1 will not update keyboard correctly (modifiers disappear)
|
||||||
|
// (all other OSs, including OSX work fine...)
|
||||||
|
// (you can use them *iff* you only have 1 per collection)
|
||||||
|
// - Mac OSX and Windows 8.1 are extremely picky about padding
|
||||||
//
|
//
|
||||||
// Packing of bitmaps are as follows:
|
// 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)
|
// 4-49 : 6 bytes (0x04-0x31) ( 46 bits + 2 padding bits for 6 bytes total)
|
||||||
// 51-155 : 14 bytes + 1 Report ID byte (0x33-0x9B) (105 bits + 6 padding bits for 15 bytes total)
|
// 51-155 : 14 bytes (0x33-0x9B) (105 bits + 6 padding bits for 15 bytes total)
|
||||||
// 157-164 : 1 byte + 1 Report ID byte (0x9D-0xA4) ( 8 bits)
|
// 157-164 : 1 byte (0x9D-0xA4) ( 8 bits)
|
||||||
// 176-221 : 6 bytes + 1 Report ID byte (0xB0-0xDD) ( 46 bits + 2 padding bits for 6 bytes total)
|
// 176-221 : 6 bytes (0xB0-0xDD) ( 46 bits + 2 padding bits for 6 bytes total)
|
||||||
//
|
// 224-231 : 1 byte (0xE0-0xE7) ( 8 bits)
|
||||||
|
|
||||||
|
// Modifier Byte
|
||||||
|
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, 0xE0, // Usage Minimum (224),
|
||||||
|
0x29, 0xE7, // Usage Maximum (231),
|
||||||
|
0x81, 0x02, // Input (Data, Variable, Absolute),
|
||||||
|
|
||||||
// 4-49 (6 bytes/46 bits) - MainKeys
|
// 4-49 (6 bytes/46 bits) - MainKeys
|
||||||
0x85, 0x03, // Report ID (3),
|
|
||||||
0x75, 0x01, // Report Size (1),
|
0x75, 0x01, // Report Size (1),
|
||||||
0x95, 0x2E, // Report Count (46),
|
0x95, 0x2E, // Report Count (46),
|
||||||
0x15, 0x00, // Logical Minimum (0),
|
0x15, 0x00, // Logical Minimum (0),
|
||||||
@ -213,10 +215,12 @@ static uint8_t nkro_keyboard_report_desc[] = {
|
|||||||
0x29, 0x31, // Usage Maximum (49),
|
0x29, 0x31, // Usage Maximum (49),
|
||||||
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
||||||
|
|
||||||
// Should pad 2 bits according to the spec, but OSX doesn't like this -HaaTa
|
// Padding (2 bits)
|
||||||
|
0x75, 0x02, // Report Size (2),
|
||||||
|
0x95, 0x01, // Report Count (1),
|
||||||
|
0x81, 0x03, // Input (Constant),
|
||||||
|
|
||||||
// 51-155 (14 bytes/105 bits) - SecondaryKeys
|
// 51-155 (14 bytes/105 bits) - SecondaryKeys
|
||||||
0x85, 0x04, // Report ID (4),
|
|
||||||
0x75, 0x01, // Report Size (1),
|
0x75, 0x01, // Report Size (1),
|
||||||
0x95, 0x69, // Report Count (105),
|
0x95, 0x69, // Report Count (105),
|
||||||
0x15, 0x00, // Logical Minimum (0),
|
0x15, 0x00, // Logical Minimum (0),
|
||||||
@ -226,10 +230,12 @@ static uint8_t nkro_keyboard_report_desc[] = {
|
|||||||
0x29, 0x9B, // Usage Maximum (155),
|
0x29, 0x9B, // Usage Maximum (155),
|
||||||
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
||||||
|
|
||||||
// Should pad 6 bits according to the spec, but OSX doesn't like this -HaaTa
|
// Padding (7 bits)
|
||||||
|
0x75, 0x07, // Report Size (7),
|
||||||
|
0x95, 0x01, // Report Count (1),
|
||||||
|
0x81, 0x03, // Input (Constant),
|
||||||
|
|
||||||
// 157-164 (1 byte/8 bits) - TertiaryKeys
|
// 157-164 (1 byte/8 bits) - TertiaryKeys
|
||||||
0x85, 0x05, // Report ID (5),
|
|
||||||
0x75, 0x01, // Report Size (1),
|
0x75, 0x01, // Report Size (1),
|
||||||
0x95, 0x08, // Report Count (8),
|
0x95, 0x08, // Report Count (8),
|
||||||
0x15, 0x00, // Logical Minimum (0),
|
0x15, 0x00, // Logical Minimum (0),
|
||||||
@ -240,9 +246,8 @@ static uint8_t nkro_keyboard_report_desc[] = {
|
|||||||
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
||||||
|
|
||||||
// 176-221 (6 bytes/46 bits) - QuartiaryKeys
|
// 176-221 (6 bytes/46 bits) - QuartiaryKeys
|
||||||
0x85, 0x06, // Report ID (6),
|
|
||||||
0x75, 0x01, // Report Size (1),
|
0x75, 0x01, // Report Size (1),
|
||||||
0x95, 0x2D, // Report Count (45),
|
0x95, 0x2E, // Report Count (46),
|
||||||
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),
|
||||||
@ -250,8 +255,10 @@ static uint8_t nkro_keyboard_report_desc[] = {
|
|||||||
0x29, 0xDD, // Usage Maximum (221),
|
0x29, 0xDD, // Usage Maximum (221),
|
||||||
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
||||||
|
|
||||||
// Should pad 2 bits according to the spec, but OSX doesn't like this -HaaTa
|
// Padding (2 bits)
|
||||||
|
0x75, 0x02, // Report Size (2),
|
||||||
|
0x95, 0x01, // Report Count (1),
|
||||||
|
0x81, 0x03, // Input (Constant),
|
||||||
0xc0, // End Collection - Keyboard
|
0xc0, // End Collection - Keyboard
|
||||||
|
|
||||||
// System Control Collection
|
// System Control Collection
|
||||||
@ -262,7 +269,7 @@ static uint8_t nkro_keyboard_report_desc[] = {
|
|||||||
0x05, 0x01, // Usage Page (Generic Desktop),
|
0x05, 0x01, // Usage Page (Generic Desktop),
|
||||||
0x09, 0x80, // Usage (System Control),
|
0x09, 0x80, // Usage (System Control),
|
||||||
0xA1, 0x01, // Collection (Application),
|
0xA1, 0x01, // Collection (Application),
|
||||||
0x85, 0x07, // Report ID (7),
|
0x85, 0x02, // Report ID (2),
|
||||||
0x75, 0x08, // Report Size (8),
|
0x75, 0x08, // Report Size (8),
|
||||||
0x95, 0x01, // Report Count (1),
|
0x95, 0x01, // Report Count (1),
|
||||||
0x16, 0x81, 0x00, // Logical Minimum (129),
|
0x16, 0x81, 0x00, // Logical Minimum (129),
|
||||||
@ -280,7 +287,7 @@ static uint8_t nkro_keyboard_report_desc[] = {
|
|||||||
0x05, 0x0c, // Usage Page (Consumer),
|
0x05, 0x0c, // Usage Page (Consumer),
|
||||||
0x09, 0x01, // Usage (Consumer Control),
|
0x09, 0x01, // Usage (Consumer Control),
|
||||||
0xA1, 0x01, // Collection (Application),
|
0xA1, 0x01, // Collection (Application),
|
||||||
0x85, 0x08, // Report ID (8),
|
0x85, 0x03, // Report ID (3),
|
||||||
0x75, 0x10, // Report Size (16),
|
0x75, 0x10, // Report Size (16),
|
||||||
0x95, 0x01, // Report Count (1),
|
0x95, 0x01, // Report Count (1),
|
||||||
0x16, 0x20, 0x00, // Logical Minimum (32),
|
0x16, 0x20, 0x00, // Logical Minimum (32),
|
||||||
|
@ -397,7 +397,7 @@ static void usb_setup()
|
|||||||
case 0x2021: // CDC_SET_LINE_CODING
|
case 0x2021: // CDC_SET_LINE_CODING
|
||||||
// XXX Needed?
|
// XXX Needed?
|
||||||
//serial_print("set coding, waiting...\n");
|
//serial_print("set coding, waiting...\n");
|
||||||
//endpoint0_stall();
|
endpoint0_stall();
|
||||||
return; // Cannot stall here (causes issues)
|
return; // Cannot stall here (causes issues)
|
||||||
|
|
||||||
case 0x0921: // HID SET_REPORT
|
case 0x0921: // HID SET_REPORT
|
||||||
|
@ -133,73 +133,10 @@ void usb_keyboard_send()
|
|||||||
|
|
||||||
// Send NKRO keyboard interrupts packet(s)
|
// Send NKRO keyboard interrupts packet(s)
|
||||||
case 1:
|
case 1:
|
||||||
// Check modifiers
|
|
||||||
if ( USBKeys_Changed & USBKeyChangeState_Modifiers )
|
|
||||||
{
|
|
||||||
*tx_buf++ = 0x01; // ID
|
|
||||||
*tx_buf = USBKeys_Modifiers;
|
|
||||||
tx_packet->len = 2;
|
|
||||||
|
|
||||||
// Send USB Packet
|
|
||||||
usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet );
|
|
||||||
USBKeys_Changed &= ~USBKeyChangeState_Modifiers; // Mark sent
|
|
||||||
}
|
|
||||||
// Check main key section
|
|
||||||
else if ( USBKeys_Changed & USBKeyChangeState_MainKeys )
|
|
||||||
{
|
|
||||||
*tx_buf++ = 0x03; // ID
|
|
||||||
|
|
||||||
// 4-49 (first 6 bytes)
|
|
||||||
memcpy( tx_buf, USBKeys_Keys, 6 );
|
|
||||||
tx_packet->len = 7;
|
|
||||||
|
|
||||||
// Send USB Packet
|
|
||||||
usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet );
|
|
||||||
USBKeys_Changed &= ~USBKeyChangeState_MainKeys; // Mark sent
|
|
||||||
}
|
|
||||||
// Check secondary key section
|
|
||||||
else if ( USBKeys_Changed & USBKeyChangeState_SecondaryKeys )
|
|
||||||
{
|
|
||||||
*tx_buf++ = 0x04; // ID
|
|
||||||
|
|
||||||
// 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 );
|
|
||||||
USBKeys_Changed &= ~USBKeyChangeState_SecondaryKeys; // Mark sent
|
|
||||||
}
|
|
||||||
// Check tertiary key section
|
|
||||||
else if ( USBKeys_Changed & USBKeyChangeState_TertiaryKeys )
|
|
||||||
{
|
|
||||||
*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_QuartiaryKeys; // Mark sent
|
|
||||||
}
|
|
||||||
// Check system control keys
|
// Check system control keys
|
||||||
else if ( USBKeys_Changed & USBKeyChangeState_System )
|
if ( USBKeys_Changed & USBKeyChangeState_System )
|
||||||
{
|
{
|
||||||
*tx_buf++ = 0x07; // ID
|
*tx_buf++ = 0x02; // ID
|
||||||
*tx_buf = USBKeys_SysCtrl;
|
*tx_buf = USBKeys_SysCtrl;
|
||||||
tx_packet->len = 2;
|
tx_packet->len = 2;
|
||||||
|
|
||||||
@ -207,10 +144,11 @@ void usb_keyboard_send()
|
|||||||
usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet );
|
usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet );
|
||||||
USBKeys_Changed &= ~USBKeyChangeState_System; // Mark sent
|
USBKeys_Changed &= ~USBKeyChangeState_System; // Mark sent
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check consumer control keys
|
// Check consumer control keys
|
||||||
else if ( USBKeys_Changed & USBKeyChangeState_Consumer )
|
if ( USBKeys_Changed & USBKeyChangeState_Consumer )
|
||||||
{
|
{
|
||||||
*tx_buf++ = 0x08; // ID
|
*tx_buf++ = 0x03; // ID
|
||||||
*tx_buf++ = (uint8_t)(USBKeys_ConsCtrl & 0x00FF);
|
*tx_buf++ = (uint8_t)(USBKeys_ConsCtrl & 0x00FF);
|
||||||
*tx_buf = (uint8_t)(USBKeys_ConsCtrl >> 8);
|
*tx_buf = (uint8_t)(USBKeys_ConsCtrl >> 8);
|
||||||
tx_packet->len = 3;
|
tx_packet->len = 3;
|
||||||
@ -220,6 +158,40 @@ void usb_keyboard_send()
|
|||||||
USBKeys_Changed &= ~USBKeyChangeState_Consumer; // Mark sent
|
USBKeys_Changed &= ~USBKeyChangeState_Consumer; // Mark sent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Standard HID Keyboard
|
||||||
|
if ( USBKeys_Changed )
|
||||||
|
{
|
||||||
|
tx_packet->len = 0;
|
||||||
|
|
||||||
|
// Modifiers
|
||||||
|
*tx_buf++ = 0x01; // ID
|
||||||
|
*tx_buf++ = USBKeys_Modifiers;
|
||||||
|
tx_packet->len += 2;
|
||||||
|
|
||||||
|
// 4-49 (first 6 bytes)
|
||||||
|
memcpy( tx_buf, USBKeys_Keys, 6 );
|
||||||
|
tx_buf += 6;
|
||||||
|
tx_packet->len += 6;
|
||||||
|
|
||||||
|
// 51-155 (Middle 14 bytes)
|
||||||
|
memcpy( tx_buf, USBKeys_Keys + 6, 14 );
|
||||||
|
tx_buf += 14;
|
||||||
|
tx_packet->len += 14;
|
||||||
|
|
||||||
|
// 157-164 (Next byte)
|
||||||
|
memcpy( tx_buf, USBKeys_Keys + 20, 1 );
|
||||||
|
tx_buf += 1;
|
||||||
|
tx_packet->len += 1;
|
||||||
|
|
||||||
|
// 176-221 (last 6 bytes)
|
||||||
|
memcpy( tx_buf, USBKeys_Keys + 21, 6 );
|
||||||
|
tx_packet->len += 6;
|
||||||
|
|
||||||
|
// Send USB Packet
|
||||||
|
usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet );
|
||||||
|
USBKeys_Changed = USBKeyChangeState_None; // Mark sent
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,85 +104,54 @@ inline void usb_keyboard_send()
|
|||||||
|
|
||||||
// Send NKRO keyboard interrupts packet(s)
|
// Send NKRO keyboard interrupts packet(s)
|
||||||
case 1:
|
case 1:
|
||||||
// Check modifiers
|
// Check system control keys
|
||||||
if ( USBKeys_Changed & USBKeyChangeState_Modifiers )
|
if ( USBKeys_Changed & USBKeyChangeState_System )
|
||||||
{
|
{
|
||||||
UEDATX = 0x01; // ID
|
UEDATX = 0x02; // ID
|
||||||
UEDATX = USBKeys_Modifiers;
|
UEDATX = USBKeys_SysCtrl;
|
||||||
UEINTX = 0; // Finished with ID
|
UEINTX = 0; // Finished with ID
|
||||||
|
|
||||||
USBKeys_Changed &= ~USBKeyChangeState_Modifiers; // Mark sent
|
USBKeys_Changed &= ~USBKeyChangeState_System; // Mark sent
|
||||||
}
|
}
|
||||||
// Check main key section
|
|
||||||
if ( USBKeys_Changed & USBKeyChangeState_MainKeys )
|
// Check consumer control keys
|
||||||
|
if ( USBKeys_Changed & USBKeyChangeState_Consumer )
|
||||||
{
|
{
|
||||||
UEDATX = 0x03; // ID
|
UEDATX = 0x03; // ID
|
||||||
|
UEDATX = (uint8_t)(USBKeys_ConsCtrl & 0x00FF);
|
||||||
|
UEDATX = (uint8_t)(USBKeys_ConsCtrl >> 8);
|
||||||
|
UEINTX = 0; // Finished with ID
|
||||||
|
|
||||||
|
USBKeys_Changed &= ~USBKeyChangeState_Consumer; // Mark sent
|
||||||
|
}
|
||||||
|
|
||||||
|
// Standard HID Keyboard
|
||||||
|
if ( USBKeys_Changed )
|
||||||
|
{
|
||||||
|
UEDATX = 0x01; // ID
|
||||||
|
|
||||||
|
// Modifiers
|
||||||
|
UEDATX = USBKeys_Modifiers;
|
||||||
|
|
||||||
// 4-49 (first 6 bytes)
|
// 4-49 (first 6 bytes)
|
||||||
for ( uint8_t byte = 0; byte < 6; byte++ )
|
for ( uint8_t byte = 0; byte < 6; byte++ )
|
||||||
UEDATX = USBKeys_Keys[ byte ];
|
UEDATX = USBKeys_Keys[ byte ];
|
||||||
|
|
||||||
UEINTX = 0; // Finished with ID
|
|
||||||
|
|
||||||
USBKeys_Changed &= ~USBKeyChangeState_MainKeys; // Mark sent
|
|
||||||
}
|
|
||||||
// Check secondary key section
|
|
||||||
if ( USBKeys_Changed & USBKeyChangeState_SecondaryKeys )
|
|
||||||
{
|
|
||||||
UEDATX = 0x04; // ID
|
|
||||||
|
|
||||||
// 51-155 (Middle 14 bytes)
|
// 51-155 (Middle 14 bytes)
|
||||||
for ( uint8_t byte = 6; byte < 20; byte++ )
|
for ( uint8_t byte = 6; byte < 20; byte++ )
|
||||||
UEDATX = USBKeys_Keys[ byte ];
|
UEDATX = USBKeys_Keys[ byte ];
|
||||||
|
|
||||||
UEINTX = 0; // Finished with ID
|
|
||||||
|
|
||||||
USBKeys_Changed &= ~USBKeyChangeState_SecondaryKeys; // Mark sent
|
|
||||||
}
|
|
||||||
// Check tertiary key section
|
|
||||||
if ( USBKeys_Changed & USBKeyChangeState_TertiaryKeys )
|
|
||||||
{
|
|
||||||
UEDATX = 0x05; // ID
|
|
||||||
|
|
||||||
// 157-164 (Next byte)
|
// 157-164 (Next byte)
|
||||||
for ( uint8_t byte = 20; byte < 21; byte++ )
|
for ( uint8_t byte = 20; byte < 21; byte++ )
|
||||||
UEDATX = USBKeys_Keys[ 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)
|
// 176-221 (last 6 bytes)
|
||||||
for ( uint8_t byte = 21; byte < 27; byte++ )
|
for ( uint8_t byte = 21; byte < 27; byte++ )
|
||||||
UEDATX = USBKeys_Keys[ byte ];
|
UEDATX = USBKeys_Keys[ byte ];
|
||||||
|
|
||||||
UEINTX = 0; // Finished with ID
|
UEINTX = 0; // Finished with ID
|
||||||
|
|
||||||
USBKeys_Changed &= ~USBKeyChangeState_QuartiaryKeys; // Mark sent
|
USBKeys_Changed = USBKeyChangeState_None; // Mark sent
|
||||||
}
|
|
||||||
// Check system control keys
|
|
||||||
if ( USBKeys_Changed & USBKeyChangeState_System )
|
|
||||||
{
|
|
||||||
UEDATX = 0x07; // ID
|
|
||||||
UEDATX = USBKeys_SysCtrl;
|
|
||||||
UEINTX = 0; // Finished with ID
|
|
||||||
|
|
||||||
USBKeys_Changed &= ~USBKeyChangeState_System; // Mark sent
|
|
||||||
}
|
|
||||||
// Check consumer control keys
|
|
||||||
if ( USBKeys_Changed & USBKeyChangeState_Consumer )
|
|
||||||
{
|
|
||||||
UEDATX = 0x08; // ID
|
|
||||||
UEDATX = (uint8_t)(USBKeys_ConsCtrl & 0x00FF);
|
|
||||||
UEDATX = (uint8_t)(USBKeys_ConsCtrl >> 8);
|
|
||||||
UEINTX = 0; // Finished with ID
|
|
||||||
|
|
||||||
USBKeys_Changed &= ~USBKeyChangeState_Consumer; // Mark sent
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -337,19 +337,8 @@ static const uint8_t PROGMEM keyboard_nkro_hid_report_desc[] = {
|
|||||||
0x09, 0x06, // Usage (Keyboard),
|
0x09, 0x06, // Usage (Keyboard),
|
||||||
0xA1, 0x01, // Collection (Application) - Keyboard,
|
0xA1, 0x01, // Collection (Application) - Keyboard,
|
||||||
|
|
||||||
// Modifier Byte
|
|
||||||
0x85, 0x01, // Report ID (1),
|
|
||||||
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, 0xE0, // Usage Minimum (224),
|
|
||||||
0x29, 0xE7, // Usage Maximum (231),
|
|
||||||
0x81, 0x02, // Input (Data, Variable, Absolute),
|
|
||||||
|
|
||||||
// LED Report
|
// LED Report
|
||||||
0x85, 0x02, // Report ID (2),
|
0x85, 0x01, // Report ID (1),
|
||||||
0x75, 0x01, // Report Size (1),
|
0x75, 0x01, // Report Size (1),
|
||||||
0x95, 0x05, // Report Count (5),
|
0x95, 0x05, // Report Count (5),
|
||||||
0x05, 0x08, // Usage Page (LEDs),
|
0x05, 0x08, // Usage Page (LEDs),
|
||||||
@ -373,21 +362,34 @@ static const uint8_t PROGMEM keyboard_nkro_hid_report_desc[] = {
|
|||||||
// 50 (ISO \ due to \ bug) and 156 (Clear due to Delete bug) must be excluded
|
// 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)
|
// due to a Linux bug with bitmaps (not useful anyways)
|
||||||
// 165-175 are reserved/unused as well as 222-223 and 232-65535
|
// 165-175 are reserved/unused as well as 222-223 and 232-65535
|
||||||
// 224-231 are used for modifiers (see above)
|
|
||||||
//
|
//
|
||||||
// Compatibility Notes:
|
// Compatibility Notes:
|
||||||
// - Using a second endpoint for a boot mode device helps with compatibility
|
// - Using a second endpoint for a boot mode device helps with compatibility
|
||||||
// - DO NOT use Padding in the descriptor for bitfields
|
// - DO NOT use Padding in the descriptor for bitfields
|
||||||
// (Mac OSX silently fails... Windows/Linux work correctly)
|
// (Mac OSX silently fails... Windows/Linux work correctly)
|
||||||
|
// - DO NOT use Report IDs, Windows 8.1 will not update keyboard correctly (modifiers disappear)
|
||||||
|
// (all other OSs, including OSX work fine...)
|
||||||
|
// (you can use them *iff* you only have 1 per collection)
|
||||||
|
// - Mac OSX and Windows 8.1 are extremely picky about padding
|
||||||
//
|
//
|
||||||
// Packing of bitmaps are as follows:
|
// 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)
|
// 4-49 : 6 bytes (0x04-0x31) ( 46 bits + 2 padding bits for 6 bytes total)
|
||||||
// 51-155 : 14 bytes + 1 Report ID byte (0x33-0x9B) (105 bits + 6 padding bits for 15 bytes total)
|
// 51-155 : 14 bytes (0x33-0x9B) (105 bits + 6 padding bits for 15 bytes total)
|
||||||
// 157-164 : 1 byte + 1 Report ID byte (0x9D-0xA4) ( 8 bits)
|
// 157-164 : 1 byte (0x9D-0xA4) ( 8 bits)
|
||||||
// 176-221 : 6 bytes + 1 Report ID byte (0xB0-0xDD) ( 46 bits + 2 padding bits for 6 bytes total)
|
// 176-221 : 6 bytes (0xB0-0xDD) ( 46 bits + 2 padding bits for 6 bytes total)
|
||||||
//
|
// 224-231 : 1 byte (0xE0-0xE7) ( 8 bits)
|
||||||
|
|
||||||
|
// Modifier Byte
|
||||||
|
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, 0xE0, // Usage Minimum (224),
|
||||||
|
0x29, 0xE7, // Usage Maximum (231),
|
||||||
|
0x81, 0x02, // Input (Data, Variable, Absolute),
|
||||||
|
|
||||||
// 4-49 (6 bytes/46 bits) - MainKeys
|
// 4-49 (6 bytes/46 bits) - MainKeys
|
||||||
0x85, 0x03, // Report ID (3),
|
|
||||||
0x75, 0x01, // Report Size (1),
|
0x75, 0x01, // Report Size (1),
|
||||||
0x95, 0x2E, // Report Count (46),
|
0x95, 0x2E, // Report Count (46),
|
||||||
0x15, 0x00, // Logical Minimum (0),
|
0x15, 0x00, // Logical Minimum (0),
|
||||||
@ -397,10 +399,12 @@ static const uint8_t PROGMEM keyboard_nkro_hid_report_desc[] = {
|
|||||||
0x29, 0x31, // Usage Maximum (49),
|
0x29, 0x31, // Usage Maximum (49),
|
||||||
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
||||||
|
|
||||||
// Should pad 2 bits according to the spec, but OSX doesn't like this -HaaTa
|
// Padding (2 bits)
|
||||||
|
0x75, 0x02, // Report Size (2),
|
||||||
|
0x95, 0x01, // Report Count (1),
|
||||||
|
0x81, 0x03, // Input (Constant),
|
||||||
|
|
||||||
// 51-155 (14 bytes/105 bits) - SecondaryKeys
|
// 51-155 (14 bytes/105 bits) - SecondaryKeys
|
||||||
0x85, 0x04, // Report ID (4),
|
|
||||||
0x75, 0x01, // Report Size (1),
|
0x75, 0x01, // Report Size (1),
|
||||||
0x95, 0x69, // Report Count (105),
|
0x95, 0x69, // Report Count (105),
|
||||||
0x15, 0x00, // Logical Minimum (0),
|
0x15, 0x00, // Logical Minimum (0),
|
||||||
@ -410,10 +414,12 @@ static const uint8_t PROGMEM keyboard_nkro_hid_report_desc[] = {
|
|||||||
0x29, 0x9B, // Usage Maximum (155),
|
0x29, 0x9B, // Usage Maximum (155),
|
||||||
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
||||||
|
|
||||||
// Should pad 6 bits according to the spec, but OSX doesn't like this -HaaTa
|
// Padding (7 bits)
|
||||||
|
0x75, 0x07, // Report Size (7),
|
||||||
|
0x95, 0x01, // Report Count (1),
|
||||||
|
0x81, 0x03, // Input (Constant),
|
||||||
|
|
||||||
// 157-164 (1 byte/8 bits) - TertiaryKeys
|
// 157-164 (1 byte/8 bits) - TertiaryKeys
|
||||||
0x85, 0x05, // Report ID (5),
|
|
||||||
0x75, 0x01, // Report Size (1),
|
0x75, 0x01, // Report Size (1),
|
||||||
0x95, 0x08, // Report Count (8),
|
0x95, 0x08, // Report Count (8),
|
||||||
0x15, 0x00, // Logical Minimum (0),
|
0x15, 0x00, // Logical Minimum (0),
|
||||||
@ -424,9 +430,8 @@ static const uint8_t PROGMEM keyboard_nkro_hid_report_desc[] = {
|
|||||||
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
||||||
|
|
||||||
// 176-221 (6 bytes/46 bits) - QuartiaryKeys
|
// 176-221 (6 bytes/46 bits) - QuartiaryKeys
|
||||||
0x85, 0x06, // Report ID (6),
|
|
||||||
0x75, 0x01, // Report Size (1),
|
0x75, 0x01, // Report Size (1),
|
||||||
0x95, 0x2D, // Report Count (45),
|
0x95, 0x2E, // Report Count (46),
|
||||||
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),
|
||||||
@ -434,8 +439,10 @@ static const uint8_t PROGMEM keyboard_nkro_hid_report_desc[] = {
|
|||||||
0x29, 0xDD, // Usage Maximum (221),
|
0x29, 0xDD, // Usage Maximum (221),
|
||||||
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
|
||||||
|
|
||||||
// Should pad 2 bits according to the spec, but OSX doesn't like this -HaaTa
|
// Padding (2 bits)
|
||||||
|
0x75, 0x02, // Report Size (2),
|
||||||
|
0x95, 0x01, // Report Count (1),
|
||||||
|
0x81, 0x03, // Input (Constant),
|
||||||
0xc0, // End Collection - Keyboard
|
0xc0, // End Collection - Keyboard
|
||||||
|
|
||||||
// System Control Collection
|
// System Control Collection
|
||||||
@ -446,7 +453,7 @@ static const uint8_t PROGMEM keyboard_nkro_hid_report_desc[] = {
|
|||||||
0x05, 0x01, // Usage Page (Generic Desktop),
|
0x05, 0x01, // Usage Page (Generic Desktop),
|
||||||
0x09, 0x80, // Usage (System Control),
|
0x09, 0x80, // Usage (System Control),
|
||||||
0xA1, 0x01, // Collection (Application),
|
0xA1, 0x01, // Collection (Application),
|
||||||
0x85, 0x07, // Report ID (7),
|
0x85, 0x02, // Report ID (2),
|
||||||
0x75, 0x08, // Report Size (8),
|
0x75, 0x08, // Report Size (8),
|
||||||
0x95, 0x01, // Report Count (1),
|
0x95, 0x01, // Report Count (1),
|
||||||
0x16, 0x81, 0x00, // Logical Minimum (129),
|
0x16, 0x81, 0x00, // Logical Minimum (129),
|
||||||
@ -464,7 +471,7 @@ static const uint8_t PROGMEM keyboard_nkro_hid_report_desc[] = {
|
|||||||
0x05, 0x0c, // Usage Page (Consumer),
|
0x05, 0x0c, // Usage Page (Consumer),
|
||||||
0x09, 0x01, // Usage (Consumer Control),
|
0x09, 0x01, // Usage (Consumer Control),
|
||||||
0xA1, 0x01, // Collection (Application),
|
0xA1, 0x01, // Collection (Application),
|
||||||
0x85, 0x08, // Report ID (8),
|
0x85, 0x03, // Report ID (3),
|
||||||
0x75, 0x10, // Report Size (16),
|
0x75, 0x10, // Report Size (16),
|
||||||
0x95, 0x01, // Report Count (1),
|
0x95, 0x01, // Report Count (1),
|
||||||
0x16, 0x20, 0x00, // Logical Minimum (32),
|
0x16, 0x20, 0x00, // Logical Minimum (32),
|
||||||
|
Reference in New Issue
Block a user