nimble/ll: Rework how TX power is configured

TX power is now always configured after channel (and PHY) is set before
transmission is started. There is no "default" TX power and all users
are expected to set it explicitly before transmission. This means that
at the end of advertising TX power is not set back to global value.

Main rationale for this change is to properly handle FEM that may have
amplification factor depends on signal frequency (channel used).
This commit is contained in:
Szymon Janc
2023-05-19 15:50:53 +02:00
parent 46fdbeeb0d
commit bd8c96621f
6 changed files with 39 additions and 21 deletions
+12 -2
View File
@@ -76,6 +76,7 @@
/* This is TX power on PHY (or FEM PA if enabled) */
int8_t g_ble_ll_tx_power;
static int8_t g_ble_ll_tx_power_phy_current;
int8_t g_ble_ll_tx_power_compensation;
int8_t g_ble_ll_rx_power_compensation;
@@ -1365,7 +1366,7 @@ ble_ll_task(void *arg)
/* Set output power to default */
g_ble_ll_tx_power = ble_ll_tx_power_round(MIN(MYNEWT_VAL(BLE_LL_TX_PWR_DBM),
MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM)));
ble_ll_tx_power_set(g_ble_ll_tx_power);
g_ble_ll_tx_power_phy_current = INT8_MAX;
/* Tell the host that we are ready to receive packets */
ble_ll_hci_send_noop();
@@ -1617,7 +1618,7 @@ ble_ll_reset(void)
/* Set output power to default */
g_ble_ll_tx_power = ble_ll_tx_power_round(MIN(MYNEWT_VAL(BLE_LL_TX_PWR_DBM),
MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM)));
ble_ll_tx_power_set(g_ble_ll_tx_power);
g_ble_ll_tx_power_phy_current = INT8_MAX;
/* FLush all packets from Link layer queues */
ble_ll_flush_pkt_queue(&g_ble_ll_data.ll_tx_pkt_q);
@@ -2011,6 +2012,15 @@ ble_ll_tx_power_set(int tx_power)
tx_power -= MYNEWT_VAL(BLE_FEM_PA_GAIN);
#endif
#endif
/* If current TX power configuration matches requested one we don't need
* to update PHY tx power.
*/
if (g_ble_ll_tx_power_phy_current == tx_power) {
return;
}
g_ble_ll_tx_power_phy_current = tx_power;
ble_phy_tx_power_set(tx_power);
}
+9 -17
View File
@@ -1030,9 +1030,6 @@ ble_ll_adv_tx_done(void *arg)
{
struct ble_ll_adv_sm *advsm;
/* reset power to default after advertising */
ble_ll_tx_power_set(g_ble_ll_tx_power);
advsm = (struct ble_ll_adv_sm *)arg;
ble_ll_trace_u32x2(BLE_LL_TRACE_ID_ADV_TXDONE, advsm->adv_instance,
@@ -1111,9 +1108,6 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch)
goto adv_tx_done;
}
/* Set the power */
ble_ll_tx_power_set(advsm->tx_power);
/* Set channel */
rc = ble_phy_setchan(advsm->adv_chan, BLE_ACCESS_ADDR_ADV, BLE_LL_CRCINIT_ADV);
BLE_LL_ASSERT(rc == 0);
@@ -1131,6 +1125,9 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch)
#endif
#endif
/* Set the power */
ble_ll_tx_power_set(advsm->tx_power);
/* Set transmit start time. */
txstart = sch->start_time + g_ble_ll_sched_offset_ticks;
rc = ble_phy_tx_set_start_time(txstart, sch->remainder);
@@ -1255,9 +1252,6 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch)
ble_ll_adv_active_chanset_set_sec(advsm);
/* Set the power */
ble_ll_tx_power_set(advsm->tx_power);
/* Set channel */
aux = AUX_CURRENT(advsm);
rc = ble_phy_setchan(aux->chan, BLE_ACCESS_ADDR_ADV,
@@ -1269,6 +1263,9 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch)
ble_phy_mode_set(advsm->sec_phy, advsm->sec_phy);
#endif
/* Set the power */
ble_ll_tx_power_set(advsm->tx_power);
/* Set transmit start time. */
txstart = sch->start_time + g_ble_ll_sched_offset_ticks;
rc = ble_phy_tx_set_start_time(txstart, sch->remainder);
@@ -1741,8 +1738,6 @@ ble_ll_adv_halt(void)
ble_ll_trace_u32(BLE_LL_TRACE_ID_ADV_HALT, advsm->adv_instance);
ble_ll_tx_power_set(g_ble_ll_tx_power);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
if (advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING) {
ble_ll_adv_flags_clear(advsm,
@@ -2176,9 +2171,6 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
static void
ble_ll_adv_sync_tx_done(struct ble_ll_adv_sm *advsm)
{
/* reset power to default after advertising */
ble_ll_tx_power_set(g_ble_ll_tx_power);
/* for sync we trace a no pri nor sec set */
ble_ll_trace_u32x2(BLE_LL_TRACE_ID_ADV_TXDONE, advsm->adv_instance, 0);
@@ -2232,9 +2224,6 @@ ble_ll_adv_sync_tx_start_cb(struct ble_ll_sched_item *sch)
ble_ll_adv_active_chanset_clear(advsm);
ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING);
/* Set the power */
ble_ll_tx_power_set(advsm->tx_power);
/* Set channel */
sync = SYNC_CURRENT(advsm);
rc = ble_phy_setchan(sync->chan, advsm->periodic_access_addr,
@@ -2247,6 +2236,9 @@ ble_ll_adv_sync_tx_start_cb(struct ble_ll_sched_item *sch)
ble_phy_mode_set(advsm->sec_phy, advsm->sec_phy);
#endif
/* Set the power */
ble_ll_tx_power_set(advsm->tx_power);
/* Set transmit start time. */
txstart = sch->start_time + g_ble_ll_sched_offset_ticks;
rc = ble_phy_tx_set_start_time(txstart, sch->remainder);
+3
View File
@@ -1523,6 +1523,9 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch)
ble_phy_mode_set(connsm->phy_data.tx_phy_mode, connsm->phy_data.rx_phy_mode);
#endif
/* Set the power */
ble_ll_tx_power_set(g_ble_ll_tx_power);
switch (connsm->conn_role) {
#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL)
case BLE_LL_CONN_ROLE_CENTRAL:
-2
View File
@@ -84,8 +84,6 @@ ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen,
g_ble_ll_tx_power_compensation);
}
ble_ll_tx_power_set(g_ble_ll_tx_power);
rsp->tx_power = g_ble_ll_tx_power + g_ble_ll_tx_power_compensation;
*rsplen = sizeof(*rsp);
+7
View File
@@ -785,6 +785,13 @@ ble_ll_scan_start(struct ble_ll_scan_sm *scansm)
ble_phy_mode_set(phy_mode, phy_mode);
#endif
/* if scan is not passive we need to set tx power as we may end up sending
* package
*/
if (scansm->scanp->scan_type != BLE_SCAN_TYPE_PASSIVE) {
ble_ll_tx_power_set(g_ble_ll_tx_power);
}
rc = ble_phy_rx_set_start_time(ble_ll_tmr_get() +
g_ble_ll_sched_offset_ticks, 0);
if (!rc || rc == BLE_PHY_ERR_RX_LATE) {
+8
View File
@@ -142,6 +142,14 @@ ble_ll_scan_aux_sched_cb(struct ble_ll_sched_item *sch)
ble_phy_mode_set(phy_mode, phy_mode);
#endif
/* if scan is not passive we need to set tx power as we may end up sending
* package
*/
/* TODO do this only on first AUX? */
if (aux->scan_type != BLE_SCAN_TYPE_PASSIVE) {
ble_ll_tx_power_set(g_ble_ll_tx_power);
}
rc = ble_phy_rx_set_start_time(sch->start_time + g_ble_ll_sched_offset_ticks,
sch->remainder);
if (rc != 0 && rc != BLE_PHY_ERR_RX_LATE) {