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

How to achieve 0.7 muA current draw as stated in the datasheet?

Hi,

First off, I'm very new to the nRF52 development so I'm suspecting to have done something wrong...

The datasheet of the nRF52832 states a current consumption of 0.7muA in SYSTEM OFF with full RAM retention, as per 18.10.1 Current consumption sleep. I'm using the aforementioned nRF52832 with the pca10040 development board and a slightly altered version of pwr_mgmt from the nRF5_SDK_17.0.2_d674dde examples, however the lowest current that I could measure was 2 muA with (what I assume to be) SYSTEM OFF with no RAM retention.

I am measuring with a Keysight 34465A 6.5 digit multimeter according to docs.

Is there something that I am missing?

Here is the code (please forgive the mess):

#include <stdbool.h>
#include <stdint.h>
#include "nrf_soc.h"
#include "boards.h"
#include "bsp.h"
#include "bsp_nfc.h"
#include "app_timer.h"
#include "nordic_common.h"
#include "app_error.h"
#include "nrf_drv_clock.h"
#include "nrf_pwr_mgmt.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"


#if NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
#include "app_scheduler.h"
#define APP_SCHED_MAX_EVENT_SIZE    0   /**< Maximum size of scheduler events. */
#define APP_SCHED_QUEUE_SIZE        4   /**< Maximum number of events in the scheduler queue. */
#endif // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER


#define BTN_ID_READY                0   /**< ID of the button used to change the readiness to sleep. */
#define BTN_ID_SLEEP                1   /**< ID of the button used to put the application into sleep/system OFF mode. */
#define BTN_ID_WAKEUP               1   /**< ID of the button used to wake up the application. */
#define BTN_ID_RESET                2   /**< ID of the button used to reset the application. */

static volatile bool m_stay_in_sysoff;  /**< True if the application should stay in system OFF mode. */
static volatile bool m_is_ready;        /**< True if the application is ready to enter sleep/system OFF mode. */
static volatile bool m_sysoff_started;  /**< True if the application started sleep preparation. */


#define NRF52_ONRAM1_OFFRAM1  	POWER_RAM_POWER_S0POWER_On      << POWER_RAM_POWER_S0POWER_Pos      \
												      | POWER_RAM_POWER_S1POWER_On      << POWER_RAM_POWER_S1POWER_Pos      \
												      | POWER_RAM_POWER_S0RETENTION_On  << POWER_RAM_POWER_S0RETENTION_Pos  \
	                            | POWER_RAM_POWER_S1RETENTION_On  << POWER_RAM_POWER_S1RETENTION_Pos; 
												
#define NRF52_ONRAM1_OFFRAM0    POWER_RAM_POWER_S0POWER_On      << POWER_RAM_POWER_S0POWER_Pos      \
												      | POWER_RAM_POWER_S1POWER_On      << POWER_RAM_POWER_S1POWER_Pos      \
												      | POWER_RAM_POWER_S0RETENTION_Off << POWER_RAM_POWER_S0RETENTION_Pos  \
	                            | POWER_RAM_POWER_S1RETENTION_Off << POWER_RAM_POWER_S1RETENTION_Pos;														
												
#define NRF52_ONRAM0_OFFRAM0    POWER_RAM_POWER_S0POWER_Off     << POWER_RAM_POWER_S0POWER_Pos      \
												      | POWER_RAM_POWER_S1POWER_Off     << POWER_RAM_POWER_S1POWER_Pos;
											


/**@brief Handler for shutdown preparation.
 */
bool shutdown_handler(nrf_pwr_mgmt_evt_t event)
{
    uint32_t err_code;

    if (m_is_ready == false)
    {
        m_sysoff_started = true;
        return false;
    }

    switch (event)
    {
        case NRF_PWR_MGMT_EVT_PREPARE_SYSOFF:
            NRF_LOG_INFO("NRF_PWR_MGMT_EVT_PREPARE_SYSOFF");
            err_code = bsp_buttons_disable();
            APP_ERROR_CHECK(err_code);
            break;

        case NRF_PWR_MGMT_EVT_PREPARE_WAKEUP:
            NRF_LOG_INFO("NRF_PWR_MGMT_EVT_PREPARE_WAKEUP");
            err_code = bsp_buttons_disable();
            // Suppress NRF_ERROR_NOT_SUPPORTED return code.
            UNUSED_VARIABLE(err_code);

            err_code = bsp_wakeup_button_enable(BTN_ID_WAKEUP);
            // Suppress NRF_ERROR_NOT_SUPPORTED return code.
            UNUSED_VARIABLE(err_code);

            err_code = bsp_nfc_sleep_mode_prepare();
            // Suppress NRF_ERROR_NOT_SUPPORTED return code.
            UNUSED_VARIABLE(err_code);
            break;

        case NRF_PWR_MGMT_EVT_PREPARE_DFU:
            NRF_LOG_ERROR("Entering DFU is not supported by this example.");
            APP_ERROR_HANDLER(NRF_ERROR_API_NOT_IMPLEMENTED);
            break;

        case NRF_PWR_MGMT_EVT_PREPARE_RESET:
            NRF_LOG_INFO("NRF_PWR_MGMT_EVT_PREPARE_RESET");
            break;
    }

    err_code = app_timer_stop_all();
    APP_ERROR_CHECK(err_code);

    return true;
}

