Skip to content

Commit b390cbd

Browse files
aviscontikartben
authored andcommitted
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 <[email protected]>
1 parent 93a30e7 commit b390cbd

File tree

10 files changed

+1102
-75
lines changed

10 files changed

+1102
-75
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: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ static int32_t iis3dwb_set_odr_raw(const struct device *dev, uint8_t odr)
4141
return iis3dwb_xl_data_rate_set(ctx, odr);
4242
}
4343

44-
static int iis3dwb_odr_set(const struct device *dev,
45-
const struct sensor_value *val)
44+
static int iis3dwb_odr_set(const struct device *dev, const struct sensor_value *val)
4645
{
4746
iis3dwb_odr_xl_t odr;
4847

@@ -58,32 +57,27 @@ static int iis3dwb_odr_set(const struct device *dev,
5857
}
5958

6059
if (iis3dwb_set_odr_raw(dev, odr)) {
61-
LOG_DBG("failed to set sampling rate");
60+
LOG_ERR("failed to set sampling rate");
6261
return -EIO;
6362
}
6463

6564
return 0;
6665
}
6766

68-
static int iis3dwb_set_fs(const struct device *dev, uint8_t fs)
67+
static int iis3dwb_set_fs(const struct device *dev, int32_t fs)
6968
{
7069
int ret;
7170
uint8_t range;
7271

73-
switch (fs) {
74-
case 2:
72+
if (fs <= 2) {
7573
range = IIS3DWB_DT_FS_2G;
76-
break;
77-
case 4:
74+
} else if (fs <= 4) {
7875
range = IIS3DWB_DT_FS_4G;
79-
break;
80-
case 8:
76+
} else if (fs <= 8) {
8177
range = IIS3DWB_DT_FS_8G;
82-
break;
83-
case 16:
78+
} else if (fs <= 16) {
8479
range = IIS3DWB_DT_FS_16G;
85-
break;
86-
default:
80+
} else {
8781
LOG_ERR("fs [%d] not supported.", fs);
8882
return -EINVAL;
8983
}
@@ -98,10 +92,8 @@ static int iis3dwb_set_fs(const struct device *dev, uint8_t fs)
9892
return ret;
9993
}
10094

101-
static int iis3dwb_attr_set(const struct device *dev,
102-
enum sensor_channel chan,
103-
enum sensor_attribute attr,
104-
const struct sensor_value *val)
95+
static int iis3dwb_attr_set(const struct device *dev, enum sensor_channel chan,
96+
enum sensor_attribute attr, const struct sensor_value *val)
10597
{
10698
if (chan != SENSOR_CHAN_ALL) {
10799
LOG_WRN("attr_set() not supported on this channel.");
@@ -115,16 +107,14 @@ static int iis3dwb_attr_set(const struct device *dev,
115107
case SENSOR_ATTR_SAMPLING_FREQUENCY:
116108
return iis3dwb_odr_set(dev, val);
117109
default:
118-
LOG_DBG("operation not supported.");
110+
LOG_ERR("operation not supported.");
119111
return -ENOTSUP;
120112
}
121113

122114
return 0;
123115
}
124116

125-
static void iis3dwb_one_shot_complete_cb(struct rtio *ctx,
126-
const struct rtio_sqe *sqe,
127-
void *arg)
117+
static void iis3dwb_one_shot_complete_cb(struct rtio *ctx, const struct rtio_sqe *sqe, void *arg)
128118
{
129119
struct rtio_iodev_sqe *iodev_sqe = (struct rtio_iodev_sqe *)sqe->userdata;
130120
int err = 0;
@@ -155,6 +145,7 @@ static void iis3dwb_submit_one_shot(const struct device *dev, struct rtio_iodev_
155145
rc = rtio_sqe_rx_buf(iodev_sqe, min_buf_len, min_buf_len, &buf, &buf_len);
156146
if (rc != 0) {
157147
LOG_ERR("Failed to get a read buffer of size %u bytes", min_buf_len);
148+
rtio_iodev_sqe_err(iodev_sqe, -ENOMEM);
158149
return;
159150
}
160151

@@ -246,43 +237,28 @@ static void iis3dwb_submit_one_shot(const struct device *dev, struct rtio_iodev_
246237
}
247238
}
248239

249-
if (edata->has_accel == 0) {
240+
if (edata->has_accel == 0 && edata->has_temp == 0) {
250241
rtio_iodev_sqe_err(iodev_sqe, -EIO);
251242
}
252243
}
253244

254-
void iis3dwb_submit_sync(struct rtio_iodev_sqe *iodev_sqe)
245+
void iis3dwb_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe)
255246
{
256247
const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data;
257-
const struct device *dev = cfg->sensor;
258248

259249
if (!cfg->is_streaming) {
260250
iis3dwb_submit_one_shot(dev, iodev_sqe);
251+
} else if (IS_ENABLED(CONFIG_IIS3DWB_STREAM)) {
252+
iis3dwb_submit_stream(dev, iodev_sqe);
261253
} else {
262254
rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP);
263255
}
264256
}
265257

266-
void iis3dwb_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe)
267-
{
268-
struct rtio_work_req *req = rtio_work_req_alloc();
269-
270-
if (req == NULL) {
271-
LOG_ERR("RTIO work item allocation failed. Consider to increase "
272-
"CONFIG_RTIO_WORKQ_POOL_ITEMS.");
273-
rtio_iodev_sqe_err(iodev_sqe, -ENOMEM);
274-
return;
275-
}
276-
277-
rtio_work_req_submit(req, iodev_sqe, iis3dwb_submit_sync);
278-
}
279-
280258
static DEVICE_API(sensor, iis3dwb_driver_api) = {
281259
.attr_set = iis3dwb_attr_set,
282-
#ifdef CONFIG_SENSOR_ASYNC_API
283260
.get_decoder = iis3dwb_get_decoder,
284261
.submit = iis3dwb_submit,
285-
#endif
286262
};
287263

