Some initial work on behavior bindings for keymaps
This commit is contained in:
parent
865f41a46d
commit
c23d752917
19 changed files with 370 additions and 64 deletions
|
@ -1,6 +1,7 @@
|
||||||
# Find Zephyr. This also loads Zephyr's build system.
|
# Find Zephyr. This also loads Zephyr's build system.
|
||||||
cmake_minimum_required(VERSION 3.13.1)
|
cmake_minimum_required(VERSION 3.13.1)
|
||||||
|
|
||||||
|
set(CONFIG_APPLICATION_DEFINED_SYSCALL true)
|
||||||
list(APPEND BOARD_ROOT ${CMAKE_SOURCE_DIR})
|
list(APPEND BOARD_ROOT ${CMAKE_SOURCE_DIR})
|
||||||
list(APPEND DTS_ROOT ${CMAKE_SOURCE_DIR})
|
list(APPEND DTS_ROOT ${CMAKE_SOURCE_DIR})
|
||||||
|
|
||||||
|
@ -29,6 +30,8 @@ target_include_directories(app PRIVATE include)
|
||||||
target_sources(app PRIVATE src/kscan.c)
|
target_sources(app PRIVATE src/kscan.c)
|
||||||
target_sources(app PRIVATE src/keymap.c)
|
target_sources(app PRIVATE src/keymap.c)
|
||||||
target_sources(app PRIVATE src/hid.c)
|
target_sources(app PRIVATE src/hid.c)
|
||||||
|
target_sources(app PRIVATE src/behaviors/behavior_key_press.c)
|
||||||
|
target_sources(app PRIVATE src/behaviors/behavior_reset.c)
|
||||||
target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/ble.c)
|
target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/ble.c)
|
||||||
target_sources_ifdef(CONFIG_ZMK_KSCAN_MOCK_DRIVER app PRIVATE src/kscan_mock.c)
|
target_sources_ifdef(CONFIG_ZMK_KSCAN_MOCK_DRIVER app PRIVATE src/kscan_mock.c)
|
||||||
target_sources_ifdef(CONFIG_ZMK_KSCAN_COMPOSITE_DRIVER app PRIVATE src/kscan_composite.c)
|
target_sources_ifdef(CONFIG_ZMK_KSCAN_COMPOSITE_DRIVER app PRIVATE src/kscan_composite.c)
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
/dts-v1/;
|
/dts-v1/;
|
||||||
#include <nordic/nrf52840_qiaa.dtsi>
|
#include <nordic/nrf52840_qiaa.dtsi>
|
||||||
|
#include <behaviors/key_press.dtsi>
|
||||||
|
#include <behaviors/reset.dtsi>
|
||||||
#include "arduino_pro_micro_pins.dtsi"
|
#include "arduino_pro_micro_pins.dtsi"
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#include <dt-bindings/zmk/keys.h>
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors/key_press.dtsi>
|
||||||
|
#include <behaviors/reset.dtsi>
|
||||||
#include <keymap.h>
|
#include <keymap.h>
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
|
@ -21,6 +23,9 @@
|
||||||
KC_A MT(MOD_LSFT, KC_B) ZC_NO ZC_NO
|
KC_A MT(MOD_LSFT, KC_B) ZC_NO ZC_NO
|
||||||
CC_RAIS CC_LOWR ZC_NO ZC_NO
|
CC_RAIS CC_LOWR ZC_NO ZC_NO
|
||||||
>;
|
>;
|
||||||
|
bindings = <
|
||||||
|
&reset &kp 0
|
||||||
|
&kp 1 &kp 2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
lower: layer_1 {
|
lower: layer_1 {
|
||||||
|
@ -29,6 +34,10 @@
|
||||||
KC_MPLY KC_MNXT ZC_NO ZC_NO
|
KC_MPLY KC_MNXT ZC_NO ZC_NO
|
||||||
ZC_TRNS ZC_TRNS ZC_NO ZC_NO
|
ZC_TRNS ZC_TRNS ZC_NO ZC_NO
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
bindings = <
|
||||||
|
&reset &kp 0
|
||||||
|
&kp 1 &kp 2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
raise: layer_2 {
|
raise: layer_2 {
|
||||||
|
@ -36,6 +45,10 @@
|
||||||
keys = <
|
keys = <
|
||||||
KC_C KC_D ZC_NO ZC_NO
|
KC_C KC_D ZC_NO ZC_NO
|
||||||
ZC_TRNS ZC_TRNS ZC_NO ZC_NO>;
|
ZC_TRNS ZC_TRNS ZC_NO ZC_NO>;
|
||||||
|
|
||||||
|
bindings = <
|
||||||
|
&reset &kp 0
|
||||||
|
&kp 1 &kp 2>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
KC_A MT(MOD_LSFT, KC_B)
|
KC_A MT(MOD_LSFT, KC_B)
|
||||||
CC_RAIS CC_LOWR
|
CC_RAIS CC_LOWR
|
||||||
>;
|
>;
|
||||||
|
bindings = <
|
||||||
|
&reset &kp 0
|
||||||
|
&kp 1 &kp 2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
lower: layer_1 {
|
lower: layer_1 {
|
||||||
|
@ -29,6 +32,9 @@
|
||||||
KC_MPLY KC_MNXT
|
KC_MPLY KC_MNXT
|
||||||
ZC_TRNS ZC_TRNS
|
ZC_TRNS ZC_TRNS
|
||||||
>;
|
>;
|
||||||
|
bindings = <
|
||||||
|
&reset &kp 0
|
||||||
|
&kp 1 &kp 2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
raise: layer_2 {
|
raise: layer_2 {
|
||||||
|
@ -37,6 +43,9 @@
|
||||||
KC_C KC_D
|
KC_C KC_D
|
||||||
ZC_TRNS ZC_TRNS
|
ZC_TRNS ZC_TRNS
|
||||||
>;
|
>;
|
||||||
|
bindings = <
|
||||||
|
&reset &kp 0
|
||||||
|
&kp 1 &kp 2>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
9
app/dts/behaviors/key_press.dtsi
Normal file
9
app/dts/behaviors/key_press.dtsi
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
/ {
|
||||||
|
behaviors {
|
||||||
|
kp: behavior_key_press {
|
||||||
|
compatible = "zmk,behavior-key-press";
|
||||||
|
label = "KEY_PRESS";
|
||||||
|
#binding-cells = <1>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
9
app/dts/behaviors/reset.dtsi
Normal file
9
app/dts/behaviors/reset.dtsi
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
/ {
|
||||||
|
behaviors {
|
||||||
|
reset: behavior_reset {
|
||||||
|
compatible = "zmk,behavior-reset";
|
||||||
|
label = "RESET";
|
||||||
|
#binding-cells = <0>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
14
app/dts/bindings/behaviors/one_param.yaml
Normal file
14
app/dts/bindings/behaviors/one_param.yaml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# Copyright (c) 2020, Pete Johanson
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
properties:
|
||||||
|
label:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
"#binding-cells":
|
||||||
|
type: int
|
||||||
|
required: true
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
binding-cells:
|
||||||
|
- param1
|
15
app/dts/bindings/behaviors/two_param.yaml
Normal file
15
app/dts/bindings/behaviors/two_param.yaml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Copyright (c) 2020, Pete Johanson
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
properties:
|
||||||
|
label:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
"#binding-cells":
|
||||||
|
type: int
|
||||||
|
required: true
|
||||||
|
const: 2
|
||||||
|
|
||||||
|
binding-cells:
|
||||||
|
- param1
|
||||||
|
- param2
|
11
app/dts/bindings/behaviors/zero_param.yaml
Normal file
11
app/dts/bindings/behaviors/zero_param.yaml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Copyright (c) 2020, Pete Johanson
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
properties:
|
||||||
|
label:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
"#binding-cells":
|
||||||
|
type: int
|
||||||
|
required: true
|
||||||
|
const: 0
|
8
app/dts/bindings/behaviors/zmk,behavior-key-press.yaml
Normal file
8
app/dts/bindings/behaviors/zmk,behavior-key-press.yaml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Copyright (c) 2020, Pete Johanson
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
description: Key press/release behavior
|
||||||
|
|
||||||
|
compatible: "zmk,behavior-key-press"
|
||||||
|
|
||||||
|
include: one_param.yaml
|
8
app/dts/bindings/behaviors/zmk,behavior-reset.yaml
Normal file
8
app/dts/bindings/behaviors/zmk,behavior-reset.yaml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Copyright (c) 2020, Pete Johanson
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
description: Keyboard Reset Behavior
|
||||||
|
|
||||||
|
compatible: "zmk,behavior-reset"
|
||||||
|
|
||||||
|
include: zero_param.yaml
|
|
@ -11,4 +11,5 @@ child-binding:
|
||||||
type: string
|
type: string
|
||||||
keys:
|
keys:
|
||||||
type: array
|
type: array
|
||||||
|
bindings:
|
||||||
|
type: phandle-array
|
||||||
|
|
88
app/include/drivers/behavior.h
Normal file
88
app/include/drivers/behavior.h
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Peter Johanson
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <zephyr/types.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <device.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @cond INTERNAL_HIDDEN
|
||||||
|
*
|
||||||
|
* Behavior driver API definition and system call entry points.
|
||||||
|
*
|
||||||
|
* (Internal use only.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef int (*behavior_position_pressed_t)(struct device *dev, u32_t param1, u32_t param2);
|
||||||
|
typedef int (*behavior_position_released_t)(struct device *dev, u32_t param1, u32_t param2);
|
||||||
|
|
||||||
|
__subsystem struct behavior_driver_api {
|
||||||
|
behavior_position_pressed_t position_pressed;
|
||||||
|
behavior_position_released_t position_released;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @endcond
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handle the assigned position being pressed
|
||||||
|
* @param dev Pointer to the device structure for the driver instance.
|
||||||
|
* @param param1 User parameter specified at time of behavior assignment.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval Negative errno code if failure.
|
||||||
|
*/
|
||||||
|
__syscall int behavior_position_pressed(struct device *dev, u32_t param1, u32_t param2);
|
||||||
|
|
||||||
|
static inline int z_impl_behavior_position_pressed(struct device *dev, u32_t param1, u32_t param2)
|
||||||
|
{
|
||||||
|
const struct behavior_driver_api *api =
|
||||||
|
(const struct behavior_driver_api *)dev->driver_api;
|
||||||
|
|
||||||
|
if (api->position_pressed == NULL) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->position_pressed(dev, param1, param2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handle the assigned position being pressed
|
||||||
|
* @param dev Pointer to the device structure for the driver instance.
|
||||||
|
* @param param1 User parameter specified at time of behavior assignment.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval Negative errno code if failure.
|
||||||
|
*/
|
||||||
|
__syscall int behavior_position_released(struct device *dev, u32_t param1, u32_t param2);
|
||||||
|
|
||||||
|
static inline int z_impl_behavior_position_released(struct device *dev, u32_t param1, u32_t param2)
|
||||||
|
{
|
||||||
|
const struct behavior_driver_api *api =
|
||||||
|
(const struct behavior_driver_api *)dev->driver_api;
|
||||||
|
|
||||||
|
if (api->position_released == NULL) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->position_released(dev, param1, param2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <syscalls/behavior.h>
|
|
@ -6,23 +6,9 @@
|
||||||
#include <dt-bindings/zmk/keys.h>
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
|
||||||
#include <zmk/matrix.h>
|
#include <zmk/matrix.h>
|
||||||
#include <zmk/keys.h>
|
// #include <zmk/keys.h>
|
||||||
|
|
||||||
#define ZMK_KEYMAP_NODE DT_CHOSEN(zmk_keymap)
|
|
||||||
#define ZMK_KEYMAP_LAYERS_LEN DT_PROP_LEN(ZMK_KEYMAP_NODE, layers)
|
|
||||||
|
|
||||||
/* TODO: Need to actually be able to get a NODELABEL from a node id
|
|
||||||
#define _ZMK_KEYMAP_GENERATE_LAYER_CONST(node_id) \
|
|
||||||
DT_NODELABEL_FOR_NODE(node_id)_layer,
|
|
||||||
|
|
||||||
enum zmk_keymap_layer
|
|
||||||
{
|
|
||||||
DT_FOREACH_CHILD(DT_INST(0, zmk_layers), _ZMK_KEYMAP_GENERATE_LAYER_CONST)
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool zmk_keymap_layer_activate(u8_t layer);
|
bool zmk_keymap_layer_activate(u8_t layer);
|
||||||
bool zmk_keymap_layer_deactivate(u8_t layer);
|
bool zmk_keymap_layer_deactivate(u8_t layer);
|
||||||
|
|
||||||
zmk_key
|
int zmk_keymap_position_state_changed(u32_t row, u32_t column, bool pressed);
|
||||||
zmk_keymap_keycode_from_position(u32_t row, u32_t column);
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
# CONFIG_LOG=y
|
CONFIG_LOG=y
|
||||||
# CONFIG_ZMK_LOG_LEVEL_DBG=y
|
CONFIG_ZMK_LOG_LEVEL_DBG=y
|
||||||
CONFIG_KERNEL_BIN_NAME="zmk"
|
CONFIG_KERNEL_BIN_NAME="zmk"
|
||||||
|
CONFIG_REBOOT=y
|
66
app/src/behaviors/behavior_key_press.c
Normal file
66
app/src/behaviors/behavior_key_press.c
Normal file
|
@ -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);
|
51
app/src/behaviors/behavior_reset.c
Normal file
51
app/src/behaviors/behavior_reset.c
Normal file
|
@ -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);
|
|
@ -3,22 +3,48 @@
|
||||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
#include <zmk/keymap.h>
|
#include <zmk/keymap.h>
|
||||||
#include <dt-bindings/zmk/matrix-transform.h>
|
#include <dt-bindings/zmk/matrix-transform.h>
|
||||||
|
#include <drivers/behavior.h>
|
||||||
#include <sys/util.h>
|
#include <sys/util.h>
|
||||||
|
|
||||||
static u32_t zmk_keymap_layer_state = 0;
|
static u32_t zmk_keymap_layer_state = 0;
|
||||||
static u8_t zmk_keymap_layer_default = 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)
|
#if DT_NODE_HAS_PROP(ZMK_KEYMAP_NODE, transform)
|
||||||
#define ZMK_KEYMAP_TRANSFORM_NODE DT_PHANDLE(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 ZMK_KEYMAP_LEN DT_PROP_LEN(ZMK_KEYMAP_TRANSFORM_NODE, map)
|
||||||
|
|
||||||
#define _TRANSFORM_ENTRY(i, l) \
|
#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) \
|
#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)
|
#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 0)
|
||||||
TRANSFORMED_LAYER(0),
|
TRANSFORMED_LAYER(0),
|
||||||
#endif
|
#endif
|
||||||
|
@ -51,36 +77,7 @@ static zmk_key zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_MATRIX_ROWS * ZMK_MATRIX_CO
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
// #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
|
|
||||||
|
|
||||||
#define SET_LAYER_STATE(layer, state) \
|
#define SET_LAYER_STATE(layer, state) \
|
||||||
if (layer >= 32) \
|
if (layer >= 32) \
|
||||||
|
@ -100,24 +97,38 @@ bool zmk_keymap_layer_deactivate(u8_t layer)
|
||||||
SET_LAYER_STATE(layer, false);
|
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--)
|
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)
|
if ((zmk_keymap_layer_state & BIT(layer)) == BIT(layer) || layer == zmk_keymap_layer_default)
|
||||||
{
|
{
|
||||||
u8_t key_index = (row * ZMK_MATRIX_COLS) + column;
|
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];
|
LOG_DBG("key index: %d, binding name: %s", key_index, binding->behavior_dev);
|
||||||
if (key == ZC_TRNS)
|
|
||||||
{
|
behavior = device_get_binding(binding->behavior_dev);
|
||||||
continue;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
while (k_msgq_get(&zmk_kscan_msgq, &ev, K_NO_WAIT) == 0)
|
||||||
{
|
{
|
||||||
bool pressed = (ev.state == ZMK_KSCAN_EVENT_STATE_PRESSED);
|
bool pressed = (ev.state == ZMK_KSCAN_EVENT_STATE_PRESSED);
|
||||||
zmk_key key = zmk_keymap_keycode_from_position(ev.row, ev.column);
|
zmk_keymap_position_state_changed(ev.row, ev.column, pressed);
|
||||||
struct zmk_key_event kev = (struct zmk_key_event){.row = ev.row, .column = ev.column, .key = key, .pressed = 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"));
|
// LOG_DBG("Row: %d, col: %d, key: %d, pressed: %s\n", ev.row, ev.column, key, (pressed ? "true" : "false"));
|
||||||
zmk_handle_key(kev);
|
// zmk_handle_key(kev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue