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?

Parents
  • W:opcode 0x2032 status 0x11

    The opcode is 0x2032. We need to convert it to binary first. 0x2032 = 0010 0000 0011 0010. So the first 6 bits represent the OGF, which is 0x08 in this case. And the last 10 bits represent the OCF, which is 0x32. With this we can find the corresponding HCI command in the core spec, and that will be le_set_phy:

    From BT core spec I can find that the status code 0x11 is:

    So basically this means that when trying to call le_set_phy that it return Unsupported.

    In this case it sounds like coded phy is not supported, so I suggest to try in prj.conf:
    CONFIG_BT_CTLR_PHY_CODED=y

    Does this help?

  • Thanks  I added that to the Project and it no longer gets an error.  I then added the same to my code and i get the error.  I will look for the differences in m code and the throughput example to see why it throughs an error.

  • I know this has been a long while.  but i got the coded PHY sample from NCS working and responds to the S=2 and S=8 accordingly.  I thought I copied the same code to my Central and Peripheral projects and it gives me the failure.  do the options of S=8 have to be set in both Peripheral and Central?  i have my connection params set as below and i also tried to set the phy option to S=8 in the phy_change function.(these are both central)  but i get PHY update failed.  any thoughts on what I am missing?

    static struct bt_conn_le_create_param *conn_params = BT_CONN_LE_CREATE_PARAM(
    		BT_CONN_LE_OPT_CODED | BT_CONN_LE_OPT_NO_1M|BT_CONN_LE_PHY_OPT_CODED_S8, //WRC test for S8
    		BT_GAP_SCAN_FAST_INTERVAL,
    		BT_GAP_SCAN_FAST_INTERVAL);
    

Reply
  • I know this has been a long while.  but i got the coded PHY sample from NCS working and responds to the S=2 and S=8 accordingly.  I thought I copied the same code to my Central and Peripheral projects and it gives me the failure.  do the options of S=8 have to be set in both Peripheral and Central?  i have my connection params set as below and i also tried to set the phy option to S=8 in the phy_change function.(these are both central)  but i get PHY update failed.  any thoughts on what I am missing?

    static struct bt_conn_le_create_param *conn_params = BT_CONN_LE_CREATE_PARAM(
    		BT_CONN_LE_OPT_CODED | BT_CONN_LE_OPT_NO_1M|BT_CONN_LE_PHY_OPT_CODED_S8, //WRC test for S8
    		BT_GAP_SCAN_FAST_INTERVAL,
    		BT_GAP_SCAN_FAST_INTERVAL);
    

Children
  • Hi again.

    Have you looked at central_hr_coded and peripheral_hr_coded examples?

    Kenneth

  • That is what i am using as a base.  Wireshark labels the packets as Coded (but what one is it 2 or 8?), I wanted to run tests to see the difference between S=2 and S=8 with the modified base code.  I cannot get it to "update successfully" like i can in the throughput example.  I clearly am missing something, just have not been able to find it

  • 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