sensing: initial sensor list and enumerate each sensor
Implement sensing_init(): 1) create sensors from device tree 2) sequence sensors following node dependency ordering rule generated by Zephyr DTS 3) initial each sensor, includes: a) creating sensor connection between reporter and client, b) calling sensor init callback, c) setting sensor state Implement sensing_open_sensor(): 1) malloc connection from reporter to application 2) bind connection Implement sensing_close_sensr(): 1) unbind connection 2) free connection from reporter to application Implement sensing_set_config(): 1) call set_interval 2) cann set_sensitivity Implement sensing_get_config(): 1) call get_interval 2) call get_sensitivity Signed-off-by: Guangfu Hu <guangfu.hu@intel.com>
This commit is contained in:
parent
25ca09ea01
commit
335278d60a
8 changed files with 561 additions and 13 deletions
|
|
@ -54,6 +54,10 @@ if(CONFIG_NETWORKING)
|
|||
zephyr_iterable_section(NAME eth_bridge GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4)
|
||||
endif()
|
||||
|
||||
if(CONFIG_SENSING)
|
||||
zephyr_iterable_section(NAME sensing_sensor GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4)
|
||||
endif()
|
||||
|
||||
if(CONFIG_UART_MUX)
|
||||
zephyr_iterable_section(NAME uart_mux GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -136,6 +136,10 @@ if(CONFIG_SETTINGS)
|
|||
zephyr_iterable_section(NAME settings_handler_static KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4)
|
||||
endif()
|
||||
|
||||
if(CONFIG_SENSING)
|
||||
zephyr_iterable_section(NAME sensing_sensor_info KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4)
|
||||
endif()
|
||||
|
||||
if(CONFIG_SENSOR_INFO)
|
||||
zephyr_iterable_section(NAME sensor_info KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -120,6 +120,10 @@
|
|||
ITERABLE_SECTION_RAM(rtio_cqe_pool, 4)
|
||||
#endif /* CONFIG_RTIO */
|
||||
|
||||
#if defined(CONFIG_SENSING)
|
||||
ITERABLE_SECTION_RAM(sensing_sensor, 4)
|
||||
#endif /* CONFIG_SENSING */
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_static_kernel_objects_end = .;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@
|
|||
ITERABLE_SECTION_ROM(settings_handler_static, 4)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SENSING)
|
||||
ITERABLE_SECTION_ROM(sensing_sensor_info, 4)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SENSOR_INFO)
|
||||
ITERABLE_SECTION_ROM(sensor_info, 4)
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -14,4 +14,16 @@ module = SENSING
|
|||
module-str = sensing
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
||||
config SENSING_MAX_SENSITIVITY_COUNT
|
||||
int "maximum sensitivity count one sensor could support"
|
||||
depends on SENSING
|
||||
default 6
|
||||
help
|
||||
This is the maximum sensitivity count one sensor could support,
|
||||
some sensors such as ALS sensor could define different sensitivity for each data filed,
|
||||
So, maximum sensitivity count is needed for sensors
|
||||
Typical values are 6
|
||||
|
||||
source "subsys/sensing/sensor/phy_3d_sensor/Kconfig"
|
||||
|
||||
endif # SENSING
|
||||
|
|
|
|||
|
|
@ -6,46 +6,140 @@
|
|||
|
||||
#include <zephyr/sensing/sensing.h>
|
||||
#include <zephyr/sensing/sensing_sensor.h>
|
||||
#include <stdlib.h>
|
||||
#include "sensor_mgmt.h"
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_DECLARE(sensing, CONFIG_SENSING_LOG_LEVEL);
|
||||
|
||||
/* sensing_open_sensor is normally called by applications: hid, chre, zephyr main, etc */
|
||||
int sensing_open_sensor(const struct sensing_sensor_info *info,
|
||||
int sensing_open_sensor(const struct sensing_sensor_info *sensor_info,
|
||||
const struct sensing_callback_list *cb_list,
|
||||
sensing_sensor_handle_t *handle)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
int ret = 0;
|
||||
|
||||
if (handle == NULL) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
STRUCT_SECTION_FOREACH(sensing_sensor, sensor) {
|
||||
if (sensor_info == sensor->info) {
|
||||
ret = open_sensor(sensor, (struct sensing_connection **)handle);
|
||||
if (ret) {
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sensing_register_callback(*handle, cb_list);
|
||||
}
|
||||
|
||||
int sensing_open_sensor_by_dt(const struct device *dev,
|
||||
const struct sensing_callback_list *cb_list,
|
||||
sensing_sensor_handle_t *handle)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
int ret = 0;
|
||||
struct sensing_sensor *sensor;
|
||||
|
||||
if (handle == NULL) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
sensor = get_sensor_by_dev(dev);
|
||||
if (sensor == NULL) {
|
||||
LOG_ERR("cannot get sensor from dev:%p", dev);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = open_sensor(sensor, (struct sensing_connection **)handle);
|
||||
if (ret) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return sensing_register_callback(*handle, cb_list);
|
||||
}
|
||||
|
||||
/* sensing_close_sensor is normally called by applications: hid, chre, zephyr main, etc */
|
||||
int sensing_close_sensor(sensing_sensor_handle_t handle)
|
||||
int sensing_close_sensor(sensing_sensor_handle_t *handle)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
return close_sensor((struct sensing_connection **)handle);
|
||||
}
|
||||
|
||||
int sensing_set_config(sensing_sensor_handle_t handle,
|
||||
struct sensing_sensor_config *configs,
|
||||
int count)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
struct sensing_sensor_config *cfg;
|
||||
int i, ret = 0;
|
||||
|
||||
if (count <= 0 || count > SENSING_SENSOR_ATTRIBUTE_MAX) {
|
||||
LOG_ERR("invalid config count:%d", count);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
cfg = &configs[i];
|
||||
switch (cfg->attri) {
|
||||
case SENSING_SENSOR_ATTRIBUTE_INTERVAL:
|
||||
ret |= set_interval(handle, cfg->interval);
|
||||
break;
|
||||
|
||||
case SENSING_SENSOR_ATTRIBUTE_SENSITIVITY:
|
||||
ret |= set_sensitivity(handle, cfg->data_field, cfg->sensitivity);
|
||||
break;
|
||||
|
||||
case SENSING_SENSOR_ATTRIBUTE_LATENCY:
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
LOG_ERR("invalid config attribute:%d\n", cfg->attri);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sensing_get_config(sensing_sensor_handle_t handle,
|
||||
struct sensing_sensor_config *configs,
|
||||
int count)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
struct sensing_sensor_config *cfg;
|
||||
int i, ret = 0;
|
||||
|
||||
if (count <= 0 || count > SENSING_SENSOR_ATTRIBUTE_MAX) {
|
||||
LOG_ERR("invalid config count:%d", count);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
cfg = &configs[i];
|
||||
switch (cfg->attri) {
|
||||
case SENSING_SENSOR_ATTRIBUTE_INTERVAL:
|
||||
ret |= get_interval(handle, &cfg->interval);
|
||||
break;
|
||||
|
||||
case SENSING_SENSOR_ATTRIBUTE_SENSITIVITY:
|
||||
ret |= get_sensitivity(handle, cfg->data_field, &cfg->sensitivity);
|
||||
break;
|
||||
|
||||
case SENSING_SENSOR_ATTRIBUTE_LATENCY:
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
LOG_ERR("invalid config attribute:%d\n", cfg->attri);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct sensing_sensor_info *sensing_get_sensor_info(sensing_sensor_handle_t handle)
|
||||
{
|
||||
return NULL;
|
||||
return get_sensor_info(handle);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,18 +15,309 @@
|
|||
|
||||
#define DT_DRV_COMPAT zephyr_sensing
|
||||
|
||||
#define SENSING_SENSOR_NUM (sizeof((int []){ DT_FOREACH_CHILD_STATUS_OKAY_SEP( \
|
||||
DT_DRV_INST(0), DT_NODE_EXISTS, (,))}) / sizeof(int))
|
||||
|
||||
BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1,
|
||||
"only one 'zephyr_sensing' compatible node may be present");
|
||||
|
||||
LOG_MODULE_REGISTER(sensing, CONFIG_SENSING_LOG_LEVEL);
|
||||
|
||||
static struct sensing_mgmt_context sensing_ctx = {0};
|
||||
DT_FOREACH_CHILD_STATUS_OKAY(DT_DRV_INST(0), SENSING_SENSOR_INFO_DEFINE)
|
||||
DT_FOREACH_CHILD_STATUS_OKAY(DT_DRV_INST(0), SENSING_SENSOR_DEFINE)
|
||||
|
||||
|
||||
/**
|
||||
* @struct sensing_context
|
||||
* @brief sensing subsystem context to include global variables
|
||||
*/
|
||||
struct sensing_context {
|
||||
bool sensing_initialized;
|
||||
int sensor_num;
|
||||
struct sensing_sensor *sensors[SENSING_SENSOR_NUM];
|
||||
};
|
||||
|
||||
static struct sensing_context sensing_ctx = {
|
||||
.sensor_num = SENSING_SENSOR_NUM,
|
||||
};
|
||||
|
||||
|
||||
static int set_sensor_state(struct sensing_sensor *sensor, enum sensing_sensor_state state)
|
||||
{
|
||||
__ASSERT(sensor, "set sensor state, sensing_sensor is NULL");
|
||||
|
||||
sensor->state = state;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void init_connection(struct sensing_connection *conn,
|
||||
struct sensing_sensor *source,
|
||||
struct sensing_sensor *sink)
|
||||
{
|
||||
__ASSERT(conn, "init each connection, invalid connection");
|
||||
|
||||
conn->source = source;
|
||||
conn->sink = sink;
|
||||
conn->interval = 0;
|
||||
memset(conn->sensitivity, 0x00, sizeof(conn->sensitivity));
|
||||
/* link connection to its reporter's client_list */
|
||||
sys_slist_append(&source->client_list, &conn->snode);
|
||||
}
|
||||
|
||||
static int init_sensor(struct sensing_sensor *sensor, int conns_num)
|
||||
{
|
||||
const struct sensing_sensor_api *sensor_api;
|
||||
struct sensing_sensor *reporter;
|
||||
struct sensing_connection *conn;
|
||||
void *tmp_conns[conns_num];
|
||||
int i;
|
||||
|
||||
__ASSERT(sensor && sensor->dev, "init sensor, sensor or sensor device is NULL");
|
||||
sensor_api = sensor->dev->api;
|
||||
__ASSERT(sensor_api, "init sensor, sensor device sensor_api is NULL");
|
||||
|
||||
if (sensor->data_buf == NULL) {
|
||||
LOG_ERR("sensor:%s memory alloc failed", sensor->dev->name);
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* physical sensor has no reporters, conns_num is 0 */
|
||||
if (conns_num == 0) {
|
||||
sensor->conns = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < conns_num; i++) {
|
||||
conn = &sensor->conns[i];
|
||||
reporter = get_reporter_sensor(sensor, i);
|
||||
__ASSERT(reporter, "sensor's reporter should not be NULL");
|
||||
|
||||
init_connection(conn, reporter, sensor);
|
||||
|
||||
LOG_DBG("init sensor, reporter:%s, client:%s, connection:%d",
|
||||
reporter->dev->name, sensor->dev->name, i);
|
||||
|
||||
tmp_conns[i] = conn;
|
||||
}
|
||||
|
||||
/* physical sensor is working at polling mode by default,
|
||||
* virtual sensor working mode is inherited from its reporter
|
||||
*/
|
||||
if (is_phy_sensor(sensor)) {
|
||||
sensor->mode = SENSOR_TRIGGER_MODE_POLLING;
|
||||
}
|
||||
|
||||
return sensor_api->init(sensor->dev, sensor->info, tmp_conns, conns_num);
|
||||
}
|
||||
|
||||
/* create struct sensing_sensor *sensor according to sensor device tree */
|
||||
static int pre_init_sensor(struct sensing_sensor *sensor)
|
||||
{
|
||||
struct sensing_sensor_ctx *sensor_ctx;
|
||||
uint16_t sample_size, total_size;
|
||||
uint16_t conn_sample_size = 0;
|
||||
int i = 0;
|
||||
void *tmp_data;
|
||||
|
||||
__ASSERT(sensor && sensor->dev, "sensor or sensor dev is invalid");
|
||||
sensor_ctx = sensor->dev->data;
|
||||
__ASSERT(sensor_ctx, "sensing sensor context is invalid");
|
||||
|
||||
sample_size = sensor_ctx->register_info->sample_size;
|
||||
for (i = 0; i < sensor->reporter_num; i++) {
|
||||
conn_sample_size += get_reporter_sample_size(sensor, i);
|
||||
}
|
||||
|
||||
/* total memory to be allocated for a sensor according to sensor device tree:
|
||||
* 1) sample data point to struct sensing_sensor->data_buf
|
||||
* 2) size of struct sensing_connection* for sensor connection to its reporter
|
||||
* 3) reporter sample size to be stored in connection data
|
||||
*/
|
||||
total_size = sample_size + sensor->reporter_num * sizeof(*sensor->conns) +
|
||||
conn_sample_size;
|
||||
|
||||
/* total size for different sensor maybe different, for example:
|
||||
* there's no reporter for physical sensor, so no connection memory is needed
|
||||
* reporter num of each virtual sensor may also different, so connection memory is also
|
||||
* varied, so here malloc is a must for different sensor.
|
||||
*/
|
||||
tmp_data = malloc(total_size);
|
||||
if (!tmp_data) {
|
||||
LOG_ERR("malloc memory for sensing_sensor error");
|
||||
return -ENOMEM;
|
||||
}
|
||||
sensor->sample_size = sample_size;
|
||||
sensor->data_buf = tmp_data;
|
||||
sensor->conns = (struct sensing_connection *)((uint8_t *)sensor->data_buf + sample_size);
|
||||
|
||||
tmp_data = sensor->conns + sensor->reporter_num;
|
||||
for (i = 0; i < sensor->reporter_num; i++) {
|
||||
sensor->conns[i].data = tmp_data;
|
||||
tmp_data = (uint8_t *)tmp_data + get_reporter_sample_size(sensor, i);
|
||||
}
|
||||
|
||||
if (tmp_data != ((uint8_t *)sensor->data_buf + total_size)) {
|
||||
LOG_ERR("sensor memory assign error, data_buf:%p, tmp_data:%p, size:%d",
|
||||
sensor->data_buf, tmp_data, total_size);
|
||||
free(sensor->data_buf);
|
||||
sensor->data_buf = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
LOG_INF("pre init sensor, sensor:%s, min_ri:%d(us)",
|
||||
sensor->dev->name, sensor->info->minimal_interval);
|
||||
|
||||
sensor->interval = 0;
|
||||
sensor->sensitivity_count = sensor_ctx->register_info->sensitivity_count;
|
||||
__ASSERT(sensor->sensitivity_count <= CONFIG_SENSING_MAX_SENSITIVITY_COUNT,
|
||||
"sensitivity count:%d should not exceed MAX_SENSITIVITY_COUNT",
|
||||
sensor->sensitivity_count);
|
||||
memset(sensor->sensitivity, 0x00, sizeof(sensor->sensitivity));
|
||||
|
||||
sys_slist_init(&sensor->client_list);
|
||||
|
||||
sensor_ctx->priv_ptr = sensor;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sensing_init(void)
|
||||
{
|
||||
struct sensing_context *ctx = &sensing_ctx;
|
||||
struct sensing_sensor *sensor;
|
||||
enum sensing_sensor_state state;
|
||||
int ret = 0;
|
||||
int i = 0;
|
||||
|
||||
LOG_INF("sensing init begin...");
|
||||
|
||||
if (ctx->sensing_initialized) {
|
||||
LOG_INF("sensing is already initialized");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->sensor_num == 0) {
|
||||
LOG_WRN("no sensor created by device tree yet");
|
||||
return 0;
|
||||
}
|
||||
|
||||
STRUCT_SECTION_FOREACH(sensing_sensor, tmp_sensor) {
|
||||
ret = pre_init_sensor(tmp_sensor);
|
||||
if (ret) {
|
||||
LOG_ERR("sensing init, pre init sensor error");
|
||||
}
|
||||
ctx->sensors[i++] = tmp_sensor;
|
||||
}
|
||||
|
||||
for_each_sensor(ctx, i, sensor) {
|
||||
ret = init_sensor(sensor, sensor->reporter_num);
|
||||
if (ret) {
|
||||
LOG_ERR("sensor:%s initial error", sensor->dev->name);
|
||||
}
|
||||
state = (ret ? SENSING_SENSOR_STATE_OFFLINE : SENSING_SENSOR_STATE_READY);
|
||||
ret = set_sensor_state(sensor, state);
|
||||
if (ret) {
|
||||
LOG_ERR("set sensor:%s state:%d error", sensor->dev->name, state);
|
||||
}
|
||||
LOG_INF("sensing init, sensor:%s state:%d", sensor->dev->name, sensor->state);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int open_sensor(struct sensing_sensor *sensor, struct sensing_connection **conn)
|
||||
{
|
||||
struct sensing_connection *tmp_conn;
|
||||
|
||||
if (sensor->state != SENSING_SENSOR_STATE_READY)
|
||||
return -EINVAL;
|
||||
|
||||
/* allocate struct sensing_connection *conn and conn data for application client */
|
||||
tmp_conn = malloc(sizeof(*tmp_conn) + sensor->sample_size);
|
||||
if (!tmp_conn) {
|
||||
LOG_ERR("malloc memory for struct sensing_connection error");
|
||||
return -ENOMEM;
|
||||
}
|
||||
tmp_conn->data = (uint8_t *)tmp_conn + sizeof(*tmp_conn);
|
||||
|
||||
/* create connection from sensor to application(client = NULL) */
|
||||
init_connection(tmp_conn, sensor, NULL);
|
||||
|
||||
*conn = tmp_conn;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int close_sensor(struct sensing_connection **conn)
|
||||
{
|
||||
struct sensing_connection *tmp_conn = *conn;
|
||||
|
||||
if (tmp_conn == NULL) {
|
||||
LOG_ERR("connection should not be NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
__ASSERT(!tmp_conn->sink, "sensor derived from device tree cannot be closed");
|
||||
|
||||
sys_slist_find_and_remove(&tmp_conn->source->client_list, &tmp_conn->snode);
|
||||
|
||||
*conn = NULL;
|
||||
free(*conn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sensing_register_callback(struct sensing_connection *conn,
|
||||
const struct sensing_callback_list *cb_list)
|
||||
{
|
||||
if (conn == NULL) {
|
||||
LOG_ERR("register sensing callback list, connection not be NULL");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
__ASSERT(!conn->sink, "only connection to application could register sensing callback");
|
||||
|
||||
if (cb_list == NULL) {
|
||||
LOG_ERR("callback should not be NULL");
|
||||
return -ENODEV;
|
||||
}
|
||||
conn->data_evt_cb = cb_list->on_data_event;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_interval(struct sensing_connection *conn, uint32_t interval)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
int get_interval(struct sensing_connection *conn, uint32_t *interval)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
int set_sensitivity(struct sensing_connection *conn, int8_t index, uint32_t sensitivity)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
int get_sensitivity(struct sensing_connection *conn, int8_t index, uint32_t *sensitivity)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
int sensing_get_sensors(int *sensor_nums, const struct sensing_sensor_info **info)
|
||||
{
|
||||
if (info == NULL) {
|
||||
LOG_ERR("sensing_sensor_info should not be NULL");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
STRUCT_SECTION_COUNT(sensing_sensor_info, sensor_nums);
|
||||
|
||||
STRUCT_SECTION_GET(sensing_sensor_info, 0, info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
SYS_INIT(sensing_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
|
||||
|
|
|
|||
|
|
@ -9,16 +9,151 @@
|
|||
|
||||
#include <zephyr/sensing/sensing_datatypes.h>
|
||||
#include <zephyr/sensing/sensing_sensor.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/sys/slist.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct sensing_mgmt_context {
|
||||
bool sensing_initialized;
|
||||
int sensor_num;
|
||||
struct sensing_sensor_info *info;
|
||||
#define PHANDLE_DEVICE_BY_IDX(idx, node, prop) \
|
||||
DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node, prop, idx))
|
||||
|
||||
#define PHANDLE_DEVICE_LIST(node, prop) \
|
||||
{ \
|
||||
LISTIFY(DT_PROP_LEN_OR(node, prop, 0), \
|
||||
PHANDLE_DEVICE_BY_IDX, \
|
||||
(,), \
|
||||
node, \
|
||||
prop) \
|
||||
}
|
||||
|
||||
#define SENSING_SENSOR_INFO_NAME(node) \
|
||||
_CONCAT(__sensing_sensor_info_, DEVICE_DT_NAME_GET(node))
|
||||
|
||||
#define SENSING_SENSOR_INFO_DEFINE(node) \
|
||||
const static STRUCT_SECTION_ITERABLE(sensing_sensor_info, \
|
||||
SENSING_SENSOR_INFO_NAME(node)) = { \
|
||||
.type = DT_PROP(node, sensor_type), \
|
||||
.name = DT_NODE_FULL_NAME(node), \
|
||||
.friendly_name = DT_PROP(node, friendly_name), \
|
||||
.vendor = DT_NODE_VENDOR_OR(node, NULL), \
|
||||
.model = DT_NODE_MODEL_OR(node, NULL), \
|
||||
.minimal_interval = DT_PROP(node, minimal_interval), \
|
||||
};
|
||||
|
||||
#define SENSING_SENSOR_NAME(node) \
|
||||
_CONCAT(__sensing_sensor_, DEVICE_DT_NAME_GET(node))
|
||||
|
||||
#define SENSING_SENSOR_DEFINE(node) \
|
||||
static STRUCT_SECTION_ITERABLE(sensing_sensor, \
|
||||
SENSING_SENSOR_NAME(node)) = { \
|
||||
.dev = DEVICE_DT_GET(node), \
|
||||
.info = &SENSING_SENSOR_INFO_NAME(node), \
|
||||
.reporter_num = DT_PROP_LEN_OR(node, reporters, 0), \
|
||||
.reporters = PHANDLE_DEVICE_LIST(node, reporters), \
|
||||
};
|
||||
|
||||
#define for_each_sensor(ctx, i, sensor) \
|
||||
for (i = 0; i < ctx->sensor_num && (sensor = ctx->sensors[i]) != NULL; i++)
|
||||
|
||||
enum sensor_trigger_mode {
|
||||
SENSOR_TRIGGER_MODE_POLLING = 1,
|
||||
SENSOR_TRIGGER_MODE_DATA_READY = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct sensing_connection information
|
||||
* @brief sensing_connection indicates connection from reporter(source) to client(sink)
|
||||
*/
|
||||
struct sensing_connection {
|
||||
struct sensing_sensor *source;
|
||||
struct sensing_sensor *sink;
|
||||
/* interval and sensitivity set from client(sink) to reporter(source) */
|
||||
uint32_t interval;
|
||||
int sensitivity[CONFIG_SENSING_MAX_SENSITIVITY_COUNT];
|
||||
/* copy sensor data to connection data buf from reporter */
|
||||
void *data;
|
||||
/* client(sink) next consume time */
|
||||
sys_snode_t snode;
|
||||
/* post data to application */
|
||||
sensing_data_event_t data_evt_cb;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct sensing_sensor
|
||||
* @brief Internal sensor instance data structure.
|
||||
*
|
||||
* Each sensor instance will have its unique data structure for storing all
|
||||
* it's related information.
|
||||
*
|
||||
* Sensor management will enumerate all these instance data structures,
|
||||
* build report relationship model base on them, etc.
|
||||
*/
|
||||
struct sensing_sensor {
|
||||
const struct device *dev;
|
||||
const struct sensing_sensor_info *info;
|
||||
const uint16_t reporter_num;
|
||||
sys_slist_t client_list;
|
||||
uint32_t interval;
|
||||
uint8_t sensitivity_count;
|
||||
int sensitivity[CONFIG_SENSING_MAX_SENSITIVITY_COUNT];
|
||||
enum sensing_sensor_state state;
|
||||
enum sensor_trigger_mode mode;
|
||||
/* runtime info */
|
||||
uint16_t sample_size;
|
||||
void *data_buf;
|
||||
struct sensing_connection *conns;
|
||||
const struct device *reporters[];
|
||||
};
|
||||
|
||||
int open_sensor(struct sensing_sensor *sensor, struct sensing_connection **conn);
|
||||
int close_sensor(struct sensing_connection **conn);
|
||||
int sensing_register_callback(struct sensing_connection *conn,
|
||||
const struct sensing_callback_list *cb_list);
|
||||
int set_interval(struct sensing_connection *conn, uint32_t interval);
|
||||
int get_interval(struct sensing_connection *con, uint32_t *sensitivity);
|
||||
int set_sensitivity(struct sensing_connection *conn, int8_t index, uint32_t interval);
|
||||
int get_sensitivity(struct sensing_connection *con, int8_t index, uint32_t *sensitivity);
|
||||
|
||||
|
||||
static inline bool is_phy_sensor(struct sensing_sensor *sensor)
|
||||
{
|
||||
return sensor->reporter_num == 0;
|
||||
}
|
||||
|
||||
static inline uint16_t get_reporter_sample_size(const struct sensing_sensor *sensor, int i)
|
||||
{
|
||||
__ASSERT(i < sensor->reporter_num, "dt index should less than reporter num");
|
||||
|
||||
return ((struct sensing_sensor_ctx *)
|
||||
sensor->reporters[i]->data)->register_info->sample_size;
|
||||
}
|
||||
|
||||
static inline struct sensing_sensor *get_sensor_by_dev(const struct device *dev)
|
||||
{
|
||||
return dev ?
|
||||
(struct sensing_sensor *)((struct sensing_sensor_ctx *)dev->data)->priv_ptr : NULL;
|
||||
}
|
||||
|
||||
static inline struct sensing_sensor *get_reporter_sensor(struct sensing_sensor *sensor, int index)
|
||||
{
|
||||
if (!sensor || index >= sensor->reporter_num) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return get_sensor_by_dev(sensor->reporters[index]);
|
||||
}
|
||||
|
||||
static inline const struct sensing_sensor_info *get_sensor_info(struct sensing_connection *conn)
|
||||
{
|
||||
__ASSERT(conn, "get sensor info, connection not be NULL");
|
||||
|
||||
__ASSERT(conn->source, "get sensor info, sensing_sensor is NULL");
|
||||
|
||||
return conn->source->info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue