Skip to content

Commit e5b8ec9

Browse files
sensor: tdk: Additional dt options for icm4268x
Add Filters for Accelerometer and Gyroscope and other dt options Signed-off-by: Sumit Batra <[email protected]>
1 parent aebff49 commit e5b8ec9

File tree

9 files changed

+827
-6
lines changed

9 files changed

+827
-6
lines changed

boards/tdk/robokit1/robokit1-common.dtsi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,11 @@
108108
accel-pwr-mode = <ICM4268X_DT_ACCEL_LN>;
109109
accel-odr = <ICM4268X_DT_ACCEL_ODR_2000>;
110110
accel-fs = <ICM42688_DT_ACCEL_FS_16>;
111+
accel-aaf-bw = <ICM4268X_DT_ACCEL_AAF_585HZ>;
111112
gyro-pwr-mode = <ICM4268X_DT_GYRO_LN>;
112113
gyro-odr = <ICM4268X_DT_GYRO_ODR_2000>;
113114
gyro-fs = <ICM42688_DT_GYRO_FS_2000>;
115+
gyro-aaf-bw = <ICM4268X_DT_GYRO_AAF_585HZ>;
114116
};
115117
spi_adc: adc@1 {
116118
compatible = "ti,ads7052";

drivers/sensor/tdk/icm4268x/icm4268x.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,13 +330,25 @@ void icm4268x_unlock(const struct device *dev)
330330
.accel_pwr_mode = DT_INST_PROP(inst, accel_pwr_mode), \
331331
.accel_fs = DT_INST_PROP(inst, accel_fs), \
332332
.accel_odr = DT_INST_PROP(inst, accel_odr), \
333+
.aaf_cfg[AAF_ACCEL_IDX].aaf_delt = DT_INST_PROP(inst, accel_aaf_bw), \
334+
.aaf_cfg[AAF_GYRO_IDX].aaf_delt = DT_INST_PROP(inst, gyro_aaf_bw), \
333335
.gyro_pwr_mode = DT_INST_PROP(inst, gyro_pwr_mode), \
334336
.gyro_fs = DT_INST_PROP(inst, gyro_fs), \
335337
.gyro_odr = DT_INST_PROP(inst, gyro_odr), \
336338
.temp_dis = false, \
337339
.fifo_en = IS_ENABLED(CONFIG_ICM4268X_STREAM), \
340+
.tmst_dis = DT_INST_PROP(inst, tmst_dis), \
341+
.tmst_fsync_en = DT_INST_PROP(inst, tmst_fsync_en), \
342+
.tmst_delta_en = DT_INST_PROP(inst, tmst_delta_en), \
343+
.tmst_res = DT_INST_PROP(inst, tmst_res), \
344+
.tmst_regs_en = DT_INST_PROP(inst, tmst_regs_en), \
345+
.fifo_mode = DT_INST_PROP(inst, fifo_mode), \
346+
.fifo_ths_int_clr = DT_INST_PROP(inst, fifo_ths_int_clr), \
347+
.fifo_full_int_clr = DT_INST_PROP(inst, fifo_full_int_clr), \
338348
.batch_ticks = 0, \
339349
.fifo_hires = false, \
350+
.int1_mode = DT_INST_PROP(inst, int1_mode), \
351+
.int1_pol = DT_INST_PROP(inst, int1_pol), \
340352
.interrupt1_drdy = false, \
341353
.interrupt1_fifo_ths = false, \
342354
.interrupt1_fifo_full = false \

drivers/sensor/tdk/icm4268x/icm4268x.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@
1515
#include <zephyr/dt-bindings/sensor/icm4268x.h>
1616
#include <stdlib.h>
1717

18+
/* ICM4268x parts support 63 AAF Bandwidths */
19+
#define AAF_BW_MAX_IDX 63
20+
21+
/* AAF is for 2 sensors Accel & Gyro */
22+
#define AAF_SENSORS_NUM 2
23+
#define AAF_ACCEL_IDX 0
24+
#define AAF_GYRO_IDX 1
25+
1826
static inline uint8_t icm42686_accel_fs_to_reg(uint8_t g)
1927
{
2028
if (g >= 32) {
@@ -371,6 +379,12 @@ static inline void icm4268x_gyro_reg_to_odr(uint8_t odr, struct sensor_value *ou
371379
/**
372380
* @brief All sensor configuration options
373381
*/
382+
struct icm4268x_aaf_cfg {
383+
uint8_t aaf_delt;
384+
uint16_t aaf_deltsqr;
385+
uint8_t aaf_bitshift;
386+
};
387+
374388
struct icm4268x_cfg {
375389
uint16_t dev_id;
376390
uint8_t accel_pwr_mode;
@@ -383,17 +397,30 @@ struct icm4268x_cfg {
383397
uint8_t gyro_odr;
384398
/* TODO gyro signal processing options */
385399

400+
/* AAF cfg for accel and gyro */
401+
struct icm4268x_aaf_cfg aaf_cfg[AAF_SENSORS_NUM];
402+
386403
bool temp_dis;
387404
/* TODO temp signal processing options */
388405

389406
/* TODO timestamp options */
407+
bool tmst_dis;
408+
bool tmst_fsync_en;
409+
bool tmst_delta_en;
410+
bool tmst_res;
411+
bool tmst_regs_en;
390412

391413
bool fifo_en;
414+
uint8_t fifo_mode;
415+
uint8_t fifo_ths_int_clr;
416+
uint8_t fifo_full_int_clr;
392417
int32_t batch_ticks;
393418
bool fifo_hires;
394419
/* TODO additional FIFO options */
395420

396421
/* TODO interrupt options */
422+
bool int1_mode;
423+
bool int1_pol;
397424
bool interrupt1_drdy;
398425
bool interrupt1_fifo_ths;
399426
bool interrupt1_fifo_full;

drivers/sensor/tdk/icm4268x/icm4268x_common.c

Lines changed: 224 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,72 @@
1818
#include <zephyr/logging/log.h>
1919
LOG_MODULE_REGISTER(ICM4268X_LL, CONFIG_SENSOR_LOG_LEVEL);
2020

21+
static struct icm4268x_aaf_cfg aaf_cfg_tbl[AAF_BW_MAX_IDX] = {
22+
{1, 1, 15},
23+
{2, 4, 13},
24+
{3, 9, 12},
25+
{4, 16, 11},
26+
{5, 25, 10},
27+
{6, 36, 10},
28+
{7, 49, 9},
29+
{8, 64, 9},
30+
{9, 81, 9},
31+
{10, 100, 8},
32+
{11, 122, 8},
33+
{12, 144, 8},
34+
{13, 170, 8},
35+
{14, 196, 7},
36+
{15, 224, 7},
37+
{16, 256, 7},
38+
{17, 288, 7},
39+
{18, 324, 7},
40+
{19, 360, 6},
41+
{20, 400, 6},
42+
{21, 440, 6},
43+
{22, 488, 6},
44+
{23, 528, 6},
45+
{24, 576, 6},
46+
{25, 624, 6},
47+
{26, 680, 6},
48+
{27, 736, 5},
49+
{28, 784, 5},
50+
{29, 848, 5},
51+
{30, 896, 5},
52+
{31, 960, 5},
53+
{32, 1024, 5},
54+
{33, 1088, 5},
55+
{34, 1152, 5},
56+
{35, 1232, 5},
57+
{36, 1296, 5},
58+
{37, 1376, 4},
59+
{38, 1440, 4},
60+
{39, 1536, 4},
61+
{40, 1600, 4},
62+
{41, 1696, 4},
63+
{42, 1760, 4},
64+
{43, 1856, 4},
65+
{44, 1952, 4},
66+
{45, 2016, 4},
67+
{46, 2112, 4},
68+
{47, 2208, 4},
69+
{48, 2304, 4},
70+
{49, 2400, 4},
71+
{50, 2496, 4},
72+
{51, 2592, 4},
73+
{52, 2720, 4},
74+
{53, 2816, 3},
75+
{54, 2944, 3},
76+
{55, 3008, 3},
77+
{56, 3136, 3},
78+
{57, 3264, 3},
79+
{58, 3392, 3},
80+
{59, 3456, 3},
81+
{60, 3584, 3},
82+
{61, 3712, 3},
83+
{62, 3840, 3},
84+
{63, 3968, 3}
85+
};
86+
2187
int icm4268x_reset(const struct device *dev)
2288
{
2389
int res;
@@ -150,7 +216,6 @@ int icm4268x_configure(const struct device *dev, struct icm4268x_cfg *cfg)
150216
}
151217

152218
/* TODO maybe do the next few steps intelligently by checking current config */
153-
154219
/* Power management to set gyro/accel modes */
155220
uint8_t pwr_mgmt0 = FIELD_PREP(MASK_GYRO_MODE, cfg->gyro_pwr_mode) |
156221
FIELD_PREP(MASK_ACCEL_MODE, cfg->accel_pwr_mode) |
@@ -189,6 +254,93 @@ int icm4268x_configure(const struct device *dev, struct icm4268x_cfg *cfg)
189254
return -EINVAL;
190255
}
191256

257+
res = icm4268x_spi_single_write(&dev_cfg->spi, REG_GYRO_CONFIG1, 0);
258+
if (res != 0) {
259+
LOG_ERR("Error writing GYRO_CONFIG1");
260+
return -EINVAL;
261+
}
262+
263+
res = icm4268x_spi_single_write(&dev_cfg->spi, REG_GYRO_ACCEL_CONFIG0, 0);
264+
if (res != 0) {
265+
LOG_ERR("Error writing GYRO_ACCEL_CONFIG0");
266+
return -EINVAL;
267+
}
268+
269+
res = icm4268x_spi_single_write(&dev_cfg->spi, REG_ACCEL_CONFIG1, 0);
270+
if (res != 0) {
271+
LOG_ERR("Error writing ACCEL_CONFIG1");
272+
return -EINVAL;
273+
}
274+
275+
/* Accelerometer AAF Configuration */
276+
uint8_t aaf_tbl_idx = ((cfg->aaf_cfg[AAF_ACCEL_IDX].aaf_delt) - 1);
277+
278+
uint8_t aaf_cfg_static2 =
279+
((cfg->aaf_cfg[AAF_ACCEL_IDX].aaf_delt << 1) & MASK_ACCEL_AAF_DELT);
280+
281+
LOG_DBG("ACCEL_CONFIG_STATIC2 (0x%x) 0x%x", ACCEL_CONFIG_STATIC2, aaf_cfg_static2);
282+
res = icm4268x_spi_single_write(&dev_cfg->spi, ACCEL_CONFIG_STATIC2, aaf_cfg_static2);
283+
if (res != 0) {
284+
LOG_ERR("Error writing ACCEL_CONFIG_STATIC2");
285+
return -EINVAL;
286+
}
287+
288+
uint8_t aaf_deltsqr_lsb =
289+
(aaf_cfg_tbl[aaf_tbl_idx].aaf_deltsqr) & MASK_ACCEL_AAF_DELTSQR_LSB;
290+
291+
LOG_DBG("ACCEL_CONFIG_STATIC3 (0x%x) 0x%x", ACCEL_CONFIG_STATIC3, aaf_deltsqr_lsb);
292+
res = icm4268x_spi_single_write(&dev_cfg->spi, ACCEL_CONFIG_STATIC3, aaf_deltsqr_lsb);
293+
if (res != 0) {
294+
LOG_ERR("Error writing ACCEL_CONFIG_STATIC3");
295+
return -EINVAL;
296+
}
297+
298+
uint8_t aaf_deltsqr_msb =
299+
((aaf_cfg_tbl[aaf_tbl_idx].aaf_deltsqr) >> 0x8) & MASK_ACCEL_AAF_DELTSQR_MSB;
300+
uint8_t aaf_bitshift =
301+
((aaf_cfg_tbl[aaf_tbl_idx].aaf_bitshift) << 0x4) & MASK_ACCEL_AAF_BITSHIFT;
302+
uint8_t aaf_cfg_static4 = (aaf_bitshift | aaf_deltsqr_msb);
303+
304+
LOG_DBG("ACCEL_CONFIG_STATIC4 (0x%x) 0x%x", ACCEL_CONFIG_STATIC4, aaf_cfg_static4);
305+
res = icm4268x_spi_single_write(&dev_cfg->spi, ACCEL_CONFIG_STATIC4, aaf_cfg_static4);
306+
if (res != 0) {
307+
LOG_ERR("Error writing ACCEL_CONFIG_STATIC4");
308+
return -EINVAL;
309+
}
310+
311+
/* Gyroscope AAF Configuration */
312+
aaf_tbl_idx = ((cfg->aaf_cfg[AAF_GYRO_IDX].aaf_delt) - 1);
313+
314+
uint8_t aaf_cfg_static3 = ((cfg->aaf_cfg[AAF_GYRO_IDX].aaf_delt << 1) & MASK_GYRO_AAF_DELT);
315+
316+
LOG_DBG("GYRO_CONFIG_STATIC3 (0x%x) 0x%x", GYRO_CONFIG_STATIC3, aaf_cfg_static3);
317+
res = icm4268x_spi_single_write(&dev_cfg->spi, GYRO_CONFIG_STATIC3, aaf_cfg_static3);
318+
if (res != 0) {
319+
LOG_ERR("Error writing GYRO_CONFIG_STATIC3");
320+
return -EINVAL;
321+
}
322+
323+
aaf_deltsqr_lsb = (aaf_cfg_tbl[aaf_tbl_idx].aaf_deltsqr) & MASK_GYRO_AAF_DELTSQR_LSB;
324+
325+
LOG_DBG("GYRO_CONFIG_STATIC4 (0x%x) 0x%x", GYRO_CONFIG_STATIC4, aaf_deltsqr_lsb);
326+
res = icm4268x_spi_single_write(&dev_cfg->spi, GYRO_CONFIG_STATIC4, aaf_deltsqr_lsb);
327+
if (res != 0) {
328+
LOG_ERR("Error writing GYRO_CONFIG_STATIC4");
329+
return -EINVAL;
330+
}
331+
332+
aaf_deltsqr_msb =
333+
((aaf_cfg_tbl[aaf_tbl_idx].aaf_deltsqr) >> 0x8) & MASK_GYRO_AAF_DELTSQR_MSB;
334+
aaf_bitshift = ((aaf_cfg_tbl[aaf_tbl_idx].aaf_bitshift) << 0x4) & MASK_GYRO_AAF_BITSHIFT;
335+
uint8_t aaf_cfg_static5 = (aaf_bitshift | aaf_deltsqr_msb);
336+
337+
LOG_DBG("GYRO_CONFIG_STATIC5 (0x%x) 0x%x", GYRO_CONFIG_STATIC5, aaf_cfg_static5);
338+
res = icm4268x_spi_single_write(&dev_cfg->spi, GYRO_CONFIG_STATIC5, aaf_cfg_static5);
339+
if (res != 0) {
340+
LOG_ERR("Error writing GYRO_CONFIG_STATIC5");
341+
return -EINVAL;
342+
}
343+
192344
/*
193345
* Accelerometer sensor need at least 10ms startup time
194346
* Gyroscope sensor need at least 30ms startup time
@@ -199,6 +351,7 @@ int icm4268x_configure(const struct device *dev, struct icm4268x_cfg *cfg)
199351
uint8_t fifo_config_bypass = FIELD_PREP(MASK_FIFO_MODE, BIT_FIFO_MODE_BYPASS);
200352

201353
LOG_DBG("FIFO_CONFIG (0x%x) 0x%x", REG_FIFO_CONFIG, fifo_config_bypass);
354+
202355
res = icm4268x_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG, fifo_config_bypass);
203356
if (res != 0) {
204357
LOG_ERR("Error writing FIFO_CONFIG");
@@ -218,19 +371,57 @@ int icm4268x_configure(const struct device *dev, struct icm4268x_cfg *cfg)
218371
LOG_ERR("Error reading TMST_CONFIG");
219372
return -EINVAL;
220373
}
374+
375+
tmst_config |= (cfg->tmst_dis ? 0 : BIT_TMST_EN);
376+
tmst_config |= (cfg->tmst_fsync_en ? BIT_TMST_FSYNC_EN : 0);
377+
tmst_config |= (cfg->tmst_delta_en ? BIT_TMST_DELTA_EN : 0);
378+
tmst_config |= (cfg->tmst_res ? BIT_TMST_RES : 0);
379+
tmst_config |= (cfg->tmst_regs_en ? BIT_TMST_TO_REGS_EN : 0);
380+
221381
res = icm4268x_spi_single_write(&dev_cfg->spi, REG_TMST_CONFIG, tmst_config & ~BIT(1));
222382
if (res != 0) {
223383
LOG_ERR("Error writing TMST_CONFIG");
224384
return -EINVAL;
225385
}
226386

227-
/* Pulse mode with async reset (resets interrupt line on int status read) */
387+
/* Interface Configuration */
388+
uint8_t intf_config0 = FIELD_PREP(MASK_UI_SIFS_CFG, BIT_UI_SIFS_CFG_DISABLE_I2C)
389+
| BIT_SENSOR_DATA_ENDIAN | BIT_FIFO_COUNT_ENDIAN;
390+
391+
res = icm4268x_spi_single_write(&dev_cfg->spi, REG_INTF_CONFIG0, intf_config0);
392+
if (res != 0) {
393+
LOG_ERR("Error writing INTF_CONFIG0");
394+
return -EINVAL;
395+
}
396+
397+
uint8_t intf_config1;
398+
399+
res = icm4268x_spi_read(&dev_cfg->spi, REG_INTF_CONFIG1, &intf_config1, 1);
400+
if (res != 0) {
401+
LOG_ERR("Error reading INTF_CONFIG1");
402+
return -EINVAL;
403+
}
404+
405+
/* Disable Adaptive Full Scale Range Mode */
406+
intf_config1 = BIT_AFSR_SET | (intf_config1 & 0x1F);
407+
408+
res = icm4268x_spi_single_write(&dev_cfg->spi, REG_INTF_CONFIG1, intf_config1);
409+
if (res != 0) {
410+
LOG_ERR("Error writing INTF_CONFIG1");
411+
return -EINVAL;
412+
}
413+
414+
/* Select the interrupt mode */
228415
if (IS_ENABLED(CONFIG_ICM4268X_TRIGGER)) {
229416
res = icm4268x_trigger_enable_interrupt(dev, cfg);
230417
} else {
418+
uint8_t int1_pol = (cfg->int1_pol ? BIT_INT1_POLARITY:0);
419+
231420
res = icm4268x_spi_single_write(&dev_cfg->spi, REG_INT_CONFIG,
232-
BIT_INT1_DRIVE_CIRCUIT | BIT_INT1_POLARITY);
421+
BIT_INT1_DRIVE_CIRCUIT | int1_pol
422+
| (cfg->int1_mode ? BIT_INT1_MODE : 0));
233423
}
424+
234425
if (res) {
235426
LOG_ERR("Error writing to INT_CONFIG");
236427
return res;
@@ -257,9 +448,16 @@ int icm4268x_configure(const struct device *dev, struct icm4268x_cfg *cfg)
257448
/* Setup desired FIFO packet fields based on the other
258449
* temp/accel/gyro en fields in cfg
259450
*/
451+
/* FSYNC is not used in this driver so as per 14.45 its is not
452+
* mandatory to set it to 1.
453+
*/
454+
/* Enabling watermark interrupt based on REG_INT_SOURCE0
455+
* Enabling High Resolution for better accuracy
456+
*/
260457
uint8_t fifo_cfg1 =
261458
FIELD_PREP(BIT_FIFO_TEMP_EN, 1) | FIELD_PREP(BIT_FIFO_GYRO_EN, 1) |
262-
FIELD_PREP(BIT_FIFO_ACCEL_EN, 1) | FIELD_PREP(BIT_FIFO_TMST_FSYN, 1);
459+
FIELD_PREP(BIT_FIFO_ACCEL_EN, 1) | FIELD_PREP(BIT_FIFO_HIRES_EN, 1) |
460+
FIELD_PREP(BIT_FIFO_WM_GT_TH, 1);
263461

264462
LOG_DBG("FIFO_CONFIG1 (0x%x) 0x%x", REG_FIFO_CONFIG1, fifo_cfg1);
265463
res = icm4268x_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG1, fifo_cfg1);
@@ -289,11 +487,31 @@ int icm4268x_configure(const struct device *dev, struct icm4268x_cfg *cfg)
289487
}
290488

291489
/* Begin streaming */
292-
uint8_t fifo_config = FIELD_PREP(MASK_FIFO_MODE, BIT_FIFO_MODE_STREAM);
490+
uint8_t fifo_config = FIELD_PREP(MASK_FIFO_MODE, cfg->fifo_mode);
491+
492+
LOG_DBG("FIFO_CONFIG (0x%x) 0x%x", REG_FIFO_CONFIG, fifo_config);
293493

294-
LOG_DBG("FIFO_CONFIG (0x%x) 0x%x", REG_FIFO_CONFIG, 1 << 6);
295494
res = icm4268x_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG, fifo_config);
296495

496+
if (res != 0) {
497+
LOG_ERR("Error writing FIFO_CONFIG");
498+
return -EINVAL;
499+
}
500+
501+
/* Select the condition to clear the interrupt line in latched mode */
502+
if (cfg->int1_mode == ICM4268X_DT_INT1_MODE_LATCHED) {
503+
uint8_t int_config0;
504+
505+
int_config0 = FIELD_PREP(MASK_FIFO_FULL_INT_CLR, cfg->fifo_full_int_clr)
506+
| FIELD_PREP(MASK_FIFO_THS_INT_CLEAR, cfg->fifo_ths_int_clr);
507+
508+
res = icm4268x_spi_single_write(&dev_cfg->spi, REG_INT_CONFIG0,
509+
int_config0);
510+
if (res != 0) {
511+
LOG_ERR("Error writing INT_CONFIG0");
512+
return -EINVAL;
513+
}
514+
}
297515
/* Config interrupt source to only be fifo wm/full */
298516
uint8_t int_source0 = BIT_FIFO_FULL_INT1_EN | BIT_FIFO_THS_INT1_EN;
299517

0 commit comments

Comments
 (0)