@@ -439,6 +439,148 @@ int icm45_ext_passthrough(bool passthrough)
439439 return 0 ;
440440}
441441
442+ int icm45_ext_setup () {
443+ int err = 0 ;
444+ err |= ssi_reg_write_byte (SENSOR_INTERFACE_DEV_IMU , ICM45686_IOC_PAD_SCENARIO_AUX_OVRD , 0x17 ); // AUX1_MODE_OVRD, AUX1 in I2CM Master, AUX1_ENABLE_OVRD, AUX1 enabled
445+ sensor_interface_ext_configure (& sensor_ext_icm45686 );
446+ return err ;
447+ }
448+
449+ int icm45_bank_write (const uint8_t bank , const uint8_t reg , const uint8_t * buf , uint32_t num_bytes )
450+ {
451+ if (num_bytes == 0 )
452+ {
453+ LOG_ERR ("Invalid bank write size" );
454+ return -1 ;
455+ }
456+
457+ int err = 0 ;
458+ uint8_t ireg_buf [3 ];
459+ ireg_buf [0 ] = bank ;
460+ ireg_buf [1 ] = reg ;
461+ ireg_buf [2 ] = buf [0 ];
462+ err |= ssi_burst_write (SENSOR_INTERFACE_DEV_IMU , ICM45686_IREG_ADDR_15_8 , ireg_buf , 3 );
463+ k_usleep (4 );
464+
465+ for (uint32_t i = 1 ; i < num_bytes ; i ++ )
466+ {
467+ err |= ssi_reg_write_byte (SENSOR_INTERFACE_DEV_IMU , ICM45686_IREG_DATA , buf [i ]);
468+ k_usleep (4 );
469+ }
470+
471+ return err ;
472+ }
473+
474+ int icm45_bank_write_byte (const uint8_t bank , const uint8_t reg , const uint8_t value )
475+ {
476+ return icm45_bank_write (bank , reg , & value , 1 );
477+ }
478+
479+ int icm45_bank_read (const uint8_t bank , const uint8_t reg , uint8_t * buf , uint32_t num_bytes )
480+ {
481+ if (num_bytes == 0 )
482+ {
483+ LOG_ERR ("Invalid bank read size" );
484+ return -1 ;
485+ }
486+
487+ int err = 0 ;
488+ uint8_t ireg_buf [2 ];
489+ ireg_buf [0 ] = bank ;
490+ ireg_buf [1 ] = reg ;
491+ err |= ssi_burst_write (SENSOR_INTERFACE_DEV_IMU , ICM45686_IREG_ADDR_15_8 , ireg_buf , 2 );
492+ k_usleep (4 );
493+
494+ for (uint32_t i = 0 ; i < num_bytes ; i ++ )
495+ {
496+ err |= ssi_reg_read_byte (SENSOR_INTERFACE_DEV_IMU , ICM45686_IREG_DATA , & buf [i ]);
497+ k_usleep (4 );
498+ }
499+ return err ;
500+ }
501+
502+ int icm45_bank_read_byte (const uint8_t bank , const uint8_t reg , uint8_t * value ) {
503+ return icm45_bank_read (bank , reg , value , 1 );
504+ }
505+
506+ int icm45_ext_write (const uint8_t addr , const uint8_t * buf , uint32_t num_bytes )
507+ {
508+ if (num_bytes > 6 )
509+ {
510+ LOG_ERR ("Unsupported write" );
511+ return -1 ;
512+ }
513+
514+ int err = 0 ;
515+
516+ err |= icm45_bank_write (ICM45686_IPREG_TOP1 , ICM45686_I2CM_WR_DATA_0 , buf , num_bytes );
517+ err |= icm45_bank_write_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_COMMAND_0 , 0x80 + num_bytes ); // Last transaction, channel 0, write num_bytes bytes
518+ err |= icm45_bank_write_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_CONTROL , 0x01 ); // No restarts, fast mode, start transaction
519+
520+ uint8_t last_status = 0 ;
521+ err |= icm45_bank_read_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_STATUS , & last_status );
522+ while (last_status & 0x01 ) // I2CM busy
523+ {
524+ err |= icm45_bank_read_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_STATUS , & last_status );
525+ }
526+
527+ if (last_status != 0x02 ) // Not (just) "done"
528+ {
529+ LOG_ERR ("I2CM error: %02x" , last_status );
530+ return -1 ;
531+ }
532+
533+ uint8_t dev_status ;
534+ err |= icm45_bank_read_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_EXT_DEV_STATUS , & dev_status );
535+
536+ if (dev_status & 0x01 ) {
537+ // Maybe log the nack?
538+ return -1 ;
539+ }
540+
541+ return err ;
542+ }
543+
544+ int icm45_ext_write_read (const uint8_t addr , const void * write_buf , size_t num_write , void * read_buf , size_t num_read ) {
545+ if (num_write != 1 || num_read < 1 || num_read > 15 )
546+ {
547+ LOG_ERR ("Unsupported write_read" );
548+ return -1 ;
549+ }
550+
551+ int err = 0 ;
552+
553+ uint8_t dev_profile_data [2 ] = {((const uint8_t * )write_buf )[0 ], addr };
554+ err |= icm45_bank_write (ICM45686_IPREG_TOP1 , ICM45686_DEV_PROFILE_0 , dev_profile_data , 2 );
555+ err |= icm45_bank_write_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_COMMAND_0 , 0x90 + num_read ); // Last transaction, channel 0, read num_read bytes with register specified
556+ err |= icm45_bank_write_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_CONTROL , 0x01 ); // No restarts, fast mode, start transaction
557+
558+ uint8_t last_status = 0 ;
559+ err |= icm45_bank_read_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_STATUS , & last_status );
560+ while (last_status & 0x01 ) // I2CM busy
561+ {
562+ err |= icm45_bank_read_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_STATUS , & last_status );
563+ }
564+
565+ if (last_status != 0x02 ) // Not (just) "done"
566+ {
567+ LOG_ERR ("I2CM error: %02x" , last_status );
568+ return -1 ;
569+ }
570+
571+ uint8_t dev_status ;
572+ err |= icm45_bank_read_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_EXT_DEV_STATUS , & dev_status );
573+
574+ if (dev_status & 0x01 ) {
575+ // Maybe log the nack?
576+ return -1 ;
577+ }
578+
579+ err |= icm45_bank_read (ICM45686_IPREG_TOP1 , ICM45686_I2CM_RD_DATA_0 , read_buf , num_read );
580+
581+ return err ;
582+ }
583+
442584const sensor_imu_t sensor_imu_icm45686 = {
443585 * icm45_init ,
444586 * icm45_shutdown ,
@@ -455,6 +597,12 @@ const sensor_imu_t sensor_imu_icm45686 = {
455597 * icm45_setup_DRDY ,
456598 * icm45_setup_WOM ,
457599
458- * imu_none_ext_setup ,
600+ * icm45_ext_setup ,
459601 * icm45_ext_passthrough
460602};
603+
604+ const sensor_ext_ssi_t sensor_ext_icm45686 = {
605+ * icm45_ext_write ,
606+ * icm45_ext_write_read ,
607+ 15
608+ };
0 commit comments