Add support for shared EP on V-USB boards (#11103)

This commit is contained in:
Ryan 2021-01-11 19:46:30 +11:00 committed by GitHub
parent 407e5be34d
commit aa0e33eca0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 104 additions and 46 deletions

View File

@ -123,12 +123,6 @@ enum desktop_usages {
#define KEYBOARD_REPORT_KEYS 6 #define KEYBOARD_REPORT_KEYS 6
/* VUSB hardcodes keyboard and mouse+extrakey only */
#if defined(PROTOCOL_VUSB)
# undef KEYBOARD_SHARED_EP
# undef MOUSE_SHARED_EP
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -46,19 +46,28 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* Interface indexes * Interface indexes
*/ */
enum usb_interfaces { enum usb_interfaces {
#ifndef KEYBOARD_SHARED_EP
KEYBOARD_INTERFACE = NEXT_INTERFACE, KEYBOARD_INTERFACE = NEXT_INTERFACE,
#else
SHARED_INTERFACE = NEXT_INTERFACE,
# define KEYBOARD_INTERFACE SHARED_INTERFACE
#endif
// It is important that the Raw HID interface is at a constant // It is important that the Raw HID interface is at a constant
// interface number, to support Linux/OSX platforms and chrome.hid // interface number, to support Linux/OSX platforms and chrome.hid
// If Raw HID is enabled, let it be always 1. // If Raw HID is enabled, let it be always 1.
#ifdef RAW_ENABLE #ifdef RAW_ENABLE
RAW_INTERFACE = NEXT_INTERFACE, RAW_INTERFACE = NEXT_INTERFACE,
#endif #endif
#if (defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE))
MOUSE_EXTRA_INTERFACE = NEXT_INTERFACE, #if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP)
SHARED_INTERFACE = NEXT_INTERFACE,
#endif #endif
#ifdef CONSOLE_ENABLE #ifdef CONSOLE_ENABLE
CONSOLE_INTERFACE = NEXT_INTERFACE, CONSOLE_INTERFACE = NEXT_INTERFACE,
#endif #endif
TOTAL_INTERFACES = NEXT_INTERFACE TOTAL_INTERFACES = NEXT_INTERFACE
}; };
@ -90,7 +99,16 @@ void vusb_transfer_keyboard(void) {
for (int i = 0; i < VUSB_TRANSFER_KEYBOARD_MAX_TRIES; i++) { for (int i = 0; i < VUSB_TRANSFER_KEYBOARD_MAX_TRIES; i++) {
if (usbInterruptIsReady()) { if (usbInterruptIsReady()) {
if (kbuf_head != kbuf_tail) { if (kbuf_head != kbuf_tail) {
#ifndef KEYBOARD_SHARED_EP
usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t)); usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t));
#else
// Ugly hack! :(
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; kbuf_tail = (kbuf_tail + 1) % KBUF_SIZE;
if (debug_keyboard) { 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)); 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));
@ -230,16 +248,18 @@ static void send_keyboard(report_keyboard_t *report) {
keyboard_report_sent = *report; keyboard_report_sent = *report;
} }
typedef struct { #ifndef KEYBOARD_SHARED_EP
uint8_t report_id; # define usbInterruptIsReadyShared usbInterruptIsReady3
report_mouse_t report; # define usbSetInterruptShared usbSetInterrupt3
} __attribute__((packed)) vusb_mouse_report_t; #else
# define usbInterruptIsReadyShared usbInterruptIsReady
# define usbSetInterruptShared usbSetInterrupt
#endif
static void send_mouse(report_mouse_t *report) { static void send_mouse(report_mouse_t *report) {
#ifdef MOUSE_ENABLE #ifdef MOUSE_ENABLE
vusb_mouse_report_t r = {.report_id = REPORT_ID_MOUSE, .report = *report}; if (usbInterruptIsReadyShared()) {
if (usbInterruptIsReady3()) { usbSetInterruptShared((void *)report, sizeof(report_mouse_t));
usbSetInterrupt3((void *)&r, sizeof(vusb_mouse_report_t));
} }
#endif #endif
} }
@ -253,8 +273,8 @@ static void send_extra(uint8_t report_id, uint16_t data) {
last_data = data; last_data = data;
report_extra_t report = {.report_id = report_id, .usage = data}; report_extra_t report = {.report_id = report_id, .usage = data};
if (usbInterruptIsReady3()) { if (usbInterruptIsReadyShared()) {
usbSetInterrupt3((void *)&report, sizeof(report)); usbSetInterruptShared((void *)&report, sizeof(report_extra_t));
} }
} }
#endif #endif
@ -360,10 +380,18 @@ void usbFunctionWriteOut(uchar *data, uchar len) {
* Descriptors * * Descriptors *
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
#ifdef KEYBOARD_SHARED_EP
const PROGMEM uchar shared_hid_report[] = {
# define SHARED_REPORT_STARTED
#else
const PROGMEM uchar keyboard_hid_report[] = { const PROGMEM uchar keyboard_hid_report[] = {
#endif
0x05, 0x01, // Usage Page (Generic Desktop) 0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard) 0x09, 0x06, // Usage (Keyboard)
0xA1, 0x01, // Collection (Application) 0xA1, 0x01, // Collection (Application)
#ifdef KEYBOARD_SHARED_EP
0x85, REPORT_ID_KEYBOARD, // Report ID
#endif
// Modifiers (8 bits) // Modifiers (8 bits)
0x05, 0x07, // Usage Page (Keyboard/Keypad) 0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0xE0, // Usage Minimum (Keyboard Left Control) 0x19, 0xE0, // Usage Minimum (Keyboard Left Control)
@ -398,12 +426,17 @@ const PROGMEM uchar keyboard_hid_report[] = {
0x95, 0x01, // Report Count (1) 0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3) 0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Constant) 0x91, 0x03, // Output (Constant)
0xC0 // End Collection 0xC0, // End Collection
#ifndef KEYBOARD_SHARED_EP
}; };
#endif
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) #if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
const PROGMEM uchar mouse_extra_hid_report[] = { const PROGMEM uchar shared_hid_report[] = {
# ifdef MOUSE_ENABLE # define SHARED_REPORT_STARTED
#endif
#ifdef MOUSE_ENABLE
// Mouse report descriptor // Mouse report descriptor
0x05, 0x01, // Usage Page (Generic Desktop) 0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x02, // Usage (Mouse) 0x09, 0x02, // Usage (Mouse)
@ -452,9 +485,9 @@ const PROGMEM uchar mouse_extra_hid_report[] = {
0x81, 0x06, // Input (Data, Variable, Relative) 0x81, 0x06, // Input (Data, Variable, Relative)
0xC0, // End Collection 0xC0, // End Collection
0xC0, // End Collection 0xC0, // End Collection
# endif #endif
# ifdef EXTRAKEY_ENABLE #ifdef EXTRAKEY_ENABLE
// Extrakeys report descriptor // Extrakeys report descriptor
0x05, 0x01, // Usage Page (Generic Desktop) 0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x80, // Usage (System Control) 0x09, 0x80, // Usage (System Control)
@ -481,7 +514,8 @@ const PROGMEM uchar mouse_extra_hid_report[] = {
0x75, 0x10, // Report Size (16) 0x75, 0x10, // Report Size (16)
0x81, 0x00, // Input (Data, Array, Absolute) 0x81, 0x00, // Input (Data, Array, Absolute)
0xC0 // End Collection 0xC0 // End Collection
# endif #endif
#ifdef SHARED_EP_ENABLE
}; };
#endif #endif
@ -618,6 +652,7 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
.bMaxPower = USB_MAX_POWER_CONSUMPTION / 2 .bMaxPower = USB_MAX_POWER_CONSUMPTION / 2
}, },
# ifndef KEYBOARD_SHARED_EP
/* /*
* Keyboard * Keyboard
*/ */
@ -655,6 +690,7 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
.wMaxPacketSize = 8, .wMaxPacketSize = 8,
.bInterval = USB_POLLING_INTERVAL_MS .bInterval = USB_POLLING_INTERVAL_MS
}, },
# endif
# if defined(RAW_ENABLE) # if defined(RAW_ENABLE)
/* /*
@ -705,24 +741,30 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
.bInterval = USB_POLLING_INTERVAL_MS .bInterval = USB_POLLING_INTERVAL_MS
}, },
# endif # endif
# if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
# ifdef SHARED_EP_ENABLE
/* /*
* Mouse/Extrakeys * Shared
*/ */
.mouseExtraInterface = { .sharedInterface = {
.header = { .header = {
.bLength = sizeof(usbInterfaceDescriptor_t), .bLength = sizeof(usbInterfaceDescriptor_t),
.bDescriptorType = USBDESCR_INTERFACE .bDescriptorType = USBDESCR_INTERFACE
}, },
.bInterfaceNumber = MOUSE_EXTRA_INTERFACE, .bInterfaceNumber = SHARED_INTERFACE,
.bAlternateSetting = 0x00, .bAlternateSetting = 0x00,
.bNumEndpoints = 1, .bNumEndpoints = 1,
.bInterfaceClass = 0x03, .bInterfaceClass = 0x03,
# ifdef KEYBOARD_SHARED_EP
.bInterfaceSubClass = 0x01,
.bInterfaceProtocol = 0x01,
# else
.bInterfaceSubClass = 0x00, .bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00, .bInterfaceProtocol = 0x00,
# endif
.iInterface = 0x00 .iInterface = 0x00
}, },
.mouseExtraHID = { .sharedHID = {
.header = { .header = {
.bLength = sizeof(usbHIDDescriptor_t), .bLength = sizeof(usbHIDDescriptor_t),
.bDescriptorType = USBDESCR_HID .bDescriptorType = USBDESCR_HID
@ -731,19 +773,24 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
.bCountryCode = 0x00, .bCountryCode = 0x00,
.bNumDescriptors = 1, .bNumDescriptors = 1,
.bDescriptorType = USBDESCR_HID_REPORT, .bDescriptorType = USBDESCR_HID_REPORT,
.wDescriptorLength = sizeof(mouse_extra_hid_report) .wDescriptorLength = sizeof(shared_hid_report)
}, },
.mouseExtraINEndpoint = { .sharedINEndpoint = {
.header = { .header = {
.bLength = sizeof(usbEndpointDescriptor_t), .bLength = sizeof(usbEndpointDescriptor_t),
.bDescriptorType = USBDESCR_ENDPOINT .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), .bEndpointAddress = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP3_NUMBER),
# endif
.bmAttributes = 0x03, .bmAttributes = 0x03,
.wMaxPacketSize = 8, .wMaxPacketSize = 8,
.bInterval = USB_POLLING_INTERVAL_MS .bInterval = USB_POLLING_INTERVAL_MS
}, },
# endif # endif
# if defined(CONSOLE_ENABLE) # if defined(CONSOLE_ENABLE)
/* /*
* Console * Console
@ -791,7 +838,7 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
.bmAttributes = 0x03, .bmAttributes = 0x03,
.wMaxPacketSize = CONSOLE_EPSIZE, .wMaxPacketSize = CONSOLE_EPSIZE,
.bInterval = 0x01 .bInterval = 0x01
}, }
# endif # endif
}; };
@ -833,22 +880,27 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) {
break; break;
case USBDESCR_HID: case USBDESCR_HID:
switch (rq->wValue.bytes[0]) { switch (rq->wValue.bytes[0]) {
#ifndef KEYBOARD_SHARED_EP
case KEYBOARD_INTERFACE: case KEYBOARD_INTERFACE:
usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.keyboardHID; usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.keyboardHID;
len = sizeof(usbHIDDescriptor_t); len = sizeof(usbHIDDescriptor_t);
break; break;
#endif
#if defined(RAW_ENABLE) #if defined(RAW_ENABLE)
case RAW_INTERFACE: case RAW_INTERFACE:
usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.rawHID; usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.rawHID;
len = sizeof(usbHIDDescriptor_t); len = sizeof(usbHIDDescriptor_t);
break; break;
#endif #endif
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
case MOUSE_EXTRA_INTERFACE: #ifdef SHARED_EP_ENABLE
usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.mouseExtraHID; case SHARED_INTERFACE:
usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.sharedHID;
len = sizeof(usbHIDDescriptor_t); len = sizeof(usbHIDDescriptor_t);
break; break;
#endif #endif
#if defined(CONSOLE_ENABLE) #if defined(CONSOLE_ENABLE)
case CONSOLE_INTERFACE: case CONSOLE_INTERFACE:
usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.consoleHID; usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.consoleHID;
@ -860,22 +912,27 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) {
case USBDESCR_HID_REPORT: case USBDESCR_HID_REPORT:
/* interface index */ /* interface index */
switch (rq->wIndex.word) { switch (rq->wIndex.word) {
#ifndef KEYBOARD_SHARED_EP
case KEYBOARD_INTERFACE: case KEYBOARD_INTERFACE:
usbMsgPtr = (usbMsgPtr_t)keyboard_hid_report; usbMsgPtr = (usbMsgPtr_t)keyboard_hid_report;
len = sizeof(keyboard_hid_report); len = sizeof(keyboard_hid_report);
break; break;
#endif
#if defined(RAW_ENABLE) #if defined(RAW_ENABLE)
case RAW_INTERFACE: case RAW_INTERFACE:
usbMsgPtr = (usbMsgPtr_t)raw_hid_report; usbMsgPtr = (usbMsgPtr_t)raw_hid_report;
len = sizeof(raw_hid_report); len = sizeof(raw_hid_report);
break; break;
#endif #endif
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
case MOUSE_EXTRA_INTERFACE: #ifdef SHARED_EP_ENABLE
usbMsgPtr = (usbMsgPtr_t)mouse_extra_hid_report; case SHARED_INTERFACE:
len = sizeof(mouse_extra_hid_report); usbMsgPtr = (usbMsgPtr_t)shared_hid_report;
len = sizeof(shared_hid_report);
break; break;
#endif #endif
#if defined(CONSOLE_ENABLE) #if defined(CONSOLE_ENABLE)
case CONSOLE_INTERFACE: case CONSOLE_INTERFACE:
usbMsgPtr = (usbMsgPtr_t)console_hid_report; usbMsgPtr = (usbMsgPtr_t)console_hid_report;

View File

@ -85,9 +85,16 @@ typedef struct usbHIDDescriptor {
typedef struct usbConfigurationDescriptor { typedef struct usbConfigurationDescriptor {
usbConfigurationDescriptorHeader_t header; usbConfigurationDescriptorHeader_t header;
usbInterfaceDescriptor_t keyboardInterface;
usbHIDDescriptor_t keyboardHID; #ifndef KEYBOARD_SHARED_EP
usbEndpointDescriptor_t keyboardINEndpoint; usbInterfaceDescriptor_t keyboardInterface;
usbHIDDescriptor_t keyboardHID;
usbEndpointDescriptor_t keyboardINEndpoint;
#else
usbInterfaceDescriptor_t sharedInterface;
usbHIDDescriptor_t sharedHID;
usbEndpointDescriptor_t sharedINEndpoint;
#endif
#if defined(RAW_ENABLE) #if defined(RAW_ENABLE)
usbInterfaceDescriptor_t rawInterface; usbInterfaceDescriptor_t rawInterface;
@ -96,10 +103,10 @@ typedef struct usbConfigurationDescriptor {
usbEndpointDescriptor_t rawOUTEndpoint; usbEndpointDescriptor_t rawOUTEndpoint;
#endif #endif
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) #if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP)
usbInterfaceDescriptor_t mouseExtraInterface; usbInterfaceDescriptor_t sharedInterface;
usbHIDDescriptor_t mouseExtraHID; usbHIDDescriptor_t sharedHID;
usbEndpointDescriptor_t mouseExtraINEndpoint; usbEndpointDescriptor_t sharedINEndpoint;
#endif #endif
#if defined(CONSOLE_ENABLE) #if defined(CONSOLE_ENABLE)