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

Power consumption related to TWIM

I recently had the need to communicate with a device over I2C. I'm using the nRF52 as the master. Everything works fine, but power is a concern. I am putting the processor into the ON low power mode. Currently, I'm typically running at around 120 uA, as measured with a Current Ranger. I'm measuring the current at the external power input to the PCA10040 board (P21). I wrote my own I2C driver, as I have with all my drivers.

I have a timer (RTC) that periodically (3-30 seconds, depending on various factors) initiates a communication with the external part over the TWIM interface. The actual communication exchange takes no longer than 60 ms at 400 KHz bus speed. I'm switching this external part on and off using a GPIO pin around the exchange. The first exchange happens 10 seconds after power up.

Before the first communication, my current consumption is about 120 uA. After the first communication, the power consumption is about 400 or so uA higher and it remains there. It certainly seems like after turning on the TWIM instance and then turning it off, it is not returning to the same state. I'm turning the TWIM on and off using the ENABLE register.

Is there something I need to do with the EasyDMA that I need to know about? I'll post a couple of code snippets.

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//======================================================================
/*!
@brief Enable the I2C.
@details
This function controls the functioning of the I2C. The I2C must be disabled
before changing any configuration parameters. It may also be disabled for
minimizing power consumption.
@param i2c Identifies the I2C.
@param enable TRUE to enable the I2C.
@author John Heaney
@test 03/14/2020 Unit Test: UNTESTED
*/
void I2cEnable(I2cEnum i2c, BOOL enable)
{
NRF_TWIM_Type * i2cBaseReg;
UINT32 enableValue;
//The register used to enable either the master or slave is the same, but the
// value used is different.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//======================================================================
/*!
@brief IRQ handler for I2C.
@detail
Each I2C interface has an interrupt vector. This is a common handler for all
of them. The parameter identifies the specific instance, which can be directly
related to a I2cEnum.
@param systemID Idenfier (ordinal number) for the I2C interrupt source.
@author John Heaney
@test 05/07/2020 Unit Test: UNTESTED
*/
static void irq_handler(UINT8 systemID)
{
I2cEnum i2c;
NRF_TWIM_Type * i2cBaseReg;
ErrorCodeEnum errCode;
UINT32 i2cError;
EventData eventData;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX