blob: 434c13b905251826b9ff30f675df0cc7258f2e8f [file] [log] [blame]
/*
* Copyright (c) 2022-2023 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_SENSING_SENSOR_H_
#define ZEPHYR_INCLUDE_SENSING_SENSOR_H_
#include <stdbool.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/sensing/sensing.h>
/**
* @defgroup sensing_sensor Sensing Sensor API
* @ingroup sensing
* @defgroup sensing_sensor_callbacks Sensor Callbacks
* @ingroup sensing_sensor
*/
/**
* @brief Sensing Sensor API
* @addtogroup sensing_sensor
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Sensor registration information
*
*/
struct sensing_sensor_register_info {
/**
* Sensor flags
*/
uint16_t flags;
/**
* Sample size in bytes for a single sample of the registered sensor.
* sensing runtime need this information for internal buffer allocation.
*/
uint16_t sample_size;
/**
* The number of sensor sensitivities
*/
uint8_t sensitivity_count;
/**
* Sensor version.
* Version can be used to identify different versions of sensor implementation.
*/
struct sensing_sensor_version version;
};
enum {
EVENT_CONFIG_READY,
};
enum {
SENSOR_LATER_CFG_BIT,
};
/**
* @brief Connection between a source and sink of sensor data
*/
struct sensing_connection {
sys_snode_t snode;
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 */
uint64_t next_consume_time;
/* post data to application */
struct sensing_callback_list *callback_list;
};
/**
* @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 struct sensing_sensor_register_info *register_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;
/* runtime info */
struct rtio_iodev *iodev;
struct k_timer timer;
struct rtio_sqe *stream_sqe;
atomic_t flag;
struct sensing_connection *conns;
};
#define SENSING_SENSOR_INFO_NAME(node, idx) \
_CONCAT(_CONCAT(__sensing_sensor_info_, idx), DEVICE_DT_NAME_GET(node))
#define SENSING_SENSOR_INFO_DEFINE(node, idx) \
const static STRUCT_SECTION_ITERABLE(sensing_sensor_info, \
SENSING_SENSOR_INFO_NAME(node, idx)) = { \
.type = DT_PROP_BY_IDX(node, sensor_types, idx), \
.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_CONNECTIONS_NAME(node) \
_CONCAT(__sensing_connections_, DEVICE_DT_NAME_GET(node))
#define SENSING_SENSOR_SOURCE_NAME(idx, node) \
SENSING_SENSOR_NAME(DT_PHANDLE_BY_IDX(node, reporters, idx), \
DT_PROP_BY_IDX(node, reporters_index, idx))
#define SENSING_SENSOR_SOURCE_EXTERN(idx, node) \
extern struct sensing_sensor SENSING_SENSOR_SOURCE_NAME(idx, node); \
#define SENSING_CONNECTION_INITIALIZER(source_name, cb_list_ptr) \
{ \
.callback_list = cb_list_ptr, \
.source = &source_name, \
}
#define SENSING_CONNECTION_DEFINE(idx, node, cb_list_ptr) \
SENSING_CONNECTION_INITIALIZER(SENSING_SENSOR_SOURCE_NAME(idx, node), \
cb_list_ptr)
#define SENSING_CONNECTIONS_DEFINE(node, num, cb_list_ptr) \
LISTIFY(num, SENSING_SENSOR_SOURCE_EXTERN, \
(), node) \
static struct sensing_connection \
SENSING_CONNECTIONS_NAME(node)[(num)] = { \
LISTIFY(num, SENSING_CONNECTION_DEFINE, \
(,), node, cb_list_ptr) \
};
struct sensing_submit_config {
enum sensor_channel chan;
const int info_index;
const bool is_streaming;
};
extern const struct rtio_iodev_api __sensing_iodev_api;
#define SENSING_SUBMIT_CFG_NAME(node, idx) \
_CONCAT(_CONCAT(__sensing_submit_cfg_, idx), DEVICE_DT_NAME_GET(node))
#define SENSING_SENSOR_IODEV_NAME(node, idx) \
_CONCAT(_CONCAT(__sensing_iodev_, idx), DEVICE_DT_NAME_GET(node))
#define SENSING_SENSOR_IODEV_DEFINE(node, idx) \
static struct sensing_submit_config SENSING_SUBMIT_CFG_NAME(node, idx) = { \
.is_streaming = DT_PROP(node, stream_mode), \
.info_index = idx, \
}; \
RTIO_IODEV_DEFINE(SENSING_SENSOR_IODEV_NAME(node, idx), \
&__sensing_iodev_api, \
&SENSING_SUBMIT_CFG_NAME(node, idx));
#define SENSING_SENSOR_NAME(node, idx) \
_CONCAT(_CONCAT(__sensing_sensor_, idx), DEVICE_DT_NAME_GET(node))
#define SENSING_SENSOR_DEFINE(node, prop, idx, reg_ptr, cb_list_ptr) \
SENSING_SENSOR_INFO_DEFINE(node, idx) \
SENSING_SENSOR_IODEV_DEFINE(node, idx) \
STRUCT_SECTION_ITERABLE(sensing_sensor, \
SENSING_SENSOR_NAME(node, idx)) = { \
.dev = DEVICE_DT_GET(node), \
.info = &SENSING_SENSOR_INFO_NAME(node, idx), \
.register_info = reg_ptr, \
.reporter_num = DT_PROP_LEN_OR(node, reporters, 0), \
.conns = SENSING_CONNECTIONS_NAME(node), \
.iodev = &SENSING_SENSOR_IODEV_NAME(node, idx), \
};
#define SENSING_SENSORS_DEFINE(node, reg_ptr, cb_list_ptr) \
DT_FOREACH_PROP_ELEM_VARGS(node, sensor_types, \
SENSING_SENSOR_DEFINE, reg_ptr, cb_list_ptr)
/**
* @brief Like SENSOR_DEVICE_DT_DEFINE() with sensing specifics.
*
* @details Defines a sensor which implements the sensor API. May define an
* element in the sensing sensor iterable section used to enumerate all sensing
* sensors.
*
* @param node The devicetree node identifier.
*
* @param reg_ptr Pointer to the device's sensing_sensor_register_info.
*
* @param cb_list_ptr Pointer to devices callback list.
*
* @param init_fn Name of the init function of the driver.
*
* @param pm_device PM device resources reference (NULL if device does not use
* PM).
*
* @param data_ptr Pointer to the device's private data.
*
* @param cfg_ptr The address to the structure containing the configuration
* information for this instance of the driver.
*
* @param level The initialization level. See SYS_INIT() for details.
*
* @param prio Priority within the selected initialization level. See
* SYS_INIT() for details.
*
* @param api_ptr Provides an initial pointer to the API function struct used
* by the driver. Can be NULL.
*/
#define SENSING_SENSORS_DT_DEFINE(node, reg_ptr, cb_list_ptr, \
init_fn, pm_device, \
data_ptr, cfg_ptr, level, prio, \
api_ptr, ...) \
SENSOR_DEVICE_DT_DEFINE(node, init_fn, pm_device, \
data_ptr, cfg_ptr, level, prio, \
api_ptr, __VA_ARGS__); \
SENSING_CONNECTIONS_DEFINE(node, \
DT_PROP_LEN_OR(node, reporters, 0), \
cb_list_ptr); \
SENSING_SENSORS_DEFINE(node, reg_ptr, cb_list_ptr);
/**
* @brief Like SENSING_SENSORS_DT_DEFINE() for an instance of a DT_DRV_COMPAT
* compatible
*
* @param inst instance number. This is replaced by
* <tt>DT_DRV_COMPAT(inst)</tt> in the call to SENSING_SENSORS_DT_DEFINE().
*
* @param ... other parameters as expected by SENSING_SENSORS_DT_DEFINE().
*/
#define SENSING_SENSORS_DT_INST_DEFINE(inst, ...) \
SENSING_SENSORS_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
/**
* @brief Get reporter handles of a given sensor instance by sensor type.
*
* @param dev The sensor instance device structure.
*
* @param type The given type, \ref SENSING_SENSOR_TYPE_ALL to get reporters
* with all types.
*
* @param max_handles The max count of the \p reporter_handles array input. Can
* get real count number via \ref sensing_sensor_get_reporters_count
*
* @param reporter_handles Input handles array for receiving found reporter
* sensor instances
*
* @return number of reporters found, 0 returned if not found.
*/
int sensing_sensor_get_reporters(
const struct device *dev, int type,
sensing_sensor_handle_t *reporter_handles, int max_handles);
/**
* @brief Get reporters count of a given sensor instance by sensor type.
*
* @param dev The sensor instance device structure.
*
* @param type The sensor type for checking, \ref SENSING_SENSOR_TYPE_ALL
*
* @return Count of reporters by \p type, 0 returned if no reporters by \p type.
*/
int sensing_sensor_get_reporters_count(
const struct device *dev, int type);
/**
* @brief Get this sensor's state
*
* @param dev The sensor instance device structure.
*
* @param state Returned sensor state value
*
* @return 0 on success or negative error value on failure.
*/
int sensing_sensor_get_state(
const struct device *dev,
enum sensing_sensor_state *state);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /*ZEPHYR_INCLUDE_SENSING_SENSOR_H_*/