Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add generic fifo stream sample #82342

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 58 additions & 21 deletions drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,42 +145,29 @@ static int lsm6dsv16x_decoder_get_frame_count(const uint8_t *buffer,
*frame_count = 1;
return 0;
default:
*frame_count = 0;
return -ENOTSUP;
}

return 0;
}

#ifdef CONFIG_LSM6DSV16X_STREAM
*frame_count = data->fifo_count;
#endif
return 0;
}

#ifdef CONFIG_LSM6DSV16X_STREAM
static int lsm6dsv16x_decode_fifo(const uint8_t *buffer, struct sensor_chan_spec chan_spec,
uint32_t *fit, uint16_t max_count, void *data_out)
{
const struct lsm6dsv16x_fifo_data *edata = (const struct lsm6dsv16x_fifo_data *)buffer;
const uint8_t *buffer_end, *tmp_buffer;
const struct lsm6dsv16x_decoder_header *header = &edata->header;
int count = 0;
const uint8_t *buffer_end;
uint8_t fifo_tag;
uint16_t xl_count = 0, gy_count = 0;
uint8_t tot_accel_fifo_words = 0, tot_gyro_fifo_words = 0;

#if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP)
uint8_t tot_temp_fifo_words = 0;
uint16_t temp_count = 0;
#endif

buffer += sizeof(struct lsm6dsv16x_fifo_data);
buffer_end = buffer + LSM6DSV16X_FIFO_SIZE(edata->fifo_count);

/* count total FIFO word for each tag */
tmp_buffer = buffer;
while (tmp_buffer < buffer_end) {
fifo_tag = (tmp_buffer[0] >> 3);
while (buffer < buffer_end) {
fifo_tag = (buffer[0] >> 3);

switch (fifo_tag) {
case LSM6DSV16X_XL_NC_TAG:
Expand All @@ -198,8 +185,58 @@ static int lsm6dsv16x_decode_fifo(const uint8_t *buffer, struct sensor_chan_spec
break;
}

tmp_buffer += LSM6DSV16X_FIFO_ITEM_LEN;
buffer += LSM6DSV16X_FIFO_ITEM_LEN;
}

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:
*frame_count = tot_accel_fifo_words;
break;

case SENSOR_CHAN_GYRO_X:
case SENSOR_CHAN_GYRO_Y:
case SENSOR_CHAN_GYRO_Z:
case SENSOR_CHAN_GYRO_XYZ:
*frame_count = tot_gyro_fifo_words;
break;

#if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP)
case SENSOR_CHAN_DIE_TEMP:
*frame_count = tot_temp_fifo_words;
break;
#endif
default:
*frame_count = 0;
break;
}
#endif
return 0;
}

#ifdef CONFIG_LSM6DSV16X_STREAM
static int lsm6dsv16x_decode_fifo(const uint8_t *buffer, struct sensor_chan_spec chan_spec,
uint32_t *fit, uint16_t max_count, void *data_out)
{
const struct lsm6dsv16x_fifo_data *edata = (const struct lsm6dsv16x_fifo_data *)buffer;
const uint8_t *buffer_end;
const struct lsm6dsv16x_decoder_header *header = &edata->header;
int count = 0;
uint8_t fifo_tag;
uint16_t xl_count = 0, gy_count = 0;
uint16_t tot_chan_fifo_words = 0;

#if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP)
uint16_t temp_count = 0;
#endif

/* count total FIFO word for each tag */
lsm6dsv16x_decoder_get_frame_count(buffer, chan_spec, &tot_chan_fifo_words);

buffer += sizeof(struct lsm6dsv16x_fifo_data);
buffer_end = buffer + LSM6DSV16X_FIFO_SIZE(edata->fifo_count);

/*
* Timestamp in header is set when FIFO threshold is reached, so
Expand All @@ -209,16 +246,16 @@ static int lsm6dsv16x_decode_fifo(const uint8_t *buffer, struct sensor_chan_spec
if (SENSOR_CHANNEL_IS_ACCEL(chan_spec.chan_type)) {
((struct sensor_data_header *)data_out)->base_timestamp_ns =
edata->header.timestamp -
(tot_accel_fifo_words - 1) * accel_period_ns[edata->accel_batch_odr];
(tot_chan_fifo_words - 1) * accel_period_ns[edata->accel_batch_odr];
} else if (SENSOR_CHANNEL_IS_GYRO(chan_spec.chan_type)) {
((struct sensor_data_header *)data_out)->base_timestamp_ns =
edata->header.timestamp -
(tot_gyro_fifo_words - 1) * gyro_period_ns[edata->gyro_batch_odr];
(tot_chan_fifo_words - 1) * gyro_period_ns[edata->gyro_batch_odr];
#if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP)
} else if (chan_spec.chan_type == SENSOR_CHAN_DIE_TEMP) {
((struct sensor_data_header *)data_out)->base_timestamp_ns =
edata->header.timestamp -
(tot_temp_fifo_words - 1) * temp_period_ns[edata->temp_batch_odr];
(tot_chan_fifo_words - 1) * temp_period_ns[edata->temp_batch_odr];
#endif
}

Expand Down
10 changes: 10 additions & 0 deletions samples/sensor/stream_fifo/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copyright (c) 2024 STMicroelectronics
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(stream_fifo)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})
148 changes: 148 additions & 0 deletions samples/sensor/stream_fifo/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
.. zephyr:code-sample:: stream_fifo
:name: Generic device FIFO streaming
:relevant-api: sensor_interface

Get accelerometer/gyroscope/temperature FIFO data frames from a sensor using
SENSOR_TRIG_FIFO_WATERMARK as a trigger.

Overview
********

This sample application demonstrates how to stream FIFO data using the `RTIO framework`_.

The streaming is started using the sensor_stream() API and it is self-sustained by the
SENSOR_TRIG_FIFO_WATERMARK trigger.

Currently the sample gets/prints data for the following sensor channels:

- SENSOR_CHAN_ACCEL_XYZ
- SENSOR_CHAN_GYRO_XYZ
- SENSOR_CHAN_DIE_TEMP

Building and Running
********************

This sample supports up to 10 FIFO streaming devices. Each device needs
to be aliased as ``streamN`` where ``N`` goes from ``0`` to ``9``. For example:

.. code-block:: devicetree

/ {
aliases {
stream0 = &lsm6dsv16x_6b_x_nucleo_iks4a1;
};
};

Example devicetree overlays and configurations are already available for nucleo_f401re and
nucleo_h503rb in the boards directory:

- :zephyr_file:`samples/sensor/stream_fifo/boards/nucleo_f401re.overlay`

DT overlay file for the nucleo_f401re board.

- :zephyr_file:`samples/sensor/stream_fifo/boards/nucleo_f401re.conf`

Configuration file for the nucleo_f401re board.

- :zephyr_file:`samples/sensor/stream_fifo/boards/nucleo_h503rb.overlay`

DT overlay file for the nucleo_h503rb board.

- :zephyr_file:`samples/sensor/stream_fifo/boards/nucleo_h503rb.conf`

Configuration file for the nucleo_h503rb board.

For example, build and run sample for nucleo_h503rb with:

.. zephyr-app-commands::
:zephyr-app: samples/sensor/stream_fifo
:board: nucleo_h503rb
:goals: build flash
:compact:

Sample Output
=============

The following example output is for a lsm6dsv16x IMU device with accelerometer, gyroscope
and temperature sensors. The FIFO watermark is set to 64. The board used is a nucleo_h503rb
equipped with a `x-nucleo-iks4a1`_ shield.

.. code-block:: console

FIFO count - 65
XL data for lsm6dsv16x@6b 708054166675ns (0.267959, -0.162689, 9.933659)
XL data for lsm6dsv16x@6b 708087500008ns (0.258389, -0.162689, 9.919304)
XL data for lsm6dsv16x@6b 708120833341ns (0.253604, -0.167474, 9.909734)
XL data for lsm6dsv16x@6b 708154166674ns (0.258389, -0.153119, 9.933659)
XL data for lsm6dsv16x@6b 708187500007ns (0.253604, -0.157904, 9.919304)
XL data for lsm6dsv16x@6b 708220833340ns (0.258389, -0.162689, 9.943229)
XL data for lsm6dsv16x@6b 708254166673ns (0.258389, -0.157904, 9.904949)
XL data for lsm6dsv16x@6b 708287500006ns (0.253604, -0.162689, 9.952799)
GY data for lsm6dsv16x@6b 708054166675ns (0.000609, 0.000000, 0.004574)
GY data for lsm6dsv16x@6b 708087500008ns (-0.000304, 0.000304, 0.003964)
GY data for lsm6dsv16x@6b 708120833341ns (-0.000609, 0.000304, 0.004269)
GY data for lsm6dsv16x@6b 708154166674ns (0.000304, -0.000304, 0.004879)
GY data for lsm6dsv16x@6b 708187500007ns (0.001219, -0.001524, 0.004269)
GY data for lsm6dsv16x@6b 708220833340ns (-0.000914, -0.000609, 0.004879)
GY data for lsm6dsv16x@6b 708254166673ns (0.000000, -0.000304, 0.004269)
GY data for lsm6dsv16x@6b 708287500006ns (0.000609, 0.000000, 0.004574)
TP data for lsm6dsv16x@6b 708087500008ns 24.390625 °C
TP data for lsm6dsv16x@6b 708154166674ns 24.421875 °C
TP data for lsm6dsv16x@6b 708220833340ns 24.414062 °C
TP data for lsm6dsv16x@6b 708287500006ns 24.441406 °C
XL data for lsm6dsv16x@6b 708320833339ns (0.258389, -0.157904, 9.957584)
XL data for lsm6dsv16x@6b 708354166672ns (0.258389, -0.177044, 9.900164)
XL data for lsm6dsv16x@6b 708387500005ns (0.019139, 0.277529, 9.426449)
XL data for lsm6dsv16x@6b 708420833338ns (-0.052634, -0.244034, 9.866669)
XL data for lsm6dsv16x@6b 708454166671ns (0.263174, -0.172259, 9.861884)
XL data for lsm6dsv16x@6b 708487500004ns (0.277529, -0.129194, 9.890594)
XL data for lsm6dsv16x@6b 708520833337ns (0.301454, -0.138764, 9.928874)
XL data for lsm6dsv16x@6b 708554166670ns (0.258389, -0.138764, 9.971939)
GY data for lsm6dsv16x@6b 708320833339ns (0.000304, 0.000609, 0.004269)
GY data for lsm6dsv16x@6b 708354166672ns (0.001524, -0.003049, 0.004269)
GY data for lsm6dsv16x@6b 708387500005ns (-0.015554, -0.025314, 0.004879)
GY data for lsm6dsv16x@6b 708420833338ns (0.006404, 0.006099, 0.011894)
GY data for lsm6dsv16x@6b 708454166671ns (-0.004879, 0.007014, -0.001829)
GY data for lsm6dsv16x@6b 708487500004ns (0.014944, -0.023789, 0.003354)
GY data for lsm6dsv16x@6b 708520833337ns (0.008539, -0.017689, 0.006099)
GY data for lsm6dsv16x@6b 708554166670ns (0.005489, -0.004574, 0.005184)
TP data for lsm6dsv16x@6b 708354166672ns 24.339843 °C
TP data for lsm6dsv16x@6b 708420833338ns 24.375000 °C
TP data for lsm6dsv16x@6b 708487500004ns 24.421875 °C
TP data for lsm6dsv16x@6b 708554166670ns 24.398437 °C
XL data for lsm6dsv16x@6b 708587500003ns (0.272744, -0.172259, 9.861884)
XL data for lsm6dsv16x@6b 708620833336ns (0.344519, -0.267959, 10.038929)
XL data for lsm6dsv16x@6b 708654166669ns (0.339734, -0.081344, 9.967154)
XL data for lsm6dsv16x@6b 708687500002ns (0.263174, -0.124409, 9.981509)
XL data for lsm6dsv16x@6b 708720833335ns (0.296669, -0.181829, 9.948014)
XL data for lsm6dsv16x@6b 708754166668ns (0.272744, -0.114839, 9.948014)
XL data for lsm6dsv16x@6b 708787500001ns (0.296669, -0.153119, 9.995864)
XL data for lsm6dsv16x@6b 708820833334ns (0.200969, -0.248819, 9.756614)
GY data for lsm6dsv16x@6b 708587500003ns (0.004879, -0.007624, 0.005489)
GY data for lsm6dsv16x@6b 708620833336ns (-0.006709, -0.001219, 0.012504)
GY data for lsm6dsv16x@6b 708654166669ns (-0.001524, -0.004269, 0.006404)
GY data for lsm6dsv16x@6b 708687500002ns (0.000304, -0.005184, 0.007319)
GY data for lsm6dsv16x@6b 708720833335ns (0.001829, 0.000609, 0.003354)
GY data for lsm6dsv16x@6b 708754166668ns (0.005489, -0.001524, 0.004574)
GY data for lsm6dsv16x@6b 708787500001ns (0.052459, -0.010979, 0.041174)
GY data for lsm6dsv16x@6b 708820833334ns (-0.021044, -0.008234, 0.089059)
TP data for lsm6dsv16x@6b 708620833336ns 24.414062 °C
TP data for lsm6dsv16x@6b 708687500002ns 24.382812 °C
TP data for lsm6dsv16x@6b 708754166668ns 24.429687 °C
TP data for lsm6dsv16x@6b 708820833334ns 24.421875 °C
XL data for lsm6dsv16x@6b 708854166667ns (0.373229, 0.325379, 9.928874)
XL data for lsm6dsv16x@6b 708887500000ns (0.086129, 0.119624, 10.986359)
GY data for lsm6dsv16x@6b 708854166667ns (0.015249, 0.003049, 0.039954)
GY data for lsm6dsv16x@6b 708887500000ns (0.025924, 0.071674, -0.101869)
TP data for lsm6dsv16x@6b 708887500000ns 24.457031 °C

References
==========

.. target-notes::

.. _RTIO framework:
https://docs.zephyrproject.org/latest/services/rtio/index.html

.. _x-nucleo-iks4a1:
http://www.st.com/en/ecosystems/x-nucleo-iks4a1.html
6 changes: 6 additions & 0 deletions samples/sensor/stream_fifo/boards/nucleo_f401re.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright (c) 2024 STMicroelectronics
# SPDX-License-Identifier: Apache-2.0

CONFIG_I2C_RTIO=y
CONFIG_LSM6DSV16X_STREAM=y
CONFIG_LSM6DSV16X_ENABLE_TEMP=y
38 changes: 38 additions & 0 deletions samples/sensor/stream_fifo/boards/nucleo_f401re.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2024 STMicroelectronics
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/dt-bindings/sensor/lsm6dsv16x.h>


/*
* Nucleo F401RE board + shield iks4a1
*
* This devicetree overlay file will be automatically picked by the Zephyr
* build system when building the sample for the nucleo_f401re board.
*/

/ {
aliases {
stream0 = &lsm6dsv16x_6b_x_nucleo_iks4a1;
};
};

&arduino_i2c {
lsm6dsv16x_6b_x_nucleo_iks4a1: lsm6dsv16x@6b {
compatible = "st,lsm6dsv16x";
reg = <0x6b>;
accel-odr = <LSM6DSV16X_DT_ODR_AT_480Hz>;
accel-range = <LSM6DSV16X_DT_FS_16G>;
gyro-odr = <LSM6DSV16X_DT_ODR_AT_480Hz>;
gyro-range = <LSM6DSV16X_DT_FS_500DPS>;
fifo-watermark = <64>;
accel-fifo-batch-rate = <LSM6DSV16X_DT_XL_BATCHED_AT_60Hz>;
gyro-fifo-batch-rate = <LSM6DSV16X_DT_GY_BATCHED_AT_60Hz>;
temp-fifo-batch-rate = <LSM6DSV16X_DT_TEMP_BATCHED_AT_15Hz>;
int2-gpios = <&arduino_header 10 GPIO_ACTIVE_HIGH>; /* D4 (PB5) */
drdy-pin = <2>;
drdy-pulsed;
};
};
6 changes: 6 additions & 0 deletions samples/sensor/stream_fifo/boards/nucleo_h503rb.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright (c) 2024 STMicroelectronics
# SPDX-License-Identifier: Apache-2.0

CONFIG_I2C_RTIO=y
CONFIG_LSM6DSV16X_STREAM=y
CONFIG_LSM6DSV16X_ENABLE_TEMP=y
38 changes: 38 additions & 0 deletions samples/sensor/stream_fifo/boards/nucleo_h503rb.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2024 STMicroelectronics
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/dt-bindings/sensor/lsm6dsv16x.h>


/*
* Nucleo F401RE board + shield iks4a1
*
* This devicetree overlay file will be automatically picked by the Zephyr
* build system when building the sample for the nucleo_f401re board.
*/

/ {
aliases {
stream0 = &lsm6dsv16x_6b_x_nucleo_iks4a1;
};
};

&arduino_i2c {
lsm6dsv16x_6b_x_nucleo_iks4a1: lsm6dsv16x@6b {
compatible = "st,lsm6dsv16x";
reg = <0x6b>;
accel-odr = <LSM6DSV16X_DT_ODR_AT_480Hz>;
accel-range = <LSM6DSV16X_DT_FS_16G>;
gyro-odr = <LSM6DSV16X_DT_ODR_AT_480Hz>;
gyro-range = <LSM6DSV16X_DT_FS_500DPS>;
fifo-watermark = <64>;
accel-fifo-batch-rate = <LSM6DSV16X_DT_XL_BATCHED_AT_60Hz>;
gyro-fifo-batch-rate = <LSM6DSV16X_DT_GY_BATCHED_AT_60Hz>;
temp-fifo-batch-rate = <LSM6DSV16X_DT_TEMP_BATCHED_AT_15Hz>;
int2-gpios = <&arduino_header 10 GPIO_ACTIVE_HIGH>; /* D4 (PB5) */
drdy-pin = <2>;
drdy-pulsed;
};
};
7 changes: 7 additions & 0 deletions samples/sensor/stream_fifo/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright (c) 2024 STMicroelectronics
# SPDX-License-Identifier: Apache-2.0

CONFIG_STDOUT_CONSOLE=y
CONFIG_SENSOR=y
CONFIG_SENSOR_ASYNC_API=y
CONFIG_CBPRINTF_FP_SUPPORT=y
12 changes: 12 additions & 0 deletions samples/sensor/stream_fifo/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
sample:
name: Stream FIFO sample
tests:
sample.sensor.stream_fifo:
harness: console
tags: sensors
filter: dt_alias_exists("stream0")
harness_config:
type: one_line
regex:
- "^\\s*[0-9A-Za-z_,+-.]*@[0-9A-Fa-f]* \\[m\/s\\^2\\]: \
\\(\\s*-?[0-9\\.]*,\\s*-?[0-9\\.]*,\\s*-?[0-9\\.]*\\)$"
Loading
Loading