diff options
-rw-r--r-- | common/host.c | 36 | ||||
-rw-r--r-- | common/report.h | 36 | ||||
-rw-r--r-- | keyboard/hhkb/Makefile (renamed from keyboard/hhkb/Makefile.lufa) | 12 | ||||
-rw-r--r-- | keyboard/hhkb/Makefile.pjrc | 4 | ||||
-rw-r--r-- | keyboard/hhkb/Makefile.tmk | 129 | ||||
-rw-r--r-- | keyboard/hhkb/README.md | 72 | ||||
-rw-r--r-- | keyboard/hhkb/config.h | 21 | ||||
-rw-r--r-- | protocol/lufa/descriptor.c | 65 | ||||
-rw-r--r-- | protocol/lufa/descriptor.h | 24 | ||||
-rw-r--r-- | protocol/lufa/lufa.c | 28 | ||||
-rw-r--r-- | protocol/pjrc/usb_keyboard.c | 13 |
11 files changed, 197 insertions, 243 deletions
diff --git a/common/host.c b/common/host.c index 2c2279aa4e..5694516527 100644 --- a/common/host.c +++ b/common/host.c @@ -37,8 +37,10 @@ static uint16_t last_consumer_report = 0; static inline void add_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 del_key_bit(uint8_t code); +#endif void host_set_driver(host_driver_t *d) @@ -63,11 +65,11 @@ void host_keyboard_send(report_keyboard_t *report) (*driver->send_keyboard)(report); 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"); } } @@ -122,8 +124,9 @@ void host_del_key(uint8_t key) 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; } } @@ -155,8 +158,8 @@ void host_clear_mods(void) uint8_t host_has_anykey(void) { 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++; } return cnt; @@ -172,9 +175,9 @@ uint8_t host_get_first_key(void) #ifdef NKRO_ENABLE if (keyboard_nkro) { 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 return keyboard_report->keys[0]; @@ -222,18 +225,18 @@ static inline void add_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) { keyboard_report->keys[i] = 0; } } } +#ifdef NKRO_ENABLE 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 { dprintf("add_key_bit: can't add: %02X\n", code); } @@ -241,9 +244,10 @@ static inline void add_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 { dprintf("del_key_bit: can't del: %02X\n", code); } } +#endif diff --git a/common/report.h b/common/report.h index 02deb7797e..91982840af 100644 --- a/common/report.h +++ b/common/report.h @@ -72,14 +72,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. /* key report size(NKRO or boot mode) */ -#if defined(PROTOCOL_PJRC) +#if defined(PROTOCOL_PJRC) && defined(NKRO_ENABLE) # 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 +# define REPORT_SIZE 8 # define REPORT_KEYS 6 #endif @@ -88,11 +94,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. extern "C" { #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 { uint8_t mods; - uint8_t rserved; + uint8_t reserved; uint8_t keys[REPORT_KEYS]; } __attribute__ ((packed)) report_keyboard_t; +*/ typedef struct { uint8_t buttons; diff --git a/keyboard/hhkb/Makefile.lufa b/keyboard/hhkb/Makefile index 97b8faab6e..1ef0a0187a 100644 --- a/keyboard/hhkb/Makefile.lufa +++ b/keyboard/hhkb/Makefile @@ -57,8 +57,10 @@ CONFIG_H = config.h # MCU name -MCU = at90usb1286 -#MCU = atmega32u4 +# PJRC Teensy++ 2.0 +#MCU = at90usb1286 +# TMK Alt Controller or PJRC Teensy 2.0 +MCU = atmega32u4 # Processor frequency. # This will define a symbol, F_CPU, in all source code files equal to the @@ -100,10 +102,10 @@ OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT # Boot Section Size in *bytes* # Teensy halfKay 512 # Teensy++ halfKay 1024 -# Atmel DFU loader 4096 +# Atmel DFU loader 4096 (TMK Alt Controller) # LUFA bootloader 4096 # USBaspLoader 2048 -OPT_DEFS += -DBOOTLOADER_SIZE=512 +OPT_DEFS += -DBOOTLOADER_SIZE=4096 # Build Options @@ -114,7 +116,7 @@ MOUSEKEY_ENABLE = yes # Mouse keys EXTRAKEY_ENABLE = yes # Audio control and System control CONSOLE_ENABLE = yes # Console for debug COMMAND_ENABLE = yes # Commands for debug and configuration -#NKRO_ENABLE = yes # USB Nkey Rollover +NKRO_ENABLE = yes # USB Nkey Rollover # Search Path diff --git a/keyboard/hhkb/Makefile.pjrc b/keyboard/hhkb/Makefile.pjrc index f64cd9be4d..5a781dd23a 100644 --- a/keyboard/hhkb/Makefile.pjrc +++ b/keyboard/hhkb/Makefile.pjrc @@ -23,9 +23,9 @@ CONFIG_H = config.h # MCU name, you MUST set this to match the board you are using # type "make clean" after changing this, so all files will be rebuilt #MCU = at90usb162 # Teensy 1.0 -#MCU = atmega32u4 # Teensy 2.0 +MCU = atmega32u4 # Teensy 2.0 #MCU = at90usb646 # Teensy++ 1.0 -MCU = at90usb1286 # Teensy++ 2.0 +#MCU = at90usb1286 # Teensy++ 2.0 # Processor frequency. diff --git a/keyboard/hhkb/Makefile.tmk b/keyboard/hhkb/Makefile.tmk deleted file mode 100644 index d3730081ff..0000000000 --- a/keyboard/hhkb/Makefile.tmk +++ /dev/null @@ -1,129 +0,0 @@ -#---------------------------------------------------------------------------- -# On command line: -# -# make all = Make software. -# -# make clean = Clean out built project files. -# -# make coff = Convert ELF to AVR COFF. -# -# make extcoff = Convert ELF to AVR Extended COFF. -# -# make program = Download the hex file to the device. -# Please customize your programmer settings(PROGRAM_CMD) -# -# make teensy = Download the hex file to the device, using teensy_loader_cli. -# (must have teensy_loader_cli installed). -# -# make dfu = Download the hex file to the device, using dfu-programmer (must -# have dfu-programmer installed). -# -# make flip = Download the hex file to the device, using Atmel FLIP (must -# have Atmel FLIP installed). -# -# make dfu-ee = Download the eeprom file to the device, using dfu-programmer -# (must have dfu-programmer installed). -# -# make flip-ee = Download the eeprom file to the device, using Atmel FLIP -# (must have Atmel FLIP installed). -# -# make debug = Start either simulavr or avarice as specified for debugging, -# with avr-gdb or avr-insight as the front end for debugging. -# -# make filename.s = Just compile filename.c into the assembler code only. -# -# make filename.i = Create a preprocessed source file for use in submitting -# bug reports to the GCC project. -# -# To rebuild project do "make clean" then "make all". -#---------------------------------------------------------------------------- - -# Target file name (without extension). -TARGET = hhkb_tmk - -# Directory common source filess exist -TOP_DIR = ../.. - -# Directory keyboard dependent files exist -TARGET_DIR = . - - -# List C source files here. (C dependencies are automatically generated.) -SRC += keymap.c \ - matrix.c \ - led.c - -CONFIG_H = config.h - - -# MCU name -#MCU = at90usb1286 -MCU = atmega32u4 - -# Processor frequency. -# This will define a symbol, F_CPU, in all source code files equal to the -# processor frequency in Hz. You can then use this symbol in your source code to -# calculate timings. Do NOT tack on a 'UL' at the end, this will be done -# automatically to create a 32-bit value in your source code. -# -# This will be an integer division of F_USB below, as it is sourced by -# F_USB after it has run through any CPU prescalers. Note that this value -# does not *change* the processor frequency - it should merely be updated to -# reflect the processor speed set externally so that the code can use accurate -# software delays. -F_CPU = 16000000 - - -# -# LUFA specific -# -# Target architecture (see library "Board Types" documentation). -ARCH = AVR8 - -# Input clock frequency. -# This will define a symbol, F_USB, in all source code files equal to the -# input clock frequency (before any prescaling is performed) in Hz. This value may -# differ from F_CPU if prescaling is used on the latter, and is required as the -# raw input clock is fed directly to the PLL sections of the AVR for high speed -# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' -# at the end, this will be done automatically to create a 32-bit value in your -# source code. -# -# If no clock division is performed on the input clock inside the AVR (via the -# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. -F_USB = $(F_CPU) - -# Interrupt driven control endpoint task -OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT - - -# Boot Section Size in *bytes* -# Teensy halfKay 512 -# Teensy++ halfKay 1024 -# Atmel DFU loader 4096 -# LUFA bootloader 4096 -# USBaspLoader 2048 -OPT_DEFS += -DBOOTLOADER_SIZE=4096 - - -# Build Options -# comment out to disable the options. -# -#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration -MOUSEKEY_ENABLE = yes # Mouse keys -EXTRAKEY_ENABLE = yes # Audio control and System control -CONSOLE_ENABLE = yes # Console for debug -COMMAND_ENABLE = yes # Commands for debug and configuration -#NKRO_ENABLE = yes # USB Nkey Rollover - - -# Search Path -VPATH += $(TARGET_DIR) -VPATH += $(TOP_DIR) - -include $(TOP_DIR)/protocol/lufa.mk -include $(TOP_DIR)/common.mk -include $(TOP_DIR)/rules.mk - -debug-on: EXTRAFLAGS += -DDEBUG -debug-on: all diff --git a/keyboard/hhkb/README.md b/keyboard/hhkb/README.md index b9e0b534a2..3959ae85a8 100644 --- a/keyboard/hhkb/README.md +++ b/keyboard/hhkb/README.md @@ -8,7 +8,6 @@ See [this thread][AltController] in geekhack.org. [HHKB]: http://www.pfu.fujitsu.com/hhkeyboard/ [AltController]: http://geekhack.org/index.php?topic=12047.0 -[Teensy]: http://www.pjrc.com/teensy/ ##Features @@ -22,8 +21,8 @@ See README of [tmk_keyboard] for more. [tmk_keyboard]: http://github.com/tmk/tmk_keyboard ###Pros -* No risk: Everything is all reversible -* Without PCB trace cutting, case mod or any destructives +* No risks: Everything is all reversible +* No need for PCB trace patching, case cutting or any other destructive mod * Can keep original controller intact * Can change all HHKB behaviour as you like @@ -41,61 +40,35 @@ See [doc/HHKB.txt](doc/HHKB.txt) and files under [doc/](doc/) for internal of HH ##Build Firmware & Program -You can choose some combination of hardware and USB protocol stack([LUFA], [PJRC]). +See [this document](../../doc/build.md) first. -### Install Tools -See [this document](../../doc/build.md). +### Configuration +Set `MCU`, `BOOTLOADER_SIZE` and other build options in `Makefile` and `config.h`. -### TMK Alt Controller Board - $ make -f Makefile.tmk +### Build +Just run make after intall tools. -This programs the controller with [dfu-programmer] if the tool is intalled and configured properly. + $ make - $ make -f Makefile.tmk dfu - -Push reset button and program with [FLIP]. The tool should be intalled and configured properly. - - $ make -f Makefile.tmk flip - -Or you can also program with FLIP GUI. - -[dfu-programmer]: http://dfu-programmer.sourceforge.net/ -[FLIP]: http://www.atmel.com/tools/FLIP.aspx - - -### PJRC Teensy++ -Build with [LUFA] USB stack: - - $ make -f Makefile.lufa - -or with [PJRC] USB stack: +Use `Makefile.pjrc` if you want to use PJRC stack instead of LUFA.(LUFA is recommended.) $ make -f Makefile.pjrc -Push reset button and program with [Teensy Loader(command line)]. The tool should be intalled and configured properly. - - $ make -f Makefile.lufa teensy - $ make -f Makefile.pjrc teensy - -Or you can also program with [Teensy Loader(GUI)]. +Use `Makefile.vusb` for [V-USB] controller.(not supported actively any more.) + $ make -f Makefile.vusb -[LUFA]: http://www.fourwalledcubicle.com/LUFA.php -[PJRC]: http://www.pjrc.com/teensy/usb_keyboard.html -[Teensy Loader(command line)]: http://www.pjrc.com/teensy/loader_cli.html -[Teensy Loader(GUI)]: http://www.pjrc.com/teensy/loader.html +### Program +First, push reset button on board to start bootloader. +This command programs the controller with [dfu-programmer] if the tool is intalled and configured properly. -###AVR Mega with [V-USB] -Build: - $ make -f Makefile.vusb + $ make dfu -Program [USBaspLoader] on MCU with AVR programmer like [AVRISPmkII] and tool like [avrdude]. +Or you can also use [FLIP] command to program. Also the tool should be intalled and configured properly. FLIP GUI app is also available. -You can programs with [avrdude] once you have programmed [USBaspLoader] on MCU. - $ make -f Makefile.vusb program + $ make flip -[AVRISPmkII]: http://www.atmel.com/tools/AVRISPMKII.aspx -[avrdude]: http://www.nongnu.org/avrdude/ +Use [Teensy Loader] if your controller is Teensy/Teensy++. ##How to Customize @@ -103,7 +76,7 @@ See [tmk_keyboard] documents. ##Hardware -You have some options for hardware. Development boards with USB AVR family(ATMega32U4, AT90USB1286) like Teensy will work while MegaAVR with V-USB library is also cheapear option for DIY. +You have some options for hardware. Development boards with USB AVR family(ATMega32U4, AT90USB1286) like Teensy will work while MegaAVR with [V-USB] library is also cheapear option for DIY. ###1. TMK Alt Controller Board TMK designed [Keyboard Controller Board for HHKB Pro2(KiCad project)](https://github.com/tmk/HHKB_controller). @@ -127,7 +100,6 @@ See [this post](http://geekhack.org/index.php?topic=12047.msg948923#msg948923). +---------------+ - NOTE: PJRC [Teensy](http://www.pjrc.com/teensy/) -[Teensy Loader]: http://www.pjrc.com/teensy/loader.html ###3. V-USB connection +---+ +---------------+ @@ -156,5 +128,11 @@ See [this post](http://geekhack.org/index.php?topic=12047.msg948923#msg948923). - NOTE: See [V-USB] documentation for more detail of hardware and the USB stack. - NOTE: [USBaspLoader] is very useful for firmware update. + +[LUFA]: http://www.fourwalledcubicle.com/LUFA.php +[PJRC]: http://www.pjrc.com/teensy/usb_keyboard.html +[dfu-programmer]: http://dfu-programmer.sourceforge.net/ +[FLIP]: http://www.atmel.com/tools/FLIP.aspx +[Teensy Loader]: http://www.pjrc.com/teensy/loader.html [V-USB]: http://www.obdev.at/products/vusb/index.html [USBaspLoader]: http://www.obdev.at/products/vusb/usbasploader.html diff --git a/keyboard/hhkb/config.h b/keyboard/hhkb/config.h index 8c93f97da5..83a911beab 100644 --- a/keyboard/hhkb/config.h +++ b/keyboard/hhkb/config.h @@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #define VENDOR_ID 0xFEED #define PRODUCT_ID 0xCAFE -#define DEVICE_VER 0x0103 +#define DEVICE_VER 0x0104 #define MANUFACTURER t.m.k. #define PRODUCT HHKB mod #define DESCRIPTION t.m.k. keyboard firmware for HHKB mod @@ -31,27 +31,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #define MATRIX_ROWS 8 #define MATRIX_COLS 8 -/* - * Boot magic keys - * call some function by pressing key when pluging cable or powering on. - */ -/* key position on matrix(ROW:COL) */ -#define KEY_FN 0x54 -#define KEY_D 0x14 -#define KEY_IS_ON(key) matrix_is_on((key)>>4, (key)&0xF) -/* kick up bootloader */ -#define IS_BOOTMAGIC_BOOTLOADER() KEY_IS_ON(KEY_FN) -/* debug on */ -#define IS_BOOTMAGIC_DEBUG() KEY_IS_ON(KEY_D) - /* key combination for command */ #define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) -/* mouse keys */ -#ifdef MOUSEKEY_ENABLE -# define MOUSEKEY_DELAY_TIME 100 -#endif /* period of tapping(ms) */ #define TAPPING_TERM 300 @@ -62,11 +45,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. /* Boot Magic salt key: Space */ #define BOOTMAGIC_KEY_SALT KC_FN6 + /* * Feature disable options * These options are also useful to firmware size reduction. */ - /* disable debug print */ //#define NO_DEBUG diff --git a/protocol/lufa/descriptor.c b/protocol/lufa/descriptor.c index d34ab1c5aa..a46ba3ec6a 100644 --- a/protocol/lufa/descriptor.c +++ b/protocol/lufa/descriptor.c @@ -57,9 +57,11 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = HID_RI_REPORT_COUNT(8, 0x08), HID_RI_REPORT_SIZE(8, 0x01), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), + HID_RI_REPORT_COUNT(8, 0x01), 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_MINIMUM(8, 0x01), /* Num Lock */ HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */ @@ -69,6 +71,7 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_SIZE(8, 0x03), HID_RI_OUTPUT(8, HID_IOF_CONSTANT), + HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */ HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */ HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */ @@ -210,11 +213,13 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM NKROReport[] = HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */ 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_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_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), + HID_RI_END_COLLECTION(0), }; #endif @@ -439,6 +444,48 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = .PollingIntervalMS = 0x01 }, #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 }; @@ -536,6 +583,12 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, Size = sizeof(USB_HID_Descriptor_HID_t); break; #endif +#ifdef NKRO_ENABLE + case NKRO_INTERFACE: + Address = &ConfigurationDescriptor.NKRO_HID; + Size = sizeof(USB_HID_Descriptor_HID_t); + break; +#endif } break; case HID_DTYPE_Report: @@ -562,6 +615,12 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, Size = sizeof(ConsoleReport); break; #endif +#ifdef NKRO_ENABLE + case NKRO_INTERFACE: + Address = &NKROReport; + Size = sizeof(NKROReport); + break; +#endif } break; } diff --git a/protocol/lufa/descriptor.h b/protocol/lufa/descriptor.h index 44f20d5a26..9ee1c04d79 100644 --- a/protocol/lufa/descriptor.h +++ b/protocol/lufa/descriptor.h @@ -1,5 +1,5 @@ /* - * Copyright 2012 Jun Wako <wakojun@gmail.com> + * Copyright 2012,2013 Jun Wako <wakojun@gmail.com> * This file is based on: * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse * LUFA-120219/Demos/Device/Lowlevel/GenericHID @@ -78,6 +78,13 @@ typedef struct USB_Descriptor_Endpoint_t Console_INEndpoint; USB_Descriptor_Endpoint_t Console_OUTEndpoint; #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; @@ -102,9 +109,15 @@ typedef struct # define CONSOLE_INTERFACE EXTRAKEY_INTERFACE #endif +#ifdef NKRO_ENABLE +# define NKRO_INTERFACE (CONSOLE_INTERFACE + 1) +#else +# define NKRO_INTERFACE CONSOLE_INTERFACE +#endif + /* nubmer of interfaces */ -#define TOTAL_INTERFACES (CONSOLE_INTERFACE + 1) +#define TOTAL_INTERFACES (NKRO_INTERFACE + 1) // Endopoint number and size @@ -125,6 +138,12 @@ typedef struct #ifdef CONSOLE_ENABLE # define CONSOLE_IN_EPNUM (EXTRAKEY_IN_EPNUM + 1) # 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 @@ -132,6 +151,7 @@ typedef struct #define MOUSE_EPSIZE 8 #define EXTRAKEY_EPSIZE 8 #define CONSOLE_EPSIZE 32 +#define NKRO_EPSIZE 16 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c index a863b8d23c..c1617cd05a 100644 --- a/protocol/lufa/lufa.c +++ b/protocol/lufa/lufa.c @@ -220,6 +220,12 @@ void EVENT_USB_Device_ConfigurationChanged(void) ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT, CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE); #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 } /* @@ -350,15 +356,31 @@ static void send_keyboard(report_keyboard_t *report) if (USB_DeviceState != DEVICE_STATE_Configured) return; - // TODO: handle NKRO report /* 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 */ while (--timeout && !Endpoint_IsReadWriteAllowed()) ; /* 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 */ Endpoint_ClearIN(); diff --git a/protocol/pjrc/usb_keyboard.c b/protocol/pjrc/usb_keyboard.c index 49b85c179f..de798fcc22 100644 --- a/protocol/pjrc/usb_keyboard.c +++ b/protocol/pjrc/usb_keyboard.c @@ -57,12 +57,12 @@ int8_t usb_keyboard_send_report(report_keyboard_t *report) #ifdef NKRO_ENABLE if (keyboard_nkro) - result = send_report(report, KBD2_ENDPOINT, 0, KBD2_REPORT_KEYS); + result = send_report(report, KBD2_ENDPOINT, 0, KBD2_SIZE); else #endif { if (usb_keyboard_protocol) - result = send_report(report, KBD_ENDPOINT, 0, KBD_REPORT_KEYS); + result = send_report(report, KBD_ENDPOINT, 0, KBD_SIZE); else result = send_report(report, KBD_ENDPOINT, 0, 6); } @@ -104,15 +104,8 @@ static inline int8_t send_report(report_keyboard_t *report, uint8_t endpoint, ui cli(); 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++) { - UEDATX = report->keys[i]; + UEDATX = report->raw[i]; } UEINTX = 0x3A; SREG = intr_state; |