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);
}

Parents
  • Might be pending FPU Exceptions. Roughly 0.5mA current seem likely.

    The non-RTOS samples in the SDK should all have code (called from idle_state_handler) that silences (skips) FPU exceptions in the hardware.

    I've not played much with FreeRTOS - no idea if that code piece made it into the Nordic examples for this OS.

    You want to call this from an "idle" thread that gets called every time the CPU is supposed to start sleeping.

    The trigger seems to be a bit random - its not unlikely that your bootloader somehow triggers conditions that would lead to an FPU exception...

Reply
  • Might be pending FPU Exceptions. Roughly 0.5mA current seem likely.

    The non-RTOS samples in the SDK should all have code (called from idle_state_handler) that silences (skips) FPU exceptions in the hardware.

    I've not played much with FreeRTOS - no idea if that code piece made it into the Nordic examples for this OS.

    You want to call this from an "idle" thread that gets called every time the CPU is supposed to start sleeping.

    The trigger seems to be a bit random - its not unlikely that your bootloader somehow triggers conditions that would lead to an FPU exception...

Children
No Data
Related