# Hardware Setup
The MCU is connected to the sensor using a 4-wire SPI connection, and a separate GPIO connected to ICM-456xx pin#9 (CLKIN). The code below is written in Micropython v1.25.0 on an RP2040-based platform.
# Initialize the SPI Bus and Sensor
We configure our MCU's 4-wire SPI bus, and configure the sensor to issue interrupts on INT1 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)
PIN_CLK = Pin(29, Pin.OUT, Pin.PULL_DOWN) # RP2040 GPIO29, to use as external clock output
icm456xx = ICM456xx(io_protocol=SPI_SLAVE(spi, cs))
icm456xx.reset()
print(icm456xx)
icm456xx.config_INT1_DRDY()
icm456xx.set_big_endian()
ODR_to_set = 100
icm456xx.gyro_setup(ODR=ODR_to_set, FSR=500)
icm456xx.accel_setup(ODR=ODR_to_set, FSR=4)
```
SPI transactions and comments:
```
SPI-Write,addr: 0x7F,data: 0x02
SPI-Write,addr: 0x16,data: 0x04
SPI-Write,addr: 0x18,data: 0x01
SPI-Write,addr: 0x7C,data: 0xA2 0x69 0x00
SPI-Write,addr: 0x7C,data: 0xA2 0x67 0x02
SPI-Write,addr: 0x1C,data: 0x39
SPI-Write,addr: 0x1B,data: 0x39
```
# Calculate ODR
We calculate the ODR before enabling the external clock.
``` python
icm456xx.enable()
sleep_ms(100)
calculated_ODR = 1/measure_N_interrupt_pulses(N=100) # measure average time between 100 interrupt pulses
csv_logfile.comment(f"Calculated ODR={calculated_ODR}Hz (with CLKIN disabled)")
icm456xx.enable(False)
```
SPI transaction log:
```
SPI-Write,addr: 0x10,data: 0x0F
[Comment],"Calculated ODR=100.425Hz (with CLKIN disabled)"
SPI-Write,addr: 0x10,data: 0x00
```
The reader may note that the measured ODR is 0.425% different from the nominal datasheet value of 100Hz, and is due to part/part variations in the internal IMU oscillator.
Now we enable the external clock, and measure the new ODR at 3 different CLKIN input frequencies: 20kHz, 32kHz, 40kHz.
``` python
icm456xx.CLKIN_enable()
for i_Freq in [20000,32000,40000]:
clock_output = configure_RP2040_PIO(i_Freq, PIN_CLK) # output external clock at frequency: i_Freq
icm456xx.enable()
sleep_ms(200) # wait to stabilize
calculated_ODR = 1/measure_N_interrupt_pulses(N=100)
csv_logfile.comment(f"Calculated ODR={calculated_ODR}Hz (with CLKIN: {i_Freq}Hz)")
icm456xx.enable(False)
```
```
SPI-Write,addr: 0x31,data: 0x06
SPI-Write,addr: 0x26,data: 0x23
SPI-Write,addr: 0x30,data: 0x40
SPI-Write,addr: 0x10,data: 0x0F
[Comment],"Calculated ODR=62.50Hz (with CLKIN: 20000Hz)"
SPI-Write,addr: 0x10,data: 0x00
SPI-Write,addr: 0x10,data: 0x0F
[Comment],"Calculated ODR=100.00Hz (with CLKIN: 32000Hz)"
SPI-Write,addr: 0x10,data: 0x00
SPI-Write,addr: 0x10,data: 0x0F
[Comment],"Calculated ODR=125.00Hz (with CLKIN: 40000Hz)"
SPI-Write,addr: 0x10,data: 0x00
```
The reader should note that when input clock frequency is 32kHz, the timing error has been dramatically reduced to less than 0.01% (measured ODR is 100.00Hz) – this is the intended benefit of using the external clock input pin.
# Further Documentation
Please see the ICM-456xx User Guide and the relevant software reference drivers for more details and information.