diff options
Diffstat (limited to 'tmk_core/protocol')
-rw-r--r-- | tmk_core/protocol/arm_atsam/main_arm_atsam.c | 59 | ||||
-rw-r--r-- | tmk_core/protocol/arm_atsam/usb/udi_device_epsize.h | 2 | ||||
-rw-r--r-- | tmk_core/protocol/chibios/chibios.c | 3 | ||||
-rw-r--r-- | tmk_core/protocol/chibios/usb_main.c | 173 | ||||
-rw-r--r-- | tmk_core/protocol/host.c | 33 | ||||
-rw-r--r-- | tmk_core/protocol/host.h | 4 | ||||
-rw-r--r-- | tmk_core/protocol/host_driver.h | 1 | ||||
-rw-r--r-- | tmk_core/protocol/lufa/lufa.c | 34 | ||||
-rw-r--r-- | tmk_core/protocol/report.c | 43 | ||||
-rw-r--r-- | tmk_core/protocol/report.h | 166 | ||||
-rw-r--r-- | tmk_core/protocol/usb_descriptor.c | 4 | ||||
-rw-r--r-- | tmk_core/protocol/usb_descriptor.h | 2 | ||||
-rw-r--r-- | tmk_core/protocol/usb_types.h | 23 | ||||
-rw-r--r-- | tmk_core/protocol/vusb/protocol.c | 1 | ||||
-rw-r--r-- | tmk_core/protocol/vusb/vusb.c | 276 | ||||
-rw-r--r-- | tmk_core/protocol/vusb/vusb.h | 1 |
16 files changed, 406 insertions, 419 deletions
diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c index 30817c17b6..8abcfd6090 100644 --- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c +++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c @@ -36,6 +36,7 @@ uint8_t g_usb_state = USB_FSMSTATUS_FSMSTATE_OFF_Val; // Saved USB state from ha void main_subtasks(void); uint8_t keyboard_leds(void); void send_keyboard(report_keyboard_t *report); +void send_nkro(report_nkro_t *report); void send_mouse(report_mouse_t *report); void send_extra(report_extra_t *report); @@ -43,7 +44,7 @@ void send_extra(report_extra_t *report); void deferred_exec_task(void); #endif // DEFERRED_EXEC_ENABLE -host_driver_t arm_atsam_driver = {keyboard_leds, send_keyboard, send_mouse, send_extra}; +host_driver_t arm_atsam_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra}; uint8_t led_states; @@ -59,41 +60,41 @@ uint8_t keyboard_leds(void) { void send_keyboard(report_keyboard_t *report) { uint32_t irqflags; -#ifdef NKRO_ENABLE - if (!keymap_config.nkro) { -#endif // NKRO_ENABLE - while (udi_hid_kbd_b_report_trans_ongoing) { - main_subtasks(); - } // Run other tasks while waiting for USB to be free + while (udi_hid_kbd_b_report_trans_ongoing) { + main_subtasks(); + } // Run other tasks while waiting for USB to be free - irqflags = __get_PRIMASK(); - __disable_irq(); - __DMB(); + irqflags = __get_PRIMASK(); + __disable_irq(); + __DMB(); - memcpy(udi_hid_kbd_report, report->raw, UDI_HID_KBD_REPORT_SIZE); - udi_hid_kbd_b_report_valid = 1; - udi_hid_kbd_send_report(); + memcpy(udi_hid_kbd_report, report, UDI_HID_KBD_REPORT_SIZE); + udi_hid_kbd_b_report_valid = 1; + udi_hid_kbd_send_report(); - __DMB(); - __set_PRIMASK(irqflags); + __DMB(); + __set_PRIMASK(irqflags); +} + +void send_nkro(report_nkro_t *report) { #ifdef NKRO_ENABLE - } else { - while (udi_hid_nkro_b_report_trans_ongoing) { - main_subtasks(); - } // Run other tasks while waiting for USB to be free + uint32_t irqflags; - irqflags = __get_PRIMASK(); - __disable_irq(); - __DMB(); + while (udi_hid_nkro_b_report_trans_ongoing) { + main_subtasks(); + } // Run other tasks while waiting for USB to be free - memcpy(udi_hid_nkro_report, report->raw, UDI_HID_NKRO_REPORT_SIZE); - udi_hid_nkro_b_report_valid = 1; - udi_hid_nkro_send_report(); + irqflags = __get_PRIMASK(); + __disable_irq(); + __DMB(); - __DMB(); - __set_PRIMASK(irqflags); - } -#endif // NKRO_ENABLE + memcpy(udi_hid_nkro_report, report, UDI_HID_NKRO_REPORT_SIZE); + udi_hid_nkro_b_report_valid = 1; + udi_hid_nkro_send_report(); + + __DMB(); + __set_PRIMASK(irqflags); +#endif } void send_mouse(report_mouse_t *report) { diff --git a/tmk_core/protocol/arm_atsam/usb/udi_device_epsize.h b/tmk_core/protocol/arm_atsam/usb/udi_device_epsize.h index 7a9ed31930..47bd02c074 100644 --- a/tmk_core/protocol/arm_atsam/usb/udi_device_epsize.h +++ b/tmk_core/protocol/arm_atsam/usb/udi_device_epsize.h @@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #define _UDI_DEVICE_EPSIZE_H_ #define KEYBOARD_EPSIZE 8 -#define MOUSE_EPSIZE 8 +#define MOUSE_EPSIZE 16 #define EXTRAKEY_EPSIZE 8 #define RAW_EPSIZE 32 #define CONSOLE_EPSIZE 32 diff --git a/tmk_core/protocol/chibios/chibios.c b/tmk_core/protocol/chibios/chibios.c index 4d97f1cd82..91bb252c7c 100644 --- a/tmk_core/protocol/chibios/chibios.c +++ b/tmk_core/protocol/chibios/chibios.c @@ -59,11 +59,12 @@ /* declarations */ uint8_t keyboard_leds(void); void send_keyboard(report_keyboard_t *report); +void send_nkro(report_nkro_t *report); void send_mouse(report_mouse_t *report); void send_extra(report_extra_t *report); /* host struct */ -host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_mouse, send_extra}; +host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra}; #ifdef VIRTSER_ENABLE void virtser_task(void); diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index b14ca30c1a..66f9ad0318 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -43,6 +43,7 @@ #include "usb_device_state.h" #include "usb_descriptor.h" #include "usb_driver.h" +#include "usb_types.h" #ifdef NKRO_ENABLE # include "keycode_config.h" @@ -71,7 +72,7 @@ static virtual_timer_t keyboard_idle_timer; static void keyboard_idle_timer_cb(struct ch_virtual_timer *, void *arg); -report_keyboard_t keyboard_report_sent = {{0}}; +report_keyboard_t keyboard_report_sent = {0}; report_mouse_t mouse_report_sent = {0}; union { @@ -103,30 +104,18 @@ union { NULL, /* SETUP buffer (not a SETUP endpoint) */ #endif -/* HID specific constants */ -#define HID_GET_REPORT 0x01 -#define HID_GET_IDLE 0x02 -#define HID_GET_PROTOCOL 0x03 -#define HID_SET_REPORT 0x09 -#define HID_SET_IDLE 0x0A -#define HID_SET_PROTOCOL 0x0B - -/* - * Handles the GET_DESCRIPTOR callback - * - * Returns the proper descriptor - */ static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype, uint8_t dindex, uint16_t wIndex) { - (void)usbp; - static USBDescriptor desc; - uint16_t wValue = ((uint16_t)dtype << 8) | dindex; - uint16_t wLength = ((uint16_t)usbp->setup[7] << 8) | usbp->setup[6]; - desc.ud_string = NULL; - desc.ud_size = get_usb_descriptor(wValue, wIndex, wLength, (const void **const) & desc.ud_string); - if (desc.ud_string == NULL) + usb_control_request_t *setup = (usb_control_request_t *)usbp->setup; + + static USBDescriptor descriptor; + descriptor.ud_string = NULL; + descriptor.ud_size = get_usb_descriptor(setup->wValue.word, setup->wIndex, setup->wLength, (const void **const) & descriptor.ud_string); + + if (descriptor.ud_string == NULL) { return NULL; - else - return &desc; + } + + return &descriptor; } /* @@ -497,8 +486,7 @@ void usb_event_queue_task(void) { } } -/* Handles the USB driver global events - * TODO: maybe disable some things when connection is lost? */ +/* Handles the USB driver global events. */ static void usb_event_cb(USBDriver *usbp, usbevent_t event) { switch (event) { case USB_EVENT_ADDRESS: @@ -570,16 +558,6 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) { } } -/* Function used locally in os/hal/src/usb.c for getting descriptors - * need it here for HID descriptor */ -static uint16_t get_hword(uint8_t *p) { - uint16_t hw; - - hw = (uint16_t)*p++; - hw |= (uint16_t)*p << 8U; - return hw; -} - /* * Appendix G: HID Request Support Requirements * @@ -596,7 +574,9 @@ static uint16_t get_hword(uint8_t *p) { static uint8_t set_report_buf[2] __attribute__((aligned(4))); static void set_led_transfer_cb(USBDriver *usbp) { - if (usbp->setup[6] == 2) { /* LSB(wLength) */ + usb_control_request_t *setup = (usb_control_request_t *)usbp->setup; + + if (setup->wLength == 2) { uint8_t report_id = set_report_buf[0]; if ((report_id == REPORT_ID_KEYBOARD) || (report_id == REPORT_ID_NKRO)) { keyboard_led_state = set_report_buf[1]; @@ -606,24 +586,16 @@ static void set_led_transfer_cb(USBDriver *usbp) { } } -/* Callback for SETUP request on the endpoint 0 (control) */ -static bool usb_request_hook_cb(USBDriver *usbp) { - const USBDescriptor *dp; - - /* usbp->setup fields: - * 0: bmRequestType (bitmask) - * 1: bRequest - * 2,3: (LSB,MSB) wValue - * 4,5: (LSB,MSB) wIndex - * 6,7: (LSB,MSB) wLength (number of bytes to transfer if there is a data phase) */ +static bool usb_requests_hook_cb(USBDriver *usbp) { + usb_control_request_t *setup = (usb_control_request_t *)usbp->setup; /* Handle HID class specific requests */ - if (((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) && ((usbp->setup[0] & USB_RTYPE_RECIPIENT_MASK) == USB_RTYPE_RECIPIENT_INTERFACE)) { - switch (usbp->setup[0] & USB_RTYPE_DIR_MASK) { + if ((setup->bmRequestType & (USB_RTYPE_TYPE_MASK | USB_RTYPE_RECIPIENT_MASK)) == (USB_RTYPE_TYPE_CLASS | USB_RTYPE_RECIPIENT_INTERFACE)) { + switch (setup->bmRequestType & USB_RTYPE_DIR_MASK) { case USB_RTYPE_DIR_DEV2HOST: - switch (usbp->setup[1]) { /* bRequest */ - case HID_GET_REPORT: - switch (usbp->setup[4]) { /* LSB(wIndex) (check MSB==0?) */ + switch (setup->bRequest) { + case HID_REQ_GetReport: + switch (setup->wIndex) { #ifndef KEYBOARD_SHARED_EP case KEYBOARD_INTERFACE: usbSetupTransfer(usbp, (uint8_t *)&keyboard_report_sent, KEYBOARD_REPORT_SIZE, NULL); @@ -639,59 +611,54 @@ static bool usb_request_hook_cb(USBDriver *usbp) { #ifdef SHARED_EP_ENABLE case SHARED_INTERFACE: # ifdef KEYBOARD_SHARED_EP - if (usbp->setup[2] == REPORT_ID_KEYBOARD) { + if (setup->wValue.lbyte == REPORT_ID_KEYBOARD) { usbSetupTransfer(usbp, (uint8_t *)&keyboard_report_sent, KEYBOARD_REPORT_SIZE, NULL); - return TRUE; - break; + return true; } # endif # ifdef MOUSE_SHARED_EP - if (usbp->setup[2] == REPORT_ID_MOUSE) { + if (setup->wValue.lbyte == REPORT_ID_MOUSE) { usbSetupTransfer(usbp, (uint8_t *)&mouse_report_sent, sizeof(mouse_report_sent), NULL); - return TRUE; - break; + return true; } # endif #endif /* SHARED_EP_ENABLE */ default: - universal_report_blank.report_id = usbp->setup[2]; - usbSetupTransfer(usbp, (uint8_t *)&universal_report_blank, usbp->setup[6], NULL); - return TRUE; - break; + universal_report_blank.report_id = setup->wValue.lbyte; + usbSetupTransfer(usbp, (uint8_t *)&universal_report_blank, setup->wLength, NULL); + return true; } break; - case HID_GET_PROTOCOL: - if ((usbp->setup[4] == KEYBOARD_INTERFACE) && (usbp->setup[5] == 0)) { /* wIndex */ - usbSetupTransfer(usbp, &keyboard_protocol, 1, NULL); - return TRUE; + case HID_REQ_GetProtocol: + if (setup->wIndex == KEYBOARD_INTERFACE) { + usbSetupTransfer(usbp, &keyboard_protocol, sizeof(uint8_t), NULL); + return true; } break; - case HID_GET_IDLE: - usbSetupTransfer(usbp, &keyboard_idle, 1, NULL); - return TRUE; - break; + case HID_REQ_GetIdle: + usbSetupTransfer(usbp, &keyboard_idle, sizeof(uint8_t), NULL); + return true; } break; case USB_RTYPE_DIR_HOST2DEV: - switch (usbp->setup[1]) { /* bRequest */ - case HID_SET_REPORT: - switch (usbp->setup[4]) { /* LSB(wIndex) (check MSB==0?) */ + switch (setup->bRequest) { + case HID_REQ_SetReport: + switch (setup->wIndex) { case KEYBOARD_INTERFACE: #if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP) case SHARED_INTERFACE: #endif usbSetupTransfer(usbp, set_report_buf, sizeof(set_report_buf), set_led_transfer_cb); - return TRUE; - break; + return true; } break; - case HID_SET_PROTOCOL: - if ((usbp->setup[4] == KEYBOARD_INTERFACE) && (usbp->setup[5] == 0)) { /* wIndex */ - keyboard_protocol = ((usbp->setup[2]) != 0x00); /* LSB(wValue) */ + case HID_REQ_SetProtocol: + if (setup->wIndex == KEYBOARD_INTERFACE) { + keyboard_protocol = setup->wValue.word; #ifdef NKRO_ENABLE if (!keyboard_protocol && keyboard_idle) { #else /* NKRO_ENABLE */ @@ -704,12 +671,11 @@ static bool usb_request_hook_cb(USBDriver *usbp) { } } usbSetupTransfer(usbp, NULL, 0, NULL); - return TRUE; - break; + return true; - case HID_SET_IDLE: - keyboard_idle = usbp->setup[3]; /* MSB(wValue) */ - /* arm the timer */ + case HID_REQ_SetIdle: + keyboard_idle = setup->wValue.hbyte; + /* arm the timer */ #ifdef NKRO_ENABLE if (!keymap_config.nkro && keyboard_idle) { #else /* NKRO_ENABLE */ @@ -720,19 +686,21 @@ static bool usb_request_hook_cb(USBDriver *usbp) { osalSysUnlockFromISR(); } usbSetupTransfer(usbp, NULL, 0, NULL); - return TRUE; - break; + return true; } break; } } - /* Handle the Get_Descriptor Request for HID class (not handled by the default hook) */ - if ((usbp->setup[0] == 0x81) && (usbp->setup[1] == USB_REQ_GET_DESCRIPTOR)) { - dp = usbp->config->get_descriptor_cb(usbp, usbp->setup[3], usbp->setup[2], get_hword(&usbp->setup[4])); - if (dp == NULL) return FALSE; - usbSetupTransfer(usbp, (uint8_t *)dp->ud_string, dp->ud_size, NULL); - return TRUE; + /* Handle the Get_Descriptor Request for HID class, which is not handled by + * the ChibiOS USB driver */ + if (((setup->bmRequestType & (USB_RTYPE_DIR_MASK | USB_RTYPE_RECIPIENT_MASK)) == (USB_RTYPE_DIR_DEV2HOST | USB_RTYPE_RECIPIENT_INTERFACE)) && (setup->bRequest == USB_REQ_GET_DESCRIPTOR)) { + const USBDescriptor *descriptor = usbp->config->get_descriptor_cb(usbp, setup->wValue.lbyte, setup->wValue.hbyte, setup->wIndex); + if (descriptor == NULL) { + return false; + } + usbSetupTransfer(usbp, (uint8_t *)descriptor->ud_string, descriptor->ud_size, NULL); + return true; } for (int i = 0; i < NUM_USB_DRIVERS; i++) { @@ -742,10 +710,9 @@ static bool usb_request_hook_cb(USBDriver *usbp) { } } - return FALSE; + return false; } -/* Start-of-frame callback */ static void usb_sof_cb(USBDriver *usbp) { osalSysLockFromISR(); for (int i = 0; i < NUM_USB_DRIVERS; i++) { @@ -758,7 +725,7 @@ static void usb_sof_cb(USBDriver *usbp) { static const USBConfig usbcfg = { usb_event_cb, /* USB events callback */ usb_get_descriptor_cb, /* Device GET_DESCRIPTOR request callback */ - usb_request_hook_cb, /* Requests hook callback */ + usb_requests_hook_cb, /* Requests hook callback */ usb_sof_cb /* Start Of Frame callback */ }; @@ -883,26 +850,22 @@ void send_report(uint8_t endpoint, void *report, size_t size) { /* prepare and start sending a report IN * not callable from ISR or locked state */ void send_keyboard(report_keyboard_t *report) { - uint8_t ep = KEYBOARD_IN_EPNUM; - size_t size = KEYBOARD_REPORT_SIZE; - /* If we're in Boot Protocol, don't send any report ID or other funky fields */ if (!keyboard_protocol) { - send_report(ep, &report->mods, 8); + send_report(KEYBOARD_IN_EPNUM, &report->mods, 8); } else { -#ifdef NKRO_ENABLE - if (keymap_config.nkro) { - ep = SHARED_IN_EPNUM; - size = sizeof(struct nkro_report); - } -#endif - - send_report(ep, report, size); + send_report(KEYBOARD_IN_EPNUM, report, KEYBOARD_REPORT_SIZE); } keyboard_report_sent = *report; } +void send_nkro(report_nkro_t *report) { +#ifdef NKRO_ENABLE + send_report(SHARED_IN_EPNUM, report, sizeof(report_nkro_t)); +#endif +} + /* --------------------------------------------------------- * Mouse functions * --------------------------------------------------------- diff --git a/tmk_core/protocol/host.c b/tmk_core/protocol/host.c index 2c6654e9a6..732fbdc37d 100644 --- a/tmk_core/protocol/host.c +++ b/tmk_core/protocol/host.c @@ -81,26 +81,29 @@ void host_keyboard_send(report_keyboard_t *report) { #endif if (!driver) return; -#if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP) - if (keyboard_protocol && keymap_config.nkro) { - /* The callers of this function assume that report->mods is where mods go in. - * But report->nkro.mods can be at a different offset if core keyboard does not have a report ID. - */ - report->nkro.mods = report->mods; - report->nkro.report_id = REPORT_ID_NKRO; - } else -#endif - { #ifdef KEYBOARD_SHARED_EP - report->report_id = REPORT_ID_KEYBOARD; + report->report_id = REPORT_ID_KEYBOARD; #endif - } (*driver->send_keyboard)(report); if (debug_keyboard) { - dprint("keyboard_report: "); - for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) { - dprintf("%02X ", report->raw[i]); + dprintf("keyboard_report: %02X | ", report->mods); + for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { + dprintf("%02X ", report->keys[i]); + } + dprint("\n"); + } +} + +void host_nkro_send(report_nkro_t *report) { + if (!driver) return; + report->report_id = REPORT_ID_NKRO; + (*driver->send_nkro)(report); + + if (debug_keyboard) { + dprintf("nkro_report: %02X | ", report->mods); + for (uint8_t i = 0; i < NKRO_REPORT_BITS; i++) { + dprintf("%02X ", report->bits[i]); } dprint("\n"); } diff --git a/tmk_core/protocol/host.h b/tmk_core/protocol/host.h index add408caf6..959753ae02 100644 --- a/tmk_core/protocol/host.h +++ b/tmk_core/protocol/host.h @@ -23,9 +23,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "host_driver.h" #include "led.h" -#define IS_LED_ON(leds, led_name) ((leds) & (1 << (led_name))) -#define IS_LED_OFF(leds, led_name) (~(leds) & (1 << (led_name))) - #ifdef __cplusplus extern "C" { #endif @@ -41,6 +38,7 @@ host_driver_t *host_get_driver(void); uint8_t host_keyboard_leds(void); led_t host_keyboard_led_state(void); void host_keyboard_send(report_keyboard_t *report); +void host_nkro_send(report_nkro_t *report); void host_mouse_send(report_mouse_t *report); void host_system_send(uint16_t usage); void host_consumer_send(uint16_t usage); diff --git a/tmk_core/protocol/host_driver.h b/tmk_core/protocol/host_driver.h index 7dc6c3d810..8aa38b6dee 100644 --- a/tmk_core/protocol/host_driver.h +++ b/tmk_core/protocol/host_driver.h @@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. typedef struct { uint8_t (*keyboard_leds)(void); void (*send_keyboard)(report_keyboard_t *); + void (*send_nkro)(report_nkro_t *); void (*send_mouse)(report_mouse_t *); void (*send_extra)(report_extra_t *); } host_driver_t; diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index f04ca79a0c..553f69b1e4 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -55,12 +55,6 @@ #include "usb_device_state.h" #include <util/atomic.h> -#ifdef NKRO_ENABLE -# include "keycode_config.h" - -extern keymap_config_t keymap_config; -#endif - #ifdef VIRTSER_ENABLE # include "virtser.h" #endif @@ -83,9 +77,10 @@ static report_keyboard_t keyboard_report_sent; /* Host driver */ static uint8_t keyboard_leds(void); static void send_keyboard(report_keyboard_t *report); +static void send_nkro(report_nkro_t *report); static void send_mouse(report_mouse_t *report); static void send_extra(report_extra_t *report); -host_driver_t lufa_driver = {keyboard_leds, send_keyboard, send_mouse, send_extra}; +host_driver_t lufa_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra}; void send_report(uint8_t endpoint, void *report, size_t size) { uint8_t timeout = 255; @@ -559,27 +554,26 @@ static uint8_t keyboard_leds(void) { * FIXME: Needs doc */ static void send_keyboard(report_keyboard_t *report) { - /* Select the Keyboard Report Endpoint */ - uint8_t ep = KEYBOARD_IN_EPNUM; - uint8_t size = KEYBOARD_REPORT_SIZE; - /* If we're in Boot Protocol, don't send any report ID or other funky fields */ if (!keyboard_protocol) { - send_report(ep, &report->mods, 8); + send_report(KEYBOARD_IN_EPNUM, &report->mods, 8); } else { -#ifdef NKRO_ENABLE - if (keymap_config.nkro) { - ep = SHARED_IN_EPNUM; - size = sizeof(struct nkro_report); - } -#endif - - send_report(ep, report, size); + send_report(KEYBOARD_IN_EPNUM, report, KEYBOARD_REPORT_SIZE); } keyboard_report_sent = *report; } +/** \brief Send NKRO + * + * FIXME: Needs doc + */ +static void send_nkro(report_nkro_t *report) { +#ifdef NKRO_ENABLE + send_report(SHARED_IN_EPNUM, report, sizeof(report_nkro_t)); +#endif +} + /** \brief Send Mouse * * FIXME: Needs doc diff --git a/tmk_core/protocol/report.c b/tmk_core/protocol/report.c index 1ba3be4604..0166bf654f 100644 --- a/tmk_core/protocol/report.c +++ b/tmk_core/protocol/report.c @@ -15,6 +15,7 @@ */ #include "report.h" +#include "action_util.h" #include "host.h" #include "keycode_config.h" #include "debug.h" @@ -35,14 +36,14 @@ static int8_t cb_count = 0; * * FIXME: Needs doc */ -uint8_t has_anykey(report_keyboard_t* keyboard_report) { +uint8_t has_anykey(void) { uint8_t cnt = 0; uint8_t* p = keyboard_report->keys; uint8_t lp = sizeof(keyboard_report->keys); #ifdef NKRO_ENABLE if (keyboard_protocol && keymap_config.nkro) { - p = keyboard_report->nkro.bits; - lp = sizeof(keyboard_report->nkro.bits); + p = nkro_report->bits; + lp = sizeof(nkro_report->bits); } #endif while (lp--) { @@ -55,13 +56,13 @@ uint8_t has_anykey(report_keyboard_t* keyboard_report) { * * FIXME: Needs doc */ -uint8_t get_first_key(report_keyboard_t* keyboard_report) { +uint8_t get_first_key(void) { #ifdef NKRO_ENABLE if (keyboard_protocol && keymap_config.nkro) { uint8_t i = 0; - for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++) + for (; i < NKRO_REPORT_BITS && !nkro_report->bits[i]; i++) ; - return i << 3 | biton(keyboard_report->nkro.bits[i]); + return i << 3 | biton(nkro_report->bits[i]); } #endif #ifdef RING_BUFFERED_6KRO_REPORT_ENABLE @@ -83,14 +84,14 @@ uint8_t get_first_key(report_keyboard_t* keyboard_report) { * Returns true if the keyboard_report reports that the key is pressed, otherwise false * Note: The function doesn't support modifers currently, and it returns false for KC_NO */ -bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key) { +bool is_key_pressed(uint8_t key) { if (key == KC_NO) { return false; } #ifdef NKRO_ENABLE if (keyboard_protocol && keymap_config.nkro) { - if ((key >> 3) < KEYBOARD_REPORT_BITS) { - return keyboard_report->nkro.bits[key >> 3] & 1 << (key & 7); + if ((key >> 3) < NKRO_REPORT_BITS) { + return nkro_report->bits[key >> 3] & 1 << (key & 7); } else { return false; } @@ -215,9 +216,9 @@ void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code) { * * FIXME: Needs doc */ -void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code) { - if ((code >> 3) < KEYBOARD_REPORT_BITS) { - keyboard_report->nkro.bits[code >> 3] |= 1 << (code & 7); +void add_key_bit(report_nkro_t* nkro_report, uint8_t code) { + if ((code >> 3) < NKRO_REPORT_BITS) { + nkro_report->bits[code >> 3] |= 1 << (code & 7); } else { dprintf("add_key_bit: can't add: %02X\n", code); } @@ -227,9 +228,9 @@ void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code) { * * FIXME: Needs doc */ -void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) { - if ((code >> 3) < KEYBOARD_REPORT_BITS) { - keyboard_report->nkro.bits[code >> 3] &= ~(1 << (code & 7)); +void del_key_bit(report_nkro_t* nkro_report, uint8_t code) { + if ((code >> 3) < NKRO_REPORT_BITS) { + nkro_report->bits[code >> 3] &= ~(1 << (code & 7)); } else { dprintf("del_key_bit: can't del: %02X\n", code); } @@ -240,10 +241,10 @@ void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) { * * FIXME: Needs doc */ -void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) { +void add_key_to_report(uint8_t key) { #ifdef NKRO_ENABLE if (keyboard_protocol && keymap_config.nkro) { - add_key_bit(keyboard_report, key); + add_key_bit(nkro_report, key); return; } #endif @@ -254,10 +255,10 @@ void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) { * * FIXME: Needs doc */ -void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) { +void del_key_from_report(uint8_t key) { #ifdef NKRO_ENABLE if (keyboard_protocol && keymap_config.nkro) { - del_key_bit(keyboard_report, key); + del_key_bit(nkro_report, key); return; } #endif @@ -268,11 +269,11 @@ void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) { * * FIXME: Needs doc */ -void clear_keys_from_report(report_keyboard_t* keyboard_report) { +void clear_keys_from_report(void) { // not clear mods #ifdef NKRO_ENABLE if (keyboard_protocol && keymap_config.nkro) { - memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits)); + memset(nkro_report->bits, 0, sizeof(nkro_report->bits)); return; } #endif diff --git a/tmk_core/protocol/report.h b/tmk_core/protocol/report.h index 9d415a3bfd..3028cf9426 100644 --- a/tmk_core/protocol/report.h +++ b/tmk_core/protocol/report.h @@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include <stdint.h> #include <stdbool.h> #include "keycode.h" +#include "util.h" // clang-format off @@ -54,9 +55,9 @@ enum mouse_buttons { */ enum consumer_usages { // 15.5 Display Controls - SNAPSHOT = 0x065, - BRIGHTNESS_UP = 0x06F, // https://www.usb.org/sites/default/files/hutrr41_0.pdf - BRIGHTNESS_DOWN = 0x070, + SNAPSHOT = 0x065, + BRIGHTNESS_UP = 0x06F, // https://www.usb.org/sites/default/files/hutrr41_0.pdf + BRIGHTNESS_DOWN = 0x070, // 15.7 Transport Controls TRANSPORT_RECORD = 0x0B2, TRANSPORT_FAST_FORWARD = 0x0B3, @@ -69,43 +70,44 @@ enum consumer_usages { TRANSPORT_STOP_EJECT = 0x0CC, TRANSPORT_PLAY_PAUSE = 0x0CD, // 15.9.1 Audio Controls - Volume - AUDIO_MUTE = 0x0E2, - AUDIO_VOL_UP = 0x0E9, - AUDIO_VOL_DOWN = 0x0EA, + AUDIO_MUTE = 0x0E2, + AUDIO_VOL_UP = 0x0E9, + AUDIO_VOL_DOWN = 0x0EA, // 15.15 Application Launch Buttons - AL_CC_CONFIG = 0x183, - AL_EMAIL = 0x18A, - AL_CALCULATOR = 0x192, - AL_LOCAL_BROWSER = 0x194, - AL_LOCK = 0x19E, - AL_CONTROL_PANEL = 0x19F, - AL_ASSISTANT = 0x1CB, - AL_KEYBOARD_LAYOUT = 0x1AE, + AL_CC_CONFIG = 0x183, + AL_EMAIL = 0x18A, + AL_CALCULATOR = 0x192, + AL_LOCAL_BROWSER = 0x194, + AL_LOCK = 0x19E, + AL_CONTROL_PANEL = 0x19F, + AL_ASSISTANT = 0x1CB, + AL_KEYBOARD_LAYOUT = 0x1AE, // 15.16 Generic GUI Application Controls - AC_NEW = 0x201, - AC_OPEN = 0x202, - AC_CLOSE = 0x203, - AC_EXIT = 0x204, - AC_MAXIMIZE = 0x205, - AC_MINIMIZE = 0x206, - AC_SAVE = 0x207, - AC_PRINT = 0x208, - AC_PROPERTIES = 0x209, - AC_UNDO = 0x21A, - AC_COPY = 0x21B, - AC_CUT = 0x21C, - AC_PASTE = 0x21D, - AC_SELECT_ALL = 0x21E, - AC_FIND = 0x21F, - AC_SEARCH = 0x221, - AC_HOME = 0x223, - AC_BACK = 0x224, - AC_FORWARD = 0x225, - AC_STOP = 0x226, - AC_REFRESH = 0x227, - AC_BOOKMARKS = 0x22A, - AC_MISSION_CONTROL = 0x29F, - AC_LAUNCHPAD = 0x2A0 + AC_NEW = 0x201, + AC_OPEN = 0x202, + AC_CLOSE = 0x203, + AC_EXIT = 0x204, + AC_MAXIMIZE = 0x205, + AC_MINIMIZE = 0x206, + AC_SAVE = 0x207, + AC_PRINT = 0x208, + AC_PROPERTIES = 0x209, + AC_UNDO = 0x21A, + AC_COPY = 0x21B, + AC_CUT = 0x21C, + AC_PASTE = 0x21D, + AC_SELECT_ALL = 0x21E, + AC_FIND = 0x21F, + AC_SEARCH = 0x221, + AC_HOME = 0x223, + AC_BACK = 0x224, + AC_FORWARD = 0x225, + AC_STOP = 0x226, + AC_REFRESH = 0x227, + AC_BOOKMARKS = 0x22A, + AC_NEXT_KEYBOARD_LAYOUT_SELECT = 0x29D, + AC_DESKTOP_SHOW_ALL_WINDOWS = 0x29F, + AC_SOFT_KEY_LEFT = 0x2A0 }; /* Generic Desktop Page (0x01) @@ -124,21 +126,7 @@ enum desktop_usages { // clang-format on -#define NKRO_SHARED_EP -/* key report size(NKRO or boot mode) */ -#if defined(NKRO_ENABLE) -# if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS) -# include "protocol/usb_descriptor.h" -# define KEYBOARD_REPORT_BITS (SHARED_EPSIZE - 2) -# elif defined(PROTOCOL_ARM_ATSAM) -# include "protocol/arm_atsam/usb/udi_device_epsize.h" -# define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1) -# undef NKRO_SHARED_EP -# undef MOUSE_SHARED_EP -# else -# error "NKRO not supported with this protocol" -# endif -#endif +#define NKRO_REPORT_BITS 30 #ifdef KEYBOARD_SHARED_EP # define KEYBOARD_REPORT_SIZE 9 @@ -172,36 +160,30 @@ extern "C" { * desc |Lcontrol|Lshift |Lalt |Lgui |Rcontrol|Rshift |Ralt |Rgui * */ -typedef union { - uint8_t raw[KEYBOARD_REPORT_SIZE]; - struct { +typedef struct { #ifdef KEYBOARD_SHARED_EP - uint8_t report_id; -#endif - uint8_t mods; - uint8_t reserved; - uint8_t keys[KEYBOARD_REPORT_KEYS]; - }; -#ifdef NKRO_ENABLE - struct nkro_report { -# ifdef NKRO_SHARED_EP - uint8_t report_id; -# endif - uint8_t mods; - uint8_t bits[KEYBOARD_REPORT_BITS]; - } nkro; + uint8_t report_id; #endif -} __attribute__((packed)) report_keyboard_t; + uint8_t mods; + uint8_t reserved; + uint8_t keys[KEYBOARD_REPORT_KEYS]; +} PACKED report_keyboard_t; + +typedef struct { + uint8_t report_id; + uint8_t mods; + uint8_t bits[NKRO_REPORT_BITS]; +} PACKED report_nkro_t; typedef struct { uint8_t report_id; uint16_t usage; -} __attribute__((packed)) report_extra_t; +} PACKED report_extra_t; typedef struct { uint8_t report_id; uint32_t usage; -} __attribute__((packed)) report_programmable_button_t; +} PACKED report_programmable_button_t; #ifdef MOUSE_EXTENDED_REPORT typedef int16_t mouse_xy_report_t; @@ -222,7 +204,7 @@ typedef struct { mouse_xy_report_t y; int8_t v; int8_t h; -} __attribute__((packed)) report_mouse_t; +} PACKED report_mouse_t; typedef struct { #ifdef DIGITIZER_SHARED_EP @@ -234,24 +216,26 @@ typedef struct { uint8_t reserved : 5; uint16_t x; uint16_t y; -} __attribute__((packed)) report_digitizer_t; +} PACKED report_digitizer_t; + +#if JOYSTICK_AXIS_RESOLUTION > 8 +typedef int16_t joystick_axis_t; +#else +typedef int8_t joystick_axis_t; +#endif typedef struct { #ifdef JOYSTICK_SHARED_EP uint8_t report_id; #endif #if JOYSTICK_AXIS_COUNT > 0 -# if JOYSTICK_AXIS_RESOLUTION > 8 - int16_t axes[JOYSTICK_AXIS_COUNT]; -# else - int8_t axes[JOYSTICK_AXIS_COUNT]; -# endif + joystick_axis_t axes[JOYSTICK_AXIS_COUNT]; #endif #if JOYSTICK_BUTTON_COUNT > 0 uint8_t buttons[(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1]; #endif -} __attribute__((packed)) report_joystick_t; +} PACKED report_joystick_t; /* keycode to system usage */ static inline uint16_t KEYCODE2SYSTEM(uint8_t key) { @@ -321,28 +305,28 @@ static inline uint16_t KEYCODE2CONSUMER(uint8_t key) { case KC_WWW_FAVORITES: return AC_BOOKMARKS; case KC_MISSION_CONTROL: - return AC_MISSION_CONTROL; + return AC_DESKTOP_SHOW_ALL_WINDOWS; case KC_LAUNCHPAD: - return AC_LAUNCHPAD; + return AC_SOFT_KEY_LEFT; default: return 0; } } -uint8_t has_anykey(report_keyboard_t* keyboard_report); -uint8_t get_first_key(report_keyboard_t* keyboard_report); -bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key); +uint8_t has_anykey(void); +uint8_t get_first_key(void); +bool is_key_pressed(uint8_t key); void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code); void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code); #ifdef NKRO_ENABLE -void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code); -void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code); +void add_key_bit(report_nkro_t* nkro_report, uint8_t code); +void del_key_bit(report_nkro_t* nkro_report, uint8_t code); #endif -void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key); -void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key); -void clear_keys_from_report(report_keyboard_t* keyboard_report); +void add_key_to_report(uint8_t key); +void del_key_from_report(uint8_t key); +void clear_keys_from_report(void); #ifdef MOUSE_ENABLE bool has_mouse_report_changed(report_mouse_t* new_report, report_mouse_t* old_report); diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c index e215c90900..eb214c0492 100644 --- a/tmk_core/protocol/usb_descriptor.c +++ b/tmk_core/protocol/usb_descriptor.c @@ -359,10 +359,10 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = { // Keycodes HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad HID_RI_USAGE_MINIMUM(8, 0x00), - HID_RI_USAGE_MAXIMUM(8, KEYBOARD_REPORT_BITS * 8 - 1), + HID_RI_USAGE_MAXIMUM(8, NKRO_REPORT_BITS * 8 - 1), HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0x01), - HID_RI_REPORT_COUNT(8, KEYBOARD_REPORT_BITS * 8), + HID_RI_REPORT_COUNT(8, NKRO_REPORT_BITS * 8), HID_RI_REPORT_SIZE(8, 0x01), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), diff --git a/tmk_core/protocol/usb_descriptor.h b/tmk_core/protocol/usb_descriptor.h index ed84f4c9ab..1268bdae73 100644 --- a/tmk_core/protocol/usb_descriptor.h +++ b/tmk_core/protocol/usb_descriptor.h @@ -299,7 +299,7 @@ enum usb_endpoints { #define KEYBOARD_EPSIZE 8 #define SHARED_EPSIZE 32 -#define MOUSE_EPSIZE 8 +#define MOUSE_EPSIZE 16 #define RAW_EPSIZE 32 #define CONSOLE_EPSIZE 32 #define MIDI_STREAM_EPSIZE 64 diff --git a/tmk_core/protocol/usb_types.h b/tmk_core/protocol/usb_types.h new file mode 100644 index 0000000000..019775a1c4 --- /dev/null +++ b/tmk_core/protocol/usb_types.h @@ -0,0 +1,23 @@ +// Copyright 2023 Stefan Kerkmann +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "util.h" + +/** + * @brief Common USB 2.0 control request structure + */ +typedef struct { + uint8_t bmRequestType; // [0] (Bitmask) + uint8_t bRequest; // [1] + union { + struct { + uint8_t lbyte; // [2] (LSB) + uint8_t hbyte; // [3] (MSB) + }; + uint16_t word; // [2,3] (LSB,MSB) + } wValue; + uint16_t wIndex; // [4,5] (LSB,MSB) + uint16_t wLength; // [6,7] (LSB,MSB) +} PACKED usb_control_request_t; diff --git a/tmk_core/protocol/vusb/protocol.c b/tmk_core/protocol/vusb/protocol.c index ae99680ce4..1f64561274 100644 --- a/tmk_core/protocol/vusb/protocol.c +++ b/tmk_core/protocol/vusb/protocol.c @@ -153,7 +153,6 @@ void protocol_task(void) { if (usbConfiguration && usbInterruptIsReady()) { keyboard_task(); } - vusb_transfer_keyboard(); #ifdef RAW_ENABLE usbPoll(); diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c index d74f375f66..d09b2f19b7 100644 --- a/tmk_core/protocol/vusb/vusb.c +++ b/tmk_core/protocol/vusb/vusb.c @@ -48,16 +48,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. # include "os_detection.h" #endif -#define NEXT_INTERFACE __COUNTER__ - /* * Interface indexes */ enum usb_interfaces { #ifndef KEYBOARD_SHARED_EP - KEYBOARD_INTERFACE = NEXT_INTERFACE, + KEYBOARD_INTERFACE, #else - SHARED_INTERFACE = NEXT_INTERFACE, + SHARED_INTERFACE, # define KEYBOARD_INTERFACE SHARED_INTERFACE #endif @@ -65,67 +63,77 @@ enum usb_interfaces { // interface number, to support Linux/OSX platforms and chrome.hid // If Raw HID is enabled, let it be always 1. #ifdef RAW_ENABLE - RAW_INTERFACE = NEXT_INTERFACE, + RAW_INTERFACE, #endif #if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP) - SHARED_INTERFACE = NEXT_INTERFACE, + SHARED_INTERFACE, #endif #ifdef CONSOLE_ENABLE - CONSOLE_INTERFACE = NEXT_INTERFACE, + CONSOLE_INTERFACE, #endif - TOTAL_INTERFACES = NEXT_INTERFACE + TOTAL_INTERFACES }; #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 +_Static_assert(TOTAL_INTERFACES <= MAX_INTERFACES, "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."); #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; - -/* Keyboard report send buffer */ -#define KBUF_SIZE 16 -static report_keyboard_t kbuf[KBUF_SIZE]; -static uint8_t kbuf_head = 0; -static uint8_t kbuf_tail = 0; +uint8_t keyboard_idle = 0; +uint8_t keyboard_protocol = 1; static report_keyboard_t keyboard_report_sent; -#define VUSB_TRANSFER_KEYBOARD_MAX_TRIES 10 - -/* transfer keyboard report from buffer */ -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 - // Ugly hack! :( - usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t) - 1); - while (!usbInterruptIsReady()) { - usbPoll(); +static void send_report_fragment(uint8_t endpoint, void *data, size_t size) { + for (uint8_t retries = 5; retries > 0; retries--) { + switch (endpoint) { + case 1: + if (usbInterruptIsReady()) { + usbSetInterrupt(data, size); + return; } - 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; + case USB_CFG_EP3_NUMBER: + if (usbInterruptIsReady3()) { + usbSetInterrupt3(data, size); + return; } - } - break; + break; + case USB_CFG_EP4_NUMBER: + if (usbInterruptIsReady4()) { + usbSetInterrupt4(data, size); + return; + } + break; + default: + return; } + usbPoll(); - wait_ms(1); + wait_ms(5); + } +} + +static void send_report(uint8_t endpoint, void *report, size_t size) { + uint8_t *temp = (uint8_t *)report; + + // Send as many full packets as possible + for (uint8_t i = 0; i < size / 8; i++) { + send_report_fragment(endpoint, temp, 8); + temp += 8; + } + + // Send any data left over + uint8_t remainder = size % 8; + if (remainder) { + send_report_fragment(endpoint, temp, remainder); } } @@ -144,18 +152,7 @@ void raw_hid_send(uint8_t *data, uint8_t length) { 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); + send_report(4, data, 32); } __attribute__((weak)) void raw_hid_receive(uint8_t *data, uint8_t length) { @@ -184,19 +181,6 @@ int8_t sendchar(uint8_t 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; @@ -213,16 +197,7 @@ void console_task(void) { 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(); + send_report(3, send_buf, CONSOLE_BUFFER_SIZE); } #endif @@ -231,10 +206,11 @@ void console_task(void) { *------------------------------------------------------------------*/ static uint8_t keyboard_leds(void); static void send_keyboard(report_keyboard_t *report); +static void send_nkro(report_nkro_t *report); static void send_mouse(report_mouse_t *report); static void send_extra(report_extra_t *report); -static host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_extra}; +static host_driver_t driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra}; host_driver_t *vusb_driver(void) { return &driver; @@ -245,65 +221,56 @@ static uint8_t keyboard_leds(void) { } 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; + if (!keyboard_protocol) { + send_report(1, &report->mods, 8); } else { - dprint("kbuf: full\n"); + send_report(1, report, sizeof(report_keyboard_t)); } - // NOTE: send key strokes of Macro - usbPoll(); - vusb_transfer_keyboard(); keyboard_report_sent = *report; } #ifndef KEYBOARD_SHARED_EP -# define usbInterruptIsReadyShared usbInterruptIsReady3 -# define usbSetInterruptShared usbSetInterrupt3 +# define MOUSE_IN_EPNUM 3 +# define SHARED_IN_EPNUM 3 #else -# define usbInterruptIsReadyShared usbInterruptIsReady -# define usbSetInterruptShared usbSetInterrupt +# define MOUSE_IN_EPNUM 1 +# define SHARED_IN_EPNUM 1 +#endif + +static void send_nkro(report_nkro_t *report) { +#ifdef NKRO_ENABLE + send_report(3, report, sizeof(report_nkro_t)); #endif +} static void send_mouse(report_mouse_t *report) { #ifdef MOUSE_ENABLE - if (usbInterruptIsReadyShared()) { - usbSetInterruptShared((void *)report, sizeof(report_mouse_t)); - } + send_report(MOUSE_IN_EPNUM, report, sizeof(report_mouse_t)); #endif } static void send_extra(report_extra_t *report) { #ifdef EXTRAKEY_ENABLE - if (usbInterruptIsReadyShared()) { - usbSetInterruptShared((void *)report, sizeof(report_extra_t)); - } + send_report(SHARED_IN_EPNUM, report, sizeof(report_extra_t)); #endif } void send_joystick(report_joystick_t *report) { #ifdef JOYSTICK_ENABLE - if (usbInterruptIsReadyShared()) { - usbSetInterruptShared((void *)report, sizeof(report_joystick_t)); - } + send_report(SHARED_IN_EPNUM, report, sizeof(report_joystick_t)); #endif } void send_digitizer(report_digitizer_t *report) { #ifdef DIGITIZER_ENABLE - if (usbInterruptIsReadyShared()) { - usbSetInterruptShared((void *)report, sizeof(report_digitizer_t)); - } + send_report(SHARED_IN_EPNUM, report, sizeof(report_digitizer_t)); #endif } void send_programmable_button(report_programmable_button_t *report) { #ifdef PROGRAMMABLE_BUTTON_ENABLE - if (usbInterruptIsReadyShared()) { - usbSetInterruptShared((void *)report, sizeof(report_programmable_button_t)); - } + send_report(SHARED_IN_EPNUM, report, sizeof(report_programmable_button_t)); #endif } @@ -319,30 +286,44 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) { usbRequest_t *rq = (void *)data; if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) { /* class request type */ - 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:"); - // Report Type: 0x02(Out)/ReportID: 0x00(none) && Interface: 0(keyboard) - 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; // to get data in usbFunctionWrite - } else { - dprint("UNKNOWN:"); + switch (rq->bRequest) { + case USBRQ_HID_GET_REPORT: + dprint("GET_REPORT:"); + if (rq->wIndex.word == KEYBOARD_INTERFACE) { + usbMsgPtr = (usbMsgPtr_t)&keyboard_report_sent; + return sizeof(keyboard_report_sent); + } + break; + case USBRQ_HID_GET_IDLE: + dprint("GET_IDLE:"); + usbMsgPtr = (usbMsgPtr_t)&keyboard_idle; + return 1; + case USBRQ_HID_GET_PROTOCOL: + dprint("GET_PROTOCOL:"); + usbMsgPtr = (usbMsgPtr_t)&keyboard_protocol; + return 1; + case USBRQ_HID_SET_REPORT: + dprint("SET_REPORT:"); + // Report Type: 0x02(Out)/ReportID: 0x00(none) && Interface: 0(keyboard) + 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; // to get data in usbFunctionWrite + case USBRQ_HID_SET_IDLE: + keyboard_idle = (rq->wValue.word & 0xFF00) >> 8; + dprintf("SET_IDLE: %02X", keyboard_idle); + break; + case USBRQ_HID_SET_PROTOCOL: + if (rq->wIndex.word == KEYBOARD_INTERFACE) { + keyboard_protocol = rq->wValue.word & 0xFF; + dprintf("SET_PROTOCOL: %02X", keyboard_protocol); + } + break; + default: + dprint("UNKNOWN:"); + break; } } else { dprint("VENDOR:"); @@ -454,6 +435,45 @@ const PROGMEM uchar shared_hid_report[] = { # define SHARED_REPORT_STARTED #endif +#ifdef NKRO_ENABLE + // NKRO report descriptor + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x06, // Usage (Keyboard) + 0xA1, 0x01, // Collection (Application) + 0x85, REPORT_ID_NKRO, // Report ID + // Modifiers (8 bits) + 0x05, 0x07, // Usage Page (Keyboard/Keypad) + 0x19, 0xE0, // Usage Minimum (Keyboard Left Control) + 0x29, 0xE7, // Usage Maximum (Keyboard Right GUI) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x95, 0x08, // Report Count (8) + 0x75, 0x01, // Report Size (1) + 0x81, 0x02, // Input (Data, Variable, Absolute) + // Keycodes + 0x05, 0x07, // Usage Page (Keyboard/Keypad) + 0x19, 0x00, // Usage Minimum (0) + 0x29, NKRO_REPORT_BITS * 8 - 1, // Usage Maximum + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x95, NKRO_REPORT_BITS * 8, // Report Count + 0x75, 0x01, // Report Size (1) + 0x81, 0x02, // Input (Data, Variable, Absolute) + + // Status LEDs (5 bits) + 0x05, 0x08, // Usage Page (LED) + 0x19, 0x01, // Usage Minimum (Num Lock) + 0x29, 0x05, // Usage Maximum (Kana) + 0x95, 0x05, // Report Count (5) + 0x75, 0x01, // Report Size (1) + 0x91, 0x02, // Output (Data, Variable, Absolute) + // LED padding (3 bits) + 0x95, 0x01, // Report Count (1) + 0x75, 0x03, // Report Size (3) + 0x91, 0x03, // Output (Constant) + 0xC0, // End Collection +#endif + #ifdef MOUSE_ENABLE // Mouse report descriptor 0x05, 0x01, // Usage Page (Generic Desktop) @@ -1024,7 +1044,7 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) { #endif break; case USBDESCR_HID: - switch (rq->wValue.bytes[0]) { + switch (rq->wIndex.word) { #ifndef KEYBOARD_SHARED_EP case KEYBOARD_INTERFACE: usbMsgPtr = (usbMsgPtr_t)&usbConfigurationDescriptor.keyboardHID; diff --git a/tmk_core/protocol/vusb/vusb.h b/tmk_core/protocol/vusb/vusb.h index c5cb27ded6..ae17e5e014 100644 --- a/tmk_core/protocol/vusb/vusb.h +++ b/tmk_core/protocol/vusb/vusb.h @@ -121,4 +121,3 @@ typedef struct usbConfigurationDescriptor { extern bool vusb_suspended; host_driver_t *vusb_driver(void); -void vusb_transfer_keyboard(void); |