Skip to content

Commit

Permalink
nimble/ll: Add support for custom TX power configuration
Browse files Browse the repository at this point in the history
This allows to provide custom TX power setting and rounding
functions which can take into account FEM configuration. Since
this is highly dependend on HW configuration (FEM type and mode,
BPFs, PA power etc) there is no point in providing "default"
implementation as this should be typically provided by BSP or
application.
  • Loading branch information
sjanc committed Sep 15, 2022
1 parent 3b02d6b commit 66d5b9c
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 16 deletions.
5 changes: 5 additions & 0 deletions nimble/controller/include/controller/ble_ll_fem.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ extern "C" {
void ble_ll_fem_pa_init(void);
void ble_ll_fem_pa_enable(void);
void ble_ll_fem_pa_disable(void);

#if MYNEWT_VAL(BLE_LL_FEM_PA_TXPOWER_TUNE)
void ble_ll_fem_txpower_set(int dbm);
int ble_ll_fem_txpower_round(int dbm);
#endif
#endif

#if MYNEWT_VAL(BLE_LL_FEM_LNA)
Expand Down
27 changes: 24 additions & 3 deletions nimble/controller/src/ble_ll.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
* right thing to do.
*/

int8_t g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM);
int8_t g_ble_ll_tx_power;

/* Supported states */
#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER)
Expand Down Expand Up @@ -1347,8 +1347,9 @@ ble_ll_task(void *arg)
/* Init ble phy */
ble_phy_init();

/* Set output power to 1mW (0 dBm) */
ble_phy_txpwr_set(g_ble_ll_tx_power);
/* Set output power to selected default */
g_ble_ll_tx_power = ble_ll_txpower_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM));
ble_ll_txpower_set(g_ble_ll_tx_power);

/* Tell the host that we are ready to receive packets */
ble_ll_hci_send_noop();
Expand Down Expand Up @@ -1976,3 +1977,23 @@ ble_transport_ll_init(void)
{
ble_ll_init();
}

void
ble_ll_txpower_set(int dbm)
{
#if MYNEWT_VAL(BLE_LL_FEM_PA_TXPOWER_TUNE)
ble_ll_fem_txpower_set(dbm);
#else
ble_phy_txpwr_set(dbm);
#endif
}

int
ble_ll_txpower_round(int dbm)
{
#if MYNEWT_VAL(BLE_LL_FEM_PA_TXPOWER_TUNE)
return ble_ll_fem_txpower_round(dbm);
#else
return ble_phy_txpower_round(dbm);
#endif
}
14 changes: 7 additions & 7 deletions nimble/controller/src/ble_ll_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,7 @@ ble_ll_adv_tx_done(void *arg)
struct ble_ll_adv_sm *advsm;

/* reset power to max after advertising */
ble_phy_txpwr_set(g_ble_ll_tx_power);
ble_ll_txpower_set(g_ble_ll_tx_power);

advsm = (struct ble_ll_adv_sm *)arg;

Expand Down Expand Up @@ -1107,7 +1107,7 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch)
}

/* Set the power */
ble_phy_txpwr_set(advsm->adv_txpwr);
ble_ll_txpower_set(advsm->adv_txpwr);

/* Set channel */
rc = ble_phy_setchan(advsm->adv_chan, BLE_ACCESS_ADDR_ADV, BLE_LL_CRCINIT_ADV);
Expand Down Expand Up @@ -1251,7 +1251,7 @@ 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_phy_txpwr_set(advsm->adv_txpwr);
ble_ll_txpower_set(advsm->adv_txpwr);

/* Set channel */
aux = AUX_CURRENT(advsm);
Expand Down Expand Up @@ -1736,7 +1736,7 @@ ble_ll_adv_halt(void)

ble_ll_trace_u32(BLE_LL_TRACE_ID_ADV_HALT, advsm->adv_instance);

