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