Browse Source

Merge branch 'lufa_nkro'

core
tmk 11 years ago
parent
commit
bc9f298a54
6 changed files with 161 additions and 41 deletions
  1. 20
    16
      common/host.c
  2. 29
    7
      common/report.h
  3. 62
    3
      protocol/lufa/descriptor.c
  4. 22
    2
      protocol/lufa/descriptor.h
  5. 25
    3
      protocol/lufa/lufa.c
  6. 3
    10
      protocol/pjrc/usb_keyboard.c

+ 20
- 16
common/host.c View File



static inline void add_key_byte(uint8_t code); static inline void add_key_byte(uint8_t code);
static inline void del_key_byte(uint8_t code); static inline void del_key_byte(uint8_t code);
#ifdef NKRO_ENABLE
static inline void add_key_bit(uint8_t code); static inline void add_key_bit(uint8_t code);
static inline void del_key_bit(uint8_t code); static inline void del_key_bit(uint8_t code);
#endif




void host_set_driver(host_driver_t *d) void host_set_driver(host_driver_t *d)
(*driver->send_keyboard)(report); (*driver->send_keyboard)(report);


if (debug_keyboard) { if (debug_keyboard) {
dprint("keys: ");
for (int i = 0; i < REPORT_KEYS; i++) {
dprintf("%02X ", keyboard_report->keys[i]);
dprint("keyboard_report: ");
for (uint8_t i = 0; i < REPORT_SIZE; i++) {
dprintf("%02X ", keyboard_report->raw[i]);
} }
dprintf(" mods: %02X\n", keyboard_report->mods);
dprint("\n");
} }
} }




void host_clear_keys(void) void host_clear_keys(void)
{ {
for (int8_t i = 0; i < REPORT_KEYS; i++) {
keyboard_report->keys[i] = 0;
// not clea mods
for (int8_t i = 1; i < REPORT_SIZE; i++) {
keyboard_report->raw[i] = 0;
} }
} }


