sensing: add hinge angle sensor
Add hinge angle virtual sensor for sensing subsystem, hinge angle sensor takes both base accel and lid accel as reporter. Signed-off-by: Zhang Lixu <lixu.zhang@intel.com>
This commit is contained in:
parent
f2bbfc8613
commit
18a257cbe4
10
dts/bindings/sensor/zephyr,sensing-hinge-angle.yaml
Normal file
10
dts/bindings/sensor/zephyr,sensing-hinge-angle.yaml
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2023, Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
description: Sensing subsystem hinge angle sensor bindings.
|
||||
|
||||
compatible: "zephyr,sensing-hinge-angle"
|
||||
|
||||
# Common sensor subsystem sensor properties.
|
||||
include: ["zephyr,sensing-sensor.yaml"]
|
|
@ -11,3 +11,4 @@ zephyr_library_sources(
|
|||
)
|
||||
|
||||
add_subdirectory_ifdef(CONFIG_SENSING_SENSOR_PHY_3D_SENSOR sensor/phy_3d_sensor)
|
||||
add_subdirectory_ifdef(CONFIG_SENSING_SENSOR_HINGE_ANGLE sensor/hinge_angle)
|
||||
|
|
|
@ -86,5 +86,6 @@ config SENSING_DISPATCH_THREAD_PRIORITY
|
|||
Typical values are 8
|
||||
|
||||
source "subsys/sensing/sensor/phy_3d_sensor/Kconfig"
|
||||
source "subsys/sensing/sensor/hinge_angle/Kconfig"
|
||||
|
||||
endif # SENSING
|
||||
|
|
3
subsys/sensing/sensor/hinge_angle/CMakeLists.txt
Normal file
3
subsys/sensing/sensor/hinge_angle/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library_sources(hinge_angle.c)
|
9
subsys/sensing/sensor/hinge_angle/Kconfig
Normal file
9
subsys/sensing/sensor/hinge_angle/Kconfig
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Copyright (c) 2023 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config SENSING_SENSOR_HINGE_ANGLE
|
||||
bool "Sensing hinge angle sensor"
|
||||
default y
|
||||
depends on DT_HAS_ZEPHYR_SENSING_HINGE_ANGLE_ENABLED
|
||||
help
|
||||
Enable sensing hinge angle sensor.
|
167
subsys/sensing/sensor/hinge_angle/hinge_angle.c
Normal file
167
subsys/sensing/sensor/hinge_angle/hinge_angle.c
Normal file
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <zephyr/drivers/sensor.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/sensing/sensing_sensor.h>
|
||||
|
||||
LOG_MODULE_REGISTER(hinge_angle, CONFIG_SENSING_LOG_LEVEL);
|
||||
|
||||
#define HINGE_REPORTER_NUM 2
|
||||
|
||||
static struct sensing_sensor_register_info hinge_reg = {
|
||||
.flags = SENSING_SENSOR_FLAG_REPORT_ON_CHANGE,
|
||||
.sample_size = sizeof(struct sensing_sensor_value_q31),
|
||||
.sensitivity_count = 1,
|
||||
.version.value = SENSING_SENSOR_VERSION(1, 0, 0, 0),
|
||||
};
|
||||
|
||||
struct hinge_angle_context {
|
||||
struct rtio_iodev_sqe *sqe;
|
||||
sensing_sensor_handle_t reporters[HINGE_REPORTER_NUM];
|
||||
struct sensing_sensor_value_3d_q31 sample[HINGE_REPORTER_NUM];
|
||||
int has_sample[HINGE_REPORTER_NUM];
|
||||
};
|
||||
|
||||
static int hinge_init(const struct device *dev)
|
||||
{
|
||||
struct hinge_angle_context *data = dev->data;
|
||||
int ret;
|
||||
|
||||
ret = sensing_sensor_get_reporters(dev,
|
||||
SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D,
|
||||
data->reporters, HINGE_REPORTER_NUM);
|
||||
if (ret != HINGE_REPORTER_NUM) {
|
||||
LOG_ERR("%s: reporter mismatch:%d", dev->name, ret);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
LOG_INF("%s:Found reporter 0: %s", dev->name,
|
||||
sensing_get_sensor_info(data->reporters[0])->name);
|
||||
LOG_INF("%s:Found reporter 1: %s", dev->name,
|
||||
sensing_get_sensor_info(data->reporters[1])->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hinge_attr_set(const struct device *dev,
|
||||
enum sensor_channel chan,
|
||||
enum sensor_attribute attr,
|
||||
const struct sensor_value *val)
|
||||
{
|
||||
struct sensing_sensor_config config = {0};
|
||||
struct hinge_angle_context *data = dev->data;
|
||||
int ret = 0;
|
||||
|
||||
switch (attr) {
|
||||
case SENSOR_ATTR_SAMPLING_FREQUENCY:
|
||||
config.attri = SENSING_SENSOR_ATTRIBUTE_INTERVAL;
|
||||
config.interval = (uint32_t)(USEC_PER_SEC * 1000LL /
|
||||
sensor_value_to_milli(val));
|
||||
ret = sensing_set_config(data->reporters[0], &config, 1);
|
||||
ret |= sensing_set_config(data->reporters[1], &config, 1);
|
||||
break;
|
||||
|
||||
case SENSOR_ATTR_HYSTERESIS:
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -ENOTSUP;
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_INF("%s set attr:%d ret:%d", dev->name, attr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hinge_submit(const struct device *dev,
|
||||
struct rtio_iodev_sqe *sqe)
|
||||
{
|
||||
struct hinge_angle_context *data = dev->data;
|
||||
|
||||
if (data->sqe) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
data->sqe = sqe;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sensor_driver_api hinge_api = {
|
||||
.attr_set = hinge_attr_set,
|
||||
.submit = hinge_submit,
|
||||
};
|
||||
|
||||
static q31_t calc_hinge_angle(struct hinge_angle_context *data)
|
||||
{
|
||||
q31_t val;
|
||||
|
||||
LOG_INF("Acc 0: x:%08x y:%08x z:%08x",
|
||||
data->sample[0].readings[0].x,
|
||||
data->sample[0].readings[0].y,
|
||||
data->sample[0].readings[0].z);
|
||||
LOG_INF("Acc 1: x:%08x y:%08x z:%08x",
|
||||
data->sample[1].readings[0].x,
|
||||
data->sample[1].readings[0].y,
|
||||
data->sample[1].readings[0].z);
|
||||
|
||||
/* Todo: calc hinge angle base on data->sample[0] and data->sample[1] */
|
||||
val = 0;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void hinge_reporter_on_data_event(sensing_sensor_handle_t handle,
|
||||
const void *buf, void *context)
|
||||
{
|
||||
struct hinge_angle_context *data = context;
|
||||
struct sensing_sensor_value_q31 *sample;
|
||||
uint32_t buffer_len = 0;
|
||||
int both = 0;
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < HINGE_REPORTER_NUM; ++i) {
|
||||
if (handle == data->reporters[i]) {
|
||||
memcpy(&data->sample[i], buf, sizeof(data->sample[i]));
|
||||
data->has_sample[i] = 1;
|
||||
}
|
||||
both += data->has_sample[i];
|
||||
}
|
||||
|
||||
if (both == HINGE_REPORTER_NUM) {
|
||||
data->has_sample[0] = 0;
|
||||
data->has_sample[1] = 0;
|
||||
|
||||
ret = rtio_sqe_rx_buf(data->sqe, sizeof(*sample), sizeof(*sample),
|
||||
(uint8_t **)&sample, &buffer_len);
|
||||
if (ret) {
|
||||
rtio_iodev_sqe_err(data->sqe, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
sample->readings[0].v = calc_hinge_angle(data);
|
||||
|
||||
rtio_iodev_sqe_ok(data->sqe, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#define DT_DRV_COMPAT zephyr_sensing_hinge_angle
|
||||
#define SENSING_HINGE_ANGLE_DT_DEFINE(_inst) \
|
||||
static struct hinge_angle_context _CONCAT(hinge_ctx, _inst); \
|
||||
static const struct sensing_callback_list _CONCAT(hinge_cb, _inst) = { \
|
||||
.on_data_event = hinge_reporter_on_data_event, \
|
||||
.context = &_CONCAT(hinge_ctx, _inst), \
|
||||
}; \
|
||||
SENSING_SENSOR_DT_INST_DEFINE(_inst, &hinge_reg, \
|
||||
&_CONCAT(hinge_cb, _inst), \
|
||||
&hinge_init, NULL, \
|
||||
&_CONCAT(hinge_ctx, _inst), NULL, \
|
||||
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
|
||||
&hinge_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(SENSING_HINGE_ANGLE_DT_DEFINE);
|
Loading…
Reference in a new issue