NCS: Softdevice+Mesh+Ext. Advertising -> TX Power Control?

Hello,

I have trouble again with TX Power control. This time using Softdevice Controller and NCS2.6.0.

Previous issue which was solved (this was using Zephyr Controller):  NCS Mesh: TX Power register value does not change when changing TX Power via HCI 

Is there a common solution to control TX Power runtime, when running Mesh + Extended Advertising and Softdevice controller?

Thanks in advance! :)

Parents
  • Hi mesh777,

    You should be able to control the TX Power following the method demonstrated in the Bluetooth: HCI Power Control sample.

    Please note that the SoftDevice Controller only raise the TX Power momentarily for the radio action, and then will set it back to 0. A crude way I used to confirm things are working is to repeatedly print out the content of the TXPOWER register.

    Hieu

  • Please note that the SoftDevice Controller only raise the TX Power momentarily for the radio action, and then will set it back to 0

    What is the reason of such behaviour? Does it mean that TX Power needs to be reconfigured continuously or it is handled by Softdevice automatically?

    The reference sample does not take into account multiple AVD sets, when EXT ADV is enabled. Maybe Conn Handle somehow can be determined to configure each set?

  • Ok, ill try to search for similar topic regarding my last question at first.

    Final thoughts -> such basic feature as TX Power control still causes issues, maybe it should be brought forward to Softdevice/NCS developers as this is not first time I am working on resolving TX Power control:)

  • Do you mean dynamic/run-time control of TX Power for Bluetooth Mesh? If so, we have registered it Slight smile

    As for other regular BLE activities, I believe the dynamic TX Power control works fine.

  • Please forward both findings, also the one that with static configuration its confusing to see that register is switched back to 0 all the time without any good reason.

  • Yes, we have recorded them. I can see how reading TX Power and seeing 0 would be concerning. I will talk with the documentation team to find a way to present the fact more clearly.

  • Hi mesh777,

    A colleague found a way to configure TX Power during run-time. It isn't exactly dynamic configuration, but maybe it can help.

    Before we go into the details, please know that this method is not tested thoroughly, and does involve using internal Mesh stack structures that were not intended for application.

    First, define the stack-internal struct bt_mesh_ext_adv in your application:

    enum {
      /** Controller is currently advertising */
      ADV_FLAG_ACTIVE,
      /** Advertising sending completed */
      ADV_FLAG_SENT,
      /** Currently performing proxy advertising */
      ADV_FLAG_PROXY,
      /** The proxy has been start, but maybe pending. */
      ADV_FLAG_PROXY_START,
      /** The send-call has been scheduled. */
      ADV_FLAG_SCHEDULED,
      /** The send-call has been pending. */
      ADV_FLAG_SCHEDULE_PENDING,
      /** Custom adv params have been set, we need to update the parameters on
       *  the next send.
       */
      ADV_FLAG_UPDATE_PARAMS,
    
      /* Number of adv flags. */
      ADV_FLAGS_NUM
    };
    
    struct bt_mesh_ext_adv {
      uint8_t tag;
      ATOMIC_DEFINE(flags, ADV_FLAGS_NUM);
      struct bt_le_ext_adv *instance;
      struct net_buf *buf;
      uint64_t timestamp;
      struct k_work_delayable work;
      struct bt_le_adv_param adv_param;
    };

    Then, after the mesh stack is initialized (at the end of bt_ready), you can set the TX Power here:

    /* Hack into the mesh stack, due to lack of proper API */
    STRUCT_SECTION_FOREACH(bt_mesh_ext_adv, adv) {
      LOG_INF("adv: %8p", (void *) adv);
    
      if (adv->instance) {
        adv->instance->tx_power = txp_lvl;
      }
    }

    Where txp_level is any valid int8_t (signed) value for a given chip. For example: 0/4/-4/-8, etc.

    This will basically find all declared advertiser instances in the stack and directly set the power. Subsequently, when new Network PDUs or Beacons or GATT advertising start, they will start using the power configured here. If advertisings are disabled and enabled again, this will have to be redone at that time.

    This should work with at least Mesh packets with ADV bearer. Once again, this isn't fully tested, so please perform additional testing, if you want to use this.

    Hieu

Reply
  • Hi mesh777,

    A colleague found a way to configure TX Power during run-time. It isn't exactly dynamic configuration, but maybe it can help.

    Before we go into the details, please know that this method is not tested thoroughly, and does involve using internal Mesh stack structures that were not intended for application.

    First, define the stack-internal struct bt_mesh_ext_adv in your application:

    enum {
      /** Controller is currently advertising */
      ADV_FLAG_ACTIVE,
      /** Advertising sending completed */
      ADV_FLAG_SENT,
      /** Currently performing proxy advertising */
      ADV_FLAG_PROXY,
      /** The proxy has been start, but maybe pending. */
      ADV_FLAG_PROXY_START,
      /** The send-call has been scheduled. */
      ADV_FLAG_SCHEDULED,
      /** The send-call has been pending. */
      ADV_FLAG_SCHEDULE_PENDING,
      /** Custom adv params have been set, we need to update the parameters on
       *  the next send.
       */
      ADV_FLAG_UPDATE_PARAMS,
    
      /* Number of adv flags. */
      ADV_FLAGS_NUM
    };
    
    struct bt_mesh_ext_adv {
      uint8_t tag;
      ATOMIC_DEFINE(flags, ADV_FLAGS_NUM);
      struct bt_le_ext_adv *instance;
      struct net_buf *buf;
      uint64_t timestamp;
      struct k_work_delayable work;
      struct bt_le_adv_param adv_param;
    };

    Then, after the mesh stack is initialized (at the end of bt_ready), you can set the TX Power here:

    /* Hack into the mesh stack, due to lack of proper API */
    STRUCT_SECTION_FOREACH(bt_mesh_ext_adv, adv) {
      LOG_INF("adv: %8p", (void *) adv);
    
      if (adv->instance) {
        adv->instance->tx_power = txp_lvl;
      }
    }

    Where txp_level is any valid int8_t (signed) value for a given chip. For example: 0/4/-4/-8, etc.

    This will basically find all declared advertiser instances in the stack and directly set the power. Subsequently, when new Network PDUs or Beacons or GATT advertising start, they will start using the power configured here. If advertisings are disabled and enabled again, this will have to be redone at that time.

    This should work with at least Mesh packets with ADV bearer. Once again, this isn't fully tested, so please perform additional testing, if you want to use this.

    Hieu

Children
No Data
Related