This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to use Long Range on NRF52833 with SDK17 ?

Hi,

I have been trying for several days to modify the ble_app_uart project on the peripheral side to use the BLE Long Range, unsuccessfully. I use the NRF52833-DK with SDK17 and S140.

My programs returns an "ERROR 7[NRF_ERROR_INVALID_PARAM] at :0" after sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, p_advertising->p_adv_data, &p_advertising->adv_params); is called in ble_advertising_start() in ble_advertising.c

I have already been looking for answers on the DevZone but all topics are related to SDK15. I have tried adapting those answers to SDK17 but that did not work. Can someone help me?

Here is the advertising_init() function I modified from the original ble_app_uart example in main.c, and then is the ble_advertising_start function where the program fails in ble_advertising.c:

/**@brief Function for initializing the Advertising functionality.
 */
static void advertising_init(void)
{
    uint32_t               err_code;
    ble_advertising_init_t init;

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

    init.advdata.name_type          = BLE_ADVDATA_FULL_NAME;
    init.advdata.include_appearance = false;
    init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;		// This was changed for Long Range

    init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    init.srdata.uuids_complete.p_uuids  = m_adv_uuids;

    init.config.ble_adv_fast_enabled        = true;
    init.config.ble_adv_fast_interval       = APP_ADV_INTERVAL;         // This is set to 320
    init.config.ble_adv_fast_timeout        = APP_ADV_DURATION;         // This is set to 18000
	init.config.ble_adv_primary_phy         = BLE_GAP_PHY_CODED;        // This was added for Long Range
    init.config.ble_adv_secondary_phy       = BLE_GAP_PHY_CODED;        // This was added for Long Range
    init.config.ble_adv_extended_enabled    = true;                     // This was added for Long Range
    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);
}
uint32_t ble_advertising_start(ble_advertising_t * const p_advertising,
                               ble_adv_mode_t            advertising_mode)
{
    uint32_t ret;

    if (p_advertising->initialized == false)
    {
        return NRF_ERROR_INVALID_STATE;
    }

    p_advertising->adv_mode_current = advertising_mode;

    memset(&p_advertising->peer_address, 0, sizeof(p_advertising->peer_address));

    if (  ((p_advertising->adv_modes_config.ble_adv_directed_high_duty_enabled) && (p_advertising->adv_mode_current == BLE_ADV_MODE_DIRECTED_HIGH_DUTY))
        ||((p_advertising->adv_modes_config.ble_adv_directed_enabled)           && (p_advertising->adv_mode_current == BLE_ADV_MODE_DIRECTED_HIGH_DUTY))
        ||((p_advertising->adv_modes_config.ble_adv_directed_enabled)           && (p_advertising->adv_mode_current == BLE_ADV_MODE_DIRECTED))
       )
    {
        if (p_advertising->evt_handler != NULL)
        {
            p_advertising->peer_addr_reply_expected = true;
            p_advertising->evt_handler(BLE_ADV_EVT_PEER_ADDR_REQUEST);
        }
        else
        {
            p_advertising->peer_addr_reply_expected = false;
        }
    }

    p_advertising->adv_mode_current = adv_mode_next_avail_get(p_advertising, advertising_mode);

    // Fetch the whitelist.
    if ((p_advertising->evt_handler != NULL) &&
        (p_advertising->adv_mode_current == BLE_ADV_MODE_FAST || p_advertising->adv_mode_current == BLE_ADV_MODE_SLOW) &&
        (p_advertising->adv_modes_config.ble_adv_whitelist_enabled) &&
        (!p_advertising->whitelist_temporarily_disabled))
    {
        p_advertising->whitelist_in_use         = false;
        p_advertising->whitelist_reply_expected = true;
        p_advertising->evt_handler(BLE_ADV_EVT_WHITELIST_REQUEST);
    }
    else
    {
        p_advertising->whitelist_reply_expected = false;
    }

    // Initialize advertising parameters with default values.
    memset(&p_advertising->adv_params, 0, sizeof(p_advertising->adv_params));

    p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED;  // This was changed to use Long Range

    // Use 1MBIT as primary phy if no phy was selected.
    if (phy_is_valid(&p_advertising->adv_modes_config.ble_adv_primary_phy))
    {
        p_advertising->adv_params.primary_phy = p_advertising->adv_modes_config.ble_adv_primary_phy;
    }
    else
    {
        p_advertising->adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
    }

    if (p_advertising->adv_modes_config.ble_adv_extended_enabled)
    {
        // Use 1MBIT as secondary phy if no phy was selected.
        if (phy_is_valid(&p_advertising->adv_modes_config.ble_adv_secondary_phy))
        {
            p_advertising->adv_params.secondary_phy = p_advertising->adv_modes_config.ble_adv_secondary_phy;
        }
        else
        {
            p_advertising->adv_params.secondary_phy = BLE_GAP_PHY_1MBPS;
        }
    }
    p_advertising->adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;

    // Set advertising parameters and events according to selected advertising mode.
    switch (p_advertising->adv_mode_current)
    {
        case BLE_ADV_MODE_DIRECTED_HIGH_DUTY:
            ret = set_adv_mode_directed_high_duty(p_advertising, &p_advertising->adv_params);
            break;

        case BLE_ADV_MODE_DIRECTED:
            ret = set_adv_mode_directed(p_advertising, &p_advertising->adv_params);
            break;

        case BLE_ADV_MODE_FAST:
            ret = set_adv_mode_fast(p_advertising, &p_advertising->adv_params);
            break;

        case BLE_ADV_MODE_SLOW:
            ret = set_adv_mode_slow(p_advertising, &p_advertising->adv_params);
            break;

        case BLE_ADV_MODE_IDLE:
            p_advertising->adv_evt = BLE_ADV_EVT_IDLE;
            break;

        default:
            break;
    }

    if (p_advertising->adv_mode_current != BLE_ADV_MODE_IDLE)
    {
        /* IT FAILS AT THE FOLLOWING LINE */
        ret = sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, p_advertising->p_adv_data, &p_advertising->adv_params);
        if (ret != NRF_SUCCESS)
        {
            /* THUS ENTERING THIS CONDITION AND RETURNING ERROR 7 */
            return ret;
        }
        ret = sd_ble_gap_adv_start(p_advertising->adv_handle, p_advertising->conn_cfg_tag);

        if (ret != NRF_SUCCESS)
        {
            return ret;
        }
    }

    if (p_advertising->evt_handler != NULL)
    {
				NRF_LOG_RAW_INFO("Still alive here 12...\r\n");
        p_advertising->evt_handler(p_advertising->adv_evt);
    }

    return NRF_SUCCESS;
}

  • There is an example on a bit older SDK to test advertising on CODED PHY for ble_app_uart. You can find the example uploaded here by Vidar. I do not think that there are that big functional changes to this API, so worth a try to test his project.

  • Hi,

    Thank you for your input. Actually, this is thanks to this example that I managed to modify my code to test CODED_PHY. But these modifications have led to the error I raised above...

    Best regards,

    Nil

  • Update : the only way I found to avoid this error is to add p_advertising->p_adv_data->adv_data.p_data = NULL; and p_advertising->p_adv_data->adv_data.len = 0; just before calling sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, p_advertising->p_adv_data, &p_advertising->adv_params); (which is the function that raises the ERROR 7). But I guess this is not the proper way to do, and indeed my advertising still does not work...

    By running the debugger on Keil, here is the adv_data structure before setting it to NULL:

  • Sorry for late response, yes that settings does not seem to work anymore and I do not know what has changed. I need to debug this example a bit to understand what is broken with CODED PHY. I need some time for that and will be back to you when i have some info.

  • Hi Nil,
    This thread missed my attention queue, sorry for that and the delay caused by it.
    I have overlooked at your code. The simple change you need is to configure advertising data and not the scan response data in the coded phy. 

    The change that you need to do is from

        init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        init.srdata.uuids_complete.p_uuids  = m_adv_uuids;

    to 

        init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        init.advdata.uuids_complete.p_uuids  = m_adv_uuids;

Related