1 /*
2  * Copyright (c) 2022 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/rtio/rtio.h>
9 #include <zephyr/logging/log.h>
10 
11 LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);
12 
13 #define N		(8)
14 #define M		(N/2)
15 #define SQ_SZ		(N)
16 #define CQ_SZ		(N)
17 
18 #define NODE_ID		DT_COMPAT_GET_ANY_STATUS_OKAY(vnd_sensor)
19 #define SAMPLE_PERIOD	DT_PROP(NODE_ID, sample_period)
20 #define SAMPLE_SIZE	DT_PROP(NODE_ID, sample_size)
21 #define PROCESS_TIME	((M - 1) * SAMPLE_PERIOD)
22 
23 RTIO_DEFINE_WITH_MEMPOOL(ez_io, SQ_SZ, CQ_SZ, N, SAMPLE_SIZE, 4);
24 
main(void)25 int main(void)
26 {
27 	const struct device *const vnd_sensor = DEVICE_DT_GET(NODE_ID);
28 	struct rtio_iodev *iodev = vnd_sensor->data;
29 
30 	/* Fill the entire submission queue. */
31 	for (int n = 0; n < N; n++) {
32 		struct rtio_sqe *sqe = rtio_sqe_acquire(&ez_io);
33 
34 		rtio_sqe_prep_read_with_pool(sqe, iodev, RTIO_PRIO_HIGH, NULL);
35 	}
36 
37 	while (true) {
38 		int m = 0;
39 		uint8_t *userdata[M] = {0};
40 		uint32_t data_len[M] = {0};
41 
42 		LOG_INF("Submitting %d read requests", M);
43 		rtio_submit(&ez_io, M);
44 
45 		/* Consume completion events until there is enough sensor data
46 		 * available to execute a batch processing algorithm, such as
47 		 * an FFT.
48 		 */
49 		while (m < M) {
50 			struct rtio_cqe *cqe = rtio_cqe_consume(&ez_io);
51 
52 			if (cqe == NULL) {
53 				LOG_DBG("No completion events available");
54 				k_msleep(SAMPLE_PERIOD);
55 				continue;
56 			}
57 			LOG_DBG("Consumed completion event %d", m);
58 
59 			if (cqe->result < 0) {
60 				LOG_ERR("Operation failed");
61 			}
62 
63 			if (rtio_cqe_get_mempool_buffer(&ez_io, cqe, &userdata[m], &data_len[m])) {
64 				LOG_ERR("Failed to get mempool buffer info");
65 			}
66 			rtio_cqe_release(&ez_io, cqe);
67 			m++;
68 		}
69 
70 		/* Here is where we would execute a batch processing algorithm.
71 		 * Model as a long sleep that takes multiple sensor sample
72 		 * periods. The sensor driver can continue reading new data
73 		 * during this time because we submitted more buffers into the
74 		 * queue than we needed for the batch processing algorithm.
75 		 */
76 		LOG_INF("Start processing %d samples", M);
77 		for (m = 0; m < M; m++) {
78 			LOG_HEXDUMP_DBG(userdata[m], SAMPLE_SIZE, "Sample data:");
79 		}
80 		k_msleep(PROCESS_TIME);
81 		LOG_INF("Finished processing %d samples", M);
82 
83 		/* Recycle the sensor data buffers and refill the submission
84 		 * queue.
85 		 */
86 		for (m = 0; m < M; m++) {
87 			struct rtio_sqe *sqe = rtio_sqe_acquire(&ez_io);
88 
89 			rtio_release_buffer(&ez_io, userdata[m], data_len[m]);
90 			rtio_sqe_prep_read_with_pool(sqe, iodev, RTIO_PRIO_HIGH, NULL);
91 		}
92 	}
93 	return 0;
94 }
95