#include <stdint.h>
#include <avr/wdt.h>
#include <usbdrv/usbdrv.h>
#include "usbconfig.h"
#include "host.h"
#include "report.h"
#include "host_driver.h"
#include "vusb.h"
#include "print.h"
#include "debug.h"
#include "wait.h"
#include "usb_descriptor_common.h"
#ifdef RAW_ENABLE
# include "raw_hid.h"
#endif
#if defined(CONSOLE_ENABLE)
# define RBUF_SIZE 128
# include "ring_buffer.h"
#endif
#define NEXT_INTERFACE __COUNTER__
enum usb_interfaces {
#ifndef KEYBOARD_SHARED_EP
KEYBOARD_INTERFACE = NEXT_INTERFACE,
#else
SHARED_INTERFACE = NEXT_INTERFACE,
# define KEYBOARD_INTERFACE SHARED_INTERFACE
#endif
#ifdef RAW_ENABLE
RAW_INTERFACE = NEXT_INTERFACE,
#endif
#if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP)
SHARED_INTERFACE = NEXT_INTERFACE,
#endif
#ifdef CONSOLE_ENABLE
CONSOLE_INTERFACE = NEXT_INTERFACE,
#endif
TOTAL_INTERFACES = NEXT_INTERFACE
};
#define MAX_INTERFACES 3
#if (NEXT_INTERFACE - 1) > MAX_INTERFACES
# error There are not enough available interfaces to support all functions. Please disable one or more of the following: Mouse Keys, Extra Keys, Raw HID, Console
#endif
#if (defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)) && CONSOLE_ENABLE
# error Mouse/Extra Keys share an endpoint with Console. Please disable one of the two.
#endif
static uint8_t keyboard_led_state = 0;
static uint8_t vusb_idle_rate = 0;
#define KBUF_SIZE 16
static report_keyboard_t kbuf[KBUF_SIZE];
static uint8_t kbuf_head = 0;
static uint8_t kbuf_tail = 0;
static report_keyboard_t keyboard_report_sent;
#define VUSB_TRANSFER_KEYBOARD_MAX_TRIES 10
void vusb_transfer_keyboard(void) {
for (int i = 0; i < VUSB_TRANSFER_KEYBOARD_MAX_TRIES; i++) {
if (usbInterruptIsReady()) {
if (kbuf_head != kbuf_tail) {
#ifndef KEYBOARD_SHARED_EP
usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t));
#else
usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t) - 1);
while (!usbInterruptIsReady()) {
usbPoll();
}
usbSetInterrupt((void *)(&(kbuf[kbuf_tail].keys[5])), 1);
#endif
kbuf_tail = (kbuf_tail + 1) % KBUF_SIZE;
if (debug_keyboard) {
dprintf("V-USB: kbuf[%d->%d](%02X)\n", kbuf_tail, kbuf_head, (kbuf_head < kbuf_tail) ? (KBUF_SIZE - kbuf_tail + kbuf_head) : (kbuf_head - kbuf_tail));
}
}
break;
}
usbPoll();
wait_ms(1);
}
}
#ifdef RAW_ENABLE
# define RAW_BUFFER_SIZE 32
# define RAW_EPSIZE 8
static uint8_t raw_output_buffer[RAW_BUFFER_SIZE];
static uint8_t raw_output_received_bytes = 0;
void raw_hid_send(uint8_t *data, uint8_t length) {
if (length != RAW_BUFFER_SIZE) {
return;
}
uint8_t *temp = data;
for (uint8_t i = 0; i < 4; i++) {
while (!usbInterruptIsReady4()) {
usbPoll();
}
usbSetInterrupt4(temp, 8);
temp += 8;
}
while (!usbInterruptIsReady4()) {
usbPoll();
}
usbSetInterrupt4(0, 0);
}
__attribute__((weak)) void raw_hid_receive(uint8_t *data, uint8_t length) {
}
void raw_hid_task(void) {
if (raw_output_received_bytes == RAW_BUFFER_SIZE) {
raw_hid_receive(raw_output_buffer, RAW_BUFFER_SIZE);
raw_output_received_bytes = 0;
}
}
#endif
#ifdef CONSOLE_ENABLE
# define CONSOLE_BUFFER_SIZE 32
# define CONSOLE_EPSIZE 8
int8_t sendchar(uint8_t c) {
rbuf_enqueue(c);
return 0;
}
static inline bool usbSendData3(char *data, uint8_t len) {
uint8_t retries = 5;
while (!usbInterruptIsReady3()) {
if (!(retries--)) {
return false;
}
usbPoll();
}
usbSetInterrupt3((unsigned char *)data, len);
return true;
}
void console_task(void) {
if (!usbConfiguration) {
return;
}
if (!rbuf_has_data()) {
return;
}
char send_buf[CONSOLE_BUFFER_SIZE] = {0};
uint8_t send_buf_count = 0;
while (rbuf_has_data() && send_buf_count < CONSOLE_EPSIZE) {
send_buf[send_buf_count++] = rbuf_dequeue();
}
char *temp = send_buf;
for (uint8_t i = 0; i < 4; i++) {
if (!usbSendData3(temp, 8)) {
break;
}
temp += 8;
}
usbSendData3(0, 0);
usbPoll();
}
#endif
static uint8_t keyboard_leds(void);
static void send_keyboard(report_keyboard_t *report);
static void send_mouse(report_mouse_t *report);
static void send_system(uint16_t data);
static void send_consumer(uint16_t data);
static host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
host_driver_t *vusb_driver(void) { return &driver; }
static uint8_t keyboard_leds(void) { return keyboard_led_state; }
static void send_keyboard(report_keyboard_t *report) {
uint8_t next = (kbuf_head + 1) % KBUF_SIZE;
if (next != kbuf_tail) {
kbuf[kbuf_head] = *report;
kbuf_head = next;
} else {
dprint("kbuf: full\n");
}
usbPoll();
vusb_transfer_keyboard();
keyboard_report_sent = *report;
}
#ifndef KEYBOARD_SHARED_EP
# define usbInterruptIsReadyShared usbInterruptIsReady3
# define usbSetInterruptShared usbSetInterrupt3
#else
# define usbInterruptIsReadyShared usbInterruptIsReady
# define usbSetInterruptShared usbSetInterrupt
#endif
static void send_mouse(report_mouse_t *report) {
#ifdef MOUSE_ENABLE
if (usbInterruptIsReadyShared()) {
usbSetInterruptShared((void *)report, sizeof(report_mouse_t));
}
#endif
}
#ifdef EXTRAKEY_ENABLE
static void send_extra(uint8_t report_id, uint16_t data) {
static uint8_t last_id = 0;
static uint16_t last_data = 0;
if ((report_id == last_id) && (data == last_data)) return;
last_id = report_id;
last_data = data;
report_extra_t report = {.report_id = report_id, .usage = data};
if (usbInterruptIsReadyShared()) {
usbSetInterruptShared((void *)&report, sizeof(report_extra_t));
}
}
#endif
static void send_system(uint16_t data) {
#ifdef EXTRAKEY_ENABLE
send_extra(REPORT_ID_SYSTEM, data);
#endif
}
static void send_consumer(uint16_t data) {
#ifdef EXTRAKEY_ENABLE
send_extra(REPORT_ID_CONSUMER, data);
#endif
}
static struct {
uint16_t len;
enum { NONE, SET_LED } kind;
} last_req;
usbMsgLen_t usbFunctionSetup(uchar data[8]) {
usbRequest_t *rq = (void *)data;
if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {
if (rq->bRequest == USBRQ_HID_GET_REPORT) {
dprint("GET_REPORT:");
if (rq->wIndex.word == KEYBOARD_INTERFACE) {
usbMsgPtr = (usbMsgPtr_t)&keyboard_report_sent;
return sizeof(keyboard_report_sent);
}
} else if (rq->bRequest == USBRQ_HID_GET_IDLE) {
dprint("GET_IDLE:");
usbMsgPtr = (usbMsgPtr_t)&vusb_idle_rate;
return 1;
} else if (rq->bRequest == USBRQ_HID_SET_IDLE) {
vusb_idle_rate = rq->wValue.bytes[1];
dprintf("SET_IDLE: %02X", vusb_idle_rate);
} else if (rq->bRequest == USBRQ_HID_SET_REPORT) {
dprint("SET_REPORT:");
if (rq->wValue.word == 0x0200 && rq->wIndex.word == KEYBOARD_INTERFACE) {
dprint("SET_LED:");
last_req.kind = SET_LED;
last_req.len = rq->wLength.word;
}
return USB_NO_MSG; } else {
dprint("UNKNOWN:");
}
} else {
dprint("VENDOR:");
}
dprint("\n");
return 0;
}
uchar usbFunctionWrite(uchar *data, uchar len) {
if (last_req.len == 0) {
return -1;
}
switch (last_req.kind) {
case SET_LED:
dprintf("SET_LED: %02X\n", data[0]);
keyboard_led_state = data[0];
last_req.len = 0;
return 1;
break;
case NONE:
default:
return -1;
break;
}
return 1;
}
void usbFunctionWriteOut(uchar *data, uchar len) {
#ifdef RAW_ENABLE
if (len != 8) {
dprint("RAW: invalid length\n");
raw_output_received_bytes = 0;
return;
}
if (raw_output_received_bytes + len > RAW_BUFFER_SIZE) {
dprint("RAW: buffer full\n");
raw_output_received_bytes = 0;
} else {
for (uint8_t i = 0; i < 8; i++) {
raw_output_buffer[raw_output_received_bytes + i] = data[i];
}
raw_output_received_bytes += len;
}
#endif
}
#ifdef KEYBOARD_SHARED_EP
const PROGMEM uchar shared_hid_report[] = {
# define SHARED_REPORT_STARTED
#else
const PROGMEM uchar keyboard_hid_report[] = {
#endif
0x05, 0x01, 0x09, 0x06, 0xA1, 0x01, #ifdef KEYBOARD_SHARED_EP
0x85, REPORT_ID_KEYBOARD, #endif
0x05, 0x07, 0x19, 0xE0, 0x29, 0xE7, 0x15, 0x00, 0x25, 0x01, 0x95, 0x08, 0x75, 0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x08, 0x81, 0x03, 0x05, 0x07, 0x19, 0x00, 0x29, 0xFF, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x95, 0x06, 0x75, 0x08, 0x81, 0x00,
0x05, 0x08, 0x19, 0x01, 0x29, 0x05, 0x95, 0x05, 0x75, 0x01, 0x91, 0x02, 0x95, 0x01, 0x75, 0x03, 0x91, 0x03, 0xC0, #ifndef KEYBOARD_SHARED_EP
};
#endif
#if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
const PROGMEM uchar shared_hid_report[] = {
# define SHARED_REPORT_STARTED
#endif
#ifdef MOUSE_ENABLE
0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x85, REPORT_ID_MOUSE, 0x09, 0x01, 0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x08, 0x15, 0x00, 0x25, 0x01, 0x95, 0x08, 0x75, 0x01, 0x81, 0x02,
0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81, 0x25, 0x7F, 0x95, 0x02, 0x75, 0x08, 0x81, 0x06,
0x09, 0x38, 0x15, 0x81, 0x25, 0x7F, 0x95, 0x01, 0x75, 0x08, 0x81, 0x06, 0x05, 0x0C, 0x0A, 0x38, 0x02, 0x15, 0x81, 0x25, 0x7F, 0x95, 0x01, 0x75, 0x08, 0x81, 0x06, 0xC0, 0xC0, #endif
#ifdef EXTRAKEY_ENABLE
0x05, 0x01, 0x09, 0x80, 0xA1, 0x01, 0x85, REPORT_ID_SYSTEM, 0x19, 0x01, 0x2A, 0xB7, 0x00, 0x15, 0x01, 0x26, 0xB7, 0x00, 0x95, 0x01, 0x75, 0x10, 0x81, 0x00, 0xC0,
0x05, 0x0C, 0x09, 0x01, 0xA1, 0x01, 0x85, REPORT_ID_CONSUMER, 0x19, 0x01, 0x2A, 0xA0, 0x02, 0x15, 0x01, 0x26, 0xA0, 0x02, 0x95, 0x01, 0x75, 0x10, 0x81, 0x00, 0xC0 #endif
#ifdef SHARED_EP_ENABLE
};
#endif
#ifdef RAW_ENABLE
const PROGMEM uchar raw_hid_report[] = {
0x06, RAW_USAGE_PAGE_LO, RAW_USAGE_PAGE_HI, 0x09, RAW_USAGE_ID, 0xA1, 0x01, 0x09, 0x62, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x95, RAW_BUFFER_SIZE, 0x75, 0x08, 0x81, 0x02, 0x09, 0x63, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x95, RAW_BUFFER_SIZE, 0x75, 0x08, 0x91, 0x02, 0xC0 };
#endif
#if defined(CONSOLE_ENABLE)
const PROGMEM uchar console_hid_report[] = {
0x06, 0x31, 0xFF, 0x09, 0x74, 0xA1, 0x01, 0x09, 0x75, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x95, CONSOLE_BUFFER_SIZE, 0x75, 0x08, 0x81, 0x02, 0x09, 0x76, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x95, CONSOLE_BUFFER_SIZE, 0x75, 0x08, 0x91, 0x02, 0xC0 };
#endif
#ifndef USB_MAX_POWER_CONSUMPTION
# define USB_MAX_POWER_CONSUMPTION 500
#endif
#ifndef USB_POLLING_INTERVAL_MS
# define USB_POLLING_INTERVAL_MS 1
#endif
const PROGMEM usbStringDescriptor_t usbStringDescriptorZero = {
.header = {
.bLength = USB_STRING_LEN(1),
.bDescriptorType = USBDESCR_STRING
},
.bString = {0x0409} };
const PROGMEM usbStringDescriptor_t usbStringDescriptorManufacturer = {
.header = {
.bLength = USB_STRING_LEN(sizeof(STR(MANUFACTURER)) - 1),
.bDescriptorType = USBDESCR_STRING
},
.bString = LSTR(MANUFACTURER)
};
const PROGMEM usbStringDescriptor_t usbStringDescriptorProduct = {
.header = {
.bLength = USB_STRING_LEN(sizeof(STR(PRODUCT)) - 1),
.bDescriptorType = USBDESCR_STRING
},
.bString = LSTR(PRODUCT)
};
#if defined(SERIAL_NUMBER)
const PROGMEM usbStringDescriptor_t usbStringDescriptorSerial = {
.header = {
.bLength = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER)) - 1),
.bDescriptorType = USBDESCR_STRING
},
.bString = LSTR(SERIAL_NUMBER)
};
#endif
const PROGMEM usbDeviceDescriptor_t usbDeviceDescriptor = {
.header = {
.bLength = sizeof(usbDeviceDescriptor_t),
.bDescriptorType = USBDESCR_DEVICE
},
.bcdUSB = 0x0110,
.bDeviceClass = 0x00,
.bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x00,
.bMaxPacketSize0 = 8,
.idVendor = VENDOR_ID,
.idProduct = PRODUCT_ID,
.bcdDevice = DEVICE_VER,
.iManufacturer = 0x01,
.iProduct = 0x02,
#if defined(SERIAL_NUMBER)
.iSerialNumber = 0x03,
#else
.iSerialNumber = 0x00,
#endif
.bNumConfigurations = 1
};
const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
.header = {
.header = {
.bLength = sizeof(usbConfigurationDescriptorHeader_t),
.bDescriptorType = USBDESCR_CONFIG
},
.wTotalLength = sizeof(usbConfigurationDescriptor_t),
.bNumInterfaces = TOTAL_INTERFACES,
.bConfigurationValue = 0x01,
.iConfiguration = 0x00,
.bmAttributes = (1 << 7) | USBATTR_REMOTEWAKE,
.bMaxPower = USB_MAX_POWER_CONSUMPTION / 2
},
# ifndef KEYBOARD_SHARED_EP
.keyboardInterface = {
.header = {
.bLength = sizeof(usbInterfaceDescriptor_t),
.bDescriptorType = USBDESCR_INTERFACE
},
.bInterfaceNumber = KEYBOARD_INTERFACE,
.bAlternateSetting = 0x00,
.bNumEndpoints = 1,
.bInterfaceClass = 0x03,
.bInterfaceSubClass = 0x01,
.bInterfaceProtocol = 0x01,
.iInterface = 0x00
},
.keyboardHID = {
.header = {
.bLength = sizeof(usbHIDDescriptor_t),
.bDescriptorType = USBDESCR_HID
},
.bcdHID = 0x0101,
.bCountryCode = 0x00,
.bNumDescriptors = 1,
.bDescriptorType = USBDESCR_HID_REPORT,
.wDescriptorLength = sizeof(keyboard_hid_report)
},
.keyboardINEndpoint = {
.header = {
.bLength = sizeof(usbEndpointDescriptor_t),
.bDescriptorType = USBDESCR_ENDPOINT
},
.bEndpointAddress = (USBRQ_DIR_DEVICE_TO_HOST | 1),
.bmAttributes = 0x03,
.wMaxPacketSize = 8,
.bInterval = USB_POLLING_INTERVAL_MS
},
# endif
# if defined(RAW_ENABLE)
.rawInterface = {
.header = {
.bLength = sizeof(usbInterfaceDescriptor_t),
.bDescriptorType = USBDESCR_INTERFACE
},
.bInterfaceNumber = RAW_INTERFACE,
.bAlternateSetting = 0x00,
.bNumEndpoints = 2,
.bInterfaceClass = 0x03,
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
.iInterface = 0x00
},
.rawHID = {
.header = {
.bLength = sizeof(usbHIDDescriptor_t),
.bDescriptorType = USBDESCR_HID
},
.bcdHID = 0x0101,
.bCountryCode = 0x00,
.bNumDescriptors = 1,
.bDescriptorType = USBDESCR_HID_REPORT,
.wDescriptorLength = sizeof(raw_hid_report)
},
.rawINEndpoint = {
.header = {
.bLength = sizeof(usbEndpointDescriptor_t),
.bDescriptorType = USBDESCR_ENDPOINT
},
.bEndpointAddress = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP4_NUMBER),
.bmAttributes = 0x03,
.wMaxPacketSize = RAW_EPSIZE,
.bInterval = USB_POLLING_INTERVAL_MS
},
.rawOUTEndpoint = {
.header = {
.bLength = sizeof(usbEndpointDescriptor_t),
.bDescriptorType = USBDESCR_ENDPOINT
},
.bEndpointAddress = (USBRQ_DIR_HOST_TO_DEVICE | USB_CFG_EP4_NUMBER),
.bmAttributes = 0x03,
.wMaxPacketSize = RAW_EPSIZE,
.bInterval = USB_POLLING_INTERVAL_MS
},
# endif
# ifdef SHARED_EP_ENABLE
.sharedInterface = {
.header = {
.bLength = sizeof(usbInterfaceDescriptor_t),
.bDescriptorType = USBDESCR_INTERFACE
},
.bInterfaceNumber = SHARED_INTERFACE,
.bAlternateSetting = 0x00,
.bNumEndpoints = 1,
.bInterfaceClass = 0x03,
# ifdef KEYBOARD_SHARED_EP
.bInterfaceSubClass = 0x01,
.bInterfaceProtocol = 0x01,
# else
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
# endif
.iInterface = 0x00
},
.sharedHID = {
.header = {
.bLength = sizeof(usbHIDDescriptor_t),
.bDescriptorType = USBDESCR_HID
},
.bcdHID = 0x0101,
.bCountryCode = 0x00,
.bNumDescriptors = 1,
.bDescriptorType = USBDESCR_HID_REPORT,
.wDescriptorLength = sizeof(shared_hid_report)
},
.sharedINEndpoint = {
.header = {
.bLength = sizeof(usbEndpointDescriptor_t),
.bDescriptorType = USBDESCR_ENDPOINT
},
# ifdef KEYBOARD_SHARED_EP
.bEndpointAddress = (USBRQ_DIR_DEVICE_TO_HOST | 1),
# else
.bEndpointAddress = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP3_NUMBER),
# endif
.bmAttributes = 0x03,
.wMaxPacketSize = 8,
.bInterval = USB_POLLING_INTERVAL_MS
},
# endif
# if defined(CONSOLE_ENABLE)
.consoleInterface = {
.header = {
.bLength = sizeof(usbInterfaceDescriptor_t),
.bDescriptorType = USBDESCR_INTERFACE
},
.bInterfaceNumber = CONSOLE_INTERFACE,
.bAlternateSetting = 0x00,
.bNumEndpoints = 2,
.bInterfaceClass = 0x03,
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
.iInterface = 0x00
},
.consoleHID = {
.header = {
.bLength = sizeof(usbHIDDescriptor_t),
.bDescriptorType = USBDESCR_HID
},
.bcdHID = 0x0111,
.bCountryCode = 0x00,
.bNumDescriptors = 1,
.bDescriptorType = USBDESCR_HID_REPORT,
.wDescriptorLength = sizeof(console_hid_report)
},
.consoleINEndpoint = {
.header = {
.bLength = sizeof(usbEndpointDescriptor_t),
.bDescriptorType = USBDESCR_ENDPOINT
},
.bEndpointAddress = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP3_NUMBER),
.bmAttributes = 0x03,
.wMaxPacketSize = CONSOLE_EPSIZE,
.bInterval = 0x01
},
.consoleOUTEndpoint = {
.header = {
.bLength = sizeof(usbEndpointDescriptor_t),
.bDescriptorType = USBDESCR_ENDPOINT
},
.bEndpointAddress = (USBRQ_DIR_HOST_TO_DEVICE | USB_CFG_EP3_NUMBER),
.bmAttributes = 0x03,
.wMaxPacketSize = CONSOLE_EPSIZE,
.bInterval = 0x01
}
# endif
};
USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) {
usbMsgLen_t len = 0;
switch (rq->wValue.bytes[1]) {
case USBDESCR_DEVICE:
usbMsgPtr = (usbMsgPtr_t)&usbDeviceDescriptor;
len = sizeof(usbDeviceDescriptor_t);
break;
case USBDESCR_CONFIG:
usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor;
len = sizeof(usbConfigurationDescriptor_t);
break;
case USBDESCR_STRING:
switch (rq->wValue.bytes[0]) {
case 0:
usbMsgPtr = (usbMsgPtr_t)&usbStringDescriptorZero;
len = usbStringDescriptorZero.header.bLength;
break;
case 1: usbMsgPtr = (usbMsgPtr_t)&usbStringDescriptorManufacturer;
len = usbStringDescriptorManufacturer.header.bLength;
break;
case 2: usbMsgPtr = (usbMsgPtr_t)&usbStringDescriptorProduct;
len = usbStringDescriptorProduct.header.bLength;
break;
#if defined(SERIAL_NUMBER)
case 3: usbMsgPtr = (usbMsgPtr_t)&usbStringDescriptorSerial;
len = usbStringDescriptorSerial.header.bLength;
break;
#endif
}
break;
case USBDESCR_HID:
switch (rq->wValue.bytes[0]) {
#ifndef KEYBOARD_SHARED_EP
case KEYBOARD_INTERFACE:
usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.keyboardHID;
len = sizeof(usbHIDDescriptor_t);
break;
#endif
#if defined(RAW_ENABLE)
case RAW_INTERFACE:
usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.rawHID;
len = sizeof(usbHIDDescriptor_t);
break;
#endif
#ifdef SHARED_EP_ENABLE
case SHARED_INTERFACE:
usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.sharedHID;
len = sizeof(usbHIDDescriptor_t);
break;
#endif
#if defined(CONSOLE_ENABLE)
case CONSOLE_INTERFACE:
usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.consoleHID;
len = sizeof(usbHIDDescriptor_t);
break;
#endif
}
break;
case USBDESCR_HID_REPORT:
switch (rq->wIndex.word) {
#ifndef KEYBOARD_SHARED_EP
case KEYBOARD_INTERFACE:
usbMsgPtr = (usbMsgPtr_t)keyboard_hid_report;
len = sizeof(keyboard_hid_report);
break;
#endif
#if defined(RAW_ENABLE)
case RAW_INTERFACE:
usbMsgPtr = (usbMsgPtr_t)raw_hid_report;
len = sizeof(raw_hid_report);
break;
#endif
#ifdef SHARED_EP_ENABLE
case SHARED_INTERFACE:
usbMsgPtr = (usbMsgPtr_t)shared_hid_report;
len = sizeof(shared_hid_report);
break;
#endif
#if defined(CONSOLE_ENABLE)
case CONSOLE_INTERFACE:
usbMsgPtr = (usbMsgPtr_t)console_hid_report;
len = sizeof(console_hid_report);
break;
#endif
}
break;
}
return len;
}