Skip to content

Commit f0010b2

Browse files
committed
drivers/sensor: iis3dwb: add streaming capabality
Add read_and_decode streaming APIs support. Triggers supported: - SENSOR_TRIG_FIFO_WATERMARK - SENSOR_TRIG_FIFO_FULL - SENSOR_TRIG_DATA_READY Signed-off-by: Armando Visconti <armando.visconti@st.com>
1 parent b848b04 commit f0010b2

File tree

9 files changed

+1079
-41
lines changed

9 files changed

+1079
-41
lines changed

drivers/sensor/st/iis3dwb/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
zephyr_library()
88

99
zephyr_library_sources(iis3dwb.c)
10+
zephyr_library_sources_ifdef(CONFIG_IIS3DWB_TRIGGER iis3dwb_trigger.c)
1011
zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API iis3dwb_decoder.c)
12+
zephyr_library_sources_ifdef(CONFIG_IIS3DWB_STREAM iis3dwb_stream.c)
1113

1214
zephyr_library_include_directories(../stmemsc)

drivers/sensor/st/iis3dwb/Kconfig

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,21 @@ menuconfig IIS3DWB
1616

1717
if IIS3DWB
1818

19+
config IIS3DWB_STREAM
20+
bool "IIS3DWB data streaming"
21+
select IIS3DWB_TRIGGER
22+
default y
23+
depends on SPI_RTIO
24+
depends on SENSOR_ASYNC_API
25+
help
26+
Use this config option to enable streaming sensor data via RTIO subsystem.
27+
28+
config IIS3DWB_TRIGGER
29+
bool
30+
1931
config IIS3DWB_ENABLE_TEMP
2032
bool "Temperature"
2133
help
2234
Enable/disable temperature sensor
2335

24-
2536
endif # IIS3DWB

drivers/sensor/st/iis3dwb/iis3dwb.c

Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ static int iis3dwb_odr_set(const struct device *dev,
5252
break;
5353

5454
default:
55+
if (val->val1 > 26) {
56+
LOG_ERR("%s: odr %d Hz not supported", dev->name, val->val1);
57+
return -EINVAL;
58+
}
59+
5560
odr = IIS3DWB_XL_ODR_26k7Hz;
5661
break;
5762
}
@@ -64,25 +69,20 @@ static int iis3dwb_odr_set(const struct device *dev,
6469
return 0;
6570
}
6671

67-
static int iis3dwb_set_fs(const struct device *dev, uint8_t fs)
72+
static int iis3dwb_set_fs(const struct device *dev, int32_t fs)
6873
{
6974
int ret;
7075
uint8_t range;
7176

72-
switch (fs) {
73-
case 2:
77+
if (fs <= 2) {
7478
range = IIS3DWB_DT_FS_2G;
75-
break;
76-
case 4:
79+
} else if (fs <= 4) {
7780
range = IIS3DWB_DT_FS_4G;
78-
break;
79-
case 8:
81+
} else if (fs <= 8) {
8082
range = IIS3DWB_DT_FS_8G;
81-
break;
82-
case 16:
83+
} else if (fs <= 16) {
8384
range = IIS3DWB_DT_FS_16G;
84-
break;
85-
default:
85+
} else {
8686
LOG_ERR("fs [%d] not supported.", fs);
8787
return -EINVAL;
8888
}
@@ -172,6 +172,8 @@ void iis3dwb_rtio_rd_transaction(const struct device *dev,
172172
read_reg = rtio_sqe_acquire(rtio);
173173

174174
if (write_addr == NULL || read_reg == NULL) {
175+
rtio_iodev_sqe_err(iodev_sqe, -ENOMEM);
176+
rtio_sqe_drop_all(rtio);
175177
return;
176178
}
177179

@@ -185,6 +187,8 @@ void iis3dwb_rtio_rd_transaction(const struct device *dev,
185187

186188
complete_op = rtio_sqe_acquire(rtio);
187189
if (complete_op == NULL) {
190+
rtio_iodev_sqe_err(iodev_sqe, -ENOMEM);
191+
rtio_sqe_drop_all(rtio);
188192
return;
189193
}
190194

@@ -210,6 +214,7 @@ static void iis3dwb_submit_one_shot(const struct device *dev, struct rtio_iodev_
210214
rc = rtio_sqe_rx_buf(iodev_sqe, min_buf_len, min_buf_len, &buf, &buf_len);
211215
if (rc != 0) {
212216
LOG_ERR("Failed to get a read buffer of size %u bytes", min_buf_len);
217+
rtio_iodev_sqe_err(iodev_sqe, -ENOMEM);
213218
return;
214219
}
215220

@@ -291,43 +296,28 @@ static void iis3dwb_submit_one_shot(const struct device *dev, struct rtio_iodev_
291296
}
292297
}
293298

294-
if (edata->has_accel == 0) {
299+
if (edata->has_accel == 0 && edata->has_temp == 0) {
295300
rtio_iodev_sqe_err(iodev_sqe, -EIO);
296301
}
297302
}
298303

299-
void iis3dwb_submit_sync(struct rtio_iodev_sqe *iodev_sqe)
304+
void iis3dwb_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe)
300305
{
301306
const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data;
302-
const struct device *dev = cfg->sensor;
303307

304308
if (!cfg->is_streaming) {
305309
iis3dwb_submit_one_shot(dev, iodev_sqe);
310+
} else if (IS_ENABLED(CONFIG_IIS3DWB_STREAM)) {
311+
iis3dwb_submit_stream(dev, iodev_sqe);
306312
} else {
307313
rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP);
308314
}
309315
}
310316

311-
void iis3dwb_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe)
312-
{
313-
struct rtio_work_req *req = rtio_work_req_alloc();
314-
315-
if (req == NULL) {
316-
LOG_ERR("RTIO work item allocation failed. Consider to increase "
317-
"CONFIG_RTIO_WORKQ_POOL_ITEMS.");
318-
rtio_iodev_sqe_err(iodev_sqe, -ENOMEM);
319-
return;
320-
}
321-
322-
rtio_work_req_submit(req, iodev_sqe, iis3dwb_submit_sync);
323-
}
324-
325317
static DEVICE_API(sensor, iis3dwb_driver_api) = {
326318
.attr_set = iis3dwb_attr_set,
327-
#ifdef CONFIG_SENSOR_ASYNC_API
328319
.get_decoder = iis3dwb_get_decoder,
329320
.submit = iis3dwb_submit,
330-
#endif
331321
};
332322

333323
static int iis3dwb_init_chip(const struct device *dev)
@@ -350,9 +340,8 @@ static int iis3dwb_init_chip(const struct device *dev)
350340
* Restore default configuration
351341
*/
352342
iis3dwb_reset_set(ctx, PROPERTY_ENABLE);
353-
do {
354-
iis3dwb_reset_get(ctx, &rst);
355-
} while (rst);
343+
WAIT_FOR((iis3dwb_reset_get(ctx, &rst) == 0) && !rst,
344+
100 * USEC_PER_MSEC, k_msleep(10));
356345

357346
/* Enable Block Data Update */
358347
iis3dwb_block_data_update_set(ctx, PROPERTY_ENABLE);
@@ -371,6 +360,15 @@ static int iis3dwb_init(const struct device *dev)
371360
return -EIO;
372361
}
373362

