1 /*
2  * Copyright (c) 2024 Intel Corporation
3  * Copyright (c) 2024 Croxel Inc.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/rtio/work.h>
9 #include <zephyr/logging/log.h>
10 
11 #include "bme280.h"
12 
13 LOG_MODULE_DECLARE(BME280, CONFIG_SENSOR_LOG_LEVEL);
14 
bme280_submit_sync(struct rtio_iodev_sqe * iodev_sqe)15 void bme280_submit_sync(struct rtio_iodev_sqe *iodev_sqe)
16 {
17 	uint32_t min_buf_len = sizeof(struct bme280_encoded_data);
18 	int rc;
19 	uint8_t *buf;
20 	uint32_t buf_len;
21 
22 	const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data;
23 	const struct device *dev = cfg->sensor;
24 	const struct sensor_chan_spec *const channels = cfg->channels;
25 	const size_t num_channels = cfg->count;
26 
27 	rc = rtio_sqe_rx_buf(iodev_sqe, min_buf_len, min_buf_len, &buf, &buf_len);
28 	if (rc != 0) {
29 		LOG_ERR("Failed to get a read buffer of size %u bytes", min_buf_len);
30 		rtio_iodev_sqe_err(iodev_sqe, rc);
31 		return;
32 	}
33 
34 	struct bme280_encoded_data *edata;
35 
36 	edata = (struct bme280_encoded_data *)buf;
37 	edata->header.timestamp = k_ticks_to_ns_floor64(k_uptime_ticks());
38 	edata->has_temp = 0;
39 	edata->has_humidity = 0;
40 	edata->has_press = 0;
41 
42 	/* Check if the requested channels are supported */
43 	for (size_t i = 0; i < num_channels; i++) {
44 		switch (channels[i].chan_type) {
45 		case SENSOR_CHAN_AMBIENT_TEMP:
46 			edata->has_temp = 1;
47 			break;
48 		case SENSOR_CHAN_HUMIDITY:
49 			edata->has_humidity = 1;
50 			break;
51 		case SENSOR_CHAN_PRESS:
52 			edata->has_press = 1;
53 			break;
54 		case SENSOR_CHAN_ALL:
55 			edata->has_temp = 1;
56 			edata->has_humidity = 1;
57 			edata->has_press = 1;
58 			break;
59 		default:
60 			continue;
61 			break;
62 		}
63 	}
64 
65 	rc = bme280_sample_fetch_helper(dev, SENSOR_CHAN_ALL, &edata->reading);
66 	if (rc != 0) {
67 		LOG_ERR("Failed to fetch samples");
68 		rtio_iodev_sqe_err(iodev_sqe, rc);
69 		return;
70 	}
71 
72 	rtio_iodev_sqe_ok(iodev_sqe, 0);
73 }
74 
bme280_submit(const struct device * dev,struct rtio_iodev_sqe * iodev_sqe)75 void bme280_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe)
76 {
77 	struct rtio_work_req *req = rtio_work_req_alloc();
78 
79 	if (req == NULL) {
80 		LOG_ERR("RTIO work item allocation failed. Consider to increase "
81 			"CONFIG_RTIO_WORKQ_POOL_ITEMS.");
82 		rtio_iodev_sqe_err(iodev_sqe, -ENOMEM);
83 		return;
84 	}
85 
86 	rtio_work_req_submit(req, iodev_sqe, bme280_submit_sync);
87 }
88