sensors: Add channel specifier

Use a structured channel specifier rather than a single enum when
specifying channels to read in the new read/decoder API.

Replaces usages of a seperate channel and channel_index parameter
where previously used with a struct sensor_chan_spec.

Signed-off-by: Tom Burdick <thomas.burdick@intel.com>
This commit is contained in:
Tom Burdick 2024-04-06 09:29:28 -05:00 committed by Carles Cufí
commit b249535093
17 changed files with 295 additions and 237 deletions

View file

@ -99,7 +99,7 @@ static int sb_tsi_emul_init(const struct emul *target, const struct device *pare
return 0;
}
static int sb_tsi_emul_set_channel(const struct emul *target, enum sensor_channel chan,
static int sb_tsi_emul_set_channel(const struct emul *target, struct sensor_chan_spec ch,
const q31_t *value, int8_t shift)
{
struct sb_tsi_emul_data *data = target->data;
@ -107,7 +107,7 @@ static int sb_tsi_emul_set_channel(const struct emul *target, enum sensor_channe
int32_t millicelsius;
int32_t reg_value;
if (chan != SENSOR_CHAN_AMBIENT_TEMP) {
if (ch.chan_type != SENSOR_CHAN_AMBIENT_TEMP && ch.chan_idx != 0) {
return -ENOTSUP;
}
@ -121,10 +121,10 @@ static int sb_tsi_emul_set_channel(const struct emul *target, enum sensor_channe
return 0;
}
static int sb_tsi_emul_get_sample_range(const struct emul *target, enum sensor_channel chan,
static int sb_tsi_emul_get_sample_range(const struct emul *target, struct sensor_chan_spec ch,
q31_t *lower, q31_t *upper, q31_t *epsilon, int8_t *shift)
{
if (chan != SENSOR_CHAN_AMBIENT_TEMP) {
if (ch.chan_type != SENSOR_CHAN_AMBIENT_TEMP || ch.chan_idx != 0) {
return -ENOTSUP;
}

View file

@ -5,22 +5,22 @@
#include "akm09918c.h"
static int akm09918c_decoder_get_frame_count(const uint8_t *buffer, enum sensor_channel channel,
size_t channel_idx, uint16_t *frame_count)
static int akm09918c_decoder_get_frame_count(const uint8_t *buffer,
struct sensor_chan_spec chan_spec,
uint16_t *frame_count)
{
ARG_UNUSED(buffer);
ARG_UNUSED(channel);
ARG_UNUSED(channel_idx);
ARG_UNUSED(chan_spec);
/* This sensor lacks a FIFO; there will always only be one frame at a time. */
*frame_count = 1;
return 0;
}
static int akm09918c_decoder_get_size_info(enum sensor_channel channel, size_t *base_size,
static int akm09918c_decoder_get_size_info(struct sensor_chan_spec chan_spec, size_t *base_size,
size_t *frame_size)
{
switch (channel) {
switch (chan_spec.chan_type) {
case SENSOR_CHAN_MAGN_X:
case SENSOR_CHAN_MAGN_Y:
case SENSOR_CHAN_MAGN_Z:
@ -48,9 +48,8 @@ static int akm09918c_convert_raw_to_q31(int16_t reading, q31_t *out)
return 0;
}
static int akm09918c_decoder_decode(const uint8_t *buffer, enum sensor_channel channel,
size_t channel_idx, uint32_t *fit,
uint16_t max_count, void *data_out)
static int akm09918c_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec,
uint32_t *fit, uint16_t max_count, void *data_out)
{
const struct akm09918c_encoded_data *edata = (const struct akm09918c_encoded_data *)buffer;
@ -58,7 +57,7 @@ static int akm09918c_decoder_decode(const uint8_t *buffer, enum sensor_channel c
return 0;
}
switch (channel) {
switch (chan_spec.chan_type) {
case SENSOR_CHAN_MAGN_X:
case SENSOR_CHAN_MAGN_Y:
case SENSOR_CHAN_MAGN_Z:

View file

@ -133,7 +133,7 @@ static int akm09918c_emul_init(const struct emul *target, const struct device *p
return 0;
}
static int akm09918c_emul_backend_set_channel(const struct emul *target, enum sensor_channel ch,
static int akm09918c_emul_backend_set_channel(const struct emul *target, struct sensor_chan_spec ch,
const q31_t *value, int8_t shift)
{
if (!target || !target->data) {
@ -143,7 +143,7 @@ static int akm09918c_emul_backend_set_channel(const struct emul *target, enum se
struct akm09918c_emul_data *data = target->data;
uint8_t reg;
switch (ch) {
switch (ch.chan_type) {
case SENSOR_CHAN_MAGN_X:
reg = AKM09918C_REG_HXL;
break;
@ -178,7 +178,7 @@ static int akm09918c_emul_backend_set_channel(const struct emul *target, enum se
}
static int akm09918c_emul_backend_get_sample_range(const struct emul *target,
enum sensor_channel ch, q31_t *lower,
struct sensor_chan_spec ch, q31_t *lower,
q31_t *upper, q31_t *epsilon, int8_t *shift)
{
ARG_UNUSED(target);
@ -187,7 +187,7 @@ static int akm09918c_emul_backend_get_sample_range(const struct emul *target,
return -EINVAL;
}
switch (ch) {
switch (ch.chan_type) {
case SENSOR_CHAN_MAGN_X:
case SENSOR_CHAN_MAGN_Y:
case SENSOR_CHAN_MAGN_Z:

View file

@ -343,7 +343,7 @@ static int bma4xx_submit_one_shot(const struct device *dev, struct rtio_iodev_sq
struct bma4xx_data *bma4xx = dev->data;
const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data;
const enum sensor_channel *const channels = cfg->channels;
const struct sensor_chan_spec *const channels = cfg->channels;
const size_t num_channels = cfg->count;
uint32_t min_buf_len = sizeof(struct bma4xx_encoded_data);
@ -370,7 +370,11 @@ static int bma4xx_submit_one_shot(const struct device *dev, struct rtio_iodev_sq
/* Determine what channels we need to fetch */
for (int i = 0; i < num_channels; i++) {
switch (channels[i]) {
if (channels[i].chan_idx != 0) {
LOG_ERR("Only channel index 0 supported");
return -ENOTSUP;
}
switch (channels[i].chan_type) {
case SENSOR_CHAN_ALL:
edata->has_accel = 1;
#ifdef CONFIG_BMA4XX_TEMPERATURE
@ -389,7 +393,8 @@ static int bma4xx_submit_one_shot(const struct device *dev, struct rtio_iodev_sq
break;
#endif /* CONFIG_BMA4XX_TEMPERATURE */
default:
LOG_ERR("Requested unsupported channel ID %d", channels[i]);
LOG_ERR("Requested unsupported channel type %d, idx %d",
channels[i].chan_type, channels[i].chan_idx);
return -ENOTSUP;
}
}
@ -436,18 +441,18 @@ static int bma4xx_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_
* RTIO decoder
*/
static int bma4xx_decoder_get_frame_count(const uint8_t *buffer, enum sensor_channel channel,
size_t channel_idx, uint16_t *frame_count)
static int bma4xx_decoder_get_frame_count(const uint8_t *buffer, struct sensor_chan_spec ch,
uint16_t *frame_count)
{
const struct bma4xx_encoded_data *edata = (const struct bma4xx_encoded_data *)buffer;
const struct bma4xx_decoder_header *header = &edata->header;
if (channel_idx != 0) {
if (ch.chan_idx != 0) {
return -ENOTSUP;
}
if (!header->is_fifo) {
switch (channel) {
switch (ch.chan_type) {
case SENSOR_CHAN_ACCEL_X:
case SENSOR_CHAN_ACCEL_Y:
case SENSOR_CHAN_ACCEL_Z:
@ -467,10 +472,10 @@ static int bma4xx_decoder_get_frame_count(const uint8_t *buffer, enum sensor_cha
return -ENOTSUP;
}
static int bma4xx_decoder_get_size_info(enum sensor_channel channel, size_t *base_size,
static int bma4xx_decoder_get_size_info(struct sensor_chan_spec ch, size_t *base_size,
size_t *frame_size)
{
switch (channel) {
switch (ch.chan_type) {
case SENSOR_CHAN_ACCEL_X:
case SENSOR_CHAN_ACCEL_Y:
case SENSOR_CHAN_ACCEL_Z:
@ -487,9 +492,9 @@ static int bma4xx_decoder_get_size_info(enum sensor_channel channel, size_t *bas
}
}
static int bma4xx_get_shift(enum sensor_channel channel, uint8_t accel_fs, int8_t *shift)
static int bma4xx_get_shift(struct sensor_chan_spec ch, uint8_t accel_fs, int8_t *shift)
{
switch (channel) {
switch (ch.chan_type) {
case SENSOR_CHAN_ACCEL_X:
case SENSOR_CHAN_ACCEL_Y:
case SENSOR_CHAN_ACCEL_Z:
@ -562,9 +567,8 @@ static void bma4xx_convert_raw_temp_to_q31(int8_t raw_val, q31_t *out)
}
#endif /* CONFIG_BMA4XX_TEMPERATURE */
static int bma4xx_one_shot_decode(const uint8_t *buffer, enum sensor_channel channel,
size_t channel_idx, uint32_t *fit, uint16_t max_count,
void *data_out)
static int bma4xx_one_shot_decode(const uint8_t *buffer, struct sensor_chan_spec ch,
uint32_t *fit, uint16_t max_count, void *data_out)
{
const struct bma4xx_encoded_data *edata = (const struct bma4xx_encoded_data *)buffer;
const struct bma4xx_decoder_header *header = &edata->header;
@ -573,11 +577,11 @@ static int bma4xx_one_shot_decode(const uint8_t *buffer, enum sensor_channel cha
if (*fit != 0) {
return 0;
}
if (max_count == 0 || channel_idx != 0) {
if (max_count == 0 || ch.chan_idx != 0) {
return -EINVAL;
}
switch (channel) {
switch (ch.chan_type) {
case SENSOR_CHAN_ACCEL_X:
case SENSOR_CHAN_ACCEL_Y:
case SENSOR_CHAN_ACCEL_Z:
@ -590,7 +594,9 @@ static int bma4xx_one_shot_decode(const uint8_t *buffer, enum sensor_channel cha
out->header.base_timestamp_ns = edata->header.timestamp;
out->header.reading_count = 1;
rc = bma4xx_get_shift(SENSOR_CHAN_ACCEL_XYZ, header->accel_fs, &out->shift);
rc = bma4xx_get_shift((struct sensor_chan_spec){.chan_type = SENSOR_CHAN_ACCEL_XYZ,
.chan_idx = 0},
header->accel_fs, &out->shift);
if (rc != 0) {
return -EINVAL;
}
@ -628,8 +634,8 @@ static int bma4xx_one_shot_decode(const uint8_t *buffer, enum sensor_channel cha
}
}
static int bma4xx_decoder_decode(const uint8_t *buffer, enum sensor_channel channel,
size_t channel_idx, uint32_t *fit, uint16_t max_count,
static int bma4xx_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec ch,
uint32_t *fit, uint16_t max_count,
void *data_out)
{
const struct bma4xx_decoder_header *header = (const struct bma4xx_decoder_header *)buffer;
@ -639,7 +645,7 @@ static int bma4xx_decoder_decode(const uint8_t *buffer, enum sensor_channel chan
return -ENOTSUP;
}
return bma4xx_one_shot_decode(buffer, channel, channel_idx, fit, max_count, data_out);
return bma4xx_one_shot_decode(buffer, ch, fit, max_count, data_out);
}
SENSOR_DECODER_API_DT_DEFINE() = {

View file

@ -216,7 +216,7 @@ void bma4xx_emul_set_accel_data(const struct emul *target, q31_t value, int8_t s
data->regs[reg + 1] = FIELD_GET(GENMASK(11, 4), reg_val);
}
static int bma4xx_emul_backend_set_channel(const struct emul *target, enum sensor_channel ch,
static int bma4xx_emul_backend_set_channel(const struct emul *target, struct sensor_chan_spec ch,
const q31_t *value, int8_t shift)
{
@ -226,7 +226,7 @@ static int bma4xx_emul_backend_set_channel(const struct emul *target, enum senso
struct bma4xx_emul_data *data = target->data;
switch (ch) {
switch (ch.chan_type) {
case SENSOR_CHAN_ACCEL_X:
bma4xx_emul_set_accel_data(target, value[0], shift, BMA4XX_REG_DATA_8);
break;
@ -250,15 +250,15 @@ static int bma4xx_emul_backend_set_channel(const struct emul *target, enum senso
return 0;
}
static int bma4xx_emul_backend_get_sample_range(const struct emul *target, enum sensor_channel ch,
q31_t *lower, q31_t *upper, q31_t *epsilon,
int8_t *shift)
static int bma4xx_emul_backend_get_sample_range(const struct emul *target,
struct sensor_chan_spec ch, q31_t *lower,
q31_t *upper, q31_t *epsilon, int8_t *shift)
{
if (!lower || !upper || !epsilon || !shift) {
return -EINVAL;
}
switch (ch) {
switch (ch.chan_type) {
case SENSOR_CHAN_ACCEL_X:
case SENSOR_CHAN_ACCEL_Y:
case SENSOR_CHAN_ACCEL_Z:

View file

@ -279,7 +279,7 @@ static struct i2c_emul_api bmi160_emul_api_i2c = {
};
#endif
static int bmi160_emul_backend_set_channel(const struct emul *target, enum sensor_channel ch,
static int bmi160_emul_backend_set_channel(const struct emul *target, struct sensor_chan_spec ch,
const q31_t *value, int8_t shift)
{
const struct bmi160_emul_cfg *cfg = target->cfg;
@ -288,11 +288,11 @@ static int bmi160_emul_backend_set_channel(const struct emul *target, enum senso
int8_t scale_shift = 0;
int reg_lsb;
switch (ch) {
switch (ch.chan_type) {
case SENSOR_CHAN_ACCEL_X:
case SENSOR_CHAN_ACCEL_Y:
case SENSOR_CHAN_ACCEL_Z:
reg_lsb = BMI160_REG_DATA_ACC_X + (ch - SENSOR_CHAN_ACCEL_X) * 2;
reg_lsb = BMI160_REG_DATA_ACC_X + (ch.chan_type - SENSOR_CHAN_ACCEL_X) * 2;
scale = 0x4e7404ea;
switch (FIELD_GET(GENMASK(3, 0), cfg->reg[BMI160_REG_ACC_RANGE])) {
@ -313,7 +313,7 @@ static int bmi160_emul_backend_set_channel(const struct emul *target, enum senso
case SENSOR_CHAN_GYRO_X:
case SENSOR_CHAN_GYRO_Y:
case SENSOR_CHAN_GYRO_Z:
reg_lsb = BMI160_REG_DATA_GYR_X + (ch - SENSOR_CHAN_GYRO_X) * 2;
reg_lsb = BMI160_REG_DATA_GYR_X + (ch.chan_type - SENSOR_CHAN_GYRO_X) * 2;
scale = 0x45d02bea;
switch (FIELD_GET(GENMASK(2, 0), cfg->reg[BMI160_REG_GYR_RANGE])) {
@ -353,7 +353,7 @@ static int bmi160_emul_backend_set_channel(const struct emul *target, enum senso
intermediate <<= shift - scale_shift;
}
if (ch == SENSOR_CHAN_DIE_TEMP) {
if (ch.chan_type == SENSOR_CHAN_DIE_TEMP) {
/* Need to subtract 23C */
intermediate -= INT64_C(23) << (31 - scale_shift);
}
@ -366,13 +366,13 @@ static int bmi160_emul_backend_set_channel(const struct emul *target, enum senso
return 0;
}
static int bmi160_emul_backend_get_sample_range(const struct emul *target, enum sensor_channel ch,
q31_t *lower, q31_t *upper, q31_t *epsilon,
int8_t *shift)
static int bmi160_emul_backend_get_sample_range(const struct emul *target,
struct sensor_chan_spec ch, q31_t *lower,
q31_t *upper, q31_t *epsilon, int8_t *shift)
{
const struct bmi160_emul_cfg *cfg = target->cfg;
switch (ch) {
switch (ch.chan_type) {
case SENSOR_CHAN_ACCEL_X:
case SENSOR_CHAN_ACCEL_Y:
case SENSOR_CHAN_ACCEL_Z:
@ -440,10 +440,10 @@ static int bmi160_emul_backend_get_sample_range(const struct emul *target, enum
}
}
static int bmi160_emul_backend_set_offset(const struct emul *target, enum sensor_channel ch,
static int bmi160_emul_backend_set_offset(const struct emul *target, struct sensor_chan_spec ch,
const q31_t *values, int8_t shift)
{
if (ch != SENSOR_CHAN_ACCEL_XYZ && ch != SENSOR_CHAN_GYRO_XYZ) {
if (ch.chan_type != SENSOR_CHAN_ACCEL_XYZ && ch.chan_type != SENSOR_CHAN_GYRO_XYZ) {
return -EINVAL;
}
@ -452,20 +452,20 @@ static int bmi160_emul_backend_set_offset(const struct emul *target, enum sensor
int8_t scale_shift = 0;
if (values[0] == 0 && values[1] == 0 && values[2] == 0) {
if (ch == SENSOR_CHAN_ACCEL_XYZ) {
if (ch.chan_type == SENSOR_CHAN_ACCEL_XYZ) {
cfg->reg[BMI160_REG_OFFSET_EN] &= ~BIT(BMI160_ACC_OFS_EN_POS);
} else {
cfg->reg[BMI160_REG_OFFSET_EN] &= ~BIT(BMI160_GYR_OFS_EN_POS);
}
} else {
if (ch == SENSOR_CHAN_ACCEL_XYZ) {
if (ch.chan_type == SENSOR_CHAN_ACCEL_XYZ) {
cfg->reg[BMI160_REG_OFFSET_EN] |= BIT(BMI160_ACC_OFS_EN_POS);
} else {
cfg->reg[BMI160_REG_OFFSET_EN] |= BIT(BMI160_GYR_OFS_EN_POS);
}
}
if (ch == SENSOR_CHAN_ACCEL_XYZ) {
if (ch.chan_type == SENSOR_CHAN_ACCEL_XYZ) {
/*
* bits = (values[i]mps2 / 9.80665g/mps2) / 0.0039g
* = values[i] / 0.038245935mps2/bit
@ -493,11 +493,11 @@ static int bmi160_emul_backend_set_offset(const struct emul *target, enum sensor
int64_t reg_value = intermediate / scale;
__ASSERT_NO_MSG(ch != SENSOR_CHAN_ACCEL_XYZ ||
__ASSERT_NO_MSG(ch.chan_type != SENSOR_CHAN_ACCEL_XYZ ||
(reg_value >= INT8_MIN && reg_value <= INT8_MAX));
__ASSERT_NO_MSG(ch != SENSOR_CHAN_GYRO_XYZ ||
__ASSERT_NO_MSG(ch.chan_type != SENSOR_CHAN_GYRO_XYZ ||
(reg_value >= -0x1ff - 1 && reg_value <= 0x1ff));
if (ch == SENSOR_CHAN_ACCEL_XYZ) {
if (ch.chan_type == SENSOR_CHAN_ACCEL_XYZ) {
cfg->reg[BMI160_REG_OFFSET_ACC_X + i] = reg_value & 0xff;
} else {
cfg->reg[BMI160_REG_OFFSET_GYR_X + i] = reg_value & 0xff;
@ -510,11 +510,11 @@ static int bmi160_emul_backend_set_offset(const struct emul *target, enum sensor
return 0;
}
static int bmi160_emul_backend_set_attribute(const struct emul *target, enum sensor_channel ch,
static int bmi160_emul_backend_set_attribute(const struct emul *target, struct sensor_chan_spec ch,
enum sensor_attribute attribute, const void *value)
{
if (attribute == SENSOR_ATTR_OFFSET &&
(ch == SENSOR_CHAN_ACCEL_XYZ || ch == SENSOR_CHAN_GYRO_XYZ)) {
(ch.chan_type == SENSOR_CHAN_ACCEL_XYZ || ch.chan_type == SENSOR_CHAN_GYRO_XYZ)) {
const struct sensor_three_axis_attribute *attribute_value = value;
return bmi160_emul_backend_set_offset(target, ch, attribute_value->values,
@ -524,12 +524,12 @@ static int bmi160_emul_backend_set_attribute(const struct emul *target, enum sen
}
static int bmi160_emul_backend_get_attribute_metadata(const struct emul *target,
enum sensor_channel ch,
struct sensor_chan_spec ch,
enum sensor_attribute attribute, q31_t *min,
q31_t *max, q31_t *increment, int8_t *shift)
{
ARG_UNUSED(target);
switch (ch) {
switch (ch.chan_type) {
case SENSOR_CHAN_ACCEL_X:
case SENSOR_CHAN_ACCEL_Y:
case SENSOR_CHAN_ACCEL_Z:

View file

@ -13,10 +13,10 @@
LOG_MODULE_REGISTER(sensor_compat, CONFIG_SENSOR_LOG_LEVEL);
/*
* Ensure that the size of the generic header aligns with the sensor channel enum. If it doesn't,
* then cores that require aligned memory access will fail to read channel[0].
* Ensure that the size of the generic header aligns with the sensor channel specifier . If it
* doesn't, then cores that require aligned memory access will fail to read channel[0].
*/
BUILD_ASSERT((sizeof(struct sensor_data_generic_header) % sizeof(enum sensor_channel)) == 0);
BUILD_ASSERT((sizeof(struct sensor_data_generic_header) % sizeof(struct sensor_chan_spec)) == 0);
static void sensor_submit_fallback(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe);
@ -46,12 +46,13 @@ const struct rtio_iodev_api __sensor_iodev_api = {
* @param[in] num_channels Number of channels on the @p channels array
* @return The number of samples required to read the given channels
*/
static inline int compute_num_samples(const enum sensor_channel *channels, size_t num_channels)
static inline int compute_num_samples(const struct sensor_chan_spec *const channels,
size_t num_channels)
{
int num_samples = 0;
for (size_t i = 0; i < num_channels; ++i) {
num_samples += SENSOR_CHANNEL_3_AXIS(channels[i]) ? 3 : 1;
num_samples += SENSOR_CHANNEL_3_AXIS(channels[i].chan_type) ? 3 : 1;
}
return num_samples;
@ -68,7 +69,7 @@ static inline int compute_num_samples(const enum sensor_channel *channels, size_
static inline uint32_t compute_header_size(int num_output_samples)
{
uint32_t size = sizeof(struct sensor_data_generic_header) +
(num_output_samples * sizeof(enum sensor_channel));
(num_output_samples * sizeof(struct sensor_chan_spec));
return (size + 3) & ~0x3;
}
@ -92,12 +93,12 @@ static inline uint32_t compute_min_buf_len(int num_output_samples)
* @return Index of the @p channel if found or negative if not found
*/
static inline int check_header_contains_channel(const struct sensor_data_generic_header *header,
enum sensor_channel channel, int num_channels)
struct sensor_chan_spec chan_spec, int num_channels)
{
__ASSERT_NO_MSG(!SENSOR_CHANNEL_3_AXIS(channel));
__ASSERT_NO_MSG(!SENSOR_CHANNEL_3_AXIS(chan_spec.chan_type));
for (int i = 0; i < num_channels; ++i) {
if (header->channels[i] == channel) {
if (sensor_chan_spec_eq(header->channels[i], chan_spec)) {
return i;
}
}
@ -113,7 +114,7 @@ static inline int check_header_contains_channel(const struct sensor_data_generic
static void sensor_submit_fallback(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe)
{
const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data;
const enum sensor_channel *const channels = cfg->channels;
const struct sensor_chan_spec *const channels = cfg->channels;
const int num_output_samples = compute_num_samples(channels, cfg->count);
uint32_t min_buf_len = compute_min_buf_len(num_output_samples);
uint64_t timestamp_ns = k_ticks_to_ns_floor64(k_uptime_ticks());
@ -148,23 +149,34 @@ static void sensor_submit_fallback(const struct device *dev, struct rtio_iodev_s
/* Populate values, update shift, and set channels */
for (size_t i = 0, sample_idx = 0; i < cfg->count; ++i) {
struct sensor_value value[3];
const int num_samples = SENSOR_CHANNEL_3_AXIS(channels[i]) ? 3 : 1;
const int num_samples = SENSOR_CHANNEL_3_AXIS(channels[i].chan_type) ? 3 : 1;
/* Get the current channel requested by the user */
rc = sensor_channel_get(dev, channels[i], value);
rc = sensor_channel_get(dev, channels[i].chan_type, value);
if (num_samples == 3) {
header->channels[sample_idx++] =
rc == 0 ? channels[i] - 3 : SENSOR_CHAN_MAX;
header->channels[sample_idx++] =
rc == 0 ? channels[i] - 2 : SENSOR_CHAN_MAX;
header->channels[sample_idx++] =
rc == 0 ? channels[i] - 1 : SENSOR_CHAN_MAX;
header->channels[sample_idx++] = (struct sensor_chan_spec) {
rc == 0 ? channels[i].chan_type - 3 : SENSOR_CHAN_MAX,
0
};
header->channels[sample_idx++] = (struct sensor_chan_spec) {
rc == 0 ? channels[i].chan_type - 2 : SENSOR_CHAN_MAX,
0
};
header->channels[sample_idx++] = (struct sensor_chan_spec) {
rc == 0 ? channels[i].chan_type - 1 : SENSOR_CHAN_MAX,
0
};
} else {
header->channels[sample_idx++] = rc == 0 ? channels[i] : SENSOR_CHAN_MAX;
header->channels[sample_idx++] = (struct sensor_chan_spec) {
rc == 0 ? channels[i].chan_type : SENSOR_CHAN_MAX,
0
};
}
if (rc != 0) {
LOG_DBG("Failed to get channel (type: %d, index %d), skipping",
channels[i].chan_type, channels[i].chan_idx);
continue;
}
@ -277,45 +289,41 @@ void sensor_processing_with_callback(struct rtio *ctx, sensor_processing_callbac
* @param[out] frame_count The number of frames in the buffer (always 1)
* @return 0 in all cases
*/
static int get_frame_count(const uint8_t *buffer, enum sensor_channel channel, size_t channel_idx,
static int get_frame_count(const uint8_t *buffer, struct sensor_chan_spec channel,
uint16_t *frame_count)
{
struct sensor_data_generic_header *header = (struct sensor_data_generic_header *)buffer;
size_t count = 0;
switch (channel) {
switch (channel.chan_type) {
case SENSOR_CHAN_ACCEL_XYZ:
channel = SENSOR_CHAN_ACCEL_X;
channel.chan_type = SENSOR_CHAN_ACCEL_X;
break;
case SENSOR_CHAN_GYRO_XYZ:
channel = SENSOR_CHAN_GYRO_X;
channel.chan_type = SENSOR_CHAN_GYRO_X;
break;
case SENSOR_CHAN_MAGN_XYZ:
channel = SENSOR_CHAN_MAGN_X;
channel.chan_type = SENSOR_CHAN_MAGN_X;
break;
default:
break;
}
for (size_t i = 0; i < header->num_channels; ++i) {
if (header->channels[i] == channel) {
if (channel_idx == count) {
*frame_count = 1;
return 0;
}
++count;
if (sensor_chan_spec_eq(header->channels[i], channel)) {
*frame_count = 1;
return 0;
}
}
return -ENOTSUP;
}
int sensor_natively_supported_channel_size_info(enum sensor_channel channel, size_t *base_size,
int sensor_natively_supported_channel_size_info(struct sensor_chan_spec channel, size_t *base_size,
size_t *frame_size)
{
__ASSERT_NO_MSG(base_size != NULL);
__ASSERT_NO_MSG(frame_size != NULL);
switch (channel) {
switch (channel.chan_type) {
case SENSOR_CHAN_ACCEL_X:
case SENSOR_CHAN_ACCEL_Y:
case SENSOR_CHAN_ACCEL_Z:
@ -391,19 +399,13 @@ int sensor_natively_supported_channel_size_info(enum sensor_channel channel, siz
}
static int get_q31_value(const struct sensor_data_generic_header *header, const q31_t *values,
enum sensor_channel channel, size_t channel_idx, q31_t *out)
struct sensor_chan_spec chan_spec, q31_t *out)
{
size_t count = 0;
for (size_t i = 0; i < header->num_channels; ++i) {
if (channel != header->channels[i]) {
continue;
}
if (count == channel_idx) {
if (sensor_chan_spec_eq(chan_spec, header->channels[i])) {
*out = values[i];
return 0;
}
++count;
}
return -EINVAL;
}
@ -419,15 +421,18 @@ static int decode_three_axis(const struct sensor_data_generic_header *header, co
data_out->shift = header->shift;
data_out->readings[0].timestamp_delta = 0;
rc = get_q31_value(header, values, x, channel_idx, &data_out->readings[0].values[0]);
rc = get_q31_value(header, values, (struct sensor_chan_spec){x, channel_idx},
&data_out->readings[0].values[0]);
if (rc < 0) {
return rc;
}
rc = get_q31_value(header, values, y, channel_idx, &data_out->readings[0].values[1]);
rc = get_q31_value(header, values, (struct sensor_chan_spec){y, channel_idx},
&data_out->readings[0].values[1]);
if (rc < 0) {
return rc;
}
rc = get_q31_value(header, values, z, channel_idx, &data_out->readings[0].values[2]);
rc = get_q31_value(header, values, (struct sensor_chan_spec){z, channel_idx},
&data_out->readings[0].values[2]);
if (rc < 0) {
return rc;
}
@ -435,8 +440,7 @@ static int decode_three_axis(const struct sensor_data_generic_header *header, co
}
static int decode_q31(const struct sensor_data_generic_header *header, const q31_t *values,
struct sensor_q31_data *data_out, enum sensor_channel channel,
size_t channel_idx)
struct sensor_q31_data *data_out, struct sensor_chan_spec chan_spec)
{
int rc;
@ -445,7 +449,7 @@ static int decode_q31(const struct sensor_data_generic_header *header, const q31
data_out->shift = header->shift;
data_out->readings[0].timestamp_delta = 0;
rc = get_q31_value(header, values, channel, channel_idx, &data_out->readings[0].value);
rc = get_q31_value(header, values, chan_spec, &data_out->readings[0].value);
if (rc < 0) {
return rc;
}
@ -469,7 +473,7 @@ static int decode_q31(const struct sensor_data_generic_header *header, const q31
* @return >0 the number of decoded frames
* @return <0 on error
*/
static int decode(const uint8_t *buffer, enum sensor_channel channel, size_t channel_idx,
static int decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec,
uint32_t *fit, uint16_t max_count, void *data_out)
{
const struct sensor_data_generic_header *header =
@ -482,33 +486,37 @@ static int decode(const uint8_t *buffer, enum sensor_channel channel, size_t cha
}
/* Check for 3d channel mappings */
switch (channel) {
switch (chan_spec.chan_type) {
case SENSOR_CHAN_ACCEL_X:
case SENSOR_CHAN_ACCEL_Y:
case SENSOR_CHAN_ACCEL_Z:
case SENSOR_CHAN_ACCEL_XYZ:
count = decode_three_axis(header, q, data_out, SENSOR_CHAN_ACCEL_X,
SENSOR_CHAN_ACCEL_Y, SENSOR_CHAN_ACCEL_Z, channel_idx);
SENSOR_CHAN_ACCEL_Y, SENSOR_CHAN_ACCEL_Z,
chan_spec.chan_idx);
break;
case SENSOR_CHAN_GYRO_X:
case SENSOR_CHAN_GYRO_Y:
case SENSOR_CHAN_GYRO_Z:
case SENSOR_CHAN_GYRO_XYZ:
count = decode_three_axis(header, q, data_out, SENSOR_CHAN_GYRO_X,
SENSOR_CHAN_GYRO_Y, SENSOR_CHAN_GYRO_Z, channel_idx);
SENSOR_CHAN_GYRO_Y, SENSOR_CHAN_GYRO_Z,
chan_spec.chan_idx);
break;
case SENSOR_CHAN_MAGN_X:
case SENSOR_CHAN_MAGN_Y:
case SENSOR_CHAN_MAGN_Z:
case SENSOR_CHAN_MAGN_XYZ:
count = decode_three_axis(header, q, data_out, SENSOR_CHAN_MAGN_X,
SENSOR_CHAN_MAGN_Y, SENSOR_CHAN_MAGN_Z, channel_idx);
SENSOR_CHAN_MAGN_Y, SENSOR_CHAN_MAGN_Z,
chan_spec.chan_idx);
break;
case SENSOR_CHAN_POS_DX:
case SENSOR_CHAN_POS_DY:
case SENSOR_CHAN_POS_DZ:
count = decode_three_axis(header, q, data_out, SENSOR_CHAN_POS_DX,
SENSOR_CHAN_POS_DY, SENSOR_CHAN_POS_DZ, channel_idx);
SENSOR_CHAN_POS_DY, SENSOR_CHAN_POS_DZ,
chan_spec.chan_idx);
break;
case SENSOR_CHAN_DIE_TEMP:
case SENSOR_CHAN_AMBIENT_TEMP:
@ -550,7 +558,7 @@ static int decode(const uint8_t *buffer, enum sensor_channel channel, size_t cha
case SENSOR_CHAN_GAUGE_DESIGN_VOLTAGE:
case SENSOR_CHAN_GAUGE_DESIRED_VOLTAGE:
case SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT:
count = decode_q31(header, q, data_out, channel, channel_idx);
count = decode_q31(header, q, data_out, chan_spec);
break;
default:
break;

View file

@ -103,7 +103,7 @@ static int f75303_emul_init(const struct emul *target, const struct device *pare
return 0;
}
static int f75303_emul_set_channel(const struct emul *target, enum sensor_channel chan,
static int f75303_emul_set_channel(const struct emul *target, struct sensor_chan_spec ch,
const q31_t *value, int8_t shift)
{
struct f75303_emul_data *data = target->data;
@ -112,7 +112,7 @@ static int f75303_emul_set_channel(const struct emul *target, enum sensor_channe
int32_t reg_value;
uint8_t reg_h, reg_l;
switch ((int32_t)chan) {
switch ((int32_t)ch.chan_type) {
case SENSOR_CHAN_AMBIENT_TEMP:
reg_h = F75303_LOCAL_TEMP_H;
reg_l = F75303_LOCAL_TEMP_L;
@ -139,12 +139,12 @@ static int f75303_emul_set_channel(const struct emul *target, enum sensor_channe
return 0;
}
static int f75303_emul_get_sample_range(const struct emul *target, enum sensor_channel chan,
static int f75303_emul_get_sample_range(const struct emul *target, struct sensor_chan_spec ch,
q31_t *lower, q31_t *upper, q31_t *epsilon, int8_t *shift)
{
if (chan != SENSOR_CHAN_AMBIENT_TEMP &&
chan != (enum sensor_channel)SENSOR_CHAN_F75303_REMOTE1 &&
chan != (enum sensor_channel)SENSOR_CHAN_F75303_REMOTE2) {
if (ch.chan_type != SENSOR_CHAN_AMBIENT_TEMP &&
ch.chan_type != (enum sensor_channel)SENSOR_CHAN_F75303_REMOTE1 &&
ch.chan_type != (enum sensor_channel)SENSOR_CHAN_F75303_REMOTE2) {
return -ENOTSUP;
}

View file

@ -217,7 +217,7 @@ static enum dynamic_command_context current_cmd_ctx = NONE;
K_MUTEX_DEFINE(cmd_get_mutex);
/* Crate a single common config for one-shot reading */
static enum sensor_channel iodev_sensor_shell_channels[SENSOR_CHAN_ALL];
static struct sensor_chan_spec iodev_sensor_shell_channels[SENSOR_CHAN_ALL];
static struct sensor_read_config iodev_sensor_shell_read_config = {
.sensor = NULL,
.is_streaming = false,
@ -330,23 +330,32 @@ void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t buf_len
: sensor_trigger_table[trigger].name));
}
for (int channel = 0; channel < SENSOR_CHAN_ALL; ++channel) {
for (struct sensor_chan_spec ch = {0, 0}; ch.chan_type < SENSOR_CHAN_ALL; ch.chan_type++) {
uint32_t fit = 0;
size_t base_size;
size_t frame_size;
size_t channel_idx = 0;
uint16_t frame_count;
if (channel == SENSOR_CHAN_ACCEL_X || channel == SENSOR_CHAN_ACCEL_Y ||
channel == SENSOR_CHAN_ACCEL_Z || channel == SENSOR_CHAN_GYRO_X ||
channel == SENSOR_CHAN_GYRO_Y || channel == SENSOR_CHAN_GYRO_Z ||
channel == SENSOR_CHAN_MAGN_X || channel == SENSOR_CHAN_MAGN_Y ||
channel == SENSOR_CHAN_MAGN_Z || channel == SENSOR_CHAN_POS_DY ||
channel == SENSOR_CHAN_POS_DZ) {
/* Channels with multi-axis equivalents are skipped */
switch (ch.chan_type) {
case SENSOR_CHAN_ACCEL_X:
case SENSOR_CHAN_ACCEL_Y:
case SENSOR_CHAN_ACCEL_Z:
case SENSOR_CHAN_GYRO_X:
case SENSOR_CHAN_GYRO_Y:
case SENSOR_CHAN_GYRO_Z:
case SENSOR_CHAN_MAGN_X:
case SENSOR_CHAN_MAGN_Y:
case SENSOR_CHAN_MAGN_Z:
case SENSOR_CHAN_POS_DY:
case SENSOR_CHAN_POS_DZ:
continue;
}
rc = decoder->get_size_info(channel, &base_size, &frame_size);
rc = decoder->get_size_info(ch, &base_size, &frame_size);
if (rc != 0) {
/* Channel not supported, skipping */
continue;
@ -354,19 +363,18 @@ void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t buf_len
if (base_size > ARRAY_SIZE(decoded_buffer)) {
shell_error(ctx->sh,
"Channel (%d) requires %zu bytes to decode, but only %zu are "
"available",
channel, base_size, ARRAY_SIZE(decoded_buffer));
"Channel (type %d, idx %d) requires %zu bytes to decode, but "
"only %zu are available",
ch.chan_type, ch.chan_idx, base_size,
ARRAY_SIZE(decoded_buffer));
continue;
}
while (decoder->get_frame_count(buf, channel, channel_idx, &frame_count) == 0) {
while (decoder->get_frame_count(buf, ch, &frame_count) == 0) {
fit = 0;
memset(&accumulator_buffer, 0, sizeof(accumulator_buffer));
while (decoder->decode(buf, channel, channel_idx, &fit, 1, decoded_buffer) >
0) {
switch (channel) {
while (decoder->decode(buf, ch, &fit, 1, decoded_buffer) > 0) {
switch (ch.chan_type) {
case SENSOR_CHAN_ACCEL_XYZ:
case SENSOR_CHAN_GYRO_XYZ:
case SENSOR_CHAN_MAGN_XYZ:
@ -420,7 +428,7 @@ void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t buf_len
}
/* Print the accumulated value average */
switch (channel) {
switch (ch.chan_type) {
case SENSOR_CHAN_ACCEL_XYZ:
case SENSOR_CHAN_GYRO_XYZ:
case SENSOR_CHAN_MAGN_XYZ:
@ -442,10 +450,10 @@ void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t buf_len
data->readings[0].values[2] = (q31_t)(accumulator_buffer.values[2] /
accumulator_buffer.count);
shell_info(ctx->sh,
"channel idx=%d %s shift=%d num_samples=%d "
"channel type=%d(%s) index=%d shift=%d num_samples=%d "
"value=%" PRIsensor_three_axis_data,
channel, sensor_channel_name[channel],
data->shift, accumulator_buffer.count,
ch.chan_type, sensor_channel_name[ch.chan_type],
ch.chan_idx, data->shift, accumulator_buffer.count,
PRIsensor_three_axis_data_arg(*data, 0));
break;
}
@ -463,10 +471,10 @@ void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t buf_len
accumulator_buffer.values[0] / accumulator_buffer.count;
shell_info(ctx->sh,
"channel idx=%d %s num_samples=%d "
"channel type=%d(%s) index=%d num_samples=%d "
"value=%" PRIsensor_byte_data(is_near),
channel, sensor_channel_name[channel],
accumulator_buffer.count,
ch.chan_type, sensor_channel_name[ch.chan_type],
ch.chan_idx, accumulator_buffer.count,
PRIsensor_byte_data_arg(*data, 0, is_near));
break;
}
@ -485,12 +493,13 @@ void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t buf_len
accumulator_buffer.count);
shell_info(ctx->sh,
"channel idx=%d %s shift=%d num_samples=%d "
"channel type=%d(%s) index=%d shift=%d num_samples=%d "
"value=%" PRIsensor_q31_data,
channel,
(channel >= ARRAY_SIZE(sensor_channel_name))
ch.chan_type,
(ch.chan_type >= ARRAY_SIZE(sensor_channel_name))
? ""
: sensor_channel_name[channel],
: sensor_channel_name[ch.chan_type],
ch.chan_idx,
data->shift, accumulator_buffer.count,
PRIsensor_q31_data_arg(*data, 0));
}
@ -521,12 +530,12 @@ static int cmd_get_sensor(const struct shell *sh, size_t argc, char *argv[])
}
if (argc == 2) {
/* read all channels */
/* read all channel types */
for (int i = 0; i < ARRAY_SIZE(iodev_sensor_shell_channels); ++i) {
if (SENSOR_CHANNEL_3_AXIS(i)) {
continue;
}
iodev_sensor_shell_channels[count++] = i;
iodev_sensor_shell_channels[count++] = (struct sensor_chan_spec){i, 0};
}
} else {
/* read specific channels */
@ -538,7 +547,8 @@ static int cmd_get_sensor(const struct shell *sh, size_t argc, char *argv[])
shell_error(sh, "Failed to read channel (%s)", argv[i]);
continue;
}
iodev_sensor_shell_channels[count++] = chan;
iodev_sensor_shell_channels[count++] =
(struct sensor_chan_spec){chan, 0};
}
}
@ -570,7 +580,6 @@ static int cmd_get_sensor(const struct shell *sh, size_t argc, char *argv[])
return 0;
}
static int cmd_sensor_attr_set(const struct shell *shell_ptr, size_t argc, char *argv[])
{
const struct device *dev;

View file

@ -178,7 +178,7 @@ static uint8_t icm42688_encode_channel(enum sensor_channel chan)
return encode_bmask;
}
int icm42688_encode(const struct device *dev, const enum sensor_channel *const channels,
int icm42688_encode(const struct device *dev, const struct sensor_chan_spec *const channels,
const size_t num_channels, uint8_t *buf)
{
struct icm42688_dev_data *data = dev->data;
@ -187,7 +187,7 @@ int icm42688_encode(const struct device *dev, const enum sensor_channel *const c
edata->channels = 0;
for (int i = 0; i < num_channels; i++) {
edata->channels |= icm42688_encode_channel(channels[i]);
edata->channels |= icm42688_encode_channel(channels[i].chan_type);
}
edata->header.is_fifo = false;
@ -345,9 +345,8 @@ static uint32_t gyro_period_ns[] = {
[ICM42688_GYRO_ODR_32000] = UINT32_C(1000000) / 32,
};
static int icm42688_fifo_decode(const uint8_t *buffer, enum sensor_channel channel,
size_t channel_idx, uint32_t *fit, uint16_t max_count,
void *data_out)
static int icm42688_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec,
uint32_t *fit, uint16_t max_count, void *data_out)
{
const struct icm42688_fifo_data *edata = (const struct icm42688_fifo_data *)buffer;
const uint8_t *buffer_end = buffer + sizeof(struct icm42688_fifo_data) + edata->fifo_count;
@ -356,7 +355,7 @@ static int icm42688_fifo_decode(const uint8_t *buffer, enum sensor_channel chann
int count = 0;
int rc;
if ((uintptr_t)buffer_end <= *fit || channel_idx != 0) {
if ((uintptr_t)buffer_end <= *fit || chan_spec.chan_idx != 0) {
return 0;
}
@ -388,7 +387,7 @@ static int icm42688_fifo_decode(const uint8_t *buffer, enum sensor_channel chann
buffer = frame_end;
continue;
}
if (channel == SENSOR_CHAN_DIE_TEMP) {
if (chan_spec.chan_type == SENSOR_CHAN_DIE_TEMP) {
struct sensor_q31_data *data = (struct sensor_q31_data *)data_out;
data->shift = 9;
@ -401,7 +400,7 @@ static int icm42688_fifo_decode(const uint8_t *buffer, enum sensor_channel chann
}
data->readings[count].temperature =
icm42688_read_temperature_from_packet(buffer);
} else if (IS_ACCEL(channel) && has_accel) {
} else if (IS_ACCEL(chan_spec.chan_type) && has_accel) {
/* Decode accel */
struct sensor_three_axis_data *data =
(struct sensor_three_axis_data *)data_out;
@ -422,7 +421,7 @@ static int icm42688_fifo_decode(const uint8_t *buffer, enum sensor_channel chann
buffer = frame_end;
continue;
}
} else if (IS_GYRO(channel) && has_gyro) {
} else if (IS_GYRO(chan_spec.chan_type) && has_gyro) {
/* Decode gyro */
struct sensor_three_axis_data *data =
(struct sensor_three_axis_data *)data_out;
@ -451,9 +450,8 @@ static int icm42688_fifo_decode(const uint8_t *buffer, enum sensor_channel chann
return count;
}
static int icm42688_one_shot_decode(const uint8_t *buffer, enum sensor_channel channel,
size_t channel_idx, uint32_t *fit, uint16_t max_count,
void *data_out)
static int icm42688_one_shot_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec,
uint32_t *fit, uint16_t max_count, void *data_out)
{
const struct icm42688_encoded_data *edata = (const struct icm42688_encoded_data *)buffer;
const struct icm42688_decoder_header *header = &edata->header;
@ -467,11 +465,11 @@ static int icm42688_one_shot_decode(const uint8_t *buffer, enum sensor_channel c
if (*fit != 0) {
return 0;
}
if (max_count == 0 || channel_idx != 0) {
if (max_count == 0 || chan_spec.chan_idx != 0) {
return -EINVAL;
}
switch (channel) {
switch (chan_spec.chan_type) {
case SENSOR_CHAN_ACCEL_X:
case SENSOR_CHAN_ACCEL_Y:
case SENSOR_CHAN_ACCEL_Z:
@ -570,31 +568,31 @@ static int icm42688_one_shot_decode(const uint8_t *buffer, enum sensor_channel c
}
}
static int icm42688_decoder_decode(const uint8_t *buffer, enum sensor_channel channel,
size_t channel_idx, uint32_t *fit, uint16_t max_count,
void *data_out)
static int icm42688_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec,
uint32_t *fit, uint16_t max_count, void *data_out)
{
const struct icm42688_decoder_header *header =
(const struct icm42688_decoder_header *)buffer;
if (header->is_fifo) {
return icm42688_fifo_decode(buffer, channel, channel_idx, fit, max_count, data_out);
return icm42688_fifo_decode(buffer, chan_spec, fit, max_count, data_out);
}
return icm42688_one_shot_decode(buffer, channel, channel_idx, fit, max_count, data_out);
return icm42688_one_shot_decode(buffer, chan_spec, fit, max_count, data_out);
}
static int icm42688_decoder_get_frame_count(const uint8_t *buffer, enum sensor_channel channel,
size_t channel_idx, uint16_t *frame_count)
static int icm42688_decoder_get_frame_count(const uint8_t *buffer,
struct sensor_chan_spec chan_spec,
uint16_t *frame_count)
{
const struct icm42688_fifo_data *data = (const struct icm42688_fifo_data *)buffer;
const struct icm42688_decoder_header *header = &data->header;
if (channel_idx != 0) {
if (chan_spec.chan_idx != 0) {
return -ENOTSUP;
}
if (!header->is_fifo) {
switch (channel) {
switch (chan_spec.chan_type) {
case SENSOR_CHAN_ACCEL_X:
case SENSOR_CHAN_ACCEL_Y:
case SENSOR_CHAN_ACCEL_Z:
@ -643,10 +641,10 @@ static int icm42688_decoder_get_frame_count(const uint8_t *buffer, enum sensor_c
return 0;
}
static int icm42688_decoder_get_size_info(enum sensor_channel channel, size_t *base_size,
static int icm42688_decoder_get_size_info(struct sensor_chan_spec chan_spec, size_t *base_size,
size_t *frame_size)
{
switch (channel) {
switch (chan_spec.chan_type) {
case SENSOR_CHAN_ACCEL_X:
case SENSOR_CHAN_ACCEL_Y:
case SENSOR_CHAN_ACCEL_Z:

View file

@ -36,7 +36,7 @@ struct icm42688_encoded_data {
int16_t readings[7];
};
int icm42688_encode(const struct device *dev, const enum sensor_channel *const channels,
int icm42688_encode(const struct device *dev, const struct sensor_chan_spec *const channels,
const size_t num_channels, uint8_t *buf);
int icm42688_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder);

View file

@ -295,15 +295,15 @@ static void icm42688_emul_get_gyro_ranges(const struct emul *target, q31_t *lowe
*lower = -*upper;
}
static int icm42688_emul_backend_get_sample_range(const struct emul *target, enum sensor_channel ch,
q31_t *lower, q31_t *upper, q31_t *epsilon,
int8_t *shift)
static int icm42688_emul_backend_get_sample_range(const struct emul *target,
struct sensor_chan_spec ch, q31_t *lower,
q31_t *upper, q31_t *epsilon, int8_t *shift)
{
if (!lower || !upper || !epsilon || !shift) {
return -EINVAL;
}
switch (ch) {
switch (ch.chan_type) {
case SENSOR_CHAN_DIE_TEMP:
/* degrees C = ([16-bit signed temp_data register] / 132.48) + 25 */
*shift = 9;
@ -328,7 +328,7 @@ static int icm42688_emul_backend_get_sample_range(const struct emul *target, enu
return 0;
}
static int icm42688_emul_backend_set_channel(const struct emul *target, enum sensor_channel ch,
static int icm42688_emul_backend_set_channel(const struct emul *target, struct sensor_chan_spec ch,
const q31_t *value, int8_t shift)
{
if (!target || !target->data) {
@ -343,7 +343,7 @@ static int icm42688_emul_backend_set_channel(const struct emul *target, enum sen
int64_t value_unshifted =
shift < 0 ? ((int64_t)*value >> -shift) : ((int64_t)*value << shift);
switch (ch) {
switch (ch.chan_type) {
case SENSOR_CHAN_DIE_TEMP:
reg_addr = REG_TEMP_DATA1;
reg_val = ((value_unshifted - (25 * Q31_SCALE)) * 13248) / (100 * Q31_SCALE);
@ -351,7 +351,7 @@ static int icm42688_emul_backend_set_channel(const struct emul *target, enum sen
case SENSOR_CHAN_ACCEL_X:
case SENSOR_CHAN_ACCEL_Y:
case SENSOR_CHAN_ACCEL_Z:
switch (ch) {
switch (ch.chan_type) {
case SENSOR_CHAN_ACCEL_X:
reg_addr = REG_ACCEL_DATA_X1;
break;
@ -370,7 +370,7 @@ static int icm42688_emul_backend_set_channel(const struct emul *target, enum sen
case SENSOR_CHAN_GYRO_X:
case SENSOR_CHAN_GYRO_Y:
case SENSOR_CHAN_GYRO_Z:
switch (ch) {
switch (ch.chan_type) {
case SENSOR_CHAN_GYRO_X:
reg_addr = REG_GYRO_DATA_X1;
break;

View file

@ -46,7 +46,7 @@ static int icm42688_rtio_sample_fetch(const struct device *dev, int16_t readings
static int icm42688_submit_one_shot(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe)
{
const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data;
const enum sensor_channel *const channels = cfg->channels;
const struct sensor_chan_spec *const channels = cfg->channels;
const size_t num_channels = cfg->count;
uint32_t min_buf_len = sizeof(struct icm42688_encoded_data);
int rc;

View file

@ -27,16 +27,16 @@
*/
__subsystem struct emul_sensor_driver_api {
/** Sets a given fractional value for a given sensor channel. */
int (*set_channel)(const struct emul *target, enum sensor_channel ch, const q31_t *value,
int8_t shift);
int (*set_channel)(const struct emul *target, struct sensor_chan_spec ch,
const q31_t *value, int8_t shift);
/** Retrieve a range of sensor values to use with test. */
int (*get_sample_range)(const struct emul *target, enum sensor_channel ch, q31_t *lower,
int (*get_sample_range)(const struct emul *target, struct sensor_chan_spec ch, q31_t *lower,
q31_t *upper, q31_t *epsilon, int8_t *shift);
/** Set the attribute value(s) of a given chanel. */
int (*set_attribute)(const struct emul *target, enum sensor_channel ch,
int (*set_attribute)(const struct emul *target, struct sensor_chan_spec ch,
enum sensor_attribute attribute, const void *value);
/** Get metadata about an attribute. */
int (*get_attribute_metadata)(const struct emul *target, enum sensor_channel ch,
int (*get_attribute_metadata)(const struct emul *target, struct sensor_chan_spec ch,
enum sensor_attribute attribute, q31_t *min, q31_t *max,
q31_t *increment, int8_t *shift);
};
@ -68,8 +68,9 @@ static inline bool emul_sensor_backend_is_supported(const struct emul *target)
* @return -ENOTSUP if no backend API or if channel not supported by emul
* @return -ERANGE if provided value is not in the sensor's supported range
*/
static inline int emul_sensor_backend_set_channel(const struct emul *target, enum sensor_channel ch,
const q31_t *value, int8_t shift)
static inline int emul_sensor_backend_set_channel(const struct emul *target,
struct sensor_chan_spec ch, const q31_t *value,
int8_t shift)
{
if (!target || !target->backend_api) {
return -ENOTSUP;
@ -101,7 +102,7 @@ static inline int emul_sensor_backend_set_channel(const struct emul *target, enu
*
*/
static inline int emul_sensor_backend_get_sample_range(const struct emul *target,
enum sensor_channel ch, q31_t *lower,
struct sensor_chan_spec ch, q31_t *lower,
q31_t *upper, q31_t *epsilon, int8_t *shift)
{
if (!target || !target->backend_api) {
@ -127,7 +128,7 @@ static inline int emul_sensor_backend_get_sample_range(const struct emul *target
* @return < 0 on error
*/
static inline int emul_sensor_backend_set_attribute(const struct emul *target,
enum sensor_channel ch,
struct sensor_chan_spec ch,
enum sensor_attribute attribute,
const void *value)
{
@ -161,7 +162,7 @@ static inline int emul_sensor_backend_set_attribute(const struct emul *target,
* @return < 0 on error
*/
static inline int emul_sensor_backend_get_attribute_metadata(const struct emul *target,
enum sensor_channel ch,
struct sensor_chan_spec ch,
enum sensor_attribute attribute,
q31_t *min, q31_t *max,
q31_t *increment, int8_t *shift)

View file

@ -418,6 +418,40 @@ typedef int (*sensor_channel_get_t)(const struct device *dev,
enum sensor_channel chan,
struct sensor_value *val);
/**
* @brief Sensor Channel Specification
*
* A sensor channel specification is a unique identifier per sensor device describing
* a measurement channel.
*
* @note Typically passed by value as the size of a sensor_chan_spec is a single word.
*/
struct sensor_chan_spec {
uint16_t chan_type; /**< A sensor channel type */
uint16_t chan_idx; /**< A sensor channel index */
};
/** @cond INTERNAL_HIDDEN */
/* Ensure sensor_chan_spec is sensibly sized to pass by value */
BUILD_ASSERT(sizeof(struct sensor_chan_spec) <= sizeof(uintptr_t),
"sensor_chan_spec size should be equal or less than the size of a machine word");
/** @endcond */
/**
* @brief Check if channel specs are equivalent
*
* @param chan_spec0 First chan spec
* @param chan_spec1 Second chan spec
* @retval true If equivalent
* @retval false If not equivalent
*/
static inline bool sensor_chan_spec_eq(struct sensor_chan_spec chan_spec0,
struct sensor_chan_spec chan_spec1)
{
return chan_spec0.chan_type == chan_spec1.chan_type &&
chan_spec0.chan_idx == chan_spec1.chan_idx;
}
/**
* @brief Decodes a single raw data buffer
*
@ -430,13 +464,12 @@ struct sensor_decoder_api {
*
* @param[in] buffer The buffer provided on the @ref rtio context.
* @param[in] channel The channel to get the count for
* @param[in] channel_idx The index of the channel
* @param[out] frame_count The number of frames on the buffer (at least 1)
* @return 0 on success
* @return -ENOTSUP if the channel/channel_idx aren't found
*/
int (*get_frame_count)(const uint8_t *buffer, enum sensor_channel channel,
size_t channel_idx, uint16_t *frame_count);
int (*get_frame_count)(const uint8_t *buffer, struct sensor_chan_spec channel,
uint16_t *frame_count);
/**
* @brief Get the size required to decode a given channel
@ -450,7 +483,8 @@ struct sensor_decoder_api {
* @return 0 on success
* @return -ENOTSUP if the channel is not supported
*/
int (*get_size_info)(enum sensor_channel channel, size_t *base_size, size_t *frame_size);
int (*get_size_info)(struct sensor_chan_spec channel, size_t *base_size,
size_t *frame_size);
/**
* @brief Decode up to @p max_count samples from the buffer
@ -470,7 +504,6 @@ struct sensor_decoder_api {
*
* @param[in] buffer The buffer provided on the @ref rtio context
* @param[in] channel The channel to decode
* @param[in] channel_idx The index of the channel
* @param[in,out] fit The current frame iterator
* @param[in] max_count The maximum number of channels to decode.
* @param[out] data_out The decoded data
@ -478,8 +511,8 @@ struct sensor_decoder_api {
* @return >0 the number of decoded frames
* @return <0 on error
*/
int (*decode)(const uint8_t *buffer, enum sensor_channel channel, size_t channel_idx,
uint32_t *fit, uint16_t max_count, void *data_out);
int (*decode)(const uint8_t *buffer, struct sensor_chan_spec channel, uint32_t *fit,
uint16_t max_count, void *data_out);
/**
* @brief Check if the given trigger type is present
@ -518,20 +551,18 @@ struct sensor_decoder_api {
struct sensor_decode_context {
const struct sensor_decoder_api *decoder;
const uint8_t *buffer;
enum sensor_channel channel;
size_t channel_idx;
struct sensor_chan_spec channel;
uint32_t fit;
};
/**
* @brief Initialize a sensor_decode_context
*/
#define SENSOR_DECODE_CONTEXT_INIT(decoder_, buffer_, channel_, channel_index_) \
#define SENSOR_DECODE_CONTEXT_INIT(decoder_, buffer_, channel_type_, channel_index_) \
{ \
.decoder = (decoder_), \
.buffer = (buffer_), \
.channel = (channel_), \
.channel_idx = (channel_index_), \
.channel = {.chan_type = (channel_type_), .chan_idx = (channel_index_)}, \
.fit = 0, \
}
@ -545,11 +576,10 @@ struct sensor_decode_context {
*/
static inline int sensor_decode(struct sensor_decode_context *ctx, void *out, uint16_t max_count)
{
return ctx->decoder->decode(ctx->buffer, ctx->channel, ctx->channel_idx, &ctx->fit,
max_count, out);
return ctx->decoder->decode(ctx->buffer, ctx->channel, &ctx->fit, max_count, out);
}
int sensor_natively_supported_channel_size_info(enum sensor_channel channel, size_t *base_size,
int sensor_natively_supported_channel_size_info(struct sensor_chan_spec channel, size_t *base_size,
size_t *frame_size);
/**
@ -582,6 +612,7 @@ struct sensor_stream_trigger {
{ \
.trigger = (_trigger), .opt = (_opt), \
}
/*
* Internal data structure used to store information about the IODevice for async reading and
* streaming sensor data.
@ -590,7 +621,7 @@ struct sensor_read_config {
const struct device *sensor;
const bool is_streaming;
union {
enum sensor_channel *const channels;
struct sensor_chan_spec *const channels;
struct sensor_stream_trigger *const triggers;
};
size_t count;
@ -604,7 +635,8 @@ struct sensor_read_config {
*
* @code(.c)
* SENSOR_DT_READ_IODEV(icm42688_accelgyro, DT_NODELABEL(icm42688),
* SENSOR_CHAN_ACCEL_XYZ, SENSOR_CHAN_GYRO_XYZ);
* { SENSOR_CHAN_ACCEL_XYZ, 0 },
* { SENSOR_CHAN_GYRO_XYZ, 0 });
*
* int main(void) {
* sensor_read(&icm42688_accelgyro, &rtio);
@ -612,7 +644,7 @@ struct sensor_read_config {
* @endcode
*/
#define SENSOR_DT_READ_IODEV(name, dt_node, ...) \
static enum sensor_channel _CONCAT(__channel_array_, name)[] = {__VA_ARGS__}; \
static struct sensor_chan_spec _CONCAT(__channel_array_, name)[] = {__VA_ARGS__}; \
static struct sensor_read_config _CONCAT(__sensor_read_config_, name) = { \
.sensor = DEVICE_DT_GET(dt_node), \
.is_streaming = false, \
@ -886,10 +918,10 @@ struct __attribute__((__packed__)) sensor_data_generic_header {
int8_t shift;
/* This padding is needed to make sure that the 'channels' field is aligned */
int8_t _padding[sizeof(enum sensor_channel) - 1];
int8_t _padding[sizeof(struct sensor_chan_spec) - 1];
/* Channels present in the frame */
enum sensor_channel channels[0];
struct sensor_chan_spec channels[0];
};
/**
@ -949,12 +981,12 @@ static inline int z_impl_sensor_get_decoder(const struct device *dev,
* @return < 0 on error
*/
__syscall int sensor_reconfigure_read_iodev(struct rtio_iodev *iodev, const struct device *sensor,
const enum sensor_channel *channels,
const struct sensor_chan_spec *channels,
size_t num_channels);
static inline int z_impl_sensor_reconfigure_read_iodev(struct rtio_iodev *iodev,
const struct device *sensor,
const enum sensor_channel *channels,
const struct sensor_chan_spec *channels,
size_t num_channels)
{
struct sensor_read_config *cfg = (struct sensor_read_config *)iodev->data;
@ -964,7 +996,7 @@ static inline int z_impl_sensor_reconfigure_read_iodev(struct rtio_iodev *iodev,
}
cfg->sensor = sensor;
memcpy(cfg->channels, channels, num_channels * sizeof(enum sensor_channel));
memcpy(cfg->channels, channels, num_channels * sizeof(struct sensor_chan_spec));
cfg->count = num_channels;
return 0;
}

View file

@ -30,7 +30,7 @@ union sensor_data_union {
* Set up an RTIO context that can be shared for all sensors
*/
static enum sensor_channel iodev_all_channels[SENSOR_CHAN_ALL];
static struct sensor_chan_spec iodev_all_channels[SENSOR_CHAN_ALL];
static struct sensor_read_config iodev_read_config = {
.channels = iodev_all_channels,
.max = SENSOR_CHAN_ALL,
@ -110,8 +110,9 @@ static void run_generic_test(const struct device *dev)
q31_t lower, upper;
int8_t shift;
struct sensor_chan_spec ch_spec = {.chan_type = ch, .chan_idx = 0};
if (emul_sensor_backend_get_sample_range(emul, ch, &lower, &upper,
if (emul_sensor_backend_get_sample_range(emul, ch_spec, &lower, &upper,
&channel_table[ch].epsilon, &shift) == 0) {
/* This channel is supported */
channel_table[ch].supported = true;
@ -120,7 +121,7 @@ static void run_generic_test(const struct device *dev)
channel_table[ch].epsilon, shift);
/* Add to the list of channels to read */
iodev_all_channels[iodev_read_config.count++] = ch;
iodev_all_channels[iodev_read_config.count++].chan_type = ch;
/* Generate a set of CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS test
* values.
@ -155,16 +156,18 @@ static void run_generic_test(const struct device *dev)
/* Set this iteration's expected values in emul for every supported channel */
for (size_t i = 0; i < iodev_read_config.count; i++) {
enum sensor_channel ch = iodev_all_channels[i];
struct sensor_chan_spec ch_spec = iodev_all_channels[i];
rv = emul_sensor_backend_set_channel(
emul, ch, &channel_table[ch].expected_values[iteration],
channel_table[ch].expected_value_shift);
zassert_ok(
rv,
"Cannot set value 0x%08x on channel %d (error %d, iteration %d/%d)",
channel_table[i].expected_values[iteration], ch, rv, iteration + 1,
CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS);
emul, ch_spec,
&channel_table[ch_spec.chan_type].expected_values[iteration],
channel_table[ch_spec.chan_type].expected_value_shift);
zassert_ok(rv,
"Cannot set value 0x%08x on channel (type: %d, index: %d) "
"(error %d, iteration %d/%d)",
channel_table[i].expected_values[iteration], ch_spec.chan_type,
ch_spec.chan_idx, rv, iteration + 1,
CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS);
}
/* Perform the actual sensor read */

View file

@ -33,7 +33,9 @@ static void sensor_bmi160_setup_emulator(const struct device *dev, const struct
zassert_ok(sensor_attr_set(dev, SENSOR_CHAN_GYRO_XYZ, SENSOR_ATTR_FULL_SCALE, &scale));
for (size_t i = 0; i < ARRAY_SIZE(values); ++i) {
zassert_ok(emul_sensor_backend_set_channel(emulator, values[i].channel,
struct sensor_chan_spec chan_spec = {.chan_type = values[i].channel, .chan_idx = 0};
zassert_ok(emul_sensor_backend_set_channel(emulator, chan_spec,
&values[i].value, 3));
}
}