363+
#ifdef CONFIG_IIS3DWB_TRIGGER
364+
if (cfg->trig_enabled) {
365+
if (iis3dwb_init_interrupt(dev) < 0) {
366+
LOG_ERR("Failed to initialize interrupt.");
367+
return -EIO;
368+
}
369+
}
370+
#endif
371+
374372
/* set sensor default scale (used to convert sample values) */
375373
LOG_DBG("%s: range is %d", dev->name, cfg->range);
376374
ret = iis3dwb_set_range_raw(dev, cfg->range);
@@ -406,6 +404,17 @@ static int iis3dwb_init(const struct device *dev)
406404
DT_DRV_INST(inst), IIS3DWB_SPI_OPERATION, 0U); \
407405
RTIO_DEFINE(iis3dwb_rtio_ctx_##inst, 8, 8);
408406

407+
#ifdef CONFIG_IIS3DWB_TRIGGER
408+
#define IIS3DWB_CFG_IRQ(inst) \
409+
.trig_enabled = true, \
410+
.int1_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int1_gpios, {0}), \
411+
.int2_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int2_gpios, {0}), \
412+
.drdy_pulsed = DT_INST_PROP(inst, drdy_pulsed), \
413+
.drdy_pin = DT_INST_PROP(inst, drdy_pin),
414+
#else
415+
#define IIS3DWB_CFG_IRQ(inst)
416+
#endif /* CONFIG_IIS3DWB_TRIGGER */
417+
409418
#define IIS3DWB_CONFIG(inst) \
410419
{ \
411420
STMEMSC_CTX_SPI(&iis3dwb_config_##inst.stmemsc_cfg), \
@@ -417,6 +426,16 @@ static int iis3dwb_init(const struct device *dev)
417426
.range = DT_INST_PROP(inst, range), \
418427
.filter = DT_INST_PROP(inst, filter), \
419428
.odr = DT_INST_PROP(inst, odr), \
429+
\
430+
IF_ENABLED(CONFIG_IIS3DWB_STREAM, \
431+
(.fifo_wtm = DT_INST_PROP(inst, fifo_watermark), \
432+
.accel_batch = DT_INST_PROP(inst, accel_fifo_batch_rate), \
433+
.temp_batch = DT_INST_PROP(inst, temp_fifo_batch_rate), \
434+
.ts_batch = DT_INST_PROP(inst, timestamp_fifo_batch_rate),)) \
435+
\
436+
IF_ENABLED(UTIL_OR(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \
437+
DT_INST_NODE_HAS_PROP(inst, int2_gpios)), \
438+
(IIS3DWB_CFG_IRQ(inst))) \
420439
}
421440

422441
#define IIS3DWB_DEFINE(inst) \

drivers/sensor/st/iis3dwb/iis3dwb.h

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,19 @@
1919
#include <zephyr/types.h>
2020
#include <zephyr/sys/util.h>
2121
#include <stmemsc.h>
22+
2223
#include "iis3dwb_reg.h"
2324
#include <zephyr/dt-bindings/sensor/iis3dwb.h>
2425
#include <zephyr/drivers/sensor_clock.h>
2526

2627
#define GAIN_UNIT (61LL)
2728

29+
struct trigger_config {
30+
uint8_t int_fifo_th : 1;
31+
uint8_t int_fifo_full : 1;
32+
uint8_t int_drdy : 1;
33+
};
34+
2835
struct iis3dwb_config {
2936
stmdev_ctx_t ctx;
3037
union {
@@ -36,6 +43,20 @@ struct iis3dwb_config {
3643
uint8_t range;
3744
uint8_t filter;
3845
uint8_t odr;
46+
47+
#ifdef CONFIG_IIS3DWB_STREAM
48+
uint16_t fifo_wtm;
49+
uint8_t accel_batch : 4;
50+
uint8_t temp_batch : 2;
51+
uint8_t ts_batch : 2;
52+
#endif
53+
#ifdef CONFIG_IIS3DWB_TRIGGER
54+
const struct gpio_dt_spec int1_gpio;
55+
const struct gpio_dt_spec int2_gpio;
56+
uint8_t drdy_pulsed;
57+
uint8_t drdy_pin;
58+
bool trig_enabled;
59+
#endif
3960
};
4061

4162
struct iis3dwb_data {
@@ -47,10 +68,35 @@ struct iis3dwb_data {
4768
struct rtio *rtio_ctx;
4869
struct rtio_iodev *iodev;
4970
struct rtio_iodev_sqe *streaming_sqe;
71+
72+
#ifdef CONFIG_IIS3DWB_STREAM
73+
uint64_t timestamp;
74+
uint8_t status;
75+
uint8_t fifo_status[2];
76+
uint16_t fifo_count;
77+
struct trigger_config trig_cfg;
78+
uint8_t accel_batch_odr : 4;
79+
uint8_t temp_batch_odr : 2;
80+
uint8_t ts_batch_odr : 2;
81+
#endif
82+
83+
#ifdef CONFIG_IIS3DWB_TRIGGER
84+
struct gpio_dt_spec *drdy_gpio;
85+
struct gpio_callback gpio_cb;
86+
87+
const struct device *dev;
88+
#endif /* CONFIG_IIS3DWB_TRIGGER */
5089
};
5190

5291
int iis3dwb_spi_init(const struct device *dev);
5392

93+
#define IIS3DWB_FIFO_ITEM_LEN 7
94+
#define IIS3DWB_FIFO_SIZE(x) (x * IIS3DWB_FIFO_ITEM_LEN)
95+
96+
#ifdef CONFIG_IIS3DWB_TRIGGER
97+
int iis3dwb_init_interrupt(const struct device *dev);
98+
#endif
99+
54100
/* decoder */
55101
struct iis3dwb_decoder_header {
56102
uint64_t timestamp;
@@ -64,11 +110,12 @@ struct iis3dwb_fifo_data {
64110
struct iis3dwb_decoder_header header;
65111
uint32_t accel_odr: 4;
66112
uint32_t fifo_mode_sel: 2;
67-
uint32_t fifo_count: 7;
113+
uint32_t fifo_count: 10;
68114
uint32_t reserved_1: 5;
69-
uint32_t accel_batch_odr: 3;
115+
uint32_t accel_batch_odr: 4;
116+
uint32_t temp_batch_odr: 2;
70117
uint32_t ts_batch_odr: 2;
71-
uint32_t reserved: 9;
118+
uint32_t reserved: 3;
72119
} __attribute__((__packed__));
73120

74121
struct iis3dwb_rtio_data {
@@ -84,9 +131,14 @@ struct iis3dwb_rtio_data {
84131

85132
int iis3dwb_encode(const struct device *dev, const struct sensor_chan_spec *const channels,
86133
const size_t num_channels, uint8_t *buf);
87-
88134
int iis3dwb_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder);
89135

136+
#ifdef CONFIG_IIS3DWB_TRIGGER
137+
int iis3dwb_route_int1(const struct device *dev, iis3dwb_pin_int1_route_t pin_int);
138+
int iis3dwb_route_int2(const struct device *dev, iis3dwb_pin_int2_route_t pin_int);
139+
void iis3dwb_stream_irq_handler(const struct device *dev);
140+
#endif
141+
90142
void iis3dwb_rtio_rd_transaction(const struct device *dev,
91143
uint8_t *regs, uint8_t regs_num,
92144
struct spi_buf *buf,

0 commit comments

Comments
 (0)