summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt3
-rw-r--r--prj.conf22
-rw-r--r--src/ble.c136
-rw-r--r--src/ble.h4
-rw-r--r--src/endpoints.c40
-rw-r--r--src/endpoints.h1
-rw-r--r--src/hid.c56
-rw-r--r--src/hid.h107
-rw-r--r--src/hog.c136
-rw-r--r--src/hog.h9
-rw-r--r--src/main.c11
-rw-r--r--src/usb_hid.c152
-rw-r--r--src/usb_hid.h6
13 files changed, 523 insertions, 160 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 12b44c1..385000c 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 1e7300a..93cb7a7 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 0000000..006d424
--- /dev/null
+++ b/src/ble.c
@@ -0,0 +1,136 @@
+
+#include <settings/settings.h>
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/conn.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/uuid.h>
+#include <bluetooth/gatt.h>
+
+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 0000000..bec3a24
--- /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 c4cd416..402b1d4 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 1a72c32..cc200f1 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 0000000..8c42df5
--- /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 0000000..0f34df2
--- /dev/null
+++ b/src/hid.h
@@ -0,0 +1,107 @@
+#pragma once
+
+#include <usb/usb_device.h>
+#include <usb/class/usb_hid.h>
+
+#include <dt-bindings/zmk/keys.h>
+
+#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 0000000..4d623fe
--- /dev/null
+++ b/src/hog.c
@@ -0,0 +1,136 @@
+#include <settings/settings.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/gatt.h>
+
+#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 0000000..a1e4142
--- /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 8604989..708f4ff 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 e155536..80b2138 100644
--- a/src/usb_hid.c
+++ b/src/usb_hid.c
@@ -5,167 +5,23 @@
#include <usb/class/usb_hid.h>
#include <dt-bindings/zmk/keys.h>
+#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 1f331cd..4b55688 100644
--- a/src/usb_hid.h
+++ b/src/usb_hid.h
@@ -5,12 +5,10 @@
#include <usb/class/usb_hid.h>
#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