uint8_t host_has_anykey(void) uint8_t host_has_anykey(void)
{ {
uint8_t cnt = 0; uint8_t cnt = 0;
for (int i = 0; i < REPORT_KEYS; i++) {
if (keyboard_report->keys[i])
for (uint8_t i = 1; i < REPORT_SIZE; i++) {
if (keyboard_report->raw[i])
cnt++; cnt++;
} }
return cnt; return cnt;
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
if (keyboard_nkro) { if (keyboard_nkro) {
uint8_t i = 0; uint8_t i = 0;
for (; i < REPORT_KEYS && !keyboard_report->keys[i]; i++)
for (; i < REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
; ;
return i<<3 | biton(keyboard_report->keys[i]);
return i<<3 | biton(keyboard_report->nkro.bits[i]);
} }
#endif #endif
return keyboard_report->keys[0]; return keyboard_report->keys[0];


static inline void del_key_byte(uint8_t code) static inline void del_key_byte(uint8_t code)
{ {
int i = 0;
for (; i < REPORT_KEYS; i++) {
for (uint8_t i = 0; i < REPORT_KEYS; i++) {
if (keyboard_report->keys[i] == code) { if (keyboard_report->keys[i] == code) {
keyboard_report->keys[i] = 0; keyboard_report->keys[i] = 0;
} }
} }
} }


#ifdef NKRO_ENABLE
static inline void add_key_bit(uint8_t code) static inline void add_key_bit(uint8_t code)
{ {
if ((code>>3) < REPORT_KEYS) {
keyboard_report->keys[code>>3] |= 1<<(code&7);
if ((code>>3) < REPORT_BITS) {
keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
} else { } else {
dprintf("add_key_bit: can't add: %02X\n", code); dprintf("add_key_bit: can't add: %02X\n", code);
} }


static inline void del_key_bit(uint8_t code) static inline void del_key_bit(uint8_t code)
{ {
if ((code>>3) < REPORT_KEYS) {
keyboard_report->keys[code>>3] &= ~(1<<(code&7));
if ((code>>3) < REPORT_BITS) {
keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
} else { } else {
dprintf("del_key_bit: can't del: %02X\n", code); dprintf("del_key_bit: can't del: %02X\n", code);
} }
} }
#endif

+ 29
- 7
common/report.h View File





/* key report size(NKRO or boot mode) */ /* key report size(NKRO or boot mode) */
#if defined(PROTOCOL_PJRC)
#if defined(PROTOCOL_PJRC) && defined(NKRO_ENABLE)
# include "usb.h" # include "usb.h"
# if defined(KBD2_REPORT_KEYS) && KBD2_REPORT_KEYS > KBD_REPORT_KEYS
# define REPORT_KEYS KBD2_REPORT_KEYS
# else
# define REPORT_KEYS KBD_REPORT_KEYS
# endif
# define REPORT_SIZE KBD2_SIZE
# define REPORT_KEYS (KBD2_SIZE - 2)
# define REPORT_BITS (KBD2_SIZE - 1)

#elif defined(PROTOCOL_LUFA) && defined(NKRO_ENABLE)
# include "protocol/lufa/descriptor.h"
# define REPORT_SIZE NKRO_EPSIZE
# define REPORT_KEYS (NKRO_EPSIZE - 2)
# define REPORT_BITS (NKRO_EPSIZE - 1)

#else #else
# define REPORT_SIZE 8
# define REPORT_KEYS 6 # define REPORT_KEYS 6
#endif #endif


extern "C" { extern "C" {
#endif #endif


typedef union {
uint8_t raw[REPORT_SIZE];
struct {
uint8_t mods;
uint8_t reserved;
uint8_t keys[REPORT_KEYS];
};
#ifdef NKRO_ENABLE
struct {
uint8_t mods;
uint8_t bits[REPORT_BITS];
} nkro;
#endif
} __attribute__ ((packed)) report_keyboard_t;
/*
typedef struct { typedef struct {
uint8_t mods; uint8_t mods;
uint8_t rserved;
uint8_t reserved;
uint8_t keys[REPORT_KEYS]; uint8_t keys[REPORT_KEYS];
} __attribute__ ((packed)) report_keyboard_t; } __attribute__ ((packed)) report_keyboard_t;
*/


typedef struct { typedef struct {
uint8_t buttons; uint8_t buttons;

+ 62
- 3
protocol/lufa/descriptor.c View File

HID_RI_REPORT_COUNT(8, 0x08), HID_RI_REPORT_COUNT(8, 0x08),
HID_RI_REPORT_SIZE(8, 0x01), HID_RI_REPORT_SIZE(8, 0x01),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),

HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_COUNT(8, 0x01),
HID_RI_REPORT_SIZE(8, 0x08), HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_CONSTANT),
HID_RI_INPUT(8, HID_IOF_CONSTANT), /* reserved */

HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */ HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */ HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */ HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_COUNT(8, 0x01),
HID_RI_REPORT_SIZE(8, 0x03), HID_RI_REPORT_SIZE(8, 0x03),
HID_RI_OUTPUT(8, HID_IOF_CONSTANT), HID_RI_OUTPUT(8, HID_IOF_CONSTANT),

HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */ HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */ HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */ HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */


HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */ HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */ HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
HID_RI_USAGE_MAXIMUM(8, NKRO_SIZE*8-1), /* Keyboard Right GUI */
HID_RI_USAGE_MAXIMUM(8, (NKRO_EPSIZE-1)*8-1), /* Keyboard Right GUI */
HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0x01), HID_RI_LOGICAL_MAXIMUM(8, 0x01),
HID_RI_REPORT_COUNT(8, NKRO_SIZE*8),
HID_RI_REPORT_COUNT(8, (NKRO_EPSIZE-1)*8),
HID_RI_REPORT_SIZE(8, 0x01), HID_RI_REPORT_SIZE(8, 0x01),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_RI_END_COLLECTION(0),
}; };
#endif #endif


.PollingIntervalMS = 0x01 .PollingIntervalMS = 0x01
}, },
#endif #endif

/*
* NKRO
*/
#ifdef NKRO_ENABLE
.NKRO_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},

.InterfaceNumber = NKRO_INTERFACE,
.AlternateSetting = 0x00,

.TotalEndpoints = 1,

.Class = HID_CSCP_HIDClass,
.SubClass = HID_CSCP_NonBootSubclass,
.Protocol = HID_CSCP_NonBootProtocol,

.InterfaceStrIndex = NO_DESCRIPTOR
},

.NKRO_HID =
{
.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},

.HIDSpec = VERSION_BCD(01.11),
.CountryCode = 0x00,
.TotalReportDescriptors = 1,
.HIDReportType = HID_DTYPE_Report,
.HIDReportLength = sizeof(NKROReport)
},

.NKRO_INEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},

.EndpointAddress = (ENDPOINT_DIR_IN | NKRO_IN_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = NKRO_EPSIZE,
.PollingIntervalMS = 0x01
},
#endif
}; };




Address = &ConfigurationDescriptor.Console_HID; Address = &ConfigurationDescriptor.Console_HID;
Size = sizeof(USB_HID_Descriptor_HID_t); Size = sizeof(USB_HID_Descriptor_HID_t);
break; break;
#endif
#ifdef NKRO_ENABLE
case NKRO_INTERFACE:
Address = &ConfigurationDescriptor.NKRO_HID;
Size = sizeof(USB_HID_Descriptor_HID_t);
break;
#endif #endif
} }
break; break;
Address = &ConsoleReport; Address = &ConsoleReport;
Size = sizeof(ConsoleReport); Size = sizeof(ConsoleReport);
break; break;
#endif
#ifdef NKRO_ENABLE
case NKRO_INTERFACE:
Address = &NKROReport;
Size = sizeof(NKROReport);
break;
#endif #endif
} }
break; break;

+ 22
- 2
protocol/lufa/descriptor.h View File

