summaryrefslogtreecommitdiff
path: root/app/src/kscan.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/kscan.c')
-rw-r--r--app/src/kscan.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/app/src/kscan.c b/app/src/kscan.c
new file mode 100644
index 0000000..1f54a14
--- /dev/null
+++ b/app/src/kscan.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2020 Peter Johanson
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <zephyr.h>
+#include <device.h>
+#include <drivers/kscan.h>
+#include <logging/log.h>
+
+LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
+
+#include <zmk/keymap.h>
+#include <zmk/handlers.h>
+
+#define ZMK_KSCAN_EVENT_STATE_PRESSED 0
+#define ZMK_KSCAN_EVENT_STATE_RELEASED 1
+
+struct zmk_kscan_event
+{
+ u32_t row;
+ u32_t column;
+ u32_t state;
+};
+
+struct zmk_kscan_msg_processor
+{
+ struct k_work work;
+} msg_processor;
+
+K_MSGQ_DEFINE(zmk_kscan_msgq, sizeof(struct zmk_kscan_event), CONFIG_ZMK_KSCAN_EVENT_QUEUE_SIZE, 4);
+
+static void zmk_kscan_callback(struct device *dev, u32_t row, u32_t column, bool pressed)
+{
+ struct zmk_kscan_event ev = {
+ .row = row,
+ .column = column,
+ .state = (pressed ? ZMK_KSCAN_EVENT_STATE_PRESSED : ZMK_KSCAN_EVENT_STATE_RELEASED)};
+
+ k_msgq_put(&zmk_kscan_msgq, &ev, K_NO_WAIT);
+ k_work_submit(&msg_processor.work);
+}
+
+void zmk_kscan_process_msgq(struct k_work *item)
+{
+ struct zmk_kscan_event ev;
+
+ while (k_msgq_get(&zmk_kscan_msgq, &ev, K_NO_WAIT) == 0)
+ {
+ bool pressed = (ev.state == ZMK_KSCAN_EVENT_STATE_PRESSED);
+ zmk_key key = zmk_keymap_keycode_from_position(ev.row, ev.column);
+ struct zmk_key_event kev = (struct zmk_key_event){.row = ev.row, .column = ev.column, .key = key, .pressed = pressed};
+
+ LOG_DBG("Row: %d, col: %d, key: %d, pressed: %s\n", ev.row, ev.column, key, (pressed ? "true" : "false"));
+ zmk_handle_key(kev);
+ }
+}
+
+int zmk_kscan_init(char *name)
+{
+ struct device *dev = device_get_binding(name);
+ if (dev == NULL)
+ {
+ LOG_ERR("Failed to get the KSCAN device");
+ return -EINVAL;
+ }
+
+ k_work_init(&msg_processor.work, zmk_kscan_process_msgq);
+
+ kscan_config(dev, zmk_kscan_callback);
+ kscan_enable_callback(dev);
+
+ return 0;
+}