refactor(sensors): Split data handling from triggers.
* All sensor behaviors should see sensor data, then selectively only have some trigger their behaviors.
This commit is contained in:
parent
d781ec795b
commit
8b29f6d345
6 changed files with 135 additions and 55 deletions
|
@ -23,9 +23,17 @@
|
||||||
* (Internal use only.)
|
* (Internal use only.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
enum behavior_sensor_binding_process_mode {
|
||||||
|
BEHAVIOR_SENSOR_BINDING_PROCESS_MODE_TRIGGER,
|
||||||
|
BEHAVIOR_SENSOR_BINDING_PROCESS_MODE_DISCARD,
|
||||||
|
};
|
||||||
|
|
||||||
typedef int (*behavior_keymap_binding_callback_t)(struct zmk_behavior_binding *binding,
|
typedef int (*behavior_keymap_binding_callback_t)(struct zmk_behavior_binding *binding,
|
||||||
struct zmk_behavior_binding_event event);
|
struct zmk_behavior_binding_event event);
|
||||||
typedef int (*behavior_sensor_keymap_binding_callback_t)(
|
typedef int (*behavior_sensor_keymap_binding_process_callback_t)(
|
||||||
|
struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event,
|
||||||
|
enum behavior_sensor_binding_process_mode mode);
|
||||||
|
typedef int (*behavior_sensor_keymap_binding_data_callback_t)(
|
||||||
struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event,
|
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_config *sensor_config, size_t channel_data_size,
|
||||||
const struct zmk_sensor_channel_data channel_data[channel_data_size]);
|
const struct zmk_sensor_channel_data channel_data[channel_data_size]);
|
||||||
|
@ -41,7 +49,8 @@ __subsystem struct behavior_driver_api {
|
||||||
behavior_keymap_binding_callback_t binding_convert_central_state_dependent_params;
|
behavior_keymap_binding_callback_t binding_convert_central_state_dependent_params;
|
||||||
behavior_keymap_binding_callback_t binding_pressed;
|
behavior_keymap_binding_callback_t binding_pressed;
|
||||||
behavior_keymap_binding_callback_t binding_released;
|
behavior_keymap_binding_callback_t binding_released;
|
||||||
behavior_sensor_keymap_binding_callback_t sensor_binding_triggered;
|
behavior_sensor_keymap_binding_data_callback_t sensor_binding_data;
|
||||||
|
behavior_sensor_keymap_binding_process_callback_t sensor_binding_process;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* @endcond
|
* @endcond
|
||||||
|
@ -151,7 +160,7 @@ static inline int z_impl_behavior_keymap_binding_released(struct zmk_behavior_bi
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handle the a sensor keymap binding being triggered
|
* @brief Handle the a sensor keymap binding processing any incoming data from the sensor
|
||||||
* @param binding Sensor keymap binding which was triggered.
|
* @param binding Sensor keymap binding which was triggered.
|
||||||
* @param sensor Pointer to the sensor device structure for the sensor driver instance.
|
* @param sensor Pointer to the sensor device structure for the sensor driver instance.
|
||||||
* @param virtual_key_position ZMK_KEYMAP_LEN + sensor number
|
* @param virtual_key_position ZMK_KEYMAP_LEN + sensor number
|
||||||
|
@ -160,12 +169,12 @@ static inline int z_impl_behavior_keymap_binding_released(struct zmk_behavior_bi
|
||||||
* @retval 0 If successful.
|
* @retval 0 If successful.
|
||||||
* @retval Negative errno code if failure.
|
* @retval Negative errno code if failure.
|
||||||
*/
|
*/
|
||||||
__syscall int behavior_sensor_keymap_binding_triggered(
|
__syscall int behavior_sensor_keymap_binding_data(
|
||||||
struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event,
|
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_config *sensor_config, size_t channel_data_size,
|
||||||
const struct zmk_sensor_channel_data *channel_data);
|
const struct zmk_sensor_channel_data *channel_data);
|
||||||
|
|
||||||
static inline int z_impl_behavior_sensor_keymap_binding_triggered(
|
static inline int z_impl_behavior_sensor_keymap_binding_data(
|
||||||
struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event,
|
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_config *sensor_config, size_t channel_data_size,
|
||||||
const struct zmk_sensor_channel_data *channel_data) {
|
const struct zmk_sensor_channel_data *channel_data) {
|
||||||
|
@ -177,12 +186,46 @@ static inline int z_impl_behavior_sensor_keymap_binding_triggered(
|
||||||
|
|
||||||
const struct behavior_driver_api *api = (const struct behavior_driver_api *)dev->api;
|
const struct behavior_driver_api *api = (const struct behavior_driver_api *)dev->api;
|
||||||
|
|
||||||
if (api->sensor_binding_triggered == NULL) {
|
if (api->sensor_binding_data == NULL) {
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
return api->sensor_binding_triggered(binding, event, sensor_config, channel_data_size,
|
return api->sensor_binding_data(binding, event, sensor_config, channel_data_size, channel_data);
|
||||||
channel_data);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handle the keymap sensor binding being triggered after updating any local data
|
||||||
|
* @param dev Pointer to the device structure for the driver instance.
|
||||||
|
* @param param1 User parameter specified at time of behavior binding.
|
||||||
|
* @param param2 User parameter specified at time of behavior binding.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval Negative errno code if failure.
|
||||||
|
*/
|
||||||
|
// clang-format off
|
||||||
|
__syscall int behavior_sensor_keymap_binding_process(
|
||||||
|
struct zmk_behavior_binding *binding,
|
||||||
|
struct zmk_behavior_binding_event event,
|
||||||
|
enum behavior_sensor_binding_process_mode mode);
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
z_impl_behavior_sensor_keymap_binding_process(struct zmk_behavior_binding *binding,
|
||||||
|
struct zmk_behavior_binding_event event,
|
||||||
|
enum behavior_sensor_binding_process_mode mode) {
|
||||||
|
const struct device *dev = device_get_binding(binding->behavior_dev);
|
||||||
|
|
||||||
|
if (dev == NULL) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct behavior_driver_api *api = (const struct behavior_driver_api *)dev->api;
|
||||||
|
|
||||||
|
if (api->sensor_binding_process == NULL) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->sensor_binding_process(binding, event, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
#include "behavior_sensor_rotate_common.h"
|
#include "behavior_sensor_rotate_common.h"
|
||||||
|
|
||||||
static const struct behavior_driver_api behavior_sensor_rotate_driver_api = {
|
static const struct behavior_driver_api behavior_sensor_rotate_driver_api = {
|
||||||
.sensor_binding_triggered = zmk_behavior_sensor_rotate_common_trigger};
|
.sensor_binding_data = zmk_behavior_sensor_rotate_common_data,
|
||||||
|
.sensor_binding_process = zmk_behavior_sensor_rotate_common_process};
|
||||||
|
|
||||||
static int behavior_sensor_rotate_init(const struct device *dev) { return 0; };
|
static int behavior_sensor_rotate_init(const struct device *dev) { return 0; };
|
||||||
|
|
||||||
|
|
|
@ -11,13 +11,12 @@
|
||||||
|
|
||||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
int zmk_behavior_sensor_rotate_common_trigger(struct zmk_behavior_binding *binding,
|
int zmk_behavior_sensor_rotate_common_data(struct zmk_behavior_binding *binding,
|
||||||
struct zmk_behavior_binding_event event,
|
struct zmk_behavior_binding_event event,
|
||||||
const struct zmk_sensor_config *sensor_config,
|
const struct zmk_sensor_config *sensor_config,
|
||||||
size_t channel_data_size,
|
size_t channel_data_size,
|
||||||
const struct zmk_sensor_channel_data *channel_data) {
|
const struct zmk_sensor_channel_data *channel_data) {
|
||||||
const struct device *dev = device_get_binding(binding->behavior_dev);
|
const struct device *dev = device_get_binding(binding->behavior_dev);
|
||||||
const struct behavior_sensor_rotate_config *cfg = dev->config;
|
|
||||||
struct behavior_sensor_rotate_data *data = dev->data;
|
struct behavior_sensor_rotate_data *data = dev->data;
|
||||||
|
|
||||||
const struct sensor_value value = channel_data[0].value;
|
const struct sensor_value value = channel_data[0].value;
|
||||||
|
@ -52,6 +51,26 @@ int zmk_behavior_sensor_rotate_common_trigger(struct zmk_behavior_binding *bindi
|
||||||
value.val1, value.val2, data->remainder[sensor_position].val1,
|
value.val1, value.val2, data->remainder[sensor_position].val1,
|
||||||
data->remainder[sensor_position].val2, triggers, binding->param1, binding->param2);
|
data->remainder[sensor_position].val2, triggers, binding->param1, binding->param2);
|
||||||
|
|
||||||
|
data->triggers[sensor_position] = triggers;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmk_behavior_sensor_rotate_common_process(struct zmk_behavior_binding *binding,
|
||||||
|
struct zmk_behavior_binding_event event,
|
||||||
|
enum behavior_sensor_binding_process_mode mode) {
|
||||||
|
const struct device *dev = device_get_binding(binding->behavior_dev);
|
||||||
|
const struct behavior_sensor_rotate_config *cfg = dev->config;
|
||||||
|
struct behavior_sensor_rotate_data *data = dev->data;
|
||||||
|
|
||||||
|
const int sensor_position = ZMK_SENSOR_POSITION_FROM_VIRTUAL_KEY_POSITION(event.position);
|
||||||
|
|
||||||
|
if (mode != BEHAVIOR_SENSOR_BINDING_PROCESS_MODE_TRIGGER) {
|
||||||
|
data->triggers[sensor_position] = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int triggers = data->triggers[sensor_position];
|
||||||
|
|
||||||
struct zmk_behavior_binding triggered_binding;
|
struct zmk_behavior_binding triggered_binding;
|
||||||
if (triggers > 0) {
|
if (triggers > 0) {
|
||||||
triggered_binding = cfg->cw_binding;
|
triggered_binding = cfg->cw_binding;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <drivers/behavior.h>
|
||||||
#include <zmk/behavior.h>
|
#include <zmk/behavior.h>
|
||||||
#include <zmk/sensors.h>
|
#include <zmk/sensors.h>
|
||||||
|
|
||||||
|
@ -16,10 +17,14 @@ struct behavior_sensor_rotate_config {
|
||||||
|
|
||||||
struct behavior_sensor_rotate_data {
|
struct behavior_sensor_rotate_data {
|
||||||
struct sensor_value remainder[ZMK_KEYMAP_SENSORS_LEN];
|
struct sensor_value remainder[ZMK_KEYMAP_SENSORS_LEN];
|
||||||
|
int triggers[ZMK_KEYMAP_SENSORS_LEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
int zmk_behavior_sensor_rotate_common_trigger(struct zmk_behavior_binding *binding,
|
int zmk_behavior_sensor_rotate_common_data(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);
|
||||||
|
int zmk_behavior_sensor_rotate_common_process(struct zmk_behavior_binding *binding,
|
||||||
struct zmk_behavior_binding_event event,
|
struct zmk_behavior_binding_event event,
|
||||||
const struct zmk_sensor_config *sensor_config,
|
enum behavior_sensor_binding_process_mode mode);
|
||||||
size_t channel_data_size,
|
|
||||||
const struct zmk_sensor_channel_data *channel_data);
|
|
|
@ -13,7 +13,8 @@
|
||||||
#include "behavior_sensor_rotate_common.h"
|
#include "behavior_sensor_rotate_common.h"
|
||||||
|
|
||||||
static const struct behavior_driver_api behavior_sensor_rotate_var_driver_api = {
|
static const struct behavior_driver_api behavior_sensor_rotate_var_driver_api = {
|
||||||
.sensor_binding_triggered = zmk_behavior_sensor_rotate_common_trigger};
|
.sensor_binding_data = zmk_behavior_sensor_rotate_common_data,
|
||||||
|
.sensor_binding_process = zmk_behavior_sensor_rotate_common_process};
|
||||||
|
|
||||||
static int behavior_sensor_rotate_var_init(const struct device *dev) { return 0; };
|
static int behavior_sensor_rotate_var_init(const struct device *dev) { return 0; };
|
||||||
|
|
||||||
|
|
|
@ -252,48 +252,59 @@ int zmk_keymap_position_state_changed(uint8_t source, uint32_t position, bool pr
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ZMK_KEYMAP_HAS_SENSORS
|
#if ZMK_KEYMAP_HAS_SENSORS
|
||||||
int zmk_keymap_sensor_triggered(
|
int zmk_keymap_sensor_event(uint8_t sensor_position, size_t channel_data_size,
|
||||||
uint8_t sensor_position, size_t channel_data_size,
|
const struct zmk_sensor_channel_data channel_data[channel_data_size],
|
||||||
const struct zmk_sensor_channel_data channel_data[channel_data_size], int64_t timestamp) {
|
int64_t timestamp) {
|
||||||
for (int layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer >= _zmk_keymap_layer_default; layer--) {
|
bool opaque_response = false;
|
||||||
if (zmk_keymap_layer_active(layer)) {
|
|
||||||
struct zmk_behavior_binding *binding = &zmk_sensor_keymap[layer][sensor_position];
|
|
||||||
const struct device *behavior;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
LOG_DBG("layer: %d sensor_position: %d, binding name: %s", layer, sensor_position,
|
for (int layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer >= 0; layer--) {
|
||||||
binding->behavior_dev);
|
struct zmk_behavior_binding *binding = &zmk_sensor_keymap[layer][sensor_position];
|
||||||
|
const struct device *behavior;
|
||||||
|
int ret;
|
||||||
|
|
||||||
behavior = device_get_binding(binding->behavior_dev);
|
LOG_DBG("layer: %d sensor_position: %d, binding name: %s", layer, sensor_position,
|
||||||
|
binding->behavior_dev);
|
||||||
|
|
||||||
if (!behavior) {
|
behavior = device_get_binding(binding->behavior_dev);
|
||||||
LOG_DBG("No behavior assigned to %d on layer %d", sensor_position, layer);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct zmk_behavior_binding_event event = {
|
if (!behavior) {
|
||||||
.layer = layer,
|
LOG_DBG("No behavior assigned to %d on layer %d", sensor_position, layer);
|
||||||
.position = ZMK_VIRTUAL_KEY_POSITION_SENSOR(sensor_position),
|
continue;
|
||||||
.timestamp = timestamp,
|
}
|
||||||
};
|
|
||||||
|
|
||||||
ret = behavior_sensor_keymap_binding_triggered(
|
struct zmk_behavior_binding_event event = {
|
||||||
binding, event, zmk_sensors_get_config_at_position(sensor_position),
|
.layer = layer,
|
||||||
channel_data_size, channel_data);
|
.position = ZMK_VIRTUAL_KEY_POSITION_SENSOR(sensor_position),
|
||||||
|
.timestamp = timestamp,
|
||||||
|
};
|
||||||
|
|
||||||
if (ret > 0) {
|
ret = behavior_sensor_keymap_binding_data(
|
||||||
LOG_DBG("behavior processing to continue to next layer");
|
binding, event, zmk_sensors_get_config_at_position(sensor_position), channel_data_size,
|
||||||
continue;
|
channel_data);
|
||||||
} else if (ret < 0) {
|
|
||||||
LOG_DBG("Behavior returned error: %d", ret);
|
if (ret > 0) {
|
||||||
return ret;
|
LOG_DBG("behavior processing to continue to next layer");
|
||||||
} else {
|
continue;
|
||||||
return ret;
|
}
|
||||||
}
|
|
||||||
|
enum behavior_sensor_binding_process_mode mode =
|
||||||
|
(!opaque_response && layer >= _zmk_keymap_layer_default &&
|
||||||
|
zmk_keymap_layer_active(layer))
|
||||||
|
? BEHAVIOR_SENSOR_BINDING_PROCESS_MODE_TRIGGER
|
||||||
|
: BEHAVIOR_SENSOR_BINDING_PROCESS_MODE_DISCARD;
|
||||||
|
|
||||||
|
ret = behavior_sensor_keymap_binding_process(binding, event, mode);
|
||||||
|
|
||||||
|
if (ret == ZMK_BEHAVIOR_OPAQUE) {
|
||||||
|
LOG_DBG("sensor event processing complete, behavior response was opaque");
|
||||||
|
opaque_response = true;
|
||||||
|
} else if (ret < 0) {
|
||||||
|
LOG_DBG("Behavior returned error: %d", ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -ENOTSUP;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
||||||
|
@ -308,8 +319,8 @@ int keymap_listener(const zmk_event_t *eh) {
|
||||||
#if ZMK_KEYMAP_HAS_SENSORS
|
#if ZMK_KEYMAP_HAS_SENSORS
|
||||||
const struct zmk_sensor_event *sensor_ev;
|
const struct zmk_sensor_event *sensor_ev;
|
||||||
if ((sensor_ev = as_zmk_sensor_event(eh)) != NULL) {
|
if ((sensor_ev = as_zmk_sensor_event(eh)) != NULL) {
|
||||||
return zmk_keymap_sensor_triggered(sensor_ev->sensor_position, sensor_ev->channel_data_size,
|
return zmk_keymap_sensor_event(sensor_ev->sensor_position, sensor_ev->channel_data_size,
|
||||||
sensor_ev->channel_data, sensor_ev->timestamp);
|
sensor_ev->channel_data, sensor_ev->timestamp);
|
||||||
}
|
}
|
||||||
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue