Skip to content

Commit ae53446

Browse files
committed
drivers/lis2dux12: add read_and_decode APIs support
Add RTIO async and RTIO stream functionalities that enables, among all the other things, the sensor data streaming from FIFO. RTIO stream supports following triggers: - SENSOR_TRIG_FIFO_WATERMARK - SENSOR_TRIG_FIFO_FULL - SENSOR_TRIG_DATA_READY Following FIFO parameters has to be defined in device tree to correctly stream sensor data: - fifo-watermark - accel-fifo-batch-rate Currently the driver can decode FIFO content with Accelerometer 16-bit samples. Signed-off-by: Armando Visconti <[email protected]>
1 parent e02bd58 commit ae53446

14 files changed

+1629
-7
lines changed

drivers/sensor/st/lis2dux12/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@ zephyr_library_sources(lis2dux12.c)
66
zephyr_library_sources_ifdef(CONFIG_LIS2DUX12_TRIGGER lis2dux12_trigger.c)
77
zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LIS2DUX12_ENABLED lis2dux12_api.c )
88
zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LIS2DUXS12_ENABLED lis2duxs12_api.c )
9+
zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API lis2dux12_rtio.c lis2dux12_decoder.c)
10+
zephyr_library_sources_ifdef(CONFIG_LIS2DUX12_STREAM lis2dux12_rtio_stream.c)
911

1012
zephyr_library_include_directories(../stmemsc)

drivers/sensor/st/lis2dux12/Kconfig

+10
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,21 @@ menuconfig LIS2DUX12
1515
select HAS_STMEMSC
1616
select USE_STDC_LIS2DUX12 if DT_HAS_ST_LIS2DUX12_ENABLED
1717
select USE_STDC_LIS2DUXS12 if DT_HAS_ST_LIS2DUXS12_ENABLED
18+
select RTIO_WORKQ if SENSOR_ASYNC_API
1819
help
1920
Enable driver for LIS2DUX12 accelerometer sensor driver
2021

2122
if LIS2DUX12
2223

24+
config LIS2DUX12_STREAM
25+
bool "Use hardware FIFO to stream data"
26+
select LIS2DUX12_TRIGGER
27+
default y
28+
depends on I2C_RTIO || SPI_RTIO
29+
depends on SENSOR_ASYNC_API
30+
help
31+
Use this config option to enable streaming sensor data via RTIO subsystem.
32+
2333
module = LIS2DUX12
2434
thread_priority = 10
2535
thread_stack_size = 1024

drivers/sensor/st/lis2dux12/lis2dux12.c

+52-7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <zephyr/logging/log.h>
1919

2020
#include "lis2dux12.h"
21+
#include "lis2dux12_decoder.h"
22+
#include "lis2dux12_rtio.h"
2123

2224
#if DT_HAS_COMPAT_STATUS_OKAY(st_lis2dux12)
2325
#include "lis2dux12_api.h"
@@ -230,6 +232,10 @@ static DEVICE_API(sensor, lis2dux12_driver_api) = {
230232
#endif
231233
.sample_fetch = lis2dux12_sample_fetch,
232234
.channel_get = lis2dux12_channel_get,
235+
#ifdef CONFIG_SENSOR_ASYNC_API
236+
.get_decoder = lis2dux12_get_decoder,
237+
.submit = lis2dux12_submit,
238+
#endif
233239
};
234240

