e5f9940 Merge commit '1bc3dd200b023cecf063a0cb3ba347f77f6d759d' into core_update da03c50 Add note for L/R side bit being ignored e80f3c1 Add in basic documentation for Macro system 35e8a76 core: Swap position of PEQL and PENT in unimap 00751f1 Merge pull request #406 from 39aldo39/patch-1 e50d7de V-USB remote wakeup 4340997 core: Fix typo in definition AC_g 958144d core: Debug print for system and consumer keys e7e1030 core: Fix sleep_led 0866323 core: Change matrix_init and matrix_print 0dbf73d core: Add matrix_clear() and default impl. 3202ca3 core: Add suspend mode options 4cda3aa core: Fix suspend/wake for converters #386 4e15247 core: LUFA_DEBUG_SUART for serial debug b9cf8e7 core: Fix mechanical locking supoort #390 12aa0fd Merge branch 'nemith-master' fccb3fa core: Fix OPT_DEFS for mbed build 2e2d2c8 Merge branch 'master' of github.com:leizzer/tmk_keyboard f1d3634 Change .gitignore for ChibiOS 3aab802 core: Fix build config in protocol.mk 5e43da0 core: Add short names in unimap 7a56998 core: Fix dfu wait in rules.mk 6d9c500 Merge branch 'mediakey-fix' 08382ac core: Fix 'make dfu' message 78cb04e Fix OS X Recognizing keyboard as Mouse/Tablet a114714 core: 'make dfu' waits for bootloader to start d0a8f13 core: Fix unimap UNIMAP_NO case e17abef core: Change lufa NKRO report size 16 to 32 bytes 375b20f core: Fix common.mk for build options 394fdff core: Fix unimap layout comment 912326c core: Add unimap support 00f4011 core: Fix doc/keymap.md for new keymap framework ddbd7b4 core: Add default implemenation of keymap read 671cacc core: action codes are action_t struct now b4fdb27 core: Change chibios repo directory names 7daed10 core: Fix keycode.txt 90399d7 core: Fix USB remote wakeup on ATmega32U2 #361 3677e84 usb_usb: Add multiple keyboard support 54d5b26 core: Fix Logical Maximum in report descriptor bd0d372 core: Fix LUFA report descriptor 95327b5 Merge pull request #355 from papodaca/XT 62bf548 core: change API of adb.c to accept device address 3097c9e Fix function name in host.h 836e209 Merge branch 'core_split_160522' 3918ea2 Merge commit '20b787fc1284176834cbe7ca2134e4b36bec5828' 7f87b11 core: Add comment of register 3 of ADB ef6478a core: Add adb_host_talk() 5c665b4 update macro names in bluefruit 4f2c5bf Merge commit '71381457fa1311dfa0b58ba882a96db740640871' 53a9c08 Merge pull request #321 from njbair/master f08a656 core: Fix media/consumer keys d526de8 Clean up wording in keymap example 0bb3dbb Clarify layer precedence d915c75 clarify layer documentation 72070d4 ps2_usb: Fix for VUSB configuration 170e2dc Mostly working. Is unstable, will emit bad codes after a while. c8e45b5 core: Actionmap support aabaa24 Codes appear to be detected correctly, the break codes are broken. git-subtree-dir: tmk_core git-subtree-split: e5f994033cbc8700745ac0c6d12772820492eed0
271 lines
10 KiB
C++
271 lines
10 KiB
C++
#include <stdint.h>
|
|
#include "USBHID.h"
|
|
#include "USBHID_Types.h"
|
|
#include "USBDescriptor.h"
|
|
#include "HIDKeyboard.h"
|
|
|
|
#define DEFAULT_CONFIGURATION (1)
|
|
|
|
|
|
HIDKeyboard::HIDKeyboard(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release)
|
|
{
|
|
USBDevice::connect();
|
|
}
|
|
|
|
bool HIDKeyboard::sendReport(report_keyboard_t report) {
|
|
USBDevice::write(EP1IN, report.raw, sizeof(report), MAX_PACKET_SIZE_EP1);
|
|
return true;
|
|
}
|
|
|
|
uint8_t HIDKeyboard::leds() {
|
|
return led_state;
|
|
}
|
|
|
|
bool HIDKeyboard::USBCallback_setConfiguration(uint8_t configuration) {
|
|
if (configuration != DEFAULT_CONFIGURATION) {
|
|
return false;
|
|
}
|
|
|
|
// Configure endpoints > 0
|
|
addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
|
|
//addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
|
|
|
|
// We activate the endpoint to be able to recceive data
|
|
//readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
|
|
return true;
|
|
}
|
|
|
|
|
|
uint8_t * HIDKeyboard::stringImanufacturerDesc() {
|
|
static uint8_t stringImanufacturerDescriptor[] = {
|
|
0x18, /*bLength*/
|
|
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
|
|
't',0,'m',0,'k',0,'-',0,'k',0,'b',0,'d',0,'.',0,'c',0,'o',0,'m',0 /*bString iManufacturer*/
|
|
};
|
|
return stringImanufacturerDescriptor;
|
|
}
|
|
|
|
uint8_t * HIDKeyboard::stringIproductDesc() {
|
|
static uint8_t stringIproductDescriptor[] = {
|
|
0x0a, /*bLength*/
|
|
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
|
|
'm',0,'b',0,'e',0,'d',0 /*bString iProduct*/
|
|
};
|
|
return stringIproductDescriptor;
|
|
}
|
|
|
|
uint8_t * HIDKeyboard::stringIserialDesc() {
|
|
static uint8_t stringIserialDescriptor[] = {
|
|
0x04, /*bLength*/
|
|
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
|
|
'0',0 /*bString iSerial*/
|
|
};
|
|
return stringIserialDescriptor;
|
|
}
|
|
|
|
uint8_t * HIDKeyboard::reportDesc() {
|
|
static uint8_t reportDescriptor[] = {
|
|
USAGE_PAGE(1), 0x01, // Generic Desktop
|
|
USAGE(1), 0x06, // Keyboard
|
|
COLLECTION(1), 0x01, // Application
|
|
|
|
USAGE_PAGE(1), 0x07, // Key Codes
|
|
USAGE_MINIMUM(1), 0xE0,
|
|
USAGE_MAXIMUM(1), 0xE7,
|
|
LOGICAL_MINIMUM(1), 0x00,
|
|
LOGICAL_MAXIMUM(1), 0x01,
|
|
REPORT_SIZE(1), 0x01,
|
|
REPORT_COUNT(1), 0x08,
|
|
INPUT(1), 0x02, // Data, Variable, Absolute
|
|
|
|
REPORT_COUNT(1), 0x01,
|
|
REPORT_SIZE(1), 0x08,
|
|
INPUT(1), 0x01, // Constant
|
|
|
|
REPORT_COUNT(1), 0x05,
|
|
REPORT_SIZE(1), 0x01,
|
|
USAGE_PAGE(1), 0x08, // LEDs
|
|
USAGE_MINIMUM(1), 0x01,
|
|
USAGE_MAXIMUM(1), 0x05,
|
|
OUTPUT(1), 0x02, // Data, Variable, Absolute
|
|
|
|
REPORT_COUNT(1), 0x01,
|
|
REPORT_SIZE(1), 0x03,
|
|
OUTPUT(1), 0x01, // Constant
|
|
|
|
|
|
REPORT_COUNT(1), 0x06,
|
|
REPORT_SIZE(1), 0x08,
|
|
LOGICAL_MINIMUM(1), 0x00,
|
|
LOGICAL_MAXIMUM(2), 0xFF, 0x00,
|
|
USAGE_PAGE(1), 0x07, // Key Codes
|
|
USAGE_MINIMUM(1), 0x00,
|
|
USAGE_MAXIMUM(1), 0xFF,
|
|
INPUT(1), 0x00, // Data, Array
|
|
END_COLLECTION(0),
|
|
};
|
|
reportLength = sizeof(reportDescriptor);
|
|
return reportDescriptor;
|
|
}
|
|
|
|
uint16_t HIDKeyboard::reportDescLength() {
|
|
reportDesc();
|
|
return reportLength;
|
|
}
|
|
|
|
#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
|
|
+ (1 * INTERFACE_DESCRIPTOR_LENGTH) \
|
|
+ (1 * HID_DESCRIPTOR_LENGTH) \
|
|
+ (1 * ENDPOINT_DESCRIPTOR_LENGTH))
|
|
uint8_t * HIDKeyboard::configurationDesc() {
|
|
static uint8_t configurationDescriptor[] = {
|
|
CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
|
|
CONFIGURATION_DESCRIPTOR, // bDescriptorType
|
|
LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
|
|
MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
|
|
0x01, // bNumInterfaces
|
|
DEFAULT_CONFIGURATION, // bConfigurationValue
|
|
0x00, // iConfiguration
|
|
C_RESERVED | C_REMOTE_WAKEUP, // bmAttributes
|
|
C_POWER(100), // bMaxPowerHello World from Mbed
|
|
|
|
INTERFACE_DESCRIPTOR_LENGTH, // bLength
|
|
INTERFACE_DESCRIPTOR, // bDescriptorType
|
|
0x00, // bInterfaceNumber
|
|
0x00, // bAlternateSetting
|
|
0x01, // bNumEndpoints
|
|
HID_CLASS, // bInterfaceClass
|
|
1, // bInterfaceSubClass (boot)
|
|
1, // bInterfaceProtocol (keyboard)
|
|
0x00, // iInterface
|
|
|
|
HID_DESCRIPTOR_LENGTH, // bLength
|
|
HID_DESCRIPTOR, // bDescriptorType
|
|
LSB(HID_VERSION_1_11), // bcdHID (LSB)
|
|
MSB(HID_VERSION_1_11), // bcdHID (MSB)
|
|
0x00, // bCountryCode
|
|
0x01, // bNumDescriptors
|
|
REPORT_DESCRIPTOR, // bDescriptorType
|
|
(uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
|
|
(uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB)
|
|
|
|
ENDPOINT_DESCRIPTOR_LENGTH, // bLength
|
|
ENDPOINT_DESCRIPTOR, // bDescriptorType
|
|
PHY_TO_DESC(EP1IN), // bEndpointAddress
|
|
E_INTERRUPT, // bmAttributes
|
|
LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
|
|
MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
|
|
1, // bInterval (milliseconds)
|
|
};
|
|
return configurationDescriptor;
|
|
}
|
|
|
|
#if 0
|
|
uint8_t * HIDKeyboard::deviceDesc() {
|
|
static uint8_t deviceDescriptor[] = {
|
|
DEVICE_DESCRIPTOR_LENGTH, /* bLength */
|
|
DEVICE_DESCRIPTOR, /* bDescriptorType */
|
|
LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */
|
|
MSB(USB_VERSION_2_0), /* bcdUSB (MSB) */
|
|
0x00, /* bDeviceClass */
|
|
0x00, /* bDeviceSubClass */
|
|
0x00, /* bDeviceprotocol */
|
|
MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */
|
|
(uint8_t)(LSB(0xfeed)), /* idVendor (LSB) */
|
|
(uint8_t)(MSB(0xfeed)), /* idVendor (MSB) */
|
|
(uint8_t)(LSB(0x1bed)), /* idProduct (LSB) */
|
|
(uint8_t)(MSB(0x1bed)), /* idProduct (MSB) */
|
|
(uint8_t)(LSB(0x0002)), /* bcdDevice (LSB) */
|
|
(uint8_t)(MSB(0x0002)), /* bcdDevice (MSB) */
|
|
0, /* iManufacturer */
|
|
0, /* iProduct */
|
|
0, /* iSerialNumber */
|
|
0x01 /* bNumConfigurations */
|
|
};
|
|
return deviceDescriptor;
|
|
}
|
|
#endif
|
|
|
|
bool HIDKeyboard::USBCallback_request() {
|
|
bool success = false;
|
|
CONTROL_TRANSFER * transfer = getTransferPtr();
|
|
uint8_t *hidDescriptor;
|
|
|
|
// Process additional standard requests
|
|
|
|
if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
|
|
{
|
|
switch (transfer->setup.bRequest)
|
|
{
|
|
case GET_DESCRIPTOR:
|
|
switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
|
|
{
|
|
case REPORT_DESCRIPTOR:
|
|
if ((reportDesc() != NULL) \
|
|
&& (reportDescLength() != 0))
|
|
{
|
|
transfer->remaining = reportDescLength();
|
|
transfer->ptr = reportDesc();
|
|
transfer->direction = DEVICE_TO_HOST;
|
|
success = true;
|
|
}
|
|
break;
|
|
case HID_DESCRIPTOR:
|
|
// Find the HID descriptor, after the configuration descriptor
|
|
hidDescriptor = findDescriptor(HID_DESCRIPTOR);
|
|
if (hidDescriptor != NULL)
|
|
{
|
|
transfer->remaining = HID_DESCRIPTOR_LENGTH;
|
|
transfer->ptr = hidDescriptor;
|
|
transfer->direction = DEVICE_TO_HOST;
|
|
success = true;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Process class-specific requests
|
|
if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
|
|
{
|
|
switch (transfer->setup.bRequest) {
|
|
case SET_REPORT:
|
|
// LED indicator
|
|
// TODO: check Interface and Report length?
|
|
// if (transfer->setup.wIndex == INTERFACE_KEYBOAD) { }
|
|
// if (transfer->setup.wLength == 1)
|
|
|
|
transfer->remaining = 1;
|
|
//transfer->ptr = ?? what ptr should be set when OUT(not used?)
|
|
transfer->direction = HOST_TO_DEVICE;
|
|
transfer->notify = true; /* notify with USBCallback_requestCompleted */
|
|
success = true;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
void HIDKeyboard::USBCallback_requestCompleted(uint8_t * buf, uint32_t length)
|
|
{
|
|
if (length > 0) {
|
|
CONTROL_TRANSFER *transfer = getTransferPtr();
|
|
if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
|
|
switch (transfer->setup.bRequest) {
|
|
case SET_REPORT:
|
|
led_state = buf[0];
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|