1818#include <zephyr/logging/log.h>
1919LOG_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+
2187int 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