Commit f5595b4b authored by Zhang Lixu's avatar Zhang Lixu Committed by Carles Cufi
Browse files

sensing: support multiple sensor types in one device

Many sensors have multiple functions, for example, icm42688 supports
accel, gyro and temperature, and the sensor streaming api always mixes
the multiple functions in one function call. So we need add a layer in
sensing subsystem to dispatch the result returned from sensor streaming
api for each function.
I changed the sensor-type(int) to sensor-types(array) in sensing sensor
device bindings, so that one device can map to multiple instances of
sensing sensor.

Signed-off-by: default avatarZhang Lixu <lixu.zhang@intel.com>
parent 91774cb0
Loading
Loading
Loading
Loading
+6 −2
Changes for dts/bindings/sensor/zephyr,sensing-sensor.yaml: 6 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -7,8 +7,8 @@ description: Sensing subsystem sensor common properties bindings.
include: sensor-device.yaml

properties:
  sensor-type:
    type: int
  sensor-types:
    type: array
    required: true
    description: sensor type id (follow HID spec definition)

@@ -24,6 +24,10 @@ properties:
    type: phandles
    description: sensor reporters

  reporters-index:
    type: array
    description: the index in sensor-types of reporter if the reporter support multiple sensor-types

  stream-mode:
    type: boolean
    description: sensor works on stream mode or poll mode
+43 −47
Changes for include/zephyr/sensing/sensing_sensor.h: 43 added lines, 47 removed lines.
Original line number Diff line number Diff line
@@ -112,25 +112,13 @@ struct sensing_sensor {
	struct sensing_connection *conns;
};

#define PHANDLE_DEVICE_BY_IDX(idx, node, prop)				\
	DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node, prop, idx))
#define SENSING_SENSOR_INFO_NAME(node, idx)					\
	_CONCAT(_CONCAT(__sensing_sensor_info_, idx), DEVICE_DT_NAME_GET(node))

#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)				\
#define SENSING_SENSOR_INFO_DEFINE(node, idx)				\
	const static STRUCT_SECTION_ITERABLE(sensing_sensor_info,	\
				SENSING_SENSOR_INFO_NAME(node)) = {	\
		.type = DT_PROP(node, sensor_type),			\
			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),		\
@@ -138,56 +126,64 @@ struct sensing_sensor {
		.minimal_interval = DT_PROP(node, minimal_interval),\
	};

#define SENSING_CONNECTIONS_NAME(node)					\
	_CONCAT(__sensing_connections, DEVICE_DT_NAME_GET(node))
