Skip to content

Commit a2d230b

Browse files
aviscontikartben
authored andcommitted
drivers/sensor/: lis2dux12: support FIFO modes
Support three different FIFO contents which are selectable through a new DT property, fifo-mode-sel, which may be set to one of the following values: - 0x0 # 1x Accelerometer @12bit and 1x temperature @12bit samples - 0x1 # 1x Accelerometer @16bit sample - 0x2 # 2x Accelerometer @8bit samples (previous and current) Signed-off-by: Armando Visconti <armando.visconti@st.com>
1 parent f9ca69d commit a2d230b

File tree

8 files changed

+186
-19
lines changed

8 files changed

+186
-19
lines changed

drivers/sensor/st/lis2dux12/lis2dux12.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ static DEVICE_API(sensor, lis2dux12_driver_api) = {
277277
.odr = DT_INST_PROP(inst, odr), \
278278
IF_ENABLED(CONFIG_LIS2DUX12_STREAM, \
279279
(.fifo_wtm = DT_INST_PROP(inst, fifo_watermark), \
280+
.fifo_mode_sel = DT_INST_PROP(inst, fifo_mode_sel), \
280281
.accel_batch = DT_INST_PROP(inst, accel_fifo_batch_rate), \
281282
.ts_batch = DT_INST_PROP(inst, timestamp_fifo_batch_rate),)) \
282283
IF_ENABLED(UTIL_OR(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \

drivers/sensor/st/lis2dux12/lis2dux12.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ struct lis2dux12_config {
106106
uint8_t fifo_wtm;
107107
uint8_t accel_batch : 3;
108108
uint8_t ts_batch : 2;
109-
uint8_t reserved : 3;
109+
uint8_t fifo_mode_sel : 2;
110+
uint8_t reserved : 1;
110111
#endif
111112
#ifdef CONFIG_LIS2DUX12_TRIGGER
112113
const struct gpio_dt_spec int1_gpio;

drivers/sensor/st/lis2dux12/lis2dux12_api.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ static void st_lis2dux12_stream_config_fifo(const struct device *dev,
155155

156156
/* disable FIFO as first thing */
157157
fifo_mode.store = LIS2DUX12_FIFO_1X;
158-
fifo_mode.xl_only = 1;
158+
fifo_mode.xl_only = 0;
159159
fifo_mode.watermark = 0;
160160
fifo_mode.operation = LIS2DUX12_BYPASS_MODE;
161161
fifo_mode.batch.dec_ts = LIS2DUX12_DEC_TS_OFF;
@@ -168,10 +168,32 @@ static void st_lis2dux12_stream_config_fifo(const struct device *dev,
168168
pin_int.fifo_th = (trig_cfg.int_fifo_th) ? PROPERTY_ENABLE : PROPERTY_DISABLE;
169169
pin_int.fifo_full = (trig_cfg.int_fifo_full) ? PROPERTY_ENABLE : PROPERTY_DISABLE;
170170

171+
switch (config->fifo_mode_sel) {
172+
case 0:
173+
fifo_mode.store = LIS2DUX12_FIFO_1X;
174+
fifo_mode.xl_only = 0;
175+
break;
176+
case 1:
177+
fifo_mode.store = LIS2DUX12_FIFO_1X;
178+
fifo_mode.xl_only = 1;
179+
break;
180+
case 2:
181+
fifo_mode.store = LIS2DUX12_FIFO_2X;
182+
fifo_mode.xl_only = 1;
183+
break;
184+
}
185+
171186
fifo_mode.operation = LIS2DUX12_STREAM_MODE;
172187
fifo_mode.batch.dec_ts = config->ts_batch;
173188
fifo_mode.batch.bdr_xl = config->accel_batch;
174189
fifo_mode.watermark = config->fifo_wtm;
190+
191+
/* In case each FIFO word contains 2x accelerometer samples,
192+
* then watermark can be divided by two to match user expectation.
193+
*/
194+
if (config->fifo_mode_sel == 2) {
195+
fifo_mode.watermark /= 2;
196+
}
175197
}
176198

177199
/*

drivers/sensor/st/lis2dux12/lis2dux12_decoder.c

Lines changed: 119 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,6 @@ static int lis2dux12_decoder_get_frame_count(const uint8_t *buffer,
167167
uint8_t tot_accel_fifo_words = 0;
168168
uint8_t tot_ts_fifo_words = 0;
169169

170-
#if defined(CONFIG_LIS2DUX12_ENABLE_TEMP)
171-
uint8_t tot_temp_fifo_words = 0;
172-
#endif
173-
174170
buffer += sizeof(struct lis2dux12_fifo_data);
175171
buffer_end = buffer + LIS2DUX12_FIFO_SIZE(edata->fifo_count);
176172

@@ -205,9 +201,10 @@ static int lis2dux12_decoder_get_frame_count(const uint8_t *buffer,
205201

206202
#if defined(CONFIG_LIS2DUX12_ENABLE_TEMP)
207203
case SENSOR_CHAN_DIE_TEMP:
208-
*frame_count = tot_temp_fifo_words;
204+
*frame_count = (data->fifo_mode_sel == 0) ? tot_accel_fifo_words : 0;
209205
break;
210206
#endif
207+
211208
default:
212209
*frame_count = 0;
213210
break;
@@ -227,11 +224,11 @@ static int lis2dux12_decode_fifo(const uint8_t *buffer, struct sensor_chan_spec
227224
int count = 0;
228225
uint8_t fifo_tag;
229226
uint16_t xl_count = 0;
230-
uint16_t tot_chan_fifo_words = 0;
227+
uint16_t tot_fifo_samples = 0;
231228
int ret;
232229

233230
/* count total FIFO word for each tag */
234-
ret = lis2dux12_decoder_get_frame_count(buffer, chan_spec, &tot_chan_fifo_words);
231+
ret = lis2dux12_decoder_get_frame_count(buffer, chan_spec, &tot_fifo_samples);
235232
if (ret < 0) {
236233
return 0;
237234
}
@@ -247,8 +244,15 @@ static int lis2dux12_decode_fifo(const uint8_t *buffer, struct sensor_chan_spec
247244
if (SENSOR_CHANNEL_IS_ACCEL(chan_spec.chan_type)) {
248245
((struct sensor_data_header *)data_out)->base_timestamp_ns =
249246
edata->header.timestamp -
250-
(tot_chan_fifo_words - 1) *
247+
(tot_fifo_samples - 1) *
251248
accel_period_ns(edata->accel_odr, edata->accel_batch_odr);
249+
#if defined(CONFIG_LIS2DUX12_ENABLE_TEMP)
250+
} else if (chan_spec.chan_type == SENSOR_CHAN_DIE_TEMP) {
251+
((struct sensor_data_header *)data_out)->base_timestamp_ns =
252+
edata->header.timestamp -
253+
(tot_fifo_samples - 1) *
254+
accel_period_ns(edata->accel_odr, edata->accel_batch_odr);
255+
#endif
252256
}
253257

254258
while (count < max_count && buffer < buffer_end) {
@@ -261,12 +265,12 @@ static int lis2dux12_decode_fifo(const uint8_t *buffer, struct sensor_chan_spec
261265
fifo_tag = (buffer[0] >> 3);
262266

263267
switch (fifo_tag) {
264-
case LIS2DUXXX_XL_TEMP_TAG: {
268+
case LIS2DUXXX_XL_ONLY_2X_TAG: {
265269
struct sensor_three_axis_data *out = data_out;
266270
int16_t x, y, z;
267271
const int32_t scale = accel_scaler[header->range];
268272

269-
xl_count++;
273+
xl_count += 2;
270274
if ((uintptr_t)buffer < *fit) {
271275
/* This frame was already decoded, move on to the next frame */
272276
buffer = frame_end;
@@ -278,22 +282,122 @@ static int lis2dux12_decode_fifo(const uint8_t *buffer, struct sensor_chan_spec
278282
continue;
279283
}
280284

285+
out->shift = accel_range[header->range];
286+
281287
out->readings[count].timestamp_delta =
282-
(xl_count - 1) * accel_period_ns(edata->accel_odr,
288+
(xl_count - 2) * accel_period_ns(edata->accel_odr,
283289
edata->accel_batch_odr);
284290

285-
x = (int16_t)buffer[1] + (int16_t)buffer[2] * 256;
286-
y = (int16_t)buffer[3] + (int16_t)buffer[4] * 256;
287-
z = (int16_t)buffer[5] + (int16_t)buffer[6] * 256;
291+
x = *(int16_t *)&buffer[0];
292+
y = *(int16_t *)&buffer[1];
293+
z = *(int16_t *)&buffer[2];
288294

289-
out->shift = accel_range[header->range];
295+
out->readings[count].x = Q31_SHIFT_MICROVAL(scale * x, out->shift);
296+
out->readings[count].y = Q31_SHIFT_MICROVAL(scale * y, out->shift);
297+
out->readings[count].z = Q31_SHIFT_MICROVAL(scale * z, out->shift);
298+
count++;
290299

300+
out->readings[count].timestamp_delta =
301+
(xl_count - 1) * accel_period_ns(edata->accel_odr,
302+
edata->accel_batch_odr);
303+
304+
x = *(int16_t *)&buffer[3];
305+
y = *(int16_t *)&buffer[4];
306+
z = *(int16_t *)&buffer[5];
291307
out->readings[count].x = Q31_SHIFT_MICROVAL(scale * x, out->shift);
292308
out->readings[count].y = Q31_SHIFT_MICROVAL(scale * y, out->shift);
293309
out->readings[count].z = Q31_SHIFT_MICROVAL(scale * z, out->shift);
294310
break;
295311
}
296312

313+
case LIS2DUXXX_XL_TEMP_TAG: {
314+
struct sensor_three_axis_data *out = data_out;
315+
int16_t x, y, z;
316+
#if defined(CONFIG_LIS2DUX12_ENABLE_TEMP)
317+
struct sensor_q31_data *t_out = data_out;
318+
int16_t t;
319+
int64_t t_uC;
320+
#endif
321+
const int32_t scale = accel_scaler[header->range];
322+
323+
xl_count++;
324+
if ((uintptr_t)buffer < *fit) {
325+
/* This frame was already decoded, move on to the next frame */
326+
buffer = frame_end;
327+
continue;
328+
}
329+
330+
if (edata->fifo_mode_sel == 1) {
331+
out->readings[count].timestamp_delta =
332+
(xl_count - 1) * accel_period_ns(edata->accel_odr,
333+
edata->accel_batch_odr);
334+
335+
if (!SENSOR_CHANNEL_IS_ACCEL(chan_spec.chan_type)) {
336+
buffer = frame_end;
337+
continue;
338+
}
339+
340+
x = (int16_t)buffer[1] + (int16_t)buffer[2] * 256;
341+
y = (int16_t)buffer[3] + (int16_t)buffer[4] * 256;
342+
z = (int16_t)buffer[5] + (int16_t)buffer[6] * 256;
343+
344+
out->shift = accel_range[header->range];
345+
346+
out->readings[count].x = Q31_SHIFT_MICROVAL(scale * x, out->shift);
347+
out->readings[count].y = Q31_SHIFT_MICROVAL(scale * y, out->shift);
348+
out->readings[count].z = Q31_SHIFT_MICROVAL(scale * z, out->shift);
349+
} else {
350+
if (!SENSOR_CHANNEL_IS_ACCEL(chan_spec.chan_type)
351+
#if defined(CONFIG_LIS2DUX12_ENABLE_TEMP)
352+
&& (chan_spec.chan_type != SENSOR_CHAN_DIE_TEMP)
353+
#endif
354+
) {
355+
buffer = frame_end;
356+
continue;
357+
}
358+
359+
if (SENSOR_CHANNEL_IS_ACCEL(chan_spec.chan_type)) {
360+
out->readings[count].timestamp_delta =
361+
(xl_count - 1) * accel_period_ns(edata->accel_odr,
362+
edata->accel_batch_odr);
363+
364+
x = (int16_t)buffer[1];
365+
x = (x + (int16_t)buffer[2] * 256) * 16;
366+
y = (int16_t)buffer[2] / 16;
367+
y = (y + ((int16_t)buffer[3] * 16)) * 16;
368+
z = (int16_t)buffer[4];
369+
z = (z + (int16_t)buffer[5] * 256) * 16;
370+
371+
out->shift = accel_range[header->range];
372+
373+
out->readings[count].x = Q31_SHIFT_MICROVAL(scale * x,
374+
out->shift);
375+
out->readings[count].y = Q31_SHIFT_MICROVAL(scale * y,
376+
out->shift);
377+
out->readings[count].z = Q31_SHIFT_MICROVAL(scale * z,
378+
out->shift);
379+
#if defined(CONFIG_LIS2DUX12_ENABLE_TEMP)
380+
} else {
381+
t_out->readings[count].timestamp_delta =
382+
(xl_count - 1) * accel_period_ns(edata->accel_odr,
383+
edata->accel_batch_odr);
384+
385+
t = ((int16_t)buffer[5] / 16 +
386+
(int16_t)buffer[6] * 16) * 16;
387+
388+
t_out->shift = temp_range;
389+
390+
/* transform temperature LSB into micro-Celsius */
391+
t_uC = SENSOR_TEMP_UCELSIUS(t);
392+
t_out->readings[count].temperature =
393+
Q31_SHIFT_MICROVAL(t_uC, t_out->shift);
394+
395+
#endif /* CONFIG_LIS2DUX12_ENABLE_TEMP */
396+
}
397+
}
398+
break;
399+
}
400+
297401
default:
298402
/* skip unhandled FIFO tag */
299403
buffer = frame_end;

drivers/sensor/st/lis2dux12/lis2dux12_decoder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,12 @@ struct lis2dux12_decoder_header {
2929
struct lis2dux12_fifo_data {
3030
struct lis2dux12_decoder_header header;
3131
uint32_t accel_odr: 4;
32+
uint32_t fifo_mode_sel: 2;
3233
uint32_t fifo_count: 7;
3334
uint32_t reserved_1: 5;
3435
uint32_t accel_batch_odr: 3;
3536
uint32_t ts_batch_odr: 2;
36-
uint32_t reserved: 11;
37+
uint32_t reserved: 9;
3738
} __attribute__((__packed__));
3839

3940
struct lis2dux12_rtio_data {

drivers/sensor/st/lis2dux12/lis2dux12_rtio_stream.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ static void lis2dux12_read_fifo_cb(struct rtio *r, const struct rtio_sqe *sqe, v
123123
{
124124
const struct device *dev = arg;
125125
struct lis2dux12_data *lis2dux12 = dev->data;
126+
const struct lis2dux12_config *cfg = dev->config;
126127
struct rtio *rtio = lis2dux12->rtio_ctx;
127128
struct gpio_dt_spec *irq_gpio = lis2dux12->drdy_gpio;
128129
struct rtio_iodev *iodev = lis2dux12->iodev;
@@ -228,6 +229,7 @@ static void lis2dux12_read_fifo_cb(struct rtio *r, const struct rtio_sqe *sqe, v
228229
rx_data->header.timestamp = lis2dux12->timestamp;
229230
rx_data->header.int_status = lis2dux12->fifo_status[0];
230231
rx_data->fifo_count = 0;
232+
rx_data->fifo_mode_sel = 0;
231233

232234
/* complete request with ok */
233235
rtio_iodev_sqe_ok(lis2dux12->streaming_sqe, 0);
@@ -281,6 +283,7 @@ static void lis2dux12_read_fifo_cb(struct rtio *r, const struct rtio_sqe *sqe, v
281283
.int_status = lis2dux12->fifo_status[0],
282284
},
283285
.fifo_count = fifo_count,
286+
.fifo_mode_sel = cfg->fifo_mode_sel,
284287
.accel_batch_odr = lis2dux12->accel_batch_odr,
285288
.accel_odr = lis2dux12->odr,
286289
};

drivers/sensor/st/lis2dux12/lis2duxs12_api.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ static void st_lis2duxs12_stream_config_fifo(const struct device *dev,
155155

156156
/* disable FIFO as first thing */
157157
fifo_mode.store = LIS2DUXS12_FIFO_1X;
158-
fifo_mode.xl_only = 1;
158+
fifo_mode.xl_only = 0;
159159
fifo_mode.watermark = 0;
160160
fifo_mode.operation = LIS2DUXS12_BYPASS_MODE;
161161
fifo_mode.batch.dec_ts = LIS2DUXS12_DEC_TS_OFF;
@@ -168,10 +168,32 @@ static void st_lis2duxs12_stream_config_fifo(const struct device *dev,
168168
pin_int.fifo_th = (trig_cfg.int_fifo_th) ? PROPERTY_ENABLE : PROPERTY_DISABLE;
169169
pin_int.fifo_full = (trig_cfg.int_fifo_full) ? PROPERTY_ENABLE : PROPERTY_DISABLE;
170170

171+
switch (config->fifo_mode_sel) {
172+
case 0:
173+
fifo_mode.store = LIS2DUXS12_FIFO_1X;
174+
fifo_mode.xl_only = 0;
175+
break;
176+
case 1:
177+
fifo_mode.store = LIS2DUXS12_FIFO_1X;
178+
fifo_mode.xl_only = 1;
179+
break;
180+
case 2:
181+
fifo_mode.store = LIS2DUXS12_FIFO_2X;
182+
fifo_mode.xl_only = 1;
183+
break;
184+
}
185+
171186
fifo_mode.operation = LIS2DUXS12_STREAM_MODE;
172187
fifo_mode.batch.dec_ts = config->ts_batch;
173188
fifo_mode.batch.bdr_xl = config->accel_batch;
174189
fifo_mode.watermark = config->fifo_wtm;
190+
191+
/* In case each FIFO word contains 2x accelerometer samples,
192+
* then watermark can be divided by two to match user expectation.
193+
*/
194+
if (config->fifo_mode_sel == 2) {
195+
fifo_mode.watermark /= 2;
196+
}
175197
}
176198

177199
/*

dts/bindings/sensor/st,lis2dux12-common.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,19 @@ properties:
9494
9595
enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
9696

97+
fifo-mode-sel:
98+
type: int
99+
default: 0x0
100+
description: |
101+
Specify the sample content to be batched in FIFO.
102+
Default is power-up configuration.
103+
104+
- 0x0 # 1x Accelerometer @12bit and 1x temperature @12bit samples
105+
- 0x1 # 1x Accelerometer @16bit sample
106+
- 0x2 # 2x Accelerometer @8bit samples (previous and current)
107+
108+
enum: [0x00, 0x01, 0x02]
109+
97110
fifo-watermark:
98111
type: int
99112
default: 32

0 commit comments

Comments
 (0)