summaryrefslogtreecommitdiff
path: root/app/src/usb.c
diff options
context:
space:
mode:
authorPete Johanson <peter@peterjohanson.com>2020-10-04 18:18:44 -0400
committerPete Johanson <peter@peterjohanson.com>2020-10-04 21:56:09 -0400
commitbbf5a5905a973d6d23457d2e7bf15bf6bac234c3 (patch)
tree93dcaaf0c3ccde9e0c6d3e8d192bc7e8ed0e32eb /app/src/usb.c
parente6d9134005588adc0d6326c7b8132b7832719990 (diff)
refactor(usb): Report USB status w/o HID output.
Diffstat (limited to 'app/src/usb.c')
-rw-r--r--app/src/usb.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/app/src/usb.c b/app/src/usb.c
new file mode 100644
index 0000000..434b3d4
--- /dev/null
+++ b/app/src/usb.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2020 The ZMK Contributors
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <device.h>
+#include <init.h>
+
+#include <usb/usb_device.h>
+#include <usb/class/usb_hid.h>
+#include <dt-bindings/zmk/keys.h>
+
+#include <zmk/hid.h>
+#include <zmk/keymap.h>
+
+LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
+
+static enum usb_dc_status_code usb_status = USB_DC_UNKNOWN;
+
+#ifdef CONFIG_ZMK_USB
+
+static struct device *hid_dev;
+
+static K_SEM_DEFINE(hid_sem, 1, 1);
+
+static void in_ready_cb(void) { k_sem_give(&hid_sem); }
+
+static const struct hid_ops ops = {
+ .int_in_ready = in_ready_cb,
+};
+
+int zmk_usb_hid_send_report(const u8_t *report, size_t len) {
+ switch (usb_status) {
+ case USB_DC_SUSPEND:
+ return usb_wakeup_request();
+ case USB_DC_ERROR:
+ case USB_DC_RESET:
+ case USB_DC_DISCONNECTED:
+ case USB_DC_UNKNOWN:
+ return -ENODEV;
+ default:
+ k_sem_take(&hid_sem, K_MSEC(30));
+ int err = hid_int_ep_write(hid_dev, report, len, NULL);
+
+ if (err) {
+ k_sem_give(&hid_sem);
+ }
+
+ return err;
+ }
+}
+
+#endif /* CONFIG_ZMK_USB */
+
+enum usb_dc_status_code zmk_usb_get_status() { return usb_status; }
+
+void usb_status_cb(enum usb_dc_status_code status, const u8_t *params) { usb_status = status; };
+
+static int zmk_usb_init(struct device *_arg) {
+ int usb_enable_ret;
+
+#ifdef CONFIG_ZMK_USB
+ hid_dev = device_get_binding("HID_0");
+ if (hid_dev == NULL) {
+ LOG_ERR("Unable to locate HID device");
+ return -EINVAL;
+ }
+
+ usb_hid_register_device(hid_dev, zmk_hid_report_desc, sizeof(zmk_hid_report_desc), &ops);
+
+ usb_hid_init(hid_dev);
+
+#endif /* CONFIG_ZMK_USB */
+
+ usb_enable_ret = usb_enable(usb_status_cb);
+
+ if (usb_enable_ret != 0) {
+ LOG_ERR("Unable to enable USB");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+SYS_INIT(zmk_usb_init, APPLICATION, CONFIG_ZMK_USB_INIT_PRIORITY);