summaryrefslogtreecommitdiff
path: root/tmk_core/protocol/chibios/usb_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/protocol/chibios/usb_main.c')
-rw-r--r--tmk_core/protocol/chibios/usb_main.c83
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 ac46a9312b..14de2fc8cc 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -49,6 +49,10 @@
extern keymap_config_t keymap_config;
#endif
+#ifdef WEBUSB_ENABLE
+# include "webusb.h"
+#endif
+
#ifdef JOYSTICK_ENABLE
# include "joystick.h"
#endif
@@ -172,6 +176,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;
@@ -319,6 +340,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
@@ -362,6 +386,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
@@ -428,9 +459,9 @@ static inline void usb_event_wakeup_handler(void) {
suspend_wakeup_init();
usb_device_state_set_resume(USB_DRIVER.configuration != 0, USB_DRIVER.configuration);
#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 */
}
@@ -670,6 +701,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]));
@@ -1076,6 +1128,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)); }