Skip to content

Commit

Permalink
Continue core refactor of sensors and their configs.
Browse files Browse the repository at this point in the history
  • Loading branch information
petejohanson committed Apr 10, 2023
1 parent 289e39f commit d557438
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 27 deletions.
Expand Up @@ -9,9 +9,6 @@ properties:
label:
type: string
required: true
triggers-per-rotation:
type: int
required: false
"#sensor-binding-cells":
type: int
required: true
Expand Down
12 changes: 11 additions & 1 deletion app/dts/bindings/zmk,keymap-sensors.yaml
Expand Up @@ -9,4 +9,14 @@ compatible: "zmk,keymap-sensors"
properties:
sensors:
type: phandles
required: true
required: false
triggers-per-rotation:
type: int
required: false

child-binding:
description: Per-sensor configuration settings
properties:
triggers-per-rotation:
type: int
required: false
5 changes: 4 additions & 1 deletion app/include/drivers/behavior.h
Expand Up @@ -27,6 +27,7 @@ typedef int (*behavior_keymap_binding_callback_t)(struct zmk_behavior_binding *b
struct zmk_behavior_binding_event event);
typedef int (*behavior_sensor_keymap_binding_callback_t)(
struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event,
const struct zmk_sensor_config *sensor_config,
size_t channel_data_size, const struct zmk_sensor_channel_data channel_data[channel_data_size]);