ble_phy_txpwr_set(g_ble_ll_tx_power);
ble_ll_txpower_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) {
Expand Down Expand Up @@ -2170,7 +2170,7 @@ static void
ble_ll_adv_sync_tx_done(struct ble_ll_adv_sm *advsm)
{
/* reset power to default after advertising */
ble_phy_txpwr_set(g_ble_ll_tx_power);
ble_ll_txpower_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);
Expand Down Expand Up @@ -2226,7 +2226,7 @@ ble_ll_adv_sync_tx_start_cb(struct ble_ll_sched_item *sch)
ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING);

/* Set the power */
ble_phy_txpwr_set(advsm->adv_txpwr);
ble_ll_txpower_set(advsm->adv_txpwr);

/* Set channel */
sync = SYNC_CURRENT(advsm);
Expand Down Expand Up @@ -3519,7 +3519,7 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len,
/* no preference */
advsm->adv_txpwr = g_ble_ll_tx_power;
} else {
advsm->adv_txpwr = ble_phy_txpower_round(cmd->tx_power);
advsm->adv_txpwr = ble_ll_txpower_round(cmd->tx_power);
}

/* we can always store as those are validated and used only when needed */
Expand Down
2 changes: 1 addition & 1 deletion nimble/controller/src/ble_ll_dtm.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ ble_ll_dtm_tx_sched_cb(struct ble_ll_sched_item *sch)
ble_phy_mode_set(ctx->phy_mode, ctx->phy_mode);
#endif
ble_phy_set_txend_cb(ble_ll_dtm_tx_done, ctx);
ble_phy_txpwr_set(0);
ble_ll_txpower_set(0);

sch->start_time += g_ble_ll_sched_offset_ticks;

Expand Down
4 changes: 2 additions & 2 deletions nimble/controller/src/ble_ll_hci.c
Original file line number Diff line number Diff line change
Expand Up @@ -786,8 +786,8 @@ ble_ll_read_tx_power(uint8_t *rspbuf, uint8_t *rsplen)
{
struct ble_hci_le_rd_transmit_power_rp *rsp = (void *) rspbuf;

rsp->min_tx_power = ble_phy_txpower_round(-127);
rsp->max_tx_power = ble_phy_txpower_round(126);
rsp->min_tx_power = ble_ll_txpower_round(-127);
rsp->max_tx_power = ble_ll_txpower_round(126);

*rsplen = sizeof(*rsp);
return BLE_ERR_SUCCESS;
Expand Down
6 changes: 3 additions & 3 deletions nimble/controller/src/ble_ll_hci_vs.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,12 @@ ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen,

if (cmd->tx_power == 127) {
/* restore reset default */
g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM);
g_ble_ll_tx_power = ble_ll_txpower_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM));
} else {
g_ble_ll_tx_power = ble_phy_txpower_round(cmd->tx_power);
g_ble_ll_tx_power = ble_ll_txpower_round(cmd->tx_power);
}

ble_phy_txpwr_set(g_ble_ll_tx_power);
ble_ll_txpower_set(g_ble_ll_tx_power);

rsp->tx_power = g_ble_ll_tx_power;
*rsplen = sizeof(*rsp);
Expand Down
3 changes: 3 additions & 0 deletions nimble/controller/src/ble_ll_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ extern "C" {

extern int8_t g_ble_ll_tx_power;

void ble_ll_txpower_set(int dbm);
int ble_ll_txpower_round(int dbm);

#ifdef MYNEWT

#include "syscfg/syscfg.h"
Expand Down
6 changes: 6 additions & 0 deletions nimble/controller/syscfg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,12 @@ syscfg.defs:
BLE_LL_FEM_PA:
description: Enable FEM PA support
value: MYNEWT_VAL(BLE_LL_PA)
BLE_LL_FEM_PA_TXPOWER_TUNE:
description: >
Indicates that FEM TX power tunning is provided. If enabled
ble_ll_fem_txpower_round() and ble_ll_fem_txpower_set() shall be
implemented. See controller/ble_ll_fem.h for defails.
value: 0
BLE_LL_FEM_PA_GPIO:
description: >
GPIO pin number to control PA. Pin is set to high state when PA
Expand Down

0 comments on commit 66d5b9c

Please sign in to comment.