set tx power with tx power service on zephyr

hello Nordic

i am using nrf52840, with zephyr 

i wish to use the nrfConnect Tx power service to read and to SET my Tx power

but in ncs in zephyr/subsys/bluetooth/services/tps.c i see implementation only for "read_tx_power_level"

does it mean that the serice does not support set of the tx power or that the use of setting via the service is done somewhere else, if so can you direct me to where ?

hope to read from you soon

best regards

Ziv 

Parents
  • Hi,

    The Tx Power Service (TPS) is a Bluetooth defined service, you can find the specification on this page. If you look at chapter 3 of the specification, you can see that only Read property is mandatory, while other properties are marked ‘X’ (excluded/not permitted).

    If you want to set the TX power, you need to create a custom service for this.

    Best regards,
    Jørgen

  • Hi,

    ziv123 said:
    i saw there is an example in zephyr/samples/bluetooth/hci_pwr_ctrl , i wanted to make sure i understand it right then .. is it just for the nrf52840 peripheral side and it is actually not showing how to set the tx power from a central side, after connection has been established and the nrf52840 peripheral is configured to by it self try save on tx power via the analysing of the RSSI ?

    Yes, that is correct.

    ziv123 said:
    is it actually possible to change the tx power within an already established ble connection via some custom service

    Yes, you you create a custom service, you can change the TX power when the set TX power characteristics is written, just like the sample changes the power dynamically based on RSSI.

    ziv123 said:
    is there some service that already contain this feature?

    I'm not aware of any such service, but you can follow "nRF Connect SDK Bluetooth Low Energy tutorial part 1: Custom Service in Peripheral role" to create your own custom service in nRF Connect SDK.

    Best regards,
    Jørgen

  • hi Jorgen

    i am using "Zephyr version: 2.6.99 (/home..), build: v2.6.99-ncs1-1

    i tried to use the implementation of the set_tx_power from the hci_pwr_ctrl example in my code

    {
        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;
    	int err;
    
        buf = bt_hci_cmd_create(BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL, sizeof(*cp));
        if (!buf) 
        {
    		LOG_ERR("Unable to allocate command buffer %d", 0);
    		return;
    	}
        LOG_INF("in TX_POWER INIT BUFFER CREATED %d", 0);
    	cp = net_buf_add(buf, sizeof(*cp));
    	cp->handle = sys_cpu_to_le16(0);
    	cp->handle_type = BT_HCI_VS_LL_HANDLE_TYPE_ADV;
        cp->tx_power_level = 4;
    
        err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL, buf, &rsp);
        
        if (err) {
    		uint8_t reason = rsp ?
    			((struct bt_hci_rp_vs_write_tx_power_level *)
    			  rsp->data)->status : 0;
    		LOG_ERR("Set Tx power err: %d reason 0x%02x\n", err, reason);
    		return;
    	}
    
    	rp = (void *)rsp->data;
    	LOG_INF("Actual Tx Power: %d\n", rp->selected_tx_power);
    
        net_buf_unref(rsp);
    }

    my prf.conf:

    # BLE Related Configs
    CONFIG_BT=y
    CONFIG_BT_PERIPHERAL=y
    CONFIG_BT_DEVICE_NAME="TX_PWR_Canary"
    CONFIG_BT_DEVICE_NAME_DYNAMIC=y
    CONFIG_BT_DIS=y
    CONFIG_BT_DIS_PNP=n
    CONFIG_BT_DIS_MODEL="Canary"
    CONFIG_BT_DIS_MANUF="Augury Inc."
    CONFIG_BT_DIS_SERIAL_NUMBER=y
    CONFIG_BT_DIS_FW_REV=y
    CONFIG_BT_DIS_HW_REV=y
    CONFIG_BT_DIS_SW_REV=n
    CONFIG_BT_CTLR_ADVANCED_FEATURES=y
    CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y
    CONFIG_BT_CTLR_TX_PWR_MINUS_20=y
    
    # Below is setup to let DIS information be read from settings
    CONFIG_SETTINGS_RUNTIME=y
    CONFIG_SETTINGS=y
    CONFIG_SETTINGS_NONE=y
    CONFIG_BT_SETTINGS=y
    CONFIG_BT_DIS_SETTINGS=y
    CONFIG_BT_DIS_STR_MAX=50
    CONFIG_BT_GATT_CACHING=n
    CONFIG_BT_HCI_VS_EXT=y
    
    
    # Some command handlers require a large stack.
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048

    strangely i got an error that i could not find in the my ncs directory

    "<wrn> bt_hci_core: opcode 0xfc0e status 0x42" what does this error mean, (also why the use of opcode 0xFC0E which is not if i understand for production tests) ?

    and the "bt_hci_cmd_send_sync(..) returns err num -5, with reason 0x00

    if i add the following to my prj.conf:

    CONFIG_MAIN_STACK_SIZE=2048
    CONFIG_BT_LL_SOFTDEVICE=n
    CONFIG_BT_LL_SW_SPLIT=y

    then i get success from the function but in fact the tx_power does not change at all, not in advertising and not in connection

    would be happy to understand what does the stack size and the sw split configs contribute, and also what am i missing or doing wrong that prevent the change to the tx power (stays on default '0' all the time)

    also i wonder why setting CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y, in the prj.conf, prevent  using the effect of  CONFIG_BT_CTLR_TX_PWR_MINUS_20=y,  for example ?

    hope to read from you soon, i actually re-edit and re-entered my replay since i did not see any message indication that my replay was received and.. i hope i get some now

    best regards

    Ziv

  • hi Jorgen

    is this on research or something ?

    i have posted a replay more the 5 days ago, re-posted an edited the replay 3 days ago and no replay

    hope to read from you soon

    best regards

    Ziv 

  • Hi,

    0xFC0E is the opcode of BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL. As you can see from the HCI VS API, this is defined as ((0x000E) | ((0x3F) << 10)) = 0xFC0E. As far as I can see, status code 0x42 means BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER

    I tested you code and configs together with the peripheral_lbs example in NCS v1.8.0, and the TX power seems to be changed correctly with the latest addition (actually only "CONFIG_BT_LL_SW_SPLIT=y" is need in my test). Verified that the RSSI is significantly lower with TX output power set to -40 through set_tx_power().

    It looks like you are using an older version, can you try with NCS v1.8.0?

    Best regards,
    Jørgen

