2025-02-05 07:11 AM - edited 2025-02-05 07:19 AM
Dear Support
I want to add timestamp registration to the FIFO.
I already use FIFO to save gyroscope and accelerometer samples, but I'm struggling to add timestamps.
Since ODR is too high for polling mode the only solution is this one.
I attach some code snippets to make it clear, also consider them as pseudo code taken from a more complex structure.
ism330dlc_fifo_time_set and timer_rd are not present in the library but I wrote them based on the AN5125
int32_t ism330dlc_fifo_time_set(stmdev_ctx_t *ctx, uint8_t val) {
ism330dlc_fifo_ctrl2_t fifo_ctrl2;
int32_t ret;
ret = ism330dlc_read_reg(ctx, ISM330DLC_FIFO_CTRL2, (uint8_t *)&fifo_ctrl2,
1);
if (ret == 0) {
fifo_ctrl2.fifo_timer_en = val;
ret = ism330dlc_write_reg(ctx, ISM330DLC_FIFO_CTRL2,
(uint8_t *)&fifo_ctrl2, 1);
}
return ret;
}
uint64_t ism330dlc_timer_rd(stmdev_ctx_t *ctx) {
uint64_t time = 0;
uint8_t t0;
ism330dlc_read_reg(ctx, ISM330DLC_TIMESTAMP0_REG, (uint8_t *)&t0, 1);
time = t0;
ism330dlc_read_reg(ctx, ISM330DLC_TIMESTAMP1_REG, (uint8_t *)&t0, 1);
time |= uint64_t(t0 << 8);
ism330dlc_read_reg(ctx, ISM330DLC_TIMESTAMP2_REG, (uint8_t *)&t0, 1);
time |= uint64_t(t0 << 16);
return time * 25;
}
void start_routine() {
sens.freq = 104u;
pattern_len = 18;
ism330dlc_block_data_update_set(&ctx.Ctx, PROPERTY_ENABLE);
ism330dlc_int1_route_t int_1_reg{};
ism330dlc_pin_int1_route_get(&ctx.Ctx, &int_1_reg);
int_1_reg.int1_fth = PROPERTY_ENABLE;
ism330dlc_pin_int1_route_set(&ctx.Ctx, int_1_reg);
ism330dlc_fifo_watermark_set(&ctx.Ctx, sens.freq * pattern_len);
ISM330DLC_ACC_Enable(&ctx);
ISM330DLC_GYRO_Enable(&ctx);
ISM330DLC_ACC_SetOutputDataRate(&ctx, sens.freq);
ISM330DLC_GYRO_SetOutputDataRate(&ctx, sens.freq);
ism330dlc_fifo_dataset_4_batch_set(&ctx.Ctx, ISM330DLC_FIFO_DS4_NO_DEC);
ism330dlc_fifo_xl_batch_set(&ctx.Ctx, ISM330DLC_FIFO_XL_NO_DEC);
ism330dlc_fifo_gy_batch_set(&ctx.Ctx, ISM330DLC_FIFO_GY_NO_DEC);
ism330dlc_timestamp_res_set(&ctx.Ctx, ISM330DLC_LSB_25us);
// ism330dlc_timer_int_set(&ctx.Ctx, 1);
ism330dlc_timestamp_set(&ctx.Ctx, 1);
ism330dlc_fifo_time_set(&ctx.Ctx, 1);
ISM330DLC_FIFO_Set_ODR_Value(&ctx, sens.freq);
ism330dlc_fifo_mode_set(&ctx.Ctx, ISM330DLC_STREAM_MODE);
}
void loop(){
int16_t num;
ism330dlc_fifo_data_level_get(&ctx.Ctx, &num);
for (auto i = 0u; i < num; i++) {
uint16_t pat;
axis ax[3]{};
ism330dlc_fifo_pattern_get(&ctx.Ctx, &pat);
auto &v = ax[pat / 3].ax.i16bit[pat % 3];
ism330dlc_fifo_raw_data_get(&ctx.Ctx, (uint8_t *)&v, sizeof(v));
auto m = (pat < 3) ? sens.gy / 1000
: pat < 6 ? sens.axl / 1000
: 25;
auto e = su::stringify(float(v) * m, 2);
auto tm = ism330dlc_timer_rd(&ctx.Ctx);
slog::println("IMU", [&]() {
return su::stringify(tm) + " pat " + su::stringify(pat) + " " +
e;
}());
}
}
Notes:
- trying different ODRs makes the same results
- enabling/disabling BDU won't change anything
- Loop() is called in a task when the IRQ is triggered
Looking forward to hearing from you,
Best regards,
Andrea