Setting Coded PHY to S=8 or S=2

Using NCS 2.0.0 and Testing on nRF52840

I run the Throughput Example from NCS on the nRF52840

When I type

"Config phy coded_s2"  or "config phy coded_s8"

I get the return of phy set to Coded S2 or S8 accordingly

but when i type RUN

i get an Error

W:opcode 0x2032 status 0x11

PHY update Failed: -5

This is the same result i get when i added the bt_conn_le_phy_update()  function to my code

The device appears to be running in coded Phy since i need to set my wireshark to coded to see the advertisement and connection information.

but what coded version is it running S=2 or S=8?

also, why does the update_phy function fail?

  • Hi,

    I have never thought of this, but BT_CONN_LE_OPT_CODED is (at least by default) BT_CONN_LE_PHY_OPT_CODED_S8 (125kbps). I don't think anyone is using BT_CONN_LE_PHY_OPT_CODED_S2 (500kbps) because there is literally no improvement in range (compared to 1MBPS), but the time on-air is doubled.

    Part of the reason why the sniffer likely don't differentiate between the two, is that the radio (afaik) decode S2 and S8 on the fly without no change in rx (though you may likely see a difference in timing). If you want to switch between the two, I suggest to possible go to 1MBPS in between. 

    Best regards,
    Kenneth

  • Hi Kenneth,

    I have an additional question which is directly related to that post. I'm trying to understand how I exactly can differentiate between CODED S=2 and S=8. I've experimented with the BLE fundamentals Lesson 3, Exercise 2 and set the PHY modes (1M, 2M, S2 and S8) (Also CONFIG_BT_CTLR_PHY_CODED=y is set in prj.conf)

    I'm setting the PHY directly in the peripheral with the update_phy(...) function. In the .options field, I tested BT_CONN_LE_PHY_OPT_CODED_S2 and  BT_CONN_LE_PHY_OPT_CODED_S8.

    static void update_phy(struct bt_conn *conn) {
        int err;
        const struct bt_conn_le_phy_param preferred_phy = {
            .options = BT_CONN_LE_PHY_OPT_CODED_S8,
            .pref_rx_phy = BT_GAP_LE_PHY_CODED,
            .pref_tx_phy = BT_GAP_LE_PHY_CODED,
        };
        err = bt_conn_le_phy_update(conn, &preferred_phy);
        if (err) {
            LOG_ERR("bt_conn_le_phy_update() returned %d", err);
        }
    }

    Although I change the options I'm always getting getting tx_phy = 4 and rx_phy = 4 in the on_le_phy_updated(...) function, which is according to the macro BT_CONN_LE_TX_POWER_PHY_CODED_S2

    void on_le_phy_updated(struct bt_conn *conn, struct bt_conn_le_phy_info *param) {
        // PHY Updated
        if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_1M) {
            LOG_INF("PHY updated. New PHY: 1M");
        }
        else if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_2M) {
            LOG_INF("PHY updated. New PHY: 2M");
        }
        else if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_CODED_S8) {
            LOG_INF("PHY updated. New PHY: Long Range S8");
        }
        else if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_CODED_S2) {
            LOG_INF("PHY updated. New PHY: Long Range S2");
        }
    }

    Is it possible that the function of checking the PHY is incorrect? Cause in update_phy(...) we are setting BT_GAP_LE_PHY_CODED for  pref_rx_phy and  pref_tx_phy (which is 4). And I think these values are just the same in the on_le_phy_updated(...) (param->tx_phy, param->rx_phy) So there can be no distinction between S2 and S8?

    So my question now, is the update_phy(...) function wrong and there is no possibility to set S8 or is the on_le_phy_updated(...) function wrong.

    Thanks a lot,
    Phobios
Related