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

nrf52 not entering sleep mode when accelerometer kx022 is used with twi manager

On a NRF52832 based beacon I use to sensors, a SHT3 temperature and humidity sensor and a KX022 accelerometer.

I'm using the twi_manager library as it is used in the example.

With the SHT3 everything is fine, the overall power consumption is ok.

As soon as I initialize the KX022 sensor exactly the same way, the power consumption stays at ~3.7 mA and is not going to the expected average of 4 uA and it seems that there is a reason why it is not going to sleep mode. The accel device itself has a standby power consumption of 0.9 uA.

In Keil using the NVIC there are no pending interrupts.

The code segments I use:

static void twi_config()
{
    uint32_t err_code;

    nrf_drv_twi_config_t const config = {
       .scl                = ARDUINO_SCL_PIN,
       .sda                = ARDUINO_SDA_PIN,
       .frequency          = NRF_DRV_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_LOWEST,
       .clear_bus_init     = false
    };

    err_code = nrf_twi_mngr_init(&m_nrf_twi_mngr, &config);
    APP_ERROR_CHECK(err_code);
}

static void sensor_init()
{	
    APP_ERROR_CHECK(nrf_twi_mngr_perform(&m_nrf_twi_mngr, NULL, kx022_init_transfers,
        KX022_INIT_TRANSFER_COUNT, NULL));
}

with

static uint8_t config_1[2] = {KX022_1020_REG_CNTL1, 				0x40 };	// KX022_1020_STANDBY | KX022_1020_HIGH_RESOLUTION
static uint8_t config_2[2] = {KX022_1020_REG_ODCNTL, 			 	0x02 };	// KX022_1020_OUTPUT_RATE_50_HZ

nrf_twi_mngr_transfer_t const kx022_init_transfers[KX022_INIT_TRANSFER_COUNT] =
{
    NRF_TWI_MNGR_WRITE(KX022_ADDR, config_1, 2, 0),
	NRF_TWI_MNGR_WRITE(KX022_ADDR, config_2, 2, 0)
}

In the current setup, I don't read any values, etc.

The initialization commands are taken from Kionix Getting Started, on page 2, first two steps from 1.

Any ideas on how to proceed or to further debug why it's not going to sleep mode?

Parents
  • I added two breakpoints in the function nrf_pwr_mgmt_run(), breakpoint A in the line with the first __WFE(), and the second breakpoint B when leaving the function again.

    void nrf_pwr_mgmt_run(void)
    {
        PWR_MGMT_FPU_SLEEP_PREPARE();
        PWR_MGMT_SLEEP_LOCK_ACQUIRE();
        PWR_MGMT_CPU_USAGE_MONITOR_SECTION_ENTER();
        PWR_MGMT_DEBUG_PIN_SET();
    
        // Wait for an event.
    #ifdef SOFTDEVICE_PRESENT
        if (nrf_sdh_is_enabled())
        {
            ret_code_t ret_code = sd_app_evt_wait();
            ASSERT((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED));
            UNUSED_VARIABLE(ret_code);
        }
        else
    #endif // SOFTDEVICE_PRESENT
        {
            // Wait for an event.
            __WFE();
            // Clear the internal event register.
            __SEV();
            __WFE();
        }
    
        PWR_MGMT_DEBUG_PIN_CLEAR();
        PWR_MGMT_CPU_USAGE_MONITOR_SECTION_EXIT();
        PWR_MGMT_SLEEP_LOCK_RELEASE();
    }

    In Keil debugging i get the figures, that between breakpoint A and B it's ~40 ns, and between B and A (so next entry of the function) ~223 usec.

    Where to look why it's leaving __WFE() so fast again?

  • It seems like the CPU is still running (check electrical specifications for the CPU from this link). Like you mentioned, for some reason it seems the TWI manager is keeping the CPU awake.

    Could you try turning TWI off via the nrf_twi_mngr_uninit() function just to double check that it is the TWI manager that is leading to the interrupt from sleep issue?

    This could also be related to the UART logging to the computer. Have you tested the sleep current by turning the UART off?

    The documentation present here may also be helpful if you have not already seen it: link 1, link 2, link 3.

    This case may also be helpful.

  • Overall power consumption is not a problem, with the temperature/humidity sensor everything is fine, UART is no problem, I'm using RTT.

    I rewrote the code part to use blocking TWI (without transaction manager) and also read the data sheet again. I found that the KX022 accel needs some delays (1.2/ODR) before putting in operation, and this seems to be the problem. With the blocking TWI and nfr_delay() the power consumption is ok, too.

    The posted link 2 is a good reference, I didn't know, that I can schedule blocking transactions with the transaction manager, too. 

    But which is the best way to implement a delay using transaction manager transactions?

  • an-erd said:
    But which is the best way to implement a delay using transaction manager transactions?

     You could consider setting in a delay in between sending packets with the packet timer. Otherwise, you could also use the RTC or app_timer to sleep while you are waiting for the KX022 accelerometer to initialize.

Reply Children
No Data
Related