/* /*
* Copyright 2012 Jun Wako <[email protected]>
* Copyright 2012,2013 Jun Wako <[email protected]>
* This file is based on: * This file is based on:
* LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
* LUFA-120219/Demos/Device/Lowlevel/GenericHID * LUFA-120219/Demos/Device/Lowlevel/GenericHID
USB_Descriptor_Endpoint_t Console_INEndpoint; USB_Descriptor_Endpoint_t Console_INEndpoint;
USB_Descriptor_Endpoint_t Console_OUTEndpoint; USB_Descriptor_Endpoint_t Console_OUTEndpoint;
#endif #endif

#ifdef NKRO_ENABLE
// NKRO HID Interface
USB_Descriptor_Interface_t NKRO_Interface;
USB_HID_Descriptor_HID_t NKRO_HID;
USB_Descriptor_Endpoint_t NKRO_INEndpoint;
#endif
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;




# define CONSOLE_INTERFACE EXTRAKEY_INTERFACE # define CONSOLE_INTERFACE EXTRAKEY_INTERFACE
#endif #endif


#ifdef NKRO_ENABLE
# define NKRO_INTERFACE (CONSOLE_INTERFACE + 1)
#else
# define NKRO_INTERFACE CONSOLE_INTERFACE
#endif



/* nubmer of interfaces */ /* nubmer of interfaces */
#define TOTAL_INTERFACES (CONSOLE_INTERFACE + 1)
#define TOTAL_INTERFACES (NKRO_INTERFACE + 1)




// Endopoint number and size // Endopoint number and size
#ifdef CONSOLE_ENABLE #ifdef CONSOLE_ENABLE
# define CONSOLE_IN_EPNUM (EXTRAKEY_IN_EPNUM + 1) # define CONSOLE_IN_EPNUM (EXTRAKEY_IN_EPNUM + 1)
# define CONSOLE_OUT_EPNUM (EXTRAKEY_IN_EPNUM + 2) # define CONSOLE_OUT_EPNUM (EXTRAKEY_IN_EPNUM + 2)
#else
# define CONSOLE_OUT_EPNUM EXTRAKEY_IN_EPNUM
#endif

#ifdef NKRO_ENABLE
# define NKRO_IN_EPNUM (CONSOLE_OUT_EPNUM + 1)
#endif #endif




#define MOUSE_EPSIZE 8 #define MOUSE_EPSIZE 8
#define EXTRAKEY_EPSIZE 8 #define EXTRAKEY_EPSIZE 8
#define CONSOLE_EPSIZE 32 #define CONSOLE_EPSIZE 32
#define NKRO_EPSIZE 16




uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,

+ 25
- 3
protocol/lufa/lufa.c View File

ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT, ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE); CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
#endif #endif

#ifdef NKRO_ENABLE
/* Setup NKRO HID Report Endpoints */
ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
#endif
} }


/* /*
if (USB_DeviceState != DEVICE_STATE_Configured) if (USB_DeviceState != DEVICE_STATE_Configured)
return; return;


// TODO: handle NKRO report
/* Select the Keyboard Report Endpoint */ /* Select the Keyboard Report Endpoint */
Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
#ifdef NKRO_ENABLE
if (keyboard_nkro) {
Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
}
else
#endif
{
Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
}


/* Check if Keyboard Endpoint Ready for Read/Write */ /* Check if Keyboard Endpoint Ready for Read/Write */
while (--timeout && !Endpoint_IsReadWriteAllowed()) ; while (--timeout && !Endpoint_IsReadWriteAllowed()) ;


/* Write Keyboard Report Data */ /* Write Keyboard Report Data */
Endpoint_Write_Stream_LE(report, sizeof(report_keyboard_t), NULL);
#ifdef NKRO_ENABLE
if (keyboard_nkro) {
Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
}
else
#endif
{
/* boot mode */
Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
}


/* Finalize the stream transfer to send the last packet */ /* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN(); Endpoint_ClearIN();

+ 3
- 10
protocol/pjrc/usb_keyboard.c View File



#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
if (keyboard_nkro) if (keyboard_nkro)
result = send_report(report, KBD2_ENDPOINT, 0, KBD2_REPORT_KEYS);
result = send_report(report, KBD2_ENDPOINT, 0, KBD2_SIZE);
else else
#endif #endif
{ {
if (usb_keyboard_protocol) if (usb_keyboard_protocol)
result = send_report(report, KBD_ENDPOINT, 0, KBD_REPORT_KEYS);
result = send_report(report, KBD_ENDPOINT, 0, KBD_SIZE);
else else
result = send_report(report, KBD_ENDPOINT, 0, 6); result = send_report(report, KBD_ENDPOINT, 0, 6);
} }
cli(); cli();
UENUM = endpoint; UENUM = endpoint;
} }
UEDATX = report->mods;
#ifdef NKRO_ENABLE
if (!keyboard_nkro)
UEDATX = 0;
#else
UEDATX = 0;
#endif
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->raw[i];
} }
UEINTX = 0x3A; UEINTX = 0x3A;
SREG = intr_state; SREG = intr_state;