Skip to content

Commit

Permalink
sensors: Add channel specifier
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
teburd committed Apr 10, 2024
1 parent a200dd8 commit 01c66ec
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 131 deletions.
18 changes: 8 additions & 10 deletions drivers/sensor/asahi_kasei/akm09918c/akm09918c_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,21 @@

#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,

Check warning on line 8 in drivers/sensor/asahi_kasei/akm09918c/akm09918c_decoder.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LONG_LINE

drivers/sensor/asahi_kasei/akm09918c/akm09918c_decoder.c:8 line length of 102 exceeds 100 columns
uint16_t *frame_count)

Check failure on line 9 in drivers/sensor/asahi_kasei/akm09918c/akm09918c_decoder.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CODE_INDENT

drivers/sensor/asahi_kasei/akm09918c/akm09918c_decoder.c:9 code indent should use tabs where possible

Check warning on line 9 in drivers/sensor/asahi_kasei/akm09918c/akm09918c_decoder.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

drivers/sensor/asahi_kasei/akm09918c/akm09918c_decoder.c:9 please, no spaces at the start of a line
{
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:
Expand Down Expand Up @@ -48,17 +47,16 @@ 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)

Check failure on line 51 in drivers/sensor/asahi_kasei/akm09918c/akm09918c_decoder.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CODE_INDENT

drivers/sensor/asahi_kasei/akm09918c/akm09918c_decoder.c:51 code indent should use tabs where possible

Check warning on line 51 in drivers/sensor/asahi_kasei/akm09918c/akm09918c_decoder.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

drivers/sensor/asahi_kasei/akm09918c/akm09918c_decoder.c:51 please, no spaces at the start of a line
{
const struct akm09918c_encoded_data *edata = (const struct akm09918c_encoded_data *)buffer;

if (*fit != 0) {
return 0;
}

switch (channel) {
switch (chan_spec.chan_type) {
case SENSOR_CHAN_MAGN_X:
case SENSOR_CHAN_MAGN_Y:
case SENSOR_CHAN_MAGN_Z:
Expand Down
8 changes: 6 additions & 2 deletions drivers/sensor/bosch/bma4xx/bma4xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand Down
103 changes: 51 additions & 52 deletions drivers/sensor/default_rtio_sensor.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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));

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;
}
}
Expand All @@ -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());
Expand Down Expand Up @@ -148,24 +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 %d, skipping", channels[i]);
LOG_DBG("Failed to get channel (type: %d, index %d), skipping",
channels[i].chan_type, channels[i].chan_idx);
continue;
}

Expand Down Expand Up @@ -277,45 +288,40 @@ 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,
uint16_t *frame_count)
static int get_frame_count(const uint8_t *buffer, struct sensor_chan_spec channel,
uint16_t *frame_count)

Check failure on line 292 in drivers/sensor/default_rtio_sensor.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CODE_INDENT

drivers/sensor/default_rtio_sensor.c:292 code indent should use tabs where possible

Check warning on line 292 in drivers/sensor/default_rtio_sensor.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

drivers/sensor/default_rtio_sensor.c:292 please, no spaces at the start of a line
{
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:
Expand Down Expand Up @@ -391,19 +397,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;
}
Expand All @@ -419,24 +419,23 @@ 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]);

Check warning on line 422 in drivers/sensor/default_rtio_sensor.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LONG_LINE

drivers/sensor/default_rtio_sensor.c:422 line length of 120 exceeds 100 columns
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]);

Check warning on line 426 in drivers/sensor/default_rtio_sensor.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LONG_LINE

drivers/sensor/default_rtio_sensor.c:426 line length of 120 exceeds 100 columns
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]);

Check warning on line 430 in drivers/sensor/default_rtio_sensor.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LONG_LINE

drivers/sensor/default_rtio_sensor.c:430 line length of 120 exceeds 100 columns
if (rc < 0) {
return rc;
}
return 1;
}

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;

Expand All @@ -445,7 +444,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;
}
Expand All @@ -469,7 +468,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 =
Expand All @@ -484,33 +483,33 @@ 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);

Check warning on line 492 in drivers/sensor/default_rtio_sensor.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LONG_LINE

drivers/sensor/default_rtio_sensor.c:492 line length of 104 exceeds 100 columns
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);

Check warning on line 499 in drivers/sensor/default_rtio_sensor.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LONG_LINE

drivers/sensor/default_rtio_sensor.c:499 line length of 102 exceeds 100 columns
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);

Check warning on line 506 in drivers/sensor/default_rtio_sensor.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LONG_LINE

drivers/sensor/default_rtio_sensor.c:506 line length of 102 exceeds 100 columns
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:
Expand Down Expand Up @@ -552,7 +551,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;
Expand Down
20 changes: 10 additions & 10 deletions drivers/sensor/sensor_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -346,7 +346,9 @@ void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t buf_len
continue;
}

rc = decoder->get_size_info(channel, &base_size, &frame_size);
struct sensor_chan_spec chan_spec = { channel, 0 };

rc = decoder->get_size_info(chan_spec, &base_size, &frame_size);
if (rc != 0) {
/* Channel not supported, skipping */
continue;
Expand All @@ -360,12 +362,10 @@ void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t buf_len
continue;
}

while (decoder->get_frame_count(buf, channel, channel_idx, &frame_count) == 0) {
while (decoder->get_frame_count(buf, chan_spec, &frame_count) == 0) {
fit = 0;
memset(&accumulator_buffer, 0, sizeof(accumulator_buffer));
while (decoder->decode(buf, channel, channel_idx, &fit, 1, decoded_buffer) >
0) {

while (decoder->decode(buf, chan_spec, &fit, 1, decoded_buffer) > 0) {
switch (channel) {
case SENSOR_CHAN_ACCEL_XYZ:
case SENSOR_CHAN_GYRO_XYZ:
Expand Down Expand Up @@ -521,12 +521,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 */
Expand All @@ -538,7 +538,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};
}
}

Expand Down Expand Up @@ -570,7 +571,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;
Expand Down
Loading

0 comments on commit 01c66ec

Please sign in to comment.