API bt_hci_cmd_send_sync() is returning -5 error

Hello,

I am trying to write some code that sets the BLE Tx power on the nRF52833 SoC.

I have based my code on the sample example code provided at C:\Zypher\v1.7.0\zephyr\samples\bluetooth\hci_pwr_ctrl\src\main.c and in particular in the function set_tx_power().

static result_t bluetooth_set_ble_tx_power( uint8_t handle_type, uint16_t handle, int8_t tx_pwr_lvl )
{
    struct bt_hci_cp_vs_write_tx_power_level    *cp;
    struct bt_hci_rp_vs_write_tx_power_level    *rp;
    struct net_buf                              *buf, *rsp = NULL;
    result_t                                    result = RESULT_ERROR;

    buf = bt_hci_cmd_create( BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL, sizeof(*cp) );
    if ( buf )
    {
        cp                  = net_buf_add( buf, sizeof(*cp) );
        cp->handle          = sys_cpu_to_le16( handle );
        cp->handle_type     = handle_type;
        cp->tx_power_level  = tx_pwr_lvl;

        result = bt_hci_cmd_send_sync( BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL, buf, &rsp );
        if ( result )
        {
            uint8_t reason = rsp ? ((struct bt_hci_rp_vs_write_tx_power_level *) rsp->data)->status : 0;
            LOG_WRN( "Set Tx power err: %d reason 0x%02x\n", result, reason );
            result = RESULT_ERROR;
        }
        else
        {
            rp = (void *)rsp->data;
            LOG_INF( "Actual Tx Power: %d\n", rp->selected_tx_power );
            net_buf_unref( rsp );
            result = RESULT_OK;
        }
    }
    else
    {
        LOG_WRN( "Unable to allocate command buffer\n" );
    }

    return result;
}

I am seeing the function bt_hci_cmd_send_sync() returning error -5.

Can you please help me find the cause of this error.

Thank you.

