Skip to content

Commit e399c16

Browse files
bperseghettijgoppert
authored andcommitted
sensor: icm42688: Fix broken build and streaming.
Makes driver actually build again. Fixes scaling, q32 encoding, bit shifts, and register mappings. Also enables High Resolution mode (a unique and beneficial feature of the chip when used with streaming). Co-authored-by: James Goppert <[email protected]> Signed-off-by: Benjamin Perseghetti <[email protected]>
1 parent 51661ef commit e399c16

File tree

4 files changed

+27
-72
lines changed

4 files changed

+27
-72
lines changed

drivers/sensor/tdk/icm42688/icm42688_common.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,11 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg)
255255
* temp/accel/gyro en fields in cfg
256256
*/
257257
uint8_t fifo_cfg1 =
258-
FIELD_PREP(BIT_FIFO_TEMP_EN, 1) | FIELD_PREP(BIT_FIFO_GYRO_EN, 1) |
259-
FIELD_PREP(BIT_FIFO_ACCEL_EN, 1) | FIELD_PREP(BIT_FIFO_TMST_FSYNC_EN, 1);
258+
FIELD_PREP(BIT_FIFO_TEMP_EN, 1) |
259+
FIELD_PREP(BIT_FIFO_GYRO_EN, 1) |
260+
FIELD_PREP(BIT_FIFO_ACCEL_EN, 1) |
261+
FIELD_PREP(BIT_FIFO_TMST_FSYNC_EN, 1) |
262+
FIELD_PREP(BIT_FIFO_HIRES_EN, 1);
260263

261264
LOG_DBG("FIFO_CONFIG1 (0x%x) 0x%x", REG_FIFO_CONFIG1, fifo_cfg1);
262265
res = icm42688_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG1, fifo_cfg1);

drivers/sensor/tdk/icm42688/icm42688_decoder.c

