This commit introduces a new Sensor Clock API, enabling the retrieval of cycle counts and conversion to nanoseconds based on the system or external clock. The API includes: - `sensor_clock_get_cycles()` to get the current cycle count from the sensor clock. - `sensor_clock_cycles_to_ns()` to convert cycles to nanoseconds using the clock's frequency. The implementation supports both system clocks and external clocks defined in the device tree, making the sensor clock integration more flexible for various sensor use cases. Signed-off-by: Mark Chen <mark.chen@cienet.com>
97 lines
2.3 KiB
C
97 lines
2.3 KiB
C
/*
|
|
* Copyright (c) 2024 Intel Corporation
|
|
* Copyright (c) 2024 Croxel Inc.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/rtio/work.h>
|
|
#include <zephyr/logging/log.h>
|
|
#include <zephyr/drivers/sensor_clock.h>
|
|
|
|
#include "bme280.h"
|
|
|
|
LOG_MODULE_DECLARE(BME280, CONFIG_SENSOR_LOG_LEVEL);
|
|
|
|
void bme280_submit_sync(struct rtio_iodev_sqe *iodev_sqe)
|
|
{
|
|
uint32_t min_buf_len = sizeof(struct bme280_encoded_data);
|
|
int rc;
|
|
uint64_t cycles;
|
|
uint8_t *buf;
|
|
uint32_t buf_len;
|
|
|
|
const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data;
|
|
const struct device *dev = cfg->sensor;
|
|
const struct sensor_chan_spec *const channels = cfg->channels;
|
|
const size_t num_channels = cfg->count;
|
|
|
|
rc = rtio_sqe_rx_buf(iodev_sqe, min_buf_len, min_buf_len, &buf, &buf_len);
|
|
if (rc != 0) {
|
|
LOG_ERR("Failed to get a read buffer of size %u bytes", min_buf_len);
|
|
rtio_iodev_sqe_err(iodev_sqe, rc);
|
|
return;
|
|
}
|
|
|
|
rc = sensor_clock_get_cycles(&cycles);
|
|
if (rc != 0) {
|
|
LOG_ERR("Failed to get sensor clock cycles");
|
|
rtio_iodev_sqe_err(iodev_sqe, rc);
|
|
return;
|
|
}
|
|
|
|
struct bme280_encoded_data *edata;
|
|
|
|
edata = (struct bme280_encoded_data *)buf;
|
|
edata->header.timestamp = sensor_clock_cycles_to_ns(cycles);
|
|
edata->has_temp = 0;
|
|
edata->has_humidity = 0;
|
|
edata->has_press = 0;
|
|
|
|
/* Check if the requested channels are supported */
|
|
for (size_t i = 0; i < num_channels; i++) {
|
|
switch (channels[i].chan_type) {
|
|
case SENSOR_CHAN_AMBIENT_TEMP:
|
|
edata->has_temp = 1;
|
|
break;
|
|
case SENSOR_CHAN_HUMIDITY:
|
|
edata->has_humidity = 1;
|
|
break;
|
|
case SENSOR_CHAN_PRESS:
|
|
edata->has_press = 1;
|
|
break;
|
|
case SENSOR_CHAN_ALL:
|
|
edata->has_temp = 1;
|
|
edata->has_humidity = 1;
|
|
edata->has_press = 1;
|
|
break;
|
|
default:
|
|
continue;
|
|
break;
|
|
}
|
|
}
|
|
|
|
rc = bme280_sample_fetch_helper(dev, SENSOR_CHAN_ALL, &edata->reading);
|
|
if (rc != 0) {
|
|
LOG_ERR("Failed to fetch samples");
|
|
rtio_iodev_sqe_err(iodev_sqe, rc);
|
|
return;
|
|
}
|
|
|
|
rtio_iodev_sqe_ok(iodev_sqe, 0);
|
|
}
|
|
|
|
void bme280_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe)
|
|
{
|
|
struct rtio_work_req *req = rtio_work_req_alloc();
|
|
|
|
if (req == NULL) {
|
|
LOG_ERR("RTIO work item allocation failed. Consider to increase "
|
|
"CONFIG_RTIO_WORKQ_POOL_ITEMS.");
|
|
rtio_iodev_sqe_err(iodev_sqe, -ENOMEM);
|
|
return;
|
|
}
|
|
|
|
rtio_work_req_submit(req, iodev_sqe, bme280_submit_sync);
|
|
}
|