Skip to content

Commit 8f681e8

Browse files
gorbit99sctanf
authored andcommitted
Implement ICM45686 I2CM interface
1 parent 633aef9 commit 8f681e8

3 files changed

Lines changed: 161 additions & 4 deletions

File tree

src/sensor/imu/ICM45686.c

Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
442584
const 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+
};

src/sensor/imu/ICM45686.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,15 @@
5353
// User Bank IPREG_TOP1
5454
#define ICM45686_IPREG_TOP1 0xA2 // MSB
5555

56+
#define ICM45686_I2CM_COMMAND_0 0x06
57+
#define ICM45686_DEV_PROFILE_0 0x0e
58+
#define ICM45686_DEV_PROFILE_1 0x0f
59+
#define ICM45686_I2CM_CONTROL 0x16
60+
#define ICM45686_I2CM_STATUS 0x18
61+
#define ICM45686_I2CM_EXT_DEV_STATUS 0x1a
62+
#define ICM45686_I2CM_RD_DATA_0 0x1b
63+
#define ICM45686_I2CM_WR_DATA_0 0x33
64+
5665
#define ICM45686_SMC_CONTROL_0 0x58
5766

5867
#define ICM45686_SREG_CTRL 0x67

src/sensor/interface.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ int ssi_write(enum sensor_interface_dev dev, const uint8_t *buf, uint32_t num_by
143143
#endif
144144
case SENSOR_INTERFACE_SPEC_I2C:
145145
return i2c_write_dt(sensor_interface_dev_i2c[dev], buf, num_bytes);
146+
case SENSOR_INTERFACE_SPEC_EXT:
147+
if (ext_ssi != NULL)
148+
return ext_ssi->ext_write(ext_addr, buf, num_bytes);
146149
default:
147150
return -1;
148151
}
@@ -179,9 +182,6 @@ int ssi_read(enum sensor_interface_dev dev, uint8_t *buf, uint32_t num_bytes)
179182
#endif
180183
case SENSOR_INTERFACE_SPEC_I2C:
181184
return i2c_read_dt(sensor_interface_dev_i2c[dev], buf, num_bytes);
182-
case SENSOR_INTERFACE_SPEC_EXT:
183-
if (ext_ssi != NULL)
184-
return ext_ssi->ext_write(ext_addr, buf, num_bytes);
185185
default:
186186
return -1;
187187
}

0 commit comments

Comments
 (0)