Kind regards
Mohamed
Parents
  • I would recommend to enable the BT_LOG to right level to be able to get more context on the error.

    which controller are you using Softdevice Controller(SDC) or Zephyr Controller? The setting you have for CONFIG_BT_LL_SW_SPLIT?

  • Good Morning Susheel,

    I am developing under zephyr using

    Zephyr OS build v2.6.99-ncs1 
    nRF Connect SDK v1.7.0 

    LOG_MODULE_REGISTER(bt, LOG_LEVEL_INF);

    This is the error I am getting:

    <wrn> bt: Set Tx power err: -5 reason 0x00

    Below is the content of my prj_debug.conf file.

    # BLE
    CONFIG_BT=y
    CONFIG_BT_PERIPHERAL=y
    CONFIG_BT_GATT_CLIENT=y
    CONFIG_BT_GATT_DYNAMIC_DB=y
    
    # Turn off/reduce Bluetooth aspects
    CONFIG_BT_LL_SW_SPLIT=y
    CONFIG_BT_PHY_UPDATE=n
    CONFIG_BT_GATT_CACHING=n
    CONFIG_BT_GATT_SERVICE_CHANGED=y
    CONFIG_BT_GAP_PERIPHERAL_PREF_PARAMS=n
    CONFIG_BT_HCI_VS_EXT=n
    CONFIG_BT_CTLR_PRIVACY=n
    CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT=1
    CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=251
    CONFIG_BT_CTLR_PHY_2M=n
    CONFIG_BT_USER_DATA_LEN_UPDATE=n
    CONFIG_BT_USER_PHY_UPDATE=n
    
    # Increase BLE packet sizes
    CONFIG_BT_DATA_LEN_UPDATE=y
    CONFIG_HEAP_MEM_POOL_SIZE=2048
    CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n
    CONFIG_BT_BUF_ACL_RX_SIZE=255
    CONFIG_BT_ATT_PREPARE_COUNT=1
    #Maximum number of pending TX buffers with a callback
    #CONFIG_BT_CONN_TX_MAX=2
    CONFIG_BT_CONN_TX_MAX=10
    #Number of L2CAP TX buffers
    CONFIG_BT_L2CAP_TX_BUF_COUNT=10
    #CONFIG_BT_L2CAP_TX_BUF_COUNT=2
    CONFIG_BT_L2CAP_TX_MTU=247
    CONFIG_BT_CTLR_RX_BUFFERS=1
    CONFIG_BT_BUF_ACL_TX_COUNT=1
    CONFIG_BT_BUF_ACL_TX_SIZE=251
    #NRF_SDH_BLE_GATT_MAX_MTU_SIZE=247
    

    Can you spot anything in my config that could explain the error I am getting?

    Thank you for your help.

    Kind regards
    Mohamed
  • Hi,

    So, you want me to replace in prj_debug.conf the line 

    CONFIG_BT_LL_SW_SPLIT=y

    with

    BT_LL_SOFTDEVICE=y

    Isn't it CONFIG_BT_LL_SOFTDEVICE i.e. with the prefix 'CONFIG_'?

  • Hi Susheel,

    bt_hci_cmd_send_sync() is working fine now after I made the following changes in prj_debug.conf. Both config items were set to 'n'.

    CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y
    CONFIG_BT_HCI_VS_EXT=y
    Does this make sense?
    Although the error from bt_hci_cmd_send_sync() is gone, the actual BLE TX power settings is not changing. I tried different values -40, -30, -20, 0 and 8 dBm and only -40 seems to work. Also, I noticed upon BLE disconnection the power level goes back to the default 0 dBm.
    Can you please help?
    Kind regards
    Mohamed
  • Learner said:
    CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y
    CONFIG_BT_HCI_VS_EXT=y
    Does this make sense?

    Hi Mohammed,

    Yes, this makes sense and CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL is necessary for the TX power control to work.

    Learner said:
    Although the error from bt_hci_cmd_send_sync() is gone, the actual BLE TX power settings is not changing. I tried different values -40, -30, -20, 0 and 8 dBm and only -40 seems to work.

    There is a known issue with setting TX power before the advertising parameters are set. This is documented in known issues for the SDC. Apart from that, it should work as I tested this on other nRF52 variants. 

    Learner said:
    Also, I noticed upon BLE disconnection the power level goes back to the default 0 dBm.

    This could be true that this setting is per role, I normally would call bluetooth_set_ble_tx_power for every role (just connected, disconnected, advertiser, scanner).

  • Good Morning Susheel,

    Thank you for your response.

    There is a known issue with setting TX power before the advertising parameters are set. This is documented in known issues for the SDC. Apart from that, it should work as I tested this on other nRF52 variants.

    I believe I am setting the advertising parameters before setting the BLE Tx power.

    This is what I have implemented. Please let me know if you spot anything wrong.

    First, I call 

    bluetooth_Initialise();

    result_t bluetooth_Initialise(void)
    {
        int err;
    
        /* Register connection callbacks */
        bt_conn_cb_register(&conn_callbacks);
    
        /* Register custom service */
        err = bt_gatt_service_register(&custom_svc);
        if (err)
        {
            LOG_ERR("Custom service failed to start (err %d)", err);
            return err;
        }
    
        /* Set ID string */
        ...
        
        /* Enable bluetooth with the ready callback */
        return (bt_enable(bluetooth_Ready) == 0 ? RESULT_OK : RESULT_ERROR);
    }
    

    static void bluetooth_Ready(int err)
    {
        if (err)
        {
            LOG_ERR("Bluetooth init failed (err %d)", err);
            return;
        }
    
        LOG_INF("Bluetooth initialised");
    
        /* Start advertising */
        err = bluetooth_start_adv();    
        if (err)
        {
            LOG_ERR("Advertising failed to start (err %d)", err);
            return;
        }
    
        LOG_INF("Advertising successfully started, awaiting connections");
    }
    

    
    static result_t bluetooth_start_adv( void )
    {
        result_t result = RESULT_ERROR;
    
        /* Select the appropriate the BLE advertising period using the current configuration setting.
         * This can be one of these settings. Note, it is a range rather than an abvsolute value.
         *   30 ms -   60 ms
         *  100 ms -  150 ms
         * 1000 ms - 1200 ms
         */
        if ( ( ble_adv_period ) == 0  || ( ble_adv_period >= 200 )   )
        {
            /* 1000 ms - 1200 ms */
            result = bt_le_adv_start(BT_LE_ADV_CONN_SLOW, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
        }
        else if ( ble_adv_period >= 80 )
        {
            /* 100 ms - 150 ms */
            result = bt_le_adv_start(BT_LE_ADV_CONN_FAST_2, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
        }
        else if ( ble_adv_period >= 1 )
        {
            /* 30 ms - 60 ms */
            result = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
        }
    
        return result;
    }
    

    Below are the functions that set the BLE Tx power level. It is called after the BLE initialisation and  advertising have been setup and started.

    result_t bluetooth_set_tx_power( int8_t tx_pwr_lvl_dbm )
    {
        result_t result = RESULT_ERROR;
    
    
        /* Now, set the BLE Tx power level in dBm*/
        if ( !conn )
        {
            result = bluetooth_set_ble_tx_power( BT_HCI_VS_LL_HANDLE_TYPE_ADV, 0, tx_pwr_lvl_dbm );
        }
        else
        {
            result = bluetooth_set_ble_tx_power( BT_HCI_VS_LL_HANDLE_TYPE_CONN, default_conn_handle, tx_pwr_lvl_dbm );
        }
    
        return result;
    }
    

    static result_t bluetooth_set_ble_tx_power( uint8_t handle_type, uint16_t handle, int8_t tx_pwr_lvl )
    {
        struct bt_hci_cp_vs_write_tx_power_level    *cp;
        struct bt_hci_rp_vs_write_tx_power_level    *rp;
        struct net_buf                              *buf, *rsp = NULL;
        result_t                                    result = RESULT_ERROR;
    
        buf = bt_hci_cmd_create( BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL, sizeof(*cp) );
        if ( buf )
        {
            cp                  = net_buf_add( buf, sizeof(*cp) );
            cp->handle          = sys_cpu_to_le16( handle );
            cp->handle_type     = handle_type;
            cp->tx_power_level  = tx_pwr_lvl;
    
            LOG_INF( "Set Tx power: %d\n", cp->tx_power_level );
    
            result = bt_hci_cmd_send_sync( BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL, buf, &rsp );
            if ( result )
            {
                uint8_t reason = rsp ? ((struct bt_hci_rp_vs_write_tx_power_level *) rsp->data)->status : 0;
                LOG_WRN( "Set Tx power err: %d reason 0x%02x\n", result, reason );
                result = RESULT_ERROR;
            }
            else
            {
                rp = (void *)rsp->data;
                LOG_INF( "Actual Tx Power: %d\n", rp->selected_tx_power );
                net_buf_unref( rsp );
                result = RESULT_OK;
            }
        }
        else
        {
            LOG_WRN( "Unable to allocate command buffer\n" );
        }
    
        return result;
    }
    

    Kind regards

    Mohamed

  • I am really sorry for the delays, I could not test your code snippet, but will try to come back to you by tomorrow, thanks for your patience.

Reply Children
No Data
Related