How to Force LE Coded PHY S=8 (125 kbps) for Extended Advertising on nRF52840 with Zephyr/nRF Connect SDK?

Hi all,

I'm working on a project with an nRF52840 using the nRF Connect SDK (version X.Y.Z) and Zephyr RTOS. My goal is to achieve maximum possible range for non-connectable extended advertising, so I'm trying to use LE Coded PHY S=8 (125 kbps).

In my sender application (peripheral), I'm setting up extended advertising with the following parameters:

struct bt_le_adv_param adv_param = {
    .id = BT_ID_DEFAULT,
    .sid = 0U,
    .secondary_max_skip = 0U,
    .options = (BT_LE_ADV_OPT_EXT_ADV | BT_LE_ADV_OPT_CODED), // Requesting Coded PHY
    .interval_min = APP_ADV_INTERVAL_MIN,
    .interval_max = APP_ADV_INTERVAL_MAX,
    .peer = NULL,
};

On my receiver (another nRF52840, using the Nordic nrf_bt_scan library via #include <bluetooth/scan.h>), I'm observing the PHYs used. The scan parameters on the receiver are set with BT_LE_SCAN_OPT_CODED.

The receiver logs consistently show:
PHY: Prim 4, Sec 4

This indicates that both primary and secondary advertising channels are using LE Coded PHY S=2 (500 kbps), not S=8 (125 kbps, which would be code 0x03 as per the Bluetooth Core Spec for the LE Extended Advertising Report event).

I've experimented with varying the advertising payload size (from very small, ~15 bytes, to larger, ~60 bytes, and even tried to go up to ~200 bytes before hitting -EMSGSIZE errors with bt_le_ext_adv_set_data), but the sender consistently seems to choose S=2. The RSSI levels observed by the receiver (even down to -95dBm) also don't seem to influence the sender's PHY choice for advertising.

My understanding is that the nRF52840 hardware and SoftDevice/controller support S=8.

My question is:
Is there a Kconfig option (e.g., CONFIG_BT_CTLR_...) or another mechanism within the nRF Connect SDK / Zephyr environment that allows me to explicitly configure or prefer LE Coded PHY S=8 (125 kbps) when BT_LE_ADV_OPT_CODED is used for extended advertising on the nRF52840? I've looked through hci_types.h and can see definitions for S2/S8 PHY options for connection PHY updates, but it's not clear how to enforce this for advertising PHY selection via the GAP API.

Any guidance or pointers to relevant documentation/Kconfig options would be greatly appreciated!

Thanks

Parents
  • Hi Lorenz242,

    Which function are you using to extract the PHY value? A value of 4 doesn't necessarily mean S=2. For example, here it means Coded PHY with unspecified encoding: sdk-zephyr/include/zephyr/bluetooth/gap.h at v4.0.99-ncs1-1 · nrfconnect/sdk-zephyr.

    Hieu

  • I'm getting the PHY values from the primary_phy and secondary_phy members of device_info->recv_info (which is a const struct bt_le_scan_recv_info *) within the filter_no_match callback of the Nordic nrf_bt_scan API (using #include <bluetooth/scan.h>).

    // From the scan_filter_no_match_cb:
    // struct bt_scan_device_info *device_info;
    // ...
    if (gps_data_deserialize_from_adv(manuf_data_ptr, manuf_data_len,
                                      &received_manuf_id, &received_gps_data)) {
        if (received_manuf_id == GPS_TRACKER_MANUFACTURER_ID) {
            LOG_INF("GPS-Tag gefunden: %s, RSSI: %d dBm, PHY: Prim %u, Sec %u, TX-Power: %d dBm",
                    addr_str,
                    device_info->recv_info->rssi,
                    device_info->recv_info->primary_phy, // This is what I'm logging as "Prim"
                    device_info->recv_info->secondary_phy, // This is what I'm logging as "Sec"
                    device_info->recv_info->tx_power);
        }
    }

    My interpretation of the logged 4 as S=2 (and 3 as S=8) is based on the Bluetooth Core Spec (v6.1, page 2357/ 2358)

Reply
  • I'm getting the PHY values from the primary_phy and secondary_phy members of device_info->recv_info (which is a const struct bt_le_scan_recv_info *) within the filter_no_match callback of the Nordic nrf_bt_scan API (using #include <bluetooth/scan.h>).

    // From the scan_filter_no_match_cb:
    // struct bt_scan_device_info *device_info;
    // ...
    if (gps_data_deserialize_from_adv(manuf_data_ptr, manuf_data_len,
                                      &received_manuf_id, &received_gps_data)) {
        if (received_manuf_id == GPS_TRACKER_MANUFACTURER_ID) {
            LOG_INF("GPS-Tag gefunden: %s, RSSI: %d dBm, PHY: Prim %u, Sec %u, TX-Power: %d dBm",
                    addr_str,
                    device_info->recv_info->rssi,
                    device_info->recv_info->primary_phy, // This is what I'm logging as "Prim"
                    device_info->recv_info->secondary_phy, // This is what I'm logging as "Sec"
                    device_info->recv_info->tx_power);
        }
    }

    My interpretation of the logged 4 as S=2 (and 3 as S=8) is based on the Bluetooth Core Spec (v6.1, page 2357/ 2358)

Children
No Data
Related