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 |
/* 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; |
# MCU name | # MCU name | ||||
MCU = at90usb1286 | |||||
#MCU = atmega32u4 | |||||
#MCU = at90usb1286 | |||||
MCU = atmega32u4 | |||||
# Processor frequency. | # Processor frequency. | ||||
# This will define a symbol, F_CPU, in all source code files equal to the | # This will define a symbol, F_CPU, in all source code files equal to the | ||||
# Atmel DFU loader 4096 | # Atmel DFU loader 4096 | ||||
# LUFA bootloader 4096 | # LUFA bootloader 4096 | ||||
# USBaspLoader 2048 | # USBaspLoader 2048 | ||||
OPT_DEFS += -DBOOTLOADER_SIZE=512 | |||||
OPT_DEFS += -DBOOTLOADER_SIZE=4096 | |||||
# Build Options | # Build Options | ||||
EXTRAKEY_ENABLE = yes # Audio control and System control | EXTRAKEY_ENABLE = yes # Audio control and System control | ||||
CONSOLE_ENABLE = yes # Console for debug | CONSOLE_ENABLE = yes # Console for debug | ||||
COMMAND_ENABLE = yes # Commands for debug and configuration | COMMAND_ENABLE = yes # Commands for debug and configuration | ||||
#NKRO_ENABLE = yes # USB Nkey Rollover | |||||
NKRO_ENABLE = yes # USB Nkey Rollover | |||||
# Search Path | # Search Path |
# MCU name, you MUST set this to match the board you are using | # 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 | # type "make clean" after changing this, so all files will be rebuilt | ||||
#MCU = at90usb162 # Teensy 1.0 | #MCU = at90usb162 # Teensy 1.0 | ||||
#MCU = atmega32u4 # Teensy 2.0 | |||||
MCU = atmega32u4 # Teensy 2.0 | |||||
#MCU = at90usb646 # Teensy++ 1.0 | #MCU = at90usb646 # Teensy++ 1.0 | ||||
MCU = at90usb1286 # Teensy++ 2.0 | |||||
#MCU = at90usb1286 # Teensy++ 2.0 | |||||
# Processor frequency. | # Processor frequency. |
#---------------------------------------------------------------------------- | |||||
# 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 |
#define VENDOR_ID 0xFEED | #define VENDOR_ID 0xFEED | ||||
#define PRODUCT_ID 0xCAFE | #define PRODUCT_ID 0xCAFE | ||||
#define DEVICE_VER 0x0103 | |||||
#define DEVICE_VER 0x0104 | |||||
#define MANUFACTURER t.m.k. | #define MANUFACTURER t.m.k. | ||||
#define PRODUCT HHKB mod | #define PRODUCT HHKB mod | ||||
#define DESCRIPTION t.m.k. keyboard firmware for HHKB mod | #define DESCRIPTION t.m.k. keyboard firmware for HHKB mod |
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; |
/* | /* | ||||
* 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, |
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(); |
#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; |