This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Excessive power usage when using i2c/twi

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

Parents
  • Hi 

    It took a while and some discussion with my colleagues, but it seems like we've gotten to the bottom of it. There seems to be some strange bug wherethe I2C driver doesn't handle the errata 89 workaround after your accReadRegister() function when the GPIO edge trigger is set. When reproducing this, we saw that commenting out the accReadRegister() function from the main loop also put the current consumption back to normal, and implementing the errata 89 workaround after the accReadRegister() function put the device back down to ~20uA. I have reported this bug internally, so the developers will take a look at it and fix this for a future release of the NCS.

    So the workaround here will be to, immediately after the accReadRegister() function in your application, add a short "wait" before implementing the errata 89 workaround manually.

    Best regards,

    Simon

Reply
  • Hi 

    It took a while and some discussion with my colleagues, but it seems like we've gotten to the bottom of it. There seems to be some strange bug wherethe I2C driver doesn't handle the errata 89 workaround after your accReadRegister() function when the GPIO edge trigger is set. When reproducing this, we saw that commenting out the accReadRegister() function from the main loop also put the current consumption back to normal, and implementing the errata 89 workaround after the accReadRegister() function put the device back down to ~20uA. I have reported this bug internally, so the developers will take a look at it and fix this for a future release of the NCS.

    So the workaround here will be to, immediately after the accReadRegister() function in your application, add a short "wait" before implementing the errata 89 workaround manually.

    Best regards,

    Simon

Children
No Data
Related