Skip to content

Commit

Permalink
Bluetooth: Controller: Update Periodic Sync drift compensation
Browse files Browse the repository at this point in the history
Update Periodic Advertising Synchronization's drift
compensation to save radio ready and address capture on
AUX_SYNC_IND reception, restore and apply at the end of
reception of all AUX_CHAIN_IND PDUs.

Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
  • Loading branch information
cvinayak authored and nashif committed Sep 1, 2021
1 parent 0c7eda9 commit a633c00
Showing 1 changed file with 54 additions and 32 deletions.
86 changes: 54 additions & 32 deletions subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,18 @@
static int init_reset(void);
static int prepare_cb(struct lll_prepare_param *p);
static void abort_cb(struct lll_prepare_param *prepare_param, void *param);
static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t *trx_cnt,
uint8_t *crc_ok);
static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t *crc_ok);
static void isr_rx_adv_sync(void *param);
static void isr_rx_aux_chain(void *param);
static void isr_rx_done_cleanup(struct lll_sync *lll, uint8_t crc_ok);
static void isr_done(void *param);
#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
static int create_iq_report(struct lll_sync *lll, uint8_t rssi_ready,
uint8_t packet_status);
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */

static uint8_t trx_cnt;

int lll_sync_init(void)
{
int err;
Expand Down Expand Up @@ -198,6 +201,9 @@ static int prepare_cb(struct lll_prepare_param *p)
lll->window_widening_event_us = lll->window_widening_max_us;
}

/* Initialize Trx count */
trx_cnt = 0U;

/* Process channel map update, if any */
if (lll->chm_first != lll->chm_last) {
uint16_t instant_latency;
Expand Down Expand Up @@ -297,7 +303,7 @@ static int prepare_cb(struct lll_prepare_param *p)
if (lll_preempt_calc(ull, (TICKER_ID_SCAN_SYNC_BASE +
ull_sync_lll_handle_get(lll)),
ticks_at_event)) {
radio_isr_set(lll_isr_abort, lll);
radio_isr_set(isr_done, lll);
radio_disable();
} else
#endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */
Expand All @@ -323,7 +329,7 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
* After event has been cleanly aborted, clean up resources
* and dispatch event done.
*/
radio_isr_set(lll_isr_done, param);
radio_isr_set(isr_done, param);
radio_disable();
return;
}
Expand Down Expand Up @@ -443,8 +449,7 @@ static void isr_aux_setup(void *param)
#endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */
}

static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t *trx_cnt,
uint8_t *crc_ok)
static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t *crc_ok)
{
uint8_t rssi_ready;
uint8_t trx_done;
Expand All @@ -463,15 +468,14 @@ static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t *trx_cnt,
lll_isr_rx_status_reset();

/* No Rx */
*trx_cnt = 0U;
if (!trx_done) {
/* TODO: Combine the early exit with above if-then-else block
*/
goto isr_rx_done;
}

/* Rx-ed */
*trx_cnt = 1U;
trx_cnt++;

/* Check CRC and generate Periodic Advertising Report */
if (*crc_ok) {
Expand Down Expand Up @@ -532,59 +536,77 @@ static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t *trx_cnt,

static void isr_rx_adv_sync(void *param)
{
struct event_done_extra *e;
struct lll_sync *lll;
uint8_t trx_cnt;
uint8_t crc_ok;
int err;

lll = param;

err = isr_rx(lll, NODE_RX_TYPE_SYNC_REPORT, &trx_cnt, &crc_ok);
err = isr_rx(lll, NODE_RX_TYPE_SYNC_REPORT, &crc_ok);

/* Calculate and place the drift information in done event */
e = ull_event_done_extra_get();
LL_ASSERT(e);

e->type = EVENT_DONE_EXTRA_TYPE_SYNC;
e->trx_cnt = trx_cnt;
e->crc_valid = crc_ok;

e->drift.preamble_to_addr_us = addr_us_get(lll->phy);

e->drift.start_to_address_actual_us = radio_tmr_aa_get() -
radio_tmr_ready_get();
e->drift.window_widening_event_us = lll->window_widening_event_us;

/* Reset window widening, as anchor point sync-ed */
lll->window_widening_event_us = 0U;
lll->window_size_event_us = 0U;
/* Save radio ready and address capture timestamp for later use for
* drift compensation.
*/
radio_tmr_aa_save(radio_tmr_aa_get());
radio_tmr_ready_save(radio_tmr_ready_get());

if (err == -EBUSY) {
return;
}

lll_isr_cleanup(param);
isr_rx_done_cleanup(lll, crc_ok);
}

static void isr_rx_aux_chain(void *param)
{
struct lll_scan_aux *aux_lll;
struct lll_sync *lll;
uint8_t trx_cnt;
uint8_t crc_ok;
int err;

lll = param;
aux_lll = lll->lll_aux;

err = isr_rx(lll, NODE_RX_TYPE_EXT_AUX_REPORT, &trx_cnt, &crc_ok);
err = isr_rx(lll, NODE_RX_TYPE_EXT_AUX_REPORT, &crc_ok);

if (err == -EBUSY) {
return;
}

lll_isr_cleanup(param);
isr_rx_done_cleanup(lll, 1U);
}

static void isr_rx_done_cleanup(struct lll_sync *lll, uint8_t crc_ok)
{
struct event_done_extra *e;

/* Calculate and place the drift information in done event */
e = ull_event_done_extra_get();
LL_ASSERT(e);

e->type = EVENT_DONE_EXTRA_TYPE_SYNC;
e->trx_cnt = trx_cnt;
e->crc_valid = crc_ok;

if (trx_cnt) {
e->drift.preamble_to_addr_us = addr_us_get(lll->phy);
e->drift.start_to_address_actual_us =
radio_tmr_aa_restore() - radio_tmr_ready_restore();
e->drift.window_widening_event_us =
lll->window_widening_event_us;

/* Reset window widening, as anchor point sync-ed */
lll->window_widening_event_us = 0U;
lll->window_size_event_us = 0U;
}

lll_isr_cleanup(lll);
}

static void isr_done(void *param)
{
lll_isr_status_reset();
isr_rx_done_cleanup(param, ((trx_cnt > 1U) ? 1U : 0U));
}

#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
Expand Down

0 comments on commit a633c00

Please sign in to comment.