288264
static int iis3dwb_init_chip(const struct device *dev)
@@ -292,22 +268,20 @@ static int iis3dwb_init_chip(const struct device *dev)
292268
uint8_t chip_id, rst;
293269

294270
if (iis3dwb_device_id_get(ctx, &chip_id) < 0) {
295-
LOG_DBG("Failed reading chip id");
271+
LOG_ERR("Failed reading chip id");
296272
return -EIO;
297273
}
298274

299275
if (chip_id != IIS3DWB_ID) {
300-
LOG_DBG("Invalid chip id 0x%x", chip_id);
276+
LOG_ERR("Invalid chip id 0x%x", chip_id);
301277
return -EIO;
302278
}
303279

304280
/*
305281
* Restore default configuration
306282
*/
307283
iis3dwb_reset_set(ctx, PROPERTY_ENABLE);
308-
do {
309-
iis3dwb_reset_get(ctx, &rst);
310-
} while (rst);
284+
WAIT_FOR((iis3dwb_reset_get(ctx, &rst) == 0) && !rst, 100 * USEC_PER_MSEC, k_msleep(10));
311285

312286
/* Enable Block Data Update */
313287
iis3dwb_block_data_update_set(ctx, PROPERTY_ENABLE);
@@ -322,9 +296,16 @@ static int iis3dwb_init(const struct device *dev)
322296
int ret;
323297

324298
if (iis3dwb_init_chip(dev) < 0) {
325-
LOG_DBG("Failed to initialize chip");
299+
LOG_ERR("Failed to initialize chip");
300+
return -EIO;
301+
}
302+
303+
#ifdef CONFIG_IIS3DWB_TRIGGER
304+
if (cfg->trig_enabled && iis3dwb_init_interrupt(dev) < 0) {
305+
LOG_ERR("Failed to initialize interrupt.");
326306
return -EIO;
327307
}
308+
#endif
328309

