diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index fe70044234..66c43108c1 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -62,10 +62,11 @@ struct os_mbuf; #define BLE_PHY_STATE_TX (2) /* BLE PHY transitions */ -#define BLE_PHY_TRANSITION_NONE (0) -#define BLE_PHY_TRANSITION_RX_TX (1) -#define BLE_PHY_TRANSITION_TX_RX (2) -#define BLE_PHY_TRANSITION_TX_TX (3) +#define BLE_PHY_TRANSITION_NONE (0) +#define BLE_PHY_TRANSITION_TO_TX (1) +#define BLE_PHY_TRANSITION_TO_RX (2) +#define BLE_PHY_TRANSITION_TO_TX_ISO_SUBEVENT (3) +#define BLE_PHY_TRANSITION_TO_RX_ISO_SUBEVENT (4) /* PHY error codes */ #define BLE_PHY_ERR_RADIO_STATE (1) @@ -88,14 +89,8 @@ int ble_phy_init(void); int ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit); uint8_t ble_phy_chan_get(void); -#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) -/* Set T_ifs time for next transition */ -void ble_phy_tifs_set(uint16_t tifs); -#endif - -/* Set T_ifs for tx-tx transitions. Anchor is 0 for start of previous PDU, - * non-zero for end of PDU */ -void ble_phy_tifs_txtx_set(uint16_t usecs, uint8_t anchor); +/* Set direction of the next transition */ +void ble_phy_transition_set(uint8_t trans, uint16_t usecs); /* Set transmit start time */ int ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs); @@ -110,7 +105,7 @@ typedef uint8_t (*ble_phy_tx_pducb_t)(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte); /* Place the PHY into transmit mode */ -int ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans); +int ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg); /* Copies the received PHY buffer into the allocated pdu */ void ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu); diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 3b36c87a53..caa7b1cf8f 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1121,7 +1121,6 @@ static int ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch) { int rc; - uint8_t end_trans; uint32_t txstart; struct ble_ll_adv_sm *advsm; @@ -1183,18 +1182,18 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch) if ((advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) && ((advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) || (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE))) { - end_trans = BLE_PHY_TRANSITION_TX_RX; + ble_phy_transition_set(BLE_PHY_TRANSITION_TO_RX, BLE_LL_IFS); ble_phy_set_txend_cb(NULL, NULL); } else { - end_trans = BLE_PHY_TRANSITION_NONE; + ble_phy_transition_set(BLE_PHY_TRANSITION_NONE, 0); ble_phy_set_txend_cb(ble_ll_adv_tx_done, advsm); } /* Transmit advertisement */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - rc = ble_phy_tx(ble_ll_adv_pdu_make, advsm, end_trans); + rc = ble_phy_tx(ble_ll_adv_pdu_make, advsm); #else - rc = ble_phy_tx(ble_ll_adv_legacy_pdu_make, advsm, end_trans); + rc = ble_phy_tx(ble_ll_adv_legacy_pdu_make, advsm); #endif if (rc) { goto adv_tx_done; @@ -1268,7 +1267,6 @@ static int ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch) { int rc; - uint8_t end_trans; uint32_t txstart; struct ble_ll_adv_sm *advsm; ble_phy_tx_pducb_t pducb; @@ -1319,22 +1317,22 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch) /* Set phy mode based on type of advertisement */ if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) { - end_trans = BLE_PHY_TRANSITION_TX_RX; + ble_phy_transition_set(BLE_PHY_TRANSITION_TO_RX, BLE_LL_IFS); ble_phy_set_txend_cb(NULL, NULL); pducb = ble_ll_adv_aux_pdu_make; } else if ((advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE) && advsm->aux_first_pdu) { - end_trans = BLE_PHY_TRANSITION_TX_RX; + ble_phy_transition_set(BLE_PHY_TRANSITION_TO_RX, BLE_LL_IFS); ble_phy_set_txend_cb(NULL, NULL); pducb = ble_ll_adv_aux_scannable_pdu_make; } else { - end_trans = BLE_PHY_TRANSITION_NONE; + ble_phy_transition_set(BLE_PHY_TRANSITION_NONE, 0); ble_phy_set_txend_cb(ble_ll_adv_tx_done, advsm); pducb = ble_ll_adv_aux_pdu_make; } /* Transmit advertisement */ - rc = ble_phy_tx(pducb, advsm, end_trans); + rc = ble_phy_tx(pducb, advsm); if (rc) { goto adv_aux_dropped; } @@ -2322,8 +2320,9 @@ ble_ll_adv_sync_tx_start_cb(struct ble_ll_sched_item *sch) #endif /* Transmit advertisement */ + ble_phy_transition_set(BLE_PHY_TRANSITION_NONE, 0); ble_phy_set_txend_cb(ble_ll_adv_sync_tx_end, advsm); - rc = ble_phy_tx(ble_ll_adv_sync_pdu_make, advsm, BLE_PHY_TRANSITION_NONE); + rc = ble_phy_tx(ble_ll_adv_sync_pdu_make, advsm); if (rc) { goto adv_tx_done; } @@ -4547,6 +4546,8 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu) */ ble_phy_set_txend_cb(ble_ll_adv_tx_done, advsm); + ble_phy_transition_set(BLE_PHY_TRANSITION_NONE, 0); + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (advsm->flags & BLE_LL_ADV_SM_FLAG_SCAN_REQ_NOTIF) { ble_ll_hci_ev_send_scan_req_recv(advsm->adv_instance, peer, @@ -4560,12 +4561,10 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu) */ advsm->rx_ble_hdr = ble_hdr; - rc = ble_phy_tx(ble_ll_adv_scan_rsp_pdu_make, advsm, - BLE_PHY_TRANSITION_NONE); + rc = ble_phy_tx(ble_ll_adv_scan_rsp_pdu_make, advsm); advsm->rx_ble_hdr = NULL; #else - rc = ble_phy_tx(ble_ll_adv_scan_rsp_legacy_pdu_make, advsm, - BLE_PHY_TRANSITION_NONE); + rc = ble_phy_tx(ble_ll_adv_scan_rsp_legacy_pdu_make, advsm); #endif if (!rc) { @@ -4599,9 +4598,9 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu) rsp_data.peer = rxbuf + BLE_LL_PDU_HDR_LEN; rsp_data.rxadd = rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK; + ble_phy_transition_set(BLE_PHY_TRANSITION_NONE, 0); ble_phy_set_txend_cb(ble_ll_adv_tx_done, advsm); - rc = ble_phy_tx(ble_ll_adv_aux_conn_rsp_pdu_make, &rsp_data, - BLE_PHY_TRANSITION_NONE); + rc = ble_phy_tx(ble_ll_adv_aux_conn_rsp_pdu_make, &rsp_data); if (!rc) { ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD); STATS_INC(ble_ll_stats, aux_conn_rsp_tx); @@ -4892,6 +4891,8 @@ ble_ll_adv_rx_isr_start(uint8_t pdu_type) */ if (rc < 0) { ble_ll_adv_tx_done(advsm); + } else if (rc > 0){ + ble_phy_transition_set(BLE_PHY_TRANSITION_TO_TX, BLE_LL_IFS); } return rc; diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 65ff4cb0d9..98b775a16d 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1347,7 +1347,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) txend_func = ble_ll_conn_wait_txend; } else { /* Wait for a response here */ - end_transition = BLE_PHY_TRANSITION_TX_RX; + end_transition = BLE_PHY_TRANSITION_TO_RX; txend_func = NULL; } @@ -1435,9 +1435,11 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) } #endif + ble_phy_transition_set(end_transition, BLE_LL_IFS); + /* Set transmit end callback */ ble_phy_set_txend_cb(txend_func, connsm); - rc = ble_phy_tx(ble_ll_tx_mbuf_pducb, m, end_transition); + rc = ble_phy_tx(ble_ll_tx_mbuf_pducb, m); if (!rc) { /* Log transmit on connection state */ cur_txlen = ble_hdr->txinfo.pyld_len; @@ -3269,9 +3271,11 @@ ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu, ble_ll_conn_prepare_connect_ind(connsm, ble_ll_scan_get_pdu_data(), addrd, rxhdr->rxinfo.channel); + ble_phy_transition_set(ext ? BLE_PHY_TRANSITION_TO_RX : + BLE_PHY_TRANSITION_NONE, + BLE_LL_IFS); ble_phy_set_txend_cb(NULL, NULL); - rc = ble_phy_tx(ble_ll_conn_tx_connect_ind_pducb, connsm, - ext ? BLE_PHY_TRANSITION_TX_RX : BLE_PHY_TRANSITION_NONE); + rc = ble_phy_tx(ble_ll_conn_tx_connect_ind_pducb, connsm); if (rc) { ble_ll_conn_send_connect_req_cancel(); return -1; diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index c57a1357a1..b4c618513e 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -244,7 +244,8 @@ ble_ll_dtm_tx_sched_cb(struct ble_ll_sched_item *sch) goto resched; } - rc = ble_phy_tx(ble_ll_tx_mbuf_pducb, ctx->om, BLE_PHY_TRANSITION_NONE); + ble_phy_transition_set(BLE_PHY_TRANSITION_NONE, 0); + rc = ble_phy_tx(ble_ll_tx_mbuf_pducb, ctx->om); if (rc) { goto resched; } diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 5aee5de123..52fc33b766 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -688,7 +688,8 @@ ble_ll_iso_big_control_tx(struct ble_ll_iso_big *big) ble_phy_set_txend_cb(ble_ll_iso_big_control_txend_cb, big); ble_phy_setchan(chan_idx, big->ctrl_aa, big->crc_init << 8); - rc = ble_phy_tx(ble_ll_iso_big_control_pdu_cb, big, BLE_PHY_TRANSITION_NONE); + ble_phy_transition_set(BLE_PHY_TRANSITION_NONE, 0); + rc = ble_phy_tx(ble_ll_iso_big_control_pdu_cb, big); return rc; } @@ -773,9 +774,12 @@ ble_ll_iso_big_subevent_tx(struct ble_ll_iso_big *big) to_tx = (big->tx.subevents_rem > 1) || big->cstf; - rc = ble_phy_tx(ble_ll_iso_big_subevent_pdu_cb, big, - to_tx ? BLE_PHY_TRANSITION_TX_TX - : BLE_PHY_TRANSITION_NONE); + ble_phy_transition_set(to_tx ? BLE_PHY_TRANSITION_TO_TX_ISO_SUBEVENT : + BLE_PHY_TRANSITION_NONE, + big->interleaved ? big->bis_spacing : + big->sub_interval); + + rc = ble_phy_tx(ble_ll_iso_big_subevent_pdu_cb, big); return rc; } @@ -874,12 +878,6 @@ ble_ll_iso_big_event_sched_cb(struct ble_ll_sched_item *sch) big->tx.bis = STAILQ_FIRST(&big->bis_q); big->tx.bis->tx.subevent_num = 1; - if (big->interleaved) { - ble_phy_tifs_txtx_set(big->bis_spacing, 0); - } else { - ble_phy_tifs_txtx_set(big->sub_interval, 0); - } - rc = ble_phy_tx_set_start_time(sch->start_time + g_ble_ll_sched_offset_ticks, sch->remainder); if (rc) { diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 157ba94c1b..6ac826102a 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1563,7 +1563,8 @@ ble_ll_scan_send_scan_req(uint8_t pdu_type, uint8_t *rxbuf, ble_ll_scan_req_pdu_prepare(scansm, addrd->adva, addrd->adva_type, rpa_index); - rc = ble_phy_tx(ble_ll_scan_req_tx_pdu_cb, scansm, BLE_PHY_TRANSITION_TX_RX); + ble_phy_transition_set(BLE_PHY_TRANSITION_TO_RX, BLE_LL_IFS); + rc = ble_phy_tx(ble_ll_scan_req_tx_pdu_cb, scansm); if (rc) { return false; } diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index b61f729db1..19ce440752 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -1226,8 +1226,8 @@ ble_ll_scan_aux_send_scan_req(struct ble_ll_scan_aux_data *aux, * interrupted if scheduler kicks in. */ - rc = ble_phy_tx(ble_ll_scan_aux_scan_req_tx_pdu_cb, aux, - BLE_PHY_TRANSITION_TX_RX); + ble_phy_transition_set(BLE_PHY_TRANSITION_TO_RX, BLE_LL_IFS); + rc = ble_phy_tx(ble_ll_scan_aux_scan_req_tx_pdu_cb, aux); if (rc) { return false; } diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index c077f25ff3..3fe68dddde 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -580,7 +580,7 @@ ble_phy_irq_field_tx_exc_bs_start_4this(void) { CMAC->CM_EXC_STAT_REG = CMAC_CM_EXC_STAT_REG_EXC_BS_START_4THIS_Msk; - if (g_ble_phy_data.end_transition == BLE_PHY_TRANSITION_TX_RX) { + if (g_ble_phy_data.end_transition == BLE_PHY_TRANSITION_TO_RX) { /* * Setup 2nd frame that will start after current one. * -2us offset to adjust for allowed active clock accuracy. @@ -642,7 +642,7 @@ ble_phy_irq_frame_tx_exc_bs_stop(void) /* Clear latched timestamp so we do not have error on next frame */ (void)CMAC->CM_TS1_REG; - if (g_ble_phy_data.end_transition == BLE_PHY_TRANSITION_TX_RX) { + if (g_ble_phy_data.end_transition == BLE_PHY_TRANSITION_TO_RX) { #if MYNEWT_VAL(BLE_LL_PHY) ble_phy_mode_apply(g_ble_phy_data.phy_mode_rx); #endif @@ -665,7 +665,7 @@ ble_phy_irq_frame_tx_exc_phy_to_idle_4this(void) { CMAC->CM_EXC_STAT_REG = CMAC_CM_EXC_STAT_REG_EXC_PHY_TO_IDLE_4THIS_Msk; - if (g_ble_phy_data.end_transition == BLE_PHY_TRANSITION_TX_RX) { + if (g_ble_phy_data.end_transition == BLE_PHY_TRANSITION_TO_RX) { ble_phy_rx_setup_xcvr(); g_ble_phy_data.phy_state = BLE_PHY_STATE_RX; @@ -1403,7 +1403,7 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) } int -ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) +ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg) { uint8_t *txbuf = g_ble_phy_tx_buf; int rc; @@ -1412,8 +1412,6 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) assert(CMAC->CM_FRAME_1_REG & CMAC_CM_FRAME_1_REG_FRAME_TX_Msk); - g_ble_phy_data.end_transition = end_trans; - /* * Program required fields now so in worst case TX can continue while we * are still preparing header and payload. @@ -1829,3 +1827,9 @@ ble_phy_dtm_carrier(uint8_t rf_channel) } #endif #endif + +void +ble_phy_transition_set(uint8_t trans, uint16_t usecs) +{ + g_ble_phy_data.end_transition = trans; +} diff --git a/nimble/drivers/native/src/ble_phy.c b/nimble/drivers/native/src/ble_phy.c index e1d2e4aa73..3ac326064c 100644 --- a/nimble/drivers/native/src/ble_phy.c +++ b/nimble/drivers/native/src/ble_phy.c @@ -241,7 +241,7 @@ ble_phy_isr(void) ble_xcvr_clear_irq(BLE_XCVR_IRQ_F_TX_END); transition = g_ble_phy_data.phy_transition; - if (transition == BLE_PHY_TRANSITION_TX_RX) { + if (transition == BLE_PHY_TRANSITION_TO_RX) { /* Disable the phy */ /* XXX: count no bufs? */ ble_phy_disable(); @@ -422,7 +422,7 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) int -ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) +ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg) { uint8_t hdr_byte; int rc; @@ -440,9 +440,6 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) } else { } - /* Set the PHY transition */ - g_ble_phy_data.phy_transition = end_trans; - /* Set phy state to transmitting and count packet statistics */ g_ble_phy_data.phy_state = BLE_PHY_STATE_TX; ++g_ble_phy_stats.tx_good; @@ -662,6 +659,7 @@ ble_phy_rfclk_disable(void) } void -ble_phy_tifs_txtx_set(uint16_t usecs, uint8_t anchor) +ble_phy_transition_set(uint8_t trans, uint16_t usecs) { + g_ble_phy_data.phy_transition = trans; } diff --git a/nimble/drivers/nrf51/src/ble_phy.c b/nimble/drivers/nrf51/src/ble_phy.c index 955db6351f..21e65906bf 100644 --- a/nimble/drivers/nrf51/src/ble_phy.c +++ b/nimble/drivers/nrf51/src/ble_phy.c @@ -585,7 +585,7 @@ ble_phy_tx_end_isr(void) } transition = g_ble_phy_data.phy_transition; - if (transition == BLE_PHY_TRANSITION_TX_RX) { + if (transition == BLE_PHY_TRANSITION_TO_RX) { /* Packet pointer needs to be reset. */ ble_phy_rx_xcvr_setup(); @@ -1127,7 +1127,7 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) } int -ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) +ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg) { int rc; uint8_t *dptr; @@ -1200,7 +1200,7 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) /* Enable shortcuts for transmit start/end. */ shortcuts = RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_READY_START_Msk; - if (end_trans == BLE_PHY_TRANSITION_TX_RX) { + if (g_ble_phy_data.phy_transition == BLE_PHY_TRANSITION_TO_RX) { shortcuts |= RADIO_SHORTS_DISABLED_RXEN_Msk; } NRF_RADIO->SHORTS = shortcuts; @@ -1216,9 +1216,6 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) dptr[2] = 0; } - /* Set the PHY transition */ - g_ble_phy_data.phy_transition = end_trans; - /* Set transmitted payload length */ g_ble_phy_data.phy_tx_pyld_len = payload_len; @@ -1523,3 +1520,9 @@ ble_phy_rfclk_disable(void) NRF_CLOCK->TASKS_HFCLKSTOP = 1; #endif } + +void +ble_phy_transition_set(uint8_t trans, uint16_t usecs) +{ + g_ble_phy_data.phy_transition = trans; +} diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 3deec7dd63..2239751f4f 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -133,6 +133,13 @@ extern uint32_t g_nrf_irk_list[]; (NRF_CILEN_BITS << RADIO_PCNF0_CILEN_Pos) | \ (NRF_TERMLEN_BITS << RADIO_PCNF0_TERMLEN_Pos) +#define PHY_TRANS_NONE (0) +#define PHY_TRANS_TO_TX (1) +#define PHY_TRANS_TO_RX (2) + +#define PHY_TRANS_ANCHOR_START (0) +#define PHY_TRANS_ANCHOR_END (1) + /* BLE PHY data structure */ struct ble_phy_obj { @@ -160,12 +167,9 @@ struct ble_phy_obj void *txend_arg; ble_phy_tx_end_func txend_cb; uint32_t phy_start_cputime; -#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) - uint16_t tifs; -#endif - - uint16_t txtx_time_us; - uint8_t txtx_time_anchor; + uint16_t wfr_usecs; + uint16_t tifs_usecs; + uint8_t tifs_anchor; }; static struct ble_phy_obj g_ble_phy_data; @@ -609,14 +613,6 @@ nrf_wait_disabled(void) } } -#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) -void -ble_phy_tifs_set(uint16_t tifs) -{ - g_ble_phy_data.tifs = tifs; -} -#endif - /** * * @@ -819,6 +815,35 @@ ble_phy_set_start_now(void) return 0; } +static void +ble_phy_wfr_enable_at(uint32_t end_time) +{ + /* wfr_secs is the time from rxen until timeout */ + nrf_timer_cc_set(NRF_TIMER0, 3, end_time); + NRF_TIMER0->EVENTS_COMPARE[3] = 0; + + /* Enable wait for response PPI */ + phy_ppi_wfr_enable(); + + /* + * It may happen that if CPU is halted for a brief moment (e.g. during flash + * erase or write), TIMER0 already counted past CC[3] and thus wfr will not + * fire as expected. In case this happened, let's just disable PPIs for wfr + * and trigger wfr manually (i.e. disable radio). + * + * Note that the same applies to RX start time set in CC[0] but since it + * should fire earlier than wfr, fixing wfr is enough. + * + * CC[1] is only used as a reference on RX start, we do not need it here so + * it can be used to read TIMER0 counter. + */ + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE1); + if (NRF_TIMER0->CC[1] > NRF_TIMER0->CC[3]) { + phy_ppi_wfr_disable(); + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + } +} + /** * Function is used to set PPI so that we can time out waiting for a reception * to occur. This happens for two reasons: we have sent a packet and we are @@ -843,11 +868,7 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) phy = g_ble_phy_data.phy_cur_phy_mode; -#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) - tifs = g_ble_phy_data.tifs; -#else - tifs = BLE_LL_IFS; -#endif + tifs = g_ble_phy_data.tifs_usecs; if (txrx == BLE_PHY_WFR_ENABLE_TXRX) { /* RX shall start exactly T_IFS after TX end captured in CC[2] */ @@ -885,30 +906,7 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) /* Adjust for delay between actual access address RX and EVENT_ADDRESS */ end_time += g_ble_phy_t_rxaddrdelay[phy]; - /* wfr_secs is the time from rxen until timeout */ - nrf_timer_cc_set(NRF_TIMER0, 3, end_time); - NRF_TIMER0->EVENTS_COMPARE[3] = 0; - - /* Enable wait for response PPI */ - phy_ppi_wfr_enable(); - - /* - * It may happen that if CPU is halted for a brief moment (e.g. during flash - * erase or write), TIMER0 already counted past CC[3] and thus wfr will not - * fire as expected. In case this happened, let's just disable PPIs for wfr - * and trigger wfr manually (i.e. disable radio). - * - * Note that the same applies to RX start time set in CC[0] but since it - * should fire earlier than wfr, fixing wfr is enough. - * - * CC[1] is only used as a reference on RX start, we do not need it here so - * it can be used to read TIMER0 counter. - */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE1); - if (NRF_TIMER0->CC[1] > NRF_TIMER0->CC[3]) { - phy_ppi_wfr_disable(); - nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); - } + ble_phy_wfr_enable_at(end_time); } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) @@ -1024,6 +1022,196 @@ ble_phy_rx_xcvr_setup(void) RADIO_INTENSET_DISABLED_Msk); } +static uint32_t +ble_phy_transition_anchor_get(uint8_t tifs_anchor, uint8_t phy_state, uint8_t phy_mode) +{ + uint32_t time; + + if (tifs_anchor == PHY_TRANS_ANCHOR_END) { + /* END timestamp is captured in CC[2] */ + time = NRF_TIMER0->CC[2]; + + /* Adjust for delay between EVENT_END and actual TX/RX end time */ + time += (phy_state == BLE_PHY_STATE_TX) + ? g_ble_phy_t_txenddelay[phy_mode] + : -g_ble_phy_t_rxenddelay[phy_mode]; + + } else { + /* ADDRESS timestamp is captured in CC[1] */ + time = NRF_TIMER0->CC[1]; + + /* Adjust for delay between EVENT_ADDRESS and actual AA time ota */ + time += (phy_state == BLE_PHY_STATE_TX) + ? g_ble_phy_t_txaddrdelay[phy_mode] + : -g_ble_phy_t_rxaddrdelay[phy_mode]; + + /* Adjust by sync word length to get TX/RX start time */ + time -= ble_ll_pdu_syncword_us(phy_mode); + } + + return time; +} + +static int +ble_transition_to_tx(uint8_t tifs_anchor, uint16_t tifs_usecs, uint8_t phy_state) +{ + uint32_t anchor_time; + uint32_t radio_time; + uint32_t start_time; + bool is_late; + uint8_t next_phy_mode; + uint8_t prev_phy_mode = g_ble_phy_data.phy_cur_phy_mode; + +#if MYNEWT_VAL(BLE_LL_PHY) + ble_phy_mode_apply(g_ble_phy_data.phy_tx_phy_mode); +#endif + next_phy_mode = g_ble_phy_data.phy_cur_phy_mode; + + anchor_time = ble_phy_transition_anchor_get(tifs_anchor, phy_state, prev_phy_mode); + start_time = anchor_time + tifs_usecs; + radio_time = start_time; + +#if PHY_USE_FEM_PA + fem_time = anchor_time - MYNEWT_VAL(BLE_FEM_PA_TURN_ON_US); + nrf_timer_cc_set(NRF_TIMER0, 2, fem_time); + NRF_TIMER0->EVENTS_COMPARE[2] = 0; + phy_fem_enable_pa(); +#endif + + /* Adjust for TX rump-up */ + radio_time -= BLE_PHY_T_TXENFAST; + /* Adjust for delay between EVENT_READY and actual TX start time */ + radio_time -= g_ble_phy_t_txdelay[next_phy_mode]; + phy_ppi_timer0_compare0_to_radio_txen_enable(); + + nrf_timer_cc_set(NRF_TIMER0, 0, radio_time); + NRF_TIMER0->EVENTS_COMPARE[0] = 0; + + /* Need to check if TIMER0 did not already count past CC[0] and/or CC[2], so + * we're not stuck waiting for events in case radio and/or PA was not + * started. If event was triggered we're fine regardless of timer value. + * + * Note: CC[3] is used only for wfr which we do not need here. + */ + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); + is_late = (NRF_TIMER0->CC[3] > radio_time) && !NRF_TIMER0->EVENTS_COMPARE[0]; +#if PHY_USE_FEM_PA + is_late = is_late || ((NRF_TIMER0->CC[3] > NRF_TIMER0->CC[2]) && + !NRF_TIMER0->EVENTS_COMPARE[2]); +#endif + if (is_late) { + g_ble_phy_data.phy_transition_late = 1; + + return 1; + } + + return 0; +} + +static int +ble_transition_to_rx(uint8_t tifs_anchor, uint16_t tifs_usecs, uint16_t wfr_usecs, + uint8_t phy_state) +{ + uint32_t anchor_time; + uint32_t radio_time; + uint32_t start_time; + uint32_t wfr_time; + uint8_t next_phy_mode; + uint8_t prev_phy_mode = g_ble_phy_data.phy_cur_phy_mode; + +#if MYNEWT_VAL(BLE_LL_PHY) + ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); +#endif + /* Packet pointer needs to be reset. */ + ble_phy_rx_xcvr_setup(); + next_phy_mode = g_ble_phy_data.phy_cur_phy_mode; + + anchor_time = ble_phy_transition_anchor_get(tifs_anchor, phy_state, prev_phy_mode); + start_time = anchor_time + tifs_usecs; + radio_time = start_time; + +#if PHY_USE_FEM_LNA + fem_time = anchor_time - MYNEWT_VAL(BLE_FEM_LNA_TURN_ON_US); + nrf_timer_cc_set(NRF_TIMER0, 2, fem_time); + NRF_TIMER0->EVENTS_COMPARE[2] = 0; + phy_fem_enable_lna(); +#endif + + /* Adjust for RX rump-up */ + radio_time -= BLE_PHY_T_RXENFAST; + /* Start listening a bit earlier due to allowed active clock accuracy */ + radio_time -= 2; + phy_ppi_timer0_compare0_to_radio_rxen_enable(); + + /* Setup wfr relative to expected radio/PDU start */ + wfr_time = start_time; + /* Add amount of usecs to wait */ + wfr_time += wfr_usecs; + /* Adjust for receiving access address since this triggers EVENT_ADDRESS */ + wfr_time += ble_phy_mode_pdu_start_off(next_phy_mode); + /* Adjust for delay between actual access address RX and EVENT_ADDRESS */ + wfr_time += g_ble_phy_t_rxaddrdelay[next_phy_mode]; + /* Wait a bit longer due to allowed active clock accuracy */ + wfr_time += 2; + /* + * It's possible that we'll capture PDU start time at the end of timer + * cycle and since wfr expires at the beginning of calculated timer + * cycle it can be almost 1 usec too early. Let's compensate for this + * by waiting 1 usec more. + */ + wfr_time += 1; + wfr_time += MYNEWT_VAL(BLE_PHY_EXTENDED_TIFS); + ble_phy_wfr_enable_at(wfr_time); + + /* In case TIMER0 did already count past CC[0] and/or CC[2], radio + * and/or LNA may not be enabled. In any case we won't be stuck since + * wfr will cancel rx if needed. + * + * FIXME failing to enable LNA may result in unexpected RSSI drop in + * case we still rxd something, so perhaps we could check it here + */ + + nrf_timer_cc_set(NRF_TIMER0, 0, radio_time); + NRF_TIMER0->EVENTS_COMPARE[0] = 0; + + return 0; +} + +static int +ble_transition_to_none(void) +{ + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP); + NRF_TIMER0->TASKS_SHUTDOWN = 1; + phy_ppi_wfr_disable(); + phy_ppi_timer0_compare0_to_radio_txen_disable(); + phy_ppi_rtc0_compare0_to_timer0_start_disable(); + ble_phy_disable(); + phy_ppi_fem_disable(); + + ble_phy_transition_set(BLE_PHY_TRANSITION_NONE, 0); + + return 0; +} + +static int +ble_phy_transition(uint8_t transition, uint8_t tifs_anchor, uint16_t tifs_usecs, + uint16_t wfr_usecs, uint8_t phy_state) +{ + int rc = 1; + + if (transition == PHY_TRANS_TO_TX) { + rc = ble_transition_to_tx(tifs_anchor, tifs_usecs, phy_state); + } else if (transition == PHY_TRANS_TO_RX) { + rc = ble_transition_to_rx(tifs_anchor, tifs_usecs, wfr_usecs, phy_state); + } + + if (rc) { + ble_transition_to_none(); + } + + return 0; +} + /** * Called from interrupt context when the transmit ends * @@ -1031,19 +1219,11 @@ ble_phy_rx_xcvr_setup(void) static void ble_phy_tx_end_isr(void) { - uint8_t tx_phy_mode; uint8_t was_encrypted; uint8_t transition; - uint32_t rx_time; - uint32_t tx_time; -#if PHY_USE_FEM - uint32_t fem_time; -#endif - uint32_t radio_time; - uint16_t tifs; - - /* Store PHY on which we've just transmitted smth */ - tx_phy_mode = g_ble_phy_data.phy_cur_phy_mode; + uint16_t wfr_usecs; + uint16_t tifs_usecs; + uint8_t tifs_anchor; /* If this transmission was encrypted we need to remember it */ was_encrypted = g_ble_phy_data.phy_encrypted; @@ -1065,110 +1245,18 @@ ble_phy_tx_end_isr(void) } #endif -#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) - tifs = g_ble_phy_data.tifs; - g_ble_phy_data.tifs = BLE_LL_IFS; -#else - tifs = BLE_LL_IFS; -#endif transition = g_ble_phy_data.phy_transition; + wfr_usecs = g_ble_phy_data.wfr_usecs; + tifs_usecs = g_ble_phy_data.tifs_usecs; + tifs_anchor = g_ble_phy_data.tifs_anchor; + + ble_phy_transition_set(BLE_PHY_TRANSITION_NONE, 0); if (g_ble_phy_data.txend_cb) { g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg); } - if (transition == BLE_PHY_TRANSITION_TX_RX) { -#if MYNEWT_VAL(BLE_LL_PHY) - ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); -#endif - - /* Packet pointer needs to be reset. */ - ble_phy_rx_xcvr_setup(); - - ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_TXRX, tx_phy_mode, 0); - - /* Schedule RX exactly T_IFS after TX end captured in CC[2] */ - rx_time = NRF_TIMER0->CC[2] + tifs; - /* Adjust for delay between EVENT_END and actual TX end time */ - rx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; - /* Start listening a bit earlier due to allowed active clock accuracy */ - rx_time -= 2; - -#if PHY_USE_FEM_LNA - fem_time = rx_time - MYNEWT_VAL(BLE_FEM_LNA_TURN_ON_US); - nrf_timer_cc_set(NRF_TIMER0, 2, fem_time); - NRF_TIMER0->EVENTS_COMPARE[2] = 0; - phy_fem_enable_lna(); -#endif - - radio_time = rx_time - BLE_PHY_T_RXENFAST; - nrf_timer_cc_set(NRF_TIMER0, 0, radio_time); - NRF_TIMER0->EVENTS_COMPARE[0] = 0; - phy_ppi_timer0_compare0_to_radio_rxen_enable(); - - /* In case TIMER0 did already count past CC[0] and/or CC[2], radio - * and/or LNA may not be enabled. In any case we won't be stuck since - * wfr will cancel rx if needed. - * - * FIXME failing to enable LNA may result in unexpected RSSI drop in - * case we still rxd something, so perhaps we could check it here - */ - } else if (transition == BLE_PHY_TRANSITION_TX_TX) { - if (g_ble_phy_data.txtx_time_anchor) { - /* Calculate TX anchor relative to current TX end */ - - /* TX end timestamp is captured in CC[2] */ - tx_time = NRF_TIMER0->CC[2]; - /* Adjust for delay between EVENT_END and actual TX end time */ - tx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; - } else { - /* Calculate TX anchor relative to current TX start */ - - /* AA timestamp is captured in CC[1] */ - tx_time = NRF_TIMER0->CC[1]; - /* Adjust for delay between EVENT_ADDRESS and actual AA time ota */ - tx_time += g_ble_phy_t_txaddrdelay[tx_phy_mode]; - /* Adjust by sync word length to get TX start time */ - tx_time -= ble_ll_pdu_syncword_us(tx_phy_mode); - } - - tx_time += g_ble_phy_data.txtx_time_us; - -#if PHY_USE_FEM_PA - fem_time = tx_time - MYNEWT_VAL(BLE_FEM_PA_TURN_ON_US); -#endif - - /* Adjust for delay between EVENT_READY and actual TX start time */ - tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; - - radio_time = tx_time - BLE_PHY_T_TXENFAST; - nrf_timer_cc_set(NRF_TIMER0, 0, radio_time); - NRF_TIMER0->EVENTS_COMPARE[0] = 0; - phy_ppi_timer0_compare0_to_radio_txen_enable(); - -#if PHY_USE_FEM_PA - nrf_timer_cc_set(NRF_TIMER0, 2, fem_time); - NRF_TIMER0->EVENTS_COMPARE[2] = 0; - phy_fem_enable_pa(); -#endif - - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); - if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) { - phy_ppi_timer0_compare0_to_radio_txen_disable(); - g_ble_phy_data.phy_transition_late = 1; - } - } else { - /* - * XXX: not sure we need to stop the timer here all the time. Or that - * it should be stopped here. - */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP); - NRF_TIMER0->TASKS_SHUTDOWN = 1; - phy_ppi_wfr_disable(); - phy_ppi_timer0_compare0_to_radio_txen_disable(); - phy_ppi_rtc0_compare0_to_timer0_start_disable(); - assert(transition == BLE_PHY_TRANSITION_NONE); - } + ble_phy_transition(transition, tifs_anchor, tifs_usecs, wfr_usecs, BLE_PHY_STATE_TX); } static inline uint8_t @@ -1201,15 +1289,8 @@ ble_phy_rx_end_isr(void) { int rc; uint8_t *dptr; - uint8_t crcok; - uint32_t tx_time; -#if PHY_USE_FEM_PA - uint32_t fem_time; -#endif - uint32_t radio_time; - uint16_t tifs; struct ble_mbuf_hdr *ble_hdr; - bool is_late; + uint8_t crcok; /* Disable automatic RXEN */ phy_ppi_timer0_compare0_to_radio_rxen_disable(); @@ -1254,10 +1335,6 @@ ble_phy_rx_end_isr(void) #endif } -#if MYNEWT_VAL(BLE_LL_PHY) - ble_phy_mode_apply(g_ble_phy_data.phy_tx_phy_mode); -#endif - /* * Let's schedule TX now and we will just cancel it after processing RXed * packet if we don't need TX. @@ -1271,53 +1348,18 @@ ble_phy_rx_end_isr(void) * during radio ramp-up - this gives us extra 40 usecs which is more than * enough. */ + if (g_ble_phy_data.phy_transition == PHY_TRANS_NONE) { + /* XXX: Should be removed after finding all missing uses of ble_phy_transition_set */ + g_ble_phy_data.phy_transition = PHY_TRANS_TO_TX; + } -#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) - tifs = g_ble_phy_data.tifs; - g_ble_phy_data.tifs = BLE_LL_IFS; -#else - tifs = BLE_LL_IFS; -#endif - - /* Schedule TX exactly T_IFS after RX end captured in CC[2] */ - tx_time = NRF_TIMER0->CC[2] + tifs; - /* Adjust for delay between actual RX end time and EVENT_END */ - tx_time -= g_ble_phy_t_rxenddelay[ble_hdr->rxinfo.phy_mode]; - -#if PHY_USE_FEM_PA - fem_time = tx_time - MYNEWT_VAL(BLE_FEM_PA_TURN_ON_US); -#endif - - /* Adjust for delay between EVENT_READY and actual TX start time */ - tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; - - radio_time = tx_time - BLE_PHY_T_TXENFAST; - nrf_timer_cc_set(NRF_TIMER0, 0, radio_time); - NRF_TIMER0->EVENTS_COMPARE[0] = 0; - phy_ppi_timer0_compare0_to_radio_txen_enable(); - -#if PHY_USE_FEM_PA - nrf_timer_cc_set(NRF_TIMER0, 2, fem_time); - NRF_TIMER0->EVENTS_COMPARE[2] = 0; - phy_fem_enable_pa(); -#endif + ble_phy_transition(g_ble_phy_data.phy_transition, + g_ble_phy_data.tifs_anchor, + g_ble_phy_data.tifs_usecs, + g_ble_phy_data.wfr_usecs, + BLE_PHY_STATE_RX); - /* Need to check if TIMER0 did not already count past CC[0] and/or CC[2], so - * we're not stuck waiting for events in case radio and/or PA was not - * started. If event was triggered we're fine regardless of timer value. - * - * Note: CC[3] is used only for wfr which we do not need here. - */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); - is_late = (NRF_TIMER0->CC[3] > radio_time) && !NRF_TIMER0->EVENTS_COMPARE[0]; -#if PHY_USE_FEM_PA - is_late = is_late || - ((NRF_TIMER0->CC[3] > fem_time) && !NRF_TIMER0->EVENTS_COMPARE[2]); -#endif - if (is_late) { - phy_ppi_timer0_compare0_to_radio_txen_disable(); - g_ble_phy_data.phy_transition_late = 1; - } + ble_phy_transition_set(BLE_PHY_TRANSITION_NONE, 0); /* * XXX: This is a horrible ugly hack to deal with the RAM S1 byte @@ -1571,9 +1613,7 @@ ble_phy_init(void) /* Set phy channel to an invalid channel so first set channel works */ g_ble_phy_data.phy_chan = BLE_PHY_NUM_CHANS; -#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) - g_ble_phy_data.tifs = BLE_LL_IFS; -#endif + ble_phy_transition_set(BLE_PHY_TRANSITION_NONE, 0); /* Toggle peripheral power to reset (just in case) */ nrf_radio_power_set(NRF_RADIO, false); @@ -1899,7 +1939,7 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) } int -ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) +ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg) { int rc; uint8_t *dptr; @@ -1908,6 +1948,7 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) uint8_t hdr_byte; uint32_t state; uint32_t shortcuts; + uint8_t end_trans; if (g_ble_phy_data.phy_transition_late) { ble_phy_disable(); @@ -1915,6 +1956,8 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) return BLE_PHY_ERR_TX_LATE; } + end_trans = g_ble_phy_data.phy_transition; + /* * This check is to make sure that the radio is not in a state where * it is moving to disabled state. If so, let it get there. @@ -2209,6 +2252,7 @@ ble_phy_disable(void) ble_phy_disable_irq_and_ppi(); g_ble_phy_data.phy_transition_late = 0; + ble_phy_transition_set(BLE_PHY_TRANSITION_NONE, 0); #if PHY_USE_FEM phy_fem_disable(); @@ -2347,8 +2391,35 @@ ble_phy_rfclk_disable(void) } void -ble_phy_tifs_txtx_set(uint16_t usecs, uint8_t anchor) +ble_phy_transition_set(uint8_t trans, uint16_t usecs) +{ + uint8_t transition; + uint8_t anchor; + + if (trans == BLE_PHY_TRANSITION_TO_TX_ISO_SUBEVENT || + trans == BLE_PHY_TRANSITION_TO_RX_ISO_SUBEVENT) { + anchor = PHY_TRANS_ANCHOR_START; + } else { + anchor = PHY_TRANS_ANCHOR_END; + } + + if (trans == BLE_PHY_TRANSITION_TO_RX || + trans == BLE_PHY_TRANSITION_TO_RX_ISO_SUBEVENT) { + transition = PHY_TRANS_TO_RX; + } else if (trans == BLE_PHY_TRANSITION_TO_TX || + trans == BLE_PHY_TRANSITION_TO_TX_ISO_SUBEVENT) { + transition = PHY_TRANS_TO_TX; + } else { + transition = PHY_TRANS_NONE; + } + + g_ble_phy_data.phy_transition = transition; + g_ble_phy_data.tifs_anchor = anchor; + g_ble_phy_data.tifs_usecs = usecs ? usecs : BLE_LL_IFS; +} + +void +ble_phy_wfr_set(uint16_t usecs) { - g_ble_phy_data.txtx_time_us = usecs; - g_ble_phy_data.txtx_time_anchor = anchor; + g_ble_phy_data.wfr_usecs = usecs; }