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

    By "the problem" I assume you mean the excess current consumption you're seeing only occurs when using the GPIO_INT_EDGE_FALLING instead of I.E. GPIO_INT_LEVEL_LOW, correct? What current does the device draw when the GPIO trigger is set to LEVEL_LOW instead for instance? 

    I think this is due to the GPIOTE is using an IN event rather than a PORT event. An IN_EVENT will require the device to use the HF clock, explaining the increased current consumption.

    Best regards,

    Simon

  • Hi

    What I meant is that the excess current consumption only happens if we set the interrupt to GPIO_INT_EDGE_FALLING _and_ read to or write to the i2c bus.

    Using any of the following uses a normal amount of current:
    * only I2c
    *only an interrupt on GPIO_INT_EDGE_FALLING

    * i2c and interrupt on GPIO_INT_LEVEL_LOW

    I can't remember off the top of my head what the normal power consumption is, and it depends on if we run the i2c bus or not. But I believe around 20 microamps or so. Please let me know if exact numbers would help and I'll get them for you.


    Could using the i2c/twi cause the device to switch what event type it uses from a Port to IN_EVENT for GPIO_INT_EDGE_FALLING?

Reply
  • Hi

    What I meant is that the excess current consumption only happens if we set the interrupt to GPIO_INT_EDGE_FALLING _and_ read to or write to the i2c bus.

    Using any of the following uses a normal amount of current:
    * only I2c
    *only an interrupt on GPIO_INT_EDGE_FALLING

    * i2c and interrupt on GPIO_INT_LEVEL_LOW

    I can't remember off the top of my head what the normal power consumption is, and it depends on if we run the i2c bus or not. But I believe around 20 microamps or so. Please let me know if exact numbers would help and I'll get them for you.


    Could using the i2c/twi cause the device to switch what event type it uses from a Port to IN_EVENT for GPIO_INT_EDGE_FALLING?

Children
No Data
Related