# Hardware Setup
The MCU is connected to the ICM-456xx using a 4-wire SPI connection. The ICM-456xx is connected to a peripheral sensor via the separate "I2CM" I2C bus using pin 2 (MAS_CLK) as clock and pin 3 (MAS_DA) as data. The code below is written in Micropython v1.25.0.
# Initialize the SPI Bus and Sensor
We configure our MCU's 4-wire SPI bus as follows:
``` python
SPI_BUS_NUMBER = 0
spi = SPI(SPI_BUS_NUMBER, baudrate=800000, polarity=1, phase=1, bits=8,
sck=Pin(18, mode=Pin.OUT),
mosi=Pin(19, mode=Pin.OUT),
miso=Pin(20, mode=Pin.IN)
) # CPOL=1, CPHA=1 --> SPI mode 3
cs = Pin(24, mode=Pin.OUT, value=1)
icm456xx = ICM456xx(io_protocol=SPI_SLAVE(spi, cs))
icm456xx.reset()
```
# I2CM Config
Next we prepare the sensor to enter I2CM mode, by setting relevant configuration bits for I2CM mode and loading the commands we want the ICM-456xx to send to the peripheral sensor.
In this case, the author configures the ICM-456xx to read from ICM-42670-S register 0x75.
``` python
# configure ICM-456xx I2CM block to read 1 byte from address 0x75 (WHO_AM_I) of ICM-42670-S (slave address 0x69)
icm456xx.I2CM_load_commands([[ 0x69, "R", 0x75, [None] ]]) # configure ICM-456xx I2CM block to perform 1 read
```
SPI transactions:
```
SPI-Write,addr: 0x7C,data: 0xA2 0x0F 0x69
SPI-Write,addr: 0x7C,data: 0xA2 0x06 0x91
SPI-Write,addr: 0x7C,data: 0xA2 0x0E 0x75
SPI-Write,addr: 0x35,data: 0x02
SPI-Write,addr: 0x30,data: 0x17
```
# I2CM Execution and Results
Finally, we execute the I2CM routine and then read the results. A successful read will should contain the ICM-42670-S's WHO_AM_I value of 0x69 which resides in register address 0x75.
``` python
csv_logfile.comment(f"Execute I2CM Commands")
icm456xx.ireg_write(IPREG_TOP1+0x16, 0b01000001) # I2CM_CONTROL register - set RESTART=1 (bit 6) and I2CM_GO=1 (bit 0)
sleep(0.1) # delay 100ms for I2CM read to complete
csv_logfile.comment(f"Read I2CM Results")
I2CM_done = icm456xx.ireg_read(IPREG_TOP1+0x18)[0] == 2 # I2CM_STATUS - did I2CM transaction happen? (with or without errors)
csv_logfile.comment(f"I2CM transaction executed: {I2CM_done}")
I2CM_successful = (icm456xx.ireg_read(IPREG_TOP1+0x1A)[0] & 1) == 0x00 # I2CM_EXT_DEV_STATUS - check bit 1 to see if peripheral sensor provided NACK (1), or ACK (0)
csv_logfile.comment(f"I2CM successful: {I2CM_successful}")
I2CM_read_result = icm456xx.ireg_read(IPREG_TOP1+0x1B)[0] # I2CM_RD_DATA0 - data for first I2CM read byte is at this address
csv_logfile.comment(f"I2CM read result: 0x{I2CM_read_result:02X}") # print data in hex format
```
```
[Comment],"Execute I2CM Commands"
SPI-Write,addr: 0x7C,data: 0xA2 0x16 0x41
[Comment],"Read I2CM Results"
SPI-Write,addr: 0x7C,data: 0xA2 0x18
SPI-Read ,addr: 0x7E,data: 0x02
[Comment],"I2CM transaction executed: True"
SPI-Write,addr: 0x7C,data: 0xA2 0x1A
SPI-Read ,addr: 0x7E,data: 0x0E
[Comment],"I2CM successful: True"
SPI-Write,addr: 0x7C,data: 0xA2 0x1B
SPI-Read ,addr: 0x7E,data: 0x69
[Comment],"I2CM read result: 0x69"
```
In the event that no sensor is found, the ICM-456xx reports the transaction "executes" but is not "successful" because it does not receive an I2C acknowledge.
```
[Comment],"Read I2CM Results"
SPI-Write,addr: 0x7C,data: 0xA2 0x18
SPI-Read ,addr: 0x7E,data: 0x02
[Comment],"I2CM transaction executed: True"
SPI-Write,addr: 0x7C,data: 0xA2 0x1A
SPI-Read ,addr: 0x7E,data: 0x0F
[Comment],"I2CM successful: False"
SPI-Write,addr: 0x7C,data: 0xA2 0x1B
SPI-Read ,addr: 0x7E,data: 0xFF
[Comment],"I2CM read result: 0xFF"
```
# Further Documentation
Please see the ICM-456xx User's Guide, as well as the "eMD" reference driver for more information and examples of the I2CM feature.
# Revision History
- 2026-02-02 - initial release