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 TEMP_CHANNELS				\
10 	{ SENSOR_CHAN_AMBIENT_TEMP, 0 },	\
11 	{ SENSOR_CHAN_AMBIENT_TEMP, 1 }
12 #define TEMP_ALIAS(id) DT_ALIAS(CONCAT(temp, id))
13 #define TEMP_IODEV_SYM(id) CONCAT(temp_iodev, id)
14 #define TEMP_IODEV_PTR(id) &TEMP_IODEV_SYM(id)
15 #define TEMP_DEFINE_IODEV(id)			\
16 	SENSOR_DT_READ_IODEV(			\
17 		TEMP_IODEV_SYM(id),		\
18 		TEMP_ALIAS(id),			\
19 		TEMP_CHANNELS			\
20 		);
21 
22 #define NUM_SENSORS 2
23 
24 LISTIFY(NUM_SENSORS, TEMP_DEFINE_IODEV, (;));
25 
26 struct sensor_iodev *iodevs[NUM_SENSORS] = { LISTIFY(NUM_SENSORS, TEMP_IODEV_PTR, (,)) };
27 
28 RTIO_DEFINE_WITH_MEMPOOL(temp_ctx, NUM_SENSORS, NUM_SENSORS, NUM_SENSORS, 8, sizeof(void *));
29 
main(void)30 int main(void)
31 {
32 	int rc;
33 	uint32_t temp_frame_iter = 0;
34 	struct sensor_q31_data temp_data[2] = {0};
35 	struct sensor_decoder_api *decoder;
36 	struct rtio_cqe *cqe;
37 	uint8_t *buf;
38 	uint32_t buf_len;
39 
40 	while (1) {
41 		/* Non-Blocking read for each sensor */
42 		for (int i = 0; i < NUM_SENSORS; i++) {
43 			rc = sensor_read_async_mempool(iodevs[i], &temp_ctx, iodevs[i]);
44 
45 			if (rc != 0) {
46 				printk("sensor_read() failed %d\n", rc);
47 				return;
48 			}
49 		}
50 
51 		/* Wait for read completions */
52 		for (int i = 0; i < NUM_SENSORS; i++) {
53 			cqe = rtio_cqe_consume_block(&temp_ctx);
54 
55 			if (cqe->result != 0) {
56 				printk("async read failed %d\n", cqe->result);
57 				return;
58 			}
59 
60 			/* Get the associated mempool buffer with the completion */
61 			rc = rtio_cqe_get_mempool_buffer(&temp_ctx, cqe, &buf, &buf_len);
62 
63 			if (rc != 0) {
64 				printk("get mempool buffer failed %d\n", rc);
65 				return;
66 			}
67 
68 			struct device *sensor = ((struct sensor_read_config *)
69 				((struct rtio_iodev *)cqe->userdata)->data)->sensor;
70 
71 			/* Done with the completion event, release it */
72 			rtio_cqe_release(&temp_ctx, cqe);
73 
74 			rc = sensor_get_decoder(sensor, &decoder);
75 			if (rc != 0) {
76 				printk("sensor_get_decoder failed %d\n", rc);
77 				return;
78 			}
79 
80 			/* Frame iterators, one per channel we are decoding */
81 			uint32_t temp_fits[2] = { 0, 0 };
82 
83 			decoder->decode(buf, {SENSOR_CHAN_AMBIENT_TEMP, 0},
84 					&temp_fits[0], 1, &temp_data[0]);
85 			decoder->decode(buf, {SENSOR_CHAN_AMBIENT_TEMP, 1},
86 					&temp_fits[1], 1, &temp_data[1]);
87 
88 			/* Done with the buffer, release it */
89 			rtio_release_buffer(&temp_ctx, buf, buf_len);
90 
91 			printk("Temperature for %s channel 0 " PRIsensor_q31_data ", channel 1 "
92 			    PRIsensor_q31_data "\n",
93 			    dev->name,
94 			    PRIsensor_q31_data_arg(temp_data[0], 0),
95 			    PRIsensor_q31_data_arg(temp_data[1], 0));
96 		}
97 	}
98 
99 	k_msleep(1);
100 }
101