1 /*
2  * Copyright (c) 2024 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/sensor.h>
8 
9 #define ACCEL_TRIGGERS						\
10 	{ SENSOR_TRIG_DRDY, SENSOR_STREAM_DATA_INCLUDE },	\
11 	{ SENSOR_TRIG_TAP, SENSOR_STREAM_DATA_NOP }
12 #define ACCEL_ALIAS(id) DT_ALIAS(CONCAT(accel, id))
13 #define ACCEL_IODEV_SYM(id) CONCAT(accel_iodev, id)
14 #define ACCEL_IODEV_PTR(id) &ACCEL_IODEV_SYM(id)
15 #define ACCEL_DEFINE_IODEV(id)					\
16 	SENSOR_DT_STREAM_IODEV(					\
17 		ACCEL_IODEV_SYM(id),				\
18 		ACCEL_ALIAS(id),				\
19 		ACCEL_TRIGGERS					\
20 		);
21 
22 #define NUM_SENSORS 2
23 
24 LISTIFY(NUM_SENSORS, ACCEL_DEFINE_IODEV, (;));
25 
26 struct sensor_iodev *iodevs[NUM_SENSORS] = { LISTIFY(NUM_SENSORS, ACCEL_IODEV_PTR, (,)) };
27 
28 RTIO_DEFINE_WITH_MEMPOOL(accel_ctx, NUM_SENSORS, NUM_SENSORS, NUM_SENSORS, 16, sizeof(void *));
29 
main(void)30 int main(void)
31 {
32 	int rc;
33 	uint32_t accel_frame_iter = 0;
34 	struct sensor_three_axis_data accel_data[2] = {0};
35 	struct sensor_decoder_api *decoder;
36 	struct rtio_cqe *cqe;
37 	uint8_t *buf;
38 	uint32_t buf_len;
39 	struct rtio_sqe *handles[2];
40 
41 	/* Start the streams */
42 	for (int i = 0; i < NUM_SENSORS; i++) {
43 		sensor_stream(iodevs[i], &accel_ctx, NULL, &handles[i]);
44 	}
45 
46 	while (1) {
47 		cqe = rtio_cqe_consume_block(&accel_ctx);
48 
49 		if (cqe->result != 0) {
50 			printk("async read failed %d\n", cqe->result);
51 			return;
52 		}
53 
54 		rc = rtio_cqe_get_mempool_buffer(&accel_ctx, cqe, &buf, &buf_len);
55 
56 		if (rc != 0) {
57 			printk("get mempool buffer failed %d\n", rc);
58 			return;
59 		}
60 
61 		struct device *sensor = ((struct sensor_read_config *)
62 					 ((struct rtio_iodev *)cqe->userdata)->data)->sensor;
63 
64 		rtio_cqe_release(&accel_ctx, cqe);
65 
66 		rc = sensor_get_decoder(sensor, &decoder);
67 
68 		if (rc != 0) {
69 			printk("sensor_get_decoder failed %d\n", rc);
70 			return;
71 		}
72 
73 		/* Frame iterator values when data comes from a FIFO */
74 		uint32_t accel_fit = 0;
75 
76 		/* Number of accelerometer data frames */
77 		uint32_t frame_count;
78 
79 		rc = decoder->get_frame_count(buf, {SENSOR_CHAN_ACCEL_XYZ, 0},
80 					      &frame_count);
81 		if (rc != 0) {
82 			printk("sensor_get_decoder failed %d\n", rc);
83 			return;
84 		}
85 
86 		/* If a tap has occurred lets print it out */
87 		if (decoder->has_trigger(buf, SENSOR_TRIG_TAP)) {
88 			printk("Tap! Sensor %s\n", dev->name);
89 		}
90 
91 		/* Decode all available accelerometer sample frames */
92 		for (int i = 0; i < frame_count; i++) {
93 			decoder->decode(buf, {SENSOR_CHAN_ACCEL_XYZ, 0},
94 					accel_fit, 1, &accel_data);
95 			printk("Accel data for %s " PRIsensor_three_axis_data "\n",
96 			       dev->name,
97 			       PRIsensor_three_axis_data_arg(accel_data, 0));
98 		}
99 
100 		rtio_release_buffer(&accel_ctx, buf, buf_len);
101 	}
102 }
103