From 0a11578bf4a506a7ce0b4536b7c8dde82cef1e1c Mon Sep 17 00:00:00 2001 From: Yuval Peress Date: Tue, 27 Jun 2023 01:15:17 -0600 Subject: [PATCH] Rework sensing subsystem Signed-off-by: Yuval Peress --- dts/bindings/sensing/zephyr,sensing-pipe.yaml | 43 ++ .../sensor/zephyr,sensing-phy-sensor.yaml | 13 - .../sensor/zephyr,sensing-sensor.yaml | 25 - dts/bindings/sensor/zephyr,sensing.yaml | 9 - .../sensor/zephyr,senss-phy-3d-sensor.yaml | 9 - include/zephyr/drivers/sensor.h | 11 +- .../{sensing_datatypes.h => datatypes.h} | 0 include/zephyr/sensing/sensing.h | 77 +-- include/zephyr/sensing/sensing_sensor.h | 594 ------------------ include/zephyr/sensing/sensor.h | 59 ++ ...{sensing_sensor_types.h => sensor_types.h} | 6 +- subsys/sensing/CMakeLists.txt | 9 +- subsys/sensing/Kconfig | 16 +- subsys/sensing/sensing.c | 145 ----- subsys/sensing/sensing_sensor.c | 28 - .../sensor/phy_3d_sensor/CMakeLists.txt | 3 - subsys/sensing/sensor/phy_3d_sensor/Kconfig | 9 - .../sensor/phy_3d_sensor/phy_3d_sensor.c | 100 --- .../sensor/phy_3d_sensor/phy_3d_sensor.h | 20 - subsys/sensing/sensor_mgmt.c | 323 ---------- subsys/sensing/sensor_mgmt.h | 166 ----- subsys/sensing/src/sensor_info.c | 14 + subsys/sensing/src/sensor_pipe.c | 29 + tests/subsys/sensing/list/CMakeLists.txt | 8 + .../sensing/list/boards/native_posix.overlay | 23 + tests/subsys/sensing/list/prj.conf | 15 + tests/subsys/sensing/list/src/main.c | 48 ++ tests/subsys/sensing/list/testcase.yaml | 9 + 28 files changed, 269 insertions(+), 1542 deletions(-) create mode 100644 dts/bindings/sensing/zephyr,sensing-pipe.yaml delete mode 100644 dts/bindings/sensor/zephyr,sensing-phy-sensor.yaml delete mode 100644 dts/bindings/sensor/zephyr,sensing-sensor.yaml delete mode 100644 dts/bindings/sensor/zephyr,sensing.yaml delete mode 100644 dts/bindings/sensor/zephyr,senss-phy-3d-sensor.yaml rename include/zephyr/sensing/{sensing_datatypes.h => datatypes.h} (100%) delete mode 100644 include/zephyr/sensing/sensing_sensor.h create mode 100644 include/zephyr/sensing/sensor.h rename include/zephyr/sensing/{sensing_sensor_types.h => sensor_types.h} (83%) delete mode 100644 subsys/sensing/sensing.c delete mode 100644 subsys/sensing/sensing_sensor.c delete mode 100644 subsys/sensing/sensor/phy_3d_sensor/CMakeLists.txt delete mode 100644 subsys/sensing/sensor/phy_3d_sensor/Kconfig delete mode 100644 subsys/sensing/sensor/phy_3d_sensor/phy_3d_sensor.c delete mode 100644 subsys/sensing/sensor/phy_3d_sensor/phy_3d_sensor.h delete mode 100644 subsys/sensing/sensor_mgmt.c delete mode 100644 subsys/sensing/sensor_mgmt.h create mode 100644 subsys/sensing/src/sensor_info.c create mode 100644 subsys/sensing/src/sensor_pipe.c create mode 100644 tests/subsys/sensing/list/CMakeLists.txt create mode 100644 tests/subsys/sensing/list/boards/native_posix.overlay create mode 100644 tests/subsys/sensing/list/prj.conf create mode 100644 tests/subsys/sensing/list/src/main.c create mode 100644 tests/subsys/sensing/list/testcase.yaml diff --git a/dts/bindings/sensing/zephyr,sensing-pipe.yaml b/dts/bindings/sensing/zephyr,sensing-pipe.yaml new file mode 100644 index 000000000000000..c5a91d0725f4061 --- /dev/null +++ b/dts/bindings/sensing/zephyr,sensing-pipe.yaml @@ -0,0 +1,43 @@ +# Copyright (c) 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +description: Passthrough sensor type which enables the sensing subsystem to communicate with physical devices + +compatible: "zephyr,sensing-pipe" + +include: [sensor-device.yaml, base.yaml] + +properties: + dev: + type: phandle + required: true + description: Physical device which provides the data + + sensor-types: + type: array + required: true + description: | + One or more sensor data types that are provided by this device. For + example, a 'dev' pointing to a bmi160 may report accel/gyro/die_temp or + any subset of those types. + + rotation-matrix: + type: array + description: | + 3x3 matrix to rotation x, y, and z axes. + In order to make application logic agnostic to how the device was placed + on the board, it's possible to enter the rotation matrix which will be + applied to every sample produced by this sensor. The final orientation + will be: + * X-axis is horizontal and positive toward the right + * Y-axis is vertical and positive toward the top + * Z-axis is depth and positive toward the user + + If not provided, the rotation matrix will be the identity matrix. + Otherwise, the following will be used: + + +- -+ +- -+ +- -+ + | v1 v2 v3 | | sensor_X | = | X | + | v4 v5 v6 | * | sensor_Y | = | Y | + | v7 v8 v9 | | sensor_Z | = | Z | + +- -+ +- -+ +- -+ diff --git a/dts/bindings/sensor/zephyr,sensing-phy-sensor.yaml b/dts/bindings/sensor/zephyr,sensing-phy-sensor.yaml deleted file mode 100644 index 8219f77a210392d..000000000000000 --- a/dts/bindings/sensor/zephyr,sensing-phy-sensor.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2023, Intel Corporation -# SPDX-License-Identifier: Apache-2.0 -# - -description: Sensing subsystem physical sensor properties bindings. - -include: zephyr,sensing-sensor.yaml - -properties: - underlying-device: - type: phandle - required: true - description: underlying sensor device for physical sensor diff --git a/dts/bindings/sensor/zephyr,sensing-sensor.yaml b/dts/bindings/sensor/zephyr,sensing-sensor.yaml deleted file mode 100644 index 5bcaa39f2570e00..000000000000000 --- a/dts/bindings/sensor/zephyr,sensing-sensor.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (c) 2023, Intel Corporation -# SPDX-License-Identifier: Apache-2.0 -# - -description: Sensing subsystem sensor common properties bindings. - -include: sensor-device.yaml - -properties: - sensor-type: - type: int - required: true - description: sensor type id (follow HID spec definition) - - friendly-name: - required: true - - minimal-interval: - type: int - required: true - description: sensor minimal report interval - - reporters: - type: phandles - description: sensor reporters diff --git a/dts/bindings/sensor/zephyr,sensing.yaml b/dts/bindings/sensor/zephyr,sensing.yaml deleted file mode 100644 index 00b5452a8471a49..000000000000000 --- a/dts/bindings/sensor/zephyr,sensing.yaml +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2023, Intel Corporation -# SPDX-License-Identifier: Apache-2.0 -# - -description: Sensing Subsystem - -compatible: "zephyr,sensing" - -# To add sensor subsystem related common feature diff --git a/dts/bindings/sensor/zephyr,senss-phy-3d-sensor.yaml b/dts/bindings/sensor/zephyr,senss-phy-3d-sensor.yaml deleted file mode 100644 index ed8cb8af19495c6..000000000000000 --- a/dts/bindings/sensor/zephyr,senss-phy-3d-sensor.yaml +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2023, Intel Corporation -# SPDX-License-Identifier: Apache-2.0 -# - -description: Sensing subsystem physical 3d sensors(accel, gyro, mag) bindings. - -compatible: "zephyr,sensing-phy-3d-sensor" - -include: zephyr,sensing-phy-sensor.yaml diff --git a/include/zephyr/drivers/sensor.h b/include/zephyr/drivers/sensor.h index 6abe9725d0219f8..fb8c2974045088d 100644 --- a/include/zephyr/drivers/sensor.h +++ b/include/zephyr/drivers/sensor.h @@ -1210,7 +1210,7 @@ struct sensor_info { } #define SENSOR_INFO_DEFINE(name, ...) \ - static const STRUCT_SECTION_ITERABLE(sensor_info, name) = \ + const STRUCT_SECTION_ITERABLE(sensor_info, name) = \ SENSOR_INFO_INITIALIZER(__VA_ARGS__) #define SENSOR_INFO_DT_NAME(node_id) \ @@ -1221,7 +1221,14 @@ struct sensor_info { DEVICE_DT_GET(node_id), \ DT_NODE_VENDOR_OR(node_id, NULL), \ DT_NODE_MODEL_OR(node_id, NULL), \ - DT_PROP_OR(node_id, friendly_name, NULL)) \ + DT_PROP_OR(node_id, friendly_name, NULL)) + +#if defined(CONFIG_HAS_DTS) || defined(__DOXYGEN__) +#define Z_MAYBE_SENSOR_INFO_DECLARE_INTERNAL(node_id) \ + extern const struct sensor_info SENSOR_INFO_DT_NAME(node_id); + +DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_SENSOR_INFO_DECLARE_INTERNAL); +#endif /* CONFIG_HAS_DTS || __DOXYGEN__ */ #else diff --git a/include/zephyr/sensing/sensing_datatypes.h b/include/zephyr/sensing/datatypes.h similarity index 100% rename from include/zephyr/sensing/sensing_datatypes.h rename to include/zephyr/sensing/datatypes.h diff --git a/include/zephyr/sensing/sensing.h b/include/zephyr/sensing/sensing.h index 3b11d1b410ca4aa..c80afe59936a025 100644 --- a/include/zephyr/sensing/sensing.h +++ b/include/zephyr/sensing/sensing.h @@ -17,9 +17,10 @@ * @ingroup sensing */ -#include -#include #include +#include +#include +#include /** * @brief Sensing Subsystem API @@ -82,17 +83,6 @@ enum sensing_sensor_state { SENSING_SENSOR_STATE_OFFLINE = 1, }; -/** - * @brief Sensing subsystem sensor config attribute - * - */ -enum sensing_sensor_attribute { - SENSING_SENSOR_ATTRIBUTE_INTERVAL = 0, - SENSING_SENSOR_ATTRIBUTE_SENSITIVITY = 1, - SENSING_SENSOR_ATTRIBUTE_LATENCY = 2, - SENSING_SENSOR_ATTRIBUTE_MAX, -}; - /** * @brief Define Sensing subsystem sensor handle @@ -118,23 +108,10 @@ typedef void (*sensing_data_event_t)( * */ struct sensing_sensor_info { - /** Name of the sensor instance */ - const char *name; - - /** Friendly name of the sensor instance */ - const char *friendly_name; - - /** Vendor name of the sensor instance */ - const char *vendor; - - /** Model name of the sensor instance */ - const char *model; + const struct sensor_info * info; /** Sensor type */ - const int32_t type; - - /** Minimal report interval in micro seconds */ - const uint32_t minimal_interval; + int32_t type; }; /** @@ -145,20 +122,6 @@ struct sensing_sensor_info { struct sensing_callback_list { sensing_data_event_t on_data_event; }; -/** - * @struct sensing_sensor_config - * @brief Sensing subsystem sensor configure, including interval, sensitivity, latency - * - */ -struct sensing_sensor_config { - enum sensing_sensor_attribute attri; - int8_t data_field; - union { - uint32_t interval; - uint32_t sensitivity; - uint64_t latency; - }; -}; /** @@ -227,36 +190,6 @@ int sensing_open_sensor_by_dt( int sensing_close_sensor( sensing_sensor_handle_t *handle); -/** - * @brief Set current config items to Sensing subsystem. - * - * @param handle The sensor instance handle. - * - * @param configs The configs to be set according to config attribute. - * - * @param count count of configs. - * - * @return 0 on success or negative error value on failure, not support etc. - */ -int sensing_set_config( - sensing_sensor_handle_t handle, - struct sensing_sensor_config *configs, int count); - -/** - * @brief Get current config items from Sensing subsystem. - * - * @param handle The sensor instance handle. - * - * @param configs The configs to be get according to config attribute. - * - * @param count count of configs. - * - * @return 0 on success or negative error value on failure, not support etc. - */ -int sensing_get_config( - sensing_sensor_handle_t handle, - struct sensing_sensor_config *configs, int count); - /** * @brief Get sensor information from sensor instance handle. * diff --git a/include/zephyr/sensing/sensing_sensor.h b/include/zephyr/sensing/sensing_sensor.h deleted file mode 100644 index e7716a317d8e81f..000000000000000 --- a/include/zephyr/sensing/sensing_sensor.h +++ /dev/null @@ -1,594 +0,0 @@ -/* - * 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 -#include -#include -#include - -/** - * @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; -}; - -/** - * @brief Sensor context data structure - * - */ -struct sensing_sensor_ctx { - - /** - * For sensing runtime internal private data, sensor should not see and touch - */ - void *priv_ptr; - - /** - * Pointer to the sensor register information. - */ - const struct sensing_sensor_register_info *register_info; - - /** - * For sensor private context data, registered by sensor with \ref SENSING_SENSOR_DT_DEFINE. - * Sensor could use \ref sensing_sensor_get_ctx_data to fetch out this filed with - * struct device. - */ - void *const sensor_ctx_ptr; -}; - -static inline int sensing_sensor_dev_init( - const struct device *dev) -{ - /** - * Nothing need to do in system auto initialization. - * Sensor subsystem runtime will call each sensor instance's initialization - * function via API callback according sensor reporting dependency sequences. - * Sensor subsystem can make sure the depends sensor instances always initialized before - * client sensors. - */ - return 0; -} - -/** - * @brief Macro for define a sensor instance from device tree node id - * - * This macro also defined a struct device for this sensor instance, and registered sensors' - * private context data, configuration data structure and API. - * - * sensing_init will enumerate all sensor instances from device tree, and initialize each sensor - * instance defined by this macro. - * - */ - -#define SENSING_SENSOR_DT_DEFINE(node_id, reg_ptr, ctx_ptr, api_ptr) \ - static struct sensing_sensor_ctx \ - _CONCAT(__sensing_sensor_ctx_, Z_DEVICE_DT_DEV_ID(node_id)) = { \ - .register_info = reg_ptr, \ - .sensor_ctx_ptr = ctx_ptr, \ - }; \ - DEVICE_DT_DEFINE(node_id, sensing_sensor_dev_init, NULL, \ - &_CONCAT(__sensing_sensor_ctx_, Z_DEVICE_DT_DEV_ID(node_id)), \ - NULL, APPLICATION, 10, api_ptr) - -/** - * @brief Get registered context data pointer for a sensor instance. - * - * Used by a sensor instance to get its registered context data pointer with its struct device. - * - * @param dev The sensor instance device structure. - */ -static inline void *sensing_sensor_get_ctx_data( - const struct device *dev) -{ - struct sensing_sensor_ctx *data = dev->data; - - return data->sensor_ctx_ptr; -} - -/** - * @brief Post sensor data, sensor subsystem runtime will deliver to it's - * clients. - * - * Unblocked function, returned immediately. - * - * Used by a virtual sensor to post data to it's clients. - * - * A reporter sensor can use this API to post data to it's clients. - * For example, when a virtual sensor computed a data, then can use this API - * to deliver the data to it's clients. - * Please note, this API just for reporter post data to the sensor subsystem - * runtime, the runtime will help delivered the data to it's all clients - * according clients' configurations such as reporter interval, data change sensitivity. - * - * @param dev The sensor instance device structure. - * - * @param buf The data buffer. - * - * @param size The buffer size in bytes. - * - * @return 0 on success or negative error value on failure. - */ -int sensing_sensor_post_data( - const struct device *dev, - void *buf, int size); - -/** - * @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, - const int *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); - -/** - * @brief Trigger the data ready event to sensing - * - * @param dev Pointer to the sensor device - * - * @return 0 on success or negative error value on failure. - */ -int sensing_sensor_notify_data_ready( - const struct device *dev); - -/** - * @brief Set the data ready mode of the sensor - * - * @param dev Pointer to the sensor device - * - * @param data_ready Enable/disable the data ready mode. Default:disabled - * - * @return 0 on success or negative error value on failure. - */ -int sensing_sensor_set_data_ready( - const struct device *dev, bool data_ready); - -/** - * @} - */ - -/** - * @brief Sensor Callbacks - * @addtogroup sensing_sensor_callbacks - * \{ - */ - -/** - * @brief Sensor initialize. - * - * Sensor can initialize it's runtime context in this callback. - * - * @param dev The sensor instance device structure. - * - * @param info The sensor instance's constant information. - * - * @param reporter_handles The reporters handles for this sensor, NULL for physical sensors. - * - * @param reporters_count The number of reporters, zero for physical sensors. - * - * @return 0 on success or negative error value on failure. - * - */ -typedef int (*sensing_sensor_init_t)( - const struct device *dev, const struct sensing_sensor_info *info, - const sensing_sensor_handle_t *reporter_handles, int reporters_count); - -/** - * @brief Sensor's de-initialize. - * - * Sensor can release it's runtime context in this callback. - * - * @param dev The sensor instance device structure. - * - * @return 0 on success or negative error value on failure. - * - */ -typedef int (*sensing_sensor_deinit_t)( - const struct device *dev); - -/** - * @brief Sensor reset. - * - * Sensor can reset its runtime context in this callback to default values without resources - * release and re-allocation. - * - * Its very useful for a virtual sensor to quickly reset its runtime context to a default state. - * - * @param dev The sensor instance device structure. - * - * @return 0 on success or negative error value on failure. - * - */ -typedef int (*sensing_sensor_reset_t)( - const struct device *dev); - -/** - * @brief Sensor read sample. - * - * Only physical sensor need implement this callback. - * Physical sensor can fetch sample data from sensor device in this callback - * - * @param dev The sensor instance device structure. - * - * @param buf Sensor subsystem runtime allocated buffer, and passed its pointer - * to this sensor for store fetched sample. - * - * @param size The size of the buffer in bytes. - * - * @return 0 on success or negative error value on failure. - * - */ -typedef int (*sensing_sensor_read_sample_t)( - const struct device *dev, - void *buf, int size); - -/** - * @brief Sensor process data. - * - * Only virtual sensor need implement this callback. - * Virtual sensor can receive reporter's data and do fusion computing - * in this callback. - * - * @param dev The sensor instance device structure. - * - * @param reporter The reporter handle who delivered this sensor data - * - * @param buf The buffer stored the reporter's sensor data. - * - * @param size The size of the buffer in bytes. - * - * @return 0 on success or negative error value on failure. - * - */ -typedef int (*sensing_sensor_process_t)( - const struct device *dev, - int reporter, - void *buf, int size); - -/** - * @brief Trigger a sensor to do self calibration - * - * If not support self calibration, can not implement this callback. - * - * @param dev The sensor instance device structure. - * - * @return 0 on success or negative error value on failure. - * - */ -typedef int (*sensing_sensor_self_calibration_t)( - const struct device *dev); - -/** - * @brief Sensitivity arbitration. - * - * This callback API provides a chance for sensor to do customized arbitration on data change - * sensitivity. - * The sensor can check two sequential samples with client's sensitivity value (passed with - * parameters in this callback) and decide if can pass the sensor sample to its client. - * - * @param dev The sensor instance device structure. - * - * @param index The value fields index to be set, -1 for all fields (global). - * - * @param sensitivity The sensitivity value. - * - * @param last_sample_buf The buffer stored last sample data. - * - * @param last_sample_size The size of last sample's data buffer in bytes - * - * @param current_sample_buf The buffer stored current sample data. - * - * @param current_sample_size The size of current sample's data buffer in bytes - * - * @return 0 on test passed or negative error value on failure. - * - */ -typedef int (*sensing_sensor_sensitivity_test_t)( - const struct device *dev, - int index, uint32_t sensitivity, - void *last_sample_buf, int last_sample_size, - void *current_sample_buf, int current_sample_size); - -/** - * @brief Set current report interval. - * - * @param dev The sensor instance device structure. - * - * @param value The value to be set. - * - * @return 0 on success or negative error value on failure. - * - */ -typedef int (*sensing_sensor_set_interval_t)( - const struct device *dev, - uint32_t value); - -/** - * @brief Get current report interval. - * - * @param dev The sensor instance device structure. - * - * @param value The data buffer to receive value. - * - * @return 0 on success or negative error value on failure. - * - */ -typedef int (*sensing_sensor_get_interval_t)( - const struct device *dev, - uint32_t *value); - -/** - * @brief Set data change sensitivity. - * - * Since each sensor type may have multiple data fields for it's value, this - * API support set separated sensitivity for each data field, or global - * sensitivity for all data fields. - * - * @param dev The sensor instance device structure. - * - * @param index The value fields index to be set, -1 for all fields (global). - * - * @param value The value to be set. - * - * @return 0 on success or negative error value on failure. - * - */ -typedef int (*sensing_sensor_set_sensitivity_t)( - const struct device *dev, - int index, uint32_t value); - -/** - * @brief Get current data change sensitivity. - * - * Since each sensor type may have multiple data fields for it's value, this - * API support get separated sensitivity for each data field, or global - * sensitivity for all data fields. - * - * @param dev The sensor instance device structure. - * - * @param index The value fields index to be set, -1 for all fields (global). - * - * @param value The data buffer to receive value. - * - * @return 0 on success or negative error value on failure, not support etc. - */ -typedef int (*sensing_sensor_get_sensitivity_t)( - const struct device *dev, - int index, uint32_t *value); - -/** - * @brief Set data range. - * - * Some sensors especially for physical sensors, support data range - * configuration, this may change data resolution. - * - * Since each sensor type may have multiple data fields for it's value, this - * API support set separated range for each data field, or global range for - * all data fields. - * - * @param dev The sensor instance device structure. - * - * @param index The value fields index to be set, -1 for all fields (global). - * - * @param value The value to be set. - * - * @return 0 on success or negative error value on failure, not support etc. - */ -typedef int (*sensing_sensor_set_range_t)( - const struct device *dev, - int index, uint32_t value); - -/** - * @brief Get current data range. - * - * Some sensors especially for physical sensors, support data range - * configuration, this may change data resolution. - * - * Since each sensor type may have multiple data fields for it's value, this - * API support get separated range for each data field, or global range for - * all data fields. - * - * @param dev The sensor instance device structure. - * - * @param index The value fields index to be set, -1 for all fields (global). - * - * @param value The data buffer to receive value. - * - * @return 0 on success or negative error value on failure, not support etc. - */ -typedef int (*sensing_sensor_get_range_t)( - const struct device *dev, - int index, uint32_t *value); - -/** - * @brief Set current sensor's hardware fifo size - * - * Some sensors especially for physical sensors, support hardware fifo, this API can - * configure the current fifo size. - * - * @param dev The sensor instance device structure. - * - * @param samples The sample number to set for fifo. - * - * @return 0 on success or negative error value on failure, not support etc. - */ -typedef int (*sensing_sensor_set_fifo_t)( - const struct device *dev, - uint32_t samples); - -/** - * @brief Get current sensor's hardware fifo size - * - * Some sensors especially for physical sensors, support fifo, this API can - * get the current fifo size. - * - * @param dev The sensor instance device structure. - * - * @param samples The data buffer to receive the fifo sample number. - * - * @return 0 on success or negative error value on failure, not support etc. - */ -typedef int (*sensing_sensor_get_fifo_t)( - const struct device *dev, - uint32_t *samples); - -/** - * @brief Set current sensor data offset - * - * Some sensors especially for physical sensors, such as accelerometer senors, - * as data drift, need configure offset calibration. - * - * Since each sensor type may have multiple data fields for it's value, this - * API support set separated offset for each data field, or global offset for - * all data fields. - * - * @param dev The sensor instance device structure. - * - * @param index The value fields index to be set, -1 for all fields (global). - * - * @param value The offset value to be set. - * - * @return 0 on success or negative error value on failure, not support etc. - */ -typedef int (*sensing_sensor_set_offset_t)( - const struct device *dev, - int index, int32_t value); - -/** - * @brief Get current sensor data offset - * - * Some sensors especially for physical sensors, such as accelerometer senors, - * as data drift, need configure offset calibration. - * - * Since each sensor type may have multiple data fields for it's value, this - * API support get separated offset for each data field, or global offset for - * all data fields. - * - * @param dev The sensor instance device structure. - * - * @param index The value fields index to be set, -1 for all fields (global). - * - * @param value The data buffer to receive the offset value. - * - * @return 0 on success or negative error value on failure, not support etc. - */ -typedef int (*sensing_sensor_get_offset_t)( - const struct device *dev, - int index, int32_t *value); -/** - * @struct sensing_sensor_api - * @brief Sensor callback api - * - * A sensor must register this callback API during sensor registration. - */ -struct sensing_sensor_api { - sensing_sensor_init_t init; - sensing_sensor_reset_t reset; - sensing_sensor_deinit_t deinit; - sensing_sensor_set_interval_t set_interval; - sensing_sensor_get_interval_t get_interval; - sensing_sensor_set_range_t set_range; - sensing_sensor_get_range_t get_range; - sensing_sensor_set_offset_t set_offset; - sensing_sensor_get_offset_t get_offset; - sensing_sensor_get_fifo_t get_fifo; - sensing_sensor_set_fifo_t set_fifo; - sensing_sensor_set_sensitivity_t set_sensitivity; - sensing_sensor_get_sensitivity_t get_sensitivity; - sensing_sensor_read_sample_t read_sample; - sensing_sensor_process_t process; - sensing_sensor_sensitivity_test_t sensitivity_test; - sensing_sensor_self_calibration_t self_calibration; -}; - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /*ZEPHYR_INCLUDE_SENSING_SENSOR_H_*/ diff --git a/include/zephyr/sensing/sensor.h b/include/zephyr/sensing/sensor.h new file mode 100644 index 000000000000000..434f9b7357403bf --- /dev/null +++ b/include/zephyr/sensing/sensor.h @@ -0,0 +1,59 @@ +/* + * 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 +#include +#include + +#define SENSING_SENSOR_INFO_DT_NAME(node_id, type) \ + _CONCAT(_CONCAT(__sensing_sensor_info_, DEVICE_DT_NAME_GET(node_id)), type) + +#define SENSING_SENSOR_INFO_INST_DEFINE(node_id, prop, idx) \ + const STRUCT_SECTION_ITERABLE( \ + sensing_sensor_info, \ + SENSING_SENSOR_INFO_DT_NAME(node_id, DT_PROP_BY_IDX(node_id, prop, idx))) = { \ + .info = &SENSOR_INFO_DT_NAME(DT_PHANDLE(node_id, dev)), \ + .type = DT_PROP_BY_IDX(node_id, prop, idx), \ + }; + +#define SENSING_SENSOR_INFO_DT_DEFINE(node_id) \ + DT_FOREACH_PROP_ELEM(node_id, sensor_types, SENSING_SENSOR_INFO_INST_DEFINE) + +#define SENSING_SENSOR_DT_DEFINE(node_id, init_fn, pm_device, data_ptr, cfg_ptr, level, prio, \ + api_ptr, ...) \ + SENSING_SENSOR_INFO_DT_DEFINE(node_id); \ + DEVICE_DT_DEFINE(node_id, init_fn, pm_device, data_ptr, cfg_ptr, level, prio, api_ptr, \ + __VA_ARGS__) + +#define SENSING_SENSOR_DT_INST_DEFINE(inst, ...) \ + SENSING_SENSOR_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__) + +#define SENSING_SENSOR_INFO_GET(node_id, type) &SENSING_SENSOR_INFO_DT_NAME(node_id, type) + +STRUCT_SECTION_START_EXTERN(sensing_sensor_info); + +#if defined(CONFIG_HAS_DTS) || defined(__DOXYGEN__) +#define Z_MAYBE_SENSING_SENSOR_INFO_DECLARE_INTERNAL_DEFINE(node_id, prop, idx) \ + extern const struct sensing_sensor_info SENSING_SENSOR_INFO_DT_NAME( \ + node_id, DT_PROP_BY_IDX(node_id, prop, idx)); + +#define Z_MAYBE_SENSING_SENSOR_INFO_DECLARE_INTERNAL(node_id) \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, sensor_types), \ + (DT_FOREACH_PROP_ELEM(node_id, sensor_types, \ + Z_MAYBE_SENSING_SENSOR_INFO_DECLARE_INTERNAL_DEFINE)), \ + ()) + +DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_SENSING_SENSOR_INFO_DECLARE_INTERNAL); +#endif /* CONFIG_HAS_DTS || __DOXYGEN__ */ + +#ifdef __cplusplus +} +#endif + +#endif /*ZEPHYR_INCLUDE_SENSING_SENSOR_H_*/ diff --git a/include/zephyr/sensing/sensing_sensor_types.h b/include/zephyr/sensing/sensor_types.h similarity index 83% rename from include/zephyr/sensing/sensing_sensor_types.h rename to include/zephyr/sensing/sensor_types.h index db15af1e279f7a4..03b7b9730c79cc5 100644 --- a/include/zephyr/sensing/sensing_sensor_types.h +++ b/include/zephyr/sensing/sensor_types.h @@ -27,9 +27,9 @@ /** * sensor category motion */ -#define SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D 0x73 -#define SENSING_SENSOR_TYPE_MOTION_GYROMETER_3D 0x76 -#define SENSING_SENSOR_TYPE_MOTION_MOTION_DETECTOR 0x77 +#define SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D 115 +#define SENSING_SENSOR_TYPE_MOTION_GYROMETER_3D 118 +#define SENSING_SENSOR_TYPE_MOTION_MOTION_DETECTOR 119 /** diff --git a/subsys/sensing/CMakeLists.txt b/subsys/sensing/CMakeLists.txt index 59aa28514b03fee..a401e0a8372c048 100644 --- a/subsys/sensing/CMakeLists.txt +++ b/subsys/sensing/CMakeLists.txt @@ -1,12 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library() -zephyr_library_include_directories(include) - zephyr_library_sources( - sensor_mgmt.c - sensing.c - sensing_sensor.c + src/sensor_info.c + src/sensor_pipe.c ) - -add_subdirectory_ifdef(CONFIG_SENSING_SENSOR_PHY_3D_SENSOR sensor/phy_3d_sensor) diff --git a/subsys/sensing/Kconfig b/subsys/sensing/Kconfig index 9101db074457a50..dff3b430b69bb26 100644 --- a/subsys/sensing/Kconfig +++ b/subsys/sensing/Kconfig @@ -3,8 +3,8 @@ config SENSING bool "Sensing Subsystem" - default y - depends on DT_HAS_ZEPHYR_SENSING_ENABLED + select DSP + select SENSOR_INFO help Enable Sensing Subsystem. @@ -14,16 +14,4 @@ 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 diff --git a/subsys/sensing/sensing.c b/subsys/sensing/sensing.c deleted file mode 100644 index 6074925437923c5..000000000000000 --- a/subsys/sensing/sensing.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2023 Intel Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include "sensor_mgmt.h" - -#include -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 *sensor_info, - const struct sensing_callback_list *cb_list, - sensing_sensor_handle_t *handle) -{ - 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) -{ - 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) -{ - return close_sensor((struct sensing_connection **)handle); -} - -int sensing_set_config(sensing_sensor_handle_t handle, - struct sensing_sensor_config *configs, - int count) -{ - 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) -{ - 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 get_sensor_info(handle); -} diff --git a/subsys/sensing/sensing_sensor.c b/subsys/sensing/sensing_sensor.c deleted file mode 100644 index c305cbb35c4facb..000000000000000 --- a/subsys/sensing/sensing_sensor.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2023 Intel Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include - -#include -LOG_MODULE_DECLARE(sensing, CONFIG_SENSING_LOG_LEVEL); - -int sensing_sensor_notify_data_ready(const struct device *dev) -{ - return -ENOTSUP; -} - -int sensing_sensor_set_data_ready(const struct device *dev, bool data_ready) -{ - return -ENOTSUP; -} - -int sensing_sensor_post_data(const struct device *dev, void *buf, int size) -{ - return -ENOTSUP; -} diff --git a/subsys/sensing/sensor/phy_3d_sensor/CMakeLists.txt b/subsys/sensing/sensor/phy_3d_sensor/CMakeLists.txt deleted file mode 100644 index 69f0b70637c7c3d..000000000000000 --- a/subsys/sensing/sensor/phy_3d_sensor/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -zephyr_library_sources(phy_3d_sensor.c) diff --git a/subsys/sensing/sensor/phy_3d_sensor/Kconfig b/subsys/sensing/sensor/phy_3d_sensor/Kconfig deleted file mode 100644 index 3e8ca66bcb0ef47..000000000000000 --- a/subsys/sensing/sensor/phy_3d_sensor/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2023 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -config SENSING_SENSOR_PHY_3D_SENSOR - bool "sensing subsystem physical 3d sensors(accel, gyro, mag)" - default y - depends on DT_HAS_ZEPHYR_SENSING_PHY_3D_SENSOR_ENABLED - help - Enable sensing subsystem physical 3d sensors(accel, gyro, mag). diff --git a/subsys/sensing/sensor/phy_3d_sensor/phy_3d_sensor.c b/subsys/sensing/sensor/phy_3d_sensor/phy_3d_sensor.c deleted file mode 100644 index 6ee2131bc3bdb05..000000000000000 --- a/subsys/sensing/sensor/phy_3d_sensor/phy_3d_sensor.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2023 Intel Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#define DT_DRV_COMPAT zephyr_sensing_phy_3d_sensor - -#include -#include -#include -#include -#include -#include -#include - -#include "phy_3d_sensor.h" - -LOG_MODULE_REGISTER(phy_3d_sensor, CONFIG_SENSING_LOG_LEVEL); - -static int phy_3d_sensor_init(const struct device *dev, - const struct sensing_sensor_info *info, - const sensing_sensor_handle_t *reporter_handles, - int reporters_count) -{ - return 0; -} - -static int phy_3d_sensor_deinit(const struct device *dev) -{ - return 0; -} - -static int phy_3d_sensor_read_sample(const struct device *dev, - void *buf, int size) -{ - return 0; -} - -static int phy_3d_sensor_sensitivity_test(const struct device *dev, - int index, uint32_t sensitivity, - void *last_sample_buf, int last_sample_size, - void *current_sample_buf, int current_sample_size) -{ - return 0; -} - -static int phy_3d_sensor_set_interval(const struct device *dev, uint32_t value) -{ - return 0; -} - -static int phy_3d_sensor_get_interval(const struct device *dev, - uint32_t *value) -{ - return 0; -} - -static int phy_3d_sensor_set_sensitivity(const struct device *dev, - int index, uint32_t value) -{ - return 0; -} - -static int phy_3d_sensor_get_sensitivity(const struct device *dev, - int index, uint32_t *value) -{ - return 0; -} - -static const struct sensing_sensor_api phy_3d_sensor_api = { - .init = phy_3d_sensor_init, - .deinit = phy_3d_sensor_deinit, - .set_interval = phy_3d_sensor_set_interval, - .get_interval = phy_3d_sensor_get_interval, - .set_sensitivity = phy_3d_sensor_set_sensitivity, - .get_sensitivity = phy_3d_sensor_get_sensitivity, - .read_sample = phy_3d_sensor_read_sample, - .sensitivity_test = phy_3d_sensor_sensitivity_test, -}; - -static const struct sensing_sensor_register_info phy_3d_sensor_reg = { - .flags = SENSING_SENSOR_FLAG_REPORT_ON_CHANGE, - .sample_size = sizeof(struct sensing_sensor_value_3d_q31), - .sensitivity_count = PHY_3D_SENSOR_CHANNEL_NUM, - .version.value = SENSING_SENSOR_VERSION(0, 8, 0, 0), -}; - -#define SENSING_PHY_3D_SENSOR_DT_DEFINE(_inst) \ - static struct phy_3d_sensor_context _CONCAT(ctx, _inst) = { \ - .hw_dev = DEVICE_DT_GET( \ - DT_PHANDLE(DT_DRV_INST(_inst), \ - underlying_device)), \ - .sensor_type = DT_PROP(DT_DRV_INST(_inst), sensor_type),\ - }; \ - SENSING_SENSOR_DT_DEFINE(DT_DRV_INST(_inst), \ - &phy_3d_sensor_reg, &_CONCAT(ctx, _inst), \ - &phy_3d_sensor_api); - -DT_INST_FOREACH_STATUS_OKAY(SENSING_PHY_3D_SENSOR_DT_DEFINE); diff --git a/subsys/sensing/sensor/phy_3d_sensor/phy_3d_sensor.h b/subsys/sensing/sensor/phy_3d_sensor/phy_3d_sensor.h deleted file mode 100644 index 966a6f088c33b90..000000000000000 --- a/subsys/sensing/sensor/phy_3d_sensor/phy_3d_sensor.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2023 Intel Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_SPHY_3D_SENSOR_H_ -#define ZEPHYR_INCLUDE_SPHY_3D_SENSOR_H_ - -#include - -#define PHY_3D_SENSOR_CHANNEL_NUM 3 - -struct phy_3d_sensor_context { - const struct device *dev; - const struct device *hw_dev; - const int32_t sensor_type; -}; - -#endif diff --git a/subsys/sensing/sensor_mgmt.c b/subsys/sensing/sensor_mgmt.c deleted file mode 100644 index 9ecde551a02a5c4..000000000000000 --- a/subsys/sensing/sensor_mgmt.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (c) 2023 Intel Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "sensor_mgmt.h" - -#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); - -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); diff --git a/subsys/sensing/sensor_mgmt.h b/subsys/sensing/sensor_mgmt.h deleted file mode 100644 index 38219305304d6e3..000000000000000 --- a/subsys/sensing/sensor_mgmt.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2023 Intel Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef SENSOR_MGMT_H_ -#define SENSOR_MGMT_H_ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#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; -} - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - - -#endif /* SENSOR_MGMT_H_ */ diff --git a/subsys/sensing/src/sensor_info.c b/subsys/sensing/src/sensor_info.c new file mode 100644 index 000000000000000..3af62d40dbdcba8 --- /dev/null +++ b/subsys/sensing/src/sensor_info.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +int sensing_get_sensors(int *num_sensors, const struct sensing_sensor_info **info) +{ + STRUCT_SECTION_COUNT(sensing_sensor_info, num_sensors); + *info = STRUCT_SECTION_START(sensing_sensor_info); + return 0; +} diff --git a/subsys/sensing/src/sensor_pipe.c b/subsys/sensing/src/sensor_pipe.c new file mode 100644 index 000000000000000..fb1a1b9e7970635 --- /dev/null +++ b/subsys/sensing/src/sensor_pipe.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#define DT_DRV_COMPAT zephyr_sensing_pipe + +static const struct sensor_driver_api sensor_pipe_api = { + .attr_set = NULL, + .attr_get = NULL, + .get_decoder = NULL, + .submit = NULL, +}; + +static int sensing_sensor_pipe_init(const struct device *dev) +{ + return 0; +} + +#define SENSING_PIPE_INIT(inst) \ + SENSING_SENSOR_DT_INST_DEFINE(inst, sensing_sensor_pipe_init, NULL, NULL, NULL, \ + APPLICATION, 10, &sensor_pipe_api); + +DT_INST_FOREACH_STATUS_OKAY(SENSING_PIPE_INIT) diff --git a/tests/subsys/sensing/list/CMakeLists.txt b/tests/subsys/sensing/list/CMakeLists.txt new file mode 100644 index 000000000000000..1b34e474c14b0c9 --- /dev/null +++ b/tests/subsys/sensing/list/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(device) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/subsys/sensing/list/boards/native_posix.overlay b/tests/subsys/sensing/list/boards/native_posix.overlay new file mode 100644 index 000000000000000..6884708a8e0311b --- /dev/null +++ b/tests/subsys/sensing/list/boards/native_posix.overlay @@ -0,0 +1,23 @@ +/* Copyright (c) 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + + #include + +/ { + accelgyro: accelgyro { + compatible = "zephyr,sensing-pipe"; + status = "okay"; + dev = <&icm42688>; + sensor-types = ; + }; +}; + +&spi0 { + icm42688: icm42688@3 { + compatible = "invensense,icm42688"; + int-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + spi-max-frequency = <50000000>; + reg = <3>; + }; +}; diff --git a/tests/subsys/sensing/list/prj.conf b/tests/subsys/sensing/list/prj.conf new file mode 100644 index 000000000000000..0e0e881d69886ab --- /dev/null +++ b/tests/subsys/sensing/list/prj.conf @@ -0,0 +1,15 @@ +# Copyright (c) 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y + +# Enable GPIO +CONFIG_GPIO=y + +# Enable sensors +CONFIG_SENSOR=y +CONFIG_SENSING=y + +# Enable emulation +CONFIG_EMUL=y diff --git a/tests/subsys/sensing/list/src/main.c b/tests/subsys/sensing/list/src/main.c new file mode 100644 index 000000000000000..0d2c1bbb8108394 --- /dev/null +++ b/tests/subsys/sensing/list/src/main.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include + +ZTEST_SUITE(sensing, NULL, NULL, NULL, NULL, NULL); + +ZTEST(sensing, test_list_sensors) +{ + int num_sensors; + const struct sensing_sensor_info *sensors; + const struct sensor_info *expected_info = &SENSOR_INFO_DT_NAME(DT_NODELABEL(icm42688)); + + zassert_ok(sensing_get_sensors(&num_sensors, &sensors)); + zassert_equal(2, num_sensors, "num_sensors=%d", num_sensors); + + zassert_equal_ptr(expected_info, sensors[0].info); + zassert_equal_ptr(expected_info, sensors[1].info); + + zassert_true(sensors[0].type == SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D || + sensors[0].type == SENSING_SENSOR_TYPE_MOTION_GYROMETER_3D); + zassert_true(sensors[1].type == SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D || + sensors[1].type == SENSING_SENSOR_TYPE_MOTION_GYROMETER_3D); + zassert_not_equal(sensors[0].type, sensors[1].type); +} + +ZTEST(sensing, test_get_single_node) +{ + const struct sensor_info *expected_info = &SENSOR_INFO_DT_NAME(DT_NODELABEL(icm42688)); + const struct sensing_sensor_info *info = SENSING_SENSOR_INFO_GET( + DT_NODELABEL(accelgyro), SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D); + + zassert_equal_ptr(expected_info, info->info); + zassert_equal(SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D, info->type); + + info = SENSING_SENSOR_INFO_GET(DT_NODELABEL(accelgyro), + SENSING_SENSOR_TYPE_MOTION_GYROMETER_3D); + + zassert_equal_ptr(expected_info, info->info); + zassert_equal(SENSING_SENSOR_TYPE_MOTION_GYROMETER_3D, info->type); +} diff --git a/tests/subsys/sensing/list/testcase.yaml b/tests/subsys/sensing/list/testcase.yaml new file mode 100644 index 000000000000000..2f9d013e2a2f4ea --- /dev/null +++ b/tests/subsys/sensing/list/testcase.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +tests: + subsys.sensing.list: + tags: + - sensor + - subsys + platform_allow: native_posix