Reply Children
  • hi

    seems that moving to ncs 1.8 forces me to update to zephyr-sdk-0.13.2 (from 0.12.4) 

    is it really a must or am i missing something ?

    also, seems that when moving to the new zephyr sdk i have a problem with the dfu (based on the smp service), i use the nrfConnect for the dfu and it seems like its done ok but then after reset the version remains the old version. any ideas on why is that, maybe i need to change some configs ? 

    do i also need to update the MCUBoot or/and the bootloader version for this to work ?

    hope to read from you soon

    best regards

    Ziv

  • Hi,

    ziv123 said:

    seems that moving to ncs 1.8 forces me to update to zephyr-sdk-0.13.2 (from 0.12.4) 

    is it really a must or am i missing something ?

    I'm not sure about this, I'm running Windows, so the Zephyr SDK is not available for my platform. What is forcing you to do this updat?

    ziv123 said:

    also, seems that when moving to the new zephyr sdk i have a problem with the dfu (based on the smp service), i use the nrfConnect for the dfu and it seems like its done ok but then after reset the version remains the old version. any ideas on why is that, maybe i need to change some configs ? 

    do i also need to update the MCUBoot or/and the bootloader version for this to work ?

    I would recommend you to post this issue in a new ticket, as it is off topic for this thread. That way, you will also get help from someone more knowledgeable about this topic than me.

    Best regards,
    Jørgen 

  • hi

    i will open a new thread on the ncs update  (wish i would have done that 10 days ago)

    currently the 'set_tx_power()' does not work for me but i moved to work on something else for the moment .. once the issue will be solved i will close this thread with the solution

    best regards

    Ziv

Related