/**@brief Register application shutdown handler with priority 0. */
NRF_PWR_MGMT_HANDLER_REGISTER(shutdown_handler, 0);


/**@brief Function for handling BSP events.
 */
static void bsp_evt_handler(bsp_event_t evt)
{
#if NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED
    nrf_pwr_mgmt_feed();
    NRF_LOG_INFO("Power management fed");
#endif // NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED

    switch (evt)
    {
        case BSP_EVENT_KEY_0:
            if (m_is_ready)
            {
                m_is_ready = false;
                NRF_LOG_INFO("System is not ready for shutdown");
            }
            else
            {
                m_is_ready = true;
                NRF_LOG_INFO("System is ready for shutdown");
            }
            if (m_sysoff_started && m_is_ready)
            {
                nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_CONTINUE);
            }
            break;

        case BSP_EVENT_SYSOFF:
            m_stay_in_sysoff = true;
            break;

        case BSP_EVENT_SLEEP:
            if (m_stay_in_sysoff)
            {
                nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_STAY_IN_SYSOFF);
            }
            else
            {
                nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
            }
            break;

        case BSP_EVENT_RESET:
            nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_RESET);
            break;

        default:
            return; // no implementation needed
    }
}


/**@brief Function for initializing low-frequency clock.
 */
static void lfclk_config(void)
{
    ret_code_t err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_clock_lfclk_request(NULL);
}


/**@brief Function for initializing the BSP module.
 */
static void bsp_configuration()
{
    uint32_t err_code;

    err_code = bsp_init(BSP_INIT_BUTTONS, bsp_evt_handler);
    APP_ERROR_CHECK(err_code);

    err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP,
                                                 BSP_BUTTON_ACTION_LONG_PUSH,
                                                 BSP_EVENT_SYSOFF);
    APP_ERROR_CHECK(err_code);

    err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP,
                                                 BSP_BUTTON_ACTION_RELEASE,
                                                 BSP_EVENT_SLEEP);
    APP_ERROR_CHECK(err_code);

    err_code = bsp_event_to_button_action_assign(BTN_ID_READY,
                                                 BSP_BUTTON_ACTION_PUSH,
                                                 BSP_EVENT_NOTHING);
    APP_ERROR_CHECK(err_code);

    err_code = bsp_event_to_button_action_assign(BTN_ID_READY,
                                                 BSP_BUTTON_ACTION_RELEASE,
                                                 BSP_EVENT_KEY_0);
    APP_ERROR_CHECK(err_code);

    err_code = bsp_event_to_button_action_assign(BTN_ID_RESET,
                                                 BSP_BUTTON_ACTION_RELEASE,
                                                 BSP_EVENT_RESET);
    APP_ERROR_CHECK(err_code);
}


void configure_ram_retention(void){
    // Configure nRF52 RAM retention parameters. Set for System Off 0kB RAM retention
    NRF_POWER->RAM[0].POWER = NRF52_ONRAM1_OFFRAM0;
    NRF_POWER->RAM[1].POWER = NRF52_ONRAM1_OFFRAM0;
    NRF_POWER->RAM[2].POWER = NRF52_ONRAM1_OFFRAM0;
    NRF_POWER->RAM[3].POWER = NRF52_ONRAM1_OFFRAM0;
    NRF_POWER->RAM[4].POWER = NRF52_ONRAM1_OFFRAM0;
    NRF_POWER->RAM[5].POWER = NRF52_ONRAM1_OFFRAM0;
    NRF_POWER->RAM[6].POWER = NRF52_ONRAM1_OFFRAM0;
    NRF_POWER->RAM[7].POWER = NRF52_ONRAM1_OFFRAM0;
}	

/**
 * @brief Function for application main entry.
 */
int main(void){
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("Power Management examplo");

    lfclk_config();

    //uint32_t err_code = app_timer_init();
    //APP_ERROR_CHECK(err_code);

    #if NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
        APP_SCHED_INIT(APP_SCHED_MAX_EVENT_SIZE, APP_SCHED_QUEUE_SIZE);
    #endif // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
    bsp_configuration();

    //ret_code_t ret_code = nrf_pwr_mgmt_init();
    //APP_ERROR_CHECK(ret_code);

    //Configure RAM retention. More RAM retention means increased current consumption (see electrical specification in the Product Specification, power chapter)
    configure_ram_retention();	
    nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
    
    while(true){
        /**
        #if NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
                app_sched_execute();
        #endif // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER

        if (NRF_LOG_PROCESS() == false)
        {
            nrf_pwr_mgmt_run();
        }
        */
    }
}

Parents Reply Children
No Data
Related