summaryrefslogtreecommitdiff
path: root/app/src
diff options
context:
space:
mode:
Diffstat (limited to 'app/src')
-rw-r--r--app/src/behaviors/behavior_key_press.c66
-rw-r--r--app/src/behaviors/behavior_reset.c51
-rw-r--r--app/src/keymap.c93
-rw-r--r--app/src/kscan.c9
4 files changed, 174 insertions, 45 deletions
diff --git a/app/src/behaviors/behavior_key_press.c b/app/src/behaviors/behavior_key_press.c
new file mode 100644
index 0000000..b9d0ff0
--- /dev/null
+++ b/app/src/behaviors/behavior_key_press.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2020 Peter Johanson <peter@peterjohanson.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#define DT_DRV_COMPAT zmk_behavior_key_press
+
+#include <device.h>
+#include <drivers/behavior.h>
+#include <logging/log.h>
+
+LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
+
+struct behavior_key_press_config { };
+struct behavior_key_press_data { };
+
+static int behavior_key_press_init(struct device *dev)
+{
+ return 0;
+};
+
+
+// They keycode is passed by the "keymap" based on the parameter created as part of the assignment.
+// Other drivers instead might activate a layer, update the consumer page state, or update the RGB state, etc.
+// Returns:
+// * > 0 - indicate successful processing, and halt further handling,
+// * 0 - Indicate successful processing, and continue propagation.
+// * < 0 - Indicate error processing, report and halt further propagation.
+static int on_position_pressed(struct device *dev, u32_t keycode, u32_t _)
+{
+ // Invoking this triggers a *new* event, that can be linked to other behaviours.
+ //return zmk_key_state_press(u32_t keycode);
+ return 0;
+}
+
+
+// They keycode is passed by the "keymap" based on the parameter created as part of the assignment.
+static int on_position_released(struct device *dev, u32_t keycode, u32_t _)
+{
+ // Invoking this triggers a *new* event, that can will be handled by other behaviors
+ // This is the "command" piece. Which could be better/richer, but captures essence here.
+ // return zmk_key_state_release(u32_t keycode);
+ return 0;
+}
+
+static const struct behavior_driver_api behavior_key_press_driver_api = {
+ // These callbacks are all optional, and define which kinds of events the behavior can handle.
+ // They can reference local functions defined here, or shared event handlers.
+ .position_pressed = on_position_pressed,
+ .position_released = on_position_released
+ // Other optional callbacks a behavior can implement
+ // .on_mouse_moved
+ // .on_sensor_data - Any behaviour that wants to be linked to a censor can implement this behavior
+};
+
+
+static const struct behavior_key_press_config behavior_key_press_config = {};
+
+static struct behavior_key_press_data behavior_key_press_data;
+
+DEVICE_AND_API_INIT(behavior_key_press, DT_INST_LABEL(0), behavior_key_press_init,
+ &behavior_key_press_data,
+ &behavior_key_press_config,
+ APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
+ &behavior_key_press_driver_api);
diff --git a/app/src/behaviors/behavior_reset.c b/app/src/behaviors/behavior_reset.c
new file mode 100644
index 0000000..1609fad
--- /dev/null
+++ b/app/src/behaviors/behavior_reset.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2020 Peter Johanson <peter@peterjohanson.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#define DT_DRV_COMPAT zmk_behavior_reset
+
+#include <device.h>
+#include <power/reboot.h>
+#include <drivers/behavior.h>
+#include <logging/log.h>
+
+LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
+
+struct behavior_reset_config { };
+struct behavior_reset_data { };
+
+static int behavior_reset_init(struct device *dev)
+{
+ return 0;
+};
+
+static int on_position_pressed(struct device *dev, u32_t _param1, u32_t _param2)
+{
+ // TODO: Correct magic code for going into DFU?
+ // See https://github.com/adafruit/Adafruit_nRF52_Bootloader/blob/d6b28e66053eea467166f44875e3c7ec741cb471/src/main.c#L107
+ sys_reboot(0);
+ return 0;
+}
+
+static int on_position_released(struct device *dev, u32_t _param1, u32_t _param2)
+{
+ return 0;
+}
+
+static const struct behavior_driver_api behavior_reset_driver_api = {
+ .position_pressed = on_position_pressed,
+ .position_released = on_position_released
+};
+
+
+static const struct behavior_reset_config behavior_reset_config = {};
+
+static struct behavior_reset_data behavior_reset_data;
+
+DEVICE_AND_API_INIT(behavior_reset, DT_INST_LABEL(0), behavior_reset_init,
+ &behavior_reset_data,
+ &behavior_reset_config,
+ APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
+ &behavior_reset_driver_api); \ No newline at end of file
diff --git a/app/src/keymap.c b/app/src/keymap.c
index 1cb705e..386de81 100644
--- a/app/src/keymap.c
+++ b/app/src/keymap.c
@@ -3,22 +3,48 @@
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/keymap.h>
#include <dt-bindings/zmk/matrix-transform.h>
+#include <drivers/behavior.h>
#include <sys/util.h>
static u32_t zmk_keymap_layer_state = 0;
static u8_t zmk_keymap_layer_default = 0;
+struct zmk_behavior_binding {
+ char *behavior_dev;
+ u32_t param1;
+ u32_t param2;
+};
+
+#define ZMK_KEYMAP_NODE DT_CHOSEN(zmk_keymap)
+#define ZMK_KEYMAP_LAYERS_LEN DT_PROP_LEN(ZMK_KEYMAP_NODE, layers)
+
+#define LAYER_NODE(l) DT_PHANDLE_BY_IDX(ZMK_KEYMAP_NODE, layers, l)
+
+#define BINDING_FOR_IDX(layer,idx) \
+ { .behavior_dev = DT_LABEL(DT_PHANDLE_BY_IDX(DT_PHANDLE_BY_IDX(ZMK_KEYMAP_NODE, layers, layer), bindings, idx)), \
+ .param1 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(LAYER_NODE(layer), bindings, idx, param1), (0), (DT_PHA_BY_IDX(LAYER_NODE(layer), bindings, idx, param1))), \
+ .param2 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(LAYER_NODE(layer), bindings, idx, param2), (0), (DT_PHA_BY_IDX(LAYER_NODE(layer), bindings, idx, param2))), \
+ }
+
#if DT_NODE_HAS_PROP(ZMK_KEYMAP_NODE, transform)
#define ZMK_KEYMAP_TRANSFORM_NODE DT_PHANDLE(ZMK_KEYMAP_NODE, transform)
#define ZMK_KEYMAP_LEN DT_PROP_LEN(ZMK_KEYMAP_TRANSFORM_NODE, map)
#define _TRANSFORM_ENTRY(i, l) \
- [(KT_ROW(DT_PROP_BY_IDX(ZMK_KEYMAP_TRANSFORM_NODE, map, i)) * ZMK_MATRIX_COLS) + KT_COL(DT_PROP_BY_IDX(ZMK_KEYMAP_TRANSFORM_NODE, map, i))] = DT_PROP_BY_IDX(DT_PHANDLE_BY_IDX(ZMK_KEYMAP_NODE, layers, l), keys, i),
+ [(KT_ROW(DT_PROP_BY_IDX(ZMK_KEYMAP_TRANSFORM_NODE, map, i)) * ZMK_MATRIX_COLS) + KT_COL(DT_PROP_BY_IDX(ZMK_KEYMAP_TRANSFORM_NODE, map, i))] = BINDING_FOR_IDX(l,i),
+
+#else
+
+#define ZMK_KEYMAP_LEN DT_PROP_LEN(ZMK_KEYMAP_NODE, bindings)
+#define _TRANSFORM_ENTRY(i, l) \
+ BINDING_FOR_IDX(l,i),
+
+#endif
#define TRANSFORMED_LAYER(idx) \
- { UTIL_LISTIFY(ZMK_KEYMAP_LEN, _TRANSFORM_ENTRY, idx) }
+ { UTIL_LISTIFY(DT_PROP_LEN(DT_PHANDLE_BY_IDX(ZMK_KEYMAP_NODE, layers, idx), bindings), _TRANSFORM_ENTRY, idx) }
-static zmk_key zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_MATRIX_ROWS * ZMK_MATRIX_COLS] = {
+static struct zmk_behavior_binding zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_MATRIX_ROWS * ZMK_MATRIX_COLS] = {
#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 0)
TRANSFORMED_LAYER(0),
#endif
@@ -51,36 +77,7 @@ static zmk_key zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_MATRIX_ROWS * ZMK_MATRIX_CO
#endif
};
-#else
-
-static zmk_key zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_MATRIX_ROWS * ZMK_MATRIX_COLS] = {
-#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 0)
- DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 0, keys),
-#endif
-#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 1)
- DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 1, keys),
-#endif
-#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 2)
- DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 2, keys),
-#endif
-#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 3)
- DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 3, keys),
-#endif
-#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 4)
- DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 4, keys),
-#endif
-#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 5)
- DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 5, keys),
-#endif
-#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 6)
- DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 6, keys),
-#endif
-#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 7)
- DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 7, keys),
-#endif
-};
-
-#endif
+// #else
#define SET_LAYER_STATE(layer, state) \
if (layer >= 32) \
@@ -100,24 +97,38 @@ bool zmk_keymap_layer_deactivate(u8_t layer)
SET_LAYER_STATE(layer, false);
};
-zmk_key zmk_keymap_keycode_from_position(u32_t row, u32_t column)
+int zmk_keymap_position_state_changed(u32_t row, u32_t column, bool pressed)
{
for (int layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer >= zmk_keymap_layer_default; layer--)
{
if ((zmk_keymap_layer_state & BIT(layer)) == BIT(layer) || layer == zmk_keymap_layer_default)
{
u8_t key_index = (row * ZMK_MATRIX_COLS) + column;
- LOG_DBG("Getting key at index %d", key_index);
+ struct zmk_behavior_binding *binding = &zmk_keymap[layer][key_index];
+ struct device *behavior;
+ int ret;
- zmk_key key = zmk_keymap[layer][key_index];
- if (key == ZC_TRNS)
- {
- continue;
+ LOG_DBG("key index: %d, binding name: %s", key_index, binding->behavior_dev);
+
+ behavior = device_get_binding(binding->behavior_dev);
+ if (pressed) {
+ ret = behavior_position_pressed(behavior, binding->param1, binding->param2);
+ } else {
+ ret = behavior_position_released(behavior, binding->param1, binding->param2);
}
+
- return key;
+ if (ret > 0) {
+ LOG_DBG("behavior processing to continue to next layer");
+ continue;
+ } else if (ret < 0) {
+ LOG_DBG("Behavior returned error: %d", ret);
+ return ret;
+ } else {
+ return ret;
+ }
}
}
- return ZC_NO;
+ return -ENOTSUP;
}
diff --git a/app/src/kscan.c b/app/src/kscan.c
index 1f54a14..d1ed621 100644
--- a/app/src/kscan.c
+++ b/app/src/kscan.c
@@ -49,11 +49,12 @@ void zmk_kscan_process_msgq(struct k_work *item)
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};
+ zmk_keymap_position_state_changed(ev.row, ev.column, 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);
+ // LOG_DBG("Row: %d, col: %d, key: %d, pressed: %s\n", ev.row, ev.column, key, (pressed ? "true" : "false"));
+ // zmk_handle_key(kev);
}
}