My setup:
I’m trying to communicate with the ICM-20948 breakout board over I2C with a Raspberry Pi Pico, and writing C++ with Visual Studio Code. I have started with the Sparkfun Arduino library for this chip, and modified it for this platform so that it can use the I2C peripheral.
What’s working:
I can see I2C traffic happening, and it can read the WHOIAM register, which reads back as 0xEA correctly.
What’s not working:
But then the initialisation code seems to hit a problem. It tries to read back the WHOIAM register from the internal magnetometer, but always seems to get 0x00. Again, looking at the I2C traffic on a logic analyser, it certainly looks like it’s doing all the right things: switching to bank 0, then performing a read of the correct register, but I can see the result coming back as zero.
My question:
Is there a possibility that this chip has a fault? I can post screenshots of the I2C traffic if that helps.
The code is failing in ICM_20948_C.c in the function ICM_20948_i2c_controller_periph4_txn()
ICM_20948_Status_e ICM_20948_i2c_controller_periph4_txn(ICM_20948_Device_t *pdev, uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len, bool Rw, bool send_reg_addr)
{
...
uint32_t max_cycles = 1000;
uint32_t count = 0;
bool peripheral4Done = false;
while (!peripheral4Done)
{
retval = ICM_20948_set_bank(pdev, 0);
retval = ICM_20948_execute_r(pdev, AGB0_REG_I2C_MST_STATUS, (uint8_t *)&i2c_mst_status, 1);
peripheral4Done = (i2c_mst_status.I2C_PERIPH4_DONE /*| (millis() > tsTimeout) */); //Avoid forever-loops
peripheral4Done |= (count >= max_cycles);
count++;
}
txn_failed = (i2c_mst_status.I2C_PERIPH4_NACK /*| (millis() > tsTimeout) */);
txn_failed |= (count >= max_cycles);
if (txn_failed)
break;
if (Rw)
{
retval = ICM_20948_set_bank(pdev, 3);
retval = ICM_20948_execute_r(pdev, AGB3_REG_I2C_PERIPH4_DI, &data[nByte], 1);
}
nByte++;
}
if (txn_failed)
{
//We often fail here if mag is stuck
return ICM_20948_Stat_Err;
}
...
}
The code exits because txn_failed is true, implying that the mag is stuck according the the comment in the code.
Here are some waveforms from the I2C bus. This first one shows the chip replying with its WHOIAM value of 0xEA.
https://i.stack.imgur.com/ygslR.png
And this one shows the failure when reading register 0x17 (AGB0_REG_I2C_MST_STATUS):
https://i.stack.imgur.com/JYw25.png