#define SENSING_CONNECTIONS_NAME(node, idx)					\
	_CONCAT(_CONCAT(__sensing_connections_, idx), 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_NAME(DT_PHANDLE_BY_IDX(node, reporters, idx));
extern struct sensing_sensor SENSING_SENSOR_SOURCE_NAME(idx, node);	\

#define SENSING_CONNECTION_INITIALIZER(source_node, cb_list_ptr)	\
#define SENSING_CONNECTION_INITIALIZER(source_name, cb_list_ptr)	\
{									\
	.callback_list = *cb_list_ptr,					\
	.source = &SENSING_SENSOR_NAME(source_node),			\
	.source = &source_name,						\
}

#define SENSING_CONNECTION_DEFINE(idx, node, cb_list_ptr)		\
	SENSING_CONNECTION_INITIALIZER(DT_PHANDLE_BY_IDX(node, reporters, idx), cb_list_ptr)
	SENSING_CONNECTION_INITIALIZER(SENSING_SENSOR_SOURCE_NAME(idx, node), \
				       cb_list_ptr)

#define SENSING_CONNECTIONS_DEFINE(node, num, cb_list_ptr)		\
#define SENSING_CONNECTIONS_DEFINE(node, idx, num, cb_list_ptr)		\
	LISTIFY(num, SENSING_SENSOR_SOURCE_EXTERN,			\
				(), node)				\
	static struct sensing_connection				\
			SENSING_CONNECTIONS_NAME(node)[(num)] = {	\
			SENSING_CONNECTIONS_NAME(node, idx)[(num)] = {	\
		LISTIFY(num, SENSING_CONNECTION_DEFINE,			\
				(,), node, cb_list_ptr)			\
	};

#define SENSING_SENSOR_IODEV_NAME(node)					\
	_CONCAT(__sensing_iodev_, 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)						\
#define SENSING_SENSOR_IODEV_DEFINE(node, idx)						\
	COND_CODE_1(DT_PROP(node, stream_mode),						\
		(SENSOR_DT_STREAM_IODEV(SENSING_SENSOR_IODEV_NAME(node), node)),	\
		(SENSOR_DT_READ_IODEV(SENSING_SENSOR_IODEV_NAME(node), node)));
		(SENSOR_DT_STREAM_IODEV(SENSING_SENSOR_IODEV_NAME(node, idx), node)),	\
		(SENSOR_DT_READ_IODEV(SENSING_SENSOR_IODEV_NAME(node, idx), node)));

#define SENSING_SENSOR_NAME(node)					\
	_CONCAT(__sensing_sensor_, DEVICE_DT_NAME_GET(node))
#define SENSING_SENSOR_NAME(node, idx)					\
	_CONCAT(_CONCAT(__sensing_sensor_, idx), DEVICE_DT_NAME_GET(node))

#define SENSING_SENSOR_DEFINE(node, reg_ptr, cb_list_ptr)		\
	SENSING_SENSOR_INFO_DEFINE(node)				\
	SENSING_CONNECTIONS_DEFINE(node,				\
#define SENSING_SENSOR_DEFINE(node, prop, idx, reg_ptr, cb_list_ptr)	\
	SENSING_SENSOR_INFO_DEFINE(node, idx)				\
	SENSING_CONNECTIONS_DEFINE(node, idx,				\
			DT_PROP_LEN_OR(node, reporters, 0), cb_list_ptr)\
	SENSING_SENSOR_IODEV_DEFINE(node)				\
	SENSING_SENSOR_IODEV_DEFINE(node, idx)				\
	STRUCT_SECTION_ITERABLE(sensing_sensor,				\
				       SENSING_SENSOR_NAME(node)) = {	\
				SENSING_SENSOR_NAME(node, idx)) = {	\
		.dev = DEVICE_DT_GET(node),				\
		.info = &SENSING_SENSOR_INFO_NAME(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),		\
		.conns = SENSING_CONNECTIONS_NAME(node, idx),		\
		.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.
 *
@@ -217,7 +213,7 @@ extern struct sensing_sensor SENSING_SENSOR_NAME(DT_PHANDLE_BY_IDX(node, reporte
 * @param api_ptr Provides an initial pointer to the API function struct used
 * by the driver. Can be NULL.
 */
#define SENSING_SENSOR_DT_DEFINE(node_id, reg_ptr, cb_list_ptr,		\
#define SENSING_SENSORS_DT_DEFINE(node_id, reg_ptr, cb_list_ptr,	\
				init_fn, pm_device,			\
				data_ptr, cfg_ptr, level, prio,		\
				api_ptr, ...)				\
@@ -225,19 +221,19 @@ extern struct sensing_sensor SENSING_SENSOR_NAME(DT_PHANDLE_BY_IDX(node, reporte
			 data_ptr, cfg_ptr, level, prio,		\
			 api_ptr, __VA_ARGS__);				\
									\
	SENSING_SENSOR_DEFINE(node_id, reg_ptr, cb_list_ptr);
	SENSING_SENSORS_DEFINE(node_id, reg_ptr, cb_list_ptr);

/**
 * @brief Like SENSING_SENSOR_DT_DEFINE() for an instance of a DT_DRV_COMPAT
 * @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_SENSOR_DT_DEFINE().
 * <tt>DT_DRV_COMPAT(inst)</tt> in the call to SENSING_SENSORS_DT_DEFINE().
 *
 * @param ... other parameters as expected by SENSING_SENSOR_DT_DEFINE().
 * @param ... other parameters as expected by SENSING_SENSORS_DT_DEFINE().
 */
#define SENSING_SENSOR_DT_INST_DEFINE(inst, reg_ptr, cb_list_ptr, ...)	\
	SENSING_SENSOR_DT_DEFINE(DT_DRV_INST(inst), reg_ptr,		\
#define SENSING_SENSORS_DT_INST_DEFINE(inst, reg_ptr, cb_list_ptr, ...)	\
	SENSING_SENSORS_DT_DEFINE(DT_DRV_INST(inst), reg_ptr,		\
			cb_list_ptr, __VA_ARGS__)

/**
+11 −8
Changes for samples/subsys/sensing/simple/boards/native_sim.overlay: 11 added lines, 8 removed lines.
Original line number Diff line number Diff line
@@ -4,6 +4,8 @@
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/sensing/sensing_sensor_types.h>

&i2c0 {
	bmi160_i2c: bmi@68 {
		compatible = "bosch,bmi160";
@@ -24,20 +26,20 @@
		compatible = "zephyr,sensing";
		status = "okay";

		base_accel: base-accel {
		base_accel_gyro: base-accel-gyro {
			compatible = "zephyr,sensing-phy-3d-sensor";
			status = "okay";
			sensor-type = <0x73>;
			friendly-name = "Base Accelerometer Sensor";
			sensor-types = <SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D SENSING_SENSOR_TYPE_MOTION_GYROMETER_3D>;
			friendly-name = "Base Accel Gyro Sensor";
			minimal-interval = <625>;
			underlying-device = <&bmi160_i2c>;
		};

		lid_accel: lid-accel {
		lid_accel_gyro: lid-accel-gyro {
			compatible = "zephyr,sensing-phy-3d-sensor";
			status = "okay";
			sensor-type = <0x73>;
			friendly-name = "Lid Accelerometer Sensor";
			sensor-types = <SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D SENSING_SENSOR_TYPE_MOTION_GYROMETER_3D>;
			friendly-name = "Lid Accel Gyro Sensor";
			minimal-interval = <625>;
			underlying-device = <&bmi160_spi>;
		};
@@ -45,9 +47,10 @@
		hinge_angle: hinge-angle {
			compatible = "zephyr,sensing-hinge-angle";
			status = "okay";
			sensor-type = <0x20B>;
			sensor-types = <SENSING_SENSOR_TYPE_MOTION_HINGE_ANGLE>;
			friendly-name = "Hinge Angle Sensor";
			reporters = <&base_accel &lid_accel>;
			reporters = <&base_accel_gyro &lid_accel_gyro>;
			reporters-index = <0 0>;
			minimal-interval = <100000>;
			stream-mode;
		};
+15 −51
Changes for samples/subsys/sensing/simple/src/main.c: 15 added lines, 51 removed lines.
Original line number Diff line number Diff line
@@ -43,20 +43,17 @@ int main(void)
	const struct sensing_callback_list base_acc_cb_list = {
		.on_data_event = &acc_data_event_callback,
	};
	const struct sensing_callback_list lid_acc_cb_list = {
		.on_data_event = &acc_data_event_callback,
	};
	const struct sensing_callback_list hinge_angle_cb_list = {
		.on_data_event = &hinge_angle_data_event_callback,
	};
	const struct sensing_sensor_info *info;
	sensing_sensor_handle_t base_acc;
	sensing_sensor_handle_t lid_acc;
	sensing_sensor_handle_t hinge_angle;
	struct sensing_sensor_config base_acc_config;
	struct sensing_sensor_config lid_acc_config;
	struct sensing_sensor_config hinge_angle_config;
	const struct sensing_sensor_info *tmp_sensor_info;
	const struct sensing_sensor_info *tmp_sensor_info = NULL;
	const struct sensing_sensor_info *accle_info = NULL;
	const struct sensing_sensor_info *hinge_info = NULL;
	int ret, i, num = 0;

	ret = sensing_get_sensors(&num, &info);
@@ -71,25 +68,27 @@ int main(void)
			 info[i].name,
			 info[i].friendly_name,
			 info[i].type);
		switch (info[i].type) {
		case SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D:
			accle_info = &info[i];
			break;
		case SENSING_SENSOR_TYPE_MOTION_HINGE_ANGLE:
			hinge_info = &info[i];
			break;
		default:
			break;
		}
	}

	LOG_INF("sensing subsystem run successfully");

	ret = sensing_open_sensor(&info[0], &base_acc_cb_list, &base_acc);
	ret = sensing_open_sensor(accle_info, &base_acc_cb_list, &base_acc);
	if (ret) {
		LOG_ERR("sensing_open_sensor, type:0x%x index:0 error:%d",
			SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D, ret);
	}

	ret = sensing_open_sensor_by_dt(DEVICE_DT_GET(DT_NODELABEL(lid_accel)),
					&lid_acc_cb_list,
					&lid_acc);
	if (ret) {
		LOG_ERR("sensing_open_sensor_by_dt, type:0x%x index:1 error:%d",
			SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D, ret);
	}
	ret = sensing_open_sensor_by_dt(DEVICE_DT_GET(DT_NODELABEL(hinge_angle)),
					&hinge_angle_cb_list,
	ret = sensing_open_sensor(hinge_info, &hinge_angle_cb_list,
					&hinge_angle);
	if (ret) {
		LOG_ERR("sensing_open_sensor_by_type, type:0x%x index:0 error:%d",
@@ -104,13 +103,6 @@ int main(void)
		LOG_ERR("base_acc sensing_set_interval error:%d\n", ret);
	}

	lid_acc_config.attri = SENSING_SENSOR_ATTRIBUTE_INTERVAL;
	lid_acc_config.interval = 100 * USEC_PER_MSEC;
	ret = sensing_set_config(lid_acc, &lid_acc_config, 1);
	if (ret) {
		LOG_ERR("lid_acc sensing_set_interval error:%d\n", ret);
	}

	tmp_sensor_info = sensing_get_sensor_info(hinge_angle);
	hinge_angle_config.attri = SENSING_SENSOR_ATTRIBUTE_INTERVAL;
	hinge_angle_config.interval = tmp_sensor_info->minimal_interval;
@@ -120,7 +112,6 @@ int main(void)
	}

	memset(&base_acc_config, 0x00, sizeof(struct sensing_sensor_config));
	memset(&lid_acc_config, 0x00, sizeof(struct sensing_sensor_config));
	memset(&hinge_angle_config, 0x00, sizeof(struct sensing_sensor_config));

	/* get base acc, lid acc, hinge sensor interval */
@@ -130,12 +121,6 @@ int main(void)
		LOG_ERR("base_acc sensing_get_interval error:%d\n", ret);
	}

	lid_acc_config.attri = SENSING_SENSOR_ATTRIBUTE_INTERVAL;
	ret = sensing_get_config(lid_acc, &lid_acc_config, 1);
	if (ret) {
		LOG_ERR("lid_acc sensing_get_interval error:%d\n", ret);
	}

	hinge_angle_config.attri = SENSING_SENSOR_ATTRIBUTE_INTERVAL;
	ret = sensing_get_config(hinge_angle, &hinge_angle_config, 1);
	if (ret) {
@@ -151,14 +136,6 @@ int main(void)
		LOG_ERR("base_acc sensing_set_sensitivity error:%d\n", ret);
	}

	lid_acc_config.attri = SENSING_SENSOR_ATTRIBUTE_SENSITIVITY;
	lid_acc_config.data_field = SENSING_SENSITIVITY_INDEX_ALL;
	lid_acc_config.sensitivity = 0;
	ret = sensing_set_config(lid_acc, &lid_acc_config, 1);
	if (ret) {
		LOG_ERR("lid_acc sensing_set_sensitivity error:%d\n", ret);
	}

	hinge_angle_config.attri = SENSING_SENSOR_ATTRIBUTE_SENSITIVITY;
	hinge_angle_config.data_field = SENSING_SENSITIVITY_INDEX_ALL;
	hinge_angle_config.sensitivity = 1;
@@ -168,7 +145,6 @@ int main(void)
	}

	memset(&base_acc_config, 0x00, sizeof(struct sensing_sensor_config));
	memset(&lid_acc_config, 0x00, sizeof(struct sensing_sensor_config));
	memset(&hinge_angle_config, 0x00, sizeof(struct sensing_sensor_config));

	/* get base acc, lid acc, hinge sensor sensitivity */
@@ -179,13 +155,6 @@ int main(void)
		LOG_ERR("base_acc sensing_get_sensitivity error:%d\n", ret);
	}

	lid_acc_config.attri = SENSING_SENSOR_ATTRIBUTE_SENSITIVITY;
	lid_acc_config.data_field = SENSING_SENSITIVITY_INDEX_ALL;
	ret = sensing_get_config(lid_acc, &lid_acc_config, 1);
	if (ret) {
		LOG_ERR("lid_acc sensing_get_sensitivity error:%d\n", ret);
	}

	hinge_angle_config.attri = SENSING_SENSOR_ATTRIBUTE_SENSITIVITY;
	hinge_angle_config.data_field = SENSING_SENSITIVITY_INDEX_ALL;
	ret = sensing_get_config(hinge_angle, &hinge_angle_config, 1);
@@ -193,10 +162,5 @@ int main(void)
		LOG_ERR("hinge_angle sensing_get_sensitivity error:%d\n", ret);
	}

	ret = sensing_close_sensor(&lid_acc);
	if (ret) {
		LOG_ERR("sensing_close_sensor:%p error:%d", lid_acc, ret);
	}

	return 0;
}
+1 −1
Changes for subsys/sensing/sensor/hinge_angle/hinge_angle.c: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ static void hinge_reporter_on_data_event(sensing_sensor_handle_t handle,
		.on_data_event = hinge_reporter_on_data_event,			\
		.context = &_CONCAT(hinge_ctx, _inst),				\
	};									\
	SENSING_SENSOR_DT_INST_DEFINE(_inst, &hinge_reg,			\
	SENSING_SENSORS_DT_INST_DEFINE(_inst, &hinge_reg,			\
		&_CONCAT(hinge_cb, _inst),					\
		&hinge_init, NULL,						\
		&_CONCAT(hinge_ctx, _inst), NULL,				\
Loading