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
  • Thanks for specifying.

    I'll need some more time to look into what might be causing this, as I don't see why the combination of TWI and EDGE_FALLING interrupt would result in a higher current consumption than using just one of the two.

    I'll get back to you on Monday when I've done some more digging on my end.

    Best regards,

    Simon

  • Thanks for taking the time to look into this!

    I realized that I can trigger the same problem with the nrf52dk (PCA10040, v1.2.4 2019.19) so I created a minimal project to that replicates it. Hopefully it'll make it easier for you to figure out.

    I've attached it below, and included pre-compiled hex files. Incase it only triggers with certain versions of the nrf connect sdk.
    I compiled it with "cmake -DBOARD=nrf52dk_nrf52832 -B./build_output && make -j9 -C ./build_output"

    The below graph shows the problem on as measured with the nrf52dk
    Green is with is using i2c (with nothing physicall connected to dk) and an edge trigger
    Red is with using i2c (again nothing connected) and a level_low trigger

    Yellow is with the edge trigger and no i2c

    bug.zip

Reply
  • Thanks for taking the time to look into this!

    I realized that I can trigger the same problem with the nrf52dk (PCA10040, v1.2.4 2019.19) so I created a minimal project to that replicates it. Hopefully it'll make it easier for you to figure out.

    I've attached it below, and included pre-compiled hex files. Incase it only triggers with certain versions of the nrf connect sdk.
    I compiled it with "cmake -DBOARD=nrf52dk_nrf52832 -B./build_output && make -j9 -C ./build_output"

    The below graph shows the problem on as measured with the nrf52dk
    Green is with is using i2c (with nothing physicall connected to dk) and an edge trigger
    Red is with using i2c (again nothing connected) and a level_low trigger

    Yellow is with the edge trigger and no i2c

    bug.zip

Children
No Data
Related