enum behavior_locality {
Expand Down Expand Up @@ -161,10 +162,12 @@ static inline int z_impl_behavior_keymap_binding_released(struct zmk_behavior_bi
*/
__syscall int behavior_sensor_keymap_binding_triggered(
struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event,
const struct zmk_sensor_config *sensor_config,
size_t channel_data_size, const struct zmk_sensor_channel_data *channel_data);

static inline int z_impl_behavior_sensor_keymap_binding_triggered(
struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event,
const struct zmk_sensor_config *sensor_config,
size_t channel_data_size, const struct zmk_sensor_channel_data *channel_data) {
const struct device *dev = device_get_binding(binding->behavior_dev);

Expand All @@ -178,7 +181,7 @@ static inline int z_impl_behavior_sensor_keymap_binding_triggered(
return -ENOTSUP;
}

return api->sensor_binding_triggered(binding, event, channel_data_size, channel_data);
return api->sensor_binding_triggered(binding, event, sensor_config, channel_data_size, channel_data);
}

/**
Expand Down
9 changes: 6 additions & 3 deletions app/include/zmk/sensors.h
Expand Up @@ -10,14 +10,17 @@

#define _SENSOR_CHILD_LEN(node) 1 +
#define ZMK_KEYMAP_SENSORS_NODE DT_INST(0, zmk_keymap_sensors)
// #define ZMK_KEYMAP_SENSORS_FOREACH(fn) DT_FOREACH_CHILD(ZMK_KEYMAP_SENSORS_NODE, fn)
// #define ZMK_KEYMAP_SENSORS_FOREACH(fn) DT_FOREACH_CHILD(ZMK_KEYMAP_SENSORS_NODE, fn)
#define ZMK_KEYMAP_SENSORS_LEN DT_PROP_LEN(ZMK_KEYMAP_SENSORS_NODE, sensors)

// #define ZMK_KEYMAP_SENSORS_LEN (DT_FOREACH_CHILD(ZMK_KEYMAP_SENSORS_NODE, _SENSOR_CHILD_LEN) 0)
#define ZMK_KEYMAP_HAS_SENSORS DT_NODE_HAS_STATUS(ZMK_KEYMAP_SENSORS_NODE, okay)
#define ZMK_KEYMAP_SENSORS_BY_IDX(idx) DT_PHANDLE_BY_IDX(ZMK_KEYMAP_SENSORS_NODE, sensors, idx)

const struct zmk_sensor_config *zmk_sensors_get_config_at_position(uint8_t sensor_position);

struct zmk_sensor_config {
uint16_t triggers_per_rotation;
};

struct zmk_sensor_channel_data {
enum sensor_channel channel;
struct sensor_value value;
Expand Down
19 changes: 5 additions & 14 deletions app/src/behaviors/behavior_sensor_rotate_key_press.c
Expand Up @@ -20,10 +20,6 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);

#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)

struct behavior_sensor_rotate_key_press_cfg {
uint8_t activation_resolution;
};

struct behavior_sensor_rotate_key_press_sensor_data {
int32_t remainder[ZMK_KEYMAP_SENSORS_LEN];
};
Expand All @@ -32,21 +28,21 @@ static int behavior_sensor_rotate_key_press_init(const struct device *dev) { ret

static int on_sensor_binding_triggered(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event,
const struct zmk_sensor_config *sensor_config,
size_t channel_data_size,
const struct zmk_sensor_channel_data *channel_data) {
const struct device *behavior_dev = device_get_binding(binding->behavior_dev);
const struct sensor_value *value = &channel_data[0].value;
const struct behavior_sensor_rotate_key_press_cfg *cfg = behavior_dev->config;
struct behavior_sensor_rotate_key_press_sensor_data *data = behavior_dev->data;
uint32_t keycode;

// Some funky special casing for "old encoder behavior" where ticks where reported in val2 only,
// instead of rotational degrees in val1.
data->remainder[event.position] +=
(value->val1 == 0 ? (value->val2 * cfg->activation_resolution) : value->val1);
(value->val1 == 0 ? (value->val2 * sensor_config->triggers_per_rotation) : value->val1);

int8_t triggers = data->remainder[event.position] / cfg->activation_resolution;
data->remainder[event.position] %= cfg->activation_resolution;
int8_t triggers = data->remainder[event.position] / sensor_config->triggers_per_rotation;
data->remainder[event.position] %= sensor_config->triggers_per_rotation;

LOG_DBG("value: %d, remainder: %d triggers: %d inc keycode 0x%02X dec keycode 0x%02X",
value->val1, data->remainder[event.position], triggers, binding->param1,
Expand Down Expand Up @@ -79,16 +75,11 @@ static const struct behavior_driver_api behavior_sensor_rotate_key_press_driver_
.sensor_binding_triggered = on_sensor_binding_triggered};

#define KP_INST(n) \
static const struct behavior_sensor_rotate_key_press_cfg \
behavior_sensor_rotate_key_press_cfg_##n = { \
.activation_resolution = \
(360 / DT_INST_PROP_OR(n, triggers_per_rotation, \
CONFIG_ZMK_ENCODERS_DEFAULT_TRIGGERS_PER_ROTATION))}; \
static struct behavior_sensor_rotate_key_press_sensor_data \
behavior_sensor_rotate_key_press_sensor_data_##n; \
DEVICE_DT_INST_DEFINE(n, behavior_sensor_rotate_key_press_init, NULL, \
&behavior_sensor_rotate_key_press_sensor_data_##n, \
&behavior_sensor_rotate_key_press_cfg_##n, APPLICATION, \
NULL, APPLICATION, \
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
&behavior_sensor_rotate_key_press_driver_api);

Expand Down
5 changes: 3 additions & 2 deletions app/src/keymap.c
Expand Up @@ -276,8 +276,9 @@ int zmk_keymap_sensor_triggered(
.timestamp = timestamp,
};

ret = behavior_sensor_keymap_binding_triggered(binding, event, channel_data_size,
channel_data);
ret = behavior_sensor_keymap_binding_triggered(binding, event,
zmk_sensors_get_config_at_position(sensor_position),
channel_data_size, channel_data);

if (ret > 0) {
LOG_DBG("behavior processing to continue to next layer");
Expand Down
32 changes: 29 additions & 3 deletions app/src/sensors.c
Expand Up @@ -20,21 +20,47 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);

struct sensors_item_cfg {
uint8_t sensor_position;
const struct zmk_sensor_config *config;
const struct device *dev;
struct sensor_trigger trigger;
};

#define _SENSOR_ITEM(node) \
#define _SENSOR_ITEM(idx, node) \
{ \
.dev = DEVICE_DT_GET_OR_NULL(node), .trigger = { \
.type = SENSOR_TRIG_DELTA, \
.chan = SENSOR_CHAN_ROTATION \
} \
}, .config = &configs[idx] \
}
#define SENSOR_ITEM(idx, _i) _SENSOR_ITEM(ZMK_KEYMAP_SENSORS_BY_IDX(idx))
#define SENSOR_ITEM(idx, _i) _SENSOR_ITEM(idx, ZMK_KEYMAP_SENSORS_BY_IDX(idx))

#define JUST_ONE(n) 1
#define ZMK_KEYMAP_SENSORS_CHILD_COUNT DT_FOREACH_CHILD_SEP(ZMK_KEYMAP_SENSORS_NODE, JUST_ONE, +)
static struct zmk_sensor_config configs[] = {

#if (ZMK_KEYMAP_SENSORS_CHILD_COUNT) > 0
#define SENSOR_CHILD_ITEM(node) \
{ .triggers_per_rotation = DT_PROP_OR(node, triggers_per_rotation, DT_PROP(ZMK_KEYMAP_SENSORS_NODE, triggers_per_rotation))}

DT_FOREACH_CHILD_SEP(ZMK_KEYMAP_SENSORS_NODE, SENSOR_CHILD_ITEM, (,))
#else
#define SENSOR_CHILD_DEFAULTS(idx, arg) \
{ .triggers_per_rotation = DT_PROP(ZMK_KEYMAP_SENSORS_NODE, triggers_per_rotation)}

LISTIFY(ZMK_KEYMAP_SENSORS_LEN, SENSOR_CHILD_DEFAULTS, (, ), 0)
#endif
};

static struct sensors_item_cfg sensors[] = {LISTIFY(ZMK_KEYMAP_SENSORS_LEN, SENSOR_ITEM, (, ), 0)};

const struct zmk_sensor_config *zmk_sensors_get_config_at_position(uint8_t sensor_position) {
if (sensor_position > ARRAY_SIZE(configs)) {
return NULL;
}

return &configs[sensor_position];
}

static void zmk_sensors_trigger_handler(const struct device *dev, struct sensor_trigger *trigger) {
int err;
struct sensors_item_cfg *item = CONTAINER_OF(trigger, struct sensors_item_cfg, trigger);
Expand Down

0 comments on commit d557438

Please sign in to comment.