@@ -277,7 +277,7 @@ static uint32_t accel_period_ns[] = {
277
277
[ICM42688_DT_ACCEL_ODR_1_5625 ] = UINT32_C (10000000000000 ) / 15625 ,
278
278
[ICM42688_DT_ACCEL_ODR_3_125 ] = UINT32_C (10000000000000 ) / 31250 ,
279
279
[ICM42688_DT_ACCEL_ODR_6_25 ] = UINT32_C (10000000000000 ) / 62500 ,
280
- [ICM42688_DT_ACCEL_ODR_12_5 ] = UINT32_C (10000000000000 ) / 12500 ,
280
+ [ICM42688_DT_ACCEL_ODR_12_5 ] = UINT32_C (10000000000000 ) / 125000 ,
281
281
[ICM42688_DT_ACCEL_ODR_25 ] = UINT32_C (1000000000 ) / 25 ,
282
282
[ICM42688_DT_ACCEL_ODR_50 ] = UINT32_C (1000000000 ) / 50 ,
283
283
[ICM42688_DT_ACCEL_ODR_100 ] = UINT32_C (1000000000 ) / 100 ,
@@ -292,7 +292,7 @@ static uint32_t accel_period_ns[] = {
292
292
};
293
293
294
294
static uint32_t gyro_period_ns [] = {
295
- [ICM42688_DT_GYRO_ODR_12_5 ] = UINT32_C (10000000000000 ) / 12500 ,
295
+ [ICM42688_DT_GYRO_ODR_12_5 ] = UINT32_C (10000000000000 ) / 125000 ,
296
296
[ICM42688_DT_GYRO_ODR_25 ] = UINT32_C (1000000000 ) / 25 ,
297
297
[ICM42688_DT_GYRO_ODR_50 ] = UINT32_C (1000000000 ) / 50 ,
298
298
[ICM42688_DT_GYRO_ODR_100 ] = UINT32_C (1000000000 ) / 100 ,
@@ -306,6 +306,28 @@ static uint32_t gyro_period_ns[] = {
306
306
[ICM42688_DT_GYRO_ODR_32000 ] = UINT32_C (1000000 ) / 32 ,
307
307
};
308
308
309
+ static int icm42688_calc_timestamp_delta (int rtc_freq , int chan_type , int dt_odr , int frame_count ,
310
+ uint64_t * out_delta )
311
+ {
312
+ uint32_t period ;
313
+
314
+ if (IS_ACCEL (chan_type )) {
315
+ period = accel_period_ns [dt_odr ];
316
+ } else if (IS_GYRO (chan_type )) {
317
+ period = gyro_period_ns [dt_odr ];
318
+ } else {
319
+ return - EINVAL ;
320
+ }
321
+
322
+ /*
323
+ * When ODR is set to r and an external clock with frequency f is used,
324
+ * the actual ODR = f * r / 32000.
325
+ */
326
+ * out_delta = (uint64_t )period * frame_count * 32000 / rtc_freq ;
327
+
328
+ return 0 ;
329
+ }
330
+
309
331
static int icm42688_fifo_decode (const uint8_t * buffer , struct sensor_chan_spec chan_spec ,
310
332
uint32_t * fit , uint16_t max_count , void * data_out )
311
333
{
@@ -353,24 +375,42 @@ static int icm42688_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec c
353
375
354
376
data -> shift = 9 ;
355
377
if (has_accel ) {
356
- data -> readings [count ].timestamp_delta =
357
- accel_period_ns [edata -> accel_odr ] * (accel_frame_count - 1 );
378
+ rc = icm42688_calc_timestamp_delta (
379
+ edata -> rtc_freq , SENSOR_CHAN_ACCEL_XYZ , edata -> accel_odr ,
380
+ accel_frame_count - 1 ,
381
+ & data -> readings [count ].timestamp_delta );
382
+ if (rc < 0 ) {
383
+ buffer = frame_end ;
384
+ continue ;
385
+ }
358
386
} else {
359
- data -> readings [count ].timestamp_delta =
360
- gyro_period_ns [edata -> gyro_odr ] * (gyro_frame_count - 1 );
387
+ rc = icm42688_calc_timestamp_delta (
388
+ edata -> rtc_freq , SENSOR_CHAN_GYRO_XYZ , edata -> gyro_odr ,
389
+ gyro_frame_count - 1 ,
390
+ & data -> readings [count ].timestamp_delta );
391
+ if (rc < 0 ) {
392
+ buffer = frame_end ;
393
+ continue ;
394
+ }
361
395
}
362
396
data -> readings [count ].temperature =
363
397
icm42688_read_temperature_from_packet (buffer );
364
398
} else if (IS_ACCEL (chan_spec .chan_type ) && has_accel ) {
365
399
/* Decode accel */
366
400
struct sensor_three_axis_data * data =
367
401
(struct sensor_three_axis_data * )data_out ;
368
- uint64_t period_ns = accel_period_ns [edata -> accel_odr ];
369
402
370
403
icm42688_get_shift (SENSOR_CHAN_ACCEL_XYZ , edata -> header .accel_fs ,
371
404
edata -> header .gyro_fs , & data -> shift );
372
405
373
- data -> readings [count ].timestamp_delta = (accel_frame_count - 1 ) * period_ns ;
406
+ rc = icm42688_calc_timestamp_delta (edata -> rtc_freq , SENSOR_CHAN_ACCEL_XYZ ,
407
+ edata -> accel_odr , accel_frame_count - 1 ,
408
+ & data -> readings [count ].timestamp_delta );
409
+ if (rc < 0 ) {
410
+ buffer = frame_end ;
411
+ continue ;
412
+ }
413
+
374
414
rc = icm42688_read_imu_from_packet (buffer , true, edata -> header .accel_fs , 0 ,
375
415
& data -> readings [count ].x );
376
416
rc |= icm42688_read_imu_from_packet (buffer , true, edata -> header .accel_fs , 1 ,
@@ -386,12 +426,18 @@ static int icm42688_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec c
386
426
/* Decode gyro */
387
427
struct sensor_three_axis_data * data =
388
428
(struct sensor_three_axis_data * )data_out ;
389
- uint64_t period_ns = gyro_period_ns [edata -> gyro_odr ];
390
429
391
430
icm42688_get_shift (SENSOR_CHAN_GYRO_XYZ , edata -> header .accel_fs ,
392
431
edata -> header .gyro_fs , & data -> shift );
393
432
394
- data -> readings [count ].timestamp_delta = (gyro_frame_count - 1 ) * period_ns ;
433
+ rc = icm42688_calc_timestamp_delta (edata -> rtc_freq , SENSOR_CHAN_GYRO_XYZ ,
434
+ edata -> gyro_odr , gyro_frame_count - 1 ,
435
+ & data -> readings [count ].timestamp_delta );
436
+ if (rc < 0 ) {
437
+ buffer = frame_end ;
438
+ continue ;
439
+ }
440
+
395
441
rc = icm42688_read_imu_from_packet (buffer , false, edata -> header .gyro_fs , 0 ,
396
442
& data -> readings [count ].x );
397
443
rc |= icm42688_read_imu_from_packet (buffer , false, edata -> header .gyro_fs , 1 ,
0 commit comments