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

Reply
  • 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

Children
No Data
Related