@@ -418,6 +418,148 @@ int icm45_ext_passthrough(bool passthrough)
418418 return 0 ;
419419}
420420
421+ int icm45_ext_setup () {
422+ int err = 0 ;
423+ 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
424+ sensor_interface_ext_configure (& sensor_ext_icm45686 );
425+ return err ;
426+ }
427+
428+ int icm45_bank_write (const uint8_t bank , const uint8_t reg , const uint8_t * buf , uint32_t num_bytes )
429+ {
430+ if (num_bytes == 0 )
431+ {
432+ LOG_ERR ("Invalid bank write size" );
433+ return -1 ;
434+ }
435+
436+ int err = 0 ;
437+ uint8_t ireg_buf [3 ];
438+ ireg_buf [0 ] = bank ;
439+ ireg_buf [1 ] = reg ;
440+ ireg_buf [2 ] = buf [0 ];
441+ err |= ssi_burst_write (SENSOR_INTERFACE_DEV_IMU , ICM45686_IREG_ADDR_15_8 , ireg_buf , 3 );
442+ k_usleep (4 );
443+
444+ for (uint32_t i = 1 ; i < num_bytes ; i ++ )
445+ {
446+ err |= ssi_reg_write_byte (SENSOR_INTERFACE_DEV_IMU , ICM45686_IREG_DATA , buf [i ]);
447+ k_usleep (4 );
448+ }
449+
450+ return err ;
451+ }
452+
453+ int icm45_bank_write_byte (const uint8_t bank , const uint8_t reg , const uint8_t value )
454+ {
455+ return icm45_bank_write (bank , reg , & value , 1 );
456+ }
457+
458+ int icm45_bank_read (const uint8_t bank , const uint8_t reg , uint8_t * buf , uint32_t num_bytes )
459+ {
460+ if (num_bytes == 0 )
461+ {
462+ LOG_ERR ("Invalid bank read size" );
463+ return -1 ;
464+ }
465+
466+ int err = 0 ;
467+ uint8_t ireg_buf [2 ];
468+ ireg_buf [0 ] = bank ;
469+ ireg_buf [1 ] = reg ;
470+ err |= ssi_burst_write (SENSOR_INTERFACE_DEV_IMU , ICM45686_IREG_ADDR_15_8 , ireg_buf , 2 );
471+ k_usleep (4 );
472+
473+ for (uint32_t i = 0 ; i < num_bytes ; i ++ )
474+ {
475+ err |= ssi_reg_read_byte (SENSOR_INTERFACE_DEV_IMU , ICM45686_IREG_DATA , & buf [i ]);
476+ k_usleep (4 );
477+ }
478+ return err ;
479+ }
480+
481+ int icm45_bank_read_byte (const uint8_t bank , const uint8_t reg , uint8_t * value ) {
482+ return icm45_bank_read (bank , reg , value , 1 );
483+ }
484+
485+ int icm45_ext_write (const uint8_t addr , const uint8_t * buf , uint32_t num_bytes )
486+ {
487+ if (num_bytes > 6 )
488+ {
489+ LOG_ERR ("Unsupported write" );
490+ return -1 ;
491+ }
492+
493+ int err = 0 ;
494+
495+ err |= icm45_bank_write (ICM45686_IPREG_TOP1 , ICM45686_I2CM_WR_DATA_0 , buf , num_bytes );
496+ err |= icm45_bank_write_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_COMMAND_0 , 0x80 + num_bytes ); // Last transaction, channel 0, write num_bytes bytes
497+ err |= icm45_bank_write_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_CONTROL , 0x01 ); // No restarts, fast mode, start transaction
498+
499+ uint8_t last_status = 0 ;
500+ err |= icm45_bank_read_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_STATUS , & last_status );
501+ while (last_status & 0x01 ) // I2CM busy
502+ {
503+ err |= icm45_bank_read_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_STATUS , & last_status );
504+ }
505+
506+ if (last_status != 0x02 ) // Not (just) "done"
507+ {
508+ LOG_ERR ("I2CM error: %02x" , last_status );
509+ return -1 ;
510+ }
511+
512+ uint8_t dev_status ;
513+ err |= icm45_bank_read_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_EXT_DEV_STATUS , & dev_status );
514+
515+ if (dev_status & 0x01 ) {
516+ // Maybe log the nack?
517+ return -1 ;
518+ }
519+
520+ return err ;
521+ }
522+
523+ int icm45_ext_write_read (const uint8_t addr , const void * write_buf , size_t num_write , void * read_buf , size_t num_read ) {
524+ if (num_write != 1 || num_read < 1 || num_read > 15 )
525+ {
526+ LOG_ERR ("Unsupported write_read" );
527+ return -1 ;
528+ }
529+
530+ int err = 0 ;
531+
532+ uint8_t dev_profile_data [2 ] = {((const uint8_t * )write_buf )[0 ], addr };
533+ err |= icm45_bank_write (ICM45686_IPREG_TOP1 , ICM45686_DEV_PROFILE_0 , dev_profile_data , 2 );
534+ 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
535+ err |= icm45_bank_write_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_CONTROL , 0x01 ); // No restarts, fast mode, start transaction
536+
537+ uint8_t last_status = 0 ;
538+ err |= icm45_bank_read_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_STATUS , & last_status );
539+ while (last_status & 0x01 ) // I2CM busy
540+ {
541+ err |= icm45_bank_read_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_STATUS , & last_status );
542+ }
543+
544+ if (last_status != 0x02 ) // Not (just) "done"
545+ {
546+ LOG_ERR ("I2CM error: %02x" , last_status );
547+ return -1 ;
548+ }
549+
550+ uint8_t dev_status ;
551+ err |= icm45_bank_read_byte (ICM45686_IPREG_TOP1 , ICM45686_I2CM_EXT_DEV_STATUS , & dev_status );
552+
553+ if (dev_status & 0x01 ) {
554+ // Maybe log the nack?
555+ return -1 ;
556+ }
557+
558+ err |= icm45_bank_read (ICM45686_IPREG_TOP1 , ICM45686_I2CM_RD_DATA_0 , read_buf , num_read );
559+
560+ return err ;
561+ }
562+
421563const sensor_imu_t sensor_imu_icm45686 = {
422564 * icm45_init ,
423565 * icm45_shutdown ,
@@ -433,6 +575,12 @@ const sensor_imu_t sensor_imu_icm45686 = {
433575
434576 * icm45_setup_WOM ,
435577
436- * imu_none_ext_setup ,
578+ * icm45_ext_setup ,
437579 * icm45_ext_passthrough
438580};
581+
582+ const sensor_ext_ssi_t sensor_ext_icm45686 = {
583+ * icm45_ext_write ,
584+ * icm45_ext_write_read ,
585+ 15
586+ };
0 commit comments