From 73bea6218e6681c62a4cbe32f6dd1394f242fa66 Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Fri, 15 May 2020 09:41:06 -0400 Subject: [PATCH] Some initial BEL HoG support. --- CMakeLists.txt | 3 + prj.conf | 22 ++++++- src/ble.c | 136 +++++++++++++++++++++++++++++++++++++++++++ src/ble.h | 4 ++ src/endpoints.c | 40 ++++++++++++- src/endpoints.h | 1 + src/hid.c | 56 ++++++++++++++++++ src/hid.h | 107 ++++++++++++++++++++++++++++++++++ src/hog.c | 136 +++++++++++++++++++++++++++++++++++++++++++ src/hog.h | 9 +++ src/main.c | 11 ++-- src/usb_hid.c | 152 ++---------------------------------------------- src/usb_hid.h | 6 +- 13 files changed, 523 insertions(+), 160 deletions(-) create mode 100644 src/ble.c create mode 100644 src/ble.h create mode 100644 src/hid.c create mode 100644 src/hid.h create mode 100644 src/hog.c create mode 100644 src/hog.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 12b44c14..385000cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,10 @@ project(zmk) target_include_directories(app PRIVATE include) target_sources(app PRIVATE src/kscan.c) target_sources(app PRIVATE src/keymap.c) +target_sources(app PRIVATE src/hid.c) +target_sources(app PRIVATE src/ble.c) target_sources(app PRIVATE src/usb_hid.c) +target_sources(app PRIVATE src/hog.c) target_sources(app PRIVATE src/endpoints.c) target_sources(app PRIVATE src/main.c) target_sources(app PRIVATE src/handlers.c) diff --git a/prj.conf b/prj.conf index 1e7300a0..93cb7a78 100644 --- a/prj.conf +++ b/prj.conf @@ -1,9 +1,29 @@ CONFIG_KSCAN=y CONFIG_KSCAN_GPIO=y -# CONFIG_LOG=y # CONFIG_ZMK_KSCAN_LOG_LEVEL_DBG=y # CONFIG_ZMK_USB_HID_LOG_LEVEL_DBG=y CONFIG_USB=y CONFIG_USB_DEVICE_STACK=y CONFIG_USB_DEVICE_HID=y CONFIG_USB_DEVICE_PRODUCT="ZMK Firmware" +CONFIG_BT=y +CONFIG_BT_SMP=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_GATT_DIS=y +# HID GATT notifications sent this way are *not* picked up by Linux, and possibly others. +CONFIG_BT_GATT_NOTIFY_MULTIPLE=n +CONFIG_BT_GATT_BAS=y +CONFIG_BT_DEVICE_NAME="ZMK Keyboard" +CONFIG_BT_DEVICE_APPEARANCE=961 +CONFIG_BT_FIXED_PASSKEY=y + +# Incresed stack due to settings API usage +# CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 +# +# CONFIG_BT_SETTINGS=y +# CONFIG_FLASH=y +# CONFIG_FLASH_PAGE_LAYOUT=y +# CONFIG_FLASH_MAP=y +# CONFIG_NVS=y +# CONFIG_SETTINGS=y +# CONFIG_SETTINGS_NONE=n diff --git a/src/ble.c b/src/ble.c new file mode 100644 index 00000000..006d424d --- /dev/null +++ b/src/ble.c @@ -0,0 +1,136 @@ + +#include +#include +#include +#include +#include +#include + +static void connected(struct bt_conn *conn, u8_t err) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + if (err) + { + printk("Failed to connect to %s (%u)\n", addr, err); + return; + } + + printk("Connected %s\n", addr); + + // if (bt_conn_set_security(conn, BT_SECURITY_L0)) + // { + // printk("Failed to set security\n"); + // } +} + +static void disconnected(struct bt_conn *conn, u8_t reason) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + printk("Disconnected from %s (reason 0x%02x)\n", addr, reason); +} + +static void security_changed(struct bt_conn *conn, bt_security_t level, + enum bt_security_err err) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + if (!err) + { + printk("Security changed: %s level %u\n", addr, level); + } + else + { + printk("Security failed: %s level %u err %d\n", addr, level, + err); + } +} + +static struct bt_conn_cb conn_callbacks = { + .connected = connected, + .disconnected = disconnected, + .security_changed = security_changed, +}; + +static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + printk("Passkey for %s: %06u\n", addr, passkey); +} + +static void auth_cancel(struct bt_conn *conn) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + printk("Pairing cancelled: %s\n", addr); +} + +static struct bt_conn_auth_cb zmk_ble_auth_cb_display = { + .passkey_display = auth_passkey_display, + .passkey_entry = NULL, + .cancel = auth_cancel, +}; + +static const struct bt_data zmk_ble_ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA_BYTES(BT_DATA_UUID16_ALL, + 0x12, 0x18, /* HID Service */ + 0x0f, 0x18), /* Battery Service */ +}; + +static void zmk_ble_ready(int err) +{ + if (err) + { + printk("Bluetooth init failed (err %d)\n", err); + return; + } + + printk("Bluetooth initialized\n"); + + err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, zmk_ble_ad, ARRAY_SIZE(zmk_ble_ad), NULL, 0); + if (err) + { + printk("Advertising failed to start (err %d)\n", err); + return; + } +} + +int zmk_ble_init() +{ + if (IS_ENABLED(CONFIG_SETTINGS)) + { + settings_load(); + } + int err = bt_enable(zmk_ble_ready); + + if (err) + { + printk("BLUETOOTH FAILED"); + return err; + } + + // err = bt_passkey_set(1234); + if (err) + { + printk("Set passkey failed: %d\n", err); + return err; + } + + bt_conn_cb_register(&conn_callbacks); + bt_conn_auth_cb_register(&zmk_ble_auth_cb_display); + + return 0; +} diff --git a/src/ble.h b/src/ble.h new file mode 100644 index 00000000..bec3a24f --- /dev/null +++ b/src/ble.h @@ -0,0 +1,4 @@ + +#pragma once + +int zmk_ble_init(); \ No newline at end of file diff --git a/src/endpoints.c b/src/endpoints.c index c4cd4165..402b1d44 100644 --- a/src/endpoints.c +++ b/src/endpoints.c @@ -1,16 +1,52 @@ #include "endpoints.h" +#include "hid.h" #include "usb_hid.h" +#include "hog.h" + +int zmk_endpoints_init() +{ + int err; + + err = zmk_usb_hid_init(); + if (err) + { + printk("USB HID Init Failed\n"); + return err; + } + + err = zmk_hog_init(); + if (err) + { + printk("HOG Init Failed\n"); + return err; + } + + return 0; +} int zmk_endpoints_send_key_event(struct zmk_key_event key_event) { + struct zmk_hid_report *report; if (key_event.pressed) { - zmk_usb_hid_press_key(key_event.key); + zmk_hid_press_key(key_event.key); } else { - zmk_usb_hid_release_key(key_event.key); + zmk_hid_release_key(key_event.key); + } + + report = zmk_hid_get_report(); + + // if (zmk_usb_hid_send_report(report) != 0) + // { + // // LOG_DBG("USB Send Failed"); + // } + + if (zmk_hog_send_report(report) != 0) + { + // LOG_DBG("HID Over GATTP Send Failed"); } return 0; diff --git a/src/endpoints.h b/src/endpoints.h index 1a72c322..cc200f19 100644 --- a/src/endpoints.h +++ b/src/endpoints.h @@ -2,4 +2,5 @@ #include "keys.h" +int zmk_endpoints_init(); int zmk_endpoints_send_key_event(struct zmk_key_event key_event); \ No newline at end of file diff --git a/src/hid.c b/src/hid.c new file mode 100644 index 00000000..8c42df58 --- /dev/null +++ b/src/hid.c @@ -0,0 +1,56 @@ +#include "hid.h" + +static struct zmk_hid_report report = { + .modifiers = 0, + .keys = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + +#define KEY_OFFSET 0x02 +#define MAX_KEYS 6 + +/* +#define TOGGLE_BOOT_KEY(match, val) \ + for (int idx = 0; idx < MAX_KEYS; idx++) \ + { \ + if (report.boot.keys[idx + KEY_OFFSET] != match) \ + { \ + continue; \ + } \ + report.boot.keys[idx + KEY_OFFSET] = val; \ + break; \ + } +*/ + +#define TOGGLE_KEY(code, val) WRITE_BIT(report.keys[code / 8], code % 8, val) + +int zmk_hid_press_key(zmk_key code) +{ + if (code > ZMK_HID_MAX_KEYCODE) + { + return -EINVAL; + } + + // TOGGLE_BOOT_KEY(0U, code); + + TOGGLE_KEY(code, true); + + return 0; +}; + +int zmk_hid_release_key(zmk_key code) +{ + if (code > ZMK_HID_MAX_KEYCODE) + { + return -EINVAL; + } + + // TOGGLE_BOOT_KEY(code, 0U); + + TOGGLE_KEY(code, false); + + return 0; +}; + +struct zmk_hid_report *zmk_hid_get_report() +{ + return &report; +} \ No newline at end of file diff --git a/src/hid.h b/src/hid.h new file mode 100644 index 00000000..0f34df23 --- /dev/null +++ b/src/hid.h @@ -0,0 +1,107 @@ +#pragma once + +#include +#include + +#include + +#include "keys.h" + +#define ZMK_HID_MAX_KEYCODE KC_APP + +static const u8_t zmk_hid_report_desc[] = { + /* USAGE_PAGE (Generic Desktop) */ + HID_GI_USAGE_PAGE, + USAGE_GEN_DESKTOP, + /* USAGE (Keyboard) */ + HID_LI_USAGE, + USAGE_GEN_DESKTOP_KEYBOARD, + /* COLLECTION (Application) */ + HID_MI_COLLECTION, + COLLECTION_APPLICATION, + /* REPORT ID (1) */ + HID_GI_REPORT_ID, + 0x01, + /* USAGE_PAGE (Keypad) */ + HID_GI_USAGE_PAGE, + USAGE_GEN_DESKTOP_KEYPAD, + /* USAGE_MINIMUM (Keyboard LeftControl) */ + HID_LI_USAGE_MIN(1), + 0xE0, + /* USAGE_MAXIMUM (Keyboard Right GUI) */ + HID_LI_USAGE_MAX(1), + 0xE7, + /* LOGICAL_MINIMUM (0) */ + HID_GI_LOGICAL_MIN(1), + 0x00, + /* LOGICAL_MAXIMUM (1) */ + HID_GI_LOGICAL_MAX(1), + 0x01, + + /* REPORT_SIZE (1) */ + HID_GI_REPORT_SIZE, + 0x01, + /* REPORT_COUNT (8) */ + HID_GI_REPORT_COUNT, + 0x08, + /* INPUT (Data,Var,Abs) */ + HID_MI_INPUT, + 0x02, + + /* USAGE_PAGE (Keypad) */ + HID_GI_USAGE_PAGE, + USAGE_GEN_DESKTOP_KEYPAD, + /* LOGICAL_MINIMUM (0) */ + HID_GI_LOGICAL_MIN(1), + 0x00, + /* LOGICAL_MAXIMUM (101) */ + HID_GI_LOGICAL_MAX(1), + 0x01, + /* USAGE_MINIMUM (Reserved) */ + HID_LI_USAGE_MIN(1), + 0x00, + /* USAGE_MAXIMUM (Keyboard Application) */ + HID_LI_USAGE_MAX(1), + ZMK_HID_MAX_KEYCODE, + /* REPORT_SIZE (8) */ + HID_GI_REPORT_SIZE, + 0x01, + /* REPORT_COUNT (6) */ + HID_GI_REPORT_COUNT, + ZMK_HID_MAX_KEYCODE + 1, + /* INPUT (Data,Ary,Abs) */ + HID_MI_INPUT, + 0x02, + /* USAGE_PAGE (Keypad) */ + HID_GI_USAGE_PAGE, + USAGE_GEN_DESKTOP_KEYPAD, + /* REPORT_SIZE (8) */ + HID_GI_REPORT_SIZE, + 0x02, + /* REPORT_COUNT (6) */ + HID_GI_REPORT_COUNT, + 0x01, + /* INPUT (Cnst,Var,Abs) */ + HID_MI_INPUT, + 0x03, + /* END_COLLECTION */ + HID_MI_COLLECTION_END, +}; + +// struct zmk_hid_boot_report +// { +// u8_t modifiers; +// u8_t _unused; +// u8_t keys[6]; +// } __packed; + +struct zmk_hid_report +{ + u8_t modifiers; + u8_t keys[13]; +} __packed; + +int zmk_hid_press_key(zmk_key key); +int zmk_hid_release_key(zmk_key key); + +struct zmk_hid_report *zmk_hid_get_report(); \ No newline at end of file diff --git a/src/hog.c b/src/hog.c new file mode 100644 index 00000000..4d623fe3 --- /dev/null +++ b/src/hog.c @@ -0,0 +1,136 @@ +#include + +#include +#include + +#include "ble.h" +#include "hog.h" +#include "hid.h" + +int zmk_hog_init() +{ + return zmk_ble_init(); +} + +enum +{ + HIDS_REMOTE_WAKE = BIT(0), + HIDS_NORMALLY_CONNECTABLE = BIT(1), +}; + +struct hids_info +{ + u16_t version; /* version number of base USB HID Specification */ + u8_t code; /* country HID Device hardware is localized for. */ + u8_t flags; +} __packed; + +struct hids_report +{ + u8_t id; /* report id */ + u8_t type; /* report type */ +} __packed; + +static struct hids_info info = { + .version = 0x0000, + .code = 0x00, + .flags = HIDS_NORMALLY_CONNECTABLE & HIDS_REMOTE_WAKE, +}; + +enum +{ + HIDS_INPUT = 0x01, + HIDS_OUTPUT = 0x02, + HIDS_FEATURE = 0x03, +}; + +static struct hids_report input = { + .id = 0x01, + .type = HIDS_INPUT, +}; + +static bool host_requests_notification = false; +static u8_t ctrl_point; +// static u8_t proto_mode; + +static ssize_t read_hids_info(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, u16_t len, u16_t offset) +{ + return bt_gatt_attr_read(conn, attr, buf, len, offset, attr->user_data, sizeof(struct hids_info)); +} + +static ssize_t read_hids_report_ref(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, u16_t len, u16_t offset) +{ + return bt_gatt_attr_read(conn, attr, buf, len, offset, attr->user_data, sizeof(struct hids_report)); +} + +static ssize_t read_hids_report_map(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, u16_t len, u16_t offset) +{ + return bt_gatt_attr_read(conn, attr, buf, len, offset, zmk_hid_report_desc, sizeof(zmk_hid_report_desc)); +} + +static ssize_t read_hids_input_report(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, u16_t len, u16_t offset) +{ + struct zmk_hid_report *report = zmk_hid_get_report(); + return bt_gatt_attr_read(conn, attr, buf, len, offset, report, sizeof(struct zmk_hid_report)); +} + +// static ssize_t write_proto_mode(struct bt_conn *conn, +// const struct bt_gatt_attr *attr, +// const void *buf, u16_t len, u16_t offset, +// u8_t flags) +// { +// printk("PROTO CHANGED\n"); +// return 0; +// } + +static void input_ccc_changed(const struct bt_gatt_attr *attr, u16_t value) +{ + host_requests_notification = (value == BT_GATT_CCC_NOTIFY) ? 1 : 0; +} + +static ssize_t write_ctrl_point(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + const void *buf, u16_t len, u16_t offset, + u8_t flags) +{ + u8_t *value = attr->user_data; + + if (offset + len > sizeof(ctrl_point)) + { + return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); + } + + memcpy(value + offset, buf, len); + + return len; +} + +/* HID Service Declaration */ +BT_GATT_SERVICE_DEFINE(hog_svc, + BT_GATT_PRIMARY_SERVICE(BT_UUID_HIDS), + // BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_PROTOCOL_MODE, BT_GATT_CHRC_WRITE_WITHOUT_RESP, + // BT_GATT_PERM_WRITE, NULL, write_proto_mode, &proto_mode), + BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_INFO, BT_GATT_CHRC_READ, + BT_GATT_PERM_READ, read_hids_info, NULL, &info), + BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT_MAP, BT_GATT_CHRC_READ, + BT_GATT_PERM_READ, read_hids_report_map, NULL, NULL), + + BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT, + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ_AUTHEN, + // BT_GATT_PERM_READ, + read_hids_input_report, NULL, NULL), + BT_GATT_CCC(input_ccc_changed, + BT_GATT_PERM_READ_AUTHEN | BT_GATT_PERM_WRITE_AUTHEN), + // BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), + BT_GATT_DESCRIPTOR(BT_UUID_HIDS_REPORT_REF, BT_GATT_PERM_READ, + read_hids_report_ref, NULL, &input), + BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_CTRL_POINT, + BT_GATT_CHRC_WRITE_WITHOUT_RESP, + BT_GATT_PERM_WRITE, + NULL, write_ctrl_point, &ctrl_point)); + +int zmk_hog_send_report(struct zmk_hid_report *report) +{ + return bt_gatt_notify(NULL, &hog_svc.attrs[5], report, sizeof(struct zmk_hid_report)); +}; diff --git a/src/hog.h b/src/hog.h new file mode 100644 index 00000000..a1e4142e --- /dev/null +++ b/src/hog.h @@ -0,0 +1,9 @@ + +#pragma once + +#include "keys.h" +#include "hid.h" + +int zmk_hog_init(); + +int zmk_hog_send_report(struct zmk_hid_report *report); \ No newline at end of file diff --git a/src/main.c b/src/main.c index 8604989c..708f4ff4 100644 --- a/src/main.c +++ b/src/main.c @@ -10,20 +10,21 @@ #include "zmk.h" #include "kscan.h" -#include "usb_hid.h" +#include "endpoints.h" #define ZMK_KSCAN_DEV DT_LABEL(ZMK_MATRIX_NODE_ID) + void main(void) { printk("Welcome to ZMK!\n"); - if (zmk_kscan_init(ZMK_KSCAN_DEV) != 0) { - printk("Keyboard Scan Init Failed\n"); + if (zmk_kscan_init(ZMK_KSCAN_DEV) != 0) + { return; } - if (zmk_usb_hid_init() < 0) { - printk("USB HID Init Failed\n"); + if (zmk_endpoints_init()) + { return; } } diff --git a/src/usb_hid.c b/src/usb_hid.c index e155536b..80b21388 100644 --- a/src/usb_hid.c +++ b/src/usb_hid.c @@ -5,167 +5,23 @@ #include #include +#include "hid.h" #include "keymap.h" LOG_MODULE_REGISTER(zmk_usb_hid, CONFIG_ZMK_USB_HID_LOG_LEVEL); -#define MAX_KEYCODE KC_APP - -static const u8_t hid_report_desc[] = { - /* USAGE_PAGE (Generic Desktop) */ - HID_GI_USAGE_PAGE, - USAGE_GEN_DESKTOP, - /* USAGE (Keyboard) */ - HID_LI_USAGE, - USAGE_GEN_DESKTOP_KEYBOARD, - /* COLLECTION (Application) */ - HID_MI_COLLECTION, - COLLECTION_APPLICATION, - /* USAGE_PAGE (Keypad) */ - HID_GI_USAGE_PAGE, - USAGE_GEN_DESKTOP_KEYPAD, - /* USAGE_MINIMUM (Keyboard LeftControl) */ - HID_LI_USAGE_MIN(1), - 0xE0, - /* USAGE_MAXIMUM (Keyboard Right GUI) */ - HID_LI_USAGE_MAX(1), - 0xE7, - /* LOGICAL_MINIMUM (0) */ - HID_GI_LOGICAL_MIN(1), - 0x00, - /* LOGICAL_MAXIMUM (1) */ - HID_GI_LOGICAL_MAX(1), - 0x01, - /* REPORT_SIZE (1) */ - HID_GI_REPORT_SIZE, - 0x01, - /* REPORT_COUNT (8) */ - HID_GI_REPORT_COUNT, - 0x08, - /* INPUT (Data,Var,Abs) */ - HID_MI_INPUT, - 0x02, - /* USAGE_PAGE (Keypad) */ - HID_GI_USAGE_PAGE, - USAGE_GEN_DESKTOP_KEYPAD, - /* REPORT_SIZE (8) */ - HID_GI_REPORT_SIZE, - 0x08, - /* REPORT_COUNT (1) */ - HID_GI_REPORT_COUNT, - 0x07, - /* INPUT (Cnst,Var,Abs) */ - HID_MI_INPUT, - 0x03, - - /* USAGE_PAGE (Keypad) */ - HID_GI_USAGE_PAGE, - USAGE_GEN_DESKTOP_KEYPAD, - /* LOGICAL_MINIMUM (0) */ - HID_GI_LOGICAL_MIN(1), - 0x00, - /* LOGICAL_MAXIMUM (101) */ - HID_GI_LOGICAL_MAX(1), - 0x01, - /* USAGE_MINIMUM (Reserved) */ - HID_LI_USAGE_MIN(1), - 0x00, - /* USAGE_MAXIMUM (Keyboard Application) */ - HID_LI_USAGE_MAX(1), - MAX_KEYCODE, - /* REPORT_SIZE (8) */ - HID_GI_REPORT_SIZE, - 0x01, - /* REPORT_COUNT (6) */ - HID_GI_REPORT_COUNT, - MAX_KEYCODE + 1, - /* INPUT (Data,Ary,Abs) */ - HID_MI_INPUT, - 0x02, - /* USAGE_PAGE (Keypad) */ - HID_GI_USAGE_PAGE, - USAGE_GEN_DESKTOP_KEYPAD, - /* REPORT_SIZE (8) */ - HID_GI_REPORT_SIZE, - 0x02, - /* REPORT_COUNT (6) */ - HID_GI_REPORT_COUNT, - 0x01, - /* INPUT (Cnst,Var,Abs) */ - HID_MI_INPUT, - 0x03, - /* END_COLLECTION */ - HID_MI_COLLECTION_END, -}; - static enum usb_dc_status_code usb_status; static struct device *hid_dev; -struct boot_report -{ - u8_t modifiers; - u8_t _unused; - u8_t keys[6]; -} __packed; - -struct extended_report -{ - u8_t keys[13]; -} __packed; - -struct hid_report -{ - struct boot_report boot; - struct extended_report extended; -} __packed report; - -#define KEY_OFFSET 0x02 -#define MAX_KEYS 6 - -#define TOGGLE_BOOT_KEY(match, val) \ - for (int idx = 0; idx < MAX_KEYS; idx++) \ - { \ - if (report.boot.keys[idx + KEY_OFFSET] != match) \ - { \ - continue; \ - } \ - report.boot.keys[idx + KEY_OFFSET] = val; \ - break; \ - } - -#define TOGGLE_EXT_KEY(code, val) WRITE_BIT(report.extended.keys[code / 8], code % 8, val) -int zmk_usb_hid_press_key(zmk_key code) +int zmk_usb_hid_send_report(const struct zmk_hid_report *report) { if (usb_status == USB_DC_SUSPEND) { return usb_wakeup_request(); } - if (code > MAX_KEYCODE) - { - return -EINVAL; - } - - TOGGLE_BOOT_KEY(0U, code); - - TOGGLE_EXT_KEY(code, true); - - return hid_int_ep_write(hid_dev, (u8_t *)&report, sizeof(report), NULL); -} - -int zmk_usb_hid_release_key(zmk_key code) -{ - if (code > MAX_KEYCODE) - { - return -EINVAL; - } - - TOGGLE_BOOT_KEY(code, 0U); - - TOGGLE_EXT_KEY(code, false); - - return hid_int_ep_write(hid_dev, (u8_t *)&report, sizeof(report), NULL); + return hid_int_ep_write(hid_dev, (u8_t *)report, sizeof(struct zmk_hid_report), NULL); } void usb_hid_status_cb(enum usb_dc_status_code status, const u8_t *params) @@ -185,7 +41,7 @@ int zmk_usb_hid_init() } usb_hid_register_device(hid_dev, - hid_report_desc, sizeof(hid_report_desc), + zmk_hid_report_desc, sizeof(zmk_hid_report_desc), NULL); usb_hid_init(hid_dev); diff --git a/src/usb_hid.h b/src/usb_hid.h index 1f331cde..4b55688e 100644 --- a/src/usb_hid.h +++ b/src/usb_hid.h @@ -5,12 +5,10 @@ #include #include "keys.h" +#include "hid.h" int zmk_usb_hid_init(); -// TODO: Modifiers! - -int zmk_usb_hid_press_key(zmk_key key); -int zmk_usb_hid_release_key(zmk_key key); +int zmk_usb_hid_send_report(const struct zmk_hid_report *report); #endif