SDK15 long advertising and long range connect

Hello all,

    I used SDK15 and nRF52840 DK made a long range advertising and long range connected.

    I modified the ble_app_uart_c and ble_app_uart example, the long range advertising I modified is ok(the smartphone nRF connect is can't scan this device), and the ble_app_uart_c is modified ok(the central is scan this device ok).

    I modified the long range connect found in SDK14.2 I used 

    ble_opt_t  opts;

    opts.gap_opt.preferred_phys.tx_phys = BLE_GAP_PHY_CODED;

    opts.gap_opt.preferred_phys.rx_phys = BLE_GAP_PHY_CODED;

    sd_ble_opt_set(BLE_GAP_OPT_PREFERRED_PHYS_SET, &opts);

    I found the SDK15 has not this set.

    And in SDK15, the central and peripheral connected , and central call the sd_ble_gap_phy_update(m_conn_handle, &phy_request_params)(In SDK14.2 is sd_ble_gap_phy_request); to update the params, but the peripheral is not received the BLE_GAP_EVT_PHY_UPDATE or BLE_GAP_EVT_PHY_UPDATE_REQUEST.  in contrast, peripheral call this function ,central also not receive this event.  But central call this function themself is enter the BLE_GAP_EVT_PHY_UPDATE function. If peripheral call this function themself is enter the BLE_GAP_EVT_PHY_UPDATE function too, and in this BLE_GAP_EVT_PHY_UPDATE case printf the phys is -4(BLE_GAP_PHY_CODED), update success ?  But I used SEGGER  Embedded studio debug watch the Radio register, the MODE register is always 0 (always 1Mbps)

    So I have some question,

    1. How to achieve long range connected?

    2. I used long range advertising (BLE_GAP_PHY_CODED)  I want to know the send connect request(ble_app_uart_c) is used 1Mbps or 125kbps ?Whether could I modified the send connect request used physical channel?

    3.Except used SEGGER  Embedded studio debug to watch the Radio register whether I could used software printf this register to see the value?

    4. Call the sd_ble_gap_phy_update() is modified the physical channel is for themself or Both sides?

    5. I see the central is could receice the extend advertising but the peripheral is always adv length limited?(or not used ble_advertising.c used softdevice function)

Best Regards,



  • Hello,

    I think there must be a different problem. I tried to run the attached projects with v.6.1.0 and it worked. Have you made any other changes apart from changing to the latest softdevice version? 

  • Hello Vidar Beg, 

    I downloaded the example and flashed it on two SDK boards. The example is working properly.

    In the second step, I provided the Central with the new 6.1.0 stack. The connection to the peripheral is still possible.

    Then I also wanted to adjust the stack for the peripheral. The project can also be compiled and flashed.

    The peripheral also starts advertising.

    However, no connection is established to the central, where is the problem?

    Many Thanks

  • Hello Tina,

    1. It will use code phy if the advertisement is done with code phy

    2. sd_ble_gap_phy_update() can be used to change the PHY once connected. What PHY use to advertise is configured in advertising init (1M or coded) 

    3. You will not get a BLE_GAP_EVT_PHY_UPDATE_REQUEST unless the peer request a phy change

    4. Sorry I'm not sure I understand the question, could you elaborate? 

  • Hello Vidor Berg,

         Thanks for your reply, and I still have doubts.

         1.Central how to know the send connect request used PHY CODED or 1Mbps or 2Mbps ?(whether is same to advertising?)

         2. If I have no request the connected used sd_ble_gap_phy_update(), which is the connect physical channel?(1Mbps 2Mbps 125kbps or related connect request)

         3. I see the docment and test , according to document connected and will enter event BLE_GAP_EVT_PHY_UPDATE_REQUEST, but test result is central and peripheral has not enter this case event. Only I call the sd_ble_gap_phy_update() in BLE_GAP_EVT_CONNECTED, and wiil enter BLE_GAP_EVT_PHY_UPDATE event, Why ?

         4.Softdevice is default support three physical channel and have not params to set support which one?

    Best Regards,


  • Hello Tina, 

    You can establish the connection with code phy if both sides support it. Attached a modified version of the UART client and peripheral example that do this. 

    1. See modifications I made in UART example:

    diff --git a/examples/ble_central/ble_app_uart_c_lr/main.c b/examples/ble_central/ble_app_uart_c_lr/main.c
    index f0e543c..4dd82ac 100644
    --- a/examples/ble_central/ble_app_uart_c_lr/main.c
    +++ b/examples/ble_central/ble_app_uart_c_lr/main.c
    @@ -98,23 +98,24 @@ static ble_gap_conn_params_t const m_connection_param =
         (uint16_t)SUPERVISION_TIMEOUT       // Supervision time-out
    -static uint8_t m_scan_buffer_data[BLE_GAP_SCAN_BUFFER_MIN]; /**< buffer where advertising reports will be stored by the SoftDevice. */
    +static uint8_t m_scan_buffer_data[BLE_GAP_SCAN_BUFFER_EXTENDED_MIN]; /**< buffer where advertising reports will be stored by the SoftDevice. */
     /**@brief Pointer to the buffer where advertising reports will be stored by the SoftDevice. */
     static ble_data_t m_scan_buffer =
     /** @brief Parameters used when scanning. */
     static ble_gap_scan_params_t const m_scan_params =
         .active   = 1,
    +    .extended = 1,
         .interval = SCAN_INTERVAL,
         .window   = SCAN_WINDOW,
         .timeout          = SCAN_DURATION,
    -    .scan_phys        = BLE_GAP_PHY_1MBPS,
    +    .scan_phys        = BLE_GAP_PHY_CODED,
         .filter_policy    = BLE_GAP_SCAN_FP_ACCEPT_ALL,
    @@ -344,6 +345,8 @@ static void on_adv_report(ble_gap_evt_adv_report_t const * p_adv_report)
         ret_code_t err_code;
    +    NRF_LOG_INFO("ADV. report");
         if (ble_advdata_uuid_find(p_adv_report->data.p_data, p_adv_report->data.len, &m_nus_uuid))
             err_code = sd_ble_gap_connect(&p_adv_report->peer_addr,
    @@ -394,15 +397,23 @@ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
                 NRF_LOG_INFO("Connected to target");
                 err_code = ble_nus_c_handles_assign(&m_ble_nus_c, p_ble_evt->evt.gap_evt.conn_handle, NULL);
    +            err_code = sd_ble_gap_rssi_start(p_ble_evt->evt.gap_evt.conn_handle, 10, 0);
    +            APP_ERROR_CHECK(err_code);
                 err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
                 // start discovery of services. The NUS Client waits for a discovery result
                 err_code = ble_db_discovery_start(&m_db_disc, p_ble_evt->evt.gap_evt.conn_handle);
    +        case BLE_GAP_EVT_RSSI_CHANGED:
    +            NRF_LOG_INFO("RSSI : %d dBm", p_gap_evt->params.rssi_changed.rssi);
    +            break;
             case BLE_GAP_EVT_TIMEOUT:
                 if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN)
    diff --git a/examples/ble_peripheral/ble_app_uart_lr/main.c b/examples/ble_peripheral/ble_app_uart_lr/main.c
    index 16ab0a1..94e4aca 100644
    --- a/examples/ble_peripheral/ble_app_uart_lr/main.c
    +++ b/examples/ble_peripheral/ble_app_uart_lr/main.c
    @@ -610,12 +610,17 @@ static void advertising_init(void)
         init.advdata.include_appearance = false;
         init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
    -    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.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    +    init.advdata.uuids_complete.p_uuids  = m_adv_uuids;
    +    init.config.ble_adv_fast_enabled     = true;
    +    init.config.ble_adv_fast_interval    = APP_ADV_INTERVAL;
    +    init.config.ble_adv_fast_timeout     = APP_ADV_DURATION;
    +    init.config.ble_adv_primary_phy      = BLE_GAP_PHY_CODED;
    +    init.config.ble_adv_secondary_phy    = BLE_GAP_PHY_CODED;
    +    init.config.ble_adv_extended_enabled = true;
    -    init.config.ble_adv_fast_enabled  = true;
    -    init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
    -    init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
         init.evt_handler = on_adv_evt;
         err_code = ble_advertising_init(&m_advertising, &init);
    @@ -688,7 +693,8 @@ static void advertising_start(void)
     int main(void)
    -    bool erase_bonds;
    +    bool       erase_bonds;
    +    ret_code_t err_code; 
         // Initialize.
    @@ -707,6 +713,8 @@ int main(void)
         printf("\r\nUART started.\r\n");
         NRF_LOG_INFO("Debug logging for UART over RTT started.");
    +    err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV,  0, 8);
    +    APP_ERROR_CHECK(err_code);
         // Enter main loop.
         for (;;)

    2. Central will connect with coded PHY

    3. Softdevice configures the radio at the beginning of radio events, and resets it when the event is finished. Thus, it's hard to read the radio registers when debugging as you need to halt the CPU while the radio is being used. 

    4.  It depends on GAP role. Please have a look the message sequence charts here:

    5. Max. adv. length should be 255 with advertisement extension.

    Note: S140 v.6.1.0 has qualified support for LE Advertising Extensions and Long range and replaces  s140 6.0.0 distributed with SDK 15.0.0