NRF52840 running with BLE Advertising every 1 second consumes 450 uA even with tickless idle mode

We are running an NRF52840 on our custom board and getting around 450 uA while is BLE Advertising with a period of about 1 second.

If we disable BLE then our current consumption drops to 45 uA.

We would like to get current consumption down to 100 uA with BLE Advertising - is this possible?

Setup

- Freertos

- Tickless idle mode (using the nrf52 cmsis port code provided by nordic)

- 17.1 SDK

- NRF_LOGS is disabled

- no other peripherals running (QSPI is off ...etc)

Any suggestions on how to reduce current consumption while BLE is advertising? 

We don't want to use the SYSTEM OFF low power mode since we will eventually need other parts of our system to be active and not require a reset.

Here is a sample of the ble advertisement init code I'm running

static void advertising_init(void)
{
    uint32_t                    err_code;
    ble_advertising_init_t      init;

    // Service UUID list for advertising.
    ble_uuid_t m_adv_uuids[] =
    {
        {BLE_UUID_DATA_SERVICE, m_dcs.uuid_type}
    };

    std::memset(&init, 0, sizeof(init));

    // Fill main advertising data packet with complete data service UUID
    init.advdata.uuids_complete.uuid_cnt           = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    init.advdata.uuids_complete.p_uuids            = m_adv_uuids;
    init.advdata.flags                             = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;

    // Begin filling scan response packet with advertising name and flags
    init.srdata.name_type                          = BLE_ADVDATA_FULL_NAME;
    init.srdata.include_appearance                 = false;

    // Create variables for advertising service data
    ble_advdata_service_data_t  service_data;
    uint8_array_t               data_array;

    // Point at the data, add service data UUID
    data_array.p_data                              = (uint8_t*)blem_get_serial_number();
    data_array.size                                = blem_get_serial_number_bytes();
    service_data.service_uuid                      = 0x180A;
    service_data.data                              = data_array;

    // Add service data structure to init
    init.srdata.p_service_data_array               = &service_data;
    init.srdata.service_data_count                 = 1;

    init.config.ble_adv_whitelist_enabled          = false;
    init.config.ble_adv_directed_high_duty_enabled = false;
    init.config.ble_adv_directed_enabled           = false;
    init.config.ble_adv_directed_interval          = 0;
    init.config.ble_adv_directed_timeout           = 0;
    init.config.ble_adv_fast_enabled               = true;
    init.config.ble_adv_fast_interval              = APP_ADV_FAST_INTERVAL_UNITS; // 25 ms
    init.config.ble_adv_fast_timeout               = APP_ADV_FAST_DURATION_UNITS; // 30 seconds
    init.config.ble_adv_slow_enabled               = true;
    init.config.ble_adv_slow_interval              = APP_ADV_SLOW_INTERVAL_UNITS; // 1022 ms
    init.config.ble_adv_slow_timeout               = APP_ADV_SLOW_DURATION_UNITS; // 0 (run forever)

    init.evt_handler                               = on_adv_evt;

    err_code                                       = ble_advertising_init(&m_advertising, &init);
    APP_ERROR_CHECK(err_code);

    ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
}

  • Hi Joshua,

    There were some issues on the earlier version of FreeRTOS but we fixed it since nRF5SDKv16, and a lot of products are out with low power on nRF52840 using tickless idle. If you can reproduce this on the nRF52840, then please attach a simplistic project for me to reproduce it. If you are using a custom hardware, then it most likely is an issue with your hardware or hardware configurations. In the latter case, I will try to look into the DCDC settings you have on your hardware to match with your firmware and also check if your clocks on your hardware match the clock configuration in your sdk_config.h file.

  • Hi Susheel,

    Thank you. I'll look into the suggestions you made.

    We are using the BL654 BLE Module that has the nrf52840 MCU integrated.

    I'm guessing that 450 uA while BLE is advertising at 1 sec intervals is too high?

    If I disable the BLE the current draw drops down to 45 uA with a few tasks running and tickless idle mode (RTC1).

    And I can provide a sample application from the 17.1 SDK that I also tested with - will post something next.

  • Hi Susheel,

    So when I use the nrf 17.1 examples / ble_peripheral / ble_app_hrs / pca10056 / s140
    I have to update the code to use the dcdc en and the low power clock. When I do this I get 60 uA on our custom board.

    But I believe this is because in 

    on_adv_evt -> 
    BLE_ADV_EVT_IDLE
    We call 
    sleep_mode_enter();


    We will not want to do this for our application since it puts the nrf into OFF mode. If I comment out the sleep_mode_enter the current draw goes up to 450 uA.
    Also, as a note: it looks like calling 
    ble_stack_init(); 
    is enough to result in 450 uA of current. I don't even init advertising, or gap or anything else.
  • If softdevice_enable itself is enough, then there are few possible reasons.

    It is possible that the softdevice is trying to turn on in the LDO mode instead of using the DCDC buck converter. Can you do a small experiment to make sure you enable the DCDC mode and then enable the softdevice like below?

    void power_management_init(void)
    {
        ret_code_t err;
    
        err = nrf_drv_power_init(NULL);
        APP_ERROR_CHECK(err);
    
        nrf_drv_power_dcdc_enable(true);
    }
    ...
    ...
    
    // In main(), very early:
    power_management_init();
    ble_stack_init();
    

    Make sure that 

    NRF_SDH_CLOCK_LF_SRC
    CLOCK_CONFIG_LF_SRC   

    are set to XTAL and not RC.
    Can't tink of anything else thatshould cause this. But try to run your firmware on the DK and see if you see the same results so that we can re-calibrate our debugging strategy. 
  • Hi Susheel,

    So I was able to get the current draw down below 100 uA with BLE Advertising.

    It looks like our bootloader code is turning on some peripherals before loading the main application (BLE advertising task).

    If I erase the bootloader and just run the application directly I get 100 uA.

Related