Bluetooth: Controller: Use remainder in Ext and Periodic PDU offset

Use remainder value in scheduling the periodic auxiliary
PDUs and use the ticker next slot get interface with
remainder value to fill the auxiliary offsets with
microsecond precision in the primary channel PDUs.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2022-04-13 15:47:00 +05:30 committed by Carles Cufí
parent aa73661b09
commit b6cf8bb580
6 changed files with 51 additions and 29 deletions

View file

@ -98,8 +98,6 @@ struct lll_adv_sync {
uint8_t chm_last;
uint16_t chm_instant;
uint32_t ticks_offset;
struct lll_adv_pdu data;
#if defined(CONFIG_BT_CTLR_ADV_PDU_LINK)
@ -129,10 +127,11 @@ struct lll_adv_aux {
*/
uint16_t data_chan_counter;
/* Temporary stored use by primary channel PDU event to fill the
/* Store used by primary channel PDU event to fill the
* auxiliary offset to this auxiliary PDU event.
*/
uint32_t ticks_offset;
uint32_t us_offset;
struct lll_adv_pdu data;
#if defined(CONFIG_BT_CTLR_ADV_PDU_LINK)

View file

@ -10,6 +10,5 @@ void lll_adv_aux_prepare(void *param);
extern uint8_t ull_adv_aux_lll_handle_get(struct lll_adv_aux *lll);
extern struct pdu_adv_aux_ptr *
ull_adv_aux_lll_offset_fill(struct pdu_adv *pdu,
uint32_t ticks_offset,
uint32_t start_us);
ull_adv_aux_lll_offset_fill(struct pdu_adv *pdu, uint32_t ticks_offset,
uint32_t remainder_us, uint32_t start_us);

View file

@ -1317,6 +1317,7 @@ static void isr_done(void *param)
if (lll_aux) {
(void)ull_adv_aux_lll_offset_fill(pdu,
lll_aux->ticks_offset,
lll_aux->us_offset,
start_us);
}
#else /* !CONFIG_BT_CTLR_ADV_EXT */

View file

@ -1118,7 +1118,7 @@ uint32_t ull_adv_aux_start(struct ll_adv_aux_set *aux, uint32_t ticks_anchor,
(TICKER_ID_ADV_AUX_BASE + aux_handle),
ticks_anchor, 0U,
HAL_TICKER_US_TO_TICKS(interval_us),
TICKER_NULL_REMAINDER, TICKER_NULL_LAZY,
HAL_TICKER_REMAINDER(interval_us), TICKER_NULL_LAZY,
(aux->ull.ticks_slot + ticks_slot_overhead),
ticker_cb, aux,
ull_ticker_status_give, (void *)&ret_cb);
@ -1272,6 +1272,7 @@ void ull_adv_aux_offset_get(struct ll_adv_set *adv)
struct pdu_adv_aux_ptr *ull_adv_aux_lll_offset_fill(struct pdu_adv *pdu,
uint32_t ticks_offset,
uint32_t remainder_us,
uint32_t start_us)
{
struct pdu_adv_com_ext_adv *pri_com_hdr;
@ -1302,7 +1303,7 @@ struct pdu_adv_aux_ptr *ull_adv_aux_lll_offset_fill(struct pdu_adv *pdu,
}
aux_ptr = (void *)ptr;
offs = HAL_TICKER_TICKS_TO_US(ticks_offset) - start_us;
offs = HAL_TICKER_TICKS_TO_US(ticks_offset) + remainder_us - start_us;
offs = offs / OFFS_UNIT_30_US;
if (!!(offs >> OFFS_UNIT_BITS)) {
aux_ptr->offs = offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US);
@ -1457,6 +1458,7 @@ static void mfy_aux_offset_get(void *param)
uint32_t ticks_current;
struct ll_adv_set *adv;
struct pdu_adv *pdu;
uint32_t remainder;
uint8_t ticker_id;
uint8_t retry;
uint8_t id;
@ -1479,11 +1481,12 @@ static void mfy_aux_offset_get(void *param)
ticks_previous = ticks_current;
ret_cb = TICKER_STATUS_BUSY;
ret = ticker_next_slot_get(TICKER_INSTANCE_ID_CTLR,
TICKER_USER_ID_ULL_LOW,
&id,
&ticks_current, &ticks_to_expire,
ticker_op_cb, (void *)&ret_cb);
ret = ticker_next_slot_get_ext(TICKER_INSTANCE_ID_CTLR,
TICKER_USER_ID_ULL_LOW,
&id, &ticks_current,
&ticks_to_expire, &remainder,
NULL, NULL, NULL,
ticker_op_cb, (void *)&ret_cb);
if (ret == TICKER_STATUS_BUSY) {
while (ret_cb == TICKER_STATUS_BUSY) {
ticker_job_sched(TICKER_INSTANCE_ID_CTLR,
@ -1499,22 +1502,31 @@ static void mfy_aux_offset_get(void *param)
LL_ASSERT(id != TICKER_NULL);
} while (id != ticker_id);
/* Adjust ticks to expire based on remainder value */
HAL_TICKER_REMOVE_JITTER(ticks_to_expire, remainder);
/* Store the ticks offset for population in other advertising primary
* channel PDUs.
*/
lll_aux->ticks_offset = ticks_to_expire;
lll_aux->ticks_offset = ticks_to_expire;
/* NOTE: as remainder used in scheduling primary PDU not available,
* compensate with a probable jitter of one ticker resolution unit that
* would be included in the packet timer capture when scheduling next
* advertising primary channel PDU.
/* NOTE: as first primary channel PDU does not use remainder, the packet
* timer is started one tick in advance to start the radio with
* microsecond precision, hence compensate for the higher start_us value
* captured at radio start of the first primary channel PDU.
*/
lll_aux->ticks_offset +=
HAL_TICKER_US_TO_TICKS(EVENT_TICKER_RES_MARGIN_US);
lll_aux->ticks_offset += 1U;
/* Store the microsecond remainder offset for population in other
* advertising primary channel PDUs.
*/
lll_aux->us_offset = remainder;
/* Fill the aux offset in the first Primary channel PDU */
/* FIXME: we are in ULL_LOW context, fill offset in LLL context? */
pdu = lll_adv_data_latest_peek(&adv->lll);
aux_ptr = ull_adv_aux_lll_offset_fill(pdu, ticks_to_expire, 0);
aux_ptr = ull_adv_aux_lll_offset_fill(pdu, ticks_to_expire, remainder,
0U);
/* Process channel map update, if any */
if (aux->chm_first != aux->chm_last) {
@ -1572,6 +1584,7 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
sync = HDR_LLL2ULL(adv->lll.sync);
if (sync->is_started) {
sync->aux_remainder = remainder;
ull_adv_sync_offset_get(adv);
}
}

View file

@ -60,6 +60,7 @@ static void mfy_sync_offset_get(void *param);
static inline struct pdu_adv_sync_info *sync_info_get(struct pdu_adv *pdu);
static inline void sync_info_offset_fill(struct pdu_adv_sync_info *si,
uint32_t ticks_offset,
uint32_t remainder_us,
uint32_t start_us);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
@ -1780,9 +1781,12 @@ static void mfy_sync_offset_get(void *param)
struct lll_adv_sync *lll_sync;
struct ll_adv_sync_set *sync;
struct pdu_adv_sync_info *si;
uint32_t sync_remainder_us;
uint32_t aux_remainder_us;
uint32_t ticks_to_expire;
uint32_t ticks_current;
struct pdu_adv *pdu;
uint32_t remainder;
uint8_t chm_first;
uint8_t ticker_id;
uint16_t lazy;
@ -1809,8 +1813,8 @@ static void mfy_sync_offset_get(void *param)
ret = ticker_next_slot_get_ext(TICKER_INSTANCE_ID_CTLR,
TICKER_USER_ID_ULL_LOW,
&id, &ticks_current,
&ticks_to_expire, NULL, &lazy,
NULL, NULL,
&ticks_to_expire, &remainder,
&lazy, NULL, NULL,
ticker_op_cb, (void *)&ret_cb);
if (ret == TICKER_STATUS_BUSY) {
while (ret_cb == TICKER_STATUS_BUSY) {
@ -1827,14 +1831,17 @@ static void mfy_sync_offset_get(void *param)
LL_ASSERT(id != TICKER_NULL);
} while (id != ticker_id);
/* NOTE: as remainder not used in scheduling primary PDU
* packet timer starts transmission after 1 tick hence the +1.
*/
lll_sync->ticks_offset = ticks_to_expire + 1;
HAL_TICKER_REMOVE_JITTER(ticks_to_expire, remainder);
sync_remainder_us = remainder;
remainder = sync->aux_remainder;
HAL_TICKER_ADD_JITTER(ticks_to_expire, remainder);
aux_remainder_us = remainder;
pdu = lll_adv_aux_data_latest_peek(adv->lll.aux);
si = sync_info_get(pdu);
sync_info_offset_fill(si, ticks_to_expire, 0);
sync_info_offset_fill(si, ticks_to_expire, sync_remainder_us,
aux_remainder_us);
si->evt_cntr = lll_sync->event_counter + lll_sync->latency_prepare +
lazy;
@ -1900,11 +1907,12 @@ static inline struct pdu_adv_sync_info *sync_info_get(struct pdu_adv *pdu)
static inline void sync_info_offset_fill(struct pdu_adv_sync_info *si,
uint32_t ticks_offset,
uint32_t remainder_us,
uint32_t start_us)
{
uint32_t offs;
offs = HAL_TICKER_TICKS_TO_US(ticks_offset) - start_us;
offs = HAL_TICKER_TICKS_TO_US(ticks_offset) + remainder_us - start_us;
if (offs >= OFFS_ADJUST_US) {
offs -= OFFS_ADJUST_US;

View file

@ -90,6 +90,8 @@ struct ll_adv_sync_set {
uint8_t is_enabled:1;
uint8_t is_started:1;
uint8_t is_data_cmplt:1;
uint32_t aux_remainder;
};
struct ll_adv_iso_set {