235241
/*
@@ -256,16 +262,25 @@ static DEVICE_API(sensor, lis2dux12_driver_api) = {
256262
.range = DT_INST_PROP(inst, range), \
257263
.pm = DT_INST_PROP(inst, power_mode), \
258264
.odr = DT_INST_PROP(inst, odr), \
265+
IF_ENABLED(CONFIG_LIS2DUX12_STREAM, \
266+
(.fifo_wtm = DT_INST_PROP(inst, fifo_watermark), \
267+
.accel_batch = DT_INST_PROP(inst, accel_fifo_batch_rate), \
268+
.ts_batch = DT_INST_PROP(inst, timestamp_fifo_batch_rate),)) \
259269
IF_ENABLED(UTIL_OR(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \
260270
DT_INST_NODE_HAS_PROP(inst, int2_gpios)), \
261271
(LIS2DUX12_CFG_IRQ(inst))) \
262272

263-
#define LIS2DUX12_SPI_OPERATION \
264-
(SPI_WORD_SET(8) | SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA)
265-
266273
/*
267274
* Instantiation macros used when a device is on a SPI bus.
268275
*/
276+
#define LIS2DUX12_SPI_OPERATION \
277+
(SPI_WORD_SET(8) | SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA)
278+
279+
#define LIS2DUX12_SPI_RTIO_DEFINE(inst, name) \
280+
SPI_DT_IODEV_DEFINE(lis2dux12_iodev_##name##_##inst, \
281+
DT_DRV_INST(inst), LIS2DUX12_SPI_OPERATION, 0U); \
282+
RTIO_DEFINE(lis2dux12_rtio_ctx_##name##_##inst, 4, 4);
283+
269284
#define LIS2DUX12_CONFIG_SPI(inst, name) \
270285
{ \
271286
STMEMSC_CTX_SPI(&lis2dux12_config_##name##_##inst.stmemsc_cfg), \
@@ -275,9 +290,27 @@ static DEVICE_API(sensor, lis2dux12_driver_api) = {
275290
LIS2DUX12_CONFIG_COMMON(inst, name) \
276291
}
277292

293+
#define LIS2DUX12_DEFINE_SPI(inst, name) \
294+
IF_ENABLED(UTIL_AND(CONFIG_LIS2DUX12_STREAM, \
295+
CONFIG_SPI_RTIO), \
296+
(LIS2DUX12_SPI_RTIO_DEFINE(inst, name))); \
297+
static struct lis2dux12_data lis2dux12_data_##name##_##inst = { \
298+
IF_ENABLED(UTIL_AND(CONFIG_LIS2DUX12_STREAM, \
299+
CONFIG_SPI_RTIO), \
300+
(.rtio_ctx = &lis2dux12_rtio_ctx_##name##_##inst, \
301+
.iodev = &lis2dux12_iodev_##name##_##inst, \
302+
.bus_type = BUS_SPI,)) \
303+
}; \
304+
static const struct lis2dux12_config lis2dux12_config_##name##_##inst = \
305+
LIS2DUX12_CONFIG_SPI(inst, name);
306+
278307
/*
279308
* Instantiation macros used when a device is on an I2C bus.
280309
*/
310+
#define LIS2DUX12_I2C_RTIO_DEFINE(inst, name) \
311+
I2C_DT_IODEV_DEFINE(lis2dux12_iodev_##name##_##inst, DT_DRV_INST(inst)); \
312+
RTIO_DEFINE(lis2dux12_rtio_ctx_##name##_##inst, 4, 4);
313+
281314
#define LIS2DUX12_CONFIG_I2C(inst, name) \
282315
{ \
283316
STMEMSC_CTX_I2C(&lis2dux12_config_##name##_##inst.stmemsc_cfg), \
@@ -287,17 +320,29 @@ static DEVICE_API(sensor, lis2dux12_driver_api) = {
287320
LIS2DUX12_CONFIG_COMMON(inst, name) \
288321
}
289322

323+
#define LIS2DUX12_DEFINE_I2C(inst, name) \
324+
IF_ENABLED(UTIL_AND(CONFIG_LIS2DUX12_STREAM, \
325+
CONFIG_I2C_RTIO), \
326+
(LIS2DUX12_I2C_RTIO_DEFINE(inst, name))); \
327+
static struct lis2dux12_data lis2dux12_data_##name##_##inst = { \
328+
IF_ENABLED(UTIL_AND(CONFIG_LIS2DUX12_STREAM, \
329+
CONFIG_I2C_RTIO), \
330+
(.rtio_ctx = &lis2dux12_rtio_ctx_##name##_##inst, \
331+
.iodev = &lis2dux12_iodev_##name##_##inst, \
332+
.bus_type = BUS_I2C,)) \
333+
}; \
334+
static const struct lis2dux12_config lis2dux12_config_##name##_##inst = \
335+
LIS2DUX12_CONFIG_I2C(inst, name);
336+
290337
/*
291338
* Main instantiation macro. Use of COND_CODE_1() selects the right
292339
* bus-specific macro at preprocessor time.
293340
*/
294341

295342
#define LIS2DUX12_DEFINE(inst, name) \
296-
static struct lis2dux12_data lis2dux12_data_##name##_##inst; \
297-
static const struct lis2dux12_config lis2dux12_config_##name##_##inst = \
298343
COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
299-
(LIS2DUX12_CONFIG_SPI(inst, name)), \
300-
(LIS2DUX12_CONFIG_I2C(inst, name))); \
344+
(LIS2DUX12_DEFINE_SPI(inst, name)), \
345+
(LIS2DUX12_DEFINE_I2C(inst, name))); \
301346
\
302347
SENSOR_DEVICE_DT_INST_DEFINE(inst, name##_init, NULL, \
303348
&lis2dux12_data_##name##_##inst, \

drivers/sensor/st/lis2dux12/lis2dux12.h

+63
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,33 @@
3434
#include <zephyr/drivers/i2c.h>
3535
#endif
3636

37+
/* Accel sensor sensitivity grain is 61 ug/LSB */
38+
#define GAIN_UNIT (61LL)
39+
40+
#ifdef CONFIG_LIS2DUX12_STREAM
41+
struct trigger_config {
42+
uint8_t int_fifo_th : 1;
43+
uint8_t int_fifo_full : 1;
44+
uint8_t int_drdy : 1;
45+
};
46+
#endif
47+
3748
typedef int32_t (*api_lis2dux12_set_odr_raw)(const struct device *dev, uint8_t odr);
3849
typedef int32_t (*api_lis2dux12_set_range)(const struct device *dev, uint8_t range);
3950
typedef int32_t (*api_lis2dux12_sample_fetch_accel)(const struct device *dev);
4051
#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP
4152
typedef int32_t (*api_lis2dux12_sample_fetch_temp)(const struct device *dev);
4253
#endif
54+
#ifdef CONFIG_SENSOR_ASYNC_API
55+
typedef int32_t (*api_lis2dux12_rtio_read_accel)(const struct device *dev, int16_t *acc);
56+
typedef int32_t (*api_lis2dux12_rtio_read_temp)(const struct device *dev, int16_t *temp);
57+
#endif
58+
#ifdef CONFIG_LIS2DUX12_STREAM
59+
typedef void (*api_lis2dux12_stream_config_fifo)(const struct device *dev,
60+
struct trigger_config trig_cfg);
61+
typedef void (*api_lis2dux12_stream_config_drdy)(const struct device *dev,
62+
struct trigger_config trig_cfg);
63+
#endif
4364
#ifdef CONFIG_LIS2DUX12_TRIGGER
4465
typedef void (*api_lis2dux12_handle_interrupt)(const struct device *dev);
4566
typedef int32_t (*api_lis2dux12_init_interrupt)(const struct device *dev);
@@ -52,6 +73,14 @@ struct lis2dux12_chip_api {
5273
#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP
5374
api_lis2dux12_sample_fetch_temp sample_fetch_temp;
5475
#endif
76+
#ifdef CONFIG_SENSOR_ASYNC_API
77+
api_lis2dux12_rtio_read_accel rtio_read_accel;
78+
api_lis2dux12_rtio_read_temp rtio_read_temp;
79+
#endif
80+
#ifdef CONFIG_LIS2DUX12_STREAM
81+
api_lis2dux12_stream_config_fifo stream_config_fifo;
82+
api_lis2dux12_stream_config_drdy stream_config_drdy;
83+
#endif
5584
#ifdef CONFIG_LIS2DUX12_TRIGGER
5685
api_lis2dux12_handle_interrupt handle_interrupt;
5786
api_lis2dux12_init_interrupt init_interrupt;
@@ -73,6 +102,12 @@ struct lis2dux12_config {
73102
uint8_t range;
74103
uint8_t pm;
75104
uint8_t odr;
105+
#ifdef CONFIG_LIS2DUX12_STREAM
106+
uint8_t fifo_wtm;
107+
uint8_t accel_batch : 3;
108+
uint8_t ts_batch : 2;
109+
uint8_t reserved : 3;
110+
#endif
76111
#ifdef CONFIG_LIS2DUX12_TRIGGER
77112
const struct gpio_dt_spec int1_gpio;
78113
const struct gpio_dt_spec int2_gpio;
@@ -95,6 +130,21 @@ struct lis2dux12_data {
95130
float sample_temp;
96131
#endif
97132

133+
#ifdef CONFIG_LIS2DUX12_STREAM
134+
struct rtio_iodev_sqe *streaming_sqe;
135+
struct rtio *rtio_ctx;
136+
struct rtio_iodev *iodev;
137+
uint64_t timestamp;
138+
uint8_t status;
139+
uint8_t fifo_status[2];
140+
uint16_t fifo_count;
141+
struct trigger_config trig_cfg;
142+
uint8_t accel_batch_odr : 3;
143+
uint8_t ts_batch_odr : 2;
144+
uint8_t bus_type : 1; /* I2C is 0, SPI is 1 */
145+
uint8_t reserved : 2;
146+
#endif
147+
98148
#ifdef CONFIG_LIS2DUX12_TRIGGER
99149
struct gpio_dt_spec *drdy_gpio;
100150
struct gpio_callback gpio_cb;
@@ -114,6 +164,19 @@ struct lis2dux12_data {
114164
#endif /* CONFIG_LIS2DUX12_TRIGGER */
115165
};
116166

167+
#ifdef CONFIG_LIS2DUX12_STREAM
168+
#define BUS_I2C 0
169+
#define BUS_SPI 1
170+
171+
static inline uint8_t lis2dux12_bus_reg(struct lis2dux12_data *data, uint8_t x)
172+
{
173+
return (data->bus_type == BUS_SPI) ? x | 0x80 : x;
174+
}
175+
176+
#define LIS2DUX12_FIFO_ITEM_LEN 7
177+
#define LIS2DUX12_FIFO_SIZE(x) (x * LIS2DUX12_FIFO_ITEM_LEN)
178+
#endif
179+
117180
#ifdef CONFIG_LIS2DUX12_TRIGGER
118181
int lis2dux12_trigger_set(const struct device *dev,
119182
const struct sensor_trigger *trig,

drivers/sensor/st/lis2dux12/lis2dux12_api.c

+123
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,121 @@ static int32_t st_lis2dux12_sample_fetch_temp(const struct device *dev)
101101
}
102102
#endif
103103

104+
#ifdef CONFIG_SENSOR_ASYNC_API
105+
static int32_t st_lis2dux12_rtio_read_accel(const struct device *dev, int16_t *acc)
106+
{
107+
struct lis2dux12_data *data = dev->data;
108+
const struct lis2dux12_config *cfg = dev->config;
109+
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
110+
111+
/* fetch raw data sample */
112+
lis2dux12_md_t mode = {.fs = data->range};
113+
lis2dux12_xl_data_t xzy_data = {0};
114+
115+
if (lis2dux12_xl_data_get(ctx, &mode, &xzy_data) < 0) {
116+
LOG_ERR("Failed to fetch raw data sample");
117+
return -EIO;
118+
}
119+
120+
acc[0] = xzy_data.raw[0];
121+
acc[1] = xzy_data.raw[1];
122+
acc[2] = xzy_data.raw[2];
123+
124+
return 0;
125+
}
126+
127+
static int32_t st_lis2dux12_rtio_read_temp(const struct device *dev, int16_t *temp)
128+
{
129+
const struct lis2dux12_config *cfg = dev->config;
130+
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
131+
132+
/* fetch raw data sample */
133+
lis2dux12_outt_data_t temp_data = {0};
134+
135+
if (lis2dux12_outt_data_get(ctx, &temp_data) < 0) {
136+
LOG_ERR("Failed to fetch raw temperature data sample");
137+
return -EIO;
138+
}
139+
140+
*temp = temp_data.heat.raw;
141+
142+
return 0;
143+
}
144+
#endif
145+
146+
#ifdef CONFIG_LIS2DUX12_STREAM
147+
static void st_lis2dux12_stream_config_fifo(const struct device *dev,
148+
struct trigger_config trig_cfg)
149+
{
150+
struct lis2dux12_data *lis2dux12 = dev->data;
151+
const struct lis2dux12_config *config = dev->config;
152+
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&config->ctx;
153+
lis2dux12_pin_int_route_t pin_int = { 0 };
154+
lis2dux12_fifo_mode_t fifo_mode;
155+
156+
/* disable FIFO as first thing */
157+
fifo_mode.store = LIS2DUX12_FIFO_1X;
158+
fifo_mode.xl_only = 1;
159+
fifo_mode.watermark = 0;
160+
fifo_mode.operation = LIS2DUX12_BYPASS_MODE;
161+
fifo_mode.batch.dec_ts = LIS2DUX12_DEC_TS_OFF;
162+
fifo_mode.batch.bdr_xl = LIS2DUX12_BDR_XL_ODR_OFF;
163+
164+
pin_int.fifo_th = PROPERTY_DISABLE;
165+
pin_int.fifo_full = PROPERTY_DISABLE;
166+
167+
if (trig_cfg.int_fifo_th || trig_cfg.int_fifo_full) {
168+
pin_int.fifo_th = (trig_cfg.int_fifo_th) ? PROPERTY_ENABLE : PROPERTY_DISABLE;
169+
pin_int.fifo_full = (trig_cfg.int_fifo_full) ? PROPERTY_ENABLE : PROPERTY_DISABLE;
170+
171+
fifo_mode.operation = LIS2DUX12_STREAM_MODE;
172+
fifo_mode.batch.dec_ts = config->ts_batch;
173+
fifo_mode.batch.bdr_xl = config->accel_batch;
174+
fifo_mode.watermark = config->fifo_wtm;
175+
}
176+
177+
/*
178+
* Set FIFO watermark (number of unread sensor data TAG + 6 bytes
179+
* stored in FIFO) to FIFO_WATERMARK samples
180+
*/
181+
lis2dux12_fifo_mode_set(ctx, fifo_mode);
182+
183+
/* Set FIFO batch rates */
184+
lis2dux12->accel_batch_odr = fifo_mode.batch.bdr_xl;
185+
lis2dux12->ts_batch_odr = fifo_mode.batch.dec_ts;
186+
187+
/* Set pin interrupt (fifo_th could be on or off) */
188+
if (config->drdy_pin == 1) {
189+
lis2dux12_pin_int1_route_set(ctx, &pin_int);
190+
} else {
191+
lis2dux12_pin_int2_route_set(ctx, &pin_int);
192+
}
193+
}
194+
195+
static void st_lis2dux12_stream_config_drdy(const struct device *dev,
196+
struct trigger_config trig_cfg)
197+
{
198+
const struct lis2dux12_config *config = dev->config;
199+
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&config->ctx;
200+
lis2dux12_pin_int_route_t pin_int = { 0 };
201+
202+
/* dummy read: re-trigger interrupt */
203+
lis2dux12_md_t md = {.fs = LIS2DUX12_2g};
204+
lis2dux12_xl_data_t buf;
205+
206+
lis2dux12_xl_data_get(ctx, &md, &buf);
207+
208+
pin_int.drdy = PROPERTY_ENABLE;
209+
210+
/* Set pin interrupt */
211+
if (config->drdy_pin == 1) {
212+
lis2dux12_pin_int1_route_set(ctx, &pin_int);
213+
} else {
214+
lis2dux12_pin_int2_route_set(ctx, &pin_int);
215+
}
216+
}
217+
#endif
218+
104219
#ifdef CONFIG_LIS2DUX12_TRIGGER
105220
static void st_lis2dux12_handle_interrupt(const struct device *dev)
106221
{
@@ -164,6 +279,14 @@ const struct lis2dux12_chip_api st_lis2dux12_chip_api = {
164279
#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP
165280
.sample_fetch_temp = st_lis2dux12_sample_fetch_temp,
166281
#endif
282+
#ifdef CONFIG_SENSOR_ASYNC_API
283+
.rtio_read_accel = st_lis2dux12_rtio_read_accel,
284+
.rtio_read_temp = st_lis2dux12_rtio_read_temp,
285+
#endif
286+
#ifdef CONFIG_LIS2DUX12_STREAM
287+
.stream_config_fifo = st_lis2dux12_stream_config_fifo,
288+
.stream_config_drdy = st_lis2dux12_stream_config_drdy,
289+
#endif
167290
#ifdef CONFIG_LIS2DUX12_TRIGGER
168291
.handle_interrupt = st_lis2dux12_handle_interrupt,
169292
.init_interrupt = st_lis2dux12_init_interrupt,

0 commit comments

Comments
 (0)