summaryrefslogtreecommitdiff
path: root/tmk_core/protocol/chibios
diff options
context:
space:
mode:
authorFlorian Didron <fd@librem.one>2019-11-04 18:50:06 +0900
committerFlorian Didron <fdidron@users.noreply.github.com>2019-12-06 08:20:51 +0900
commitae96eed205c736275b6498ba50946e99a0a35485 (patch)
tree1aaa52dc94bd351a0654cf977c9f33240a700caf /tmk_core/protocol/chibios
parent560d1c53851e5c3d45c5a0f5e16a925ee21a4396 (diff)
feat: adds webusb
Diffstat (limited to 'tmk_core/protocol/chibios')
-rw-r--r--tmk_core/protocol/chibios/usb_main.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index c8a6bbb43f..e2440601e3 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -151,6 +151,22 @@ 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
+
typedef struct {
size_t queue_capacity_in;
size_t queue_capacity_out;
@@ -233,6 +249,9 @@ typedef struct {
#ifdef VIRTSER_ENABLE
usb_driver_config_t serial_driver;
#endif
+#ifdef WEBUSB_ENABLE
+ usb_driver_config_t webusb_driver;
+#endif
};
usb_driver_config_t array[0];
};
@@ -269,6 +288,14 @@ static usb_driver_configs_t drivers = {
# define CDC_OUT_MODE USB_EP_MODE_TYPE_BULK
.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
};
#define NUM_USB_DRIVERS (sizeof(drivers) / sizeof(usb_driver_config_t))
@@ -496,6 +523,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]));
@@ -817,6 +865,28 @@ void raw_hid_task(void) {
#endif
+#ifdef WEBUSB_ENABLE
+void webusb_send(uint8_t *data, uint8_t length) { chnWrite(&drivers.webusb_driver.driver, data, length); }
+
+__attribute__((weak)) void webusb_receive(uint8_t *data, uint8_t length) {
+ // 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)); }