From 523e7f702faa8b08ae2d61b979868d2d02ed4ecc Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Fri, 1 May 2020 23:10:11 -0400 Subject: [PATCH] Message queue and work item for process scan events. * Prep for using ISR for kscan GPIO, by moving event process into a work item. --- Kconfig | 7 +++++++ src/kscan.c | 51 ++++++++++++++++++++++++++++++++++++++++++++------- src/kscan.h | 4 ++++ 3 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 Kconfig diff --git a/Kconfig b/Kconfig new file mode 100644 index 00000000..89dc9116 --- /dev/null +++ b/Kconfig @@ -0,0 +1,7 @@ +mainmenu "ZMK Firmware" + +config ZMK_KSCAN_EVENT_QUEUE_SIZE + int "Size of the event queue for KSCAN events to buffer events" + default 4 + +source "Kconfig.zephyr" diff --git a/src/kscan.c b/src/kscan.c index 244bedcf..268fac09 100644 --- a/src/kscan.c +++ b/src/kscan.c @@ -6,24 +6,61 @@ #include #include -#include #include +#include -static void zmk_kscan_callback(struct device *dev, u32_t row, u32_t column, bool pressed) { - printk("Row: %d, col: %d, pressed: %s\n", row, column, (pressed ? "true" : "false")); - // TODO: Push this to a message box, and then trigger a work item! +LOG_MODULE_REGISTER(zmk_kscan, CONFIG_ZMK_KSCAN_LOG_LEVEL); + +#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); } -int zmk_kscan_init(char* name) { +void zmk_kscan_process_msgq(struct k_work *item) +{ + struct zmk_kscan_event ev; + printk("process messages!\n"); + + while(k_msgq_get(&zmk_kscan_msgq, &ev, K_NO_WAIT) == 0) { + bool pressed = (ev.state == ZMK_KSCAN_EVENT_STATE_PRESSED); + printk("Row: %d, col: %d, pressed: %s\n", ev.row, ev.column, (pressed ? "true" : "false")); + } +} + +int zmk_kscan_init(char* name) +{ struct device *dev = device_get_binding(name); if (dev == NULL) { - printk("NO DEVICE!\n"); + LOG_ERR("Failed to get the KSCAN device"); return -EINVAL; } return 0; - kscan_config(dev, zmk_kscan_callback); + k_work_init(&msg_processor.work, zmk_kscan_process_msgq); + kscan_config(dev, zmk_kscan_callback); kscan_enable_callback(dev); } diff --git a/src/kscan.h b/src/kscan.h index 18f08a6a..7f640316 100644 --- a/src/kscan.h +++ b/src/kscan.h @@ -1,2 +1,6 @@ +#ifndef ZMK_KSCAN_H +#define ZMK_KSCAN_H int zmk_kscan_init(char *name); + +#endif