Lines changed: 17 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -243,81 +243,33 @@ static inline q31_t icm42688_read_temperature_from_packet(const uint8_t *pkt)
243243
static int icm42688_read_imu_from_packet(const uint8_t *pkt, bool is_accel, int fs,
244244
uint8_t axis_offset, q31_t *out)
245245
{
246-
int32_t value;
247-
int64_t scale = 0;
248-
int32_t max = BIT(15);
246+
uint32_t unsigned_value;
247+
int32_t signed_value;
248+
bool is_hires = FIELD_GET(FIFO_HEADER_ACCEL, pkt[0]) == 1;
249249
int offset = 1 + (axis_offset * 2);
250250

251-
if (is_accel) {
252-
switch (fs) {
253-
case ICM42688_DT_ACCEL_FS_2:
254-
scale = INT64_C(2) * BIT(31 - 5) * 9.80665;
255-
break;
256-
case ICM42688_DT_ACCEL_FS_4:
257-
scale = INT64_C(4) * BIT(31 - 6) * 9.80665;
258-
break;
259-
case ICM42688_DT_ACCEL_FS_8:
260-
scale = INT64_C(8) * BIT(31 - 7) * 9.80665;
261-
break;
262-
case ICM42688_DT_ACCEL_FS_16:
263-
scale = INT64_C(16) * BIT(31 - 8) * 9.80665;
264-
break;
265-
}
266-
} else {
267-
switch (fs) {
268-
case ICM42688_DT_GYRO_FS_2000:
269-
scale = 164;
270-
break;
271-
case ICM42688_DT_GYRO_FS_1000:
272-
scale = 328;
273-
break;
274-
case ICM42688_DT_GYRO_FS_500:
275-
scale = 655;
276-
break;
277-
case ICM42688_DT_GYRO_FS_250:
278-
scale = 1310;
279-
break;
280-
case ICM42688_DT_GYRO_FS_125:
281-
scale = 2620;
282-
break;
283-
case ICM42688_DT_GYRO_FS_62_5:
284-
scale = 5243;
285-
break;
286-
case ICM42688_DT_GYRO_FS_31_25:
287-
scale = 10486;
288-
break;
289-
case ICM42688_DT_GYRO_FS_15_625:
290-
scale = 20972;
291-
break;
292-
}
293-
}
251+
const uint32_t scale[2][2] = {
252+
/* low-res, hi-res */
253+
{35744, 8936}, /* gyro */
254+
{40168, 2511}, /* accel */
255+
};
294256

295257
if (!is_accel && FIELD_GET(FIFO_HEADER_ACCEL, pkt[0]) == 1) {
296-
offset += 7;
258+
offset += 6;
297259
}
298260

299-
value = (int16_t)sys_le16_to_cpu((pkt[offset] << 8) | pkt[offset + 1]);
261+
unsigned_value = (pkt[offset] << 8) | pkt[offset + 1];
300262

301-
if (FIELD_GET(FIFO_HEADER_20, pkt[0]) == 1) {
263+
if (is_hires) {
302264
uint32_t mask = is_accel ? GENMASK(7, 4) : GENMASK(3, 0);
303-
304-
offset = 0x11 + axis_offset;
305-
value = (value << 4) | FIELD_GET(mask, pkt[offset]);
306-
/* In 20 bit mode, FS can only be +/-16g and +/-2000dps */
307-
scale = is_accel ? (INT64_C(16) * BIT(8) * 9.80665) : 131;
308-
max = is_accel ? BIT(18) : BIT(19);
309-
if (value == -524288) {
310-
/* Invalid 20 bit value */
311-
return -ENODATA;
312-
}
265+
offset = 17 + axis_offset;
266+
unsigned_value = (unsigned_value << 4) | FIELD_GET(mask, pkt[offset]);
267+
signed_value = unsigned_value | (0 - (unsigned_value & BIT(19)));
313268
} else {
314-
if (value <= -32767) {
315-
/* Invalid 16 bit value */
316-
return -ENODATA;
317-
}
269+
signed_value = unsigned_value | (0 - (unsigned_value & BIT(16)));
318270
}
319271

320-
*out = (q31_t)(value * scale / max);
272+
*out = (q31_t)(signed_value * scale[is_accel][is_hires]);
321273
return 0;
322274
}
323275

@@ -434,7 +386,7 @@ static int icm42688_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec c
434386
/* Decode gyro */
435387
struct sensor_three_axis_data *data =
436388
(struct sensor_three_axis_data *)data_out;
437-
uint64_t period_ns = accel_period_ns[edata->gyro_odr];
389+
uint64_t period_ns = gyro_period_ns[edata->gyro_odr];
438390

439391
icm42688_get_shift(SENSOR_CHAN_GYRO_XYZ, edata->header.accel_fs,
440392
edata->header.gyro_fs, &data->shift);

drivers/sensor/tdk/icm42688/icm42688_reg.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,9 @@
254254
#define BIT_FIFO_WM_GT_TH BIT(5)
255255
#define BIT_FIFO_HIRES_EN BIT(4)
256256
#define BIT_FIFO_TMST_FSYNC_EN BIT(3)
257-
#define BIT_FIFO_GYRO_EN BIT(2)
258-
#define BIT_FIFO_ACCEL_EN BIT(1)
259-
#define BIT_FIFO_TEMP_EN BIT(0)
257+
#define BIT_FIFO_TEMP_EN BIT(2)
258+
#define BIT_FIFO_GYRO_EN BIT(1)
259+
#define BIT_FIFO_ACCEL_EN BIT(0)
260260

261261
/* Bank0 INT_SOURCE0 */
262262
#define BIT_UI_FSYNC_INT1_EN BIT(6)

drivers/sensor/tdk/icm42688/icm42688_rtio_stream.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ static void icm42688_fifo_count_cb(struct rtio *r, const struct rtio_sqe *sqe, v
130130
read_len = pkts * packet_size;
131131
((struct icm42688_fifo_data *)buf)->fifo_count = read_len;
132132

133-
__ASSERT_NO_MSG(read_len % pkt_size == 0);
133+
__ASSERT_NO_MSG(read_len % packet_size == 0);
134134

135135
uint8_t *read_buf = buf + sizeof(hdr);
136136

@@ -302,7 +302,7 @@ void icm42688_fifo_event(const struct device *dev)
302302
rc = sensor_clock_get_cycles(&cycles);
303303
if (rc != 0) {
304304
LOG_ERR("Failed to get sensor clock cycles");
305-
rtio_iodev_sqe_err(drv_data->streaming_sqe, err);
305+
rtio_iodev_sqe_err(drv_data->streaming_sqe, rc);
306306
return;
307307
}
308308

0 commit comments

Comments
 (0)