Skip to content

[wip] path loss #1911

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions nimble/controller/include/controller/ble_fem.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ int ble_fem_pa_tx_power_set(int tx_power);

/* returns rounded FEM TX power */
int ble_fem_pa_tx_power_round(int tx_power);

/* returns rounded up FEM TX power */
int ble_fem_pa_tx_power_round(int tx_power);
#endif
#endif

Expand Down
68 changes: 68 additions & 0 deletions nimble/controller/include/controller/ble_ll_conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ struct ble_ll_conn_sm_flags {
#if MYNEWT_VAL(BLE_LL_CONN_INIT_AUTO_DLE)
uint32_t pending_initiate_dle : 1;
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_POWER_CONTROL)
uint32_t power_request_host_w4event : 1;
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PATH_LOSS_MON)
uint32_t path_loss_configured : 1;
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE)
uint8_t subrate_trans : 1;
uint8_t subrate_ind_txd : 1;
Expand Down Expand Up @@ -201,6 +207,60 @@ struct ble_ll_conn_subrate_req_params {
uint16_t supervision_tmo;
};

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_POWER_CONTROL)
struct ble_ll_conn_power_control_data {
/*
* Current local TxPower.
* Updated when PHY is changed or when current PHY's TxPower is changed
*/
int8_t curr_local_tx_power;

/* Stores local TxPower for each PHY mode */
int8_t local_tx_power[BLE_PHY_NUM_MODE];

/* Stores min max flags for each PHY mode */
int8_t local_min_max[BLE_PHY_NUM_MODE];

/* Indicates on which PHY we requested Power Control Request Procedure */
int8_t req_phy_mode;

/* Stores delta for Power Control Request */
int8_t req_delta;

/* Flags that indicate if reports are enabled */
uint8_t local_reports_enabled : 1;
uint8_t remote_reports_enabled : 1;
};
#endif

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PATH_LOSS_MON)
struct ble_ll_conn_path_loss_data {
/* High threshold for the path loss */
uint8_t high_threshold;

/* Hysteresis value for the high threshold */
uint8_t high_hysteresis;

/* Low threshold for the path loss */
uint8_t low_threshold;

/* Hysteresis value for the low threshold */
uint8_t low_hysteresis;

/*
* Minimum time in number of connection events to be observed
* once the path loss crosses the threshold before an event is generated
*/
uint16_t min_time_spent;

/* Flag that indicates if reports are enabled */
uint8_t reports_enabled;

/* Remote TxPower */
int8_t remote_tx_power;
};
#endif

/* Connection state machine */
struct ble_ll_conn_sm
{
Expand Down Expand Up @@ -397,6 +457,14 @@ struct ble_ll_conn_sm
uint16_t css_slot_idx_pending;
uint8_t css_period_idx;
#endif

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_POWER_CONTROL)
struct ble_ll_conn_power_control_data pwr_ctrl;
#endif

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PATH_LOSS_MON)
struct ble_ll_conn_path_loss_data path_loss;
#endif
};

/* Role */
Expand Down
4 changes: 4 additions & 0 deletions nimble/controller/include/controller/ble_ll_ctrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ extern "C" {
#define BLE_LL_CTRL_PROC_SUBRATE_REQ (12)
#define BLE_LL_CTRL_PROC_SUBRATE_UPDATE (13)
#define BLE_LL_CTRL_PROC_NUM (14)
#define BLE_LL_CTRL_PROC_POWER_CTRL_REQ (15)
#define BLE_LL_CTRL_PROC_IDLE (255)

/* Checks if a particular control procedure is running */
Expand Down Expand Up @@ -338,6 +339,9 @@ void ble_ll_hci_ev_send_vs_assert(const char *file, uint32_t line);
void ble_ll_hci_ev_send_vs_printf(uint8_t id, const char *fmt, ...);
void ble_ll_hci_ev_send_vs_llcp_trace(uint8_t type, uint16_t handle, uint16_t count,
void *pdu, size_t length);
void ble_ll_hci_ev_transmit_power_report(struct ble_ll_conn_sm *connsm, uint8_t status,
uint8_t reason, uint8_t phy_mode, int8_t tx_power,
uint8_t tx_power_flags, int8_t delta);

uint8_t ble_ll_ctrl_phy_tx_transition_get(uint8_t phy_mask);
uint8_t ble_ll_ctrl_phy_from_phy_mask(uint8_t phy_mask);
Expand Down
3 changes: 3 additions & 0 deletions nimble/controller/include/controller/ble_phy.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ int ble_phy_tx_power_set(int dbm);
/* Get highest allowed power from range */
int ble_phy_tx_power_round(int dbm);

/* Get the next allowed power level above the specified value */
int ble_phy_tx_power_round_up(int dbm);

/* Get the transmit power */
int ble_phy_tx_power_get(void);

Expand Down
18 changes: 18 additions & 0 deletions nimble/controller/src/ble_ll.c
Original file line number Diff line number Diff line change
Expand Up @@ -2030,6 +2030,24 @@ ble_ll_tx_power_round(int tx_power)
return tx_power;
}

