diff options
Diffstat (limited to 'tmk_core/protocol/chibios/usb_main.c')
-rw-r--r-- | tmk_core/protocol/chibios/usb_main.c | 83 |
1 files changed, 80 insertions, 3 deletions
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index cc282e6a9b..697566e27a 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -48,6 +48,10 @@ extern keymap_config_t keymap_config; #endif +#ifdef WEBUSB_ENABLE +# include "webusb.h" +#endif + #ifdef JOYSTICK_ENABLE # include "joystick.h" #endif @@ -166,6 +170,23 @@ static const USBEndpointConfig shared_ep_config = { }; #endif + +#ifdef WEBUSB_ENABLE +/** Microsoft OS 2.0 Descriptor. This is used by Windows to select the USB driver for the device. + * + * For WebUSB in Chrome, the correct driver is WinUSB, which is selected via CompatibleID. + * + * Additionally, while Chrome is built using libusb, a magic registry key needs to be set containing a GUID for + * the device. + */ +const MS_OS_20_Descriptor_t PROGMEM MS_OS_20_Descriptor = MS_OS_20_DESCRIPTOR; + +/** URL descriptor string. This is a UTF-8 string containing a URL excluding the prefix. At least one of these must be + * defined and returned when the Landing Page descriptor index is requested. + */ +const WebUSB_URL_Descriptor_t PROGMEM WebUSB_LandingPage = WEBUSB_URL_DESCRIPTOR(WEBUSB_LANDING_PAGE_URL); +#endif + #if STM32_USB_USE_OTG1 typedef struct { size_t queue_capacity_in; @@ -313,6 +334,9 @@ typedef struct { #ifdef VIRTSER_ENABLE usb_driver_config_t serial_driver; #endif +#ifdef WEBUSB_ENABLE + usb_driver_config_t webusb_driver; +#endif #ifdef JOYSTICK_ENABLE usb_driver_config_t joystick_driver; #endif @@ -356,6 +380,13 @@ static usb_driver_configs_t drivers = { .serial_driver = QMK_USB_DRIVER_CONFIG(CDC, CDC_NOTIFICATION_EPNUM, false), #endif +#ifdef WEBUSB_ENABLE +# define WEBUSB_IN_CAPACITY 4 +# define WEBUSB_OUT_CAPACITY 4 +# define WEBUSB_IN_MODE USB_EP_MODE_TYPE_INTR +# define WEBUSB_OUT_MODE USB_EP_MODE_TYPE_INTR + .webusb_driver = QMK_USB_DRIVER_CONFIG(WEBUSB, 0, false), +#endif #ifdef JOYSTICK_ENABLE # define JOYSTICK_IN_CAPACITY 4 # define JOYSTICK_OUT_CAPACITY 4 @@ -420,9 +451,9 @@ static inline void usb_event_suspend_handler(void) { static inline void usb_event_wakeup_handler(void) { suspend_wakeup_init(); #ifdef SLEEP_LED_ENABLE - sleep_led_disable(); - // NOTE: converters may not accept this - led_set(host_keyboard_leds()); + sleep_led_disable(); + // NOTE: converters may not accept this + led_set(host_keyboard_leds()); #endif /* SLEEP_LED_ENABLE */ } @@ -652,6 +683,27 @@ static bool usb_request_hook_cb(USBDriver *usbp) { } } +#ifdef WEBUSB_ENABLE + switch (usbp->setup[1]) { + case WEBUSB_VENDOR_CODE: + if (usbp->setup[4] == WebUSB_RTYPE_GetURL) { + if (usbp->setup[2] == WEBUSB_LANDING_PAGE_INDEX) { + usbSetupTransfer(usbp, (uint8_t *)&WebUSB_LandingPage, WebUSB_LandingPage.Header.Size, NULL); + return TRUE; + break; + } + } + break; + + case MS_OS_20_VENDOR_CODE: + if (usbp->setup[4] == MS_OS_20_DESCRIPTOR_INDEX) { + usbSetupTransfer(usbp, (uint8_t *)&MS_OS_20_Descriptor, MS_OS_20_Descriptor.Header.TotalLength, NULL); + return TRUE; + break; + } + break; + } +#endif /* 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])); @@ -1042,6 +1094,31 @@ void raw_hid_task(void) { #endif +#ifdef WEBUSB_ENABLE +void webusb_send(uint8_t *data, uint8_t length) { + if(chnWriteTimeout(&drivers.webusb_driver.driver, data, length, TIME_IMMEDIATE) != length){ + webusb_state.paired = false; + webusb_state.pairing = false; + } +} + + // Users should #include "raw_hid.h" in their own code + // and implement this function there. Leave this as weak linkage + // so users can opt to not handle data coming in. + +void webusb_task(void) { + uint8_t buffer[WEBUSB_EPSIZE]; + size_t size = 0; + do { + size_t size = chnReadTimeout(&drivers.webusb_driver.driver, buffer, sizeof(buffer), TIME_IMMEDIATE); + if (size > 0) { + webusb_receive(buffer, size); + } + } while (size > 0); +} + +#endif + #ifdef MIDI_ENABLE void send_midi_packet(MIDI_EventPacket_t *event) { chnWrite(&drivers.midi_driver.driver, (uint8_t *)event, sizeof(MIDI_EventPacket_t)); } |