Hi
We are developing a project where we are using a peripheral over i2c, specifically a lis3dh accelerometer. However we have encountered a problem and would be really grateful for any help you could provide.
Whenever we start to read or write to the i2c bus we are seeing excessive power usage on the order of several hundred micro-amperes. This excessive power usage also occurs if we try to use the accelerometer via the lis2dh driver.
I tried applying the fix from errata 89 to see if that helped, but that caused a crash in the nrf twi driver with the message: "<err> i2c_nrfx_twi: Error on I2C line occurred for message 0"
The hardware we are using is an nrf5832, and we are using the nrf connect sdk v2.4.99
Because of we are running on a board with other peripherals that need to be configured I can unfortunately not attach a complete build-able project, but I've isolated the problem to the below line of code, marked with a comment:
#define LIS3DH_REG_INT1SRC 0x31
#define I2C0_LABEL DT_LABEL(DT_NODELABEL(i2c0))
#define LIS3DH_I2C_ADDRESS (0x19) // SA0 pulled high
const struct device *g_i2c_dev;
static uint8_t accReadRegister(uint8_t address)
{
struct i2c_msg msgs[2];
/* Setup I2C messages */
/* Send the address to read */
msgs[0].buf = &address;
msgs[0].len = 1U;
msgs[0].flags = I2C_MSG_WRITE;
/* Read from device. RESTART as neededm and STOP after this. */
uint8_t data[55];
msgs[1].buf = data;
msgs[1].len = 2U;
msgs[1].flags = I2C_MSG_READ | I2C_MSG_RESTART | I2C_MSG_STOP;
int read_succ = i2c_transfer(g_i2c_dev, &msgs[0], 2, LIS3DH_I2C_ADDRESS);
__ASSERT(read_succ == 0, "read from accel failed");
//k_sleep(K_MSEC(100)); // For some reason necessary
return 0;
}
int main(void)
{
//Important that accelerometer is completely powered
k_sleep(K_MSEC(10));
g_i2c_dev = device_get_binding(I2C0_LABEL);
// not needed, trigger without or without these lines
uint32_t i2c_cfg = I2C_SPEED_SET(I2C_SPEED_STANDARD) | I2C_MODE_MASTER;
int conf_i2c_ret = i2c_configure(g_i2c_dev, i2c_cfg);
__ASSERT(conf_i2c_ret == 0, "failed to configure i2c");
// end not needed
accReadRegister(LIS3DH_REG_INT1SRC); //this line triggers the problem, a write also triggers it
while(true){
k_sleep(K_MSEC(100));
}
return;
}
The relevant part of the prj.conf
# accelerometer CONFIG_I2C=y CONFIG_PM_DEVICE=y CONFIG_DEVICE_POWER_MANAGEMENT=y CONFIG_PM_DEVICE_IDLE=y