Distinguish between Coded S2 and S8 (NRF52840)

Hi,

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
Parents
  • Hi

    So, after looking at this it seems you're reading the incorrect defines here. struct bt_conn_le_phy_info  only provides uint8_t tx_phy and uint8_t rx_phy  and only correspond to 1MBPS PHY, 2MBPS PHY and CODED PHY, so you should look at these instead of the BT_CONN_LE_PHY_OPT_CODED parameters.

    /** All LE PHYs. */
    #define BT_CONN_LE_PHY_PARAM_ALL BT_CONN_LE_PHY_PARAM(BT_GAP_LE_PHY_1M |   \
    						      BT_GAP_LE_PHY_2M |   \
    						      BT_GAP_LE_PHY_CODED, \
    						      BT_GAP_LE_PHY_1M |   \
    						      BT_GAP_LE_PHY_2M |   \
    						      BT_GAP_LE_PHY_CODED)

    By hovering BT_GAP_LE_PHY_CODED you can see that it also returns 4 if in use:

     

    I think you're running in the option you're setting, but you will need to check the option's return code specifically to make sure. Or connect with the nRF Connect app for Android/iOS and see what PHY is used there.

    Best regards,

    Simon

Reply
  • Hi

    So, after looking at this it seems you're reading the incorrect defines here. struct bt_conn_le_phy_info  only provides uint8_t tx_phy and uint8_t rx_phy  and only correspond to 1MBPS PHY, 2MBPS PHY and CODED PHY, so you should look at these instead of the BT_CONN_LE_PHY_OPT_CODED parameters.

    /** All LE PHYs. */
    #define BT_CONN_LE_PHY_PARAM_ALL BT_CONN_LE_PHY_PARAM(BT_GAP_LE_PHY_1M |   \
    						      BT_GAP_LE_PHY_2M |   \
    						      BT_GAP_LE_PHY_CODED, \
    						      BT_GAP_LE_PHY_1M |   \
    						      BT_GAP_LE_PHY_2M |   \
    						      BT_GAP_LE_PHY_CODED)

    By hovering BT_GAP_LE_PHY_CODED you can see that it also returns 4 if in use:

     

    I think you're running in the option you're setting, but you will need to check the option's return code specifically to make sure. Or connect with the nRF Connect app for Android/iOS and see what PHY is used there.

    Best regards,

    Simon

Children
  • I'm try same exercise to test different Coded PHY, but settings as below into the update_phy function:

    	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);
    	}

    also I've enabled the Kconfig

    CONFIG_BT_CTLR_PHY_CODED=y

    into the prj.conf file but the log always write PHY updated. New PHY: 1M.

    Also by nRF Connect App (Android) it give in Log view PHY = LE 1M.

    How to be sure about the mode?

    Thanks and best regards.

    Fabio

  • Hi Fabio

    This config only enables support for the Bluetooth 5.0 Coded PHY in the controller. You still need to enable it in the application. Here it seems like you're setting the preferred PHY in the connection parameters, but the device likely still advertises in 1MBPS PHY. I'd recommend checking out the peripheral_hr_coded sample available here.

    Best regards,

    Simon

Related