/* TODO(m): is this necessary? */
int
ble_ll_tx_power_round_up(int tx_power)
{
#if MYNEWT_VAL(BLE_FEM_PA)
#if MYNEWT_VAL(BLE_FEM_PA_GAIN_TUNABLE)
tx_power = ble_fem_pa_tx_power_round_up(tx_power);
#else
tx_power = ble_phy_tx_power_round_up(tx_power);
tx_power += MYNEWT_VAL(BLE_FEM_PA_GAIN);
#endif
#else
tx_power = ble_phy_tx_power_round_up(tx_power);
#endif

return tx_power;
}

void
ble_ll_tx_power_set(int tx_power)
{
Expand Down
56 changes: 56 additions & 0 deletions nimble/controller/src/ble_ll_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -1526,8 +1526,12 @@ 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

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_POWER_CONTROL)
ble_ll_tx_power_set(connsm->pwr_ctrl.curr_local_tx_power);
#else
/* Set the power */
ble_ll_tx_power_set(g_ble_ll_tx_power);
#endif

switch (connsm->conn_role) {
#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL)
Expand Down Expand Up @@ -1746,6 +1750,19 @@ ble_ll_conn_auth_pyld_timer_start(struct ble_ll_conn_sm *connsm)
}
#endif

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_POWER_CONTROL)
static void
ble_ll_conn_init_tx_power(struct ble_ll_conn_sm *connsm)
{
int i;

for (i = 0; i < BLE_PHY_NUM_MODE; i++) {
connsm->pwr_ctrl.local_tx_power[i] = g_ble_ll_tx_power;
}
connsm->pwr_ctrl.curr_local_tx_power = g_ble_ll_tx_power;
}
#endif

#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL)
static void
ble_ll_conn_central_common_init(struct ble_ll_conn_sm *connsm)
Expand Down Expand Up @@ -2018,6 +2035,10 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm)
connsm->phy_tx_transition = 0;
#endif

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_POWER_CONTROL)
ble_ll_conn_init_tx_power(connsm);
#endif

/* Reset current control procedure */
connsm->cur_ctrl_proc = BLE_LL_CTRL_PROC_IDLE;
connsm->pending_ctrl_procs = 0;
Expand Down Expand Up @@ -2325,6 +2346,38 @@ ble_ll_conn_move_anchor(struct ble_ll_conn_sm *connsm, uint16_t offset)
}
#endif

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_POWER_CONTROL)
void
ble_ll_conn_update_local_tx_power(struct ble_ll_conn_sm *connsm)
{
uint8_t curr_phy_mode;
int8_t new_tx_power;
int8_t delta;

#if MYNEWT_VAL(BLE_LL_PHY)
curr_phy_mode = connsm->phy_data.tx_phy_mode;
#else
curr_phy_mode = BLE_PHY_MODE_1M;
#endif

new_tx_power = connsm->pwr_ctrl.local_tx_power[curr_phy_mode];
if (connsm->pwr_ctrl.curr_local_tx_power == new_tx_power) {
return;
}

delta = new_tx_power - connsm->pwr_ctrl.curr_local_tx_power;
connsm->pwr_ctrl.curr_local_tx_power = new_tx_power;

if (connsm->pwr_ctrl.local_reports_enabled) {
ble_ll_hci_ev_transmit_power_report(connsm, BLE_ERR_SUCCESS, 0x00,
curr_phy_mode,
connsm->pwr_ctrl.curr_local_tx_power,
connsm->pwr_ctrl.local_min_max[curr_phy_mode],
delta);
}
}
#endif

/**
* Called to move to the next connection event.
*
Expand Down Expand Up @@ -2659,6 +2712,9 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm)
connsm->phy_data.tx_phy_mode =
ble_ll_phy_to_phy_mode(connsm->phy_data.cur_tx_phy,
connsm->phy_data.pref_opts);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_POWER_CONTROL)
ble_ll_conn_update_local_tx_power(connsm);
#endif
}

if (connsm->phy_data.new_rx_phy) {
Expand Down
Loading
Loading