2023-02-06 09:43:11 +01:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2023 Intel Corporation.
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
#include <zephyr/sys/__assert.h>
|
|
|
|
#include <zephyr/devicetree.h>
|
2023-08-29 12:19:30 +02:00
|
|
|
#include <zephyr/init.h>
|
2023-02-06 09:43:11 +01:00
|
|
|
#include <zephyr/kernel.h>
|
|
|
|
#include <zephyr/sensing/sensing.h>
|
|
|
|
#include <zephyr/sensing/sensing_sensor.h>
|
|
|
|
#include <zephyr/logging/log.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "sensor_mgmt.h"
|
|
|
|
|
|
|
|
#define DT_DRV_COMPAT zephyr_sensing
|
|
|
|
|
2023-05-19 04:26:13 +02:00
|
|
|
BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1,
|
|
|
|
"only one 'zephyr_sensing' compatible node may be present");
|
|
|
|
|
2023-02-06 09:43:11 +01:00
|
|
|
LOG_MODULE_REGISTER(sensing, CONFIG_SENSING_LOG_LEVEL);
|
|
|
|
|
2023-05-19 04:26:13 +02:00
|
|
|
static struct sensing_context sensing_ctx = {
|
|
|
|
};
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
2023-10-23 09:30:57 +02:00
|
|
|
if (source) {
|
|
|
|
conn->source = source;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sink) {
|
|
|
|
conn->sink = sink;
|
|
|
|
}
|
|
|
|
|
2023-05-19 04:26:13 +02:00
|
|
|
conn->interval = 0;
|
|
|
|
memset(conn->sensitivity, 0x00, sizeof(conn->sensitivity));
|
|
|
|
/* link connection to its reporter's client_list */
|
2023-10-23 09:30:57 +02:00
|
|
|
sys_slist_append(&conn->source->client_list, &conn->snode);
|
2023-05-19 04:26:13 +02:00
|
|
|
}
|
|
|
|
|
2023-10-23 09:30:57 +02:00
|
|
|
static int init_sensor(struct sensing_sensor *sensor)
|
2023-05-19 04:26:13 +02:00
|
|
|
{
|
|
|
|
struct sensing_connection *conn;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
__ASSERT(sensor && sensor->dev, "init sensor, sensor or sensor device is NULL");
|
|
|
|
|
2023-10-23 09:30:57 +02:00
|
|
|
sys_slist_init(&sensor->client_list);
|
2023-05-19 04:26:13 +02:00
|
|
|
|
|
|
|
for (i = 0; i < sensor->reporter_num; i++) {
|
2023-10-23 09:30:57 +02:00
|
|
|
conn = &sensor->conns[i];
|
2023-05-19 04:26:13 +02:00
|
|
|
|
2023-10-23 09:30:57 +02:00
|
|
|
/* source sensor has been assigned in compile time */
|
|
|
|
init_connection(conn, NULL, sensor);
|
2023-05-19 04:26:13 +02:00
|
|
|
|
2023-10-23 09:30:57 +02:00
|
|
|
LOG_INF("init sensor, reporter:%s, client:%s, connection:%d(%p)",
|
|
|
|
conn->source->dev->name, sensor->dev->name, i, conn);
|
2023-05-19 04:26:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2023-02-06 09:43:11 +01:00
|
|
|
|
2023-10-23 09:30:57 +02:00
|
|
|
static int sensing_init(const struct device *dev)
|
2023-05-19 04:26:13 +02:00
|
|
|
{
|
2023-10-23 09:30:57 +02:00
|
|
|
struct sensing_context *ctx = dev->data;
|
2023-05-19 04:26:13 +02:00
|
|
|
enum sensing_sensor_state state;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
LOG_INF("sensing init begin...");
|
|
|
|
|
2023-10-23 09:30:57 +02:00
|
|
|
for_each_sensor(sensor) {
|
|
|
|
ret = init_sensor(sensor);
|
2023-05-19 04:26:13 +02:00
|
|
|
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);
|
|
|
|
}
|
2023-10-23 09:30:57 +02:00
|
|
|
LOG_INF("sensing init, sensor:%s, state:%d", sensor->dev->name, sensor->state);
|
2023-05-19 04:26:13 +02:00
|
|
|
}
|
|
|
|
|
2023-10-23 09:30:57 +02:00
|
|
|
k_sem_init(&ctx->event_sem, 0, 1);
|
|
|
|
|
|
|
|
LOG_INF("create sensing runtime thread ok");
|
|
|
|
ctx->sensing_initialized = true;
|
|
|
|
|
2023-05-19 04:26:13 +02:00
|
|
|
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;
|
|
|
|
|
2023-10-23 09:30:57 +02:00
|
|
|
/* create connection from sensor to application(client = NULL) */
|
|
|
|
tmp_conn = malloc(sizeof(*tmp_conn));
|
2023-05-19 04:26:13 +02:00
|
|
|
if (!tmp_conn) {
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
2023-10-23 09:30:57 +02:00
|
|
|
__ASSERT(tmp_conn->source, "reporter should not be NULL");
|
|
|
|
|
2023-05-19 04:26:13 +02:00
|
|
|
sys_slist_find_and_remove(&tmp_conn->source->client_list, &tmp_conn->snode);
|
|
|
|
|
|
|
|
free(*conn);
|
2023-10-23 09:30:57 +02:00
|
|
|
*conn = NULL;
|
2023-05-19 04:26:13 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2023-10-23 09:30:57 +02:00
|
|
|
conn->callback_list = *cb_list;
|
2023-05-19 04:26:13 +02:00
|
|
|
|
|
|
|
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)
|
2023-02-06 09:43:11 +01:00
|
|
|
{
|
|
|
|
return -ENOTSUP;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sensing_get_sensors(int *sensor_nums, const struct sensing_sensor_info **info)
|
|
|
|
{
|
2023-05-19 04:26:13 +02:00
|
|
|
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);
|
|
|
|
|
2023-02-06 09:43:11 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-05-19 04:26:13 +02:00
|
|
|
|
2023-10-23 09:30:57 +02:00
|
|
|
DEVICE_DT_INST_DEFINE(0, sensing_init, NULL, &sensing_ctx, NULL, \
|
|
|
|
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, NULL);
|