SDK 17.1 nrf_pwr_mgmt_shutdown high sleep current

Hello,

I am running into difficulties getting the sleep current below 2.356mA.  I have a custom board but I went ahead and tested it sleep current capabilities by programming an application that puts the nRF52832 to sleep and nothing else.  Meaning, I'm not using secure bootloader, softdevice, and application with DFU support.  I get 4uA sleep current which is what I expect.

My confusion is with the following power down sequence in my application with DFU support and softdevice loaded...

I call the following functions that power down all ICs and set GPIO to high impedance.  

static void setHiZ(void)
{
	nrf_gpio_cfg_default(ICM_INT);
	nrf_gpio_cfg_default(EN_VBAT_SNS);	
	nrf_gpio_cfg_default(VBAT_SNS);
	nrf_gpio_cfg_default(THERM1);
	nrf_gpio_cfg_default(VL_INT);
	nrf_gpio_cfg_default(THERM1_DETECT);
	nrf_gpio_cfg_default(PL_SDA);	
	nrf_gpio_cfg_default(PL_SCL);	
  nrf_gpio_cfg_default(VL_XSHUT);
	nrf_gpio_cfg_default(SI_INT);
	nrf_gpio_cfg_default(PL_CLK);
	nrf_gpio_cfg_default(PL_MOSI);
	nrf_gpio_cfg_default(PL_MISO);
  nrf_gpio_cfg_default(MEM_SS);
  nrf_gpio_cfg_default(MEM_HOLDb);	
	nrf_gpio_cfg_default(MEM_WCb);
#ifndef DISABLE_SENSE	
	nrf_gpio_cfg(CHRG_B,
							 NRF_GPIO_PIN_DIR_INPUT,
							 NRF_GPIO_PIN_INPUT_CONNECT,
							 NRF_GPIO_PIN_NOPULL,
							 //NRF_GPIO_PIN_PULLUP,
							 NRF_GPIO_PIN_S0S1,
							 NRF_GPIO_PIN_SENSE_LOW);
	nrf_gpio_cfg(BTN_MSTR,
							 NRF_GPIO_PIN_DIR_INPUT,
							 NRF_GPIO_PIN_INPUT_CONNECT,
							 NRF_GPIO_PIN_PULLUP,
							 NRF_GPIO_PIN_S0S1,
							 NRF_GPIO_PIN_SENSE_LOW);
#endif							 
}

static void powerDownICs(void)
{
	uint32_t err_code;
	nrf_gpio_pin_clear(EN_VBAT_SNS);
	nrf_gpio_pin_clear(LED_G);
	nrf_gpio_pin_clear(LED_R);
	nrf_gpio_pin_clear(VL_XSHUT);
	nrf_gpio_pin_clear(MEM_WCb);
	nrf_gpio_pin_clear(RUN);
	nrf_gpio_pin_set(RUNb);
	saadc_sampling_event_disable();
	saadc_uninit();	
	setHiZ();
	//Disable SoftDevice. It is required to be able to write to GPREGRET2 register (SoftDevice API blocks it).
	//GPREGRET2 register holds the information about skipping CRC check on next boot.	
	err_code = nrf_sdh_disable_request();
	APP_ERROR_CHECK(err_code);		
}
  

I have used this method for many years now but a few things changed when I decided I wanted to support DFU.  It appears I can not shutdown the device with the normal softdevice commands.  I have to disable the softdevice and then use nrf_pwr_mgmt_shutdown() along with app_shutdown_handler()  These functions were provided from the buttonless_dfu example.

/**@brief Handler for shutdown preparation.
 *
 * @details During shutdown procedures, this function will be called at a 1 second interval
 *          untill the function returns true. When the function returns true, it means that the
 *          app is ready to reset to DFU mode.
 *
 * @param[in]   event   Power manager event.
 *
 * @retval  True if shutdown is allowed by this power manager handler, otherwise false.
 */
static bool app_shutdown_handler(nrf_pwr_mgmt_evt_t event)
{
    switch (event)
    {
        case NRF_PWR_MGMT_EVT_PREPARE_DFU:
            //NRF_LOG_INFO("Power management wants to reset to DFU mode.");
            // YOUR_JOB: Get ready to reset into DFU mode
            //
            // If you aren't finished with any ongoing tasks, return "false" to
            // signal to the system that reset is impossible at this stage.
            //
            // Here is an example using a variable to delay resetting the device.
            //
            // if (!m_ready_for_reset)
            // {
            //      return false;
            // }
            // else
            //{
            //
            //    // Device ready to enter
                //uint32_t err_code;
                //err_code = sd_softdevice_disable();
                //APP_ERROR_CHECK(err_code);
                //err_code = app_timer_stop_all();
                //APP_ERROR_CHECK(err_code);
            //}
            break;

        default:
						
            // YOUR_JOB: Implement any of the other events available from the power management module:
            //      -NRF_PWR_MGMT_EVT_PREPARE_SYSOFF
            //      -NRF_PWR_MGMT_EVT_PREPARE_WAKEUP
            //      -NRF_PWR_MGMT_EVT_PREPARE_RESET
            return true;
    }	
		//nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_STAY_IN_SYSOFF);
    //NRF_LOG_INFO("Power management allowed to reset to DFU mode.");
    return true;
}

//lint -esym(528, m_app_shutdown_handler)
/**@brief Register application shutdown handler with priority 0.
 */
NRF_PWR_MGMT_HANDLER_REGISTER(app_shutdown_handler, 0);


static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void * p_context)
{
    if (state == NRF_SDH_EVT_STATE_DISABLED)
    {
        // Softdevice was disabled before going into reset. Inform bootloader to skip CRC on next boot.
        nrf_power_gpregret2_set(BOOTLOADER_DFU_SKIP_CRC);

        //Go to system off.
        nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
    }
}

So how do I shutdown the nRF52832 properly via the app_shutdown_handler() and/or buttonless_dfu_sdh_state_observer()?  I have used my debugger extensively to make sure it get's all the way to nrf_power_system_off().  I see the current go into the microamps for a split second and then it jumps up to 2.356mA and stays there.  

Thank you for you help.  I have searched on devzone for the past week and have not found anything that has resolved my issue.

John

Related