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

TWI Current Consumption

Dear All ,

I am a little stumped.... Basically first i was working with the beacon app on sdk 12 on the 51822 chip. Now I have moved to the 52382 chip.

I modified the app to run with my requirements. I added a timer to fire at every 5 seconds to check the input pin. and set advertising intervals to 10 seconds. I was getting really good current consumption of 8ua when broadcasting. and 2ua when sleeping.

But then I moved to sdk 16 and 52382 chip, only added a TWI I2c , connected to a mp121 capacitive touch sensor. All was going well until I started checking the final step of current consumption. The consumption was hitting 6ma when using the TWI(meaning sending and reading data).. which seems obsurd.... I disabled nrf Log but did not help at all. When the chip goes in a system power of mode the consumption is still hitting 70ua.

I read somewhere that the TWI' Consumption is not that high only around .5ma max when running.(I am hitting 6ma also when i just read one register)

Here is my code for twi init.

/**
* @brief UART initialization.
*/
void twi_init (void)
{
ret_code_t err_code;

const nrf_drv_twi_config_t twi_mp121_config = {
.scl = 19,
.sda = 4,
.frequency = NRF_DRV_TWI_FREQ_100K,
.interrupt_priority = APP_IRQ_PRIORITY_HIGH,
.clear_bus_init = false
};

err_code = nrf_drv_twi_init(&m_twi, &twi_lm75b_config, twi_handler, NULL);
APP_ERROR_CHECK(err_code);

nrf_drv_twi_enable(&m_twi);
}

My repeated timer which is triggered every 5 seconds:-


/**@brief Timeout handler for the repeated timer.
*/
static void repeated_timer_handler(void * p_context)
{
nrf_gpio_cfg_input(3,NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_sense_input(3,NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
//readRegister8(MPR121_E0BV);
// readRegister16(MPR121_TOUCHSTATUS_L);
if(m_sample==1)//(nrf_gpio_pin_read(3)==0)
{

NRF_LOG_INFO("Button Pressed.");
advertising_stop();
advertising_init(1,0);
advertising_start();
nrf_gpio_cfg_default(23);
DelCounter=0;
}
else
{
DelCounter=DelCounter+1;
NRF_LOG_INFO("DelCounter %d.",DelCounter);
if(DelCounter>9)
{
sd_power_system_off();
}
}
}

My main:-

*/
int main(void)
{
// Initialize.
uint32_t err_code;
log_init();
NRF_LOG_INFO("Beacon example started.");
NRF_LOG_FLUSH();


timers_init();
twi_init();
MP121_set_mode();
NRF_LOG_FLUSH();
//leds_init();
create_timers();
err_code = app_timer_start(m_repeated_timer_id, APP_TIMER_TICKS(5000), NULL);
APP_ERROR_CHECK(err_code);
power_management_init();
ble_stack_init();
//sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE);
advertising_init(0,0);

// nrf_gpio_cfg_input(3,BUTTON_PULL);

//nrf_gpio_cfg_sense_input(3, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
// APP_ERROR_CHECK(err_code);
// Start execution.

advertising_start();

// Enter main loop.

// Enter main loop.
for (;; )
{
// power_manage();
idle_state_handle();


}
}

Powe Functions:-

/**@brief Function for handling the idle state (main loop).
*
* @details If there is no pending log operation, then sleep until next the next event occurs.
*/
static void idle_state_handle(void)
{
if (NRF_LOG_PROCESS() == false)
{
nrf_pwr_mgmt_run();
}
}

/**@brief Function for doing power management.
*/
static void power_manage(void)
{
uint32_t err_code = sd_app_evt_wait();
APP_ERROR_CHECK(err_code);
}

  • Read and write functions:


    void writeRegister(uint8_t RegisterAddr, uint8_t Data)
    {
    ret_code_t err_code;
    uint8_t reg[2] = {RegisterAddr,Data};
    err_code = nrf_drv_twi_tx(&m_twi, MP121_ADDR, reg, 2, false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
    nrf_delay_ms(10);
    }

    void readRegister8(uint8_t RegisterAddr)
    {
    ret_code_t err_code;
    uint8_t reg[2];
    reg[0] =RegisterAddr;
    nrf_delay_ms(20);
    err_code = nrf_drv_twi_tx(&m_twi, MP121_ADDR, reg, 1, true);
    nrf_delay_ms(100);
    if (NRF_SUCCESS == err_code)
    err_code = nrf_drv_twi_rx(&m_twi, MP121_ADDR, &m_sample, 1);
    APP_ERROR_CHECK(err_code);
    nrf_delay_ms(100);
    }
    void readRegister16(uint8_t RegisterAddr)
    {
    ret_code_t err_code;
    uint8_t reg[2];
    reg[0] =RegisterAddr;
    nrf_delay_ms(100);
    err_code = nrf_drv_twi_tx(&m_twi, MP121_ADDR, reg, 1, true);
    nrf_delay_ms(100);
    if (NRF_SUCCESS == err_code)
    err_code = nrf_drv_twi_rx(&m_twi, MP121_ADDR, &m_sample, 2);
    APP_ERROR_CHECK(err_code);
    nrf_delay_ms(100);
    }

  • I notice you are writing: nrf_drv_twi_init(&m_twi, &twi_lm75b_config, twi_handler, NULL);

    But I can't see your twi_handler()? 

    Have you tried:

    nrf_drv_twi_init(&m_twi, &twi_lm75b_config, NULL, NULL);

    If you don't have any debugging, you can use nrf_pwr_mgmt_run() directly. What is the implementation of nrf_pwr_mgmt_run()?

  • I have a handlre whicb just stores the return data to a global variable.  What concerns me is two things.. that how is it possible when running the twi can consume so much data.. also when sd power of.. my system still consumes 60 ua...

    I am already using power manage run as shown in idle state handle function...

  • You may get some pointers here in general:
    https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/optimizing-power-on-nrf52-designs

    If the CPU is running (not in sleep) it will draw a few mA, in sleep the chip should draw only a few uA. If it is drawing tens of uA you should check for floating GPIO's or if it may be due to a known errata that require workaround:
    https://infocenter.nordicsemi.com/topic/errata_nRF52832_Rev2/ERR/nRF52832/Rev2/latest/err_832_new.html

    Best regards,
    Kenneth

  • Hey Kenneth ,

    Thanks for your reply.. Can you help me on how to send consecutive reads and writes.. I believe your right in the fact that its because of the CPU running and not being able to sleep.

    The issue is if i remove the Delays i always get NRF_busy error. although i have while (m_xfer_done == false);

    I tried to make a function called waitms() with a single shot timer, but the timer handler is not being called. It works fine when i dont send any TWI reads or writes.. but when i send some read and writes the handler is not called..

    My idea was :-

    void writeRegister(uint8_t RegisterAddr, uint8_t Data)
    {
    ret_code_t err_code;
    //while (m_xfer_done == false);
    uint8_t reg[2] = {RegisterAddr,Data};
    err_code = nrf_drv_twi_tx(&m_twi, MP121_ADDR, reg, 2, false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
    watMs(10);

    while (WaitFlage== false);
    }

    But this doesnt work as the Waitflag is not being set by the single shot timer handler. Maybe my idea is not feasible in first place.. if not can you advise how to avoid wasted cpu cycles and put the cpu in sleep mode.. 

    Secondly is the NRF_busy related to the Sensor chip or something else? I initialy thought the sensor needed time to process the request but when i saw the data sheet of the mpr121 it is pretty fast .. only needs 1.5 us to respond , while i am needing atleast 10 ms. to avoid getting the nrf busy error.

Related