nimble/ll: Optimize AUX_CONNECT_REQ tx

Currently we initialize a lot of connsm settings prior to scheduling
1st connection event and this takes some time. However, we only need
connection interval, latency and supervision timeout to be initialized
in order to schedule event properly and send AUX_CONNECT_REQ, other
stuff can be done after tx has already started.

This is especially important on slower MCU like CMAC as with old code
it was barely possible to make tx within Tifs even on speed build.

New code saves ~15us on CMAC prior to tx so we have quite a good margin
to complete on time.
This commit is contained in:
Andrzej Kaczmarek
2021-10-07 11:43:15 +02:00
parent 6c9f70972e
commit 6c9f95ad23
3 changed files with 66 additions and 31 deletions
@@ -192,8 +192,9 @@ struct hci_ext_conn_params
{
uint16_t scan_itvl;
uint16_t scan_window;
uint16_t conn_itvl_min;
uint16_t conn_itvl_max;
uint32_t conn_itvl;
uint16_t conn_itvl_ticks;
uint8_t conn_itvl_usecs;
uint16_t conn_latency;
uint16_t supervision_timeout;
uint16_t min_ce_len;
+21 -17
View File
@@ -1755,14 +1755,6 @@ void
ble_ll_conn_ext_set_params(struct ble_ll_conn_sm *connsm,
struct hci_ext_conn_params *hcc_params, int phy)
{
/* Set slave latency and supervision timeout */
connsm->slave_latency = hcc_params->conn_latency;
connsm->supervision_tmo = hcc_params->supervision_timeout;
/* XXX: for now, just make connection interval equal to max */
connsm->conn_itvl = hcc_params->conn_itvl_max;
/* Check the min/max CE lengths are less than connection interval */
if (hcc_params->min_ce_len > (connsm->conn_itvl * 2)) {
connsm->min_ce_len = connsm->conn_itvl * 2;
@@ -1776,8 +1768,6 @@ ble_ll_conn_ext_set_params(struct ble_ll_conn_sm *connsm,
connsm->max_ce_len = hcc_params->max_ce_len;
}
ble_ll_conn_calc_itvl_ticks(connsm);
#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
ble_ll_conn_init_phy(connsm, phy);
#endif
@@ -3176,6 +3166,7 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
struct ble_ll_resolv_entry *rl;
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
struct hci_ext_conn_params *hcp;
struct ble_ll_scan_sm *scansm;
uint8_t phy;
#endif
@@ -3425,15 +3416,16 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
}
if (connsm->scansm->ext_scanning) {
phy = ble_hdr->rxinfo.phy;
phy = ble_hdr->rxinfo.phy;
/* Update connection state machine with appropriate parameters for
* certain PHY
*/
ble_ll_conn_ext_set_params(connsm,
&connsm->initial_params.params[phy - 1],
phy);
hcp = &connsm->initial_params.params[phy - 1];
connsm->slave_latency = hcp->conn_latency;
connsm->supervision_tmo = hcp->supervision_timeout;
connsm->conn_itvl = hcp->conn_itvl;
connsm->conn_itvl_ticks = hcp->conn_itvl_ticks;
connsm->conn_itvl_usecs = hcp->conn_itvl_usecs;
}
#endif
@@ -3472,6 +3464,18 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
ble_hdr->rxinfo.user_data = NULL;
STATS_INC(ble_ll_stats, aux_conn_req_tx);
}
if (connsm->scansm->ext_scanning) {
phy = ble_hdr->rxinfo.phy;
/* Update connection state machine with appropriate parameters for
* certain PHY
*/
ble_ll_conn_ext_set_params(connsm,
&connsm->initial_params.params[phy - 1],
phy);
}
#endif
STATS_INC(ble_ll_conn_stats, conn_req_txd);
+42 -12
View File
@@ -556,6 +556,25 @@ ble_ll_conn_hcc_params_set_fallback(struct hci_ext_create_conn *hcc,
#endif
}
static void
ble_ll_conn_itvl_to_ticks(uint32_t itvl, uint16_t *itvl_ticks,
uint8_t *itvl_usecs)
{
uint32_t ticks;
uint32_t usecs;
usecs = itvl * BLE_LL_CONN_ITVL_USECS;
ticks = os_cputime_usecs_to_ticks(usecs);
usecs = usecs - os_cputime_ticks_to_usecs(ticks);
if (usecs == 31) {
usecs = 0;
++ticks;
}
*itvl_ticks = ticks;
*itvl_usecs = usecs;
}
int
ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len)
{
@@ -564,6 +583,8 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len)
const struct hci_ext_conn_params *fallback_params = NULL;
struct hci_ext_create_conn hcc = { 0 };
struct ble_ll_conn_sm *connsm;
uint16_t conn_itvl_min;
uint16_t conn_itvl_max;
int rc;
/* validate length */
@@ -629,13 +650,12 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len)
return rc;
}
hcc.params[0].conn_itvl_min = le16toh(params->conn_min_itvl);
hcc.params[0].conn_itvl_max = le16toh(params->conn_min_itvl);
conn_itvl_min = le16toh(params->conn_min_itvl);
conn_itvl_max = le16toh(params->conn_max_itvl);
hcc.params[0].conn_latency = le16toh(params->conn_latency);
hcc.params[0].supervision_timeout = le16toh(params->supervision_timeout);
rc = ble_ll_conn_hci_chk_conn_params(hcc.params[0].conn_itvl_min,
hcc.params[0].conn_itvl_max,
rc = ble_ll_conn_hci_chk_conn_params(conn_itvl_min, conn_itvl_max,
hcc.params[0].conn_latency,
hcc.params[0].supervision_timeout);
if (rc) {
@@ -649,6 +669,10 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len)
return BLE_ERR_INV_HCI_CMD_PARMS;
}
hcc.params[0].conn_itvl = conn_itvl_max;
ble_ll_conn_itvl_to_ticks(conn_itvl_max, &hcc.params[0].conn_itvl_ticks,
&hcc.params[0].conn_itvl_usecs);
fallback_params = &hcc.params[0];
params++;
}
@@ -660,13 +684,12 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len)
}
len -= sizeof(*params);
hcc.params[1].conn_itvl_min = le16toh(params->conn_min_itvl);
hcc.params[1].conn_itvl_max = le16toh(params->conn_min_itvl);
conn_itvl_min = le16toh(params->conn_min_itvl);
conn_itvl_max = le16toh(params->conn_max_itvl);
hcc.params[1].conn_latency = le16toh(params->conn_latency);
hcc.params[1].supervision_timeout = le16toh(params->supervision_timeout);
rc = ble_ll_conn_hci_chk_conn_params(hcc.params[1].conn_itvl_min,
hcc.params[1].conn_itvl_max,
rc = ble_ll_conn_hci_chk_conn_params(conn_itvl_min, conn_itvl_max,
hcc.params[1].conn_latency,
hcc.params[1].supervision_timeout);
if (rc) {
@@ -680,6 +703,10 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len)
return BLE_ERR_INV_HCI_CMD_PARMS;
}
hcc.params[1].conn_itvl = conn_itvl_max;
ble_ll_conn_itvl_to_ticks(conn_itvl_max, &hcc.params[1].conn_itvl_ticks,
&hcc.params[1].conn_itvl_usecs);
params++;
}
#endif
@@ -700,13 +727,12 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len)
return rc;
}
hcc.params[2].conn_itvl_min = le16toh(params->conn_min_itvl);
hcc.params[2].conn_itvl_max = le16toh(params->conn_min_itvl);
conn_itvl_min = le16toh(params->conn_min_itvl);
conn_itvl_max = le16toh(params->conn_max_itvl);
hcc.params[2].conn_latency = le16toh(params->conn_latency);
hcc.params[2].supervision_timeout = le16toh(params->supervision_timeout);
rc = ble_ll_conn_hci_chk_conn_params(hcc.params[2].conn_itvl_min,
hcc.params[2].conn_itvl_max,
rc = ble_ll_conn_hci_chk_conn_params(conn_itvl_min, conn_itvl_max,
hcc.params[2].conn_latency,
hcc.params[2].supervision_timeout);
if (rc) {
@@ -720,6 +746,10 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len)
return BLE_ERR_INV_HCI_CMD_PARMS;
}
hcc.params[2].conn_itvl = conn_itvl_max;
ble_ll_conn_itvl_to_ticks(conn_itvl_max, &hcc.params[2].conn_itvl_ticks,
&hcc.params[2].conn_itvl_usecs);
if (!fallback_params) {
fallback_params = &hcc.params[2];
}