329310
/* set sensor default scale (used to convert sample values) */
330311
LOG_DBG("%s: range is %d", dev->name, cfg->range);
@@ -361,6 +342,17 @@ static int iis3dwb_init(const struct device *dev)
361342
DT_DRV_INST(inst), IIS3DWB_SPI_OPERATION, 0U); \
362343
RTIO_DEFINE(iis3dwb_rtio_ctx_##inst, 8, 8);
363344

345+
#ifdef CONFIG_IIS3DWB_TRIGGER
346+
#define IIS3DWB_CFG_IRQ(inst) \
347+
.trig_enabled = true, \
348+
.int1_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int1_gpios, {0}), \
349+
.int2_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int2_gpios, {0}), \
350+
.drdy_pulsed = DT_INST_PROP(inst, drdy_pulsed), \
351+
.drdy_pin = DT_INST_PROP(inst, drdy_pin),
352+
#else
353+
#define IIS3DWB_CFG_IRQ(inst)
354+
#endif /* CONFIG_IIS3DWB_TRIGGER */
355+
364356
#define IIS3DWB_CONFIG(inst) \
365357
{ \
366358
STMEMSC_CTX_SPI(&iis3dwb_config_##inst.stmemsc_cfg), \
@@ -372,6 +364,16 @@ static int iis3dwb_init(const struct device *dev)
372364
.range = DT_INST_PROP(inst, range), \
373365
.filter = DT_INST_PROP(inst, filter), \
374366
.odr = DT_INST_PROP(inst, odr), \
367+
\
368+
IF_ENABLED(CONFIG_IIS3DWB_STREAM, \
369+
(.fifo_wtm = DT_INST_PROP(inst, fifo_watermark), \
370+
.accel_batch = DT_INST_PROP(inst, accel_fifo_batch_rate), \
371+
.temp_batch = DT_INST_PROP(inst, temp_fifo_batch_rate), \
372+
.ts_batch = DT_INST_PROP(inst, timestamp_fifo_batch_rate),)) \
373+
\
374+
IF_ENABLED(UTIL_OR(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \
375+
DT_INST_NODE_HAS_PROP(inst, int2_gpios)), \
376+
(IIS3DWB_CFG_IRQ(inst))) \
375377
}
376378

377379
#define IIS3DWB_DEFINE(inst) \

drivers/sensor/st/iis3dwb/iis3dwb.h

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727

2828
#define GAIN_UNIT (61LL)
2929

30+
struct trigger_config {
31+
uint8_t int_fifo_th : 1;
32+
uint8_t int_fifo_full : 1;
33+
uint8_t int_drdy : 1;
34+
};
35+
3036
struct iis3dwb_config {
3137
stmdev_ctx_t ctx;
3238
union {
@@ -38,6 +44,20 @@ struct iis3dwb_config {
3844
uint8_t range;
3945
uint8_t filter;
4046
uint8_t odr;
47+
48+
#ifdef CONFIG_IIS3DWB_STREAM
49+
uint16_t fifo_wtm;
50+
uint8_t accel_batch : 4;
51+
uint8_t temp_batch : 2;
52+
uint8_t ts_batch : 2;
53+
#endif
54+
#ifdef CONFIG_IIS3DWB_TRIGGER
55+
const struct gpio_dt_spec int1_gpio;
56+
const struct gpio_dt_spec int2_gpio;
57+
uint8_t drdy_pulsed;
58+
uint8_t drdy_pin;
59+
bool trig_enabled;
60+
#endif
4161
};
4262

4363
struct iis3dwb_data {
@@ -49,10 +69,35 @@ struct iis3dwb_data {
4969
struct rtio *rtio_ctx;
5070
struct rtio_iodev *iodev;
5171
struct rtio_iodev_sqe *streaming_sqe;
72+
73+
#ifdef CONFIG_IIS3DWB_STREAM
74+
uint64_t timestamp;
75+
uint8_t status;
76+
uint8_t fifo_status[2];
77+
uint16_t fifo_count;
78+
struct trigger_config trig_cfg;
79+
uint8_t accel_batch_odr : 4;
80+
uint8_t temp_batch_odr : 2;
81+
uint8_t ts_batch_odr : 2;
82+
#endif
83+
84+
#ifdef CONFIG_IIS3DWB_TRIGGER
85+
const struct gpio_dt_spec *drdy_gpio;
86+
struct gpio_callback gpio_cb;
87+
88+
const struct device *dev;
89+
#endif /* CONFIG_IIS3DWB_TRIGGER */
5290
};
5391

5492
int iis3dwb_spi_init(const struct device *dev);
5593

94+
#define IIS3DWB_FIFO_ITEM_LEN 7
95+
#define IIS3DWB_FIFO_SIZE(x) (x * IIS3DWB_FIFO_ITEM_LEN)
96+
97+
#ifdef CONFIG_IIS3DWB_TRIGGER
98+
int iis3dwb_init_interrupt(const struct device *dev);
99+
#endif
100+
56101
/* decoder */
57102
struct iis3dwb_decoder_header {
58103
uint64_t timestamp;
@@ -66,11 +111,12 @@ struct iis3dwb_fifo_data {
66111
struct iis3dwb_decoder_header header;
67112
uint32_t accel_odr: 4;
68113
uint32_t fifo_mode_sel: 2;
69-
uint32_t fifo_count: 7;
114+
uint32_t fifo_count: 10;
70115
uint32_t reserved_1: 5;
71-
uint32_t accel_batch_odr: 3;
116+
uint32_t accel_batch_odr: 4;
117+
uint32_t temp_batch_odr: 2;
72118
uint32_t ts_batch_odr: 2;
73-
uint32_t reserved: 9;
119+
uint32_t reserved: 3;
74120
} __attribute__((__packed__));
75121

76122
struct iis3dwb_rtio_data {
@@ -79,14 +125,19 @@ struct iis3dwb_rtio_data {
79125
uint8_t has_accel: 1; /* set if accel channel has data */
80126
uint8_t has_temp: 1; /* set if temp channel has data */
81127
uint8_t reserved: 6;
82-
} __attribute__((__packed__));
128+
} __attribute__((__packed__));
83129
int16_t accel[3];
84130
int16_t temp;
85131
};
86132

87133
int iis3dwb_encode(const struct device *dev, const struct sensor_chan_spec *const channels,
88-
const size_t num_channels, uint8_t *buf);
89-
134+
const size_t num_channels, uint8_t *buf);
90135
int iis3dwb_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder);
91136

137+
#ifdef CONFIG_IIS3DWB_TRIGGER
138+
int iis3dwb_route_int1(const struct device *dev, iis3dwb_pin_int1_route_t pin_int);
139+
int iis3dwb_route_int2(const struct device *dev, iis3dwb_pin_int2_route_t pin_int);
140+
void iis3dwb_stream_irq_handler(const struct device *dev);
141+
#endif
142+
92143
#endif /* ZEPHYR_DRIVERS_SENSOR_IIS3DWB_IIS3DWB_H_ */

0 commit comments

Comments
 (0)